diff options
Diffstat (limited to 'test/functional')
398 files changed, 51038 insertions, 45112 deletions
diff --git a/test/functional/api/autocmd_spec.lua b/test/functional/api/autocmd_spec.lua index fd46a1dcfa..e89abf6c64 100644 --- a/test/functional/api/autocmd_spec.lua +++ b/test/functional/api/autocmd_spec.lua @@ -6,7 +6,7 @@ local eq = helpers.eq local neq = helpers.neq local exec_lua = helpers.exec_lua local matches = helpers.matches -local meths = helpers.meths +local api = helpers.api local source = helpers.source local pcall_err = helpers.pcall_err @@ -15,43 +15,74 @@ before_each(clear) describe('autocmd api', function() describe('nvim_create_autocmd', function() it('validation', function() - eq("Cannot use both 'callback' and 'command'", pcall_err(meths.create_autocmd, 'BufReadPost', { - pattern = '*.py,*.pyi', - command = "echo 'Should Have Errored", - callback = 'NotAllowed', - })) - eq("Cannot use both 'pattern' and 'buffer' for the same autocmd", pcall_err(meths.create_autocmd, 'FileType', { - command = 'let g:called = g:called + 1', - buffer = 0, - pattern = '*.py', - })) - eq("Required: 'event'", pcall_err(meths.create_autocmd, {}, { - command = 'ls', - })) - eq("Required: 'command' or 'callback'", pcall_err(meths.create_autocmd, 'FileType', { - })) - eq("Invalid 'desc': expected String, got Integer", pcall_err(meths.create_autocmd, 'FileType', { - command = 'ls', - desc = 42, - })) - eq("Invalid 'callback': expected Lua function or Vim function name, got Integer", pcall_err(meths.create_autocmd, 'FileType', { - callback = 0, - })) - eq("Invalid 'event' item: expected String, got Array", pcall_err(meths.create_autocmd, - {'FileType', {}}, {})) - eq("Invalid 'group': 0", pcall_err(meths.create_autocmd, 'FileType', { - group = 0, - command = 'ls', - })) - - eq("Invalid 'event': 'foo'", pcall_err(meths.create_autocmd, 'foo', { command = '' })) - eq("Invalid 'event': 'VimEnter '", pcall_err(meths.create_autocmd, 'VimEnter ', { command = '' })) - eq("Invalid 'event': 'VimEnter foo'", pcall_err(meths.create_autocmd, 'VimEnter foo', { command = '' })) - eq("Invalid 'event': 'BufAdd,BufDelete'", pcall_err(meths.create_autocmd, 'BufAdd,BufDelete', { command = '' })) + eq( + "Cannot use both 'callback' and 'command'", + pcall_err(api.nvim_create_autocmd, 'BufReadPost', { + pattern = '*.py,*.pyi', + command = "echo 'Should Have Errored", + callback = 'NotAllowed', + }) + ) + eq( + "Cannot use both 'pattern' and 'buffer' for the same autocmd", + pcall_err(api.nvim_create_autocmd, 'FileType', { + command = 'let g:called = g:called + 1', + buffer = 0, + pattern = '*.py', + }) + ) + eq( + "Required: 'event'", + pcall_err(api.nvim_create_autocmd, {}, { + command = 'ls', + }) + ) + eq("Required: 'command' or 'callback'", pcall_err(api.nvim_create_autocmd, 'FileType', {})) + eq( + "Invalid 'desc': expected String, got Integer", + pcall_err(api.nvim_create_autocmd, 'FileType', { + command = 'ls', + desc = 42, + }) + ) + eq( + "Invalid 'callback': expected Lua function or Vim function name, got Integer", + pcall_err(api.nvim_create_autocmd, 'FileType', { + callback = 0, + }) + ) + eq( + "Invalid 'event' item: expected String, got Array", + pcall_err(api.nvim_create_autocmd, { 'FileType', {} }, {}) + ) + eq( + "Invalid 'group': 0", + pcall_err(api.nvim_create_autocmd, 'FileType', { + group = 0, + command = 'ls', + }) + ) + + eq("Invalid 'event': 'foo'", pcall_err(api.nvim_create_autocmd, 'foo', { command = '' })) + eq( + "Invalid 'event': 'VimEnter '", + pcall_err(api.nvim_create_autocmd, 'VimEnter ', { command = '' }) + ) + eq( + "Invalid 'event': 'VimEnter foo'", + pcall_err(api.nvim_create_autocmd, 'VimEnter foo', { command = '' }) + ) + eq( + "Invalid 'event': 'BufAdd,BufDelete'", + pcall_err(api.nvim_create_autocmd, 'BufAdd,BufDelete', { command = '' }) + ) end) it('doesnt leak when you use ++once', function() - eq(1, exec_lua([[ + eq( + 1, + exec_lua( + [[ local count = 0 vim.api.nvim_create_autocmd("FileType", { @@ -64,30 +95,33 @@ describe('autocmd api', function() vim.cmd "set filetype=python" return count - ]], {})) + ]], + {} + ) + ) end) it('allows passing buffer by key', function() - meths.set_var('called', 0) + api.nvim_set_var('called', 0) - meths.create_autocmd("FileType", { - command = "let g:called = g:called + 1", + api.nvim_create_autocmd('FileType', { + command = 'let g:called = g:called + 1', buffer = 0, }) - meths.command "set filetype=txt" - eq(1, meths.get_var('called')) + command 'set filetype=txt' + eq(1, api.nvim_get_var('called')) -- switch to a new buffer - meths.command "new" - meths.command "set filetype=python" + command 'new' + command 'set filetype=python' - eq(1, meths.get_var('called')) + eq(1, api.nvim_get_var('called')) end) it('does not allow passing invalid buffers', function() - local ok, msg = pcall(meths.create_autocmd, 'FileType', { - command = "let g:called = g:called + 1", + local ok, msg = pcall(api.nvim_create_autocmd, 'FileType', { + command = 'let g:called = g:called + 1', buffer = -1, }) @@ -96,60 +130,66 @@ describe('autocmd api', function() end) it('errors on non-functions for cb', function() - eq(false, pcall(exec_lua, [[ + eq( + false, + pcall( + exec_lua, + [[ vim.api.nvim_create_autocmd("BufReadPost", { pattern = "*.py,*.pyi", callback = 5, }) - ]])) + ]] + ) + ) end) it('allow passing pattern and <buffer> in same pattern', function() - local ok = pcall(meths.create_autocmd, "BufReadPost", { - pattern = "*.py,<buffer>", - command = "echo 'Should Not Error'" + local ok = pcall(api.nvim_create_autocmd, 'BufReadPost', { + pattern = '*.py,<buffer>', + command = "echo 'Should Not Error'", }) eq(true, ok) end) it('should handle multiple values as comma separated list', function() - meths.create_autocmd("BufReadPost", { - pattern = "*.py,*.pyi", - command = "echo 'Should Not Have Errored'" + api.nvim_create_autocmd('BufReadPost', { + pattern = '*.py,*.pyi', + command = "echo 'Should Not Have Errored'", }) -- We should have one autocmd for *.py and one for *.pyi - eq(2, #meths.get_autocmds { event = "BufReadPost" }) + eq(2, #api.nvim_get_autocmds { event = 'BufReadPost' }) end) it('should handle multiple values as array', function() - meths.create_autocmd("BufReadPost", { - pattern = { "*.py", "*.pyi", }, - command = "echo 'Should Not Have Errored'" + api.nvim_create_autocmd('BufReadPost', { + pattern = { '*.py', '*.pyi' }, + command = "echo 'Should Not Have Errored'", }) -- We should have one autocmd for *.py and one for *.pyi - eq(2, #meths.get_autocmds { event = "BufReadPost" }) + eq(2, #api.nvim_get_autocmds { event = 'BufReadPost' }) end) describe('desc', function() it('can add description to one autocmd', function() - local cmd = "echo 'Should Not Have Errored'" - local desc = "Can show description" - meths.create_autocmd("BufReadPost", { - pattern = "*.py", + local cmd = "echo 'Should Not Have Errored'" + local desc = 'Can show description' + api.nvim_create_autocmd('BufReadPost', { + pattern = '*.py', command = cmd, desc = desc, }) - eq(desc, meths.get_autocmds { event = "BufReadPost" }[1].desc) - eq(cmd, meths.get_autocmds { event = "BufReadPost" }[1].command) + eq(desc, api.nvim_get_autocmds { event = 'BufReadPost' }[1].desc) + eq(cmd, api.nvim_get_autocmds { event = 'BufReadPost' }[1].command) end) it('can add description to one autocmd that uses a callback', function() local desc = 'Can show description' - meths.set_var('desc', desc) + api.nvim_set_var('desc', desc) local result = exec_lua([[ local callback = function() print 'Should Not Have Errored' end @@ -178,38 +218,38 @@ describe('autocmd api', function() }) ]]) - eq(nil, meths.get_autocmds({ event = 'BufReadPost' })[1].desc) + eq(nil, api.nvim_get_autocmds({ event = 'BufReadPost' })[1].desc) end) it('can add description to multiple autocmd', function() - meths.create_autocmd("BufReadPost", { - pattern = {"*.py", "*.pyi"}, + api.nvim_create_autocmd('BufReadPost', { + pattern = { '*.py', '*.pyi' }, command = "echo 'Should Not Have Errored'", - desc = "Can show description", + desc = 'Can show description', }) - local aus = meths.get_autocmds { event = "BufReadPost" } + local aus = api.nvim_get_autocmds { event = 'BufReadPost' } eq(2, #aus) - eq("Can show description", aus[1].desc) - eq("Can show description", aus[2].desc) + eq('Can show description', aus[1].desc) + eq('Can show description', aus[2].desc) end) end) pending('script and verbose settings', function() it('marks API client', function() - meths.create_autocmd("BufReadPost", { - pattern = "*.py", + api.nvim_create_autocmd('BufReadPost', { + pattern = '*.py', command = "echo 'Should Not Have Errored'", - desc = "Can show description", + desc = 'Can show description', }) - local aus = meths.get_autocmds { event = "BufReadPost" } + local aus = api.nvim_get_autocmds { event = 'BufReadPost' } eq(1, #aus, aus) end) end) it('removes an autocommand if the callback returns true', function() - meths.set_var("some_condition", false) + api.nvim_set_var('some_condition', false) exec_lua [[ vim.api.nvim_create_autocmd("User", { @@ -221,21 +261,21 @@ describe('autocmd api', function() }) ]] - meths.exec_autocmds("User", {pattern = "Test"}) + api.nvim_exec_autocmds('User', { pattern = 'Test' }) - local aus = meths.get_autocmds({ event = 'User', pattern = 'Test' }) + local aus = api.nvim_get_autocmds({ event = 'User', pattern = 'Test' }) local first = aus[1] eq(true, first.id > 0) - meths.set_var("some_condition", true) - meths.exec_autocmds("User", {pattern = "Test"}) - eq({}, meths.get_autocmds({event = "User", pattern = "Test"})) + api.nvim_set_var('some_condition', true) + api.nvim_exec_autocmds('User', { pattern = 'Test' }) + eq({}, api.nvim_get_autocmds({ event = 'User', pattern = 'Test' })) end) it('receives an args table', function() - local group_id = meths.create_augroup("TestGroup", {}) + local group_id = api.nvim_create_augroup('TestGroup', {}) -- Having an existing autocmd calling expand("<afile>") shouldn't change args #18964 - meths.create_autocmd('User', { + api.nvim_create_autocmd('User', { group = 'TestGroup', pattern = 'Te*', command = 'call expand("<afile>")', @@ -251,15 +291,15 @@ describe('autocmd api', function() }) ]] - meths.exec_autocmds("User", {pattern = "Test pattern"}) + api.nvim_exec_autocmds('User', { pattern = 'Test pattern' }) eq({ id = autocmd_id, group = group_id, - event = "User", - match = "Test pattern", - file = "Test pattern", + event = 'User', + match = 'Test pattern', + file = 'Test pattern', buf = 1, - }, meths.get_var("autocmd_args")) + }, api.nvim_get_var('autocmd_args')) -- Test without a group autocmd_id = exec_lua [[ @@ -271,20 +311,23 @@ describe('autocmd api', function() }) ]] - meths.exec_autocmds("User", {pattern = "some_pat"}) + api.nvim_exec_autocmds('User', { pattern = 'some_pat' }) eq({ id = autocmd_id, group = nil, - event = "User", - match = "some_pat", - file = "some_pat", + event = 'User', + match = 'some_pat', + file = 'some_pat', buf = 1, - }, meths.get_var("autocmd_args")) + }, api.nvim_get_var('autocmd_args')) end) it('can receive arbitrary data', function() local function test(data) - eq(data, exec_lua([[ + eq( + data, + exec_lua( + [[ local input = ... local output vim.api.nvim_create_autocmd("User", { @@ -300,40 +343,64 @@ describe('autocmd api', function() }) return output - ]], data)) + ]], + data + ) + ) end - test("Hello") + test('Hello') test(42) test(true) - test({ "list" }) - test({ foo = "bar" }) + test({ 'list' }) + test({ foo = 'bar' }) end) end) describe('nvim_get_autocmds', function() it('validation', function() - eq("Invalid 'group': 9997999", pcall_err(meths.get_autocmds, { - group = 9997999, - })) - eq("Invalid 'group': 'bogus'", pcall_err(meths.get_autocmds, { - group = 'bogus', - })) - eq("Invalid 'group': 0", pcall_err(meths.get_autocmds, { - group = 0, - })) - eq("Invalid 'group': expected String or Integer, got Array", pcall_err(meths.get_autocmds, { - group = {}, - })) - eq("Invalid 'buffer': expected Integer or Array, got Boolean", pcall_err(meths.get_autocmds, { - buffer = true, - })) - eq("Invalid 'event': expected String or Array", pcall_err(meths.get_autocmds, { - event = true, - })) - eq("Invalid 'pattern': expected String or Array, got Boolean", pcall_err(meths.get_autocmds, { - pattern = true, - })) + eq( + "Invalid 'group': 9997999", + pcall_err(api.nvim_get_autocmds, { + group = 9997999, + }) + ) + eq( + "Invalid 'group': 'bogus'", + pcall_err(api.nvim_get_autocmds, { + group = 'bogus', + }) + ) + eq( + "Invalid 'group': 0", + pcall_err(api.nvim_get_autocmds, { + group = 0, + }) + ) + eq( + "Invalid 'group': expected String or Integer, got Array", + pcall_err(api.nvim_get_autocmds, { + group = {}, + }) + ) + eq( + "Invalid 'buffer': expected Integer or Array, got Boolean", + pcall_err(api.nvim_get_autocmds, { + buffer = true, + }) + ) + eq( + "Invalid 'event': expected String or Array", + pcall_err(api.nvim_get_autocmds, { + event = true, + }) + ) + eq( + "Invalid 'pattern': expected String or Array, got Boolean", + pcall_err(api.nvim_get_autocmds, { + pattern = true, + }) + ) end) describe('events', function() @@ -341,7 +408,7 @@ describe('autocmd api', function() command [[au! InsertEnter]] command [[au InsertEnter * :echo "1"]] - local aus = meths.get_autocmds { event = "InsertEnter" } + local aus = api.nvim_get_autocmds { event = 'InsertEnter' } eq(1, #aus) end) @@ -350,7 +417,7 @@ describe('autocmd api', function() command [[au InsertEnter * :echo "1"]] command [[au InsertEnter * :echo "2"]] - local aus = meths.get_autocmds { event = "InsertEnter" } + local aus = api.nvim_get_autocmds { event = 'InsertEnter' } eq(2, #aus) end) @@ -359,8 +426,8 @@ describe('autocmd api', function() command [[au InsertEnter * :echo "1"]] command [[au InsertEnter * :echo "2"]] - local string_aus = meths.get_autocmds { event = "InsertEnter" } - local array_aus = meths.get_autocmds { event = { "InsertEnter" } } + local string_aus = api.nvim_get_autocmds { event = 'InsertEnter' } + local array_aus = api.nvim_get_autocmds { event = { 'InsertEnter' } } eq(string_aus, array_aus) end) @@ -370,7 +437,7 @@ describe('autocmd api', function() command [[au InsertEnter * :echo "1"]] command [[au InsertEnter * :echo "2"]] - local aus = meths.get_autocmds { event = { "InsertEnter", "InsertLeave" } } + local aus = api.nvim_get_autocmds { event = { 'InsertEnter', 'InsertLeave' } } eq(2, #aus) end) @@ -384,7 +451,7 @@ describe('autocmd api', function() \ }) ]] - local aus = meths.get_autocmds { event = { "InsertEnter", "InsertLeave" } } + local aus = api.nvim_get_autocmds { event = { 'InsertEnter', 'InsertLeave' } } local first = aus[1] eq(first.id, nil) @@ -392,8 +459,8 @@ describe('autocmd api', function() local second = aus[2] neq(second.id, nil) - meths.del_autocmd(second.id) - local new_aus = meths.get_autocmds { event = { "InsertEnter", "InsertLeave" } } + api.nvim_del_autocmd(second.id) + local new_aus = api.nvim_get_autocmds { event = { 'InsertEnter', 'InsertLeave' } } eq(1, #new_aus) eq(first, new_aus[1]) end) @@ -402,8 +469,16 @@ describe('autocmd api', function() command [[au! InsertEnter]] command [[au InsertEnter * :echo "1"]] - local aus = meths.get_autocmds { event = "InsertEnter" } - eq({ { buflocal = false, command = ':echo "1"', event = "InsertEnter", once = false, pattern = "*" } }, aus) + local aus = api.nvim_get_autocmds { event = 'InsertEnter' } + eq({ + { + buflocal = false, + command = ':echo "1"', + event = 'InsertEnter', + once = false, + pattern = '*', + }, + }, aus) end) it('works with buffer numbers', function() @@ -412,77 +487,96 @@ describe('autocmd api', function() command [[au InsertEnter <buffer=1> :echo "1"]] command [[au InsertEnter <buffer=2> :echo "2"]] - local aus = meths.get_autocmds { event = "InsertEnter", buffer = 0 } - eq({{ - buffer = 2, - buflocal = true, - command = ':echo "2"', - event = 'InsertEnter', - once = false, - pattern = '<buffer=2>', - }}, aus) - - aus = meths.get_autocmds { event = "InsertEnter", buffer = 1 } - eq({{ - buffer = 1, - buflocal = true, - command = ':echo "1"', - event = "InsertEnter", - once = false, - pattern = "<buffer=1>", - }}, aus) - - aus = meths.get_autocmds { event = "InsertEnter", buffer = { 1, 2 } } - eq({{ - buffer = 1, - buflocal = true, - command = ':echo "1"', - event = "InsertEnter", - once = false, - pattern = "<buffer=1>", - }, { - buffer = 2, - buflocal = true, - command = ':echo "2"', - event = "InsertEnter", - once = false, - pattern = "<buffer=2>", - }}, aus) - - eq("Invalid 'buffer': expected Integer or Array, got String", pcall_err(meths.get_autocmds, { event = "InsertEnter", buffer = "foo" })) - eq("Invalid 'buffer': expected Integer, got String", pcall_err(meths.get_autocmds, { event = "InsertEnter", buffer = { "foo", 42 } })) - eq("Invalid buffer id: 42", pcall_err(meths.get_autocmds, { event = "InsertEnter", buffer = { 42 } })) + local aus = api.nvim_get_autocmds { event = 'InsertEnter', buffer = 0 } + eq({ + { + buffer = 2, + buflocal = true, + command = ':echo "2"', + event = 'InsertEnter', + once = false, + pattern = '<buffer=2>', + }, + }, aus) + + aus = api.nvim_get_autocmds { event = 'InsertEnter', buffer = 1 } + eq({ + { + buffer = 1, + buflocal = true, + command = ':echo "1"', + event = 'InsertEnter', + once = false, + pattern = '<buffer=1>', + }, + }, aus) + + aus = api.nvim_get_autocmds { event = 'InsertEnter', buffer = { 1, 2 } } + eq({ + { + buffer = 1, + buflocal = true, + command = ':echo "1"', + event = 'InsertEnter', + once = false, + pattern = '<buffer=1>', + }, + { + buffer = 2, + buflocal = true, + command = ':echo "2"', + event = 'InsertEnter', + once = false, + pattern = '<buffer=2>', + }, + }, aus) + + eq( + "Invalid 'buffer': expected Integer or Array, got String", + pcall_err(api.nvim_get_autocmds, { event = 'InsertEnter', buffer = 'foo' }) + ) + eq( + "Invalid 'buffer': expected Integer, got String", + pcall_err(api.nvim_get_autocmds, { event = 'InsertEnter', buffer = { 'foo', 42 } }) + ) + eq( + 'Invalid buffer id: 42', + pcall_err(api.nvim_get_autocmds, { event = 'InsertEnter', buffer = { 42 } }) + ) local bufs = {} for _ = 1, 257 do - table.insert(bufs, meths.create_buf(true, false)) + table.insert(bufs, api.nvim_create_buf(true, false)) end - eq("Too many buffers (maximum of 256)", pcall_err(meths.get_autocmds, { event = "InsertEnter", buffer = bufs })) + eq( + 'Too many buffers (maximum of 256)', + pcall_err(api.nvim_get_autocmds, { event = 'InsertEnter', buffer = bufs }) + ) end) it('returns autocmds when group is specified by id', function() - local auid = meths.create_augroup("nvim_test_augroup", { clear = true }) - meths.create_autocmd("FileType", { group = auid, command = 'echo "1"' }) - meths.create_autocmd("FileType", { group = auid, command = 'echo "2"' }) + local auid = api.nvim_create_augroup('nvim_test_augroup', { clear = true }) + api.nvim_create_autocmd('FileType', { group = auid, command = 'echo "1"' }) + api.nvim_create_autocmd('FileType', { group = auid, command = 'echo "2"' }) - local aus = meths.get_autocmds { group = auid } + local aus = api.nvim_get_autocmds { group = auid } eq(2, #aus) - local aus2 = meths.get_autocmds { group = auid, event = "InsertEnter" } + local aus2 = api.nvim_get_autocmds { group = auid, event = 'InsertEnter' } eq(0, #aus2) end) it('returns autocmds when group is specified by name', function() - local auname = "nvim_test_augroup" - meths.create_augroup(auname, { clear = true }) - meths.create_autocmd("FileType", { group = auname, command = 'echo "1"' }) - meths.create_autocmd("FileType", { group = auname, command = 'echo "2"' }) + local auname = 'nvim_test_augroup' + api.nvim_create_augroup(auname, { clear = true }) + api.nvim_create_autocmd('FileType', { group = auname, command = 'echo "1"' }) + api.nvim_create_autocmd('FileType', { group = auname, command = 'echo "2"' }) - local aus = meths.get_autocmds { group = auname } + local aus = api.nvim_get_autocmds { group = auname } eq(2, #aus) - local aus2 = meths.get_autocmds { group = auname, event = "InsertEnter" } + local aus2 = api.nvim_get_autocmds { group = auname, event = 'InsertEnter' } eq(0, #aus2) end) @@ -510,12 +604,12 @@ describe('autocmd api', function() -- 1 for the first buffer -- 2 for First.md -- 3-7 for the 5 we make in the autocmd - eq({1, 2, 3, 4, 5, 6, 7}, bufs) + eq({ 1, 2, 3, 4, 5, 6, 7 }, bufs) end) it('can retrieve a callback from an autocmd', function() local content = 'I Am A Callback' - meths.set_var('content', content) + api.nvim_set_var('content', content) local result = exec_lua([[ local cb = function() return vim.g.content end @@ -534,12 +628,14 @@ describe('autocmd api', function() } ]]) - eq("function", result.cb.type) + eq('function', result.cb.type) eq(true, result.cb.can_retrieve) end) - it('will return an empty string as the command for an autocmd that uses a callback', function() - local result = exec_lua([[ + it( + 'will return an empty string as the command for an autocmd that uses a callback', + function() + local result = exec_lua([[ local callback = function() print 'I Am A Callback' end vim.api.nvim_create_autocmd("BufWritePost", { pattern = "*.py", @@ -553,8 +649,9 @@ describe('autocmd api', function() } ]]) - eq({ command = "", cbtype = 'function' }, result) - end) + eq({ command = '', cbtype = 'function' }, result) + end + ) end) describe('groups', function() @@ -574,7 +671,7 @@ describe('autocmd api', function() end) it('returns all groups if no group is specified', function() - local aus = meths.get_autocmds { event = "InsertEnter" } + local aus = api.nvim_get_autocmds { event = 'InsertEnter' } if #aus ~= 4 then eq({}, aus) end @@ -583,33 +680,34 @@ describe('autocmd api', function() end) it('returns only the group specified', function() - local aus = meths.get_autocmds { - event = "InsertEnter", - group = "GroupOne", + local aus = api.nvim_get_autocmds { + event = 'InsertEnter', + group = 'GroupOne', } eq(1, #aus) eq([[:echo "GroupOne:1"]], aus[1].command) - eq("GroupOne", aus[1].group_name) + eq('GroupOne', aus[1].group_name) end) it('returns only the group specified, multiple values', function() - local aus = meths.get_autocmds { - event = "InsertEnter", - group = "GroupTwo", + local aus = api.nvim_get_autocmds { + event = 'InsertEnter', + group = 'GroupTwo', } eq(2, #aus) eq([[:echo "GroupTwo:2"]], aus[1].command) - eq("GroupTwo", aus[1].group_name) + eq('GroupTwo', aus[1].group_name) eq([[:echo "GroupTwo:3"]], aus[2].command) - eq("GroupTwo", aus[2].group_name) + eq('GroupTwo', aus[2].group_name) end) end) describe('groups: 2', function() it('raises error for undefined augroup name', function() - local success, code = unpack(meths.exec_lua([[ + local success, code = unpack(api.nvim_exec_lua( + [[ return {pcall(function() vim.api.nvim_create_autocmd("FileType", { pattern = "*", @@ -617,14 +715,17 @@ describe('autocmd api', function() command = "echo 'hello'", }) end)} - ]], {})) + ]], + {} + )) eq(false, success) matches("Invalid 'group': 'NotDefined'", code) end) it('raises error for undefined augroup id', function() - local success, code = unpack(meths.exec_lua([[ + local success, code = unpack(api.nvim_exec_lua( + [[ return {pcall(function() -- Make sure the augroup is deleted vim.api.nvim_del_augroup_by_id(1) @@ -635,14 +736,17 @@ describe('autocmd api', function() command = "echo 'hello'", }) end)} - ]], {})) + ]], + {} + )) eq(false, success) matches("Invalid 'group': 1", code) end) it('raises error for invalid group type', function() - local success, code = unpack(meths.exec_lua([[ + local success, code = unpack(api.nvim_exec_lua( + [[ return {pcall(function() vim.api.nvim_create_autocmd("FileType", { pattern = "*", @@ -650,21 +754,26 @@ describe('autocmd api', function() command = "echo 'hello'", }) end)} - ]], {})) + ]], + {} + )) eq(false, success) matches("Invalid 'group': expected String or Integer, got Boolean", code) end) it('raises error for invalid pattern array', function() - local success, code = unpack(meths.exec_lua([[ + local success, code = unpack(api.nvim_exec_lua( + [[ return {pcall(function() vim.api.nvim_create_autocmd("FileType", { pattern = {{}}, command = "echo 'hello'", }) end)} - ]], {})) + ]], + {} + )) eq(false, success) matches("Invalid 'pattern' item: expected String, got Array", code) @@ -683,9 +792,9 @@ describe('autocmd api', function() end) it('returns for literal match', function() - local aus = meths.get_autocmds { - event = "InsertEnter", - pattern = "*" + local aus = api.nvim_get_autocmds { + event = 'InsertEnter', + pattern = '*', } eq(1, #aus) @@ -694,9 +803,9 @@ describe('autocmd api', function() it('returns for multiple matches', function() -- vim.api.nvim_get_autocmds - local aus = meths.get_autocmds { - event = "InsertEnter", - pattern = { "*.one", "*.two" }, + local aus = api.nvim_get_autocmds { + event = 'InsertEnter', + pattern = { '*.one', '*.two' }, } eq(3, #aus) @@ -706,19 +815,19 @@ describe('autocmd api', function() end) it('should work for buffer autocmds', function() - local normalized_aus = meths.get_autocmds { - event = "InsertEnter", - pattern = "<buffer=1>", + local normalized_aus = api.nvim_get_autocmds { + event = 'InsertEnter', + pattern = '<buffer=1>', } - local raw_aus = meths.get_autocmds { - event = "InsertEnter", - pattern = "<buffer>", + local raw_aus = api.nvim_get_autocmds { + event = 'InsertEnter', + pattern = '<buffer>', } - local zero_aus = meths.get_autocmds { - event = "InsertEnter", - pattern = "<buffer=0>", + local zero_aus = api.nvim_get_autocmds { + event = 'InsertEnter', + pattern = '<buffer=0>', } eq(normalized_aus, raw_aus) @@ -730,165 +839,186 @@ describe('autocmd api', function() describe('nvim_exec_autocmds', function() it('validation', function() - eq("Invalid 'group': 9997999", pcall_err(meths.exec_autocmds, 'FileType', { - group = 9997999, - })) - eq("Invalid 'group': 'bogus'", pcall_err(meths.exec_autocmds, 'FileType', { - group = 'bogus', - })) - eq("Invalid 'group': expected String or Integer, got Array", pcall_err(meths.exec_autocmds, 'FileType', { - group = {}, - })) - eq("Invalid 'group': 0", pcall_err(meths.exec_autocmds, 'FileType', { - group = 0, - })) - eq("Invalid 'buffer': expected Buffer, got Array", pcall_err(meths.exec_autocmds, 'FileType', { - buffer = {}, - })) - eq("Invalid 'event' item: expected String, got Array", pcall_err(meths.exec_autocmds, - {'FileType', {}}, {})) + eq( + "Invalid 'group': 9997999", + pcall_err(api.nvim_exec_autocmds, 'FileType', { + group = 9997999, + }) + ) + eq( + "Invalid 'group': 'bogus'", + pcall_err(api.nvim_exec_autocmds, 'FileType', { + group = 'bogus', + }) + ) + eq( + "Invalid 'group': expected String or Integer, got Array", + pcall_err(api.nvim_exec_autocmds, 'FileType', { + group = {}, + }) + ) + eq( + "Invalid 'group': 0", + pcall_err(api.nvim_exec_autocmds, 'FileType', { + group = 0, + }) + ) + eq( + "Invalid 'buffer': expected Buffer, got Array", + pcall_err(api.nvim_exec_autocmds, 'FileType', { + buffer = {}, + }) + ) + eq( + "Invalid 'event' item: expected String, got Array", + pcall_err(api.nvim_exec_autocmds, { 'FileType', {} }, {}) + ) end) - it("can trigger builtin autocmds", function() - meths.set_var("autocmd_executed", false) + it('can trigger builtin autocmds', function() + api.nvim_set_var('autocmd_executed', false) - meths.create_autocmd("BufReadPost", { - pattern = "*", - command = "let g:autocmd_executed = v:true", + api.nvim_create_autocmd('BufReadPost', { + pattern = '*', + command = 'let g:autocmd_executed = v:true', }) - eq(false, meths.get_var("autocmd_executed")) - meths.exec_autocmds("BufReadPost", {}) - eq(true, meths.get_var("autocmd_executed")) + eq(false, api.nvim_get_var('autocmd_executed')) + api.nvim_exec_autocmds('BufReadPost', {}) + eq(true, api.nvim_get_var('autocmd_executed')) end) - it("can trigger multiple patterns", function() - meths.set_var("autocmd_executed", 0) + it('can trigger multiple patterns', function() + api.nvim_set_var('autocmd_executed', 0) - meths.create_autocmd("BufReadPost", { - pattern = "*", - command = "let g:autocmd_executed += 1", + api.nvim_create_autocmd('BufReadPost', { + pattern = '*', + command = 'let g:autocmd_executed += 1', }) - meths.exec_autocmds("BufReadPost", { pattern = { "*.lua", "*.vim" } }) - eq(2, meths.get_var("autocmd_executed")) + api.nvim_exec_autocmds('BufReadPost', { pattern = { '*.lua', '*.vim' } }) + eq(2, api.nvim_get_var('autocmd_executed')) - meths.create_autocmd("BufReadPre", { - pattern = { "bar", "foo" }, - command = "let g:autocmd_executed += 10", + api.nvim_create_autocmd('BufReadPre', { + pattern = { 'bar', 'foo' }, + command = 'let g:autocmd_executed += 10', }) - meths.exec_autocmds("BufReadPre", { pattern = { "foo", "bar", "baz", "frederick" }}) - eq(22, meths.get_var("autocmd_executed")) + api.nvim_exec_autocmds('BufReadPre', { pattern = { 'foo', 'bar', 'baz', 'frederick' } }) + eq(22, api.nvim_get_var('autocmd_executed')) end) - it("can pass the buffer", function() - meths.set_var("buffer_executed", -1) - eq(-1, meths.get_var("buffer_executed")) + it('can pass the buffer', function() + api.nvim_set_var('buffer_executed', -1) + eq(-1, api.nvim_get_var('buffer_executed')) - meths.create_autocmd("BufLeave", { - pattern = "*", + api.nvim_create_autocmd('BufLeave', { + pattern = '*', command = 'let g:buffer_executed = +expand("<abuf>")', }) -- Doesn't execute for other non-matching events - meths.exec_autocmds("CursorHold", { buffer = 1 }) - eq(-1, meths.get_var("buffer_executed")) + api.nvim_exec_autocmds('CursorHold', { buffer = 1 }) + eq(-1, api.nvim_get_var('buffer_executed')) - meths.exec_autocmds("BufLeave", { buffer = 1 }) - eq(1, meths.get_var("buffer_executed")) + api.nvim_exec_autocmds('BufLeave', { buffer = 1 }) + eq(1, api.nvim_get_var('buffer_executed')) end) - it("can pass the filename, pattern match", function() - meths.set_var("filename_executed", 'none') - eq('none', meths.get_var("filename_executed")) + it('can pass the filename, pattern match', function() + api.nvim_set_var('filename_executed', 'none') + eq('none', api.nvim_get_var('filename_executed')) - meths.create_autocmd("BufEnter", { - pattern = "*.py", + api.nvim_create_autocmd('BufEnter', { + pattern = '*.py', command = 'let g:filename_executed = expand("<afile>")', }) -- Doesn't execute for other non-matching events - meths.exec_autocmds("CursorHold", { buffer = 1 }) - eq('none', meths.get_var("filename_executed")) + api.nvim_exec_autocmds('CursorHold', { buffer = 1 }) + eq('none', api.nvim_get_var('filename_executed')) - meths.command('edit __init__.py') - eq('__init__.py', meths.get_var("filename_executed")) + command('edit __init__.py') + eq('__init__.py', api.nvim_get_var('filename_executed')) end) it('cannot pass buf and fname', function() - local ok = pcall(meths.exec_autocmds, "BufReadPre", { pattern = "literally_cannot_error.rs", buffer = 1 }) + local ok = pcall( + api.nvim_exec_autocmds, + 'BufReadPre', + { pattern = 'literally_cannot_error.rs', buffer = 1 } + ) eq(false, ok) end) - it("can pass the filename, exact match", function() - meths.set_var("filename_executed", 'none') - eq('none', meths.get_var("filename_executed")) + it('can pass the filename, exact match', function() + api.nvim_set_var('filename_executed', 'none') + eq('none', api.nvim_get_var('filename_executed')) - meths.command('edit other_file.txt') - meths.command('edit __init__.py') - eq('none', meths.get_var("filename_executed")) + command('edit other_file.txt') + command('edit __init__.py') + eq('none', api.nvim_get_var('filename_executed')) - meths.create_autocmd("CursorHoldI", { - pattern = "__init__.py", + api.nvim_create_autocmd('CursorHoldI', { + pattern = '__init__.py', command = 'let g:filename_executed = expand("<afile>")', }) -- Doesn't execute for other non-matching events - meths.exec_autocmds("CursorHoldI", { buffer = 1 }) - eq('none', meths.get_var("filename_executed")) + api.nvim_exec_autocmds('CursorHoldI', { buffer = 1 }) + eq('none', api.nvim_get_var('filename_executed')) - meths.exec_autocmds("CursorHoldI", { buffer = meths.get_current_buf() }) - eq('__init__.py', meths.get_var("filename_executed")) + api.nvim_exec_autocmds('CursorHoldI', { buffer = api.nvim_get_current_buf() }) + eq('__init__.py', api.nvim_get_var('filename_executed')) -- Reset filename - meths.set_var("filename_executed", 'none') + api.nvim_set_var('filename_executed', 'none') - meths.exec_autocmds("CursorHoldI", { pattern = '__init__.py' }) - eq('__init__.py', meths.get_var("filename_executed")) + api.nvim_exec_autocmds('CursorHoldI', { pattern = '__init__.py' }) + eq('__init__.py', api.nvim_get_var('filename_executed')) end) - it("works with user autocmds", function() - meths.set_var("matched", 'none') + it('works with user autocmds', function() + api.nvim_set_var('matched', 'none') - meths.create_autocmd("User", { - pattern = "TestCommand", - command = 'let g:matched = "matched"' + api.nvim_create_autocmd('User', { + pattern = 'TestCommand', + command = 'let g:matched = "matched"', }) - meths.exec_autocmds("User", { pattern = "OtherCommand" }) - eq('none', meths.get_var('matched')) - meths.exec_autocmds("User", { pattern = "TestCommand" }) - eq('matched', meths.get_var('matched')) + api.nvim_exec_autocmds('User', { pattern = 'OtherCommand' }) + eq('none', api.nvim_get_var('matched')) + api.nvim_exec_autocmds('User', { pattern = 'TestCommand' }) + eq('matched', api.nvim_get_var('matched')) end) it('can pass group by id', function() - meths.set_var("group_executed", false) + api.nvim_set_var('group_executed', false) - local auid = meths.create_augroup("nvim_test_augroup", { clear = true }) - meths.create_autocmd("FileType", { + local auid = api.nvim_create_augroup('nvim_test_augroup', { clear = true }) + api.nvim_create_autocmd('FileType', { group = auid, command = 'let g:group_executed = v:true', }) - eq(false, meths.get_var("group_executed")) - meths.exec_autocmds("FileType", { group = auid }) - eq(true, meths.get_var("group_executed")) + eq(false, api.nvim_get_var('group_executed')) + api.nvim_exec_autocmds('FileType', { group = auid }) + eq(true, api.nvim_get_var('group_executed')) end) it('can pass group by name', function() - meths.set_var("group_executed", false) + api.nvim_set_var('group_executed', false) - local auname = "nvim_test_augroup" - meths.create_augroup(auname, { clear = true }) - meths.create_autocmd("FileType", { + local auname = 'nvim_test_augroup' + api.nvim_create_augroup(auname, { clear = true }) + api.nvim_create_autocmd('FileType', { group = auname, command = 'let g:group_executed = v:true', }) - eq(false, meths.get_var("group_executed")) - meths.exec_autocmds("FileType", { group = auname }) - eq(true, meths.get_var("group_executed")) + eq(false, api.nvim_get_var('group_executed')) + api.nvim_exec_autocmds('FileType', { group = auname }) + eq(true, api.nvim_get_var('group_executed')) end) end) @@ -896,39 +1026,39 @@ describe('autocmd api', function() before_each(function() clear() - meths.set_var('executed', 0) + api.nvim_set_var('executed', 0) end) local make_counting_autocmd = function(opts) opts = opts or {} local resulting = { - pattern = "*", - command = "let g:executed = g:executed + 1", + pattern = '*', + command = 'let g:executed = g:executed + 1', } resulting.group = opts.group resulting.once = opts.once - meths.create_autocmd("FileType", resulting) + api.nvim_create_autocmd('FileType', resulting) end local set_ft = function(ft) - ft = ft or "txt" - source(string.format("set filetype=%s", ft)) + ft = ft or 'txt' + source(string.format('set filetype=%s', ft)) end local get_executed_count = function() - return meths.get_var('executed') + return api.nvim_get_var('executed') end it('can be added in a group', function() - local augroup = "TestGroup" - meths.create_augroup(augroup, { clear = true }) + local augroup = 'TestGroup' + api.nvim_create_augroup(augroup, { clear = true }) make_counting_autocmd { group = augroup } - set_ft("txt") - set_ft("python") + set_ft('txt') + set_ft('python') eq(2, get_executed_count()) end) @@ -943,7 +1073,7 @@ describe('autocmd api', function() end) it('handles ++once', function() - make_counting_autocmd {once = true} + make_counting_autocmd { once = true } set_ft('txt') set_ft('help') set_ft('txt') @@ -953,9 +1083,9 @@ describe('autocmd api', function() end) it('errors on unexpected keys', function() - local success, code = pcall(meths.create_autocmd, "FileType", { - pattern = "*", - not_a_valid_key = "NotDefined", + local success, code = pcall(api.nvim_create_autocmd, 'FileType', { + pattern = '*', + not_a_valid_key = 'NotDefined', }) eq(false, success) @@ -963,24 +1093,35 @@ describe('autocmd api', function() end) it('can execute simple callback', function() - exec_lua([[ + exec_lua( + [[ vim.g.executed = false vim.api.nvim_create_autocmd("FileType", { pattern = "*", callback = function() vim.g.executed = true end, }) - ]], {}) - - - eq(true, exec_lua([[ + ]], + {} + ) + + eq( + true, + exec_lua( + [[ vim.cmd "set filetype=txt" return vim.g.executed - ]], {})) + ]], + {} + ) + ) end) it('calls multiple lua callbacks for the same autocmd execution', function() - eq(4, exec_lua([[ + eq( + 4, + exec_lua( + [[ local count = 0 local counter = function() count = count + 1 @@ -1000,7 +1141,10 @@ describe('autocmd api', function() vim.cmd "set filetype=txt" return count - ]], {})) + ]], + {} + ) + ) end) it('properly releases functions with ++once', function() @@ -1030,108 +1174,112 @@ describe('autocmd api', function() command [[set filetype=txt]] eq(1, exec_lua([[return OnceCount]], {})) - eq(0, exec_lua([[ + eq( + 0, + exec_lua([[ local count = 0 for _ in pairs(WeakTable) do count = count + 1 end return count - ]]), "Should have no keys remaining") + ]]), + 'Should have no keys remaining' + ) end) it('groups can be cleared', function() - local augroup = "TestGroup" - meths.create_augroup(augroup, { clear = true }) - meths.create_autocmd("FileType", { + local augroup = 'TestGroup' + api.nvim_create_augroup(augroup, { clear = true }) + api.nvim_create_autocmd('FileType', { group = augroup, - command = "let g:executed = g:executed + 1" + command = 'let g:executed = g:executed + 1', }) - set_ft("txt") - set_ft("txt") - eq(2, get_executed_count(), "should only count twice") + set_ft('txt') + set_ft('txt') + eq(2, get_executed_count(), 'should only count twice') - meths.create_augroup(augroup, { clear = true }) - eq({}, meths.get_autocmds { group = augroup }) + api.nvim_create_augroup(augroup, { clear = true }) + eq({}, api.nvim_get_autocmds { group = augroup }) - set_ft("txt") - set_ft("txt") - eq(2, get_executed_count(), "No additional counts") + set_ft('txt') + set_ft('txt') + eq(2, get_executed_count(), 'No additional counts') end) it('can delete non-existent groups with pcall', function() - eq(false, exec_lua[[return pcall(vim.api.nvim_del_augroup_by_name, 'noexist')]]) - eq('Vim:E367: No such group: "noexist"', pcall_err(meths.del_augroup_by_name, 'noexist')) + eq(false, exec_lua [[return pcall(vim.api.nvim_del_augroup_by_name, 'noexist')]]) + eq('Vim:E367: No such group: "noexist"', pcall_err(api.nvim_del_augroup_by_name, 'noexist')) - eq(false, exec_lua[[return pcall(vim.api.nvim_del_augroup_by_id, -12342)]]) - eq('Vim:E367: No such group: "--Deleted--"', pcall_err(meths.del_augroup_by_id, -12312)) + eq(false, exec_lua [[return pcall(vim.api.nvim_del_augroup_by_id, -12342)]]) + eq('Vim:E367: No such group: "--Deleted--"', pcall_err(api.nvim_del_augroup_by_id, -12312)) - eq(false, exec_lua[[return pcall(vim.api.nvim_del_augroup_by_id, 0)]]) - eq('Vim:E367: No such group: "[NULL]"', pcall_err(meths.del_augroup_by_id, 0)) + eq(false, exec_lua [[return pcall(vim.api.nvim_del_augroup_by_id, 0)]]) + eq('Vim:E367: No such group: "[NULL]"', pcall_err(api.nvim_del_augroup_by_id, 0)) - eq(false, exec_lua[[return pcall(vim.api.nvim_del_augroup_by_id, 12342)]]) - eq('Vim:E367: No such group: "[NULL]"', pcall_err(meths.del_augroup_by_id, 12312)) + eq(false, exec_lua [[return pcall(vim.api.nvim_del_augroup_by_id, 12342)]]) + eq('Vim:E367: No such group: "[NULL]"', pcall_err(api.nvim_del_augroup_by_id, 12312)) end) it('groups work with once', function() - local augroup = "TestGroup" + local augroup = 'TestGroup' - meths.create_augroup(augroup, { clear = true }) + api.nvim_create_augroup(augroup, { clear = true }) make_counting_autocmd { group = augroup, once = true } - set_ft("txt") - set_ft("python") + set_ft('txt') + set_ft('python') eq(1, get_executed_count()) end) it('autocmds can be registered multiple times.', function() - local augroup = "TestGroup" + local augroup = 'TestGroup' - meths.create_augroup(augroup, { clear = true }) + api.nvim_create_augroup(augroup, { clear = true }) make_counting_autocmd { group = augroup, once = false } make_counting_autocmd { group = augroup, once = false } make_counting_autocmd { group = augroup, once = false } - set_ft("txt") - set_ft("python") + set_ft('txt') + set_ft('python') eq(3 * 2, get_executed_count()) end) it('can be deleted', function() - local augroup = "WillBeDeleted" + local augroup = 'WillBeDeleted' - meths.create_augroup(augroup, { clear = true }) - meths.create_autocmd({"FileType"}, { - pattern = "*", + api.nvim_create_augroup(augroup, { clear = true }) + api.nvim_create_autocmd({ 'FileType' }, { + pattern = '*', command = "echo 'does not matter'", }) -- Clears the augroup from before, which erases the autocmd - meths.create_augroup(augroup, { clear = true }) + api.nvim_create_augroup(augroup, { clear = true }) - local result = #meths.get_autocmds { group = augroup } + local result = #api.nvim_get_autocmds { group = augroup } eq(0, result) end) it('can be used for buffer local autocmds', function() - local augroup = "WillBeDeleted" + local augroup = 'WillBeDeleted' - meths.set_var("value_set", false) + api.nvim_set_var('value_set', false) - meths.create_augroup(augroup, { clear = true }) - meths.create_autocmd("FileType", { - pattern = "<buffer>", - command = "let g:value_set = v:true", + api.nvim_create_augroup(augroup, { clear = true }) + api.nvim_create_autocmd('FileType', { + pattern = '<buffer>', + command = 'let g:value_set = v:true', }) - command "new" - command "set filetype=python" + command 'new' + command 'set filetype=python' - eq(false, meths.get_var("value_set")) + eq(false, api.nvim_get_var('value_set')) end) it('can accept vimscript functions', function() @@ -1154,118 +1302,124 @@ describe('autocmd api', function() set filetype=txt ]] - eq(2, meths.get_var("vimscript_executed")) + eq(2, api.nvim_get_var('vimscript_executed')) end) end) describe('augroup!', function() it('legacy: should clear and not return any autocmds for delete groups', function() - command('augroup TEMP_A') - command(' autocmd! BufReadPost *.py :echo "Hello"') - command('augroup END') + command('augroup TEMP_A') + command(' autocmd! BufReadPost *.py :echo "Hello"') + command('augroup END') - command('augroup! TEMP_A') + command('augroup! TEMP_A') - eq(false, pcall(meths.get_autocmds, { group = 'TEMP_A' })) + eq(false, pcall(api.nvim_get_autocmds, { group = 'TEMP_A' })) - -- For some reason, augroup! doesn't clear the autocmds themselves, which is just wild - -- but we managed to keep this behavior. - eq(1, #meths.get_autocmds { event = 'BufReadPost' }) + -- For some reason, augroup! doesn't clear the autocmds themselves, which is just wild + -- but we managed to keep this behavior. + eq(1, #api.nvim_get_autocmds { event = 'BufReadPost' }) end) it('legacy: remove augroups that have no autocmds', function() - command('augroup TEMP_AB') - command('augroup END') + command('augroup TEMP_AB') + command('augroup END') - command('augroup! TEMP_AB') + command('augroup! TEMP_AB') - eq(false, pcall(meths.get_autocmds, { group = 'TEMP_AB' })) - eq(0, #meths.get_autocmds { event = 'BufReadPost' }) + eq(false, pcall(api.nvim_get_autocmds, { group = 'TEMP_AB' })) + eq(0, #api.nvim_get_autocmds { event = 'BufReadPost' }) end) it('legacy: multiple remove and add augroup', function() - command('augroup TEMP_ABC') - command(' au!') - command(' autocmd BufReadPost *.py echo "Hello"') - command('augroup END') + command('augroup TEMP_ABC') + command(' au!') + command(' autocmd BufReadPost *.py echo "Hello"') + command('augroup END') - command('augroup! TEMP_ABC') + command('augroup! TEMP_ABC') - -- Should still have one autocmd :'( - local aus = meths.get_autocmds { event = 'BufReadPost' } - eq(1, #aus, aus) + -- Should still have one autocmd :'( + local aus = api.nvim_get_autocmds { event = 'BufReadPost' } + eq(1, #aus, aus) - command('augroup TEMP_ABC') - command(' au!') - command(' autocmd BufReadPost *.py echo "Hello"') - command('augroup END') + command('augroup TEMP_ABC') + command(' au!') + command(' autocmd BufReadPost *.py echo "Hello"') + command('augroup END') - -- Should now have two autocmds :'( - aus = meths.get_autocmds { event = 'BufReadPost' } - eq(2, #aus, aus) + -- Should now have two autocmds :'( + aus = api.nvim_get_autocmds { event = 'BufReadPost' } + eq(2, #aus, aus) - command('augroup! TEMP_ABC') + command('augroup! TEMP_ABC') - eq(false, pcall(meths.get_autocmds, { group = 'TEMP_ABC' })) - eq(2, #meths.get_autocmds { event = 'BufReadPost' }) + eq(false, pcall(api.nvim_get_autocmds, { group = 'TEMP_ABC' })) + eq(2, #api.nvim_get_autocmds { event = 'BufReadPost' }) end) it('api: should clear and not return any autocmds for delete groups by id', function() - command('augroup TEMP_ABCD') - command('autocmd! BufReadPost *.py :echo "Hello"') - command('augroup END') + command('augroup TEMP_ABCD') + command('autocmd! BufReadPost *.py :echo "Hello"') + command('augroup END') - local augroup_id = meths.create_augroup("TEMP_ABCD", { clear = false }) - meths.del_augroup_by_id(augroup_id) + local augroup_id = api.nvim_create_augroup('TEMP_ABCD', { clear = false }) + api.nvim_del_augroup_by_id(augroup_id) - -- For good reason, we kill all the autocmds from del_augroup, - -- so now this works as expected - eq(false, pcall(meths.get_autocmds, { group = 'TEMP_ABCD' })) - eq(0, #meths.get_autocmds { event = 'BufReadPost' }) + -- For good reason, we kill all the autocmds from del_augroup, + -- so now this works as expected + eq(false, pcall(api.nvim_get_autocmds, { group = 'TEMP_ABCD' })) + eq(0, #api.nvim_get_autocmds { event = 'BufReadPost' }) end) it('api: should clear and not return any autocmds for delete groups by name', function() - command('augroup TEMP_ABCDE') - command('autocmd! BufReadPost *.py :echo "Hello"') - command('augroup END') + command('augroup TEMP_ABCDE') + command('autocmd! BufReadPost *.py :echo "Hello"') + command('augroup END') - meths.del_augroup_by_name("TEMP_ABCDE") + api.nvim_del_augroup_by_name('TEMP_ABCDE') - -- For good reason, we kill all the autocmds from del_augroup, - -- so now this works as expected - eq(false, pcall(meths.get_autocmds, { group = 'TEMP_ABCDE' })) - eq(0, #meths.get_autocmds { event = 'BufReadPost' }) + -- For good reason, we kill all the autocmds from del_augroup, + -- so now this works as expected + eq(false, pcall(api.nvim_get_autocmds, { group = 'TEMP_ABCDE' })) + eq(0, #api.nvim_get_autocmds { event = 'BufReadPost' }) end) end) describe('nvim_clear_autocmds', function() it('validation', function() - eq("Cannot use both 'pattern' and 'buffer'", pcall_err(meths.clear_autocmds, { - pattern = '*', - buffer = 42, - })) - eq("Invalid 'event' item: expected String, got Array", pcall_err(meths.clear_autocmds, { - event = {'FileType', {}} - })) - eq("Invalid 'group': 0", pcall_err(meths.clear_autocmds, {group = 0})) + eq( + "Cannot use both 'pattern' and 'buffer'", + pcall_err(api.nvim_clear_autocmds, { + pattern = '*', + buffer = 42, + }) + ) + eq( + "Invalid 'event' item: expected String, got Array", + pcall_err(api.nvim_clear_autocmds, { + event = { 'FileType', {} }, + }) + ) + eq("Invalid 'group': 0", pcall_err(api.nvim_clear_autocmds, { group = 0 })) end) it('should clear based on event + pattern', function() command('autocmd InsertEnter *.py :echo "Python can be cool sometimes"') command('autocmd InsertEnter *.txt :echo "Text Files Are Cool"') - local search = { event = "InsertEnter", pattern = "*.txt" } - local before_delete = meths.get_autocmds(search) + local search = { event = 'InsertEnter', pattern = '*.txt' } + local before_delete = api.nvim_get_autocmds(search) eq(1, #before_delete) - local before_delete_all = meths.get_autocmds { event = search.event } + local before_delete_all = api.nvim_get_autocmds { event = search.event } eq(2, #before_delete_all) - meths.clear_autocmds(search) - local after_delete = meths.get_autocmds(search) + api.nvim_clear_autocmds(search) + local after_delete = api.nvim_get_autocmds(search) eq(0, #after_delete) - local after_delete_all = meths.get_autocmds { event = search.event } + local after_delete_all = api.nvim_get_autocmds { event = search.event } eq(1, #after_delete_all) end) @@ -1273,12 +1427,12 @@ describe('autocmd api', function() command('autocmd InsertEnter *.py :echo "Python can be cool sometimes"') command('autocmd InsertEnter *.txt :echo "Text Files Are Cool"') - local search = { event = "InsertEnter"} - local before_delete = meths.get_autocmds(search) + local search = { event = 'InsertEnter' } + local before_delete = api.nvim_get_autocmds(search) eq(2, #before_delete) - meths.clear_autocmds(search) - local after_delete = meths.get_autocmds(search) + api.nvim_clear_autocmds(search) + local after_delete = api.nvim_get_autocmds(search) eq(0, #after_delete) end) @@ -1288,17 +1442,18 @@ describe('autocmd api', function() command('autocmd InsertEnter *.TestPat2 :echo "Enter 2"') command('autocmd InsertLeave *.TestPat2 :echo "Leave 2"') - local search = { pattern = "*.TestPat1"} - local before_delete = meths.get_autocmds(search) + local search = { pattern = '*.TestPat1' } + local before_delete = api.nvim_get_autocmds(search) eq(2, #before_delete) - local before_delete_events = meths.get_autocmds { event = { "InsertEnter", "InsertLeave" } } + local before_delete_events = + api.nvim_get_autocmds { event = { 'InsertEnter', 'InsertLeave' } } eq(4, #before_delete_events) - meths.clear_autocmds(search) - local after_delete = meths.get_autocmds(search) + api.nvim_clear_autocmds(search) + local after_delete = api.nvim_get_autocmds(search) eq(0, #after_delete) - local after_delete_events = meths.get_autocmds { event = { "InsertEnter", "InsertLeave" } } + local after_delete_events = api.nvim_get_autocmds { event = { 'InsertEnter', 'InsertLeave' } } eq(2, #after_delete_events) end) @@ -1307,14 +1462,14 @@ describe('autocmd api', function() command('autocmd InsertEnter <buffer> :echo "Enter Buffer"') command('autocmd InsertEnter *.TestPat1 :echo "Enter Pattern"') - local search = { event = "InsertEnter" } - local before_delete = meths.get_autocmds(search) + local search = { event = 'InsertEnter' } + local before_delete = api.nvim_get_autocmds(search) eq(2, #before_delete) - meths.clear_autocmds { buffer = 0 } - local after_delete = meths.get_autocmds(search) + api.nvim_clear_autocmds { buffer = 0 } + local after_delete = api.nvim_get_autocmds(search) eq(1, #after_delete) - eq("*.TestPat1", after_delete[1].pattern) + eq('*.TestPat1', after_delete[1].pattern) end) it('should allow clearing by buffer and group', function() @@ -1324,18 +1479,18 @@ describe('autocmd api', function() command(' autocmd InsertEnter *.TestPat1 :echo "Enter Pattern"') command('augroup END') - local search = { event = "InsertEnter", group = "TestNvimClearAutocmds" } - local before_delete = meths.get_autocmds(search) + local search = { event = 'InsertEnter', group = 'TestNvimClearAutocmds' } + local before_delete = api.nvim_get_autocmds(search) eq(2, #before_delete) -- Doesn't clear without passing group. - meths.clear_autocmds { buffer = 0 } - local without_group = meths.get_autocmds(search) + api.nvim_clear_autocmds { buffer = 0 } + local without_group = api.nvim_get_autocmds(search) eq(2, #without_group) -- Doesn't clear with passing group. - meths.clear_autocmds { buffer = 0, group = search.group } - local with_group = meths.get_autocmds(search) + api.nvim_clear_autocmds { buffer = 0, group = search.group } + local with_group = api.nvim_get_autocmds(search) eq(1, #with_group) end) end) diff --git a/test/functional/api/buffer_spec.lua b/test/functional/api/buffer_spec.lua index 6ed9aa574a..78d220ff57 100644 --- a/test/functional/api/buffer_spec.lua +++ b/test/functional/api/buffer_spec.lua @@ -1,19 +1,18 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local clear, nvim, buffer = helpers.clear, helpers.nvim, helpers.buffer -local curbuf, curwin, eq = helpers.curbuf, helpers.curwin, helpers.eq -local curbufmeths, ok = helpers.curbufmeths, helpers.ok +local clear = helpers.clear +local eq = helpers.eq +local ok = helpers.ok local describe_lua_and_rpc = helpers.describe_lua_and_rpc(describe) -local meths = helpers.meths -local funcs = helpers.funcs +local api = helpers.api +local fn = helpers.fn local request = helpers.request local exc_exec = helpers.exc_exec local exec_lua = helpers.exec_lua local feed_command = helpers.feed_command local insert = helpers.insert -local NIL = helpers.NIL +local NIL = vim.NIL local command = helpers.command -local bufmeths = helpers.bufmeths local feed = helpers.feed local pcall_err = helpers.pcall_err local assert_alive = helpers.assert_alive @@ -23,16 +22,15 @@ describe('api/buf', function() -- access deprecated functions local function curbuf_depr(method, ...) - return request('buffer_'..method, 0, ...) + return request('buffer_' .. method, 0, ...) end - describe('nvim_buf_set_lines, nvim_buf_line_count', function() it('deprecated forms', function() eq(1, curbuf_depr('line_count')) - curbuf_depr('insert', -1, {'line'}) + curbuf_depr('insert', -1, { 'line' }) eq(2, curbuf_depr('line_count')) - curbuf_depr('insert', -1, {'line'}) + curbuf_depr('insert', -1, { 'line' }) eq(3, curbuf_depr('line_count')) curbuf_depr('del_line', -1) eq(2, curbuf_depr('line_count')) @@ -43,108 +41,114 @@ describe('api/buf', function() end) it("doesn't crash just after set undolevels=1 #24894", function() - local buf = meths.create_buf(false, true) - meths.buf_set_option(buf, 'undolevels', -1) - meths.buf_set_lines(buf, 0, 1, false, { }) + local buf = api.nvim_create_buf(false, true) + api.nvim_buf_set_option(buf, 'undolevels', -1) + api.nvim_buf_set_lines(buf, 0, 1, false, {}) assert_alive() end) it('cursor position is maintained after lines are inserted #9961', function() -- replace the buffer contents with these three lines. - request('nvim_buf_set_lines', 0, 0, -1, 1, {"line1", "line2", "line3", "line4"}) + api.nvim_buf_set_lines(0, 0, -1, true, { 'line1', 'line2', 'line3', 'line4' }) -- Set the current cursor to {3, 2}. - curwin('set_cursor', {3, 2}) + api.nvim_win_set_cursor(0, { 3, 2 }) -- add 2 lines and delete 1 line above the current cursor position. - request('nvim_buf_set_lines', 0, 1, 2, 1, {"line5", "line6"}) + api.nvim_buf_set_lines(0, 1, 2, true, { 'line5', 'line6' }) -- check the current set of lines in the buffer. - eq({"line1", "line5", "line6", "line3", "line4"}, buffer('get_lines', 0, 0, -1, 1)) + eq({ 'line1', 'line5', 'line6', 'line3', 'line4' }, api.nvim_buf_get_lines(0, 0, -1, true)) -- cursor should be moved below by 1 line. - eq({4, 2}, curwin('get_cursor')) + eq({ 4, 2 }, api.nvim_win_get_cursor(0)) -- add a line after the current cursor position. - request('nvim_buf_set_lines', 0, 5, 5, 1, {"line7"}) + api.nvim_buf_set_lines(0, 5, 5, true, { 'line7' }) -- check the current set of lines in the buffer. - eq({"line1", "line5", "line6", "line3", "line4", "line7"}, buffer('get_lines', 0, 0, -1, 1)) + eq( + { 'line1', 'line5', 'line6', 'line3', 'line4', 'line7' }, + api.nvim_buf_get_lines(0, 0, -1, true) + ) -- cursor position is unchanged. - eq({4, 2}, curwin('get_cursor')) + eq({ 4, 2 }, api.nvim_win_get_cursor(0)) -- overwrite current cursor line. - request('nvim_buf_set_lines', 0, 3, 5, 1, {"line8", "line9"}) + api.nvim_buf_set_lines(0, 3, 5, true, { 'line8', 'line9' }) -- check the current set of lines in the buffer. - eq({"line1", "line5", "line6", "line8", "line9", "line7"}, buffer('get_lines', 0, 0, -1, 1)) + eq( + { 'line1', 'line5', 'line6', 'line8', 'line9', 'line7' }, + api.nvim_buf_get_lines(0, 0, -1, true) + ) -- cursor position is unchanged. - eq({4, 2}, curwin('get_cursor')) + eq({ 4, 2 }, api.nvim_win_get_cursor(0)) -- delete current cursor line. - request('nvim_buf_set_lines', 0, 3, 5, 1, {}) + api.nvim_buf_set_lines(0, 3, 5, true, {}) -- check the current set of lines in the buffer. - eq({"line1", "line5", "line6", "line7"}, buffer('get_lines', 0, 0, -1, 1)) + eq({ 'line1', 'line5', 'line6', 'line7' }, api.nvim_buf_get_lines(0, 0, -1, true)) -- cursor position is unchanged. - eq({4, 2}, curwin('get_cursor')) + eq({ 4, 2 }, api.nvim_win_get_cursor(0)) end) it('cursor position is maintained in non-current window', function() - meths.buf_set_lines(0, 0, -1, 1, {"line1", "line2", "line3", "line4"}) - meths.win_set_cursor(0, {3, 2}) - local win = meths.get_current_win() - local buf = meths.get_current_buf() + api.nvim_buf_set_lines(0, 0, -1, true, { 'line1', 'line2', 'line3', 'line4' }) + api.nvim_win_set_cursor(0, { 3, 2 }) + local win = api.nvim_get_current_win() + local buf = api.nvim_get_current_buf() command('new') - meths.buf_set_lines(buf, 1, 2, 1, {"line5", "line6"}) - eq({"line1", "line5", "line6", "line3", "line4"}, meths.buf_get_lines(buf, 0, -1, true)) - eq({4, 2}, meths.win_get_cursor(win)) + api.nvim_buf_set_lines(buf, 1, 2, true, { 'line5', 'line6' }) + eq({ 'line1', 'line5', 'line6', 'line3', 'line4' }, api.nvim_buf_get_lines(buf, 0, -1, true)) + eq({ 4, 2 }, api.nvim_win_get_cursor(win)) end) it('cursor position is maintained in TWO non-current windows', function() - meths.buf_set_lines(0, 0, -1, 1, {"line1", "line2", "line3", "line4"}) - meths.win_set_cursor(0, {3, 2}) - local win = meths.get_current_win() - local buf = meths.get_current_buf() + api.nvim_buf_set_lines(0, 0, -1, true, { 'line1', 'line2', 'line3', 'line4' }) + api.nvim_win_set_cursor(0, { 3, 2 }) + local win = api.nvim_get_current_win() + local buf = api.nvim_get_current_buf() command('split') - meths.win_set_cursor(0, {4, 2}) - local win2 = meths.get_current_win() + api.nvim_win_set_cursor(0, { 4, 2 }) + local win2 = api.nvim_get_current_win() -- set current window to third one with another buffer - command("new") + command('new') - meths.buf_set_lines(buf, 1, 2, 1, {"line5", "line6"}) - eq({"line1", "line5", "line6", "line3", "line4"}, meths.buf_get_lines(buf, 0, -1, true)) - eq({4, 2}, meths.win_get_cursor(win)) - eq({5, 2}, meths.win_get_cursor(win2)) + api.nvim_buf_set_lines(buf, 1, 2, true, { 'line5', 'line6' }) + eq({ 'line1', 'line5', 'line6', 'line3', 'line4' }, api.nvim_buf_get_lines(buf, 0, -1, true)) + eq({ 4, 2 }, api.nvim_win_get_cursor(win)) + eq({ 5, 2 }, api.nvim_win_get_cursor(win2)) end) it('line_count has defined behaviour for unloaded buffers', function() -- we'll need to know our bufnr for when it gets unloaded - local bufnr = curbuf('get_number') + local bufnr = api.nvim_buf_get_number(0) -- replace the buffer contents with these three lines - request('nvim_buf_set_lines', bufnr, 0, -1, 1, {"line1", "line2", "line3", "line4"}) + api.nvim_buf_set_lines(bufnr, 0, -1, true, { 'line1', 'line2', 'line3', 'line4' }) -- check the line count is correct - eq(4, request('nvim_buf_line_count', bufnr)) + eq(4, api.nvim_buf_line_count(bufnr)) -- force unload the buffer (this will discard changes) command('new') - command('bunload! '..bufnr) + command('bunload! ' .. bufnr) -- line count for an unloaded buffer should always be 0 - eq(0, request('nvim_buf_line_count', bufnr)) + eq(0, api.nvim_buf_line_count(bufnr)) end) it('get_lines has defined behaviour for unloaded buffers', function() -- we'll need to know our bufnr for when it gets unloaded - local bufnr = curbuf('get_number') + local bufnr = api.nvim_buf_get_number(0) -- replace the buffer contents with these three lines - buffer('set_lines', bufnr, 0, -1, 1, {"line1", "line2", "line3", "line4"}) + api.nvim_buf_set_lines(bufnr, 0, -1, true, { 'line1', 'line2', 'line3', 'line4' }) -- confirm that getting lines works - eq({"line2", "line3"}, buffer('get_lines', bufnr, 1, 3, 1)) + eq({ 'line2', 'line3' }, api.nvim_buf_get_lines(bufnr, 1, 3, true)) -- force unload the buffer (this will discard changes) command('new') - command('bunload! '..bufnr) + command('bunload! ' .. bufnr) -- attempting to get lines now always gives empty list - eq({}, buffer('get_lines', bufnr, 1, 3, 1)) + eq({}, api.nvim_buf_get_lines(bufnr, 1, 3, true)) -- it's impossible to get out-of-bounds errors for an unloaded buffer - eq({}, buffer('get_lines', bufnr, 8888, 9999, 1)) + eq({}, api.nvim_buf_get_lines(bufnr, 8888, 9999, true)) end) describe('handles topline', function() @@ -152,28 +156,32 @@ describe('api/buf', function() before_each(function() screen = Screen.new(20, 12) screen:set_default_attr_ids { - [1] = {bold = true, foreground = Screen.colors.Blue1}; - [2] = {reverse = true, bold = true}; - [3] = {reverse = true}; + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { reverse = true, bold = true }, + [3] = { reverse = true }, } screen:attach() - meths.buf_set_lines(0, 0, -1, 1, {"aaa", "bbb", "ccc", "ddd", "www", "xxx", "yyy", "zzz"}) - meths.set_option_value('modified', false, {}) + api.nvim_buf_set_lines( + 0, + 0, + -1, + true, + { 'aaa', 'bbb', 'ccc', 'ddd', 'www', 'xxx', 'yyy', 'zzz' } + ) + api.nvim_set_option_value('modified', false, {}) end) it('of current window', function() - local win = meths.get_current_win() - local buf = meths.get_current_buf() + local win = api.nvim_get_current_win() + local buf = api.nvim_get_current_buf() command('new | wincmd w') - meths.win_set_cursor(win, {8,0}) + api.nvim_win_set_cursor(win, { 8, 0 }) - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {3:[No Name] }| www | xxx | @@ -181,15 +189,14 @@ describe('api/buf', function() ^zzz | {2:[No Name] }| | - ]]} + ]], + } - meths.buf_set_lines(buf, 0, 2, true, {"aaabbb"}) - screen:expect{grid=[[ + api.nvim_buf_set_lines(buf, 0, 2, true, { 'aaabbb' }) + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {3:[No Name] }| www | xxx | @@ -197,16 +204,15 @@ describe('api/buf', function() ^zzz | {2:[No Name] [+] }| | - ]]} + ]], + } -- replacing topline keeps it the topline - meths.buf_set_lines(buf, 3, 4, true, {"wwweeee"}) - screen:expect{grid=[[ + api.nvim_buf_set_lines(buf, 3, 4, true, { 'wwweeee' }) + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {3:[No Name] }| wwweeee | xxx | @@ -214,16 +220,15 @@ describe('api/buf', function() ^zzz | {2:[No Name] [+] }| | - ]]} + ]], + } -- inserting just before topline does not scroll up if cursor would be moved - meths.buf_set_lines(buf, 3, 3, true, {"mmm"}) - screen:expect{grid=[[ + api.nvim_buf_set_lines(buf, 3, 3, true, { 'mmm' }) + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {3:[No Name] }| wwweeee | xxx | @@ -231,15 +236,15 @@ describe('api/buf', function() ^zzz | {2:[No Name] [+] }| | - ]], unchanged=true} + ]], + unchanged = true, + } - meths.win_set_cursor(0, {7, 0}) - screen:expect{grid=[[ + api.nvim_win_set_cursor(0, { 7, 0 }) + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {3:[No Name] }| wwweeee | xxx | @@ -247,15 +252,14 @@ describe('api/buf', function() zzz | {2:[No Name] [+] }| | - ]]} + ]], + } - meths.buf_set_lines(buf, 4, 4, true, {"mmmeeeee"}) - screen:expect{grid=[[ + api.nvim_buf_set_lines(buf, 4, 4, true, { 'mmmeeeee' }) + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {3:[No Name] }| mmmeeeee | wwweeee | @@ -263,22 +267,21 @@ describe('api/buf', function() ^yyy | {2:[No Name] [+] }| | - ]]} + ]], + } end) it('of non-current window', function() - local win = meths.get_current_win() - local buf = meths.get_current_buf() + local win = api.nvim_get_current_win() + local buf = api.nvim_get_current_buf() command('new') - meths.win_set_cursor(win, {8,0}) + api.nvim_win_set_cursor(win, { 8, 0 }) - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {2:[No Name] }| www | xxx | @@ -286,15 +289,14 @@ describe('api/buf', function() zzz | {3:[No Name] }| | - ]]} + ]], + } - meths.buf_set_lines(buf, 0, 2, true, {"aaabbb"}) - screen:expect{grid=[[ + api.nvim_buf_set_lines(buf, 0, 2, true, { 'aaabbb' }) + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {2:[No Name] }| www | xxx | @@ -302,16 +304,15 @@ describe('api/buf', function() zzz | {3:[No Name] [+] }| | - ]]} + ]], + } -- replacing topline keeps it the topline - meths.buf_set_lines(buf, 3, 4, true, {"wwweeee"}) - screen:expect{grid=[[ + api.nvim_buf_set_lines(buf, 3, 4, true, { 'wwweeee' }) + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {2:[No Name] }| wwweeee | xxx | @@ -319,16 +320,15 @@ describe('api/buf', function() zzz | {3:[No Name] [+] }| | - ]]} + ]], + } -- inserting just before topline scrolls up - meths.buf_set_lines(buf, 3, 3, true, {"mmm"}) - screen:expect{grid=[[ + api.nvim_buf_set_lines(buf, 3, 3, true, { 'mmm' }) + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {2:[No Name] }| mmm | wwweeee | @@ -336,18 +336,20 @@ describe('api/buf', function() yyy | {3:[No Name] [+] }| | - ]]} + ]], + } end) it('of split windows with same buffer', function() - local win = meths.get_current_win() - local buf = meths.get_current_buf() + local win = api.nvim_get_current_win() + local buf = api.nvim_get_current_buf() command('split') - meths.win_set_cursor(win, {8,0}) - meths.win_set_cursor(0, {1,0}) + api.nvim_win_set_cursor(win, { 8, 0 }) + api.nvim_win_set_cursor(0, { 1, 0 }) - screen:expect{grid=[[ + screen:expect { + grid = [[ ^aaa | bbb | ccc | @@ -360,10 +362,12 @@ describe('api/buf', function() zzz | {3:[No Name] }| | - ]]} - meths.buf_set_lines(buf, 0, 2, true, {"aaabbb"}) + ]], + } + api.nvim_buf_set_lines(buf, 0, 2, true, { 'aaabbb' }) - screen:expect{grid=[[ + screen:expect { + grid = [[ ^aaabbb | ccc | ddd | @@ -376,11 +380,13 @@ describe('api/buf', function() zzz | {3:[No Name] [+] }| | - ]]} + ]], + } -- replacing topline keeps it the topline - meths.buf_set_lines(buf, 3, 4, true, {"wwweeee"}) - screen:expect{grid=[[ + api.nvim_buf_set_lines(buf, 3, 4, true, { 'wwweeee' }) + screen:expect { + grid = [[ ^aaabbb | ccc | ddd | @@ -393,11 +399,13 @@ describe('api/buf', function() zzz | {3:[No Name] [+] }| | - ]]} + ]], + } -- inserting just before topline scrolls up - meths.buf_set_lines(buf, 3, 3, true, {"mmm"}) - screen:expect{grid=[[ + api.nvim_buf_set_lines(buf, 3, 3, true, { 'mmm' }) + screen:expect { + grid = [[ ^aaabbb | ccc | ddd | @@ -410,20 +418,21 @@ describe('api/buf', function() yyy | {3:[No Name] [+] }| | - ]]} + ]], + } end) end) it('handles clearing out non-current buffer #24911', function() - local buf = meths.get_current_buf() - meths.buf_set_lines(buf, 0, -1, true, {"aaa", "bbb", "ccc"}) - command("new") + local buf = api.nvim_get_current_buf() + api.nvim_buf_set_lines(buf, 0, -1, true, { 'aaa', 'bbb', 'ccc' }) + command('new') - meths.buf_set_lines(0, 0, -1, true, {"xxx", "yyy", "zzz"}) + api.nvim_buf_set_lines(0, 0, -1, true, { 'xxx', 'yyy', 'zzz' }) - meths.buf_set_lines(buf, 0, -1, true, {}) - eq({"xxx", "yyy", "zzz"}, meths.buf_get_lines(0, 0, -1, true)) - eq({''}, meths.buf_get_lines(buf, 0, -1, true)) + api.nvim_buf_set_lines(buf, 0, -1, true, {}) + eq({ 'xxx', 'yyy', 'zzz' }, api.nvim_buf_get_lines(0, 0, -1, true)) + eq({ '' }, api.nvim_buf_get_lines(buf, 0, -1, true)) end) end) @@ -461,8 +470,8 @@ describe('api/buf', function() describe('deprecated: {get,set}_line_slice', function() it('get_line_slice: out-of-bounds returns empty array', function() - curbuf_depr('set_line_slice', 0, 0, true, true, {'a', 'b', 'c'}) - eq({'a', 'b', 'c'}, curbuf_depr('get_line_slice', 0, 2, true, true)) --sanity + curbuf_depr('set_line_slice', 0, 0, true, true, { 'a', 'b', 'c' }) + eq({ 'a', 'b', 'c' }, curbuf_depr('get_line_slice', 0, 2, true, true)) --sanity eq({}, curbuf_depr('get_line_slice', 2, 3, false, true)) eq({}, curbuf_depr('get_line_slice', 3, 9, true, true)) @@ -472,62 +481,73 @@ describe('api/buf', function() end) it('set_line_slice: out-of-bounds extends past end', function() - curbuf_depr('set_line_slice', 0, 0, true, true, {'a', 'b', 'c'}) - eq({'a', 'b', 'c'}, curbuf_depr('get_line_slice', 0, 2, true, true)) --sanity + curbuf_depr('set_line_slice', 0, 0, true, true, { 'a', 'b', 'c' }) + eq({ 'a', 'b', 'c' }, curbuf_depr('get_line_slice', 0, 2, true, true)) --sanity - eq({'c'}, curbuf_depr('get_line_slice', -1, 4, true, true)) - eq({'a', 'b', 'c'}, curbuf_depr('get_line_slice', 0, 5, true, true)) - curbuf_depr('set_line_slice', 4, 5, true, true, {'d'}) - eq({'a', 'b', 'c', 'd'}, curbuf_depr('get_line_slice', 0, 5, true, true)) - curbuf_depr('set_line_slice', -4, -5, true, true, {'e'}) - eq({'e', 'a', 'b', 'c', 'd'}, curbuf_depr('get_line_slice', 0, 5, true, true)) + eq({ 'c' }, curbuf_depr('get_line_slice', -1, 4, true, true)) + eq({ 'a', 'b', 'c' }, curbuf_depr('get_line_slice', 0, 5, true, true)) + curbuf_depr('set_line_slice', 4, 5, true, true, { 'd' }) + eq({ 'a', 'b', 'c', 'd' }, curbuf_depr('get_line_slice', 0, 5, true, true)) + curbuf_depr('set_line_slice', -4, -5, true, true, { 'e' }) + eq({ 'e', 'a', 'b', 'c', 'd' }, curbuf_depr('get_line_slice', 0, 5, true, true)) end) it('works', function() - eq({''}, curbuf_depr('get_line_slice', 0, -1, true, true)) + eq({ '' }, curbuf_depr('get_line_slice', 0, -1, true, true)) -- Replace buffer - curbuf_depr('set_line_slice', 0, -1, true, true, {'a', 'b', 'c'}) - eq({'a', 'b', 'c'}, curbuf_depr('get_line_slice', 0, -1, true, true)) - eq({'b', 'c'}, curbuf_depr('get_line_slice', 1, -1, true, true)) - eq({'b'}, curbuf_depr('get_line_slice', 1, 2, true, false)) + curbuf_depr('set_line_slice', 0, -1, true, true, { 'a', 'b', 'c' }) + eq({ 'a', 'b', 'c' }, curbuf_depr('get_line_slice', 0, -1, true, true)) + eq({ 'b', 'c' }, curbuf_depr('get_line_slice', 1, -1, true, true)) + eq({ 'b' }, curbuf_depr('get_line_slice', 1, 2, true, false)) eq({}, curbuf_depr('get_line_slice', 1, 1, true, false)) - eq({'a', 'b'}, curbuf_depr('get_line_slice', 0, -1, true, false)) - eq({'b'}, curbuf_depr('get_line_slice', 1, -1, true, false)) - eq({'b', 'c'}, curbuf_depr('get_line_slice', -2, -1, true, true)) - curbuf_depr('set_line_slice', 1, 2, true, false, {'a', 'b', 'c'}) - eq({'a', 'a', 'b', 'c', 'c'}, curbuf_depr('get_line_slice', 0, -1, true, true)) - curbuf_depr('set_line_slice', -1, -1, true, true, {'a', 'b', 'c'}) - eq({'a', 'a', 'b', 'c', 'a', 'b', 'c'}, - curbuf_depr('get_line_slice', 0, -1, true, true)) + eq({ 'a', 'b' }, curbuf_depr('get_line_slice', 0, -1, true, false)) + eq({ 'b' }, curbuf_depr('get_line_slice', 1, -1, true, false)) + eq({ 'b', 'c' }, curbuf_depr('get_line_slice', -2, -1, true, true)) + curbuf_depr('set_line_slice', 1, 2, true, false, { 'a', 'b', 'c' }) + eq({ 'a', 'a', 'b', 'c', 'c' }, curbuf_depr('get_line_slice', 0, -1, true, true)) + curbuf_depr('set_line_slice', -1, -1, true, true, { 'a', 'b', 'c' }) + eq({ 'a', 'a', 'b', 'c', 'a', 'b', 'c' }, curbuf_depr('get_line_slice', 0, -1, true, true)) curbuf_depr('set_line_slice', 0, -3, true, false, {}) - eq({'a', 'b', 'c'}, curbuf_depr('get_line_slice', 0, -1, true, true)) + eq({ 'a', 'b', 'c' }, curbuf_depr('get_line_slice', 0, -1, true, true)) curbuf_depr('set_line_slice', 0, -1, true, true, {}) - eq({''}, curbuf_depr('get_line_slice', 0, -1, true, true)) + eq({ '' }, curbuf_depr('get_line_slice', 0, -1, true, true)) end) end) - describe_lua_and_rpc('nvim_buf_get_lines, nvim_buf_set_lines', function(api) - local get_lines = api.curbufmeths.get_lines - local set_lines = api.curbufmeths.set_lines - local line_count = api.curbufmeths.line_count + describe_lua_and_rpc('nvim_buf_get_lines, nvim_buf_set_lines', function(lua_or_rpc) + local function get_lines(...) + return lua_or_rpc.nvim_buf_get_lines(0, ...) + end + + local function set_lines(...) + return lua_or_rpc.nvim_buf_set_lines(0, ...) + end + + local function line_count() + return lua_or_rpc.nvim_buf_line_count(0) + end it('fails correctly when input is not valid', function() - eq(1, api.curbufmeths.get_number()) - eq([['replacement string' item contains newlines]], - pcall_err(bufmeths.set_lines, 1, 1, 2, false, {'b\na'})) + eq(1, lua_or_rpc.nvim_buf_get_number(0)) + eq( + [['replacement string' item contains newlines]], + pcall_err(lua_or_rpc.nvim_buf_set_lines, 1, 1, 2, false, { 'b\na' }) + ) end) it("fails if 'nomodifiable'", function() command('set nomodifiable') - eq([[Buffer is not 'modifiable']], - pcall_err(api.bufmeths.set_lines, 1, 1, 2, false, {'a','b'})) + eq( + [[Buffer is not 'modifiable']], + pcall_err(lua_or_rpc.nvim_buf_set_lines, 1, 1, 2, false, { 'a', 'b' }) + ) end) it('has correct line_count when inserting and deleting', function() eq(1, line_count()) - set_lines(-1, -1, true, {'line'}) + set_lines(-1, -1, true, { 'line' }) eq(2, line_count()) - set_lines(-1, -1, true, {'line'}) + set_lines(-1, -1, true, { 'line' }) eq(3, line_count()) set_lines(-2, -1, true, {}) eq(2, line_count()) @@ -538,81 +558,80 @@ describe('api/buf', function() end) it('can get, set and delete a single line', function() - eq({''}, get_lines(0, 1, true)) - set_lines(0, 1, true, {'line1'}) - eq({'line1'}, get_lines(0, 1, true)) - set_lines(0, 1, true, {'line2'}) - eq({'line2'}, get_lines(0, 1, true)) + eq({ '' }, get_lines(0, 1, true)) + set_lines(0, 1, true, { 'line1' }) + eq({ 'line1' }, get_lines(0, 1, true)) + set_lines(0, 1, true, { 'line2' }) + eq({ 'line2' }, get_lines(0, 1, true)) set_lines(0, 1, true, {}) - eq({''}, get_lines(0, 1, true)) + eq({ '' }, get_lines(0, 1, true)) end) it('can get a single line with strict indexing', function() - set_lines(0, 1, true, {'line1.a'}) + set_lines(0, 1, true, { 'line1.a' }) eq(1, line_count()) -- sanity eq('Index out of bounds', pcall_err(get_lines, 1, 2, true)) eq('Index out of bounds', pcall_err(get_lines, -3, -2, true)) end) it('can get a single line with non-strict indexing', function() - set_lines(0, 1, true, {'line1.a'}) + set_lines(0, 1, true, { 'line1.a' }) eq(1, line_count()) -- sanity eq({}, get_lines(1, 2, false)) eq({}, get_lines(-3, -2, false)) end) it('can set and delete a single line with strict indexing', function() - set_lines(0, 1, true, {'line1.a'}) - eq('Index out of bounds', pcall_err(set_lines, 1, 2, true, {'line1.b'})) - eq('Index out of bounds', pcall_err(set_lines, -3, -2, true, {'line1.c'})) - eq({'line1.a'}, get_lines(0, -1, true)) + set_lines(0, 1, true, { 'line1.a' }) + eq('Index out of bounds', pcall_err(set_lines, 1, 2, true, { 'line1.b' })) + eq('Index out of bounds', pcall_err(set_lines, -3, -2, true, { 'line1.c' })) + eq({ 'line1.a' }, get_lines(0, -1, true)) eq('Index out of bounds', pcall_err(set_lines, 1, 2, true, {})) eq('Index out of bounds', pcall_err(set_lines, -3, -2, true, {})) - eq({'line1.a'}, get_lines(0, -1, true)) + eq({ 'line1.a' }, get_lines(0, -1, true)) end) it('can set and delete a single line with non-strict indexing', function() - set_lines(0, 1, true, {'line1.a'}) - set_lines(1, 2, false, {'line1.b'}) - set_lines(-4, -3, false, {'line1.c'}) - eq({'line1.c', 'line1.a', 'line1.b'}, get_lines(0, -1, true)) + set_lines(0, 1, true, { 'line1.a' }) + set_lines(1, 2, false, { 'line1.b' }) + set_lines(-4, -3, false, { 'line1.c' }) + eq({ 'line1.c', 'line1.a', 'line1.b' }, get_lines(0, -1, true)) set_lines(3, 4, false, {}) set_lines(-5, -4, false, {}) - eq({'line1.c', 'line1.a', 'line1.b'}, get_lines(0, -1, true)) + eq({ 'line1.c', 'line1.a', 'line1.b' }, get_lines(0, -1, true)) end) it('can handle NULs', function() - set_lines(0, 1, true, {'ab\0cd'}) - eq({'ab\0cd'}, get_lines(0, -1, true)) + set_lines(0, 1, true, { 'ab\0cd' }) + eq({ 'ab\0cd' }, get_lines(0, -1, true)) end) it('works with multiple lines', function() - eq({''}, get_lines(0, -1, true)) + eq({ '' }, get_lines(0, -1, true)) -- Replace buffer - for _, mode in pairs({false, true}) do - set_lines(0, -1, mode, {'a', 'b', 'c'}) - eq({'a', 'b', 'c'}, get_lines(0, -1, mode)) - eq({'b', 'c'}, get_lines(1, -1, mode)) - eq({'b'}, get_lines(1, 2, mode)) + for _, mode in pairs({ false, true }) do + set_lines(0, -1, mode, { 'a', 'b', 'c' }) + eq({ 'a', 'b', 'c' }, get_lines(0, -1, mode)) + eq({ 'b', 'c' }, get_lines(1, -1, mode)) + eq({ 'b' }, get_lines(1, 2, mode)) eq({}, get_lines(1, 1, mode)) - eq({'a', 'b'}, get_lines(0, -2, mode)) - eq({'b'}, get_lines(1, -2, mode)) - eq({'b', 'c'}, get_lines(-3, -1, mode)) - set_lines(1, 2, mode, {'a', 'b', 'c'}) - eq({'a', 'a', 'b', 'c', 'c'}, get_lines(0, -1, mode)) - set_lines(-2, -1, mode, {'a', 'b', 'c'}) - eq({'a', 'a', 'b', 'c', 'a', 'b', 'c'}, - get_lines(0, -1, mode)) + eq({ 'a', 'b' }, get_lines(0, -2, mode)) + eq({ 'b' }, get_lines(1, -2, mode)) + eq({ 'b', 'c' }, get_lines(-3, -1, mode)) + set_lines(1, 2, mode, { 'a', 'b', 'c' }) + eq({ 'a', 'a', 'b', 'c', 'c' }, get_lines(0, -1, mode)) + set_lines(-2, -1, mode, { 'a', 'b', 'c' }) + eq({ 'a', 'a', 'b', 'c', 'a', 'b', 'c' }, get_lines(0, -1, mode)) set_lines(0, -4, mode, {}) - eq({'a', 'b', 'c'}, get_lines(0, -1, mode)) + eq({ 'a', 'b', 'c' }, get_lines(0, -1, mode)) set_lines(0, -1, mode, {}) - eq({''}, get_lines(0, -1, mode)) + eq({ '' }, get_lines(0, -1, mode)) end end) it('can get line ranges with non-strict indexing', function() - set_lines(0, -1, true, {'a', 'b', 'c'}) - eq({'a', 'b', 'c'}, get_lines(0, -1, true)) --sanity + set_lines(0, -1, true, { 'a', 'b', 'c' }) + eq({ 'a', 'b', 'c' }, get_lines(0, -1, true)) --sanity eq({}, get_lines(3, 4, false)) eq({}, get_lines(3, 10, false)) @@ -622,8 +641,8 @@ describe('api/buf', function() end) it('can get line ranges with strict indexing', function() - set_lines(0, -1, true, {'a', 'b', 'c'}) - eq({'a', 'b', 'c'}, get_lines(0, -1, true)) --sanity + set_lines(0, -1, true, { 'a', 'b', 'c' }) + eq({ 'a', 'b', 'c' }, get_lines(0, -1, true)) --sanity eq('Index out of bounds', pcall_err(get_lines, 3, 4, true)) eq('Index out of bounds', pcall_err(get_lines, 3, 10, true)) @@ -634,20 +653,20 @@ describe('api/buf', function() end) it('set_lines: out-of-bounds can extend past end', function() - set_lines(0, -1, true, {'a', 'b', 'c'}) - eq({'a', 'b', 'c'}, get_lines(0, -1, true)) --sanity + set_lines(0, -1, true, { 'a', 'b', 'c' }) + eq({ 'a', 'b', 'c' }, get_lines(0, -1, true)) --sanity - eq({'c'}, get_lines(-2, 5, false)) - eq({'a', 'b', 'c'}, get_lines(0, 6, false)) - eq('Index out of bounds', pcall_err(set_lines, 4, 6, true, {'d'})) - set_lines(4, 6, false, {'d'}) - eq({'a', 'b', 'c', 'd'}, get_lines(0, -1, true)) - eq('Index out of bounds', pcall_err(set_lines, -6, -6, true, {'e'})) - set_lines(-6, -6, false, {'e'}) - eq({'e', 'a', 'b', 'c', 'd'}, get_lines(0, -1, true)) + eq({ 'c' }, get_lines(-2, 5, false)) + eq({ 'a', 'b', 'c' }, get_lines(0, 6, false)) + eq('Index out of bounds', pcall_err(set_lines, 4, 6, true, { 'd' })) + set_lines(4, 6, false, { 'd' }) + eq({ 'a', 'b', 'c', 'd' }, get_lines(0, -1, true)) + eq('Index out of bounds', pcall_err(set_lines, -6, -6, true, { 'e' })) + set_lines(-6, -6, false, { 'e' }) + eq({ 'e', 'a', 'b', 'c', 'd' }, get_lines(0, -1, true)) end) - it("set_lines on alternate buffer does not access invalid line (E315)", function() + it('set_lines on alternate buffer does not access invalid line (E315)', function() feed_command('set hidden') insert('Initial file') command('enew') @@ -667,8 +686,8 @@ describe('api/buf', function() it("set_lines of invisible buffer doesn't move cursor in current window", function() local screen = Screen.new(20, 5) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {bold = true}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { bold = true }, }) screen:attach() @@ -676,7 +695,7 @@ describe('api/buf', function() Who would win? A real window with proper text]]) - local buf = api.meths.create_buf(false,true) + local buf = lua_or_rpc.nvim_create_buf(false, true) screen:expect([[ Who would win? | A real window | @@ -685,7 +704,7 @@ describe('api/buf', function() | ]]) - api.meths.buf_set_lines(buf, 0, -1, true, {'or some', 'scratchy text'}) + lua_or_rpc.nvim_buf_set_lines(buf, 0, -1, true, { 'or some', 'scratchy text' }) feed('i') -- provoke redraw screen:expect([[ Who would win? | @@ -701,37 +720,42 @@ describe('api/buf', function() visible buffer line 1 line 2 ]]) - local hiddenbuf = api.meths.create_buf(false,true) + local hiddenbuf = lua_or_rpc.nvim_create_buf(false, true) command('vsplit') command('vsplit') feed('<c-w>l<c-w>l<c-w>l') - eq(3, funcs.winnr()) + eq(3, fn.winnr()) feed('<c-w>h') - eq(2, funcs.winnr()) - api.meths.buf_set_lines(hiddenbuf, 0, -1, true, - {'hidden buffer line 1', 'line 2'}) + eq(2, fn.winnr()) + lua_or_rpc.nvim_buf_set_lines(hiddenbuf, 0, -1, true, { 'hidden buffer line 1', 'line 2' }) feed('<c-w>p') - eq(3, funcs.winnr()) + eq(3, fn.winnr()) end) it('set_lines on unloaded buffer #8659 #22670', function() - local bufnr = curbuf('get_number') - meths.buf_set_lines(bufnr, 0, -1, false, {'a', 'b', 'c'}) - meths.buf_set_name(bufnr, 'set_lines') + local bufnr = api.nvim_get_current_buf() + lua_or_rpc.nvim_buf_set_lines(bufnr, 0, -1, false, { 'a', 'b', 'c' }) + lua_or_rpc.nvim_buf_set_name(bufnr, 'set_lines') finally(function() os.remove('set_lines') end) command('write!') command('new') - command('bunload! '..bufnr) - local new_bufnr = funcs.bufnr('set_lines', true) - meths.buf_set_lines(new_bufnr, 0, -1, false, {}) - eq({''}, meths.buf_get_lines(new_bufnr, 0, -1, false)) + command('bunload! ' .. bufnr) + local new_bufnr = fn.bufnr('set_lines', true) + lua_or_rpc.nvim_buf_set_lines(new_bufnr, 0, -1, false, {}) + eq({ '' }, lua_or_rpc.nvim_buf_get_lines(new_bufnr, 0, -1, false)) end) end) describe('nvim_buf_set_text', function() - local get_lines, set_text = curbufmeths.get_lines, curbufmeths.set_text + local function get_lines(...) + return api.nvim_buf_get_lines(0, ...) + end + + local function set_text(...) + return api.nvim_buf_set_text(0, ...) + end it('works', function() insert([[ @@ -739,70 +763,69 @@ describe('api/buf', function() text ]]) - eq({'hello foo!'}, get_lines(0, 1, true)) - + eq({ 'hello foo!' }, get_lines(0, 1, true)) -- can replace a single word - set_text(0, 6, 0, 9, {'world'}) - eq({'hello world!', 'text'}, get_lines(0, 2, true)) + set_text(0, 6, 0, 9, { 'world' }) + eq({ 'hello world!', 'text' }, get_lines(0, 2, true)) -- can insert text - set_text(0, 0, 0, 0, {'well '}) - eq({'well hello world!', 'text'}, get_lines(0, 2, true)) + set_text(0, 0, 0, 0, { 'well ' }) + eq({ 'well hello world!', 'text' }, get_lines(0, 2, true)) -- can delete text - set_text(0, 0, 0, 5, {''}) - eq({'hello world!', 'text'}, get_lines(0, 2, true)) + set_text(0, 0, 0, 5, { '' }) + eq({ 'hello world!', 'text' }, get_lines(0, 2, true)) -- can replace with multiple lines - set_text(0, 6, 0, 11, {'foo', 'wo', 'more'}) - eq({'hello foo', 'wo', 'more!', 'text'}, get_lines(0, 4, true)) + set_text(0, 6, 0, 11, { 'foo', 'wo', 'more' }) + eq({ 'hello foo', 'wo', 'more!', 'text' }, get_lines(0, 4, true)) -- will join multiple lines if needed - set_text(0, 6, 3, 4, {'bar'}) - eq({'hello bar'}, get_lines(0, 1, true)) + set_text(0, 6, 3, 4, { 'bar' }) + eq({ 'hello bar' }, get_lines(0, 1, true)) -- can use negative line numbers - set_text(-2, 0, -2, 5, {'goodbye'}) - eq({'goodbye bar', ''}, get_lines(0, -1, true)) + set_text(-2, 0, -2, 5, { 'goodbye' }) + eq({ 'goodbye bar', '' }, get_lines(0, -1, true)) - set_text(-1, 0, -1, 0, {'text'}) - eq({'goodbye bar', 'text'}, get_lines(0, 2, true)) + set_text(-1, 0, -1, 0, { 'text' }) + eq({ 'goodbye bar', 'text' }, get_lines(0, 2, true)) -- can append to a line - set_text(1, 4, -1, 4, {' and', 'more'}) - eq({'goodbye bar', 'text and', 'more'}, get_lines(0, 3, true)) + set_text(1, 4, -1, 4, { ' and', 'more' }) + eq({ 'goodbye bar', 'text and', 'more' }, get_lines(0, 3, true)) -- can use negative column numbers - set_text(0, -5, 0, -1, {'!'}) - eq({'goodbye!'}, get_lines(0, 1, true)) + set_text(0, -5, 0, -1, { '!' }) + eq({ 'goodbye!' }, get_lines(0, 1, true)) end) it('works with undo', function() - insert([[ + insert([[ hello world! foo bar ]]) - -- setting text - set_text(0, 0, 0, 0, {'well '}) - feed('u') - eq({'hello world!'}, get_lines(0, 1, true)) + -- setting text + set_text(0, 0, 0, 0, { 'well ' }) + feed('u') + eq({ 'hello world!' }, get_lines(0, 1, true)) - -- deleting text - set_text(0, 0, 0, 6, {''}) - feed('u') - eq({'hello world!'}, get_lines(0, 1, true)) + -- deleting text + set_text(0, 0, 0, 6, { '' }) + feed('u') + eq({ 'hello world!' }, get_lines(0, 1, true)) - -- inserting newlines - set_text(0, 0, 0, 0, {'hello', 'mr '}) - feed('u') - eq({'hello world!'}, get_lines(0, 1, true)) + -- inserting newlines + set_text(0, 0, 0, 0, { 'hello', 'mr ' }) + feed('u') + eq({ 'hello world!' }, get_lines(0, 1, true)) - -- deleting newlines - set_text(0, 0, 1, 4, {'hello'}) - feed('u') - eq({'hello world!'}, get_lines(0, 1, true)) + -- deleting newlines + set_text(0, 0, 1, 4, { 'hello' }) + feed('u') + eq({ 'hello world!' }, get_lines(0, 1, true)) end) it('updates the cursor position', function() @@ -811,12 +834,12 @@ describe('api/buf', function() ]]) -- position the cursor on `!` - curwin('set_cursor', {1, 11}) + api.nvim_win_set_cursor(0, { 1, 11 }) -- replace 'world' with 'foo' - set_text(0, 6, 0, 11, {'foo'}) + set_text(0, 6, 0, 11, { 'foo' }) eq('hello foo!', curbuf_depr('get_line', 0)) -- cursor should be moved left by two columns (replacement is shorter by 2 chars) - eq({1, 9}, curwin('get_cursor')) + eq({ 1, 9 }, api.nvim_win_get_cursor(0)) end) it('updates the cursor position in non-current window', function() @@ -824,18 +847,18 @@ describe('api/buf', function() hello world!]]) -- position the cursor on `!` - meths.win_set_cursor(0, {1, 11}) + api.nvim_win_set_cursor(0, { 1, 11 }) - local win = meths.get_current_win() - local buf = meths.get_current_buf() + local win = api.nvim_get_current_win() + local buf = api.nvim_get_current_buf() - command("new") + command('new') -- replace 'world' with 'foo' - meths.buf_set_text(buf, 0, 6, 0, 11, {'foo'}) - eq({'hello foo!'}, meths.buf_get_lines(buf, 0, -1, true)) + api.nvim_buf_set_text(buf, 0, 6, 0, 11, { 'foo' }) + eq({ 'hello foo!' }, api.nvim_buf_get_lines(buf, 0, -1, true)) -- cursor should be moved left by two columns (replacement is shorter by 2 chars) - eq({1, 9}, meths.win_get_cursor(win)) + eq({ 1, 9 }, api.nvim_win_get_cursor(win)) end) it('updates the cursor position in TWO non-current windows', function() @@ -843,24 +866,24 @@ describe('api/buf', function() hello world!]]) -- position the cursor on `!` - meths.win_set_cursor(0, {1, 11}) - local win = meths.get_current_win() - local buf = meths.get_current_buf() + api.nvim_win_set_cursor(0, { 1, 11 }) + local win = api.nvim_get_current_win() + local buf = api.nvim_get_current_buf() - command("split") - local win2 = meths.get_current_win() + command('split') + local win2 = api.nvim_get_current_win() -- position the cursor on `w` - meths.win_set_cursor(0, {1, 6}) + api.nvim_win_set_cursor(0, { 1, 6 }) - command("new") + command('new') -- replace 'hello' with 'foo' - meths.buf_set_text(buf, 0, 0, 0, 5, {'foo'}) - eq({'foo world!'}, meths.buf_get_lines(buf, 0, -1, true)) + api.nvim_buf_set_text(buf, 0, 0, 0, 5, { 'foo' }) + eq({ 'foo world!' }, api.nvim_buf_get_lines(buf, 0, -1, true)) -- both cursors should be moved left by two columns (replacement is shorter by 2 chars) - eq({1, 9}, meths.win_get_cursor(win)) - eq({1, 4}, meths.win_get_cursor(win2)) + eq({ 1, 9 }, api.nvim_win_get_cursor(win)) + eq({ 1, 4 }, api.nvim_win_get_cursor(win2)) end) describe('when text is being added right at cursor position #22526', function() @@ -869,12 +892,12 @@ describe('api/buf', function() abcd]]) -- position the cursor on 'c' - curwin('set_cursor', {1, 2}) + api.nvim_win_set_cursor(0, { 1, 2 }) -- add 'xxx' before 'c' - set_text(0, 2, 0, 2, {'xxx'}) - eq({'abxxxcd'}, get_lines(0, -1, true)) + set_text(0, 2, 0, 2, { 'xxx' }) + eq({ 'abxxxcd' }, get_lines(0, -1, true)) -- cursor should be on 'c' - eq({1, 5}, curwin('get_cursor')) + eq({ 1, 5 }, api.nvim_win_get_cursor(0)) end) it('updates the cursor position only in non-current window when in INSERT mode', function() @@ -882,23 +905,23 @@ describe('api/buf', function() abcd]]) -- position the cursor on 'c' - curwin('set_cursor', {1, 2}) + api.nvim_win_set_cursor(0, { 1, 2 }) -- open vertical split feed('<c-w>v') -- get into INSERT mode to treat cursor -- as being after 'b', not on 'c' feed('i') -- add 'xxx' between 'b' and 'c' - set_text(0, 2, 0, 2, {'xxx'}) - eq({'abxxxcd'}, get_lines(0, -1, true)) + set_text(0, 2, 0, 2, { 'xxx' }) + eq({ 'abxxxcd' }, get_lines(0, -1, true)) -- in the current window cursor should stay after 'b' - eq({1, 2}, curwin('get_cursor')) + eq({ 1, 2 }, api.nvim_win_get_cursor(0)) -- quit INSERT mode feed('<esc>') -- close current window feed('<c-w>c') -- in another window cursor should be on 'c' - eq({1, 5}, curwin('get_cursor')) + eq({ 1, 5 }, api.nvim_win_get_cursor(0)) end) end) @@ -908,20 +931,20 @@ describe('api/buf', function() abcd]]) -- position the cursor on 'b' - curwin('set_cursor', {1, 1}) + api.nvim_win_set_cursor(0, { 1, 1 }) -- delete 'b' set_text(0, 1, 0, 2, {}) - eq({'acd'}, get_lines(0, -1, true)) + eq({ 'acd' }, get_lines(0, -1, true)) -- cursor is now on 'c' - eq({1, 1}, curwin('get_cursor')) + eq({ 1, 1 }, api.nvim_win_get_cursor(0)) end) - it('leaves cursor at the same position in INSERT mode in current and non-current window', function() + it('maintains INSERT-mode cursor position current/non-current window', function() insert([[ abcd]]) -- position the cursor on 'b' - curwin('set_cursor', {1, 1}) + api.nvim_win_set_cursor(0, { 1, 1 }) -- open vertical split feed('<c-w>v') -- get into INSERT mode to treat cursor @@ -929,27 +952,27 @@ describe('api/buf', function() feed('i') -- delete 'b' set_text(0, 1, 0, 2, {}) - eq({'acd'}, get_lines(0, -1, true)) + eq({ 'acd' }, get_lines(0, -1, true)) -- cursor in the current window should stay after 'a' - eq({1, 1}, curwin('get_cursor')) + eq({ 1, 1 }, api.nvim_win_get_cursor(0)) -- quit INSERT mode feed('<esc>') -- close current window feed('<c-w>c') -- cursor in non-current window should stay on 'c' - eq({1, 1}, curwin('get_cursor')) + eq({ 1, 1 }, api.nvim_win_get_cursor(0)) end) end) describe('when cursor is inside replaced row range', function() - it('keeps cursor at the same position if cursor is at start_row, but before start_col', function() + it('maintains cursor position if at start_row, but before start_col', function() insert([[ This should be first then there is a line we do not want and finally the last one]]) -- position the cursor on ' ' before 'first' - curwin('set_cursor', {1, 14}) + api.nvim_win_set_cursor(0, { 1, 14 }) set_text(0, 15, 2, 11, { 'the line we do not want', @@ -961,17 +984,17 @@ describe('api/buf', function() 'but hopefully the last one', }, get_lines(0, -1, true)) -- cursor should stay at the same position - eq({1, 14}, curwin('get_cursor')) + eq({ 1, 14 }, api.nvim_win_get_cursor(0)) end) - it('keeps cursor at the same position if cursor is at start_row and column is still valid', function() + it('maintains cursor position if at start_row and column is still valid', function() insert([[ This should be first then there is a line we do not want and finally the last one]]) -- position the cursor on 'f' in 'first' - curwin('set_cursor', {1, 15}) + api.nvim_win_set_cursor(0, { 1, 15 }) set_text(0, 15, 2, 11, { 'the line we do not want', @@ -983,7 +1006,7 @@ describe('api/buf', function() 'but hopefully the last one', }, get_lines(0, -1, true)) -- cursor should stay at the same position - eq({1, 15}, curwin('get_cursor')) + eq({ 1, 15 }, api.nvim_win_get_cursor(0)) end) it('adjusts cursor column to keep it valid if start_row got smaller', function() @@ -993,7 +1016,7 @@ describe('api/buf', function() and finally the last one]]) -- position the cursor on 't' in 'first' - curwin('set_cursor', {1, 19}) + api.nvim_win_set_cursor(0, { 1, 19 }) local cursor = exec_lua([[ vim.api.nvim_buf_set_text(0, 0, 15, 2, 24, {'last'}) @@ -1002,19 +1025,19 @@ describe('api/buf', function() eq({ 'This should be last' }, get_lines(0, -1, true)) -- cursor should end up on 't' in 'last' - eq({1, 18}, curwin('get_cursor')) + eq({ 1, 18 }, api.nvim_win_get_cursor(0)) -- immediate call to nvim_win_get_cursor should have returned the same position - eq({1, 18}, cursor) + eq({ 1, 18 }, cursor) end) - it('adjusts cursor column to keep it valid if start_row got smaller in INSERT mode', function() + it('adjusts cursor column to keep it valid if start_row decreased in INSERT mode', function() insert([[ This should be first then there is a line we do not want and finally the last one]]) -- position the cursor on 't' in 'first' - curwin('set_cursor', {1, 19}) + api.nvim_win_set_cursor(0, { 1, 19 }) -- enter INSERT mode to treat cursor as being after 't' feed('a') @@ -1025,19 +1048,19 @@ describe('api/buf', function() eq({ 'This should be last' }, get_lines(0, -1, true)) -- cursor should end up after 't' in 'last' - eq({1, 19}, curwin('get_cursor')) + eq({ 1, 19 }, api.nvim_win_get_cursor(0)) -- immediate call to nvim_win_get_cursor should have returned the same position - eq({1, 19}, cursor) + eq({ 1, 19 }, cursor) end) - it('adjusts cursor column to keep it valid in a row after start_row if it got smaller', function() + it('adjusts cursor to valid column in row after start_row if it got smaller', function() insert([[ This should be first then there is a line we do not want and finally the last one]]) -- position the cursor on 'w' in 'want' - curwin('set_cursor', {2, 31}) + api.nvim_win_set_cursor(0, { 2, 31 }) local cursor = exec_lua([[ vim.api.nvim_buf_set_text(0, 0, 15, 2, 11, { @@ -1054,23 +1077,25 @@ describe('api/buf', function() 'and then the last one', }, get_lines(0, -1, true)) -- cursor column should end up at the end of a row - eq({2, 5}, curwin('get_cursor')) + eq({ 2, 5 }, api.nvim_win_get_cursor(0)) -- immediate call to nvim_win_get_cursor should have returned the same position - eq({2, 5}, cursor) + eq({ 2, 5 }, cursor) end) - it('adjusts cursor column to keep it valid in a row after start_row if it got smaller in INSERT mode', function() - insert([[ + it( + 'adjusts cursor to valid column in row after start_row if it got smaller in INSERT mode', + function() + insert([[ This should be first then there is a line we do not want and finally the last one]]) - -- position the cursor on 'w' in 'want' - curwin('set_cursor', {2, 31}) - -- enter INSERT mode - feed('a') + -- position the cursor on 'w' in 'want' + api.nvim_win_set_cursor(0, { 2, 31 }) + -- enter INSERT mode + feed('a') - local cursor = exec_lua([[ + local cursor = exec_lua([[ vim.api.nvim_buf_set_text(0, 0, 15, 2, 11, { '1', 'then 2', @@ -1079,16 +1104,17 @@ describe('api/buf', function() return vim.api.nvim_win_get_cursor(0) ]]) - eq({ - 'This should be 1', - 'then 2', - 'and then the last one', - }, get_lines(0, -1, true)) - -- cursor column should end up at the end of a row - eq({2, 6}, curwin('get_cursor')) - -- immediate call to nvim_win_get_cursor should have returned the same position - eq({2, 6}, cursor) - end) + eq({ + 'This should be 1', + 'then 2', + 'and then the last one', + }, get_lines(0, -1, true)) + -- cursor column should end up at the end of a row + eq({ 2, 6 }, api.nvim_win_get_cursor(0)) + -- immediate call to nvim_win_get_cursor should have returned the same position + eq({ 2, 6 }, cursor) + end + ) it('adjusts cursor line and column to keep it inside replacement range', function() insert([[ @@ -1097,7 +1123,7 @@ describe('api/buf', function() and finally the last one]]) -- position the cursor on 'n' in 'finally' - curwin('set_cursor', {3, 6}) + api.nvim_win_set_cursor(0, { 3, 6 }) local cursor = exec_lua([[ vim.api.nvim_buf_set_text(0, 0, 15, 2, 11, { @@ -1113,9 +1139,9 @@ describe('api/buf', function() }, get_lines(0, -1, true)) -- cursor should end up on 'y' in 'hopefully' -- to stay in the range, because it got smaller - eq({2, 12}, curwin('get_cursor')) + eq({ 2, 12 }, api.nvim_win_get_cursor(0)) -- immediate call to nvim_win_get_cursor should have returned the same position - eq({2, 12}, cursor) + eq({ 2, 12 }, cursor) end) it('adjusts cursor line and column if replacement is empty', function() @@ -1125,7 +1151,7 @@ describe('api/buf', function() and finally the last one]]) -- position the cursor on 'r' in 'there' - curwin('set_cursor', {2, 8}) + api.nvim_win_set_cursor(0, { 2, 8 }) local cursor = exec_lua([[ vim.api.nvim_buf_set_text(0, 0, 15, 2, 12, {}) @@ -1134,9 +1160,9 @@ describe('api/buf', function() eq({ 'This should be the last one' }, get_lines(0, -1, true)) -- cursor should end up on the next column after deleted range - eq({1, 15}, curwin('get_cursor')) + eq({ 1, 15 }, api.nvim_win_get_cursor(0)) -- immediate call to nvim_win_get_cursor should have returned the same position - eq({1, 15}, cursor) + eq({ 1, 15 }, cursor) end) it('adjusts cursor line and column if replacement is empty and start_col == 0', function() @@ -1146,7 +1172,7 @@ describe('api/buf', function() and finally the last one]]) -- position the cursor on 'r' in 'there' - curwin('set_cursor', {2, 8}) + api.nvim_win_set_cursor(0, { 2, 8 }) local cursor = exec_lua([[ vim.api.nvim_buf_set_text(0, 0, 0, 2, 4, {}) @@ -1155,9 +1181,9 @@ describe('api/buf', function() eq({ 'finally the last one' }, get_lines(0, -1, true)) -- cursor should end up in column 0 - eq({1, 0}, curwin('get_cursor')) + eq({ 1, 0 }, api.nvim_win_get_cursor(0)) -- immediate call to nvim_win_get_cursor should have returned the same position - eq({1, 0}, cursor) + eq({ 1, 0 }, cursor) end) it('adjusts cursor column if replacement ends at cursor row, after cursor column', function() @@ -1167,7 +1193,7 @@ describe('api/buf', function() and finally the last one]]) -- position the cursor on 'y' in 'finally' - curwin('set_cursor', {3, 10}) + api.nvim_win_set_cursor(0, { 3, 10 }) set_text(0, 15, 2, 11, { '1', 'this 2', 'and then' }) eq({ @@ -1176,29 +1202,32 @@ describe('api/buf', function() 'and then the last one', }, get_lines(0, -1, true)) -- cursor should end up on 'n' in 'then' - eq({3, 7}, curwin('get_cursor')) + eq({ 3, 7 }, api.nvim_win_get_cursor(0)) end) - it('adjusts cursor column if replacement ends at cursor row, at cursor column in INSERT mode', function() - insert([[ + it( + 'adjusts cursor column if replacement ends at cursor row, at cursor column in INSERT mode', + function() + insert([[ This should be first then there is a line we do not want and finally the last one]]) - -- position the cursor on 'y' at 'finally' - curwin('set_cursor', {3, 10}) - -- enter INSERT mode to treat cursor as being between 'l' and 'y' - feed('i') - set_text(0, 15, 2, 11, { '1', 'this 2', 'and then' }) + -- position the cursor on 'y' at 'finally' + api.nvim_win_set_cursor(0, { 3, 10 }) + -- enter INSERT mode to treat cursor as being between 'l' and 'y' + feed('i') + set_text(0, 15, 2, 11, { '1', 'this 2', 'and then' }) - eq({ - 'This should be 1', - 'this 2', - 'and then the last one', - }, get_lines(0, -1, true)) - -- cursor should end up after 'n' in 'then' - eq({3, 8}, curwin('get_cursor')) - end) + eq({ + 'This should be 1', + 'this 2', + 'and then the last one', + }, get_lines(0, -1, true)) + -- cursor should end up after 'n' in 'then' + eq({ 3, 8 }, api.nvim_win_get_cursor(0)) + end + ) it('adjusts cursor column if replacement is inside of a single line', function() insert([[ @@ -1207,7 +1236,7 @@ describe('api/buf', function() and finally the last one]]) -- position the cursor on 'y' in 'finally' - curwin('set_cursor', {3, 10}) + api.nvim_win_set_cursor(0, { 3, 10 }) set_text(2, 4, 2, 11, { 'then' }) eq({ @@ -1216,7 +1245,7 @@ describe('api/buf', function() 'and then the last one', }, get_lines(0, -1, true)) -- cursor should end up on 'n' in 'then' - eq({3, 7}, curwin('get_cursor')) + eq({ 3, 7 }, api.nvim_win_get_cursor(0)) end) it('does not move cursor column after end of a line', function() @@ -1225,7 +1254,7 @@ describe('api/buf', function() !!!]]) -- position cursor on the last '1' - curwin('set_cursor', {2, 2}) + api.nvim_win_set_cursor(0, { 2, 2 }) local cursor = exec_lua([[ vim.api.nvim_buf_set_text(0, 0, 33, 1, 3, {}) @@ -1234,16 +1263,16 @@ describe('api/buf', function() eq({ 'This should be the only line here' }, get_lines(0, -1, true)) -- cursor should end up on '!' - eq({1, 32}, curwin('get_cursor')) + eq({ 1, 32 }, api.nvim_win_get_cursor(0)) -- immediate call to nvim_win_get_cursor should have returned the same position - eq({1, 32}, cursor) + eq({ 1, 32 }, cursor) end) it('does not move cursor column before start of a line', function() insert('\n!!!') -- position cursor on the last '1' - curwin('set_cursor', {2, 2}) + api.nvim_win_set_cursor(0, { 2, 2 }) local cursor = exec_lua([[ vim.api.nvim_buf_set_text(0, 0, 0, 1, 3, {}) @@ -1252,20 +1281,20 @@ describe('api/buf', function() eq({ '' }, get_lines(0, -1, true)) -- cursor should end up on '!' - eq({1, 0}, curwin('get_cursor')) + eq({ 1, 0 }, api.nvim_win_get_cursor(0)) -- immediate call to nvim_win_get_cursor should have returned the same position - eq({1, 0}, cursor) + eq({ 1, 0 }, cursor) end) describe('with virtualedit', function() - it('adjusts cursor line and column to keep it inside replacement range if cursor is not after eol', function() + it('adjusts cursor line/col to keep inside replacement range if not after eol', function() insert([[ This should be first then there is a line we do not want and finally the last one]]) -- position cursor on 't' in 'want' - curwin('set_cursor', {2, 34}) + api.nvim_win_set_cursor(0, { 2, 34 }) -- turn on virtualedit command('set virtualedit=all') @@ -1283,23 +1312,26 @@ describe('api/buf', function() }, get_lines(0, -1, true)) -- cursor should end up on 'y' in 'hopefully' -- to stay in the range - eq({2, 12}, curwin('get_cursor')) + eq({ 2, 12 }, api.nvim_win_get_cursor(0)) -- immediate call to nvim_win_get_cursor should have returned the same position - eq({2, 12}, cursor) + eq({ 2, 12 }, cursor) -- coladd should be 0 - eq(0, exec_lua([[ + eq( + 0, + exec_lua([[ return vim.fn.winsaveview().coladd - ]])) + ]]) + ) end) - it('does not change cursor screen column when cursor is after eol and row got shorter', function() + it('does not change cursor screen column when cursor >EOL and row got shorter', function() insert([[ This should be first then there is a line we do not want and finally the last one]]) -- position cursor on 't' in 'want' - curwin('set_cursor', {2, 34}) + api.nvim_win_set_cursor(0, { 2, 34 }) -- turn on virtualedit command('set virtualedit=all') -- move cursor after eol @@ -1320,31 +1352,36 @@ describe('api/buf', function() 'but hopefully the last one', }, get_lines(0, -1, true)) -- cursor should end up at eol of a new row - eq({2, 26}, curwin('get_cursor')) + eq({ 2, 26 }, api.nvim_win_get_cursor(0)) -- immediate call to nvim_win_get_cursor should have returned the same position - eq({2, 26}, cursor) + eq({ 2, 26 }, cursor) -- coladd should be increased so that cursor stays in the same screen column - eq(13, exec_lua([[ + eq( + 13, + exec_lua([[ return vim.fn.winsaveview().coladd - ]])) + ]]) + ) end) - it('does not change cursor screen column when cursor is after eol and row got longer', function() - insert([[ + it( + 'does not change cursor screen column when cursor is after eol and row got longer', + function() + insert([[ This should be first then there is a line we do not want and finally the last one]]) - -- position cursor on 't' in 'first' - curwin('set_cursor', {1, 19}) - -- turn on virtualedit - command('set virtualedit=all') - -- move cursor after eol - exec_lua([[ + -- position cursor on 't' in 'first' + api.nvim_win_set_cursor(0, { 1, 19 }) + -- turn on virtualedit + command('set virtualedit=all') + -- move cursor after eol + exec_lua([[ vim.fn.winrestview({ coladd = 21 }) ]]) - local cursor = exec_lua([[ + local cursor = exec_lua([[ vim.api.nvim_buf_set_text(0, 0, 15, 2, 11, { 'the line we do not want', 'but hopefully', @@ -1352,36 +1389,42 @@ describe('api/buf', function() return vim.api.nvim_win_get_cursor(0) ]]) - eq({ - 'This should be the line we do not want', - 'but hopefully the last one', - }, get_lines(0, -1, true)) - -- cursor should end up at eol of a new row - eq({1, 38}, curwin('get_cursor')) - -- immediate call to nvim_win_get_cursor should have returned the same position - eq({1, 38}, cursor) - -- coladd should be increased so that cursor stays in the same screen column - eq(2, exec_lua([[ + eq({ + 'This should be the line we do not want', + 'but hopefully the last one', + }, get_lines(0, -1, true)) + -- cursor should end up at eol of a new row + eq({ 1, 38 }, api.nvim_win_get_cursor(0)) + -- immediate call to nvim_win_get_cursor should have returned the same position + eq({ 1, 38 }, cursor) + -- coladd should be increased so that cursor stays in the same screen column + eq( + 2, + exec_lua([[ return vim.fn.winsaveview().coladd - ]])) - end) - - it('does not change cursor screen column when cursor is after eol and row extended past cursor column', function() - insert([[ + ]]) + ) + end + ) + + it( + 'does not change cursor screen column when cursor is after eol and row extended past cursor column', + function() + insert([[ This should be first then there is a line we do not want and finally the last one]]) - -- position cursor on 't' in 'first' - curwin('set_cursor', {1, 19}) - -- turn on virtualedit - command('set virtualedit=all') - -- move cursor after eol just a bit - exec_lua([[ + -- position cursor on 't' in 'first' + api.nvim_win_set_cursor(0, { 1, 19 }) + -- turn on virtualedit + command('set virtualedit=all') + -- move cursor after eol just a bit + exec_lua([[ vim.fn.winrestview({ coladd = 3 }) ]]) - local cursor = exec_lua([[ + local cursor = exec_lua([[ vim.api.nvim_buf_set_text(0, 0, 15, 2, 11, { 'the line we do not want', 'but hopefully', @@ -1389,37 +1432,43 @@ describe('api/buf', function() return vim.api.nvim_win_get_cursor(0) ]]) - eq({ - 'This should be the line we do not want', - 'but hopefully the last one', - }, get_lines(0, -1, true)) - -- cursor should stay at the same screen column - eq({1, 22}, curwin('get_cursor')) - -- immediate call to nvim_win_get_cursor should have returned the same position - eq({1, 22}, cursor) - -- coladd should become 0 - eq(0, exec_lua([[ + eq({ + 'This should be the line we do not want', + 'but hopefully the last one', + }, get_lines(0, -1, true)) + -- cursor should stay at the same screen column + eq({ 1, 22 }, api.nvim_win_get_cursor(0)) + -- immediate call to nvim_win_get_cursor should have returned the same position + eq({ 1, 22 }, cursor) + -- coladd should become 0 + eq( + 0, + exec_lua([[ return vim.fn.winsaveview().coladd - ]])) - end) - - it('does not change cursor screen column when cursor is after eol and row range decreased', function() - insert([[ + ]]) + ) + end + ) + + it( + 'does not change cursor screen column when cursor is after eol and row range decreased', + function() + insert([[ This should be first then there is a line we do not want and one more and finally the last one]]) - -- position cursor on 'e' in 'more' - curwin('set_cursor', {3, 11}) - -- turn on virtualedit - command('set virtualedit=all') - -- move cursor after eol - exec_lua([[ + -- position cursor on 'e' in 'more' + api.nvim_win_set_cursor(0, { 3, 11 }) + -- turn on virtualedit + command('set virtualedit=all') + -- move cursor after eol + exec_lua([[ vim.fn.winrestview({ coladd = 28 }) ]]) - local cursor = exec_lua([[ + local cursor = exec_lua([[ vim.api.nvim_buf_set_text(0, 0, 15, 3, 11, { 'the line we do not want', 'but hopefully', @@ -1427,19 +1476,23 @@ describe('api/buf', function() return vim.api.nvim_win_get_cursor(0) ]]) - eq({ - 'This should be the line we do not want', - 'but hopefully the last one', - }, get_lines(0, -1, true)) - -- cursor should end up at eol of a new row - eq({2, 26}, curwin('get_cursor')) - -- immediate call to nvim_win_get_cursor should have returned the same position - eq({2, 26}, cursor) - -- coladd should be increased so that cursor stays in the same screen column - eq(13, exec_lua([[ + eq({ + 'This should be the line we do not want', + 'but hopefully the last one', + }, get_lines(0, -1, true)) + -- cursor should end up at eol of a new row + eq({ 2, 26 }, api.nvim_win_get_cursor(0)) + -- immediate call to nvim_win_get_cursor should have returned the same position + eq({ 2, 26 }, cursor) + -- coladd should be increased so that cursor stays in the same screen column + eq( + 13, + exec_lua([[ return vim.fn.winsaveview().coladd - ]])) - end) + ]]) + ) + end + ) end) end) @@ -1451,80 +1504,86 @@ describe('api/buf', function() line]]) -- position the cursor on 'i' - curwin('set_cursor', {3, 2}) + api.nvim_win_set_cursor(0, { 3, 2 }) set_text(1, 6, 2, 0, {}) - eq({'first line', 'second line'}, get_lines(0, -1, true)) + eq({ 'first line', 'second line' }, get_lines(0, -1, true)) -- cursor should stay on 'i' - eq({2, 8}, curwin('get_cursor')) + eq({ 2, 8 }, api.nvim_win_get_cursor(0)) -- add a newline back - set_text(1, 6, 1, 6, {'', ''}) - eq({'first line', 'second', ' line'}, get_lines(0, -1, true)) + set_text(1, 6, 1, 6, { '', '' }) + eq({ 'first line', 'second', ' line' }, get_lines(0, -1, true)) -- cursor should return back to the original position - eq({3, 2}, curwin('get_cursor')) + eq({ 3, 2 }, api.nvim_win_get_cursor(0)) end) - it('adjusts cursor column if the range is not bound to either start or end of a line', function() - insert([[ + it( + 'adjusts cursor column if the range is not bound to either start or end of a line', + function() + insert([[ This should be first then there is a line we do not want and finally the last one]]) - -- position the cursor on 'h' in 'the' - curwin('set_cursor', {3, 13}) - set_text(0, 14, 2, 11, {}) - eq({'This should be the last one'}, get_lines(0, -1, true)) - -- cursor should stay on 'h' - eq({1, 16}, curwin('get_cursor')) - -- add deleted lines back - set_text(0, 14, 0, 14, { - ' first', - 'then there is a line we do not want', - 'and finally', - }) - eq({ - 'This should be first', - 'then there is a line we do not want', - 'and finally the last one', - }, get_lines(0, -1, true)) - -- cursor should return back to the original position - eq({3, 13}, curwin('get_cursor')) - end) - - it('adjusts cursor column if replacing lines in range, not just deleting and adding', function() - insert([[ + -- position the cursor on 'h' in 'the' + api.nvim_win_set_cursor(0, { 3, 13 }) + set_text(0, 14, 2, 11, {}) + eq({ 'This should be the last one' }, get_lines(0, -1, true)) + -- cursor should stay on 'h' + eq({ 1, 16 }, api.nvim_win_get_cursor(0)) + -- add deleted lines back + set_text(0, 14, 0, 14, { + ' first', + 'then there is a line we do not want', + 'and finally', + }) + eq({ + 'This should be first', + 'then there is a line we do not want', + 'and finally the last one', + }, get_lines(0, -1, true)) + -- cursor should return back to the original position + eq({ 3, 13 }, api.nvim_win_get_cursor(0)) + end + ) + + it( + 'adjusts cursor column if replacing lines in range, not just deleting and adding', + function() + insert([[ This should be first then there is a line we do not want and finally the last one]]) - -- position the cursor on 's' in 'last' - curwin('set_cursor', {3, 18}) - set_text(0, 15, 2, 11, { - 'the line we do not want', - 'but hopefully', - }) + -- position the cursor on 's' in 'last' + api.nvim_win_set_cursor(0, { 3, 18 }) + set_text(0, 15, 2, 11, { + 'the line we do not want', + 'but hopefully', + }) - eq({ - 'This should be the line we do not want', - 'but hopefully the last one', - }, get_lines(0, -1, true)) - -- cursor should stay on 's' - eq({2, 20}, curwin('get_cursor')) + eq({ + 'This should be the line we do not want', + 'but hopefully the last one', + }, get_lines(0, -1, true)) + -- cursor should stay on 's' + eq({ 2, 20 }, api.nvim_win_get_cursor(0)) - set_text(0, 15, 1, 13, { - 'first', - 'then there is a line we do not want', - 'and finally', - }) + set_text(0, 15, 1, 13, { + 'first', + 'then there is a line we do not want', + 'and finally', + }) - eq({ - 'This should be first', - 'then there is a line we do not want', - 'and finally the last one', - }, get_lines(0, -1, true)) - -- cursor should return back to the original position - eq({3, 18}, curwin('get_cursor')) - end) + eq({ + 'This should be first', + 'then there is a line we do not want', + 'and finally the last one', + }, get_lines(0, -1, true)) + -- cursor should return back to the original position + eq({ 3, 18 }, api.nvim_win_get_cursor(0)) + end + ) it('does not move cursor column after end of a line', function() insert([[ @@ -1532,7 +1591,7 @@ describe('api/buf', function() ]]) -- position cursor at the empty line - curwin('set_cursor', {2, 0}) + api.nvim_win_set_cursor(0, { 2, 0 }) local cursor = exec_lua([[ vim.api.nvim_buf_set_text(0, 0, 33, 1, 0, {'!'}) @@ -1541,9 +1600,9 @@ describe('api/buf', function() eq({ 'This should be the only line here!' }, get_lines(0, -1, true)) -- cursor should end up on '!' - eq({1, 33}, curwin('get_cursor')) + eq({ 1, 33 }, api.nvim_win_get_cursor(0)) -- immediate call to nvim_win_get_cursor should have returned the same position - eq({1, 33}, cursor) + eq({ 1, 33 }, cursor) end) it('does not move cursor column before start of a line', function() @@ -1552,7 +1611,7 @@ describe('api/buf', function() eq({ '', '' }, get_lines(0, -1, true)) -- position cursor on the last '1' - curwin('set_cursor', {2, 2}) + api.nvim_win_set_cursor(0, { 2, 2 }) local cursor = exec_lua([[ vim.api.nvim_buf_set_text(0, 0, 0, 1, 0, {''}) @@ -1561,61 +1620,61 @@ describe('api/buf', function() eq({ '' }, get_lines(0, -1, true)) -- cursor should end up on '!' - eq({1, 0}, curwin('get_cursor')) + eq({ 1, 0 }, api.nvim_win_get_cursor(0)) -- immediate call to nvim_win_get_cursor should have returned the same position - eq({1, 0}, cursor) + eq({ 1, 0 }, cursor) end) end) it('can handle NULs', function() - set_text(0, 0, 0, 0, {'ab\0cd'}) + set_text(0, 0, 0, 0, { 'ab\0cd' }) eq('ab\0cd', curbuf_depr('get_line', 0)) end) it('adjusts extmarks', function() - local ns = request('nvim_create_namespace', "my-fancy-plugin") + local ns = api.nvim_create_namespace('my-fancy-plugin') insert([[ foo bar baz ]]) - local id1 = curbufmeths.set_extmark(ns, 0, 1, {}) - local id2 = curbufmeths.set_extmark(ns, 0, 7, {}) - local id3 = curbufmeths.set_extmark(ns, 1, 1, {}) - set_text(0, 4, 0, 7, {"q"}) + local id1 = api.nvim_buf_set_extmark(0, ns, 0, 1, {}) + local id2 = api.nvim_buf_set_extmark(0, ns, 0, 7, {}) + local id3 = api.nvim_buf_set_extmark(0, ns, 1, 1, {}) + set_text(0, 4, 0, 7, { 'q' }) - eq({'foo q', 'baz'}, get_lines(0, 2, true)) + eq({ 'foo q', 'baz' }, get_lines(0, 2, true)) -- mark before replacement point is unaffected - eq({0, 1}, curbufmeths.get_extmark_by_id(ns, id1, {})) + eq({ 0, 1 }, api.nvim_buf_get_extmark_by_id(0, ns, id1, {})) -- mark gets shifted back because the replacement was shorter - eq({0, 5}, curbufmeths.get_extmark_by_id(ns, id2, {})) + eq({ 0, 5 }, api.nvim_buf_get_extmark_by_id(0, ns, id2, {})) -- mark on the next line is unaffected - eq({1, 1}, curbufmeths.get_extmark_by_id(ns, id3, {})) + eq({ 1, 1 }, api.nvim_buf_get_extmark_by_id(0, ns, id3, {})) -- replacing the text spanning two lines will adjust the mark on the next line - set_text(0, 3, 1, 3, {"qux"}) - eq({'fooqux', ''}, get_lines(0, 2, true)) - eq({0, 6}, curbufmeths.get_extmark_by_id(ns, id3, {})) + set_text(0, 3, 1, 3, { 'qux' }) + eq({ 'fooqux', '' }, get_lines(0, 2, true)) + eq({ 0, 6 }, api.nvim_buf_get_extmark_by_id(0, ns, id3, {})) -- but mark before replacement point is still unaffected - eq({0, 1}, curbufmeths.get_extmark_by_id(ns, id1, {})) + eq({ 0, 1 }, api.nvim_buf_get_extmark_by_id(0, ns, id1, {})) -- and the mark in the middle was shifted to the end of the insertion - eq({0, 6}, curbufmeths.get_extmark_by_id(ns, id2, {})) + eq({ 0, 6 }, api.nvim_buf_get_extmark_by_id(0, ns, id2, {})) -- marks should be put back into the same place after undoing - set_text(0, 0, 0, 2, {''}) + set_text(0, 0, 0, 2, { '' }) feed('u') - eq({0, 1}, curbufmeths.get_extmark_by_id(ns, id1, {})) - eq({0, 6}, curbufmeths.get_extmark_by_id(ns, id2, {})) - eq({0, 6}, curbufmeths.get_extmark_by_id(ns, id3, {})) + eq({ 0, 1 }, api.nvim_buf_get_extmark_by_id(0, ns, id1, {})) + eq({ 0, 6 }, api.nvim_buf_get_extmark_by_id(0, ns, id2, {})) + eq({ 0, 6 }, api.nvim_buf_get_extmark_by_id(0, ns, id3, {})) -- marks should be shifted over by the correct number of bytes for multibyte -- chars - set_text(0, 0, 0, 0, {'Ø'}) - eq({0, 3}, curbufmeths.get_extmark_by_id(ns, id1, {})) - eq({0, 8}, curbufmeths.get_extmark_by_id(ns, id2, {})) - eq({0, 8}, curbufmeths.get_extmark_by_id(ns, id3, {})) + set_text(0, 0, 0, 0, { 'Ø' }) + eq({ 0, 3 }, api.nvim_buf_get_extmark_by_id(0, ns, id1, {})) + eq({ 0, 8 }, api.nvim_buf_get_extmark_by_id(0, ns, id2, {})) + eq({ 0, 8 }, api.nvim_buf_get_extmark_by_id(0, ns, id3, {})) end) - it("correctly marks changed region for redraw #13890", function() + it('correctly marks changed region for redraw #13890', function() local screen = Screen.new(20, 5) screen:attach() @@ -1624,7 +1683,7 @@ describe('api/buf', function() BBB ]]) - curbufmeths.set_text(0, 0, 1, 3, {'XXX', 'YYY'}) + api.nvim_buf_set_text(0, 0, 0, 1, 3, { 'XXX', 'YYY' }) screen:expect([[ XXX | @@ -1657,14 +1716,14 @@ describe('api/buf', function() end) it('no heap-use-after-free when called consecutively #19643', function() - set_text(0, 0, 0, 0, {'one', '', '', 'two'}) - eq({'one', '', '', 'two'}, get_lines(0, 4, true)) - meths.win_set_cursor(0, {1, 0}) + set_text(0, 0, 0, 0, { 'one', '', '', 'two' }) + eq({ 'one', '', '', 'two' }, get_lines(0, 4, true)) + api.nvim_win_set_cursor(0, { 1, 0 }) exec_lua([[ vim.api.nvim_buf_set_text(0, 0, 3, 1, 0, {''}) vim.api.nvim_buf_set_text(0, 0, 3, 1, 0, {''}) ]]) - eq({'one', 'two'}, get_lines(0, 2, true)) + eq({ 'one', 'two' }, get_lines(0, 2, true)) end) describe('handles topline', function() @@ -1672,28 +1731,32 @@ describe('api/buf', function() before_each(function() screen = Screen.new(20, 12) screen:set_default_attr_ids { - [1] = {bold = true, foreground = Screen.colors.Blue1}; - [2] = {reverse = true, bold = true}; - [3] = {reverse = true}; + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { reverse = true, bold = true }, + [3] = { reverse = true }, } screen:attach() - meths.buf_set_lines(0, 0, -1, 1, {"aaa", "bbb", "ccc", "ddd", "www", "xxx", "yyy", "zzz"}) - meths.set_option_value('modified', false, {}) + api.nvim_buf_set_lines( + 0, + 0, + -1, + true, + { 'aaa', 'bbb', 'ccc', 'ddd', 'www', 'xxx', 'yyy', 'zzz' } + ) + api.nvim_set_option_value('modified', false, {}) end) it('of current window', function() - local win = meths.get_current_win() - local buf = meths.get_current_buf() + local win = api.nvim_get_current_win() + local buf = api.nvim_get_current_buf() command('new | wincmd w') - meths.win_set_cursor(win, {8,0}) + api.nvim_win_set_cursor(win, { 8, 0 }) - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {3:[No Name] }| www | xxx | @@ -1701,15 +1764,14 @@ describe('api/buf', function() ^zzz | {2:[No Name] }| | - ]]} - meths.buf_set_text(buf, 0,3, 1,0, {"X"}) + ]], + } + api.nvim_buf_set_text(buf, 0, 3, 1, 0, { 'X' }) - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {3:[No Name] }| www | xxx | @@ -1717,22 +1779,21 @@ describe('api/buf', function() ^zzz | {2:[No Name] [+] }| | - ]]} + ]], + } end) it('of non-current window', function() - local win = meths.get_current_win() - local buf = meths.get_current_buf() + local win = api.nvim_get_current_win() + local buf = api.nvim_get_current_buf() command('new') - meths.win_set_cursor(win, {8,0}) + api.nvim_win_set_cursor(win, { 8, 0 }) - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {2:[No Name] }| www | xxx | @@ -1740,15 +1801,14 @@ describe('api/buf', function() zzz | {3:[No Name] }| | - ]]} + ]], + } - meths.buf_set_text(buf, 0,3, 1,0, {"X"}) - screen:expect{grid=[[ + api.nvim_buf_set_text(buf, 0, 3, 1, 0, { 'X' }) + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {2:[No Name] }| www | xxx | @@ -1756,18 +1816,20 @@ describe('api/buf', function() zzz | {3:[No Name] [+] }| | - ]]} + ]], + } end) it('of split windows with same buffer', function() - local win = meths.get_current_win() - local buf = meths.get_current_buf() + local win = api.nvim_get_current_win() + local buf = api.nvim_get_current_buf() command('split') - meths.win_set_cursor(win, {8,0}) - meths.win_set_cursor(0, {1,1}) + api.nvim_win_set_cursor(win, { 8, 0 }) + api.nvim_win_set_cursor(0, { 1, 1 }) - screen:expect{grid=[[ + screen:expect { + grid = [[ a^aa | bbb | ccc | @@ -1780,10 +1842,12 @@ describe('api/buf', function() zzz | {3:[No Name] }| | - ]]} - meths.buf_set_text(buf, 0,3, 1,0, {"X"}) + ]], + } + api.nvim_buf_set_text(buf, 0, 3, 1, 0, { 'X' }) - screen:expect{grid=[[ + screen:expect { + grid = [[ a^aaXbbb | ccc | ddd | @@ -1796,13 +1860,14 @@ describe('api/buf', function() zzz | {3:[No Name] [+] }| | - ]]} + ]], + } end) end) end) - describe_lua_and_rpc('nvim_buf_get_text', function(api) - local get_text = api.curbufmeths.get_text + describe_lua_and_rpc('nvim_buf_get_text', function(lua_or_rpc) + local get_text = lua_or_rpc.nvim_buf_get_text before_each(function() insert([[ hello foo! @@ -1811,119 +1876,118 @@ describe('api/buf', function() end) it('works', function() - eq({'hello'}, get_text(0, 0, 0, 5, {})) - eq({'hello foo!'}, get_text(0, 0, 0, 42, {})) - eq({'foo!'}, get_text(0, 6, 0, 10, {})) - eq({'foo!', 'tex'}, get_text(0, 6, 1, 3, {})) - eq({'foo!', 'tex'}, get_text(-3, 6, -2, 3, {})) - eq({''}, get_text(0, 18, 0, 20, {})) - eq({'ext'}, get_text(-2, 1, -2, 4, {})) - eq({'hello foo!', 'text', 'm'}, get_text(0, 0, 2, 1, {})) + eq({ 'hello' }, get_text(0, 0, 0, 0, 5, {})) + eq({ 'hello foo!' }, get_text(0, 0, 0, 0, 42, {})) + eq({ 'foo!' }, get_text(0, 0, 6, 0, 10, {})) + eq({ 'foo!', 'tex' }, get_text(0, 0, 6, 1, 3, {})) + eq({ 'foo!', 'tex' }, get_text(0, -3, 6, -2, 3, {})) + eq({ '' }, get_text(0, 0, 18, 0, 20, {})) + eq({ 'ext' }, get_text(0, -2, 1, -2, 4, {})) + eq({ 'hello foo!', 'text', 'm' }, get_text(0, 0, 0, 2, 1, {})) end) it('errors on out-of-range', function() - eq('Index out of bounds', pcall_err(get_text, 2, 0, 4, 0, {})) - eq('Index out of bounds', pcall_err(get_text, -4, 0, 0, 0, {})) - eq('Index out of bounds', pcall_err(get_text, 0, 0, 3, 0, {})) - eq('Index out of bounds', pcall_err(get_text, 0, 0, -4, 0, {})) + eq('Index out of bounds', pcall_err(get_text, 0, 2, 0, 4, 0, {})) + eq('Index out of bounds', pcall_err(get_text, 0, -4, 0, 0, 0, {})) + eq('Index out of bounds', pcall_err(get_text, 0, 0, 0, 3, 0, {})) + eq('Index out of bounds', pcall_err(get_text, 0, 0, 0, -4, 0, {})) -- no ml_get errors should happen #19017 - eq('', meths.get_vvar('errmsg')) + eq('', api.nvim_get_vvar('errmsg')) end) it('errors when start is greater than end', function() - eq("'start' is higher than 'end'", pcall_err(get_text, 1, 0, 0, 0, {})) - eq('start_col must be less than end_col', pcall_err(get_text, 0, 1, 0, 0, {})) + eq("'start' is higher than 'end'", pcall_err(get_text, 0, 1, 0, 0, 0, {})) + eq('start_col must be less than end_col', pcall_err(get_text, 0, 0, 1, 0, 0, {})) end) end) describe('nvim_buf_get_offset', function() - local get_offset = curbufmeths.get_offset + local get_offset = api.nvim_buf_get_offset it('works', function() - curbufmeths.set_lines(0,-1,true,{'Some\r','exa\000mple', '', 'buf\rfer', 'text'}) - eq(5, curbufmeths.line_count()) - eq(0, get_offset(0)) - eq(6, get_offset(1)) - eq(15, get_offset(2)) - eq(16, get_offset(3)) - eq(24, get_offset(4)) - eq(29, get_offset(5)) - eq('Index out of bounds', pcall_err(get_offset, 6)) - eq('Index out of bounds', pcall_err(get_offset, -1)) - - meths.set_option_value('eol', false, {}) - meths.set_option_value('fixeol', false, {}) - eq(28, get_offset(5)) + api.nvim_buf_set_lines(0, 0, -1, true, { 'Some\r', 'exa\000mple', '', 'buf\rfer', 'text' }) + eq(5, api.nvim_buf_line_count(0)) + eq(0, get_offset(0, 0)) + eq(6, get_offset(0, 1)) + eq(15, get_offset(0, 2)) + eq(16, get_offset(0, 3)) + eq(24, get_offset(0, 4)) + eq(29, get_offset(0, 5)) + eq('Index out of bounds', pcall_err(get_offset, 0, 6)) + eq('Index out of bounds', pcall_err(get_offset, 0, -1)) + + api.nvim_set_option_value('eol', false, {}) + api.nvim_set_option_value('fixeol', false, {}) + eq(28, get_offset(0, 5)) -- fileformat is ignored - meths.set_option_value('fileformat', 'dos', {}) - eq(0, get_offset(0)) - eq(6, get_offset(1)) - eq(15, get_offset(2)) - eq(16, get_offset(3)) - eq(24, get_offset(4)) - eq(28, get_offset(5)) - meths.set_option_value('eol', true, {}) - eq(29, get_offset(5)) - - command("set hidden") - command("enew") - eq(6, bufmeths.get_offset(1,1)) - command("bunload! 1") - eq(-1, bufmeths.get_offset(1,1)) - eq(-1, bufmeths.get_offset(1,0)) + api.nvim_set_option_value('fileformat', 'dos', {}) + eq(0, get_offset(0, 0)) + eq(6, get_offset(0, 1)) + eq(15, get_offset(0, 2)) + eq(16, get_offset(0, 3)) + eq(24, get_offset(0, 4)) + eq(28, get_offset(0, 5)) + api.nvim_set_option_value('eol', true, {}) + eq(29, get_offset(0, 5)) + + command('set hidden') + command('enew') + eq(6, api.nvim_buf_get_offset(1, 1)) + command('bunload! 1') + eq(-1, api.nvim_buf_get_offset(1, 1)) + eq(-1, api.nvim_buf_get_offset(1, 0)) end) it('works in empty buffer', function() - eq(0, get_offset(0)) - eq(1, get_offset(1)) + eq(0, get_offset(0, 0)) + eq(1, get_offset(0, 1)) + eq(-1, fn.line2byte('$')) end) it('works in buffer with one line inserted', function() feed('itext') - eq(0, get_offset(0)) - eq(5, get_offset(1)) + eq(0, get_offset(0, 0)) + eq(5, get_offset(0, 1)) end) end) describe('nvim_buf_get_var, nvim_buf_set_var, nvim_buf_del_var', function() it('works', function() - curbuf('set_var', 'lua', {1, 2, {['3'] = 1}}) - eq({1, 2, {['3'] = 1}}, curbuf('get_var', 'lua')) - eq({1, 2, {['3'] = 1}}, nvim('eval', 'b:lua')) - eq(1, funcs.exists('b:lua')) - curbufmeths.del_var('lua') - eq(0, funcs.exists('b:lua')) - eq( 'Key not found: lua', pcall_err(curbufmeths.del_var, 'lua')) - curbufmeths.set_var('lua', 1) + api.nvim_buf_set_var(0, 'lua', { 1, 2, { ['3'] = 1 } }) + eq({ 1, 2, { ['3'] = 1 } }, api.nvim_buf_get_var(0, 'lua')) + eq({ 1, 2, { ['3'] = 1 } }, api.nvim_eval('b:lua')) + eq(1, fn.exists('b:lua')) + api.nvim_buf_del_var(0, 'lua') + eq(0, fn.exists('b:lua')) + eq('Key not found: lua', pcall_err(api.nvim_buf_del_var, 0, 'lua')) + api.nvim_buf_set_var(0, 'lua', 1) command('lockvar b:lua') - eq('Key is locked: lua', pcall_err(curbufmeths.del_var, 'lua')) - eq('Key is locked: lua', pcall_err(curbufmeths.set_var, 'lua', 1)) - eq('Key is read-only: changedtick', - pcall_err(curbufmeths.del_var, 'changedtick')) - eq('Key is read-only: changedtick', - pcall_err(curbufmeths.set_var, 'changedtick', 1)) + eq('Key is locked: lua', pcall_err(api.nvim_buf_del_var, 0, 'lua')) + eq('Key is locked: lua', pcall_err(api.nvim_buf_set_var, 0, 'lua', 1)) + eq('Key is read-only: changedtick', pcall_err(api.nvim_buf_del_var, 0, 'changedtick')) + eq('Key is read-only: changedtick', pcall_err(api.nvim_buf_set_var, 0, 'changedtick', 1)) end) end) describe('nvim_buf_get_changedtick', function() it('works', function() - eq(2, curbufmeths.get_changedtick()) - curbufmeths.set_lines(0, 1, false, {'abc\0', '\0def', 'ghi'}) - eq(3, curbufmeths.get_changedtick()) - eq(3, curbufmeths.get_var('changedtick')) + eq(2, api.nvim_buf_get_changedtick(0)) + api.nvim_buf_set_lines(0, 0, 1, false, { 'abc\0', '\0def', 'ghi' }) + eq(3, api.nvim_buf_get_changedtick(0)) + eq(3, api.nvim_buf_get_var(0, 'changedtick')) end) it('buffer_set_var returns the old value', function() - local val1 = {1, 2, {['3'] = 1}} - local val2 = {4, 7} + local val1 = { 1, 2, { ['3'] = 1 } } + local val2 = { 4, 7 } eq(NIL, request('buffer_set_var', 0, 'lua', val1)) eq(val1, request('buffer_set_var', 0, 'lua', val2)) end) it('buffer_del_var returns the old value', function() - local val1 = {1, 2, {['3'] = 1}} - local val2 = {4, 7} - eq(NIL, request('buffer_set_var', 0, 'lua', val1)) + local val1 = { 1, 2, { ['3'] = 1 } } + local val2 = { 4, 7 } + eq(NIL, request('buffer_set_var', 0, 'lua', val1)) eq(val1, request('buffer_set_var', 0, 'lua', val2)) eq(val2, request('buffer_del_var', 0, 'lua')) end) @@ -1931,33 +1995,33 @@ describe('api/buf', function() describe('nvim_get_option_value, nvim_set_option_value', function() it('works', function() - eq(8, nvim('get_option_value', 'shiftwidth', {})) - nvim('set_option_value', 'shiftwidth', 4, {}) - eq(4, nvim('get_option_value', 'shiftwidth', {})) + eq(8, api.nvim_get_option_value('shiftwidth', {})) + api.nvim_set_option_value('shiftwidth', 4, {}) + eq(4, api.nvim_get_option_value('shiftwidth', {})) -- global-local option - nvim('set_option_value', 'define', 'test', {buf = 0}) - eq('test', nvim('get_option_value', 'define', {buf = 0})) + api.nvim_set_option_value('define', 'test', { buf = 0 }) + eq('test', api.nvim_get_option_value('define', { buf = 0 })) -- Doesn't change the global value - eq("", nvim('get_option_value', 'define', {scope='global'})) + eq('', api.nvim_get_option_value('define', { scope = 'global' })) end) it('returns values for unset local options', function() -- 'undolevels' is only set to its "unset" value when a new buffer is -- created command('enew') - eq(-123456, nvim('get_option_value', 'undolevels', {buf=0})) + eq(-123456, api.nvim_get_option_value('undolevels', { buf = 0 })) end) end) describe('nvim_buf_get_name, nvim_buf_set_name', function() it('works', function() - nvim('command', 'new') - eq('', curbuf('get_name')) - local new_name = nvim('eval', 'resolve(tempname())') - curbuf('set_name', new_name) - eq(new_name, curbuf('get_name')) - nvim('command', 'w!') - eq(1, funcs.filereadable(new_name)) + command('new') + eq('', api.nvim_buf_get_name(0)) + local new_name = api.nvim_eval('resolve(tempname())') + api.nvim_buf_set_name(0, new_name) + eq(new_name, api.nvim_buf_get_name(0)) + command('w!') + eq(1, fn.filereadable(new_name)) os.remove(new_name) end) end) @@ -1965,119 +2029,121 @@ describe('api/buf', function() describe('nvim_buf_is_loaded', function() it('works', function() -- record our buffer number for when we unload it - local bufnr = curbuf('get_number') + local bufnr = api.nvim_buf_get_number(0) -- api should report that the buffer is loaded - ok(buffer('is_loaded', bufnr)) + ok(api.nvim_buf_is_loaded(bufnr)) -- hide the current buffer by switching to a new empty buffer -- Careful! we need to modify the buffer first or vim will just reuse it - buffer('set_lines', bufnr, 0, -1, 1, {'line1'}) + api.nvim_buf_set_lines(bufnr, 0, -1, true, { 'line1' }) command('hide enew') -- confirm the buffer is hidden, but still loaded - local infolist = nvim('eval', 'getbufinfo('..bufnr..')') + local infolist = api.nvim_eval('getbufinfo(' .. bufnr .. ')') eq(1, #infolist) eq(1, infolist[1].hidden) eq(1, infolist[1].loaded) -- now force unload the buffer - command('bunload! '..bufnr) + command('bunload! ' .. bufnr) -- confirm the buffer is unloaded - infolist = nvim('eval', 'getbufinfo('..bufnr..')') + infolist = api.nvim_eval('getbufinfo(' .. bufnr .. ')') eq(0, infolist[1].loaded) -- nvim_buf_is_loaded() should also report the buffer as unloaded - eq(false, buffer('is_loaded', bufnr)) + eq(false, api.nvim_buf_is_loaded(bufnr)) end) end) describe('nvim_buf_is_valid', function() it('works', function() - nvim('command', 'new') - local b = nvim('get_current_buf') - ok(buffer('is_valid', b)) - nvim('command', 'bw!') - ok(not buffer('is_valid', b)) + command('new') + local b = api.nvim_get_current_buf() + ok(api.nvim_buf_is_valid(b)) + command('bw!') + ok(not api.nvim_buf_is_valid(b)) end) end) describe('nvim_buf_delete', function() it('allows for just deleting', function() - nvim('command', 'new') - local b = nvim('get_current_buf') - ok(buffer('is_valid', b)) - nvim('buf_delete', b, {}) - ok(not buffer('is_loaded', b)) - ok(not buffer('is_valid', b)) + command('new') + local b = api.nvim_get_current_buf() + ok(api.nvim_buf_is_valid(b)) + api.nvim_buf_delete(b, {}) + ok(not api.nvim_buf_is_loaded(b)) + ok(not api.nvim_buf_is_valid(b)) end) it('allows for just unloading', function() - nvim('command', 'new') - local b = nvim('get_current_buf') - ok(buffer('is_valid', b)) - nvim('buf_delete', b, { unload = true }) - ok(not buffer('is_loaded', b)) - ok(buffer('is_valid', b)) + command('new') + local b = api.nvim_get_current_buf() + ok(api.nvim_buf_is_valid(b)) + api.nvim_buf_delete(b, { unload = true }) + ok(not api.nvim_buf_is_loaded(b)) + ok(api.nvim_buf_is_valid(b)) end) end) describe('nvim_buf_get_mark', function() it('works', function() - curbuf('set_lines', -1, -1, true, {'a', 'bit of', 'text'}) - curwin('set_cursor', {3, 4}) - nvim('command', 'mark v') - eq({3, 0}, curbuf('get_mark', 'v')) + api.nvim_buf_set_lines(0, -1, -1, true, { 'a', 'bit of', 'text' }) + api.nvim_win_set_cursor(0, { 3, 4 }) + command('mark v') + eq({ 3, 0 }, api.nvim_buf_get_mark(0, 'v')) end) end) describe('nvim_buf_set_mark', function() it('works with buffer local marks', function() - curbufmeths.set_lines(-1, -1, true, {'a', 'bit of', 'text'}) - eq(true, curbufmeths.set_mark('z', 1, 1, {})) - eq({1, 1}, curbufmeths.get_mark('z')) + api.nvim_buf_set_lines(0, -1, -1, true, { 'a', 'bit of', 'text' }) + eq(true, api.nvim_buf_set_mark(0, 'z', 1, 1, {})) + eq({ 1, 1 }, api.nvim_buf_get_mark(0, 'z')) + eq({ 0, 1, 2, 0 }, fn.getpos("'z")) end) it('works with file/uppercase marks', function() - curbufmeths.set_lines(-1, -1, true, {'a', 'bit of', 'text'}) - eq(true, curbufmeths.set_mark('Z', 3, 1, {})) - eq({3, 1}, curbufmeths.get_mark('Z')) + api.nvim_buf_set_lines(0, -1, -1, true, { 'a', 'bit of', 'text' }) + eq(true, api.nvim_buf_set_mark(0, 'Z', 3, 2, {})) + eq({ 3, 2 }, api.nvim_buf_get_mark(0, 'Z')) + eq({ api.nvim_get_current_buf(), 3, 3, 0 }, fn.getpos("'Z")) end) it('fails when invalid marks names are used', function() - eq(false, pcall(curbufmeths.set_mark, '!', 1, 0, {})) - eq(false, pcall(curbufmeths.set_mark, 'fail', 1, 0, {})) + eq(false, pcall(api.nvim_buf_set_mark, 0, '!', 1, 0, {})) + eq(false, pcall(api.nvim_buf_set_mark, 0, 'fail', 1, 0, {})) end) it('fails when invalid buffer number is used', function() - eq(false, pcall(meths.buf_set_mark, 99, 'a', 1, 1, {})) + eq(false, pcall(api.nvim_buf_set_mark, 99, 'a', 1, 1, {})) end) end) describe('nvim_buf_del_mark', function() it('works with buffer local marks', function() - curbufmeths.set_lines(-1, -1, true, {'a', 'bit of', 'text'}) - curbufmeths.set_mark('z', 3, 1, {}) - eq(true, curbufmeths.del_mark('z')) - eq({0, 0}, curbufmeths.get_mark('z')) + api.nvim_buf_set_lines(0, -1, -1, true, { 'a', 'bit of', 'text' }) + api.nvim_buf_set_mark(0, 'z', 3, 1, {}) + eq(true, api.nvim_buf_del_mark(0, 'z')) + eq({ 0, 0 }, api.nvim_buf_get_mark(0, 'z')) end) it('works with file/uppercase marks', function() - curbufmeths.set_lines(-1, -1, true, {'a', 'bit of', 'text'}) - curbufmeths.set_mark('Z', 3, 3, {}) - eq(true, curbufmeths.del_mark('Z')) - eq({0, 0}, curbufmeths.get_mark('Z')) + api.nvim_buf_set_lines(0, -1, -1, true, { 'a', 'bit of', 'text' }) + api.nvim_buf_set_mark(0, 'Z', 3, 3, {}) + eq(true, api.nvim_buf_del_mark(0, 'Z')) + eq({ 0, 0 }, api.nvim_buf_get_mark(0, 'Z')) end) it('returns false in marks not set in this buffer', function() - local abuf = meths.create_buf(false,true) - bufmeths.set_lines(abuf, -1, -1, true, {'a', 'bit of', 'text'}) - bufmeths.set_mark(abuf, 'A', 2, 2, {}) - eq(false, curbufmeths.del_mark('A')) - eq({2, 2}, bufmeths.get_mark(abuf, 'A')) + local abuf = api.nvim_create_buf(false, true) + api.nvim_buf_set_lines(abuf, -1, -1, true, { 'a', 'bit of', 'text' }) + api.nvim_buf_set_mark(abuf, 'A', 2, 2, {}) + eq(false, api.nvim_buf_del_mark(0, 'A')) + eq({ 2, 2 }, api.nvim_buf_get_mark(abuf, 'A')) end) it('returns false if mark was not deleted', function() - curbufmeths.set_lines(-1, -1, true, {'a', 'bit of', 'text'}) - curbufmeths.set_mark('z', 3, 1, {}) - eq(true, curbufmeths.del_mark('z')) - eq(false, curbufmeths.del_mark('z')) -- Mark was already deleted + api.nvim_buf_set_lines(0, -1, -1, true, { 'a', 'bit of', 'text' }) + api.nvim_buf_set_mark(0, 'z', 3, 1, {}) + eq(true, api.nvim_buf_del_mark(0, 'z')) + eq(false, api.nvim_buf_del_mark(0, 'z')) -- Mark was already deleted end) it('fails when invalid marks names are used', function() - eq(false, pcall(curbufmeths.del_mark, '!')) - eq(false, pcall(curbufmeths.del_mark, 'fail')) + eq(false, pcall(api.nvim_buf_del_mark, 0, '!')) + eq(false, pcall(api.nvim_buf_del_mark, 0, 'fail')) end) it('fails when invalid buffer number is used', function() - eq(false, pcall(meths.buf_del_mark, 99, 'a')) + eq(false, pcall(api.nvim_buf_del_mark, 99, 'a')) end) end) end) diff --git a/test/functional/api/buffer_updates_spec.lua b/test/functional/api/buffer_updates_spec.lua index 80e29c1ff2..262ca40e28 100644 --- a/test/functional/api/buffer_updates_spec.lua +++ b/test/functional/api/buffer_updates_spec.lua @@ -1,39 +1,43 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local eq, ok = helpers.eq, helpers.ok -local buffer, command, eval, nvim, next_msg = helpers.buffer, - helpers.command, helpers.eval, helpers.nvim, helpers.next_msg +local fn = helpers.fn +local api = helpers.api +local command, eval, next_msg = helpers.command, helpers.eval, helpers.next_msg local nvim_prog = helpers.nvim_prog local pcall_err = helpers.pcall_err -local sleep = helpers.sleep +local sleep = vim.uv.sleep local write_file = helpers.write_file -local origlines = {"original line 1", - "original line 2", - "original line 3", - "original line 4", - "original line 5", - "original line 6"} +local origlines = { + 'original line 1', + 'original line 2', + 'original line 3', + 'original line 4', + 'original line 5', + 'original line 6', +} local function expectn(name, args) -- expect the next message to be the specified notification event - eq({'notification', name, args}, next_msg()) + eq({ 'notification', name, args }, next_msg()) end local function sendkeys(keys) - nvim('input', keys) + api.nvim_input(keys) -- give nvim some time to process msgpack requests before possibly sending -- more key presses - otherwise they all pile up in the queue and get -- processed at once local ntime = os.clock() + 0.1 - repeat until os.clock() > ntime + repeat + until os.clock() > ntime end local function open(activate, lines) local filename = helpers.tmpname() - write_file(filename, table.concat(lines, "\n").."\n", true) + write_file(filename, table.concat(lines, '\n') .. '\n', true) command('edit ' .. filename) - local b = nvim('get_current_buf') + local b = api.nvim_get_current_buf() -- what is the value of b:changedtick? local tick = eval('b:changedtick') @@ -41,8 +45,8 @@ local function open(activate, lines) -- arrive as expected if activate then local firstline = 0 - ok(buffer('attach', b, true, {})) - expectn('nvim_buf_lines_event', {b, tick, firstline, -1, lines, false}) + ok(api.nvim_buf_attach(b, true, {})) + expectn('nvim_buf_lines_event', { b, tick, firstline, -1, lines, false }) end return b, tick, filename @@ -58,14 +62,14 @@ local function editoriginal(activate, lines) end local function reopen(buf, expectedlines) - ok(buffer('detach', buf)) - expectn('nvim_buf_detach_event', {buf}) + ok(api.nvim_buf_detach(buf)) + expectn('nvim_buf_detach_event', { buf }) -- for some reason the :edit! increments tick by 2 command('edit!') local tick = eval('b:changedtick') - ok(buffer('attach', buf, true, {})) + ok(api.nvim_buf_attach(buf, true, {})) local firstline = 0 - expectn('nvim_buf_lines_event', {buf, tick, firstline, -1, expectedlines, false}) + expectn('nvim_buf_lines_event', { buf, tick, firstline, -1, expectedlines, false }) command('normal! gg') return tick end @@ -80,18 +84,36 @@ local function reopenwithfolds(b) -- add a fold command('2,4fold') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 1, 4, {'original line 2/*{{{*/', - 'original line 3', - 'original line 4/*}}}*/'}, false}) + expectn('nvim_buf_lines_event', { + b, + tick, + 1, + 4, + { + 'original line 2/*{{{*/', + 'original line 3', + 'original line 4/*}}}*/', + }, + false, + }) -- make a new fold that wraps lines 1-6 command('1,6fold') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 6, {'original line 1/*{{{*/', - 'original line 2/*{{{*/', - 'original line 3', - 'original line 4/*}}}*/', - 'original line 5', - 'original line 6/*}}}*/'}, false}) + expectn('nvim_buf_lines_event', { + b, + tick, + 0, + 6, + { + 'original line 1/*{{{*/', + 'original line 2/*{{{*/', + 'original line 3', + 'original line 4/*}}}*/', + 'original line 5', + 'original line 6/*}}}*/', + }, + false, + }) return tick end @@ -104,97 +126,105 @@ describe('API: buffer events:', function() -- add a new line at the start of the buffer command('normal! GyyggP') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 0, {'original line 6'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 0, { 'original line 6' }, false }) -- add multiple lines at the start of the file command('normal! GkkyGggP') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 0, {'original line 4', - 'original line 5', - 'original line 6'}, false}) + expectn( + 'nvim_buf_lines_event', + { b, tick, 0, 0, { 'original line 4', 'original line 5', 'original line 6' }, false } + ) -- add one line to the middle of the file, several times command('normal! ggYjjp') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 3, 3, {'original line 4'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 3, 3, { 'original line 4' }, false }) command('normal! p') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 4, 4, {'original line 4'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 4, 4, { 'original line 4' }, false }) command('normal! p') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 5, 5, {'original line 4'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 5, 5, { 'original line 4' }, false }) -- add multiple lines to the middle of the file command('normal! gg4Yjjp') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 3, 3, {'original line 4', - 'original line 5', - 'original line 6', - 'original line 4'}, false}) + expectn('nvim_buf_lines_event', { + b, + tick, + 3, + 3, + { + 'original line 4', + 'original line 5', + 'original line 6', + 'original line 4', + }, + false, + }) -- add one line to the end of the file command('normal! ggYGp') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 17, 17, {'original line 4'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 17, 17, { 'original line 4' }, false }) -- add one line to the end of the file, several times command('normal! ggYGppp') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 18, 18, {'original line 4'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 18, 18, { 'original line 4' }, false }) tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 19, 19, {'original line 4'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 19, 19, { 'original line 4' }, false }) tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 20, 20, {'original line 4'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 20, 20, { 'original line 4' }, false }) -- add several lines to the end of the file, several times command('normal! gg4YGp') command('normal! Gp') command('normal! Gp') - local firstfour = {'original line 4', - 'original line 5', - 'original line 6', - 'original line 4'} + local firstfour = { 'original line 4', 'original line 5', 'original line 6', 'original line 4' } tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 21, 21, firstfour, false}) + expectn('nvim_buf_lines_event', { b, tick, 21, 21, firstfour, false }) tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 25, 25, firstfour, false}) + expectn('nvim_buf_lines_event', { b, tick, 25, 25, firstfour, false }) tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 29, 29, firstfour, false}) + expectn('nvim_buf_lines_event', { b, tick, 29, 29, firstfour, false }) -- delete the current buffer to turn off buffer events command('bdelete!') - expectn('nvim_buf_detach_event', {b}) + expectn('nvim_buf_detach_event', { b }) -- add a line at the start of an empty file command('enew') tick = eval('b:changedtick') - local b2 = nvim('get_current_buf') - ok(buffer('attach', b2, true, {})) - expectn('nvim_buf_lines_event', {b2, tick, 0, -1, {""}, false}) + local b2 = api.nvim_get_current_buf() + ok(api.nvim_buf_attach(b2, true, {})) + expectn('nvim_buf_lines_event', { b2, tick, 0, -1, { '' }, false }) eval('append(0, ["new line 1"])') tick = tick + 1 - expectn('nvim_buf_lines_event', {b2, tick, 0, 0, {'new line 1'}, false}) + expectn('nvim_buf_lines_event', { b2, tick, 0, 0, { 'new line 1' }, false }) -- turn off buffer events manually - buffer('detach', b2) - expectn('nvim_buf_detach_event', {b2}) + api.nvim_buf_detach(b2) + expectn('nvim_buf_detach_event', { b2 }) -- add multiple lines to a blank file command('enew!') - local b3 = nvim('get_current_buf') - ok(buffer('attach', b3, true, {})) + local b3 = api.nvim_get_current_buf() + ok(api.nvim_buf_attach(b3, true, {})) tick = eval('b:changedtick') - expectn('nvim_buf_lines_event', {b3, tick, 0, -1, {""}, false}) + expectn('nvim_buf_lines_event', { b3, tick, 0, -1, { '' }, false }) eval('append(0, ["new line 1", "new line 2", "new line 3"])') tick = tick + 1 - expectn('nvim_buf_lines_event', {b3, tick, 0, 0, {'new line 1', - 'new line 2', - 'new line 3'}, false}) + expectn( + 'nvim_buf_lines_event', + { b3, tick, 0, 0, { 'new line 1', 'new line 2', 'new line 3' }, false } + ) -- use the API itself to add a line to the start of the buffer - buffer('set_lines', b3, 0, 0, true, {'New First Line'}) + api.nvim_buf_set_lines(b3, 0, 0, true, { 'New First Line' }) tick = tick + 1 - expectn('nvim_buf_lines_event', {b3, tick, 0, 0, {"New First Line"}, false}) + expectn('nvim_buf_lines_event', { b3, tick, 0, 0, { 'New First Line' }, false }) end) it('when lines are removed', function() @@ -203,37 +233,37 @@ describe('API: buffer events:', function() -- remove one line from start of file command('normal! dd') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 1, {}, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 1, {}, false }) -- remove multiple lines from the start of the file command('normal! 4dd') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 4, {}, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 4, {}, false }) -- remove multiple lines from middle of file tick = reopen(b, origlines) command('normal! jj3dd') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 2, 5, {}, false}) + expectn('nvim_buf_lines_event', { b, tick, 2, 5, {}, false }) -- remove one line from the end of the file tick = reopen(b, origlines) command('normal! Gdd') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 5, 6, {}, false}) + expectn('nvim_buf_lines_event', { b, tick, 5, 6, {}, false }) -- remove multiple lines from the end of the file tick = reopen(b, origlines) command('normal! 4G3dd') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 3, 6, {}, false}) + expectn('nvim_buf_lines_event', { b, tick, 3, 6, {}, false }) -- pretend to remove heaps lines from the end of the file but really -- just remove two tick = reopen(b, origlines) command('normal! Gk5dd') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 4, 6, {}, false}) + expectn('nvim_buf_lines_event', { b, tick, 4, 6, {}, false }) end) it('when text is changed', function() @@ -242,53 +272,56 @@ describe('API: buffer events:', function() -- some normal text editing command('normal! A555') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 1, {'original line 1555'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 1, { 'original line 1555' }, false }) command('normal! jj8X') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 2, 3, {'origin3'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 2, 3, { 'origin3' }, false }) -- modify multiple lines at once using visual block mode tick = reopen(b, origlines) command('normal! jjw') sendkeys('<C-v>jjllx') tick = tick + 1 - expectn('nvim_buf_lines_event', - {b, tick, 2, 5, {'original e 3', 'original e 4', 'original e 5'}, false}) + expectn( + 'nvim_buf_lines_event', + { b, tick, 2, 5, { 'original e 3', 'original e 4', 'original e 5' }, false } + ) -- replace part of a line line using :s tick = reopen(b, origlines) command('3s/line 3/foo/') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 2, 3, {'original foo'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 2, 3, { 'original foo' }, false }) -- replace parts of several lines line using :s tick = reopen(b, origlines) command('%s/line [35]/foo/') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 2, 5, {'original foo', - 'original line 4', - 'original foo'}, false}) + expectn( + 'nvim_buf_lines_event', + { b, tick, 2, 5, { 'original foo', 'original line 4', 'original foo' }, false } + ) -- type text into the first line of a blank file, one character at a time command('bdelete!') tick = 2 - expectn('nvim_buf_detach_event', {b}) - local bnew = nvim('get_current_buf') - ok(buffer('attach', bnew, true, {})) - expectn('nvim_buf_lines_event', {bnew, tick, 0, -1, {''}, false}) + expectn('nvim_buf_detach_event', { b }) + local bnew = api.nvim_get_current_buf() + ok(api.nvim_buf_attach(bnew, true, {})) + expectn('nvim_buf_lines_event', { bnew, tick, 0, -1, { '' }, false }) sendkeys('i') sendkeys('h') sendkeys('e') sendkeys('l') sendkeys('l') sendkeys('o\nworld') - expectn('nvim_buf_lines_event', {bnew, tick + 1, 0, 1, {'h'}, false}) - expectn('nvim_buf_lines_event', {bnew, tick + 2, 0, 1, {'he'}, false}) - expectn('nvim_buf_lines_event', {bnew, tick + 3, 0, 1, {'hel'}, false}) - expectn('nvim_buf_lines_event', {bnew, tick + 4, 0, 1, {'hell'}, false}) - expectn('nvim_buf_lines_event', {bnew, tick + 5, 0, 1, {'hello'}, false}) - expectn('nvim_buf_lines_event', {bnew, tick + 6, 0, 1, {'hello', ''}, false}) - expectn('nvim_buf_lines_event', {bnew, tick + 7, 1, 2, {'world'}, false}) + expectn('nvim_buf_lines_event', { bnew, tick + 1, 0, 1, { 'h' }, false }) + expectn('nvim_buf_lines_event', { bnew, tick + 2, 0, 1, { 'he' }, false }) + expectn('nvim_buf_lines_event', { bnew, tick + 3, 0, 1, { 'hel' }, false }) + expectn('nvim_buf_lines_event', { bnew, tick + 4, 0, 1, { 'hell' }, false }) + expectn('nvim_buf_lines_event', { bnew, tick + 5, 0, 1, { 'hello' }, false }) + expectn('nvim_buf_lines_event', { bnew, tick + 6, 0, 1, { 'hello', '' }, false }) + expectn('nvim_buf_lines_event', { bnew, tick + 7, 1, 2, { 'world' }, false }) end) it('when lines are replaced', function() @@ -297,169 +330,179 @@ describe('API: buffer events:', function() -- blast away parts of some lines with visual mode command('normal! jjwvjjllx') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 2, 3, {'original '}, false}) + expectn('nvim_buf_lines_event', { b, tick, 2, 3, { 'original ' }, false }) tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 3, 4, {}, false}) + expectn('nvim_buf_lines_event', { b, tick, 3, 4, {}, false }) tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 3, 4, {'e 5'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 3, 4, { 'e 5' }, false }) tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 2, 3, {'original e 5'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 2, 3, { 'original e 5' }, false }) tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 3, 4, {}, false}) + expectn('nvim_buf_lines_event', { b, tick, 3, 4, {}, false }) -- blast away a few lines using :g tick = reopen(b, origlines) command('global/line [35]/delete') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 2, 3, {}, false}) + expectn('nvim_buf_lines_event', { b, tick, 2, 3, {}, false }) tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 3, 4, {}, false}) + expectn('nvim_buf_lines_event', { b, tick, 3, 4, {}, false }) + end) + + it('visual paste split empty line', function() + local b, tick = editoriginal(true, { 'abc', '{', 'def', '}' }) + command('normal! ggyyjjvi{p') + expectn('nvim_buf_lines_event', { b, tick + 1, 2, 3, { '' }, false }) + expectn('nvim_buf_lines_event', { b, tick + 2, 2, 3, { '}' }, false }) + expectn('nvim_buf_lines_event', { b, tick + 3, 3, 4, {}, false }) + expectn('nvim_buf_lines_event', { b, tick + 3, 2, 3, { '' }, false }) + expectn('nvim_buf_lines_event', { b, tick + 4, 3, 3, { 'abc', '}' }, false }) end) it('when lines are filtered', function() -- Test filtering lines with !cat - local b, tick = editoriginal(true, {"A", "C", "E", "B", "D", "F"}) + local b, tick = editoriginal(true, { 'A', 'C', 'E', 'B', 'D', 'F' }) command('silent 2,5!cat') -- the change comes through as two changes: -- 1) addition of the new lines after the filtered lines -- 2) removal of the original lines tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 5, 5, {"C", "E", "B", "D"}, false}) + expectn('nvim_buf_lines_event', { b, tick, 5, 5, { 'C', 'E', 'B', 'D' }, false }) tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 1, 5, {}, false}) + expectn('nvim_buf_lines_event', { b, tick, 1, 5, {}, false }) end) it('when you use "o"', function() - local b, tick = editoriginal(true, {'AAA', 'BBB'}) + local b, tick = editoriginal(true, { 'AAA', 'BBB' }) command('set noautoindent nosmartindent') -- use 'o' to start a new line from a line with no indent command('normal! o') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 1, 1, {""}, false}) + expectn('nvim_buf_lines_event', { b, tick, 1, 1, { '' }, false }) -- undo the change, indent line 1 a bit, and try again command('undo') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 1, 2, {}, false}) + expectn('nvim_buf_lines_event', { b, tick, 1, 2, {}, false }) tick = tick + 1 - expectn('nvim_buf_changedtick_event', {b, tick}) + expectn('nvim_buf_changedtick_event', { b, tick }) command('set autoindent') command('normal! >>') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 1, {"\tAAA"}, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 1, { '\tAAA' }, false }) command('normal! ommm') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 1, 1, {"\t"}, false}) + expectn('nvim_buf_lines_event', { b, tick, 1, 1, { '\t' }, false }) tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 1, 2, {"\tmmm"}, false}) + expectn('nvim_buf_lines_event', { b, tick, 1, 2, { '\tmmm' }, false }) -- undo the change, and try again with 'O' command('undo') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 1, 2, {'\t'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 1, 2, { '\t' }, false }) tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 1, 2, {}, false}) + expectn('nvim_buf_lines_event', { b, tick, 1, 2, {}, false }) tick = tick + 1 - expectn('nvim_buf_changedtick_event', {b, tick}) + expectn('nvim_buf_changedtick_event', { b, tick }) command('normal! ggOmmm') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 0, {"\t"}, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 0, { '\t' }, false }) tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 1, {"\tmmm"}, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 1, { '\tmmm' }, false }) end) it('deactivates if the buffer is changed externally', function() -- Test changing file from outside vim and reloading using :edit - local lines = {"Line 1", "Line 2"}; + local lines = { 'Line 1', 'Line 2' } local b, tick, filename = editoriginal(true, lines) command('normal! x') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 1, {'ine 1'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 1, { 'ine 1' }, false }) command('undo') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 1, {'Line 1'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 1, { 'Line 1' }, false }) tick = tick + 1 - expectn('nvim_buf_changedtick_event', {b, tick}) + expectn('nvim_buf_changedtick_event', { b, tick }) -- change the file directly - write_file(filename, "another line\n", true, true) + write_file(filename, 'another line\n', true, true) -- reopen the file and watch buffer events shut down command('edit') - expectn('nvim_buf_detach_event', {b}) + expectn('nvim_buf_detach_event', { b }) end) it('channel can watch many buffers at once', function() -- edit 3 buffers, make sure they all have windows visible so that when we -- move between buffers, none of them are unloaded - local b1, tick1 = editoriginal(true, {'A1', 'A2'}) + local b1, tick1 = editoriginal(true, { 'A1', 'A2' }) local b1nr = eval('bufnr("")') command('split') - local b2, tick2 = open(true, {'B1', 'B2'}) + local b2, tick2 = open(true, { 'B1', 'B2' }) local b2nr = eval('bufnr("")') command('split') - local b3, tick3 = open(true, {'C1', 'C2'}) + local b3, tick3 = open(true, { 'C1', 'C2' }) local b3nr = eval('bufnr("")') -- make a new window for moving between buffers command('split') - command('b'..b1nr) + command('b' .. b1nr) command('normal! x') tick1 = tick1 + 1 - expectn('nvim_buf_lines_event', {b1, tick1, 0, 1, {'1'}, false}) + expectn('nvim_buf_lines_event', { b1, tick1, 0, 1, { '1' }, false }) command('undo') tick1 = tick1 + 1 - expectn('nvim_buf_lines_event', {b1, tick1, 0, 1, {'A1'}, false}) + expectn('nvim_buf_lines_event', { b1, tick1, 0, 1, { 'A1' }, false }) tick1 = tick1 + 1 - expectn('nvim_buf_changedtick_event', {b1, tick1}) + expectn('nvim_buf_changedtick_event', { b1, tick1 }) - command('b'..b2nr) + command('b' .. b2nr) command('normal! x') tick2 = tick2 + 1 - expectn('nvim_buf_lines_event', {b2, tick2, 0, 1, {'1'}, false}) + expectn('nvim_buf_lines_event', { b2, tick2, 0, 1, { '1' }, false }) command('undo') tick2 = tick2 + 1 - expectn('nvim_buf_lines_event', {b2, tick2, 0, 1, {'B1'}, false}) + expectn('nvim_buf_lines_event', { b2, tick2, 0, 1, { 'B1' }, false }) tick2 = tick2 + 1 - expectn('nvim_buf_changedtick_event', {b2, tick2}) + expectn('nvim_buf_changedtick_event', { b2, tick2 }) - command('b'..b3nr) + command('b' .. b3nr) command('normal! x') tick3 = tick3 + 1 - expectn('nvim_buf_lines_event', {b3, tick3, 0, 1, {'1'}, false}) + expectn('nvim_buf_lines_event', { b3, tick3, 0, 1, { '1' }, false }) command('undo') tick3 = tick3 + 1 - expectn('nvim_buf_lines_event', {b3, tick3, 0, 1, {'C1'}, false}) + expectn('nvim_buf_lines_event', { b3, tick3, 0, 1, { 'C1' }, false }) tick3 = tick3 + 1 - expectn('nvim_buf_changedtick_event', {b3, tick3}) + expectn('nvim_buf_changedtick_event', { b3, tick3 }) end) it('does not get confused if enabled/disabled many times', function() - local channel = nvim('get_api_info')[1] + local channel = api.nvim_get_chan_info(0).id local b, tick = editoriginal(false) -- Enable buffer events many times. - ok(buffer('attach', b, true, {})) - ok(buffer('attach', b, true, {})) - ok(buffer('attach', b, true, {})) - ok(buffer('attach', b, true, {})) - ok(buffer('attach', b, true, {})) - expectn('nvim_buf_lines_event', {b, tick, 0, -1, origlines, false}) - eval('rpcnotify('..channel..', "Hello There")') + ok(api.nvim_buf_attach(b, true, {})) + ok(api.nvim_buf_attach(b, true, {})) + ok(api.nvim_buf_attach(b, true, {})) + ok(api.nvim_buf_attach(b, true, {})) + ok(api.nvim_buf_attach(b, true, {})) + expectn('nvim_buf_lines_event', { b, tick, 0, -1, origlines, false }) + eval('rpcnotify(' .. channel .. ', "Hello There")') expectn('Hello There', {}) -- Disable buffer events many times. - ok(buffer('detach', b)) - ok(buffer('detach', b)) - ok(buffer('detach', b)) - ok(buffer('detach', b)) - ok(buffer('detach', b)) - expectn('nvim_buf_detach_event', {b}) - eval('rpcnotify('..channel..', "Hello Again")') + ok(api.nvim_buf_detach(b)) + ok(api.nvim_buf_detach(b)) + ok(api.nvim_buf_detach(b)) + ok(api.nvim_buf_detach(b)) + ok(api.nvim_buf_detach(b)) + expectn('nvim_buf_detach_event', { b }) + eval('rpcnotify(' .. channel .. ', "Hello Again")') expectn('Hello Again', {}) end) @@ -469,7 +512,7 @@ describe('API: buffer events:', function() -- create several new sessions, in addition to our main API local sessions = {} local pipe = helpers.new_pipename() - eval("serverstart('"..pipe.."')") + eval("serverstart('" .. pipe .. "')") sessions[1] = helpers.connect(pipe) sessions[2] = helpers.connect(pipe) sessions[3] = helpers.connect(pipe) @@ -484,109 +527,105 @@ describe('API: buffer events:', function() local function wantn(sessionid, name, args) local session = sessions[sessionid] - eq({'notification', name, args}, session:next_message(10000)) + eq({ 'notification', name, args }, session:next_message(10000)) end -- Edit a new file, but don't enable buffer events. - local lines = {'AAA', 'BBB'} + local lines = { 'AAA', 'BBB' } local b, tick = open(false, lines) -- Enable buffer events for sessions 1, 2 and 3. ok(request(1, 'nvim_buf_attach', b, true, {})) ok(request(2, 'nvim_buf_attach', b, true, {})) ok(request(3, 'nvim_buf_attach', b, true, {})) - wantn(1, 'nvim_buf_lines_event', {b, tick, 0, -1, lines, false}) - wantn(2, 'nvim_buf_lines_event', {b, tick, 0, -1, lines, false}) - wantn(3, 'nvim_buf_lines_event', {b, tick, 0, -1, lines, false}) + wantn(1, 'nvim_buf_lines_event', { b, tick, 0, -1, lines, false }) + wantn(2, 'nvim_buf_lines_event', { b, tick, 0, -1, lines, false }) + wantn(3, 'nvim_buf_lines_event', { b, tick, 0, -1, lines, false }) -- Change the buffer. command('normal! x') tick = tick + 1 - wantn(1, 'nvim_buf_lines_event', {b, tick, 0, 1, {'AA'}, false}) - wantn(2, 'nvim_buf_lines_event', {b, tick, 0, 1, {'AA'}, false}) - wantn(3, 'nvim_buf_lines_event', {b, tick, 0, 1, {'AA'}, false}) + wantn(1, 'nvim_buf_lines_event', { b, tick, 0, 1, { 'AA' }, false }) + wantn(2, 'nvim_buf_lines_event', { b, tick, 0, 1, { 'AA' }, false }) + wantn(3, 'nvim_buf_lines_event', { b, tick, 0, 1, { 'AA' }, false }) -- Stop watching on channel 1. ok(request(1, 'nvim_buf_detach', b)) - wantn(1, 'nvim_buf_detach_event', {b}) + wantn(1, 'nvim_buf_detach_event', { b }) -- Undo the change to buffer 1. command('undo') tick = tick + 1 - wantn(2, 'nvim_buf_lines_event', {b, tick, 0, 1, {'AAA'}, false}) - wantn(3, 'nvim_buf_lines_event', {b, tick, 0, 1, {'AAA'}, false}) + wantn(2, 'nvim_buf_lines_event', { b, tick, 0, 1, { 'AAA' }, false }) + wantn(3, 'nvim_buf_lines_event', { b, tick, 0, 1, { 'AAA' }, false }) tick = tick + 1 - wantn(2, 'nvim_buf_changedtick_event', {b, tick}) - wantn(3, 'nvim_buf_changedtick_event', {b, tick}) + wantn(2, 'nvim_buf_changedtick_event', { b, tick }) + wantn(3, 'nvim_buf_changedtick_event', { b, tick }) -- make sure there are no other pending nvim_buf_lines_event messages going to -- channel 1 - local channel1 = request(1, 'nvim_get_api_info')[1] - eval('rpcnotify('..channel1..', "Hello")') + local channel1 = request(1, 'nvim_get_chan_info', 0).id + eval('rpcnotify(' .. channel1 .. ', "Hello")') wantn(1, 'Hello', {}) -- close the buffer and channels 2 and 3 should get a nvim_buf_detach_event -- notification command('edit') - wantn(2, 'nvim_buf_detach_event', {b}) - wantn(3, 'nvim_buf_detach_event', {b}) + wantn(2, 'nvim_buf_detach_event', { b }) + wantn(3, 'nvim_buf_detach_event', { b }) -- make sure there are no other pending nvim_buf_lines_event messages going to -- channel 1 - channel1 = request(1, 'nvim_get_api_info')[1] - eval('rpcnotify('..channel1..', "Hello Again")') + channel1 = request(1, 'nvim_get_chan_info', 0).id + eval('rpcnotify(' .. channel1 .. ', "Hello Again")') wantn(1, 'Hello Again', {}) end) it('works with :diffput and :diffget', function() - local b1, tick1 = editoriginal(true, {"AAA", "BBB"}) - local channel = nvim('get_api_info')[1] + local b1, tick1 = editoriginal(true, { 'AAA', 'BBB' }) + local channel = api.nvim_get_chan_info(0).id command('diffthis') command('rightbelow vsplit') - local b2, tick2 = open(true, {"BBB", "CCC"}) + local b2, tick2 = open(true, { 'BBB', 'CCC' }) command('diffthis') -- go back to first buffer, and push the 'AAA' line to the second buffer command('1wincmd w') command('normal! gg') command('diffput') tick2 = tick2 + 1 - expectn('nvim_buf_lines_event', {b2, tick2, 0, 0, {"AAA"}, false}) + expectn('nvim_buf_lines_event', { b2, tick2, 0, 0, { 'AAA' }, false }) -- use :diffget to grab the other change from buffer 2 command('normal! G') command('diffget') tick1 = tick1 + 1 - expectn('nvim_buf_lines_event', {b1, tick1, 2, 2, {"CCC"}, false}) + expectn('nvim_buf_lines_event', { b1, tick1, 2, 2, { 'CCC' }, false }) - eval('rpcnotify('..channel..', "Goodbye")') + eval('rpcnotify(' .. channel .. ', "Goodbye")') expectn('Goodbye', {}) end) it('works with :sort', function() -- test for :sort - local b, tick = editoriginal(true, {"B", "D", "C", "A", "E"}) + local b, tick = editoriginal(true, { 'B', 'D', 'C', 'A', 'E' }) command('%sort') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 5, {"A", "B", "C", "D", "E"}, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 5, { 'A', 'B', 'C', 'D', 'E' }, false }) end) it('works with :left', function() - local b, tick = editoriginal(true, {" A", " B", "B", "\tB", "\t\tC"}) + local b, tick = editoriginal(true, { ' A', ' B', 'B', '\tB', '\t\tC' }) command('2,4left') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 1, 4, {"B", "B", "B"}, false}) + expectn('nvim_buf_lines_event', { b, tick, 1, 4, { 'B', 'B', 'B' }, false }) end) it('works with :right', function() - local b, tick = editoriginal(true, {" A", - "\t B", - "\t \tBB", - " \tB", - "\t\tC"}) + local b, tick = editoriginal(true, { ' A', '\t B', '\t \tBB', ' \tB', '\t\tC' }) command('set ts=2 et') command('2,4retab') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 1, 4, {" B", " BB", " B"}, false}) + expectn('nvim_buf_lines_event', { b, tick, 1, 4, { ' B', ' BB', ' B' }, false }) end) it('works with :move', function() @@ -594,19 +633,23 @@ describe('API: buffer events:', function() -- move text down towards the end of the file command('2,3move 4') tick = tick + 2 - expectn('nvim_buf_lines_event', {b, tick, 4, 4, {"original line 2", - "original line 3"}, false}) + expectn( + 'nvim_buf_lines_event', + { b, tick, 4, 4, { 'original line 2', 'original line 3' }, false } + ) tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 1, 3, {}, false}) + expectn('nvim_buf_lines_event', { b, tick, 1, 3, {}, false }) -- move text up towards the start of the file tick = reopen(b, origlines) command('4,5move 2') tick = tick + 2 - expectn('nvim_buf_lines_event', {b, tick, 2, 2, {"original line 4", - "original line 5"}, false}) + expectn( + 'nvim_buf_lines_event', + { b, tick, 2, 2, { 'original line 4', 'original line 5' }, false } + ) tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 5, 7, {}, false}) + expectn('nvim_buf_lines_event', { b, tick, 5, 7, {}, false }) end) it('when you manually add/remove folds', function() @@ -616,13 +659,14 @@ describe('API: buffer events:', function() -- delete the inner fold command('normal! zR3Gzd') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 1, 4, {'original line 2', - 'original line 3', - 'original line 4'}, false}) + expectn( + 'nvim_buf_lines_event', + { b, tick, 1, 4, { 'original line 2', 'original line 3', 'original line 4' }, false } + ) -- delete the outer fold command('normal! zd') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 6, origlines, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 6, origlines, false }) -- discard changes and put the folds back tick = reopenwithfolds(b) @@ -630,7 +674,7 @@ describe('API: buffer events:', function() -- remove both folds at once command('normal! ggzczD') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 6, origlines, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 6, origlines, false }) -- discard changes and put the folds back tick = reopenwithfolds(b) @@ -638,101 +682,102 @@ describe('API: buffer events:', function() -- now delete all folds at once command('normal! zE') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 6, origlines, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 6, origlines, false }) -- create a fold from line 4 to the end of the file command('normal! 4GA/*{{{*/') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 3, 4, {'original line 4/*{{{*/'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 3, 4, { 'original line 4/*{{{*/' }, false }) -- delete the fold which only has one marker command('normal! Gzd') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 3, 6, {'original line 4', - 'original line 5', - 'original line 6'}, false}) + expectn( + 'nvim_buf_lines_event', + { b, tick, 3, 6, { 'original line 4', 'original line 5', 'original line 6' }, false } + ) end) it('detaches if the buffer is closed', function() - local b, tick = editoriginal(true, {'AAA'}) - local channel = nvim('get_api_info')[1] + local b, tick = editoriginal(true, { 'AAA' }) + local channel = api.nvim_get_chan_info(0).id -- Test that buffer events are working. command('normal! x') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 1, {'AA'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 1, { 'AA' }, false }) command('undo') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 1, {'AAA'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 1, { 'AAA' }, false }) tick = tick + 1 - expectn('nvim_buf_changedtick_event', {b, tick}) + expectn('nvim_buf_changedtick_event', { b, tick }) -- close our buffer and create a new one command('bdelete') command('enew') - expectn('nvim_buf_detach_event', {b}) + expectn('nvim_buf_detach_event', { b }) -- Reopen the original buffer, make sure there are no buffer events sent. command('b1') command('normal! x') - eval('rpcnotify('..channel..', "Hello There")') + eval('rpcnotify(' .. channel .. ', "Hello There")') expectn('Hello There', {}) end) it(':edit! (reload) causes detach #9642', function() - local b, tick = editoriginal(true, {'AAA', 'BBB'}) + local b, tick = editoriginal(true, { 'AAA', 'BBB' }) command('set undoreload=1') command('normal! x') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 1, {'AA'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 1, { 'AA' }, false }) command('edit!') - expectn('nvim_buf_detach_event', {b}) + expectn('nvim_buf_detach_event', { b }) end) it(':enew! does not detach hidden buffer', function() - local b, tick = editoriginal(true, {'AAA', 'BBB'}) - local channel = nvim('get_api_info')[1] + local b, tick = editoriginal(true, { 'AAA', 'BBB' }) + local channel = api.nvim_get_chan_info(0).id command('set undoreload=1 hidden') command('normal! x') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 1, {'AA'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 1, { 'AA' }, false }) command('enew!') - eval('rpcnotify('..channel..', "Hello There")') + eval('rpcnotify(' .. channel .. ', "Hello There")') expectn('Hello There', {}) end) it('stays attached if the buffer is hidden', function() - local b, tick = editoriginal(true, {'AAA'}) - local channel = nvim('get_api_info')[1] + local b, tick = editoriginal(true, { 'AAA' }) + local channel = api.nvim_get_chan_info(0).id -- Test that buffer events are working. command('normal! x') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 1, {'AA'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 1, { 'AA' }, false }) command('undo') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 1, {'AAA'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 1, { 'AAA' }, false }) tick = tick + 1 - expectn('nvim_buf_changedtick_event', {b, tick}) + expectn('nvim_buf_changedtick_event', { b, tick }) -- Close our buffer by creating a new one. command('set hidden') command('enew') -- Assert that no nvim_buf_detach_event is sent. - eval('rpcnotify('..channel..', "Hello There")') + eval('rpcnotify(' .. channel .. ', "Hello There")') expectn('Hello There', {}) -- Reopen the original buffer, assert that buffer events are still active. command('b1') command('normal! x') tick = tick + 1 - expectn('nvim_buf_lines_event', {b, tick, 0, 1, {'AA'}, false}) + expectn('nvim_buf_lines_event', { b, tick, 0, 1, { 'AA' }, false }) end) it('detaches if the buffer is unloaded/deleted/wiped', function() @@ -740,29 +785,29 @@ describe('API: buffer events:', function() clear() -- need to make a new window with a buffer because :bunload doesn't let you -- unload the last buffer - for _, cmd in ipairs({'bunload', 'bdelete', 'bwipeout'}) do + for _, cmd in ipairs({ 'bunload', 'bdelete', 'bwipeout' }) do command('new') -- open a brand spanking new file - local b = open(true, {'AAA'}) + local b = open(true, { 'AAA' }) -- call :bunload or whatever the command is, and then check that we -- receive a nvim_buf_detach_event command(cmd) - expectn('nvim_buf_detach_event', {b}) + expectn('nvim_buf_detach_event', { b }) end end) it('does not send the buffer content if not requested', function() clear() local b, tick = editoriginal(false) - ok(buffer('attach', b, false, {})) - expectn('nvim_buf_changedtick_event', {b, tick}) + ok(api.nvim_buf_attach(b, false, {})) + expectn('nvim_buf_changedtick_event', { b, tick }) end) it('returns a proper error on nonempty options dict', function() clear() local b = editoriginal(false) - eq("Invalid 'opts' key: 'builtin'", pcall_err(buffer, 'attach', b, false, {builtin="asfd"})) + eq("Invalid key: 'builtin'", pcall_err(api.nvim_buf_attach, b, false, { builtin = 'asfd' })) end) it('nvim_buf_attach returns response after delay #8634', function() @@ -772,11 +817,13 @@ describe('API: buffer events:', function() eq(true, helpers.request('nvim_buf_attach', 0, false, {})) -- notification eq({ - [1] = 'notification', - [2] = 'nvim_buf_changedtick_event', - [3] = { - [1] = { id = 1 }, - [2] = 2 }, }, next_msg()) + [1] = 'notification', + [2] = 'nvim_buf_changedtick_event', + [3] = { + [1] = 1, + [2] = 2, + }, + }, next_msg()) end) end) @@ -786,7 +833,7 @@ describe('API: buffer events:', function() end) local function lines_subset(first, second) - for i = 1,#first do + for i = 1, #first do -- need to ignore trailing spaces if first[i]:gsub(' +$', '') ~= second[i]:gsub(' +$', '') then return false @@ -802,7 +849,7 @@ describe('API: buffer events:', function() local function assert_match_somewhere(expected_lines, buffer_lines) local msg = next_msg() - while(msg ~= nil) do + while msg ~= nil do local event = msg[2] if event == 'nvim_buf_lines_event' then local args = msg[3] @@ -813,7 +860,7 @@ describe('API: buffer events:', function() -- with the test setup. Note updates are contiguous. assert(#newlines <= 23) - for i = 1,#newlines do + for i = 1, #newlines do buffer_lines[starts + i] = newlines[i] end -- we don't compare the msg area of the embedded nvim, it's too flakey @@ -832,36 +879,35 @@ describe('API: buffer events:', function() it('when :terminal lines change', function() local buffer_lines = {} local expected_lines = {} - command('terminal "'..nvim_prog..'" -u NONE -i NONE -n -c "set shortmess+=A"') - local b = nvim('get_current_buf') - ok(buffer('attach', b, true, {})) + fn.termopen({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '-n', '-c', 'set shortmess+=A' }, { + env = { VIMRUNTIME = os.getenv('VIMRUNTIME') }, + }) - for _ = 1,22 do - table.insert(expected_lines,'~') + local b = api.nvim_get_current_buf() + ok(api.nvim_buf_attach(b, true, {})) + + for _ = 1, 22 do + table.insert(expected_lines, '~') end expected_lines[1] = '' - expected_lines[22] = ('tmp_terminal_nvim'..(' '):rep(45) - ..'0,0-1 All') + expected_lines[22] = ('tmp_terminal_nvim' .. (' '):rep(45) .. '0,0-1 All') sendkeys('i:e tmp_terminal_nvim<Enter>') assert_match_somewhere(expected_lines, buffer_lines) expected_lines[1] = 'Blarg' - expected_lines[22] = ('tmp_terminal_nvim [+]'..(' '):rep(41) - ..'1,6 All') + expected_lines[22] = ('tmp_terminal_nvim [+]' .. (' '):rep(41) .. '1,6 All') sendkeys('iBlarg') assert_match_somewhere(expected_lines, buffer_lines) - for i = 1,21 do + for i = 1, 21 do expected_lines[i] = 'xyz' end - expected_lines[22] = ('tmp_terminal_nvim [+]'..(' '):rep(41) - ..'31,4 Bot') + expected_lines[22] = ('tmp_terminal_nvim [+]' .. (' '):rep(41) .. '31,4 Bot') local s = string.rep('\nxyz', 30) sendkeys(s) assert_match_somewhere(expected_lines, buffer_lines) end) - end) diff --git a/test/functional/api/command_spec.lua b/test/functional/api/command_spec.lua index 1ddb289ded..f73b9c8b13 100644 --- a/test/functional/api/command_spec.lua +++ b/test/functional/api/command_spec.lua @@ -1,76 +1,177 @@ local helpers = require('test.functional.helpers')(after_each) -local NIL = helpers.NIL +local NIL = vim.NIL local clear = helpers.clear local command = helpers.command -local curbufmeths = helpers.curbufmeths local eq = helpers.eq -local meths = helpers.meths -local bufmeths = helpers.bufmeths +local api = helpers.api local matches = helpers.matches local source = helpers.source local pcall_err = helpers.pcall_err local exec_lua = helpers.exec_lua local assert_alive = helpers.assert_alive local feed = helpers.feed -local funcs = helpers.funcs +local fn = helpers.fn describe('nvim_get_commands', function() - local cmd_dict = { addr=NIL, bang=false, bar=false, complete=NIL, complete_arg=NIL, count=NIL, definition='echo "Hello World"', name='Hello', nargs='1', preview=false, range=NIL, register=false, keepscript=false, script_id=0, } - local cmd_dict2 = { addr=NIL, bang=false, bar=false, complete=NIL, complete_arg=NIL, count=NIL, definition='pwd', name='Pwd', nargs='?', preview=false, range=NIL, register=false, keepscript=false, script_id=0, } + local cmd_dict = { + addr = NIL, + bang = false, + bar = false, + complete = NIL, + complete_arg = NIL, + count = NIL, + definition = 'echo "Hello World"', + name = 'Hello', + nargs = '1', + preview = false, + range = NIL, + register = false, + keepscript = false, + script_id = 0, + } + local cmd_dict2 = { + addr = NIL, + bang = false, + bar = false, + complete = NIL, + complete_arg = NIL, + count = NIL, + definition = 'pwd', + name = 'Pwd', + nargs = '?', + preview = false, + range = NIL, + register = false, + keepscript = false, + script_id = 0, + } before_each(clear) it('gets empty list if no commands were defined', function() - eq({}, meths.get_commands({builtin=false})) + eq({}, api.nvim_get_commands({ builtin = false })) end) it('validation', function() - eq('builtin=true not implemented', pcall_err(meths.get_commands, - {builtin=true})) - eq("Invalid key: 'foo'", pcall_err(meths.get_commands, - {foo='blah'})) + eq('builtin=true not implemented', pcall_err(api.nvim_get_commands, { builtin = true })) + eq("Invalid key: 'foo'", pcall_err(api.nvim_get_commands, { foo = 'blah' })) end) it('gets global user-defined commands', function() -- Define a command. command('command -nargs=1 Hello echo "Hello World"') - eq({Hello=cmd_dict}, meths.get_commands({builtin=false})) + eq({ Hello = cmd_dict }, api.nvim_get_commands({ builtin = false })) -- Define another command. - command('command -nargs=? Pwd pwd'); - eq({Hello=cmd_dict, Pwd=cmd_dict2}, meths.get_commands({builtin=false})) + command('command -nargs=? Pwd pwd') + eq({ Hello = cmd_dict, Pwd = cmd_dict2 }, api.nvim_get_commands({ builtin = false })) -- Delete a command. command('delcommand Pwd') - eq({Hello=cmd_dict}, meths.get_commands({builtin=false})) + eq({ Hello = cmd_dict }, api.nvim_get_commands({ builtin = false })) end) it('gets buffer-local user-defined commands', function() -- Define a buffer-local command. command('command -buffer -nargs=1 Hello echo "Hello World"') - eq({Hello=cmd_dict}, curbufmeths.get_commands({builtin=false})) + eq({ Hello = cmd_dict }, api.nvim_buf_get_commands(0, { builtin = false })) -- Define another buffer-local command. command('command -buffer -nargs=? Pwd pwd') - eq({Hello=cmd_dict, Pwd=cmd_dict2}, curbufmeths.get_commands({builtin=false})) + eq({ Hello = cmd_dict, Pwd = cmd_dict2 }, api.nvim_buf_get_commands(0, { builtin = false })) -- Delete a command. command('delcommand Pwd') - eq({Hello=cmd_dict}, curbufmeths.get_commands({builtin=false})) + eq({ Hello = cmd_dict }, api.nvim_buf_get_commands(0, { builtin = false })) -- {builtin=true} always returns empty for buffer-local case. - eq({}, curbufmeths.get_commands({builtin=true})) + eq({}, api.nvim_buf_get_commands(0, { builtin = true })) end) it('gets various command attributes', function() - local cmd0 = { addr='arguments', bang=false, bar=false, complete='dir', complete_arg=NIL, count='10', definition='pwd <args>', name='TestCmd', nargs='1', preview=false, range='10', register=false, keepscript=false, script_id=0, } - local cmd1 = { addr=NIL, bang=false, bar=false, complete='custom', complete_arg='ListUsers', count=NIL, definition='!finger <args>', name='Finger', nargs='+', preview=false, range=NIL, register=false, keepscript=false, script_id=1, } - local cmd2 = { addr=NIL, bang=true, bar=false, complete=NIL, complete_arg=NIL, count=NIL, definition='call \128\253R2_foo(<q-args>)', name='Cmd2', nargs='*', preview=false, range=NIL, register=false, keepscript=false, script_id=2, } - local cmd3 = { addr=NIL, bang=false, bar=true, complete=NIL, complete_arg=NIL, count=NIL, definition='call \128\253R3_ohyeah()', name='Cmd3', nargs='0', preview=false, range=NIL, register=false, keepscript=false, script_id=3, } - local cmd4 = { addr=NIL, bang=false, bar=false, complete=NIL, complete_arg=NIL, count=NIL, definition='call \128\253R4_just_great()', name='Cmd4', nargs='0', preview=false, range=NIL, register=true, keepscript=false, script_id=4, } + local cmd0 = { + addr = 'arguments', + bang = false, + bar = false, + complete = 'dir', + complete_arg = NIL, + count = '10', + definition = 'pwd <args>', + name = 'TestCmd', + nargs = '1', + preview = false, + range = '10', + register = false, + keepscript = false, + script_id = 0, + } + local cmd1 = { + addr = NIL, + bang = false, + bar = false, + complete = 'custom', + complete_arg = 'ListUsers', + count = NIL, + definition = '!finger <args>', + name = 'Finger', + nargs = '+', + preview = false, + range = NIL, + register = false, + keepscript = false, + script_id = 1, + } + local cmd2 = { + addr = NIL, + bang = true, + bar = false, + complete = NIL, + complete_arg = NIL, + count = NIL, + definition = 'call \128\253R2_foo(<q-args>)', + name = 'Cmd2', + nargs = '*', + preview = false, + range = NIL, + register = false, + keepscript = false, + script_id = 2, + } + local cmd3 = { + addr = NIL, + bang = false, + bar = true, + complete = NIL, + complete_arg = NIL, + count = NIL, + definition = 'call \128\253R3_ohyeah()', + name = 'Cmd3', + nargs = '0', + preview = false, + range = NIL, + register = false, + keepscript = false, + script_id = 3, + } + local cmd4 = { + addr = NIL, + bang = false, + bar = false, + complete = NIL, + complete_arg = NIL, + count = NIL, + definition = 'call \128\253R4_just_great()', + name = 'Cmd4', + nargs = '0', + preview = false, + range = NIL, + register = true, + keepscript = false, + script_id = 4, + } source([[ let s:foo = 1 command -complete=custom,ListUsers -nargs=+ Finger !finger <args> ]]) - eq({Finger=cmd1}, meths.get_commands({builtin=false})) + eq({ Finger = cmd1 }, api.nvim_get_commands({ builtin = false })) command('command -nargs=1 -complete=dir -addr=arguments -count=10 TestCmd pwd <args>') - eq({Finger=cmd1, TestCmd=cmd0}, meths.get_commands({builtin=false})) + eq({ Finger = cmd1, TestCmd = cmd0 }, api.nvim_get_commands({ builtin = false })) source([[ function! s:foo() abort @@ -88,7 +189,10 @@ describe('nvim_get_commands', function() command -register Cmd4 call <SID>just_great() ]]) -- TODO(justinmk): Order is stable but undefined. Sort before return? - eq({Cmd2=cmd2, Cmd3=cmd3, Cmd4=cmd4, Finger=cmd1, TestCmd=cmd0}, meths.get_commands({builtin=false})) + eq( + { Cmd2 = cmd2, Cmd3 = cmd3, Cmd4 = cmd4, Finger = cmd1, TestCmd = cmd0 }, + api.nvim_get_commands({ builtin = false }) + ) end) end) @@ -96,9 +200,9 @@ describe('nvim_create_user_command', function() before_each(clear) it('works with strings', function() - meths.create_user_command('SomeCommand', 'let g:command_fired = <args>', {nargs = 1}) - meths.command('SomeCommand 42') - eq(42, meths.eval('g:command_fired')) + api.nvim_create_user_command('SomeCommand', 'let g:command_fired = <args>', { nargs = 1 }) + command('SomeCommand 42') + eq(42, api.nvim_eval('g:command_fired')) end) it('works with Lua functions', function() @@ -113,227 +217,245 @@ describe('nvim_create_user_command', function() }) ]] - eq({ - name = "CommandWithLuaCallback", - args = [[this\ is a\ test]], - fargs = {"this ", "is", "a test"}, - bang = false, - line1 = 1, - line2 = 1, - mods = "", - smods = { - browse = false, - confirm = false, - emsg_silent = false, - hide = false, - horizontal = false, - keepalt = false, - keepjumps = false, - keepmarks = false, - keeppatterns = false, - lockmarks = false, - noautocmd = false, - noswapfile = false, - sandbox = false, - silent = false, - split = "", - tab = -1, - unsilent = false, - verbose = -1, - vertical = false, + eq( + { + name = 'CommandWithLuaCallback', + args = [[this\ is a\ test]], + fargs = { 'this ', 'is', 'a test' }, + bang = false, + line1 = 1, + line2 = 1, + mods = '', + smods = { + browse = false, + confirm = false, + emsg_silent = false, + hide = false, + horizontal = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + split = '', + tab = -1, + unsilent = false, + verbose = -1, + vertical = false, + }, + range = 0, + count = 2, + reg = '', }, - range = 0, - count = 2, - reg = "", - }, exec_lua [=[ + exec_lua [=[ vim.api.nvim_command([[CommandWithLuaCallback this\ is a\ test]]) return result - ]=]) - - eq({ - name = "CommandWithLuaCallback", - args = [[this includes\ a backslash: \\]], - fargs = {"this", "includes a", "backslash:", "\\"}, - bang = false, - line1 = 1, - line2 = 1, - mods = "", - smods = { - browse = false, - confirm = false, - emsg_silent = false, - hide = false, - horizontal = false, - keepalt = false, - keepjumps = false, - keepmarks = false, - keeppatterns = false, - lockmarks = false, - noautocmd = false, - noswapfile = false, - sandbox = false, - silent = false, - split = "", - tab = -1, - unsilent = false, - verbose = -1, - vertical = false, + ]=] + ) + + eq( + { + name = 'CommandWithLuaCallback', + args = [[this includes\ a backslash: \\]], + fargs = { 'this', 'includes a', 'backslash:', '\\' }, + bang = false, + line1 = 1, + line2 = 1, + mods = '', + smods = { + browse = false, + confirm = false, + emsg_silent = false, + hide = false, + horizontal = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + split = '', + tab = -1, + unsilent = false, + verbose = -1, + vertical = false, + }, + range = 0, + count = 2, + reg = '', }, - range = 0, - count = 2, - reg = "", - }, exec_lua [=[ + exec_lua [=[ vim.api.nvim_command([[CommandWithLuaCallback this includes\ a backslash: \\]]) return result - ]=]) - - eq({ - name = "CommandWithLuaCallback", - args = "a\\b", - fargs = {"a\\b"}, - bang = false, - line1 = 1, - line2 = 1, - mods = "", - smods = { - browse = false, - confirm = false, - emsg_silent = false, - hide = false, - horizontal = false, - keepalt = false, - keepjumps = false, - keepmarks = false, - keeppatterns = false, - lockmarks = false, - noautocmd = false, - noswapfile = false, - sandbox = false, - silent = false, - split = "", - tab = -1, - unsilent = false, - verbose = -1, - vertical = false, + ]=] + ) + + eq( + { + name = 'CommandWithLuaCallback', + args = 'a\\b', + fargs = { 'a\\b' }, + bang = false, + line1 = 1, + line2 = 1, + mods = '', + smods = { + browse = false, + confirm = false, + emsg_silent = false, + hide = false, + horizontal = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + split = '', + tab = -1, + unsilent = false, + verbose = -1, + vertical = false, + }, + range = 0, + count = 2, + reg = '', }, - range = 0, - count = 2, - reg = "", - }, exec_lua [=[ + exec_lua [=[ vim.api.nvim_command('CommandWithLuaCallback a\\b') return result - ]=]) - - eq({ - name = "CommandWithLuaCallback", - args = 'h\tey ', - fargs = {[[h]], [[ey]]}, - bang = true, - line1 = 10, - line2 = 10, - mods = "confirm unsilent botright horizontal", - smods = { - browse = false, - confirm = true, - emsg_silent = false, - hide = false, - horizontal = true, - keepalt = false, - keepjumps = false, - keepmarks = false, - keeppatterns = false, - lockmarks = false, - noautocmd = false, - noswapfile = false, - sandbox = false, - silent = false, - split = "botright", - tab = -1, - unsilent = true, - verbose = -1, - vertical = false, + ]=] + ) + + eq( + { + name = 'CommandWithLuaCallback', + args = 'h\tey ', + fargs = { [[h]], [[ey]] }, + bang = true, + line1 = 10, + line2 = 10, + mods = 'confirm unsilent botright horizontal', + smods = { + browse = false, + confirm = true, + emsg_silent = false, + hide = false, + horizontal = true, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + split = 'botright', + tab = -1, + unsilent = true, + verbose = -1, + vertical = false, + }, + range = 1, + count = 10, + reg = '', }, - range = 1, - count = 10, - reg = "", - }, exec_lua [=[ + exec_lua [=[ vim.api.nvim_command('unsilent horizontal botright confirm 10CommandWithLuaCallback! h\tey ') return result - ]=]) - - eq({ - name = "CommandWithLuaCallback", - args = "h", - fargs = {"h"}, - bang = false, - line1 = 1, - line2 = 42, - mods = "", - smods = { - browse = false, - confirm = false, - emsg_silent = false, - hide = false, - horizontal = false, - keepalt = false, - keepjumps = false, - keepmarks = false, - keeppatterns = false, - lockmarks = false, - noautocmd = false, - noswapfile = false, - sandbox = false, - silent = false, - split = "", - tab = -1, - unsilent = false, - verbose = -1, - vertical = false, + ]=] + ) + + eq( + { + name = 'CommandWithLuaCallback', + args = 'h', + fargs = { 'h' }, + bang = false, + line1 = 1, + line2 = 42, + mods = '', + smods = { + browse = false, + confirm = false, + emsg_silent = false, + hide = false, + horizontal = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + split = '', + tab = -1, + unsilent = false, + verbose = -1, + vertical = false, + }, + range = 1, + count = 42, + reg = '', }, - range = 1, - count = 42, - reg = "", - }, exec_lua [[ + exec_lua [[ vim.api.nvim_command('CommandWithLuaCallback 42 h') return result - ]]) - - eq({ - name = "CommandWithLuaCallback", - args = "", - fargs = {}, -- fargs works without args - bang = false, - line1 = 1, - line2 = 1, - mods = "", - smods = { - browse = false, - confirm = false, - emsg_silent = false, - hide = false, - horizontal = false, - keepalt = false, - keepjumps = false, - keepmarks = false, - keeppatterns = false, - lockmarks = false, - noautocmd = false, - noswapfile = false, - sandbox = false, - silent = false, - split = "", - tab = -1, - unsilent = false, - verbose = -1, - vertical = false, + ]] + ) + + eq( + { + name = 'CommandWithLuaCallback', + args = '', + fargs = {}, -- fargs works without args + bang = false, + line1 = 1, + line2 = 1, + mods = '', + smods = { + browse = false, + confirm = false, + emsg_silent = false, + hide = false, + horizontal = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + split = '', + tab = -1, + unsilent = false, + verbose = -1, + vertical = false, + }, + range = 0, + count = 2, + reg = '', }, - range = 0, - count = 2, - reg = "", - }, exec_lua [[ + exec_lua [[ vim.api.nvim_command('CommandWithLuaCallback') return result - ]]) + ]] + ) -- f-args doesn't split when command nargs is 1 or "?" exec_lua [[ @@ -347,80 +469,86 @@ describe('nvim_create_user_command', function() }) ]] - eq({ - name = "CommandWithOneOrNoArg", - args = "hello I'm one argument", - fargs = {"hello I'm one argument"}, -- Doesn't split args - bang = false, - line1 = 1, - line2 = 1, - mods = "", - smods = { - browse = false, - confirm = false, - emsg_silent = false, - hide = false, - horizontal = false, - keepalt = false, - keepjumps = false, - keepmarks = false, - keeppatterns = false, - lockmarks = false, - noautocmd = false, - noswapfile = false, - sandbox = false, - silent = false, - split = "", - tab = -1, - unsilent = false, - verbose = -1, - vertical = false, + eq( + { + name = 'CommandWithOneOrNoArg', + args = "hello I'm one argument", + fargs = { "hello I'm one argument" }, -- Doesn't split args + bang = false, + line1 = 1, + line2 = 1, + mods = '', + smods = { + browse = false, + confirm = false, + emsg_silent = false, + hide = false, + horizontal = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + split = '', + tab = -1, + unsilent = false, + verbose = -1, + vertical = false, + }, + range = 0, + count = 2, + reg = '', }, - range = 0, - count = 2, - reg = "", - }, exec_lua [[ + exec_lua [[ vim.api.nvim_command('CommandWithOneOrNoArg hello I\'m one argument') return result - ]]) + ]] + ) -- f-args is an empty table if no args were passed - eq({ - name = "CommandWithOneOrNoArg", - args = "", - fargs = {}, - bang = false, - line1 = 1, - line2 = 1, - mods = "", - smods = { - browse = false, - confirm = false, - emsg_silent = false, - hide = false, - horizontal = false, - keepalt = false, - keepjumps = false, - keepmarks = false, - keeppatterns = false, - lockmarks = false, - noautocmd = false, - noswapfile = false, - sandbox = false, - silent = false, - split = "", - tab = -1, - unsilent = false, - verbose = -1, - vertical = false, + eq( + { + name = 'CommandWithOneOrNoArg', + args = '', + fargs = {}, + bang = false, + line1 = 1, + line2 = 1, + mods = '', + smods = { + browse = false, + confirm = false, + emsg_silent = false, + hide = false, + horizontal = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + split = '', + tab = -1, + unsilent = false, + verbose = -1, + vertical = false, + }, + range = 0, + count = 2, + reg = '', }, - range = 0, - count = 2, - reg = "", - }, exec_lua [[ + exec_lua [[ vim.api.nvim_command('CommandWithOneOrNoArg') return result - ]]) + ]] + ) -- f-args is an empty table when the command nargs=0 exec_lua [[ @@ -434,88 +562,93 @@ describe('nvim_create_user_command', function() register = true, }) ]] - eq({ - name = "CommandWithNoArgs", - args = "", - fargs = {}, - bang = false, - line1 = 1, - line2 = 1, - mods = "", - smods = { - browse = false, - confirm = false, - emsg_silent = false, - hide = false, - horizontal = false, - keepalt = false, - keepjumps = false, - keepmarks = false, - keeppatterns = false, - lockmarks = false, - noautocmd = false, - noswapfile = false, - sandbox = false, - silent = false, - split = "", - tab = -1, - unsilent = false, - verbose = -1, - vertical = false, + eq( + { + name = 'CommandWithNoArgs', + args = '', + fargs = {}, + bang = false, + line1 = 1, + line2 = 1, + mods = '', + smods = { + browse = false, + confirm = false, + emsg_silent = false, + hide = false, + horizontal = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + split = '', + tab = -1, + unsilent = false, + verbose = -1, + vertical = false, + }, + range = 0, + count = 2, + reg = '', }, - range = 0, - count = 2, - reg = "", - }, exec_lua [[ + exec_lua [[ vim.cmd('CommandWithNoArgs') return result - ]]) + ]] + ) -- register can be specified - eq({ - name = "CommandWithNoArgs", - args = "", - fargs = {}, - bang = false, - line1 = 1, - line2 = 1, - mods = "", - smods = { - browse = false, - confirm = false, - emsg_silent = false, - hide = false, - horizontal = false, - keepalt = false, - keepjumps = false, - keepmarks = false, - keeppatterns = false, - lockmarks = false, - noautocmd = false, - noswapfile = false, - sandbox = false, - silent = false, - split = "", - tab = -1, - unsilent = false, - verbose = -1, - vertical = false, + eq( + { + name = 'CommandWithNoArgs', + args = '', + fargs = {}, + bang = false, + line1 = 1, + line2 = 1, + mods = '', + smods = { + browse = false, + confirm = false, + emsg_silent = false, + hide = false, + horizontal = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + split = '', + tab = -1, + unsilent = false, + verbose = -1, + vertical = false, + }, + range = 0, + count = 2, + reg = '+', }, - range = 0, - count = 2, - reg = "+", - }, exec_lua [[ + exec_lua [[ vim.cmd('CommandWithNoArgs +') return result - ]]) - + ]] + ) end) it('can define buffer-local commands', function() - local bufnr = meths.create_buf(false, false) - bufmeths.create_user_command(bufnr, "Hello", "", {}) - matches("Not an editor command: Hello", pcall_err(meths.command, "Hello")) - meths.set_current_buf(bufnr) - meths.command("Hello") + local bufnr = api.nvim_create_buf(false, false) + api.nvim_buf_create_user_command(bufnr, 'Hello', '', {}) + matches('Not an editor command: Hello', pcall_err(command, 'Hello')) + api.nvim_set_current_buf(bufnr) + command('Hello') assert_alive() end) @@ -537,58 +670,88 @@ describe('nvim_create_user_command', function() ]] feed(':Test a<Tab>') - eq('Test aaa', funcs.getcmdline()) + eq('Test aaa', fn.getcmdline()) feed('<C-U>Test b<Tab>') - eq('Test bbb', funcs.getcmdline()) + eq('Test bbb', fn.getcmdline()) end) it('does not allow invalid command names', function() - eq("Invalid command name (must start with uppercase): 'test'", pcall_err(exec_lua, [[ + eq( + "Invalid command name (must start with uppercase): 'test'", + pcall_err( + exec_lua, + [[ vim.api.nvim_create_user_command('test', 'echo "hi"', {}) - ]])) - eq("Invalid command name: 't@'", pcall_err(exec_lua, [[ + ]] + ) + ) + eq( + "Invalid command name: 't@'", + pcall_err( + exec_lua, + [[ vim.api.nvim_create_user_command('t@', 'echo "hi"', {}) - ]])) - eq("Invalid command name: 'T@st'", pcall_err(exec_lua, [[ + ]] + ) + ) + eq( + "Invalid command name: 'T@st'", + pcall_err( + exec_lua, + [[ vim.api.nvim_create_user_command('T@st', 'echo "hi"', {}) - ]])) - eq("Invalid command name: 'Test!'", pcall_err(exec_lua, [[ + ]] + ) + ) + eq( + "Invalid command name: 'Test!'", + pcall_err( + exec_lua, + [[ vim.api.nvim_create_user_command('Test!', 'echo "hi"', {}) - ]])) - eq("Invalid command name: '💩'", pcall_err(exec_lua, [[ + ]] + ) + ) + eq( + "Invalid command name: '💩'", + pcall_err( + exec_lua, + [[ vim.api.nvim_create_user_command('💩', 'echo "hi"', {}) - ]])) + ]] + ) + ) end) it('smods can be used with nvim_cmd', function() - exec_lua[[ + exec_lua [[ vim.api.nvim_create_user_command('MyEcho', function(opts) vim.api.nvim_cmd({ cmd = 'echo', args = { '&verbose' }, mods = opts.smods }, {}) end, {}) ]] - eq("3", meths.cmd({ cmd = 'MyEcho', mods = { verbose = 3 } }, { output = true })) + eq('3', api.nvim_cmd({ cmd = 'MyEcho', mods = { verbose = 3 } }, { output = true })) - eq(1, #meths.list_tabpages()) - exec_lua[[ + eq(1, #api.nvim_list_tabpages()) + exec_lua [[ vim.api.nvim_create_user_command('MySplit', function(opts) vim.api.nvim_cmd({ cmd = 'split', mods = opts.smods }, {}) end, {}) ]] - meths.cmd({ cmd = 'MySplit' }, {}) - eq(1, #meths.list_tabpages()) - eq(2, #meths.list_wins()) - meths.cmd({ cmd = 'MySplit', mods = { tab = 1 } }, {}) - eq(2, #meths.list_tabpages()) - eq(2, funcs.tabpagenr()) - meths.cmd({ cmd = 'MySplit', mods = { tab = 1 } }, {}) - eq(3, #meths.list_tabpages()) - eq(2, funcs.tabpagenr()) - meths.cmd({ cmd = 'MySplit', mods = { tab = 3 } }, {}) - eq(4, #meths.list_tabpages()) - eq(4, funcs.tabpagenr()) - meths.cmd({ cmd = 'MySplit', mods = { tab = 0 } }, {}) - eq(5, #meths.list_tabpages()) - eq(1, funcs.tabpagenr()) + api.nvim_cmd({ cmd = 'MySplit' }, {}) + eq(1, #api.nvim_list_tabpages()) + eq(2, #api.nvim_list_wins()) + api.nvim_cmd({ cmd = 'MySplit', mods = { tab = 1 } }, {}) + eq(2, #api.nvim_list_tabpages()) + eq(2, fn.tabpagenr()) + api.nvim_cmd({ cmd = 'MySplit', mods = { tab = 1 } }, {}) + eq(3, #api.nvim_list_tabpages()) + eq(2, fn.tabpagenr()) + api.nvim_cmd({ cmd = 'MySplit', mods = { tab = 3 } }, {}) + eq(4, #api.nvim_list_tabpages()) + eq(4, fn.tabpagenr()) + api.nvim_cmd({ cmd = 'MySplit', mods = { tab = 0 } }, {}) + eq(5, #api.nvim_list_tabpages()) + eq(1, fn.tabpagenr()) end) end) @@ -596,16 +759,16 @@ describe('nvim_del_user_command', function() before_each(clear) it('can delete global commands', function() - meths.create_user_command('Hello', 'echo "Hi"', {}) - meths.command('Hello') - meths.del_user_command('Hello') - matches("Not an editor command: Hello", pcall_err(meths.command, "Hello")) + api.nvim_create_user_command('Hello', 'echo "Hi"', {}) + command('Hello') + api.nvim_del_user_command('Hello') + matches('Not an editor command: Hello', pcall_err(command, 'Hello')) end) it('can delete buffer-local commands', function() - bufmeths.create_user_command(0, 'Hello', 'echo "Hi"', {}) - meths.command('Hello') - bufmeths.del_user_command(0, 'Hello') - matches("Not an editor command: Hello", pcall_err(meths.command, "Hello")) + api.nvim_buf_create_user_command(0, 'Hello', 'echo "Hi"', {}) + command('Hello') + api.nvim_buf_del_user_command(0, 'Hello') + matches('Not an editor command: Hello', pcall_err(command, 'Hello')) end) end) diff --git a/test/functional/api/extmark_spec.lua b/test/functional/api/extmark_spec.lua index 44a151cf6a..2acfbfc949 100644 --- a/test/functional/api/extmark_spec.lua +++ b/test/functional/api/extmark_spec.lua @@ -4,15 +4,13 @@ local Screen = require('test.functional.ui.screen') local request = helpers.request local eq = helpers.eq local ok = helpers.ok -local curbufmeths = helpers.curbufmeths -local bufmeths = helpers.bufmeths local pcall_err = helpers.pcall_err local insert = helpers.insert local feed = helpers.feed local clear = helpers.clear local command = helpers.command local exec = helpers.exec -local meths = helpers.meths +local api = helpers.api local assert_alive = helpers.assert_alive local function expect(contents) @@ -26,32 +24,32 @@ local function set_extmark(ns_id, id, line, col, opts) if id ~= nil and id ~= 0 then opts.id = id end - return curbufmeths.set_extmark(ns_id, line, col, opts) + return api.nvim_buf_set_extmark(0, ns_id, line, col, opts) end local function get_extmarks(ns_id, start, end_, opts) if opts == nil then opts = {} end - return curbufmeths.get_extmarks(ns_id, start, end_, opts) + return api.nvim_buf_get_extmarks(0, ns_id, start, end_, opts) end local function get_extmark_by_id(ns_id, id, opts) if opts == nil then opts = {} end - return curbufmeths.get_extmark_by_id(ns_id, id, opts) + return api.nvim_buf_get_extmark_by_id(0, ns_id, id, opts) end local function check_undo_redo(ns, mark, sr, sc, er, ec) --s = start, e = end local rv = get_extmark_by_id(ns, mark) - eq({er, ec}, rv) - feed("u") + eq({ er, ec }, rv) + feed('u') rv = get_extmark_by_id(ns, mark) - eq({sr, sc}, rv) - feed("<c-r>") + eq({ sr, sc }, rv) + feed('<c-r>') rv = get_extmark_by_id(ns, mark) - eq({er, ec}, rv) + eq({ er, ec }, rv) end local function batch_set(ns_id, positions) @@ -64,20 +62,20 @@ end local function batch_check(ns_id, ids, positions) local actual, expected = {}, {} - for i,id in ipairs(ids) do + for i, id in ipairs(ids) do expected[id] = positions[i] end for _, mark in pairs(get_extmarks(ns_id, 0, -1, {})) do - actual[mark[1]] = {mark[2], mark[3]} + actual[mark[1]] = { mark[2], mark[3] } end eq(expected, actual) end local function batch_check_undo_redo(ns_id, ids, before, after) batch_check(ns_id, ids, after) - feed("u") + feed('u') batch_check(ns_id, ids, before) - feed("<c-r>") + feed('<c-r>') batch_check(ns_id, ids, after) end @@ -88,49 +86,78 @@ describe('API/extmarks', function() before_each(function() -- Initialize some namespaces and insert 12345 into a buffer - marks = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} - positions = {{0, 0,}, {0, 2}, {0, 3}} + marks = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 } + positions = { { 0, 0 }, { 0, 2 }, { 0, 3 } } - init_text = "12345" + init_text = '12345' row = 0 col = 2 clear() insert(init_text) - ns = request('nvim_create_namespace', "my-fancy-plugin") - ns2 = request('nvim_create_namespace', "my-fancy-plugin2") + ns = request('nvim_create_namespace', 'my-fancy-plugin') + ns2 = request('nvim_create_namespace', 'my-fancy-plugin2') end) it('validation', function() - eq("Invalid 'end_col': expected Integer, got Array", pcall_err(set_extmark, ns, marks[2], 0, 0, { end_col = {}, end_row = 1 })) - eq("Invalid 'end_row': expected Integer, got Array", pcall_err(set_extmark, ns, marks[2], 0, 0, { end_col = 1, end_row = {} })) - eq("Invalid 'virt_text_pos': expected String, got Integer", pcall_err(set_extmark, ns, marks[2], 0, 0, { virt_text_pos = 0 })) - eq("Invalid 'virt_text_pos': 'foo'", pcall_err(set_extmark, ns, marks[2], 0, 0, { virt_text_pos = 'foo' })) - eq("Invalid 'hl_mode': expected String, got Integer", pcall_err(set_extmark, ns, marks[2], 0, 0, { hl_mode = 0 })) + eq( + "Invalid 'end_col': expected Integer, got Array", + pcall_err(set_extmark, ns, marks[2], 0, 0, { end_col = {}, end_row = 1 }) + ) + eq( + "Invalid 'end_row': expected Integer, got Array", + pcall_err(set_extmark, ns, marks[2], 0, 0, { end_col = 1, end_row = {} }) + ) + eq( + "Invalid 'virt_text_pos': expected String, got Integer", + pcall_err(set_extmark, ns, marks[2], 0, 0, { virt_text_pos = 0 }) + ) + eq( + "Invalid 'virt_text_pos': 'foo'", + pcall_err(set_extmark, ns, marks[2], 0, 0, { virt_text_pos = 'foo' }) + ) + eq( + "Invalid 'hl_mode': expected String, got Integer", + pcall_err(set_extmark, ns, marks[2], 0, 0, { hl_mode = 0 }) + ) eq("Invalid 'hl_mode': 'foo'", pcall_err(set_extmark, ns, marks[2], 0, 0, { hl_mode = 'foo' })) - eq("Invalid 'id': expected Integer, got Array", pcall_err(set_extmark, ns, {}, 0, 0, { end_col = 1, end_row = 1 })) - eq("Invalid mark position: expected 2 Integer items", pcall_err(get_extmarks, ns, {}, {-1, -1})) - eq("Invalid mark position: expected mark id Integer or 2-item Array", pcall_err(get_extmarks, ns, true, {-1, -1})) + eq( + "Invalid 'id': expected Integer, got Array", + pcall_err(set_extmark, ns, {}, 0, 0, { end_col = 1, end_row = 1 }) + ) + eq( + 'Invalid mark position: expected 2 Integer items', + pcall_err(get_extmarks, ns, {}, { -1, -1 }) + ) + eq( + 'Invalid mark position: expected mark id Integer or 2-item Array', + pcall_err(get_extmarks, ns, true, { -1, -1 }) + ) -- No memory leak with virt_text, virt_lines, sign_text - eq("right_gravity is not a boolean", pcall_err(set_extmark, ns, marks[2], 0, 0, { - virt_text = {{'foo', 'Normal'}}, - virt_lines = {{{'bar', 'Normal'}}}, - sign_text = 'a', - right_gravity = 'baz', - })) + eq( + 'right_gravity is not a boolean', + pcall_err(set_extmark, ns, marks[2], 0, 0, { + virt_text = { { 'foo', 'Normal' } }, + virt_lines = { { { 'bar', 'Normal' } } }, + sign_text = 'a', + right_gravity = 'baz', + }) + ) end) - it("can end extranges past final newline using end_col = 0", function() + it('can end extranges past final newline using end_col = 0', function() set_extmark(ns, marks[1], 0, 0, { end_col = 0, - end_row = 1 + end_row = 1, }) - eq("Invalid 'end_col': out of range", - pcall_err(set_extmark, ns, marks[2], 0, 0, { end_col = 1, end_row = 1 })) + eq( + "Invalid 'end_col': out of range", + pcall_err(set_extmark, ns, marks[2], 0, 0, { end_col = 1, end_row = 1 }) + ) end) - it("can end extranges past final newline when strict mode is false", function() + it('can end extranges past final newline when strict mode is false', function() set_extmark(ns, marks[1], 0, 0, { end_col = 1, end_row = 1, @@ -138,7 +165,7 @@ describe('API/extmarks', function() }) end) - it("can end extranges past final column when strict mode is false", function() + it('can end extranges past final column when strict mode is false', function() set_extmark(ns, marks[1], 0, 0, { end_col = 6, end_row = 0, @@ -150,7 +177,7 @@ describe('API/extmarks', function() local rv = set_extmark(ns, marks[1], positions[1][1], positions[1][2]) eq(marks[1], rv) rv = get_extmark_by_id(ns, marks[1]) - eq({positions[1][1], positions[1][2]}, rv) + eq({ positions[1][1], positions[1][2] }, rv) -- Test adding a second mark on same row works rv = set_extmark(ns, marks[2], positions[2][1], positions[2][2]) eq(marks[2], rv) @@ -159,21 +186,21 @@ describe('API/extmarks', function() rv = set_extmark(ns, marks[1], positions[1][1], positions[1][2]) eq(marks[1], rv) rv = get_extmark_by_id(ns, marks[2]) - eq({positions[2][1], positions[2][2]}, rv) + eq({ positions[2][1], positions[2][2] }, rv) -- Test an update, (new pos) row = positions[1][1] col = positions[1][2] + 1 rv = set_extmark(ns, marks[1], row, col) eq(marks[1], rv) rv = get_extmark_by_id(ns, marks[1]) - eq({row, col}, rv) + eq({ row, col }, rv) -- remove the test marks - eq(true, curbufmeths.del_extmark(ns, marks[1])) - eq(false, curbufmeths.del_extmark(ns, marks[1])) - eq(true, curbufmeths.del_extmark(ns, marks[2])) - eq(false, curbufmeths.del_extmark(ns, marks[3])) - eq(false, curbufmeths.del_extmark(ns, 1000)) + eq(true, api.nvim_buf_del_extmark(0, ns, marks[1])) + eq(false, api.nvim_buf_del_extmark(0, ns, marks[1])) + eq(true, api.nvim_buf_del_extmark(0, ns, marks[2])) + eq(false, api.nvim_buf_del_extmark(0, ns, marks[3])) + eq(false, api.nvim_buf_del_extmark(0, ns, 1000)) end) it('can clear a specific namespace range', function() @@ -181,15 +208,15 @@ describe('API/extmarks', function() set_extmark(ns2, 1, 0, 1) -- force a new undo buffer feed('o<esc>') - curbufmeths.clear_namespace(ns2, 0, -1) - eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) - eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) + api.nvim_buf_clear_namespace(0, ns2, 0, -1) + eq({ { 1, 0, 1 } }, get_extmarks(ns, { 0, 0 }, { -1, -1 })) + eq({}, get_extmarks(ns2, { 0, 0 }, { -1, -1 })) feed('u') - eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) - eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) + eq({ { 1, 0, 1 } }, get_extmarks(ns, { 0, 0 }, { -1, -1 })) + eq({}, get_extmarks(ns2, { 0, 0 }, { -1, -1 })) feed('<c-r>') - eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) - eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) + eq({ { 1, 0, 1 } }, get_extmarks(ns, { 0, 0 }, { -1, -1 })) + eq({}, get_extmarks(ns2, { 0, 0 }, { -1, -1 })) end) it('can clear a namespace range using 0,-1', function() @@ -197,32 +224,32 @@ describe('API/extmarks', function() set_extmark(ns2, 1, 0, 1) -- force a new undo buffer feed('o<esc>') - curbufmeths.clear_namespace(-1, 0, -1) - eq({}, get_extmarks(ns, {0, 0}, {-1, -1})) - eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) + api.nvim_buf_clear_namespace(0, -1, 0, -1) + eq({}, get_extmarks(ns, { 0, 0 }, { -1, -1 })) + eq({}, get_extmarks(ns2, { 0, 0 }, { -1, -1 })) feed('u') - eq({}, get_extmarks(ns, {0, 0}, {-1, -1})) - eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) + eq({}, get_extmarks(ns, { 0, 0 }, { -1, -1 })) + eq({}, get_extmarks(ns2, { 0, 0 }, { -1, -1 })) feed('<c-r>') - eq({}, get_extmarks(ns, {0, 0}, {-1, -1})) - eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) + eq({}, get_extmarks(ns, { 0, 0 }, { -1, -1 })) + eq({}, get_extmarks(ns2, { 0, 0 }, { -1, -1 })) end) it('can undo with extmarks (#25147)', function() feed('itest<esc>') set_extmark(ns, 1, 0, 0) set_extmark(ns, 2, 1, 0) - eq({ { 1, 0, 0 }, { 2, 1, 0 } }, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({ { 1, 0, 0 }, { 2, 1, 0 } }, get_extmarks(ns, { 0, 0 }, { -1, -1 })) feed('dd') - eq({ { 1, 1, 0 }, { 2, 1, 0 } }, get_extmarks(ns, {0, 0}, {-1, -1})) - curbufmeths.clear_namespace(ns, 0, -1) - eq({}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({ { 1, 1, 0 }, { 2, 1, 0 } }, get_extmarks(ns, { 0, 0 }, { -1, -1 })) + api.nvim_buf_clear_namespace(0, ns, 0, -1) + eq({}, get_extmarks(ns, { 0, 0 }, { -1, -1 })) set_extmark(ns, 1, 0, 0, { right_gravity = false }) set_extmark(ns, 2, 1, 0, { right_gravity = false }) - eq({ { 1, 0, 0 }, { 2, 1, 0 } }, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({ { 1, 0, 0 }, { 2, 1, 0 } }, get_extmarks(ns, { 0, 0 }, { -1, -1 })) feed('u') - eq({ { 1, 0, 0 }, { 2, 1, 0 } }, get_extmarks(ns, {0, 0}, {-1, -1})) - curbufmeths.clear_namespace(ns, 0, -1) + eq({ { 1, 0, 0 }, { 2, 1, 0 } }, get_extmarks(ns, { 0, 0 }, { -1, -1 })) + api.nvim_buf_clear_namespace(0, ns, 0, -1) end) it('querying for information and ranges', function() @@ -237,112 +264,114 @@ describe('API/extmarks', function() end -- {0, 0} and {-1, -1} work as extreme values - eq({{1, 0, 0}}, get_extmarks(ns, {0, 0}, {0, 0})) - eq({}, get_extmarks(ns, {-1, -1}, {-1, -1})) - local rv = get_extmarks(ns, {0, 0}, {-1, -1}) + eq({ { 1, 0, 0 } }, get_extmarks(ns, { 0, 0 }, { 0, 0 })) + eq({}, get_extmarks(ns, { -1, -1 }, { -1, -1 })) + local rv = get_extmarks(ns, { 0, 0 }, { -1, -1 }) for i, m in ipairs(marks) do if positions[i] ~= nil then - eq({m, positions[i][1], positions[i][2]}, rv[i]) + eq({ m, positions[i][1], positions[i][2] }, rv[i]) end end -- 0 and -1 works as short hand extreme values - eq({{1, 0, 0}}, get_extmarks(ns, 0, 0)) + eq({ { 1, 0, 0 } }, get_extmarks(ns, 0, 0)) eq({}, get_extmarks(ns, -1, -1)) rv = get_extmarks(ns, 0, -1) for i, m in ipairs(marks) do if positions[i] ~= nil then - eq({m, positions[i][1], positions[i][2]}, rv[i]) + eq({ m, positions[i][1], positions[i][2] }, rv[i]) end end -- next with mark id - rv = get_extmarks(ns, marks[1], {-1, -1}, {limit=1}) - eq({{marks[1], positions[1][1], positions[1][2]}}, rv) - rv = get_extmarks(ns, marks[2], {-1, -1}, {limit=1}) - eq({{marks[2], positions[2][1], positions[2][2]}}, rv) + rv = get_extmarks(ns, marks[1], { -1, -1 }, { limit = 1 }) + eq({ { marks[1], positions[1][1], positions[1][2] } }, rv) + rv = get_extmarks(ns, marks[2], { -1, -1 }, { limit = 1 }) + eq({ { marks[2], positions[2][1], positions[2][2] } }, rv) -- next with positional when mark exists at position - rv = get_extmarks(ns, positions[1], {-1, -1}, {limit=1}) - eq({{marks[1], positions[1][1], positions[1][2]}}, rv) + rv = get_extmarks(ns, positions[1], { -1, -1 }, { limit = 1 }) + eq({ { marks[1], positions[1][1], positions[1][2] } }, rv) -- next with positional index (no mark at position) - rv = get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {-1, -1}, {limit=1}) - eq({{marks[2], positions[2][1], positions[2][2]}}, rv) + rv = get_extmarks(ns, { positions[1][1], positions[1][2] + 1 }, { -1, -1 }, { limit = 1 }) + eq({ { marks[2], positions[2][1], positions[2][2] } }, rv) -- next with Extremity index - rv = get_extmarks(ns, {0,0}, {-1, -1}, {limit=1}) - eq({{marks[1], positions[1][1], positions[1][2]}}, rv) + rv = get_extmarks(ns, { 0, 0 }, { -1, -1 }, { limit = 1 }) + eq({ { marks[1], positions[1][1], positions[1][2] } }, rv) -- nextrange with mark id rv = get_extmarks(ns, marks[1], marks[3]) - eq({marks[1], positions[1][1], positions[1][2]}, rv[1]) - eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) + eq({ marks[1], positions[1][1], positions[1][2] }, rv[1]) + eq({ marks[2], positions[2][1], positions[2][2] }, rv[2]) -- nextrange with `limit` - rv = get_extmarks(ns, marks[1], marks[3], {limit=2}) + rv = get_extmarks(ns, marks[1], marks[3], { limit = 2 }) eq(2, #rv) -- nextrange with positional when mark exists at position rv = get_extmarks(ns, positions[1], positions[3]) - eq({marks[1], positions[1][1], positions[1][2]}, rv[1]) - eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) + eq({ marks[1], positions[1][1], positions[1][2] }, rv[1]) + eq({ marks[2], positions[2][1], positions[2][2] }, rv[2]) rv = get_extmarks(ns, positions[2], positions[3]) eq(2, #rv) -- nextrange with positional index (no mark at position) - local lower = {positions[1][1], positions[2][2] -1} - local upper = {positions[2][1], positions[3][2] - 1} + local lower = { positions[1][1], positions[2][2] - 1 } + local upper = { positions[2][1], positions[3][2] - 1 } rv = get_extmarks(ns, lower, upper) - eq({{marks[2], positions[2][1], positions[2][2]}}, rv) - lower = {positions[3][1], positions[3][2] + 1} - upper = {positions[3][1], positions[3][2] + 2} + eq({ { marks[2], positions[2][1], positions[2][2] } }, rv) + lower = { positions[3][1], positions[3][2] + 1 } + upper = { positions[3][1], positions[3][2] + 2 } rv = get_extmarks(ns, lower, upper) eq({}, rv) -- nextrange with extremity index - lower = {positions[2][1], positions[2][2]+1} - upper = {-1, -1} + lower = { positions[2][1], positions[2][2] + 1 } + upper = { -1, -1 } rv = get_extmarks(ns, lower, upper) - eq({{marks[3], positions[3][1], positions[3][2]}}, rv) + eq({ { marks[3], positions[3][1], positions[3][2] } }, rv) -- prev with mark id - rv = get_extmarks(ns, marks[3], {0, 0}, {limit=1}) - eq({{marks[3], positions[3][1], positions[3][2]}}, rv) - rv = get_extmarks(ns, marks[2], {0, 0}, {limit=1}) - eq({{marks[2], positions[2][1], positions[2][2]}}, rv) + rv = get_extmarks(ns, marks[3], { 0, 0 }, { limit = 1 }) + eq({ { marks[3], positions[3][1], positions[3][2] } }, rv) + rv = get_extmarks(ns, marks[2], { 0, 0 }, { limit = 1 }) + eq({ { marks[2], positions[2][1], positions[2][2] } }, rv) -- prev with positional when mark exists at position - rv = get_extmarks(ns, positions[3], {0, 0}, {limit=1}) - eq({{marks[3], positions[3][1], positions[3][2]}}, rv) + rv = get_extmarks(ns, positions[3], { 0, 0 }, { limit = 1 }) + eq({ { marks[3], positions[3][1], positions[3][2] } }, rv) -- prev with positional index (no mark at position) - rv = get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {0, 0}, {limit=1}) - eq({{marks[1], positions[1][1], positions[1][2]}}, rv) + rv = get_extmarks(ns, { positions[1][1], positions[1][2] + 1 }, { 0, 0 }, { limit = 1 }) + eq({ { marks[1], positions[1][1], positions[1][2] } }, rv) -- prev with Extremity index - rv = get_extmarks(ns, {-1,-1}, {0,0}, {limit=1}) - eq({{marks[3], positions[3][1], positions[3][2]}}, rv) + rv = get_extmarks(ns, { -1, -1 }, { 0, 0 }, { limit = 1 }) + eq({ { marks[3], positions[3][1], positions[3][2] } }, rv) -- prevrange with mark id rv = get_extmarks(ns, marks[3], marks[1]) - eq({marks[3], positions[3][1], positions[3][2]}, rv[1]) - eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) - eq({marks[1], positions[1][1], positions[1][2]}, rv[3]) + eq({ marks[3], positions[3][1], positions[3][2] }, rv[1]) + eq({ marks[2], positions[2][1], positions[2][2] }, rv[2]) + eq({ marks[1], positions[1][1], positions[1][2] }, rv[3]) -- prevrange with limit - rv = get_extmarks(ns, marks[3], marks[1], {limit=2}) + rv = get_extmarks(ns, marks[3], marks[1], { limit = 2 }) eq(2, #rv) -- prevrange with positional when mark exists at position rv = get_extmarks(ns, positions[3], positions[1]) - eq({{marks[3], positions[3][1], positions[3][2]}, - {marks[2], positions[2][1], positions[2][2]}, - {marks[1], positions[1][1], positions[1][2]}}, rv) + eq({ + { marks[3], positions[3][1], positions[3][2] }, + { marks[2], positions[2][1], positions[2][2] }, + { marks[1], positions[1][1], positions[1][2] }, + }, rv) rv = get_extmarks(ns, positions[2], positions[1]) eq(2, #rv) -- prevrange with positional index (no mark at position) - lower = {positions[2][1], positions[2][2] + 1} - upper = {positions[3][1], positions[3][2] + 1} + lower = { positions[2][1], positions[2][2] + 1 } + upper = { positions[3][1], positions[3][2] + 1 } rv = get_extmarks(ns, upper, lower) - eq({{marks[3], positions[3][1], positions[3][2]}}, rv) - lower = {positions[3][1], positions[3][2] + 1} - upper = {positions[3][1], positions[3][2] + 2} + eq({ { marks[3], positions[3][1], positions[3][2] } }, rv) + lower = { positions[3][1], positions[3][2] + 1 } + upper = { positions[3][1], positions[3][2] + 2 } rv = get_extmarks(ns, upper, lower) eq({}, rv) -- prevrange with extremity index - lower = {0,0} - upper = {positions[2][1], positions[2][2] - 1} + lower = { 0, 0 } + upper = { positions[2][1], positions[2][2] - 1 } rv = get_extmarks(ns, upper, lower) - eq({{marks[1], positions[1][1], positions[1][2]}}, rv) + eq({ { marks[1], positions[1][1], positions[1][2] } }, rv) end) it('querying for information with limit', function() @@ -354,34 +383,34 @@ describe('API/extmarks', function() end end - local rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=1}) + local rv = get_extmarks(ns, { 0, 0 }, { -1, -1 }, { limit = 1 }) eq(1, #rv) - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=2}) + rv = get_extmarks(ns, { 0, 0 }, { -1, -1 }, { limit = 2 }) eq(2, #rv) - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=3}) + rv = get_extmarks(ns, { 0, 0 }, { -1, -1 }, { limit = 3 }) eq(3, #rv) -- now in reverse - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=1}) + rv = get_extmarks(ns, { 0, 0 }, { -1, -1 }, { limit = 1 }) eq(1, #rv) - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=2}) + rv = get_extmarks(ns, { 0, 0 }, { -1, -1 }, { limit = 2 }) eq(2, #rv) - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=3}) + rv = get_extmarks(ns, { 0, 0 }, { -1, -1 }, { limit = 3 }) eq(3, #rv) end) it('get_marks works when mark col > upper col', function() feed('A<cr>12345<esc>') feed('A<cr>12345<esc>') - set_extmark(ns, 10, 0, 2) -- this shouldn't be found - set_extmark(ns, 11, 2, 1) -- this shouldn't be found + set_extmark(ns, 10, 0, 2) -- this shouldn't be found + set_extmark(ns, 11, 2, 1) -- this shouldn't be found set_extmark(ns, marks[1], 0, 4) -- check col > our upper bound set_extmark(ns, marks[2], 1, 1) -- check col < lower bound set_extmark(ns, marks[3], 2, 0) -- check is inclusive - eq({{marks[1], 0, 4}, - {marks[2], 1, 1}, - {marks[3], 2, 0}}, - get_extmarks(ns, {0, 3}, {2, 0})) + eq( + { { marks[1], 0, 4 }, { marks[2], 1, 1 }, { marks[3], 2, 0 } }, + get_extmarks(ns, { 0, 3 }, { 2, 0 }) + ) end) it('get_marks works in reverse when mark col < lower col', function() @@ -392,28 +421,24 @@ describe('API/extmarks', function() set_extmark(ns, marks[1], 2, 1) -- check col < our lower bound set_extmark(ns, marks[2], 1, 4) -- check col > upper bound set_extmark(ns, marks[3], 0, 2) -- check is inclusive - local rv = get_extmarks(ns, {2, 3}, {0, 2}) - eq({{marks[1], 2, 1}, - {marks[2], 1, 4}, - {marks[3], 0, 2}}, - rv) + local rv = get_extmarks(ns, { 2, 3 }, { 0, 2 }) + eq({ { marks[1], 2, 1 }, { marks[2], 1, 4 }, { marks[3], 0, 2 } }, rv) end) it('get_marks limit=0 returns nothing', function() set_extmark(ns, marks[1], positions[1][1], positions[1][2]) - local rv = get_extmarks(ns, {-1, -1}, {-1, -1}, {limit=0}) + local rv = get_extmarks(ns, { -1, -1 }, { -1, -1 }, { limit = 0 }) eq({}, rv) end) - it('marks move with line insertations', function() set_extmark(ns, marks[1], 0, 0) - feed("yyP") + feed('yyP') check_undo_redo(ns, marks[1], 0, 0, 1, 0) end) it('marks move with multiline insertations', function() - feed("a<cr>22<cr>33<esc>") + feed('a<cr>22<cr>33<esc>') set_extmark(ns, marks[1], 1, 1) feed('ggVGyP') check_undo_redo(ns, marks[1], 1, 1, 4, 1) @@ -421,7 +446,7 @@ describe('API/extmarks', function() it('marks move with line join', function() -- do_join in ops.c - feed("a<cr>222<esc>") + feed('a<cr>222<esc>') set_extmark(ns, marks[1], 1, 0) feed('ggJ') check_undo_redo(ns, marks[1], 1, 0, 0, 6) @@ -430,40 +455,33 @@ describe('API/extmarks', function() it('join works when no marks are present', function() screen = Screen.new(15, 10) screen:attach() - feed("a<cr>1<esc>") + feed('a<cr>1<esc>') feed('kJ') -- This shouldn't seg fault screen:expect([[ 12345^ 1 | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*8 | ]]) end) it('marks move with multiline join', function() -- do_join in ops.c - feed("a<cr>222<cr>333<cr>444<esc>") + feed('a<cr>222<cr>333<cr>444<esc>') set_extmark(ns, marks[1], 3, 0) feed('2GVGJ') check_undo_redo(ns, marks[1], 3, 0, 1, 8) end) it('marks move with line deletes', function() - feed("a<cr>222<cr>333<cr>444<esc>") + feed('a<cr>222<cr>333<cr>444<esc>') set_extmark(ns, marks[1], 2, 1) feed('ggjdd') check_undo_redo(ns, marks[1], 2, 1, 1, 1) end) it('marks move with multiline deletes', function() - feed("a<cr>222<cr>333<cr>444<esc>") + feed('a<cr>222<cr>333<cr>444<esc>') set_extmark(ns, marks[1], 3, 0) feed('gg2dd') check_undo_redo(ns, marks[1], 3, 0, 1, 0) @@ -475,7 +493,7 @@ describe('API/extmarks', function() it('marks move with open line', function() -- open_line in change.c -- testing marks below are also moved - feed("yyP") + feed('yyP') set_extmark(ns, marks[1], 0, 4) set_extmark(ns, marks[2], 1, 4) feed('1G<s-o><esc>') @@ -495,18 +513,11 @@ describe('API/extmarks', function() insert('abc') screen:expect([[ ab^c12345 | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*8 | ]]) local rv = get_extmark_by_id(ns, marks[1]) - eq({0, 6}, rv) + eq({ 0, 6 }, rv) check_undo_redo(ns, marks[1], 0, 3, 0, 6) end) @@ -515,12 +526,12 @@ describe('API/extmarks', function() -- insertchar in edit.c (the ins_str branch) set_extmark(ns, marks[1], 0, 2) feed('03l') - insert("X") + insert('X') check_undo_redo(ns, marks[1], 0, 2, 0, 2) -- check multibyte chars feed('03l<esc>') - insert("~~") + insert('~~') check_undo_redo(ns, marks[1], 0, 2, 0, 2) end) @@ -544,7 +555,7 @@ describe('API/extmarks', function() it('marks move with line splits (using enter)', function() -- open_line in change.c -- testing marks below are also moved - feed("yyP") + feed('yyP') set_extmark(ns, marks[1], 0, 4) set_extmark(ns, marks[2], 1, 4) feed('1Gla<cr><esc>') @@ -561,16 +572,16 @@ describe('API/extmarks', function() it('yet again marks move with line splits', function() -- the first test above wasn't catching all errors.. - feed("A67890<esc>") + feed('A67890<esc>') set_extmark(ns, marks[1], 0, 4) - feed("04li<cr><esc>") + feed('04li<cr><esc>') check_undo_redo(ns, marks[1], 0, 4, 1, 0) end) it('and one last time line splits...', function() set_extmark(ns, marks[1], 0, 1) set_extmark(ns, marks[2], 0, 2) - feed("02li<cr><esc>") + feed('02li<cr><esc>') check_undo_redo(ns, marks[1], 0, 1, 0, 1) check_undo_redo(ns, marks[2], 0, 2, 1, 0) end) @@ -578,7 +589,7 @@ describe('API/extmarks', function() it('multiple marks move with mark splits', function() set_extmark(ns, marks[1], 0, 1) set_extmark(ns, marks[2], 0, 3) - feed("0li<cr><esc>") + feed('0li<cr><esc>') check_undo_redo(ns, marks[1], 0, 1, 1, 0) check_undo_redo(ns, marks[2], 0, 3, 1, 2) end) @@ -670,11 +681,11 @@ describe('API/extmarks', function() feed('0vx<esc>') check_undo_redo(ns, marks[1], 0, 3, 0, 2) - feed("u") + feed('u') feed('0vlx<esc>') check_undo_redo(ns, marks[1], 0, 3, 0, 1) - feed("u") + feed('u') feed('0v2lx<esc>') check_undo_redo(ns, marks[1], 0, 3, 0, 0) @@ -689,16 +700,16 @@ describe('API/extmarks', function() feed('0x<esc>') check_undo_redo(ns, marks[1], 0, 3, 0, 2) - feed("u") + feed('u') feed('02x<esc>') check_undo_redo(ns, marks[1], 0, 3, 0, 1) - feed("u") + feed('u') feed('0v3lx<esc>') check_undo_redo(ns, marks[1], 0, 3, 0, 0) -- from the other side (nothing should happen) - feed("u") + feed('u') feed('$vx') check_undo_redo(ns, marks[1], 0, 3, 0, 3) end) @@ -756,27 +767,44 @@ describe('API/extmarks', function() it('delete', function() local pos1 = { - {2, 4}, {2, 12}, {2, 13}, {2, 14}, {2, 25}, - {4, 8}, {4, 10}, {4, 20}, - {5, 3}, {6, 10} + { 2, 4 }, + { 2, 12 }, + { 2, 13 }, + { 2, 14 }, + { 2, 25 }, + { 4, 8 }, + { 4, 10 }, + { 4, 20 }, + { 5, 3 }, + { 6, 10 }, } local ids = batch_set(ns, pos1) batch_check(ns, ids, pos1) feed('3Gfiv2+ftd') batch_check_undo_redo(ns, ids, pos1, { - {2, 4}, {2, 12}, {2, 13}, {2, 13}, {2, 13}, - {2, 13}, {2, 15}, {2, 25}, - {3, 3}, {4, 10} + { 2, 4 }, + { 2, 12 }, + { 2, 13 }, + { 2, 13 }, + { 2, 13 }, + { 2, 13 }, + { 2, 15 }, + { 2, 25 }, + { 3, 3 }, + { 4, 10 }, }) end) it('can get overlapping extmarks', function() - set_extmark(ns, 1, 0, 0, {end_row = 5, end_col=0}) - set_extmark(ns, 2, 2, 5, {end_row = 2, end_col=30}) - set_extmark(ns, 3, 0, 5, {end_row = 2, end_col=10}) - set_extmark(ns, 4, 0, 0, {end_row = 1, end_col=0}) - eq({{ 2, 2, 5 }}, get_extmarks(ns, {2, 0}, {2, -1}, { overlap=false })) - eq({{ 1, 0, 0 }, { 3, 0, 5}, {2, 2, 5}}, get_extmarks(ns, {2, 0}, {2, -1}, { overlap=true })) + set_extmark(ns, 1, 0, 0, { end_row = 5, end_col = 0 }) + set_extmark(ns, 2, 2, 5, { end_row = 2, end_col = 30 }) + set_extmark(ns, 3, 0, 5, { end_row = 2, end_col = 10 }) + set_extmark(ns, 4, 0, 0, { end_row = 1, end_col = 0 }) + eq({ { 2, 2, 5 } }, get_extmarks(ns, { 2, 0 }, { 2, -1 }, { overlap = false })) + eq( + { { 1, 0, 0 }, { 3, 0, 5 }, { 2, 2, 5 } }, + get_extmarks(ns, { 2, 0 }, { 2, -1 }, { overlap = true }) + ) end) end) @@ -876,33 +904,40 @@ describe('API/extmarks', function() set_extmark(ns, marks[2], 0, -1) set_extmark(ns, marks[3], 0, -1) - feed("u") - local rv = get_extmarks(ns, {0, 0}, {-1, -1}) + feed('u') + local rv = get_extmarks(ns, { 0, 0 }, { -1, -1 }) eq(3, #rv) - feed("<c-r>") - rv = get_extmarks(ns, {0, 0}, {-1, -1}) + feed('<c-r>') + rv = get_extmarks(ns, { 0, 0 }, { -1, -1 }) eq(3, #rv) -- Test updates feed('o<esc>') set_extmark(ns, marks[1], positions[1][1], positions[1][2]) - rv = get_extmarks(ns, marks[1], marks[1], {limit=1}) + rv = get_extmarks(ns, marks[1], marks[1], { limit = 1 }) eq(1, #rv) - feed("u") - feed("<c-r>") + feed('u') + feed('<c-r>') -- old value is NOT kept in history - check_undo_redo(ns, marks[1], positions[1][1], positions[1][2], positions[1][1], positions[1][2]) + check_undo_redo( + ns, + marks[1], + positions[1][1], + positions[1][2], + positions[1][1], + positions[1][2] + ) -- Test unset feed('o<esc>') - curbufmeths.del_extmark(ns, marks[3]) - feed("u") - rv = get_extmarks(ns, {0, 0}, {-1, -1}) + api.nvim_buf_del_extmark(0, ns, marks[3]) + feed('u') + rv = get_extmarks(ns, { 0, 0 }, { -1, -1 }) -- undo does NOT restore deleted marks eq(2, #rv) - feed("<c-r>") - rv = get_extmarks(ns, {0, 0}, {-1, -1}) + feed('<c-r>') + rv = get_extmarks(ns, { 0, 0 }, { -1, -1 }) eq(2, #rv) end) @@ -919,9 +954,9 @@ describe('API/extmarks', function() eq(1, rv) rv = set_extmark(ns2, marks[1], positions[1][1], positions[1][2]) eq(1, rv) - rv = get_extmarks(ns, {0, 0}, {-1, -1}) + rv = get_extmarks(ns, { 0, 0 }, { -1, -1 }) eq(1, #rv) - rv = get_extmarks(ns2, {0, 0}, {-1, -1}) + rv = get_extmarks(ns2, { 0, 0 }, { -1, -1 }) eq(1, #rv) -- Set more marks for testing the ranges @@ -931,14 +966,14 @@ describe('API/extmarks', function() set_extmark(ns2, marks[3], positions[3][1], positions[3][2]) -- get_next (limit set) - rv = get_extmarks(ns, {0, 0}, positions[2], {limit=1}) + rv = get_extmarks(ns, { 0, 0 }, positions[2], { limit = 1 }) eq(1, #rv) - rv = get_extmarks(ns2, {0, 0}, positions[2], {limit=1}) + rv = get_extmarks(ns2, { 0, 0 }, positions[2], { limit = 1 }) eq(1, #rv) -- get_prev (limit set) - rv = get_extmarks(ns, positions[1], {0, 0}, {limit=1}) + rv = get_extmarks(ns, positions[1], { 0, 0 }, { limit = 1 }) eq(1, #rv) - rv = get_extmarks(ns2, positions[1], {0, 0}, {limit=1}) + rv = get_extmarks(ns2, positions[1], { 0, 0 }, { limit = 1 }) eq(1, #rv) -- get_next (no limit) @@ -952,11 +987,11 @@ describe('API/extmarks', function() rv = get_extmarks(ns2, positions[2], positions[1]) eq(2, #rv) - curbufmeths.del_extmark(ns, marks[1]) - rv = get_extmarks(ns, {0, 0}, {-1, -1}) + api.nvim_buf_del_extmark(0, ns, marks[1]) + rv = get_extmarks(ns, { 0, 0 }, { -1, -1 }) eq(2, #rv) - curbufmeths.del_extmark(ns2, marks[1]) - rv = get_extmarks(ns2, {0, 0}, {-1, -1}) + api.nvim_buf_del_extmark(0, ns2, marks[1]) + rv = get_extmarks(ns2, { 0, 0 }, { -1, -1 }) eq(2, #rv) end) @@ -980,16 +1015,16 @@ describe('API/extmarks', function() feed(':set cindent<cr><esc>') feed(':set autoindent<cr><esc>') feed(':set shiftwidth=2<cr><esc>') - feed("0iint <esc>A {1M1<esc>b<esc>") + feed('0iint <esc>A {1M1<esc>b<esc>') -- Set the mark on the M, should move.. set_extmark(ns, marks[1], 0, 12) -- Set the mark before the cursor, should stay there set_extmark(ns, marks[2], 0, 10) - feed("i<cr><esc>") + feed('i<cr><esc>') local rv = get_extmark_by_id(ns, marks[1]) - eq({1, 3}, rv) + eq({ 1, 3 }, rv) rv = get_extmark_by_id(ns, marks[2]) - eq({0, 10}, rv) + eq({ 0, 10 }, rv) check_undo_redo(ns, marks[1], 0, 12, 1, 3) end) @@ -998,39 +1033,39 @@ describe('API/extmarks', function() feed(':set autoindent<cr><esc>') feed(':set shiftwidth=2<cr><esc>') -- <c-f> will force an indent of 2 - feed("0iint <esc>A {<cr><esc>0i1M1<esc>") + feed('0iint <esc>A {<cr><esc>0i1M1<esc>') set_extmark(ns, marks[1], 1, 1) - feed("0i<c-f><esc>") + feed('0i<c-f><esc>') local rv = get_extmark_by_id(ns, marks[1]) - eq({1, 3}, rv) + eq({ 1, 3 }, rv) check_undo_redo(ns, marks[1], 1, 1, 1, 3) -- now check when cursor at eol - feed("uA<c-f><esc>") + feed('uA<c-f><esc>') rv = get_extmark_by_id(ns, marks[1]) - eq({1, 3}, rv) + eq({ 1, 3 }, rv) end) it('removing auto indenting with <C-D> works', function() feed(':set cindent<cr><esc>') feed(':set autoindent<cr><esc>') feed(':set shiftwidth=2<cr><esc>') - feed("0i<tab><esc>") + feed('0i<tab><esc>') set_extmark(ns, marks[1], 0, 3) - feed("bi<c-d><esc>") + feed('bi<c-d><esc>') local rv = get_extmark_by_id(ns, marks[1]) - eq({0, 1}, rv) + eq({ 0, 1 }, rv) check_undo_redo(ns, marks[1], 0, 3, 0, 1) -- check when cursor at eol - feed("uA<c-d><esc>") + feed('uA<c-d><esc>') rv = get_extmark_by_id(ns, marks[1]) - eq({0, 1}, rv) + eq({ 0, 1 }, rv) end) it('indenting multiple lines with = works', function() feed(':set cindent<cr><esc>') feed(':set autoindent<cr><esc>') feed(':set shiftwidth=2<cr><esc>') - feed("0iint <esc>A {<cr><bs>1M1<cr><bs>2M2<esc>") + feed('0iint <esc>A {<cr><bs>1M1<cr><bs>2M2<esc>') set_extmark(ns, marks[1], 1, 1) set_extmark(ns, marks[2], 2, 1) feed('=gg') @@ -1152,7 +1187,7 @@ describe('API/extmarks', function() check_undo_redo(ns, marks[5], 2, 0, 3, 0) feed('u') feed([[:1,2s:3:\rxx<cr>]]) - eq({1, 3}, get_extmark_by_id(ns, marks[3])) + eq({ 1, 3 }, get_extmark_by_id(ns, marks[3])) end) it('substitutes over multiple lines with replace in substitution', function() @@ -1388,8 +1423,11 @@ describe('API/extmarks', function() it('throws consistent error codes', function() local ns_invalid = ns2 + 1 - eq("Invalid 'ns_id': 3", pcall_err(set_extmark, ns_invalid, marks[1], positions[1][1], positions[1][2])) - eq("Invalid 'ns_id': 3", pcall_err(curbufmeths.del_extmark, ns_invalid, marks[1])) + eq( + "Invalid 'ns_id': 3", + pcall_err(set_extmark, ns_invalid, marks[1], positions[1][1], positions[1][2]) + ) + eq("Invalid 'ns_id': 3", pcall_err(api.nvim_buf_del_extmark, 0, ns_invalid, marks[1])) eq("Invalid 'ns_id': 3", pcall_err(get_extmarks, ns_invalid, positions[1], positions[2])) eq("Invalid 'ns_id': 3", pcall_err(get_extmark_by_id, ns_invalid, marks[1])) end) @@ -1397,11 +1435,11 @@ describe('API/extmarks', function() it('when col = line-length, set the mark on eol', function() set_extmark(ns, marks[1], 0, -1) local rv = get_extmark_by_id(ns, marks[1]) - eq({0, init_text:len()}, rv) + eq({ 0, init_text:len() }, rv) -- Test another set_extmark(ns, marks[1], 0, -1) rv = get_extmark_by_id(ns, marks[1]) - eq({0, init_text:len()}, rv) + eq({ 0, init_text:len() }, rv) end) it('when col = line-length, set the mark on eol', function() @@ -1412,7 +1450,10 @@ describe('API/extmarks', function() it('fails when line > line_count', function() local invalid_col = init_text:len() + 1 local invalid_lnum = 3 - eq("Invalid 'line': out of range", pcall_err(set_extmark, ns, marks[1], invalid_lnum, invalid_col)) + eq( + "Invalid 'line': out of range", + pcall_err(set_extmark, ns, marks[1], invalid_lnum, invalid_col) + ) eq({}, get_extmark_by_id(ns, marks[1])) end) @@ -1428,17 +1469,17 @@ describe('API/extmarks', function() end) it('in read-only buffer', function() - command("view! runtime/doc/help.txt") - eq(true, meths.get_option_value('ro', {})) + command('view! runtime/doc/help.txt') + eq(true, api.nvim_get_option_value('ro', {})) local id = set_extmark(ns, 0, 0, 2) - eq({{id, 0, 2}}, get_extmarks(ns,0, -1)) + eq({ { id, 0, 2 } }, get_extmarks(ns, 0, -1)) end) it('can set a mark to other buffer', function() local buf = request('nvim_create_buf', 0, 1) - request('nvim_buf_set_lines', buf, 0, -1, 1, {"", ""}) - local id = bufmeths.set_extmark(buf, ns, 1, 0, {}) - eq({{id, 1, 0}}, bufmeths.get_extmarks(buf, ns, 0, -1, {})) + request('nvim_buf_set_lines', buf, 0, -1, 1, { '', '' }) + local id = api.nvim_buf_set_extmark(buf, ns, 1, 0, {}) + eq({ { id, 1, 0 } }, api.nvim_buf_get_extmarks(buf, ns, 0, -1, {})) end) it('does not crash with append/delete/undo sequence', function() @@ -1454,210 +1495,274 @@ describe('API/extmarks', function() it('works with left and right gravity', function() -- right gravity should move with inserted text, while -- left gravity should stay in place. - curbufmeths.set_extmark(ns, 0, 5, {right_gravity = false}) - curbufmeths.set_extmark(ns, 0, 5, {right_gravity = true}) + api.nvim_buf_set_extmark(0, ns, 0, 5, { right_gravity = false }) + api.nvim_buf_set_extmark(0, ns, 0, 5, { right_gravity = true }) feed([[Aasdfasdf]]) - eq({ {1, 0, 5}, {2, 0, 13} }, - curbufmeths.get_extmarks(ns, 0, -1, {})) + eq({ { 1, 0, 5 }, { 2, 0, 13 } }, api.nvim_buf_get_extmarks(0, ns, 0, -1, {})) -- but both move when text is inserted before feed([[<esc>Iasdf<esc>]]) - -- eq({}, curbufmeths.get_lines(0, -1, true)) - eq({ {1, 0, 9}, {2, 0, 17} }, - curbufmeths.get_extmarks(ns, 0, -1, {})) + -- eq({}, api.nvim_buf_get_lines(0, 0, -1, true)) + eq({ { 1, 0, 9 }, { 2, 0, 17 } }, api.nvim_buf_get_extmarks(0, ns, 0, -1, {})) -- clear text - curbufmeths.set_text(0, 0, 0, 17, {}) + api.nvim_buf_set_text(0, 0, 0, 0, 17, {}) -- handles set_text correctly as well - eq({ {1, 0, 0}, {2, 0, 0} }, - meths.buf_get_extmarks(0, ns, 0, -1, {})) - curbufmeths.set_text(0, 0, 0, 0, {'asdfasdf'}) - eq({ {1, 0, 0}, {2, 0, 8} }, - curbufmeths.get_extmarks(ns, 0, -1, {})) + eq({ { 1, 0, 0 }, { 2, 0, 0 } }, api.nvim_buf_get_extmarks(0, ns, 0, -1, {})) + api.nvim_buf_set_text(0, 0, 0, 0, 0, { 'asdfasdf' }) + eq({ { 1, 0, 0 }, { 2, 0, 8 } }, api.nvim_buf_get_extmarks(0, ns, 0, -1, {})) feed('u') -- handles pasting exec([[let @a='asdfasdf']]) feed([["ap]]) - eq({ {1, 0, 0}, {2, 0, 8} }, - meths.buf_get_extmarks(0, ns, 0, -1, {})) + eq({ { 1, 0, 0 }, { 2, 0, 8 } }, api.nvim_buf_get_extmarks(0, ns, 0, -1, {})) end) it('can accept "end_row" or "end_line" #16548', function() set_extmark(ns, marks[1], 0, 0, { end_col = 0, - end_line = 1 + end_line = 1, }) - eq({ {1, 0, 0, { - ns_id = 1, - end_col = 0, - end_row = 1, - right_gravity = true, - end_right_gravity = false, - }} }, get_extmarks(ns, 0, -1, {details=true})) + eq({ + { + 1, + 0, + 0, + { + ns_id = 1, + end_col = 0, + end_row = 1, + right_gravity = true, + end_right_gravity = false, + }, + }, + }, get_extmarks(ns, 0, -1, { details = true })) end) it('in prompt buffer', function() feed('dd') local id = set_extmark(ns, marks[1], 0, 0, {}) - meths.set_option_value('buftype', 'prompt', {}) + api.nvim_set_option_value('buftype', 'prompt', {}) feed('i<esc>') - eq({{id, 0, 2}}, get_extmarks(ns, 0, -1)) + eq({ { id, 0, 2 } }, get_extmarks(ns, 0, -1)) end) it('can get details', function() set_extmark(ns, marks[1], 0, 0, { - conceal = "c", - cursorline_hl_group = "Statement", + conceal = 'c', + cursorline_hl_group = 'Statement', end_col = 0, end_right_gravity = true, end_row = 1, hl_eol = true, - hl_group = "String", - hl_mode = "blend", - line_hl_group = "Statement", - number_hl_group = "Statement", + hl_group = 'String', + hl_mode = 'blend', + line_hl_group = 'Statement', + number_hl_group = 'Statement', priority = 0, right_gravity = false, - sign_hl_group = "Statement", - sign_text = ">>", + sign_hl_group = 'Statement', + sign_text = '>>', spell = true, virt_lines = { - { { "lines", "Macro" }, { "???" } }, - { { "stack", { "Type", "Search" } }, { "!!!" } }, + { { 'lines', 'Macro' }, { '???' } }, + { { 'stack', { 'Type', 'Search' } }, { '!!!' } }, }, virt_lines_above = true, virt_lines_leftcol = true, - virt_text = { { "text", "Macro" }, { "???" }, { "stack", { "Type", "Search" } } }, + virt_text = { { 'text', 'Macro' }, { '???' }, { 'stack', { 'Type', 'Search' } } }, virt_text_hide = true, - virt_text_pos = "right_align", + virt_text_pos = 'right_align', }) set_extmark(ns, marks[2], 0, 0, { priority = 0, - virt_text = { { "", "Macro" }, { "", { "Type", "Search" } }, { "" } }, + virt_text = { { '', 'Macro' }, { '', { 'Type', 'Search' } }, { '' } }, virt_text_win_col = 1, }) - eq({0, 0, { - conceal = "c", - cursorline_hl_group = "Statement", - end_col = 0, - end_right_gravity = true, - end_row = 1, - hl_eol = true, - hl_group = "String", - hl_mode = "blend", - line_hl_group = "Statement", - ns_id = 1, - number_hl_group = "Statement", - priority = 0, - right_gravity = false, - sign_hl_group = "Statement", - sign_text = ">>", + eq({ + 0, + 0, + { + conceal = 'c', + cursorline_hl_group = 'Statement', + end_col = 0, + end_right_gravity = true, + end_row = 1, + hl_eol = true, + hl_group = 'String', + hl_mode = 'blend', + line_hl_group = 'Statement', + ns_id = 1, + number_hl_group = 'Statement', + priority = 0, + right_gravity = false, + sign_hl_group = 'Statement', + sign_text = '>>', + spell = true, + virt_lines = { + { { 'lines', 'Macro' }, { '???' } }, + { { 'stack', { 'Type', 'Search' } }, { '!!!' } }, + }, + virt_lines_above = true, + virt_lines_leftcol = true, + virt_text = { { 'text', 'Macro' }, { '???' }, { 'stack', { 'Type', 'Search' } } }, + virt_text_repeat_linebreak = false, + virt_text_hide = true, + virt_text_pos = 'right_align', + }, + }, get_extmark_by_id(ns, marks[1], { details = true })) + eq({ + 0, + 0, + { + ns_id = 1, + right_gravity = true, + priority = 0, + virt_text = { { '', 'Macro' }, { '', { 'Type', 'Search' } }, { '' } }, + virt_text_repeat_linebreak = false, + virt_text_hide = false, + virt_text_pos = 'win_col', + virt_text_win_col = 1, + }, + }, get_extmark_by_id(ns, marks[2], { details = true })) + set_extmark(ns, marks[3], 0, 0, { cursorline_hl_group = 'Statement' }) + eq({ + 0, + 0, + { + ns_id = 1, + cursorline_hl_group = 'Statement', + priority = 4096, + right_gravity = true, + }, + }, get_extmark_by_id(ns, marks[3], { details = true })) + set_extmark(ns, marks[4], 0, 0, { + end_col = 1, + conceal = 'a', spell = true, - virt_lines = { - { { "lines", "Macro" }, { "???" } }, - { { "stack", { "Type", "Search" } }, { "!!!" } }, + }) + eq({ + 0, + 0, + { + conceal = 'a', + end_col = 1, + end_right_gravity = false, + end_row = 0, + ns_id = 1, + right_gravity = true, + spell = true, }, - virt_lines_above = true, - virt_lines_leftcol = true, - virt_text = { { "text", "Macro" }, { "???" }, { "stack", { "Type", "Search" } } }, - virt_text_hide = true, - virt_text_pos = "right_align", - } }, get_extmark_by_id(ns, marks[1], { details = true })) - eq({0, 0, { - ns_id = 1, - right_gravity = true, - priority = 0, - virt_text = { { "", "Macro" }, { "", { "Type", "Search" } }, { "" } }, - virt_text_hide = false, - virt_text_pos = "win_col", - virt_text_win_col = 1, - } }, get_extmark_by_id(ns, marks[2], { details = true })) - set_extmark(ns, marks[3], 0, 0, { cursorline_hl_group = "Statement" }) - eq({0, 0, { - ns_id = 1, - cursorline_hl_group = "Statement", - priority = 4096, - right_gravity = true, - } }, get_extmark_by_id(ns, marks[3], { details = true })) - curbufmeths.clear_namespace(ns, 0, -1) + }, get_extmark_by_id(ns, marks[4], { details = true })) + set_extmark(ns, marks[5], 0, 0, { + end_col = 1, + spell = false, + }) + eq({ + 0, + 0, + { + end_col = 1, + end_right_gravity = false, + end_row = 0, + ns_id = 1, + right_gravity = true, + spell = false, + }, + }, get_extmark_by_id(ns, marks[5], { details = true })) + api.nvim_buf_clear_namespace(0, ns, 0, -1) -- legacy sign mark includes sign name command('sign define sign1 text=s1 texthl=Title linehl=LineNR numhl=Normal culhl=CursorLine') command('sign place 1 name=sign1 line=1') - eq({ {1, 0, 0, { - cursorline_hl_group = 'CursorLine', - invalidate = true, - line_hl_group = 'LineNr', - ns_id = 0, - number_hl_group = 'Normal', - priority = 10, - right_gravity = true, - sign_hl_group = 'Title', - sign_name = 'sign1', - sign_text = 's1', - undo_restore = false - } } }, get_extmarks(-1, 0, -1, { details = true })) + eq({ + { + 1, + 0, + 0, + { + cursorline_hl_group = 'CursorLine', + invalidate = true, + line_hl_group = 'LineNr', + ns_id = 0, + number_hl_group = 'Normal', + priority = 10, + right_gravity = true, + sign_hl_group = 'Title', + sign_name = 'sign1', + sign_text = 's1', + undo_restore = false, + }, + }, + }, get_extmarks(-1, 0, -1, { details = true })) end) it('can get marks from anonymous namespaces', function() - ns = request('nvim_create_namespace', "") - ns2 = request('nvim_create_namespace', "") + ns = request('nvim_create_namespace', '') + ns2 = request('nvim_create_namespace', '') set_extmark(ns, 1, 0, 0, {}) set_extmark(ns2, 2, 1, 0, {}) - eq({{ 1, 0, 0, { ns_id = ns, right_gravity = true }}, - { 2, 1, 0, { ns_id = ns2, right_gravity = true }}}, - get_extmarks(-1, 0, -1, { details = true })) + eq({ + { 1, 0, 0, { ns_id = ns, right_gravity = true } }, + { 2, 1, 0, { ns_id = ns2, right_gravity = true } }, + }, get_extmarks(-1, 0, -1, { details = true })) end) it('can filter by extmark properties', function() set_extmark(ns, 1, 0, 0, {}) set_extmark(ns, 2, 0, 0, { hl_group = 'Normal' }) set_extmark(ns, 3, 0, 0, { sign_text = '>>' }) - set_extmark(ns, 4, 0, 0, { virt_text = {{'text', 'Normal'}}}) - set_extmark(ns, 5, 0, 0, { virt_lines = {{{ 'line', 'Normal' }}}}) + set_extmark(ns, 4, 0, 0, { virt_text = { { 'text', 'Normal' } } }) + set_extmark(ns, 5, 0, 0, { virt_lines = { { { 'line', 'Normal' } } } }) eq(5, #get_extmarks(-1, 0, -1, {})) - eq({{ 2, 0, 0 }}, get_extmarks(-1, 0, -1, { type = 'highlight' })) - eq({{ 3, 0, 0 }}, get_extmarks(-1, 0, -1, { type = 'sign' })) - eq({{ 4, 0, 0 }}, get_extmarks(-1, 0, -1, { type = 'virt_text' })) - eq({{ 5, 0, 0 }}, get_extmarks(-1, 0, -1, { type = 'virt_lines' })) + eq({ { 2, 0, 0 } }, get_extmarks(-1, 0, -1, { type = 'highlight' })) + eq({ { 3, 0, 0 } }, get_extmarks(-1, 0, -1, { type = 'sign' })) + eq({ { 4, 0, 0 } }, get_extmarks(-1, 0, -1, { type = 'virt_text' })) + eq({ { 5, 0, 0 } }, get_extmarks(-1, 0, -1, { type = 'virt_lines' })) end) - it("invalidated marks are deleted", function() + it('invalidated marks are deleted', function() screen = Screen.new(40, 6) screen:attach() feed('dd6iaaa bbb ccc<CR><ESC>gg') - set_extmark(ns, 1, 0, 0, { invalidate = true, sign_text = 'S1' }) - set_extmark(ns, 2, 1, 0, { invalidate = true, sign_text = 'S2' }) + api.nvim_set_option_value('signcolumn', 'auto:2', {}) + set_extmark(ns, 1, 0, 0, { invalidate = true, sign_text = 'S1', end_row = 1 }) + set_extmark(ns, 2, 1, 0, { invalidate = true, sign_text = 'S2', end_row = 2 }) -- mark with invalidate is removed - command('d') + command('d2') screen:expect([[ S2^aaa bbb ccc | - aaa bbb ccc | - aaa bbb ccc | - aaa bbb ccc | - aaa bbb ccc | - | + aaa bbb ccc |*3 + |*2 ]]) -- mark is restored with undo_restore == true command('silent undo') screen:expect([[ - S1^aaa bbb ccc | - S2aaa bbb ccc | - aaa bbb ccc | - aaa bbb ccc | - aaa bbb ccc | + S1 ^aaa bbb ccc | + S1S2aaa bbb ccc | + S2 aaa bbb ccc | + aaa bbb ccc |*2 | ]]) + -- decor is not removed twice + command('d3') + api.nvim_buf_del_extmark(0, ns, 1) + command('silent undo') -- mark is deleted with undo_restore == false set_extmark(ns, 1, 0, 0, { invalidate = true, undo_restore = false, sign_text = 'S1' }) set_extmark(ns, 2, 1, 0, { invalidate = true, undo_restore = false, sign_text = 'S2' }) command('1d 2') eq(0, #get_extmarks(-1, 0, -1, {})) -- mark is not removed when deleting bytes before the range - set_extmark(ns, 3, 0, 4, { invalidate = true, undo_restore = false, - hl_group = 'Error', end_col = 7 }) + set_extmark( + ns, + 3, + 0, + 4, + { invalidate = true, undo_restore = false, hl_group = 'Error', end_col = 7 } + ) feed('dw') eq(3, get_extmark_by_id(ns, 3, { details = true })[3].end_col) -- mark is not removed when deleting bytes at the start of the range @@ -1665,22 +1770,64 @@ describe('API/extmarks', function() eq(2, get_extmark_by_id(ns, 3, { details = true })[3].end_col) -- mark is not removed when deleting bytes from the end of the range feed('lx') - eq(1, get_extmark_by_id(ns, 3, { details = true})[3].end_col) + eq(1, get_extmark_by_id(ns, 3, { details = true })[3].end_col) -- mark is not removed when deleting bytes beyond end of the range feed('x') - eq(1, get_extmark_by_id(ns, 3, { details = true})[3].end_col) + eq(1, get_extmark_by_id(ns, 3, { details = true })[3].end_col) -- mark is removed when all bytes in the range are deleted feed('hx') eq({}, get_extmark_by_id(ns, 3, {})) -- multiline mark is not removed when start of its range is deleted - set_extmark(ns, 4, 1, 4, { undo_restore = false, invalidate = true, - hl_group = 'Error', end_col = 7, end_row = 3 }) + set_extmark( + ns, + 4, + 1, + 4, + { undo_restore = false, invalidate = true, hl_group = 'Error', end_col = 7, end_row = 3 } + ) feed('ddDdd') - eq({0, 0}, get_extmark_by_id(ns, 4, {})) + eq({ 0, 0 }, get_extmark_by_id(ns, 4, {})) -- multiline mark is removed when entirety of its range is deleted feed('vj2ed') eq({}, get_extmark_by_id(ns, 4, {})) end) + + it('can set a URL', function() + set_extmark(ns, 1, 0, 0, { url = 'https://example.com', end_col = 3 }) + local extmarks = get_extmarks(ns, 0, -1, { details = true }) + eq(1, #extmarks) + eq('https://example.com', extmarks[1][4].url) + end) + + it('respects priority', function() + screen = Screen.new(15, 10) + screen:attach() + + set_extmark(ns, marks[1], 0, 0, { + hl_group = 'Comment', + end_col = 2, + priority = 20, + }) + + -- Extmark defined after first extmark but has lower priority, first extmark "wins" + set_extmark(ns, marks[2], 0, 0, { + hl_group = 'String', + end_col = 2, + priority = 10, + }) + + screen:expect { + grid = [[ + {1:12}34^5 | + {2:~ }|*8 + | + ]], + attr_ids = { + [1] = { foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.Blue1, bold = true }, + }, + } + end) end) describe('Extmarks buffer api with many marks', function() @@ -1689,29 +1836,28 @@ describe('Extmarks buffer api with many marks', function() local ns_marks = {} before_each(function() clear() - ns1 = request('nvim_create_namespace', "ns1") - ns2 = request('nvim_create_namespace', "ns2") - ns_marks = {[ns1]={}, [ns2]={}} + ns1 = request('nvim_create_namespace', 'ns1') + ns2 = request('nvim_create_namespace', 'ns2') + ns_marks = { [ns1] = {}, [ns2] = {} } local lines = {} - for i = 1,30 do - lines[#lines+1] = string.rep("x ",i) + for i = 1, 30 do + lines[#lines + 1] = string.rep('x ', i) end - curbufmeths.set_lines(0, -1, true, lines) + api.nvim_buf_set_lines(0, 0, -1, true, lines) local ns = ns1 local q = 0 - for i = 0,29 do - for j = 0,i do - local id = set_extmark(ns,0, i,j) + for i = 0, 29 do + for j = 0, i do + local id = set_extmark(ns, 0, i, j) eq(nil, ns_marks[ns][id]) ok(id > 0) - ns_marks[ns][id] = {i,j} - ns = ns1+ns2-ns + ns_marks[ns][id] = { i, j } + ns = ns1 + ns2 - ns q = q + 1 end end eq(233, #ns_marks[ns1]) eq(232, #ns_marks[ns2]) - end) local function get_marks(ns) @@ -1719,28 +1865,28 @@ describe('Extmarks buffer api with many marks', function() local marks = {} for _, mark in ipairs(mark_list) do local id, row, col = unpack(mark) - eq(nil, marks[id], "duplicate mark") - marks[id] = {row,col} + eq(nil, marks[id], 'duplicate mark') + marks[id] = { row, col } end return marks end - it("can get marks", function() + it('can get marks', function() eq(ns_marks[ns1], get_marks(ns1)) eq(ns_marks[ns2], get_marks(ns2)) end) - it("can clear all marks in ns", function() - curbufmeths.clear_namespace(ns1, 0, -1) + it('can clear all marks in ns', function() + api.nvim_buf_clear_namespace(0, ns1, 0, -1) eq({}, get_marks(ns1)) eq(ns_marks[ns2], get_marks(ns2)) - curbufmeths.clear_namespace(ns2, 0, -1) + api.nvim_buf_clear_namespace(0, ns2, 0, -1) eq({}, get_marks(ns1)) eq({}, get_marks(ns2)) end) - it("can clear line range", function() - curbufmeths.clear_namespace(ns1, 10, 20) + it('can clear line range', function() + api.nvim_buf_clear_namespace(0, ns1, 10, 20) for id, mark in pairs(ns_marks[ns1]) do if 10 <= mark[1] and mark[1] < 20 then ns_marks[ns1][id] = nil @@ -1750,12 +1896,12 @@ describe('Extmarks buffer api with many marks', function() eq(ns_marks[ns2], get_marks(ns2)) end) - it("can delete line", function() + it('can delete line', function() feed('10Gdd') for _, marks in pairs(ns_marks) do for id, mark in pairs(marks) do if mark[1] == 9 then - marks[id] = {9,0} + marks[id] = { 9, 0 } elseif mark[1] >= 10 then mark[1] = mark[1] - 1 end @@ -1765,12 +1911,12 @@ describe('Extmarks buffer api with many marks', function() eq(ns_marks[ns2], get_marks(ns2)) end) - it("can delete lines", function() + it('can delete lines', function() feed('10G10dd') for _, marks in pairs(ns_marks) do for id, mark in pairs(marks) do if 9 <= mark[1] and mark[1] < 19 then - marks[id] = {9,0} + marks[id] = { 9, 0 } elseif mark[1] >= 19 then mark[1] = mark[1] - 10 end @@ -1780,7 +1926,7 @@ describe('Extmarks buffer api with many marks', function() eq(ns_marks[ns2], get_marks(ns2)) end) - it("can wipe buffer", function() + it('can wipe buffer', function() command('bwipe!') eq({}, get_marks(ns1)) eq({}, get_marks(ns2)) @@ -1794,17 +1940,17 @@ describe('API/win_extmark', function() before_each(function() -- Initialize some namespaces and insert text into a buffer - marks = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} + marks = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 } - line1 = "non ui-watched line" - line2 = "ui-watched line" + line1 = 'non ui-watched line' + line2 = 'ui-watched line' clear() insert(line1) - feed("o<esc>") + feed('o<esc>') insert(line2) - ns = request('nvim_create_namespace', "extmark-ui") + ns = request('nvim_create_namespace', 'extmark-ui') end) it('sends and only sends ui-watched marks to ui', function() @@ -1824,8 +1970,8 @@ describe('API/win_extmark', function() extmarks = { [2] = { -- positioned at the end of the 2nd line - { {id = 1000}, 1, 1, 1, 16 }, - } + { 1000, ns, marks[1], 1, 16 }, + }, }, }) end) @@ -1833,35 +1979,45 @@ describe('API/win_extmark', function() it('sends multiple ui-watched marks to ui', function() screen = Screen.new(20, 4) screen:attach() + feed('15A!<Esc>') -- should send all of these - set_extmark(ns, marks[1], 1, 0, { ui_watched = true, virt_text_pos = "overlay" }) - set_extmark(ns, marks[2], 1, 2, { ui_watched = true, virt_text_pos = "overlay" }) - set_extmark(ns, marks[3], 1, 4, { ui_watched = true, virt_text_pos = "overlay" }) - set_extmark(ns, marks[4], 1, 6, { ui_watched = true, virt_text_pos = "overlay" }) + set_extmark(ns, marks[1], 1, 0, { ui_watched = true, virt_text_pos = 'overlay' }) + set_extmark(ns, marks[2], 1, 2, { ui_watched = true, virt_text_pos = 'overlay' }) + set_extmark(ns, marks[3], 1, 4, { ui_watched = true, virt_text_pos = 'overlay' }) + set_extmark(ns, marks[4], 1, 6, { ui_watched = true, virt_text_pos = 'overlay' }) set_extmark(ns, marks[5], 1, 8, { ui_watched = true }) screen:expect({ grid = [[ non ui-watched line | - ui-watched lin^e | - ~ | + ui-watched line!!!!!| + !!!!!!!!!^! | | ]], extmarks = { [2] = { - -- earlier notifications - { {id = 1000}, 1, 1, 1, 0 }, - { {id = 1000}, 1, 1, 1, 0 }, { {id = 1000}, 1, 2, 1, 2 }, - { {id = 1000}, 1, 1, 1, 0 }, { {id = 1000}, 1, 2, 1, 2 }, { {id = 1000}, 1, 3, 1, 4 }, - { {id = 1000}, 1, 1, 1, 0 }, { {id = 1000}, 1, 2, 1, 2 }, { {id = 1000}, 1, 3, 1, 4 }, { {id = 1000}, 1, 4, 1, 6 }, + -- notification from 1st call + { 1000, ns, marks[1], 1, 0 }, + -- notifications from 2nd call + { 1000, ns, marks[1], 1, 0 }, + { 1000, ns, marks[2], 1, 2 }, + -- notifications from 3rd call + { 1000, ns, marks[1], 1, 0 }, + { 1000, ns, marks[2], 1, 2 }, + { 1000, ns, marks[3], 1, 4 }, + -- notifications from 4th call + { 1000, ns, marks[1], 1, 0 }, + { 1000, ns, marks[2], 1, 2 }, + { 1000, ns, marks[3], 1, 4 }, + { 1000, ns, marks[4], 1, 6 }, -- final -- overlay - { {id = 1000}, 1, 1, 1, 0 }, - { {id = 1000}, 1, 2, 1, 2 }, - { {id = 1000}, 1, 3, 1, 4 }, - { {id = 1000}, 1, 4, 1, 6 }, + { 1000, ns, marks[1], 1, 0 }, + { 1000, ns, marks[2], 1, 2 }, + { 1000, ns, marks[3], 1, 4 }, + { 1000, ns, marks[4], 1, 6 }, -- eol - { {id = 1000}, 1, 5, 1, 16 }, - } + { 1000, ns, marks[5], 2, 11 }, + }, }, }) end) @@ -1874,7 +2030,7 @@ describe('API/win_extmark', function() -- should not send this set_extmark(ns, marks[2], 0, 0, { ui_watched = false }) -- make some changes - insert(" update") + insert(' update') screen:expect({ grid = [[ non ui-watched line | @@ -1885,13 +2041,13 @@ describe('API/win_extmark', function() extmarks = { [2] = { -- positioned at the end of the 2nd line - { {id = 1000}, 1, 1, 1, 16 }, + { 1000, ns, marks[1], 1, 16 }, -- updated and wrapped to 3rd line - { {id = 1000}, 1, 1, 2, 2 }, - } - } + { 1000, ns, marks[1], 2, 2 }, + }, + }, }) - feed("<c-e>") + feed('<c-e>') screen:expect({ grid = [[ ui-watched linupdat^e| @@ -1902,18 +2058,18 @@ describe('API/win_extmark', function() extmarks = { [2] = { -- positioned at the end of the 2nd line - { {id = 1000}, 1, 1, 1, 16 }, + { 1000, ns, marks[1], 1, 16 }, -- updated and wrapped to 3rd line - { {id = 1000}, 1, 1, 2, 2 }, + { 1000, ns, marks[1], 2, 2 }, -- scrolled up one line, should be handled by grid scroll - } - } + }, + }, }) end) it('sends ui-watched to splits', function() screen = Screen.new(20, 8) - screen:attach({ext_multigrid=true}) + screen:attach({ ext_multigrid = true }) -- should send this set_extmark(ns, marks[1], 1, 0, { ui_watched = true }) -- should not send this @@ -1922,12 +2078,9 @@ describe('API/win_extmark', function() screen:expect({ grid = [[ ## grid 1 - [4:--------------------]| - [4:--------------------]| - [4:--------------------]| + [4:--------------------]|*3 [No Name] [+] | - [2:--------------------]| - [2:--------------------]| + [2:--------------------]|*2 [No Name] [+] | [3:--------------------]| ## grid 2 @@ -1943,27 +2096,24 @@ describe('API/win_extmark', function() extmarks = { [2] = { -- positioned at the end of the 2nd line - { {id = 1000}, 1, 1, 1, 16 }, + { 1000, ns, marks[1], 1, 16 }, -- updated after split - { {id = 1000}, 1, 1, 1, 16 }, + { 1000, ns, marks[1], 1, 16 }, }, [4] = { -- only after split - { {id = 1001}, 1, 1, 1, 16 }, - } - } + { 1001, ns, marks[1], 1, 16 }, + }, + }, }) -- make some changes - insert(" update") + insert(' update') screen:expect({ grid = [[ ## grid 1 - [4:--------------------]| - [4:--------------------]| - [4:--------------------]| + [4:--------------------]|*3 [No Name] [+] | - [2:--------------------]| - [2:--------------------]| + [2:--------------------]|*2 [No Name] [+] | [3:--------------------]| ## grid 2 @@ -1979,16 +2129,16 @@ describe('API/win_extmark', function() extmarks = { [2] = { -- positioned at the end of the 2nd line - { {id = 1000}, 1, 1, 1, 16 }, + { 1000, ns, marks[1], 1, 16 }, -- updated after split - { {id = 1000}, 1, 1, 1, 16 }, + { 1000, ns, marks[1], 1, 16 }, }, [4] = { - { {id = 1001}, 1, 1, 1, 16 }, + { 1001, ns, marks[1], 1, 16 }, -- updated - { {id = 1001}, 1, 1, 2, 2 }, - } - } + { 1001, ns, marks[1], 2, 2 }, + }, + }, }) end) end) diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua index 7d7d07e30e..1973d3e1c7 100644 --- a/test/functional/api/highlight_spec.lua +++ b/test/functional/api/highlight_spec.lua @@ -1,16 +1,16 @@ local helpers = require('test.functional.helpers')(after_each) -local clear, nvim = helpers.clear, helpers.nvim +local clear = helpers.clear local Screen = require('test.functional.ui.screen') local eq, eval = helpers.eq, helpers.eval local command = helpers.command local exec_capture = helpers.exec_capture -local meths = helpers.meths -local funcs = helpers.funcs +local api = helpers.api +local fn = helpers.fn local pcall_err = helpers.pcall_err local ok = helpers.ok local assert_alive = helpers.assert_alive -describe('API: highlight',function() +describe('API: highlight', function() clear() Screen.new() -- initialize Screen.colors @@ -45,127 +45,138 @@ describe('API: highlight',function() before_each(function() clear() - command("hi NewHighlight cterm=underline ctermbg=green guifg=red guibg=yellow guisp=blue gui=bold") + command( + 'hi NewHighlight cterm=underline ctermbg=green guifg=red guibg=yellow guisp=blue gui=bold' + ) end) - it("nvim_get_hl_by_id", function() + it('nvim_get_hl_by_id', function() local hl_id = eval("hlID('NewHighlight')") - eq(expected_cterm, nvim("get_hl_by_id", hl_id, false)) + eq(expected_cterm, api.nvim_get_hl_by_id(hl_id, false)) hl_id = eval("hlID('NewHighlight')") -- Test valid id. - eq(expected_rgb, nvim("get_hl_by_id", hl_id, true)) + eq(expected_rgb, api.nvim_get_hl_by_id(hl_id, true)) -- Test invalid id. - eq('Invalid highlight id: 30000', pcall_err(meths.get_hl_by_id, 30000, false)) + eq('Invalid highlight id: 30000', pcall_err(api.nvim_get_hl_by_id, 30000, false)) -- Test all highlight properties. command('hi NewHighlight gui=underline,bold,italic,reverse,strikethrough,altfont,nocombine') - eq(expected_rgb2, nvim("get_hl_by_id", hl_id, true)) + eq(expected_rgb2, api.nvim_get_hl_by_id(hl_id, true)) -- Test undercurl command('hi NewHighlight gui=undercurl') - eq(expected_undercurl, nvim("get_hl_by_id", hl_id, true)) + eq(expected_undercurl, api.nvim_get_hl_by_id(hl_id, true)) -- Test nil argument. - eq('Wrong type for argument 1 when calling nvim_get_hl_by_id, expecting Integer', - pcall_err(meths.get_hl_by_id, { nil }, false)) + eq( + 'Wrong type for argument 1 when calling nvim_get_hl_by_id, expecting Integer', + pcall_err(api.nvim_get_hl_by_id, { nil }, false) + ) -- Test 0 argument. - eq('Invalid highlight id: 0', pcall_err(meths.get_hl_by_id, 0, false)) + eq('Invalid highlight id: 0', pcall_err(api.nvim_get_hl_by_id, 0, false)) -- Test -1 argument. - eq('Invalid highlight id: -1', pcall_err(meths.get_hl_by_id, -1, false)) + eq('Invalid highlight id: -1', pcall_err(api.nvim_get_hl_by_id, -1, false)) -- Test highlight group without ctermbg value. command('hi Normal ctermfg=red ctermbg=yellow') command('hi NewConstant ctermfg=green guifg=white guibg=blue') hl_id = eval("hlID('NewConstant')") - eq({foreground = 10,}, meths.get_hl_by_id(hl_id, false)) + eq({ foreground = 10 }, api.nvim_get_hl_by_id(hl_id, false)) -- Test highlight group without ctermfg value. command('hi clear NewConstant') command('hi NewConstant ctermbg=Magenta guifg=white guibg=blue') - eq({background = 13,}, meths.get_hl_by_id(hl_id, false)) + eq({ background = 13 }, api.nvim_get_hl_by_id(hl_id, false)) -- Test highlight group with ctermfg and ctermbg values. command('hi clear NewConstant') command('hi NewConstant ctermfg=green ctermbg=Magenta guifg=white guibg=blue') - eq({foreground = 10, background = 13,}, meths.get_hl_by_id(hl_id, false)) + eq({ foreground = 10, background = 13 }, api.nvim_get_hl_by_id(hl_id, false)) end) - it("nvim_get_hl_by_name", function() - local expected_normal = { background = Screen.colors.Yellow, - foreground = Screen.colors.Red } + it('nvim_get_hl_by_name', function() + local expected_normal = { background = Screen.colors.Yellow, foreground = Screen.colors.Red } -- Test `Normal` default values. - eq({}, nvim("get_hl_by_name", 'Normal', true)) + eq({}, api.nvim_get_hl_by_name('Normal', true)) - eq(expected_cterm, nvim("get_hl_by_name", 'NewHighlight', false)) - eq(expected_rgb, nvim("get_hl_by_name", 'NewHighlight', true)) + eq(expected_cterm, api.nvim_get_hl_by_name('NewHighlight', false)) + eq(expected_rgb, api.nvim_get_hl_by_name('NewHighlight', true)) -- Test `Normal` modified values. command('hi Normal guifg=red guibg=yellow') - eq(expected_normal, nvim("get_hl_by_name", 'Normal', true)) + eq(expected_normal, api.nvim_get_hl_by_name('Normal', true)) -- Test invalid name. - eq("Invalid highlight name: 'unknown_highlight'", - pcall_err(meths.get_hl_by_name , 'unknown_highlight', false)) + eq( + "Invalid highlight name: 'unknown_highlight'", + pcall_err(api.nvim_get_hl_by_name, 'unknown_highlight', false) + ) -- Test nil argument. - eq('Wrong type for argument 1 when calling nvim_get_hl_by_name, expecting String', - pcall_err(meths.get_hl_by_name , { nil }, false)) + eq( + 'Wrong type for argument 1 when calling nvim_get_hl_by_name, expecting String', + pcall_err(api.nvim_get_hl_by_name, { nil }, false) + ) -- Test empty string argument. - eq('Invalid highlight name', - pcall_err(meths.get_hl_by_name , '', false)) + eq('Invalid highlight name', pcall_err(api.nvim_get_hl_by_name, '', false)) -- Test "standout" attribute. #8054 - eq({ underline = true, }, - meths.get_hl_by_name('cursorline', 0)); + eq({ underline = true }, api.nvim_get_hl_by_name('cursorline', 0)) command('hi CursorLine cterm=standout,underline term=standout,underline gui=standout,underline') command('set cursorline') - eq({ underline = true, standout = true, }, - meths.get_hl_by_name('cursorline', 0)); + eq({ underline = true, standout = true }, api.nvim_get_hl_by_name('cursorline', 0)) -- Test cterm & Normal values. #18024 (tail) & #18980 -- Ensure Normal, and groups that match Normal return their fg & bg cterm values - meths.set_hl(0, 'Normal', {ctermfg = 17, ctermbg = 213}) - meths.set_hl(0, 'NotNormal', {ctermfg = 17, ctermbg = 213, nocombine = true}) + api.nvim_set_hl(0, 'Normal', { ctermfg = 17, ctermbg = 213 }) + api.nvim_set_hl(0, 'NotNormal', { ctermfg = 17, ctermbg = 213, nocombine = true }) -- Note colors are "cterm" values, not rgb-as-ints - eq({foreground = 17, background = 213}, nvim("get_hl_by_name", 'Normal', false)) - eq({foreground = 17, background = 213, nocombine = true}, nvim("get_hl_by_name", 'NotNormal', false)) + eq({ foreground = 17, background = 213 }, api.nvim_get_hl_by_name('Normal', false)) + eq( + { foreground = 17, background = 213, nocombine = true }, + api.nvim_get_hl_by_name('NotNormal', false) + ) end) it('nvim_get_hl_id_by_name', function() -- precondition: use a hl group that does not yet exist - eq("Invalid highlight name: 'Shrubbery'", pcall_err(meths.get_hl_by_name, "Shrubbery", true)) - eq(0, funcs.hlID("Shrubbery")) + eq("Invalid highlight name: 'Shrubbery'", pcall_err(api.nvim_get_hl_by_name, 'Shrubbery', true)) + eq(0, fn.hlID('Shrubbery')) - local hl_id = meths.get_hl_id_by_name("Shrubbery") + local hl_id = api.nvim_get_hl_id_by_name('Shrubbery') ok(hl_id > 0) - eq(hl_id, funcs.hlID("Shrubbery")) + eq(hl_id, fn.hlID('Shrubbery')) command('hi Shrubbery guifg=#888888 guibg=#888888') - eq({foreground=tonumber("0x888888"), background=tonumber("0x888888")}, - meths.get_hl_by_id(hl_id, true)) - eq({foreground=tonumber("0x888888"), background=tonumber("0x888888")}, - meths.get_hl_by_name("Shrubbery", true)) + eq( + { foreground = tonumber('0x888888'), background = tonumber('0x888888') }, + api.nvim_get_hl_by_id(hl_id, true) + ) + eq( + { foreground = tonumber('0x888888'), background = tonumber('0x888888') }, + api.nvim_get_hl_by_name('Shrubbery', true) + ) end) it("nvim_buf_add_highlight to other buffer doesn't crash if undo is disabled #12873", function() command('vsplit file') - local err, _ = pcall(meths.set_option_value, 'undofile', false, { buf = 1 }) + local err, _ = pcall(api.nvim_set_option_value, 'undofile', false, { buf = 1 }) eq(true, err) - err, _ = pcall(meths.set_option_value, 'undolevels', -1, { buf = 1 }) + err, _ = pcall(api.nvim_set_option_value, 'undolevels', -1, { buf = 1 }) eq(true, err) - err, _ = pcall(meths.buf_add_highlight, 1, -1, 'Question', 0, 0, -1) + err, _ = pcall(api.nvim_buf_add_highlight, 1, -1, 'Question', 0, 0, -1) eq(true, err) assert_alive() end) end) -describe("API: set highlight", function() +describe('API: set highlight', function() local highlight_color = { fg = tonumber('0xff0000'), bg = tonumber('0x0032aa'), @@ -207,7 +218,7 @@ describe("API: set highlight", function() strikethrough = true, altfont = true, nocombine = true, - } + }, } local highlight3_result_gui = { background = highlight_color.bg, @@ -230,57 +241,61 @@ describe("API: set highlight", function() } local function get_ns() - local ns = meths.create_namespace('Test_set_hl') - meths.set_hl_ns(ns) + local ns = api.nvim_create_namespace('Test_set_hl') + api.nvim_set_hl_ns(ns) return ns end before_each(clear) it('validation', function() - eq("Invalid 'blend': out of range", - pcall_err(meths.set_hl, 0, 'Test_hl3', {fg='#FF00FF', blend=999})) - eq("Invalid 'blend': expected Integer, got Array", - pcall_err(meths.set_hl, 0, 'Test_hl3', {fg='#FF00FF', blend={}})) + eq( + "Invalid 'blend': out of range", + pcall_err(api.nvim_set_hl, 0, 'Test_hl3', { fg = '#FF00FF', blend = 999 }) + ) + eq( + "Invalid 'blend': expected Integer, got Array", + pcall_err(api.nvim_set_hl, 0, 'Test_hl3', { fg = '#FF00FF', blend = {} }) + ) end) - it("can set gui highlight", function() + it('can set gui highlight', function() local ns = get_ns() - meths.set_hl(ns, 'Test_hl', highlight1) - eq(highlight1, meths.get_hl_by_name('Test_hl', true)) + api.nvim_set_hl(ns, 'Test_hl', highlight1) + eq(highlight1, api.nvim_get_hl_by_name('Test_hl', true)) end) - it("can set cterm highlight", function() + it('can set cterm highlight', function() local ns = get_ns() - meths.set_hl(ns, 'Test_hl', highlight2_config) - eq(highlight2_result, meths.get_hl_by_name('Test_hl', false)) + api.nvim_set_hl(ns, 'Test_hl', highlight2_config) + eq(highlight2_result, api.nvim_get_hl_by_name('Test_hl', false)) end) - it("can set empty cterm attr", function() + it('can set empty cterm attr', function() local ns = get_ns() - meths.set_hl(ns, 'Test_hl', { cterm = {} }) - eq({}, meths.get_hl_by_name('Test_hl', false)) + api.nvim_set_hl(ns, 'Test_hl', { cterm = {} }) + eq({}, api.nvim_get_hl_by_name('Test_hl', false)) end) - it("cterm attr defaults to gui attr", function() + it('cterm attr defaults to gui attr', function() local ns = get_ns() - meths.set_hl(ns, 'Test_hl', highlight1) + api.nvim_set_hl(ns, 'Test_hl', highlight1) eq({ bold = true, italic = true, - }, meths.get_hl_by_name('Test_hl', false)) + }, api.nvim_get_hl_by_name('Test_hl', false)) end) - it("can overwrite attr for cterm", function() + it('can overwrite attr for cterm', function() local ns = get_ns() - meths.set_hl(ns, 'Test_hl', highlight3_config) - eq(highlight3_result_gui, meths.get_hl_by_name('Test_hl', true)) - eq(highlight3_result_cterm, meths.get_hl_by_name('Test_hl', false)) + api.nvim_set_hl(ns, 'Test_hl', highlight3_config) + eq(highlight3_result_gui, api.nvim_get_hl_by_name('Test_hl', true)) + eq(highlight3_result_cterm, api.nvim_get_hl_by_name('Test_hl', false)) end) - it("only allows one underline attribute #22371", function() + it('only allows one underline attribute #22371', function() local ns = get_ns() - meths.set_hl(ns, 'Test_hl', { + api.nvim_set_hl(ns, 'Test_hl', { underdouble = true, underdotted = true, cterm = { @@ -288,84 +303,86 @@ describe("API: set highlight", function() undercurl = true, }, }) - eq({ undercurl = true }, meths.get_hl_by_name('Test_hl', false)) - eq({ underdotted = true }, meths.get_hl_by_name('Test_hl', true)) + eq({ undercurl = true }, api.nvim_get_hl_by_name('Test_hl', false)) + eq({ underdotted = true }, api.nvim_get_hl_by_name('Test_hl', true)) end) - it("can set a highlight in the global namespace", function() - meths.set_hl(0, 'Test_hl', highlight2_config) - eq('Test_hl xxx cterm=underline,reverse ctermfg=8 ctermbg=15 gui=underline,reverse', - exec_capture('highlight Test_hl')) + it('can set a highlight in the global namespace', function() + api.nvim_set_hl(0, 'Test_hl', highlight2_config) + eq( + 'Test_hl xxx cterm=underline,reverse ctermfg=8 ctermbg=15 gui=underline,reverse', + exec_capture('highlight Test_hl') + ) - meths.set_hl(0, 'Test_hl', { background = highlight_color.bg }) - eq('Test_hl xxx guibg=#0032aa', - exec_capture('highlight Test_hl')) + api.nvim_set_hl(0, 'Test_hl', { background = highlight_color.bg }) + eq('Test_hl xxx guibg=#0032aa', exec_capture('highlight Test_hl')) - meths.set_hl(0, 'Test_hl2', highlight3_config) - eq('Test_hl2 xxx cterm=italic,reverse,strikethrough,altfont,nocombine ctermfg=8 ctermbg=15 gui=bold,underdashed,italic,reverse,strikethrough,altfont guifg=#ff0000 guibg=#0032aa', - exec_capture('highlight Test_hl2')) + api.nvim_set_hl(0, 'Test_hl2', highlight3_config) + eq( + 'Test_hl2 xxx cterm=italic,reverse,strikethrough,altfont,nocombine ctermfg=8 ctermbg=15 gui=bold,underdashed,italic,reverse,strikethrough,altfont guifg=#ff0000 guibg=#0032aa', + exec_capture('highlight Test_hl2') + ) -- Colors are stored with the name they are defined, but -- with canonical casing - meths.set_hl(0, 'Test_hl3', { bg = 'reD', fg = 'bLue'}) - eq('Test_hl3 xxx guifg=Blue guibg=Red', - exec_capture('highlight Test_hl3')) + api.nvim_set_hl(0, 'Test_hl3', { bg = 'reD', fg = 'bLue' }) + eq('Test_hl3 xxx guifg=Blue guibg=Red', exec_capture('highlight Test_hl3')) end) - it("can modify a highlight in the global namespace", function() - meths.set_hl(0, 'Test_hl3', { bg = 'red', fg = 'blue'}) - eq('Test_hl3 xxx guifg=Blue guibg=Red', - exec_capture('highlight Test_hl3')) + it('can modify a highlight in the global namespace', function() + api.nvim_set_hl(0, 'Test_hl3', { bg = 'red', fg = 'blue' }) + eq('Test_hl3 xxx guifg=Blue guibg=Red', exec_capture('highlight Test_hl3')) - meths.set_hl(0, 'Test_hl3', { bg = 'red' }) - eq('Test_hl3 xxx guibg=Red', - exec_capture('highlight Test_hl3')) + api.nvim_set_hl(0, 'Test_hl3', { bg = 'red' }) + eq('Test_hl3 xxx guibg=Red', exec_capture('highlight Test_hl3')) - meths.set_hl(0, 'Test_hl3', { ctermbg = 9, ctermfg = 12}) - eq('Test_hl3 xxx ctermfg=12 ctermbg=9', - exec_capture('highlight Test_hl3')) + api.nvim_set_hl(0, 'Test_hl3', { ctermbg = 9, ctermfg = 12 }) + eq('Test_hl3 xxx ctermfg=12 ctermbg=9', exec_capture('highlight Test_hl3')) - meths.set_hl(0, 'Test_hl3', { ctermbg = 'red' , ctermfg = 'blue'}) - eq('Test_hl3 xxx ctermfg=12 ctermbg=9', - exec_capture('highlight Test_hl3')) + api.nvim_set_hl(0, 'Test_hl3', { ctermbg = 'red', ctermfg = 'blue' }) + eq('Test_hl3 xxx ctermfg=12 ctermbg=9', exec_capture('highlight Test_hl3')) - meths.set_hl(0, 'Test_hl3', { ctermbg = 9 }) - eq('Test_hl3 xxx ctermbg=9', - exec_capture('highlight Test_hl3')) + api.nvim_set_hl(0, 'Test_hl3', { ctermbg = 9 }) + eq('Test_hl3 xxx ctermbg=9', exec_capture('highlight Test_hl3')) - eq("Invalid highlight color: 'redd'", - pcall_err(meths.set_hl, 0, 'Test_hl3', {fg='redd'})) + eq( + "Invalid highlight color: 'redd'", + pcall_err(api.nvim_set_hl, 0, 'Test_hl3', { fg = 'redd' }) + ) - eq("Invalid highlight color: 'bleu'", - pcall_err(meths.set_hl, 0, 'Test_hl3', {ctermfg='bleu'})) + eq( + "Invalid highlight color: 'bleu'", + pcall_err(api.nvim_set_hl, 0, 'Test_hl3', { ctermfg = 'bleu' }) + ) - meths.set_hl(0, 'Test_hl3', {fg='#FF00FF'}) - eq('Test_hl3 xxx guifg=#ff00ff', - exec_capture('highlight Test_hl3')) + api.nvim_set_hl(0, 'Test_hl3', { fg = '#FF00FF' }) + eq('Test_hl3 xxx guifg=#ff00ff', exec_capture('highlight Test_hl3')) - eq("Invalid highlight color: '#FF00FF'", - pcall_err(meths.set_hl, 0, 'Test_hl3', {ctermfg='#FF00FF'})) + eq( + "Invalid highlight color: '#FF00FF'", + pcall_err(api.nvim_set_hl, 0, 'Test_hl3', { ctermfg = '#FF00FF' }) + ) - for _, fg_val in ipairs{ nil, 'NONE', 'nOnE', '', -1 } do - meths.set_hl(0, 'Test_hl3', {fg = fg_val}) - eq('Test_hl3 xxx cleared', - exec_capture('highlight Test_hl3')) + for _, fg_val in ipairs { nil, 'NONE', 'nOnE', '', -1 } do + api.nvim_set_hl(0, 'Test_hl3', { fg = fg_val }) + eq('Test_hl3 xxx cleared', exec_capture('highlight Test_hl3')) end - meths.set_hl(0, 'Test_hl3', {fg='#FF00FF', blend=50}) - eq('Test_hl3 xxx guifg=#ff00ff blend=50', - exec_capture('highlight Test_hl3')) - + api.nvim_set_hl(0, 'Test_hl3', { fg = '#FF00FF', blend = 50 }) + eq('Test_hl3 xxx guifg=#ff00ff blend=50', exec_capture('highlight Test_hl3')) end) it("correctly sets 'Normal' internal properties", function() -- Normal has some special handling internally. #18024 - meths.set_hl(0, 'Normal', {fg='#000083', bg='#0000F3'}) - eq({foreground = 131, background = 243}, nvim("get_hl_by_name", 'Normal', true)) + api.nvim_set_hl(0, 'Normal', { fg = '#000083', bg = '#0000F3' }) + eq({ foreground = 131, background = 243 }, api.nvim_get_hl_by_name('Normal', true)) end) it('does not segfault on invalid group name #20009', function() - eq("Invalid highlight name: 'foo bar'", pcall_err(meths.set_hl, 0, 'foo bar', {bold = true})) + eq( + "Invalid highlight name: 'foo bar'", + pcall_err(api.nvim_set_hl, 0, 'foo bar', { bold = true }) + ) assert_alive() end) end) @@ -380,14 +397,16 @@ describe('API: get highlight', function() local highlight1 = { bg = highlight_color.bg, fg = highlight_color.fg, - bold = true, italic = true, - cterm = {bold = true, italic = true}, + bold = true, + italic = true, + cterm = { bold = true, italic = true }, } local highlight2 = { ctermbg = highlight_color.ctermbg, ctermfg = highlight_color.ctermfg, - underline = true, reverse = true, - cterm = {underline = true, reverse = true}, + underline = true, + reverse = true, + cterm = { underline = true, reverse = true }, } local highlight3_config = { bg = highlight_color.bg, @@ -413,20 +432,31 @@ describe('API: get highlight', function() fg = highlight_color.fg, ctermbg = highlight_color.ctermbg, ctermfg = highlight_color.ctermfg, - bold = true, italic = true, reverse = true, underdashed = true, strikethrough = true, altfont = true, - cterm = {italic = true, nocombine = true, reverse = true, strikethrough = true, altfont = true} + bold = true, + italic = true, + reverse = true, + underdashed = true, + strikethrough = true, + altfont = true, + cterm = { + italic = true, + nocombine = true, + reverse = true, + strikethrough = true, + altfont = true, + }, } local function get_ns() -- Test namespace filtering behavior - local ns2 = meths.create_namespace('Another_namespace') - meths.set_hl(ns2, 'Test_hl', { ctermfg = 23 }) - meths.set_hl(ns2, 'Test_another_hl', { link = 'Test_hl' }) - meths.set_hl(ns2, 'Test_hl_link', { link = 'Test_another_hl' }) - meths.set_hl(ns2, 'Test_another_hl_link', { link = 'Test_hl_link' }) + local ns2 = api.nvim_create_namespace('Another_namespace') + api.nvim_set_hl(ns2, 'Test_hl', { ctermfg = 23 }) + api.nvim_set_hl(ns2, 'Test_another_hl', { link = 'Test_hl' }) + api.nvim_set_hl(ns2, 'Test_hl_link', { link = 'Test_another_hl' }) + api.nvim_set_hl(ns2, 'Test_another_hl_link', { link = 'Test_hl_link' }) - local ns = meths.create_namespace('Test_set_hl') - meths.set_hl_ns(ns) + local ns = api.nvim_create_namespace('Test_set_hl') + api.nvim_set_hl_ns(ns) return ns end @@ -434,67 +464,69 @@ describe('API: get highlight', function() before_each(clear) it('validation', function() - eq("Invalid 'name': expected String, got Integer", - pcall_err(meths.get_hl, 0, { name = 177 })) - eq('Highlight id out of bounds', pcall_err(meths.get_hl, 0, { name = 'Test set hl' })) + eq( + "Invalid 'name': expected String, got Integer", + pcall_err(api.nvim_get_hl, 0, { name = 177 }) + ) + eq('Highlight id out of bounds', pcall_err(api.nvim_get_hl, 0, { name = 'Test set hl' })) end) it('nvim_get_hl with create flag', function() - eq({}, nvim("get_hl", 0, {name = 'Foo', create = false})) - eq(0, funcs.hlexists('Foo')) - meths.get_hl(0, {name = 'Bar', create = true}) - eq(1, funcs.hlexists('Bar')) - meths.get_hl(0, {name = 'FooBar'}) - eq(1, funcs.hlexists('FooBar')) + eq({}, api.nvim_get_hl(0, { name = 'Foo', create = false })) + eq(0, fn.hlexists('Foo')) + api.nvim_get_hl(0, { name = 'Bar', create = true }) + eq(1, fn.hlexists('Bar')) + api.nvim_get_hl(0, { name = 'FooBar' }) + eq(1, fn.hlexists('FooBar')) end) it('can get all highlights in current namespace', function() local ns = get_ns() - meths.set_hl(ns, 'Test_hl', { bg = '#B4BEFE' }) - meths.set_hl(ns, 'Test_hl_link', { link = 'Test_hl' }) + api.nvim_set_hl(ns, 'Test_hl', { bg = '#B4BEFE' }) + api.nvim_set_hl(ns, 'Test_hl_link', { link = 'Test_hl' }) eq({ Test_hl = { - bg = 11845374 + bg = 11845374, }, Test_hl_link = { - link = 'Test_hl' - } - }, meths.get_hl(ns, {})) + link = 'Test_hl', + }, + }, api.nvim_get_hl(ns, {})) end) it('can get gui highlight', function() local ns = get_ns() - meths.set_hl(ns, 'Test_hl', highlight1) - eq(highlight1, meths.get_hl(ns, { name = 'Test_hl' })) + api.nvim_set_hl(ns, 'Test_hl', highlight1) + eq(highlight1, api.nvim_get_hl(ns, { name = 'Test_hl' })) end) it('can get cterm highlight', function() local ns = get_ns() - meths.set_hl(ns, 'Test_hl', highlight2) - eq(highlight2, meths.get_hl(ns, { name = 'Test_hl' })) + api.nvim_set_hl(ns, 'Test_hl', highlight2) + eq(highlight2, api.nvim_get_hl(ns, { name = 'Test_hl' })) end) it('can get empty cterm attr', function() local ns = get_ns() - meths.set_hl(ns, 'Test_hl', { cterm = {} }) - eq({}, meths.get_hl(ns, { name = 'Test_hl' })) + api.nvim_set_hl(ns, 'Test_hl', { cterm = {} }) + eq({}, api.nvim_get_hl(ns, { name = 'Test_hl' })) end) it('cterm attr defaults to gui attr', function() local ns = get_ns() - meths.set_hl(ns, 'Test_hl', highlight1) - eq(highlight1, meths.get_hl(ns, { name = 'Test_hl' })) + api.nvim_set_hl(ns, 'Test_hl', highlight1) + eq(highlight1, api.nvim_get_hl(ns, { name = 'Test_hl' })) end) it('can overwrite attr for cterm', function() local ns = get_ns() - meths.set_hl(ns, 'Test_hl', highlight3_config) - eq(highlight3_result, meths.get_hl(ns, { name = 'Test_hl' })) + api.nvim_set_hl(ns, 'Test_hl', highlight3_config) + eq(highlight3_result, api.nvim_get_hl(ns, { name = 'Test_hl' })) end) it('only allows one underline attribute #22371', function() local ns = get_ns() - meths.set_hl(ns, 'Test_hl', { + api.nvim_set_hl(ns, 'Test_hl', { underdouble = true, underdotted = true, cterm = { @@ -502,154 +534,178 @@ describe('API: get highlight', function() undercurl = true, }, }) - eq({ underdotted = true, cterm = { undercurl = true} }, - meths.get_hl(ns, { name = 'Test_hl' })) + eq( + { underdotted = true, cterm = { undercurl = true } }, + api.nvim_get_hl(ns, { name = 'Test_hl' }) + ) end) it('can get a highlight in the global namespace', function() - meths.set_hl(0, 'Test_hl', highlight2) - eq(highlight2, meths.get_hl(0, { name = 'Test_hl' })) + api.nvim_set_hl(0, 'Test_hl', highlight2) + eq(highlight2, api.nvim_get_hl(0, { name = 'Test_hl' })) - meths.set_hl(0, 'Test_hl', { background = highlight_color.bg }) + api.nvim_set_hl(0, 'Test_hl', { background = highlight_color.bg }) eq({ bg = 12970, - }, meths.get_hl(0, { name = 'Test_hl' })) + }, api.nvim_get_hl(0, { name = 'Test_hl' })) - meths.set_hl(0, 'Test_hl2', highlight3_config) - eq(highlight3_result, meths.get_hl(0, { name = 'Test_hl2' })) + api.nvim_set_hl(0, 'Test_hl2', highlight3_config) + eq(highlight3_result, api.nvim_get_hl(0, { name = 'Test_hl2' })) -- Colors are stored with the name they are defined, but -- with canonical casing - meths.set_hl(0, 'Test_hl3', { bg = 'reD', fg = 'bLue' }) + api.nvim_set_hl(0, 'Test_hl3', { bg = 'reD', fg = 'bLue' }) eq({ bg = 16711680, fg = 255, - }, meths.get_hl(0, { name = 'Test_hl3' })) + }, api.nvim_get_hl(0, { name = 'Test_hl3' })) end) it('nvim_get_hl by id', function() - local hl_id = meths.get_hl_id_by_name('NewHighlight') + local hl_id = api.nvim_get_hl_id_by_name('NewHighlight') command( 'hi NewHighlight cterm=underline ctermbg=green guifg=red guibg=yellow guisp=blue gui=bold' ) - eq({ fg = 16711680, bg = 16776960, sp = 255, bold = true, - ctermbg = 10, cterm = { underline = true }, - }, meths.get_hl(0, { id = hl_id })) + eq({ + fg = 16711680, + bg = 16776960, + sp = 255, + bold = true, + ctermbg = 10, + cterm = { underline = true }, + }, api.nvim_get_hl(0, { id = hl_id })) -- Test 0 argument - eq('Highlight id out of bounds', pcall_err(meths.get_hl, 0, { id = 0 })) + eq('Highlight id out of bounds', pcall_err(api.nvim_get_hl, 0, { id = 0 })) eq( "Invalid 'id': expected Integer, got String", - pcall_err(meths.get_hl, 0, { id = 'Test_set_hl' }) + pcall_err(api.nvim_get_hl, 0, { id = 'Test_set_hl' }) ) -- Test all highlight properties. command('hi NewHighlight gui=underline,bold,italic,reverse,strikethrough,altfont,nocombine') - eq({ fg = 16711680, bg = 16776960, sp = 255, - altfont = true, bold = true, italic = true, nocombine = true, reverse = true, strikethrough = true, underline = true, - ctermbg = 10, cterm = {underline = true}, - }, meths.get_hl(0, { id = hl_id })) + eq({ + fg = 16711680, + bg = 16776960, + sp = 255, + altfont = true, + bold = true, + italic = true, + nocombine = true, + reverse = true, + strikethrough = true, + underline = true, + ctermbg = 10, + cterm = { underline = true }, + }, api.nvim_get_hl(0, { id = hl_id })) -- Test undercurl command('hi NewHighlight gui=undercurl') - eq({ fg = 16711680, bg = 16776960, sp = 255, undercurl = true, - ctermbg = 10, - cterm = {underline = true}, - }, meths.get_hl(0, { id = hl_id })) + eq({ + fg = 16711680, + bg = 16776960, + sp = 255, + undercurl = true, + ctermbg = 10, + cterm = { underline = true }, + }, api.nvim_get_hl(0, { id = hl_id })) end) it('can correctly detect links', function() - command('hi String guifg=#a6e3a1') + command('hi String guifg=#a6e3a1 ctermfg=NONE') command('hi link @string string') command('hi link @string.cpp @string') - eq({ fg = 10937249 }, meths.get_hl(0, { name = 'String' })) - eq({ link = 'String' }, meths.get_hl(0, { name = '@string' })) - eq({ fg = 10937249 }, meths.get_hl(0, { name = '@string.cpp', link = false })) + eq({ fg = 10937249 }, api.nvim_get_hl(0, { name = 'String' })) + eq({ link = 'String' }, api.nvim_get_hl(0, { name = '@string' })) + eq({ fg = 10937249 }, api.nvim_get_hl(0, { name = '@string.cpp', link = false })) end) it('can get all attributes for a linked group', function() command('hi Bar guifg=red') command('hi Foo guifg=#00ff00 gui=bold,underline') command('hi! link Foo Bar') - eq({ link = 'Bar', fg = tonumber('00ff00', 16), bold = true, underline = true }, meths.get_hl(0, { name = 'Foo', link = true })) + eq( + { link = 'Bar', fg = tonumber('00ff00', 16), bold = true, underline = true }, + api.nvim_get_hl(0, { name = 'Foo', link = true }) + ) end) it('can set link as well as other attributes', function() command('hi Bar guifg=red') local hl = { link = 'Bar', fg = tonumber('00ff00', 16), bold = true, cterm = { bold = true } } - meths.set_hl(0, 'Foo', hl) - eq(hl, meths.get_hl(0, { name = 'Foo', link = true })) + api.nvim_set_hl(0, 'Foo', hl) + eq(hl, api.nvim_get_hl(0, { name = 'Foo', link = true })) end) it("doesn't contain unset groups", function() - local id = meths.get_hl_id_by_name "@foobar.hubbabubba" + local id = api.nvim_get_hl_id_by_name '@foobar.hubbabubba' ok(id > 0) - local data = meths.get_hl(0, {}) - eq(nil, data["@foobar.hubbabubba"]) - eq(nil, data["@foobar"]) + local data = api.nvim_get_hl(0, {}) + eq(nil, data['@foobar.hubbabubba']) + eq(nil, data['@foobar']) command 'hi @foobar.hubbabubba gui=bold' - data = meths.get_hl(0, {}) - eq({bold = true}, data["@foobar.hubbabubba"]) - eq(nil, data["@foobar"]) + data = api.nvim_get_hl(0, {}) + eq({ bold = true }, data['@foobar.hubbabubba']) + eq(nil, data['@foobar']) -- @foobar.hubbabubba was explicitly cleared and thus shows up -- but @foobar was never touched, and thus doesn't command 'hi clear @foobar.hubbabubba' - data = meths.get_hl(0, {}) - eq({}, data["@foobar.hubbabubba"]) - eq(nil, data["@foobar"]) + data = api.nvim_get_hl(0, {}) + eq({}, data['@foobar.hubbabubba']) + eq(nil, data['@foobar']) end) it('should return default flag', function() - meths.set_hl(0, 'Tried', { fg = "#00ff00", default = true }) - eq({ fg = tonumber('00ff00', 16), default = true }, meths.get_hl(0, { name = 'Tried' })) + api.nvim_set_hl(0, 'Tried', { fg = '#00ff00', default = true }) + eq({ fg = tonumber('00ff00', 16), default = true }, api.nvim_get_hl(0, { name = 'Tried' })) end) it('should not output empty gui and cterm #23474', function() - meths.set_hl(0, 'Foo', {default = true}) - meths.set_hl(0, 'Bar', { default = true, fg = '#ffffff' }) - meths.set_hl(0, 'FooBar', { default = true, fg = '#ffffff', cterm = {bold = true} }) - meths.set_hl(0, 'FooBarA', { default = true, fg = '#ffffff', cterm = {bold = true,italic = true}}) - - eq('Foo xxx cleared', - exec_capture('highlight Foo')) - eq({default = true}, meths.get_hl(0, {name = 'Foo'})) - eq('Bar xxx guifg=#ffffff', - exec_capture('highlight Bar')) - eq('FooBar xxx cterm=bold guifg=#ffffff', - exec_capture('highlight FooBar')) - eq('FooBarA xxx cterm=bold,italic guifg=#ffffff', - exec_capture('highlight FooBarA')) + api.nvim_set_hl(0, 'Foo', { default = true }) + api.nvim_set_hl(0, 'Bar', { default = true, fg = '#ffffff' }) + api.nvim_set_hl(0, 'FooBar', { default = true, fg = '#ffffff', cterm = { bold = true } }) + api.nvim_set_hl( + 0, + 'FooBarA', + { default = true, fg = '#ffffff', cterm = { bold = true, italic = true } } + ) + + eq('Foo xxx cleared', exec_capture('highlight Foo')) + eq({ default = true }, api.nvim_get_hl(0, { name = 'Foo' })) + eq('Bar xxx guifg=#ffffff', exec_capture('highlight Bar')) + eq('FooBar xxx cterm=bold guifg=#ffffff', exec_capture('highlight FooBar')) + eq('FooBarA xxx cterm=bold,italic guifg=#ffffff', exec_capture('highlight FooBarA')) end) it('can override exist highlight group by force #20323', function() local white = tonumber('ffffff', 16) local green = tonumber('00ff00', 16) - meths.set_hl(0, 'Foo', { fg=white }) - meths.set_hl(0, 'Foo', { fg=green, force = true }) - eq({ fg = green },meths.get_hl(0, {name = 'Foo'})) - meths.set_hl(0, 'Bar', {link = 'Comment', default = true}) - meths.set_hl(0, 'Bar', {link = 'Foo',default = true, force = true}) - eq({link ='Foo', default = true}, meths.get_hl(0, {name = 'Bar'})) + api.nvim_set_hl(0, 'Foo', { fg = white }) + api.nvim_set_hl(0, 'Foo', { fg = green, force = true }) + eq({ fg = green }, api.nvim_get_hl(0, { name = 'Foo' })) + api.nvim_set_hl(0, 'Bar', { link = 'Comment', default = true }) + api.nvim_set_hl(0, 'Bar', { link = 'Foo', default = true, force = true }) + eq({ link = 'Foo', default = true }, api.nvim_get_hl(0, { name = 'Bar' })) end) end) describe('API: set/get highlight namespace', function() it('set/get highlight namespace', function() - eq(0, meths.get_hl_ns({})) - local ns = meths.create_namespace('') - meths.set_hl_ns(ns) - eq(ns, meths.get_hl_ns({})) + eq(0, api.nvim_get_hl_ns({})) + local ns = api.nvim_create_namespace('') + api.nvim_set_hl_ns(ns) + eq(ns, api.nvim_get_hl_ns({})) end) it('set/get window highlight namespace', function() - eq(-1, meths.get_hl_ns({winid = 0})) - local ns = meths.create_namespace('') - meths.win_set_hl_ns(0, ns) - eq(ns, meths.get_hl_ns({winid = 0})) + eq(-1, api.nvim_get_hl_ns({ winid = 0 })) + local ns = api.nvim_create_namespace('') + api.nvim_win_set_hl_ns(0, ns) + eq(ns, api.nvim_get_hl_ns({ winid = 0 })) end) end) diff --git a/test/functional/api/keymap_spec.lua b/test/functional/api/keymap_spec.lua index 434f117956..0decd710e9 100644 --- a/test/functional/api/keymap_spec.lua +++ b/test/functional/api/keymap_spec.lua @@ -1,20 +1,18 @@ local helpers = require('test.functional.helpers')(after_each) -local bufmeths = helpers.bufmeths local clear = helpers.clear local command = helpers.command -local curbufmeths = helpers.curbufmeths local eq, neq = helpers.eq, helpers.neq local exec_lua = helpers.exec_lua local exec = helpers.exec local feed = helpers.feed -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local source = helpers.source local pcall_err = helpers.pcall_err local shallowcopy = helpers.shallowcopy -local sleep = helpers.sleep +local sleep = vim.uv.sleep local sid_api_client = -9 local sid_lua = -8 @@ -39,25 +37,25 @@ describe('nvim_get_keymap', function() -- Basic mapping and table to be used to describe results local foo_bar_string = 'nnoremap foo bar' local foo_bar_map_table = { - lhs='foo', - lhsraw='foo', - script=0, - silent=0, - rhs='bar', - expr=0, - sid=0, - scriptversion=1, - buffer=0, - nowait=0, - mode='n', - mode_bits=0x01, - abbr=0, - noremap=1, - lnum=0, + lhs = 'foo', + lhsraw = 'foo', + script = 0, + silent = 0, + rhs = 'bar', + expr = 0, + sid = 0, + scriptversion = 1, + buffer = 0, + nowait = 0, + mode = 'n', + mode_bits = 0x01, + abbr = 0, + noremap = 1, + lnum = 0, } it('returns empty list when no map', function() - eq({}, meths.get_keymap('n')) + eq({}, api.nvim_get_keymap('n')) end) it('returns list of all applicable mappings', function() @@ -66,10 +64,8 @@ describe('nvim_get_keymap', function() -- Should be the same as the dictionary we supplied earlier -- and the dictionary you would get from maparg -- since this is a global map, and not script local - eq({foo_bar_map_table}, meths.get_keymap('n')) - eq({funcs.maparg('foo', 'n', false, true)}, - meths.get_keymap('n') - ) + eq({ foo_bar_map_table }, api.nvim_get_keymap('n')) + eq({ fn.maparg('foo', 'n', false, true) }, api.nvim_get_keymap('n')) -- Add another mapping command('nnoremap foo_longer bar_longer') @@ -78,15 +74,11 @@ describe('nvim_get_keymap', function() foolong_bar_map_table['lhsraw'] = 'foo_longer' foolong_bar_map_table['rhs'] = 'bar_longer' - eq({foolong_bar_map_table, foo_bar_map_table}, - meths.get_keymap('n') - ) + eq({ foolong_bar_map_table, foo_bar_map_table }, api.nvim_get_keymap('n')) -- Remove a mapping command('unmap foo_longer') - eq({foo_bar_map_table}, - meths.get_keymap('n') - ) + eq({ foo_bar_map_table }, api.nvim_get_keymap('n')) end) it('works for other modes', function() @@ -100,7 +92,7 @@ describe('nvim_get_keymap', function() insert_table['mode'] = 'i' insert_table['mode_bits'] = 0x10 - eq({insert_table}, meths.get_keymap('i')) + eq({ insert_table }, api.nvim_get_keymap('i')) end) it('considers scope', function() @@ -117,8 +109,8 @@ describe('nvim_get_keymap', function() command('nnoremap <buffer> foo bar') -- The buffer mapping should not show up - eq({foolong_bar_map_table}, meths.get_keymap('n')) - eq({buffer_table}, curbufmeths.get_keymap('n')) + eq({ foolong_bar_map_table }, api.nvim_get_keymap('n')) + eq({ buffer_table }, api.nvim_buf_get_keymap(0, 'n')) end) it('considers scope for overlapping maps', function() @@ -129,12 +121,12 @@ describe('nvim_get_keymap', function() command('nnoremap <buffer> foo bar') - eq({foo_bar_map_table}, meths.get_keymap('n')) - eq({buffer_table}, curbufmeths.get_keymap('n')) + eq({ foo_bar_map_table }, api.nvim_get_keymap('n')) + eq({ buffer_table }, api.nvim_buf_get_keymap(0, 'n')) end) it('can retrieve mapping for different buffers', function() - local original_buffer = curbufmeths.get_number() + local original_buffer = api.nvim_buf_get_number(0) -- Place something in each of the buffers to make sure they stick around -- and set hidden so we can leave them command('set hidden') @@ -143,87 +135,124 @@ describe('nvim_get_keymap', function() command('new') command('normal! ihello 3') - local final_buffer = curbufmeths.get_number() + local final_buffer = api.nvim_buf_get_number(0) command('nnoremap <buffer> foo bar') -- Final buffer will have buffer mappings local buffer_table = shallowcopy(foo_bar_map_table) buffer_table['buffer'] = final_buffer - eq({buffer_table}, meths.buf_get_keymap(final_buffer, 'n')) - eq({buffer_table}, meths.buf_get_keymap(0, 'n')) + eq({ buffer_table }, api.nvim_buf_get_keymap(final_buffer, 'n')) + eq({ buffer_table }, api.nvim_buf_get_keymap(0, 'n')) command('buffer ' .. original_buffer) - eq(original_buffer, curbufmeths.get_number()) + eq(original_buffer, api.nvim_buf_get_number(0)) -- Original buffer won't have any mappings - eq({}, meths.get_keymap('n')) - eq({}, curbufmeths.get_keymap('n')) - eq({buffer_table}, meths.buf_get_keymap(final_buffer, 'n')) + eq({}, api.nvim_get_keymap('n')) + eq({}, api.nvim_buf_get_keymap(0, 'n')) + eq({ buffer_table }, api.nvim_buf_get_keymap(final_buffer, 'n')) end) -- Test toggle switches for basic options -- @param option The key represented in the `maparg()` result dict - local function global_and_buffer_test(map, - option, - option_token, - global_on_result, - buffer_on_result, - global_off_result, - buffer_off_result, - new_windows) - + local function global_and_buffer_test( + map, + option, + option_token, + global_on_result, + buffer_on_result, + global_off_result, + buffer_off_result, + new_windows + ) local function make_new_windows(number_of_windows) if new_windows == nil then return nil end - for _=1,number_of_windows do + for _ = 1, number_of_windows do command('new') end end - local mode = string.sub(map, 1,1) + local mode = string.sub(map, 1, 1) -- Don't run this for the <buffer> mapping, since it doesn't make sense if option_token ~= '<buffer>' then - it(string.format( 'returns %d for the key "%s" when %s is used globally with %s (%s)', - global_on_result, option, option_token, map, mode), function() - make_new_windows(new_windows) - command(map .. ' ' .. option_token .. ' foo bar') - local result = meths.get_keymap(mode)[1][option] - eq(global_on_result, result) - end) + it( + string.format( + 'returns %d for the key "%s" when %s is used globally with %s (%s)', + global_on_result, + option, + option_token, + map, + mode + ), + function() + make_new_windows(new_windows) + command(map .. ' ' .. option_token .. ' foo bar') + local result = api.nvim_get_keymap(mode)[1][option] + eq(global_on_result, result) + end + ) end - it(string.format('returns %d for the key "%s" when %s is used for buffers with %s (%s)', - buffer_on_result, option, option_token, map, mode), function() - make_new_windows(new_windows) - command(map .. ' <buffer> ' .. option_token .. ' foo bar') - local result = curbufmeths.get_keymap(mode)[1][option] - eq(buffer_on_result, result) - end) + it( + string.format( + 'returns %d for the key "%s" when %s is used for buffers with %s (%s)', + buffer_on_result, + option, + option_token, + map, + mode + ), + function() + make_new_windows(new_windows) + command(map .. ' <buffer> ' .. option_token .. ' foo bar') + local result = api.nvim_buf_get_keymap(0, mode)[1][option] + eq(buffer_on_result, result) + end + ) -- Don't run these for the <buffer> mapping, since it doesn't make sense if option_token ~= '<buffer>' then - it(string.format('returns %d for the key "%s" when %s is not used globally with %s (%s)', - global_off_result, option, option_token, map, mode), function() - make_new_windows(new_windows) - command(map .. ' baz bat') - local result = meths.get_keymap(mode)[1][option] - eq(global_off_result, result) - end) - - it(string.format('returns %d for the key "%s" when %s is not used for buffers with %s (%s)', - buffer_off_result, option, option_token, map, mode), function() - make_new_windows(new_windows) - command(map .. ' <buffer> foo bar') + it( + string.format( + 'returns %d for the key "%s" when %s is not used globally with %s (%s)', + global_off_result, + option, + option_token, + map, + mode + ), + function() + make_new_windows(new_windows) + command(map .. ' baz bat') + local result = api.nvim_get_keymap(mode)[1][option] + eq(global_off_result, result) + end + ) - local result = curbufmeths.get_keymap(mode)[1][option] - eq(buffer_off_result, result) - end) + it( + string.format( + 'returns %d for the key "%s" when %s is not used for buffers with %s (%s)', + buffer_off_result, + option, + option_token, + map, + mode + ), + function() + make_new_windows(new_windows) + command(map .. ' <buffer> foo bar') + + local result = api.nvim_buf_get_keymap(0, mode)[1][option] + eq(buffer_off_result, result) + end + ) end end -- Standard modes and returns the same values in the dictionary as maparg() - local mode_list = {'nnoremap', 'nmap', 'imap', 'inoremap', 'cnoremap'} + local mode_list = { 'nnoremap', 'nmap', 'imap', 'inoremap', 'cnoremap' } for mode in pairs(mode_list) do global_and_buffer_test(mode_list[mode], 'silent', '<silent>', 1, 1, 0, 0) global_and_buffer_test(mode_list[mode], 'nowait', '<nowait>', 1, 1, 0, 0) @@ -246,9 +275,9 @@ describe('nvim_get_keymap', function() nnoremap fizz :call <SID>maparg_test_function()<CR> ]]) - local sid_result = meths.get_keymap('n')[1]['sid'] + local sid_result = api.nvim_get_keymap('n')[1]['sid'] eq(1, sid_result) - eq('testing', meths.call_function('<SNR>' .. sid_result .. '_maparg_test_function', {})) + eq('testing', api.nvim_call_function('<SNR>' .. sid_result .. '_maparg_test_function', {})) end) it('returns script numbers for buffer maps', function() @@ -259,29 +288,29 @@ describe('nvim_get_keymap', function() nnoremap <buffer> fizz :call <SID>maparg_test_function()<CR> ]]) - local sid_result = curbufmeths.get_keymap('n')[1]['sid'] + local sid_result = api.nvim_buf_get_keymap(0, 'n')[1]['sid'] eq(1, sid_result) - eq('testing', meths.call_function('<SNR>' .. sid_result .. '_maparg_test_function', {})) + eq('testing', api.nvim_call_function('<SNR>' .. sid_result .. '_maparg_test_function', {})) end) it('works with <F12> and others', function() command('nnoremap <F12> :let g:maparg_test_var = 1<CR>') - eq('<F12>', meths.get_keymap('n')[1]['lhs']) - eq(':let g:maparg_test_var = 1<CR>', meths.get_keymap('n')[1]['rhs']) + eq('<F12>', api.nvim_get_keymap('n')[1]['lhs']) + eq(':let g:maparg_test_var = 1<CR>', api.nvim_get_keymap('n')[1]['rhs']) end) it('works correctly despite various &cpo settings', function() local cpo_table = { - script=0, - silent=0, - expr=0, - sid=0, - scriptversion=1, - buffer=0, - nowait=0, - abbr=0, - noremap=1, - lnum=0, + script = 0, + silent = 0, + expr = 0, + sid = 0, + scriptversion = 1, + buffer = 0, + nowait = 0, + abbr = 0, + noremap = 1, + lnum = 0, } local function cpomap(lhs, rhs, mode) local ret = shallowcopy(cpo_table) @@ -310,7 +339,7 @@ describe('nvim_get_keymap', function() -- wrapper around get_keymap() that drops "lhsraw" and "lhsrawalt" which are hard to check local function get_keymap_noraw(...) - local ret = meths.get_keymap(...) + local ret = api.nvim_get_keymap(...) for _, item in ipairs(ret) do item.lhsraw = nil item.lhsrawalt = nil @@ -323,103 +352,164 @@ describe('nvim_get_keymap', function() 'set cpo+=B', }) do command(cmd) - eq({cpomap('\\<C-C><C-C><lt>C-c>\\', '\\<C-D><C-D><lt>C-d>\\', 'n'), - cpomap('\\<C-A><C-A><lt>C-a>\\', '\\<C-B><C-B><lt>C-b>\\', 'n')}, - get_keymap_noraw('n')) - eq({cpomap('\\<C-C><C-C><lt>C-c>\\', '\\<C-D><C-D><lt>C-d>\\', 'x'), - cpomap('\\<C-A><C-A><lt>C-a>\\', '\\<C-B><C-B><lt>C-b>\\', 'x')}, - get_keymap_noraw('x')) - eq({cpomap('<lt>C-c><C-C><lt>C-c> ', '<lt>C-d><C-D><lt>C-d>', 's'), - cpomap('<lt>C-a><C-A><lt>C-a> ', '<lt>C-b><C-B><lt>C-b>', 's')}, - get_keymap_noraw('s')) - eq({cpomap('<lt>C-c><C-C><lt>C-c> ', '<lt>C-d><C-D><lt>C-d>', 'o'), - cpomap('<lt>C-a><C-A><lt>C-a> ', '<lt>C-b><C-B><lt>C-b>', 'o')}, - get_keymap_noraw('o')) + eq({ + cpomap('\\<C-C><C-C><lt>C-c>\\', '\\<C-D><C-D><lt>C-d>\\', 'n'), + cpomap('\\<C-A><C-A><lt>C-a>\\', '\\<C-B><C-B><lt>C-b>\\', 'n'), + }, get_keymap_noraw('n')) + eq({ + cpomap('\\<C-C><C-C><lt>C-c>\\', '\\<C-D><C-D><lt>C-d>\\', 'x'), + cpomap('\\<C-A><C-A><lt>C-a>\\', '\\<C-B><C-B><lt>C-b>\\', 'x'), + }, get_keymap_noraw('x')) + eq({ + cpomap('<lt>C-c><C-C><lt>C-c> ', '<lt>C-d><C-D><lt>C-d>', 's'), + cpomap('<lt>C-a><C-A><lt>C-a> ', '<lt>C-b><C-B><lt>C-b>', 's'), + }, get_keymap_noraw('s')) + eq({ + cpomap('<lt>C-c><C-C><lt>C-c> ', '<lt>C-d><C-D><lt>C-d>', 'o'), + cpomap('<lt>C-a><C-A><lt>C-a> ', '<lt>C-b><C-B><lt>C-b>', 'o'), + }, get_keymap_noraw('o')) end end) it('always uses space for space and bar for bar', function() local space_table = { - lhs='| |', - lhsraw='| |', - rhs='| |', - mode='n', - mode_bits=0x01, - abbr=0, - script=0, - silent=0, - expr=0, - sid=0, - scriptversion=1, - buffer=0, - nowait=0, - noremap=1, - lnum=0, + lhs = '| |', + lhsraw = '| |', + rhs = '| |', + mode = 'n', + mode_bits = 0x01, + abbr = 0, + script = 0, + silent = 0, + expr = 0, + sid = 0, + scriptversion = 1, + buffer = 0, + nowait = 0, + noremap = 1, + lnum = 0, } command('nnoremap \\|<Char-0x20><Char-32><Space><Bar> \\|<Char-0x20><Char-32><Space> <Bar>') - eq({space_table}, meths.get_keymap('n')) + eq({ space_table }, api.nvim_get_keymap('n')) end) it('can handle lua mappings', function() - eq(0, exec_lua([[ + eq( + 0, + exec_lua([[ GlobalCount = 0 vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) return GlobalCount - ]])) + ]]) + ) feed('asdf\n') eq(1, exec_lua([[return GlobalCount]])) - eq(2, exec_lua([[ + eq( + 2, + exec_lua([[ vim.api.nvim_get_keymap('n')[1].callback() return GlobalCount - ]])) + ]]) + ) exec([[ call nvim_get_keymap('n')[0].callback() ]]) eq(3, exec_lua([[return GlobalCount]])) - local mapargs = meths.get_keymap('n') + local mapargs = api.nvim_get_keymap('n') mapargs[1].callback = nil eq({ - lhs='asdf', - lhsraw='asdf', - script=0, - silent=0, - expr=0, - sid=sid_lua, - scriptversion=1, - buffer=0, - nowait=0, - mode='n', - mode_bits=0x01, - abbr=0, - noremap=0, - lnum=0, + lhs = 'asdf', + lhsraw = 'asdf', + script = 0, + silent = 0, + expr = 0, + sid = sid_lua, + scriptversion = 1, + buffer = 0, + nowait = 0, + mode = 'n', + mode_bits = 0x01, + abbr = 0, + noremap = 0, + lnum = 0, }, mapargs[1]) end) it('can handle map descriptions', function() - meths.set_keymap('n', 'lhs', 'rhs', {desc="map description"}) + api.nvim_set_keymap('n', 'lhs', 'rhs', { desc = 'map description' }) eq({ - lhs='lhs', - lhsraw='lhs', - rhs='rhs', - script=0, - silent=0, - expr=0, - sid=sid_api_client, - scriptversion=1, - buffer=0, - nowait=0, - mode='n', - mode_bits=0x01, - abbr=0, - noremap=0, - lnum=0, - desc='map description' - }, meths.get_keymap('n')[1]) + lhs = 'lhs', + lhsraw = 'lhs', + rhs = 'rhs', + script = 0, + silent = 0, + expr = 0, + sid = sid_api_client, + scriptversion = 1, + buffer = 0, + nowait = 0, + mode = 'n', + mode_bits = 0x01, + abbr = 0, + noremap = 0, + lnum = 0, + desc = 'map description', + }, api.nvim_get_keymap('n')[1]) + end) + + it('can get abbreviations', function() + command('inoreabbr foo bar') + command('cnoreabbr <buffer> foo baz') + + local mapargs_i = { + abbr = 1, + buffer = 0, + expr = 0, + lhs = 'foo', + lhsraw = 'foo', + lnum = 0, + mode = 'i', + mode_bits = 0x10, + noremap = 1, + nowait = 0, + rhs = 'bar', + script = 0, + scriptversion = 1, + sid = 0, + silent = 0, + } + local mapargs_c = { + abbr = 1, + buffer = 1, + expr = 0, + lhs = 'foo', + lhsraw = 'foo', + lnum = 0, + mode = 'c', + mode_bits = 0x08, + noremap = 1, + nowait = 0, + rhs = 'baz', + script = 0, + scriptversion = 1, + sid = 0, + silent = 0, + } + + local curbuf = api.nvim_get_current_buf() + + eq({ mapargs_i }, api.nvim_get_keymap('ia')) + eq({}, api.nvim_buf_get_keymap(curbuf, 'ia')) + + eq({}, api.nvim_get_keymap('ca')) + eq({ mapargs_c }, api.nvim_buf_get_keymap(curbuf, 'ca')) + + eq({ mapargs_i }, api.nvim_get_keymap('!a')) + eq({ mapargs_c }, api.nvim_buf_get_keymap(curbuf, '!a')) end) end) @@ -472,7 +562,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function() -- Gets a maparg() dict from Nvim, if one exists. local function get_mapargs(mode, lhs) - local mapargs = funcs.maparg(lhs, normalize_mapmode(mode), mode:sub(-1) == 'a', true) + local mapargs = fn.maparg(lhs, normalize_mapmode(mode), mode:sub(-1) == 'a', true) -- drop "lhsraw" and "lhsrawalt" which are hard to check mapargs.lhsraw = nil mapargs.lhsrawalt = nil @@ -481,238 +571,239 @@ describe('nvim_set_keymap, nvim_del_keymap', function() it('error on empty LHS', function() -- escape parentheses in lua string, else comparison fails erroneously - eq('Invalid (empty) LHS', pcall_err(meths.set_keymap, '', '', 'rhs', {})) - eq('Invalid (empty) LHS', pcall_err(meths.set_keymap, '', '', '', {})) - eq('Invalid (empty) LHS', pcall_err(meths.del_keymap, '', '')) + eq('Invalid (empty) LHS', pcall_err(api.nvim_set_keymap, '', '', 'rhs', {})) + eq('Invalid (empty) LHS', pcall_err(api.nvim_set_keymap, '', '', '', {})) + eq('Invalid (empty) LHS', pcall_err(api.nvim_del_keymap, '', '')) end) it('error if LHS longer than MAXMAPLEN', function() -- assume MAXMAPLEN of 50 chars, as declared in mapping_defs.h local MAXMAPLEN = 50 local lhs = '' - for i=1,MAXMAPLEN do - lhs = lhs..(i % 10) + for i = 1, MAXMAPLEN do + lhs = lhs .. (i % 10) end -- exactly 50 chars should be fine - meths.set_keymap('', lhs, 'rhs', {}) + api.nvim_set_keymap('', lhs, 'rhs', {}) -- del_keymap should unmap successfully - meths.del_keymap('', lhs) + api.nvim_del_keymap('', lhs) eq({}, get_mapargs('', lhs)) -- 51 chars should produce an error - lhs = lhs..'1' - eq('LHS exceeds maximum map length: '..lhs, - pcall_err(meths.set_keymap, '', lhs, 'rhs', {})) - eq('LHS exceeds maximum map length: '..lhs, - pcall_err(meths.del_keymap, '', lhs)) + lhs = lhs .. '1' + eq( + 'LHS exceeds maximum map length: ' .. lhs, + pcall_err(api.nvim_set_keymap, '', lhs, 'rhs', {}) + ) + eq('LHS exceeds maximum map length: ' .. lhs, pcall_err(api.nvim_del_keymap, '', lhs)) end) it('does not throw errors when rhs is longer than MAXMAPLEN', function() local MAXMAPLEN = 50 local rhs = '' - for i=1,MAXMAPLEN do - rhs = rhs..(i % 10) + for i = 1, MAXMAPLEN do + rhs = rhs .. (i % 10) end - rhs = rhs..'1' - meths.set_keymap('', 'lhs', rhs, {}) - eq(generate_mapargs('', 'lhs', rhs), - get_mapargs('', 'lhs')) + rhs = rhs .. '1' + api.nvim_set_keymap('', 'lhs', rhs, {}) + eq(generate_mapargs('', 'lhs', rhs), get_mapargs('', 'lhs')) end) it('error on invalid mode shortname', function() - eq('Invalid mode shortname: " "', pcall_err(meths.set_keymap, ' ', 'lhs', 'rhs', {})) - eq('Invalid mode shortname: "m"', pcall_err(meths.set_keymap, 'm', 'lhs', 'rhs', {})) - eq('Invalid mode shortname: "?"', pcall_err(meths.set_keymap, '?', 'lhs', 'rhs', {})) - eq('Invalid mode shortname: "y"', pcall_err(meths.set_keymap, 'y', 'lhs', 'rhs', {})) - eq('Invalid mode shortname: "p"', pcall_err(meths.set_keymap, 'p', 'lhs', 'rhs', {})) - eq('Invalid mode shortname: "a"', pcall_err(meths.set_keymap, 'a', 'lhs', 'rhs', {})) - eq('Invalid mode shortname: "oa"', pcall_err(meths.set_keymap, 'oa', 'lhs', 'rhs', {})) - eq('Invalid mode shortname: "!o"', pcall_err(meths.set_keymap, '!o', 'lhs', 'rhs', {})) - eq('Invalid mode shortname: "!i"', pcall_err(meths.set_keymap, '!i', 'lhs', 'rhs', {})) - eq('Invalid mode shortname: "!!"', pcall_err(meths.set_keymap, '!!', 'lhs', 'rhs', {})) - eq('Invalid mode shortname: "map"', pcall_err(meths.set_keymap, 'map', 'lhs', 'rhs', {})) - eq('Invalid mode shortname: "vmap"', pcall_err(meths.set_keymap, 'vmap', 'lhs', 'rhs', {})) - eq('Invalid mode shortname: "xnoremap"', pcall_err(meths.set_keymap, 'xnoremap', 'lhs', 'rhs', {})) - eq('Invalid mode shortname: " "', pcall_err(meths.del_keymap, ' ', 'lhs')) - eq('Invalid mode shortname: "m"', pcall_err(meths.del_keymap, 'm', 'lhs')) - eq('Invalid mode shortname: "?"', pcall_err(meths.del_keymap, '?', 'lhs')) - eq('Invalid mode shortname: "y"', pcall_err(meths.del_keymap, 'y', 'lhs')) - eq('Invalid mode shortname: "p"', pcall_err(meths.del_keymap, 'p', 'lhs')) - eq('Invalid mode shortname: "a"', pcall_err(meths.del_keymap, 'a', 'lhs')) - eq('Invalid mode shortname: "oa"', pcall_err(meths.del_keymap, 'oa', 'lhs')) - eq('Invalid mode shortname: "!o"', pcall_err(meths.del_keymap, '!o', 'lhs')) - eq('Invalid mode shortname: "!i"', pcall_err(meths.del_keymap, '!i', 'lhs')) - eq('Invalid mode shortname: "!!"', pcall_err(meths.del_keymap, '!!', 'lhs')) - eq('Invalid mode shortname: "map"', pcall_err(meths.del_keymap, 'map', 'lhs')) - eq('Invalid mode shortname: "vmap"', pcall_err(meths.del_keymap, 'vmap', 'lhs')) - eq('Invalid mode shortname: "xnoremap"', pcall_err(meths.del_keymap, 'xnoremap', 'lhs')) + eq('Invalid mode shortname: " "', pcall_err(api.nvim_set_keymap, ' ', 'lhs', 'rhs', {})) + eq('Invalid mode shortname: "m"', pcall_err(api.nvim_set_keymap, 'm', 'lhs', 'rhs', {})) + eq('Invalid mode shortname: "?"', pcall_err(api.nvim_set_keymap, '?', 'lhs', 'rhs', {})) + eq('Invalid mode shortname: "y"', pcall_err(api.nvim_set_keymap, 'y', 'lhs', 'rhs', {})) + eq('Invalid mode shortname: "p"', pcall_err(api.nvim_set_keymap, 'p', 'lhs', 'rhs', {})) + eq('Invalid mode shortname: "a"', pcall_err(api.nvim_set_keymap, 'a', 'lhs', 'rhs', {})) + eq('Invalid mode shortname: "oa"', pcall_err(api.nvim_set_keymap, 'oa', 'lhs', 'rhs', {})) + eq('Invalid mode shortname: "!o"', pcall_err(api.nvim_set_keymap, '!o', 'lhs', 'rhs', {})) + eq('Invalid mode shortname: "!i"', pcall_err(api.nvim_set_keymap, '!i', 'lhs', 'rhs', {})) + eq('Invalid mode shortname: "!!"', pcall_err(api.nvim_set_keymap, '!!', 'lhs', 'rhs', {})) + eq('Invalid mode shortname: "map"', pcall_err(api.nvim_set_keymap, 'map', 'lhs', 'rhs', {})) + eq('Invalid mode shortname: "vmap"', pcall_err(api.nvim_set_keymap, 'vmap', 'lhs', 'rhs', {})) + eq( + 'Invalid mode shortname: "xnoremap"', + pcall_err(api.nvim_set_keymap, 'xnoremap', 'lhs', 'rhs', {}) + ) + eq('Invalid mode shortname: " "', pcall_err(api.nvim_del_keymap, ' ', 'lhs')) + eq('Invalid mode shortname: "m"', pcall_err(api.nvim_del_keymap, 'm', 'lhs')) + eq('Invalid mode shortname: "?"', pcall_err(api.nvim_del_keymap, '?', 'lhs')) + eq('Invalid mode shortname: "y"', pcall_err(api.nvim_del_keymap, 'y', 'lhs')) + eq('Invalid mode shortname: "p"', pcall_err(api.nvim_del_keymap, 'p', 'lhs')) + eq('Invalid mode shortname: "a"', pcall_err(api.nvim_del_keymap, 'a', 'lhs')) + eq('Invalid mode shortname: "oa"', pcall_err(api.nvim_del_keymap, 'oa', 'lhs')) + eq('Invalid mode shortname: "!o"', pcall_err(api.nvim_del_keymap, '!o', 'lhs')) + eq('Invalid mode shortname: "!i"', pcall_err(api.nvim_del_keymap, '!i', 'lhs')) + eq('Invalid mode shortname: "!!"', pcall_err(api.nvim_del_keymap, '!!', 'lhs')) + eq('Invalid mode shortname: "map"', pcall_err(api.nvim_del_keymap, 'map', 'lhs')) + eq('Invalid mode shortname: "vmap"', pcall_err(api.nvim_del_keymap, 'vmap', 'lhs')) + eq('Invalid mode shortname: "xnoremap"', pcall_err(api.nvim_del_keymap, 'xnoremap', 'lhs')) end) it('error on invalid optnames', function() - eq("Invalid key: 'silentt'", - pcall_err(meths.set_keymap, 'n', 'lhs', 'rhs', {silentt = true})) - eq("Invalid key: 'sidd'", - pcall_err(meths.set_keymap, 'n', 'lhs', 'rhs', {sidd = false})) - eq("Invalid key: 'nowaiT'", - pcall_err(meths.set_keymap, 'n', 'lhs', 'rhs', {nowaiT = false})) + eq( + "Invalid key: 'silentt'", + pcall_err(api.nvim_set_keymap, 'n', 'lhs', 'rhs', { silentt = true }) + ) + eq("Invalid key: 'sidd'", pcall_err(api.nvim_set_keymap, 'n', 'lhs', 'rhs', { sidd = false })) + eq( + "Invalid key: 'nowaiT'", + pcall_err(api.nvim_set_keymap, 'n', 'lhs', 'rhs', { nowaiT = false }) + ) end) it('error on <buffer> option key', function() - eq("Invalid key: 'buffer'", - pcall_err(meths.set_keymap, 'n', 'lhs', 'rhs', {buffer = true})) + eq( + "Invalid key: 'buffer'", + pcall_err(api.nvim_set_keymap, 'n', 'lhs', 'rhs', { buffer = true }) + ) end) it('error when "replace_keycodes" is used without "expr"', function() - eq('"replace_keycodes" requires "expr"', - pcall_err(meths.set_keymap, 'n', 'lhs', 'rhs', {replace_keycodes = true})) + eq( + '"replace_keycodes" requires "expr"', + pcall_err(api.nvim_set_keymap, 'n', 'lhs', 'rhs', { replace_keycodes = true }) + ) end) - local optnames = {'nowait', 'silent', 'script', 'expr', 'unique'} + local optnames = { 'nowait', 'silent', 'script', 'expr', 'unique' } for _, opt in ipairs(optnames) do -- note: need '%' to escape hyphens, which have special meaning in lua - it('throws an error when given non-boolean value for '..opt, function() + it('throws an error when given non-boolean value for ' .. opt, function() local opts = {} opts[opt] = 'fooo' - eq(opt..' is not a boolean', - pcall_err(meths.set_keymap, 'n', 'lhs', 'rhs', opts)) + eq(opt .. ' is not a boolean', pcall_err(api.nvim_set_keymap, 'n', 'lhs', 'rhs', opts)) end) end -- Perform tests of basic functionality it('sets ordinary mappings', function() - meths.set_keymap('n', 'lhs', 'rhs', {}) + api.nvim_set_keymap('n', 'lhs', 'rhs', {}) eq(generate_mapargs('n', 'lhs', 'rhs'), get_mapargs('n', 'lhs')) - meths.set_keymap('v', 'lhs', 'rhs', {}) + api.nvim_set_keymap('v', 'lhs', 'rhs', {}) eq(generate_mapargs('v', 'lhs', 'rhs'), get_mapargs('v', 'lhs')) end) it('does not throw when LHS or RHS have leading/trailing whitespace', function() - meths.set_keymap('n', ' lhs', 'rhs', {}) - eq(generate_mapargs('n', '<Space><Space><Space>lhs', 'rhs'), - get_mapargs('n', ' lhs')) + api.nvim_set_keymap('n', ' lhs', 'rhs', {}) + eq(generate_mapargs('n', '<Space><Space><Space>lhs', 'rhs'), get_mapargs('n', ' lhs')) - meths.set_keymap('n', 'lhs ', 'rhs', {}) - eq(generate_mapargs('n', 'lhs<Space><Space><Space><Space>', 'rhs'), - get_mapargs('n', 'lhs ')) + api.nvim_set_keymap('n', 'lhs ', 'rhs', {}) + eq(generate_mapargs('n', 'lhs<Space><Space><Space><Space>', 'rhs'), get_mapargs('n', 'lhs ')) - meths.set_keymap('v', ' lhs ', '\trhs\t\f', {}) - eq(generate_mapargs('v', '<Space>lhs<Space><Space>', '\trhs\t\f'), - get_mapargs('v', ' lhs ')) + api.nvim_set_keymap('v', ' lhs ', '\trhs\t\f', {}) + eq(generate_mapargs('v', '<Space>lhs<Space><Space>', '\trhs\t\f'), get_mapargs('v', ' lhs ')) end) it('can set noremap mappings', function() - meths.set_keymap('x', 'lhs', 'rhs', {noremap = true}) - eq(generate_mapargs('x', 'lhs', 'rhs', {noremap = true}), - get_mapargs('x', 'lhs')) + api.nvim_set_keymap('x', 'lhs', 'rhs', { noremap = true }) + eq(generate_mapargs('x', 'lhs', 'rhs', { noremap = true }), get_mapargs('x', 'lhs')) - meths.set_keymap('t', 'lhs', 'rhs', {noremap = true}) - eq(generate_mapargs('t', 'lhs', 'rhs', {noremap = true}), - get_mapargs('t', 'lhs')) + api.nvim_set_keymap('t', 'lhs', 'rhs', { noremap = true }) + eq(generate_mapargs('t', 'lhs', 'rhs', { noremap = true }), get_mapargs('t', 'lhs')) end) it('can unmap mappings', function() - meths.set_keymap('v', 'lhs', 'rhs', {}) - meths.del_keymap('v', 'lhs') + api.nvim_set_keymap('v', 'lhs', 'rhs', {}) + api.nvim_del_keymap('v', 'lhs') eq({}, get_mapargs('v', 'lhs')) - meths.set_keymap('t', 'lhs', 'rhs', {noremap = true}) - meths.del_keymap('t', 'lhs') + api.nvim_set_keymap('t', 'lhs', 'rhs', { noremap = true }) + api.nvim_del_keymap('t', 'lhs') eq({}, get_mapargs('t', 'lhs')) end) -- Test some edge cases it('"!" and empty string are synonyms for mapmode-nvo', function() - local nvo_shortnames = {'', '!'} + local nvo_shortnames = { '', '!' } for _, name in ipairs(nvo_shortnames) do - meths.set_keymap(name, 'lhs', 'rhs', {}) - meths.del_keymap(name, 'lhs') + api.nvim_set_keymap(name, 'lhs', 'rhs', {}) + api.nvim_del_keymap(name, 'lhs') eq({}, get_mapargs(name, 'lhs')) end end) - local special_chars = {'<C-U>', '<S-Left>', '<F12><F2><Tab>', '<Space><Tab>'} + local special_chars = { '<C-U>', '<S-Left>', '<F12><F2><Tab>', '<Space><Tab>' } for _, lhs in ipairs(special_chars) do for _, rhs in ipairs(special_chars) do local mapmode = '!' - it('can set mappings with special characters, lhs: '..lhs..', rhs: '..rhs, - function() - meths.set_keymap(mapmode, lhs, rhs, {}) + it('can set mappings with special characters, lhs: ' .. lhs .. ', rhs: ' .. rhs, function() + api.nvim_set_keymap(mapmode, lhs, rhs, {}) eq(generate_mapargs(mapmode, lhs, rhs), get_mapargs(mapmode, lhs)) end) end end it('can set mappings containing literal keycodes', function() - meths.set_keymap('n', '\n\r\n', 'rhs', {}) + api.nvim_set_keymap('n', '\n\r\n', 'rhs', {}) local expected = generate_mapargs('n', '<NL><CR><NL>', 'rhs') eq(expected, get_mapargs('n', '<NL><CR><NL>')) end) it('can set mappings whose RHS is a <Nop>', function() - meths.set_keymap('i', 'lhs', '<Nop>', {}) + api.nvim_set_keymap('i', 'lhs', '<Nop>', {}) command('normal ilhs') - eq({''}, curbufmeths.get_lines(0, -1, 0)) -- imap to <Nop> does nothing - eq(generate_mapargs('i', 'lhs', '<Nop>', {}), - get_mapargs('i', 'lhs')) + eq({ '' }, api.nvim_buf_get_lines(0, 0, -1, 0)) -- imap to <Nop> does nothing + eq(generate_mapargs('i', 'lhs', '<Nop>', {}), get_mapargs('i', 'lhs')) -- also test for case insensitivity - meths.set_keymap('i', 'lhs', '<nOp>', {}) + api.nvim_set_keymap('i', 'lhs', '<nOp>', {}) command('normal ilhs') - eq({''}, curbufmeths.get_lines(0, -1, 0)) + eq({ '' }, api.nvim_buf_get_lines(0, 0, -1, 0)) -- note: RHS in returned mapargs() dict reflects the original RHS -- provided by the user - eq(generate_mapargs('i', 'lhs', '<nOp>', {}), - get_mapargs('i', 'lhs')) + eq(generate_mapargs('i', 'lhs', '<nOp>', {}), get_mapargs('i', 'lhs')) - meths.set_keymap('i', 'lhs', '<NOP>', {}) + api.nvim_set_keymap('i', 'lhs', '<NOP>', {}) command('normal ilhs') - eq({''}, curbufmeths.get_lines(0, -1, 0)) - eq(generate_mapargs('i', 'lhs', '<NOP>', {}), - get_mapargs('i', 'lhs')) + eq({ '' }, api.nvim_buf_get_lines(0, 0, -1, 0)) + eq(generate_mapargs('i', 'lhs', '<NOP>', {}), get_mapargs('i', 'lhs')) -- a single ^V in RHS is also <Nop> (see :h map-empty-rhs) - meths.set_keymap('i', 'lhs', '\022', {}) + api.nvim_set_keymap('i', 'lhs', '\022', {}) command('normal ilhs') - eq({''}, curbufmeths.get_lines(0, -1, 0)) - eq(generate_mapargs('i', 'lhs', '\022', {}), - get_mapargs('i', 'lhs')) + eq({ '' }, api.nvim_buf_get_lines(0, 0, -1, 0)) + eq(generate_mapargs('i', 'lhs', '\022', {}), get_mapargs('i', 'lhs')) end) it('treats an empty RHS in a mapping like a <Nop>', function() - meths.set_keymap('i', 'lhs', '', {}) + api.nvim_set_keymap('i', 'lhs', '', {}) command('normal ilhs') - eq({''}, curbufmeths.get_lines(0, -1, 0)) - eq(generate_mapargs('i', 'lhs', '', {}), - get_mapargs('i', 'lhs')) + eq({ '' }, api.nvim_buf_get_lines(0, 0, -1, 0)) + eq(generate_mapargs('i', 'lhs', '', {}), get_mapargs('i', 'lhs')) end) it('can set and unset <M-">', function() -- Taken from the legacy test: test_mapping.vim. Exposes a bug in which -- replace_termcodes changes the length of the mapping's LHS, but -- do_map continues to use the *old* length of LHS. - meths.set_keymap('i', '<M-">', 'foo', {}) - meths.del_keymap('i', '<M-">') + api.nvim_set_keymap('i', '<M-">', 'foo', {}) + api.nvim_del_keymap('i', '<M-">') eq({}, get_mapargs('i', '<M-">')) end) - it('interprets control sequences in expr-quotes correctly when called ' - ..'inside vim', function() - command([[call nvim_set_keymap('i', "\<space>", "\<tab>", {})]]) - eq(generate_mapargs('i', '<Space>', '\t', {sid=0}), - get_mapargs('i', '<Space>')) - feed('i ') - eq({'\t'}, curbufmeths.get_lines(0, -1, 0)) - end) + it( + 'interprets control sequences in expr-quotes correctly when called ' .. 'inside vim', + function() + command([[call nvim_set_keymap('i', "\<space>", "\<tab>", {})]]) + eq(generate_mapargs('i', '<Space>', '\t', { sid = 0 }), get_mapargs('i', '<Space>')) + feed('i ') + eq({ '\t' }, api.nvim_buf_get_lines(0, 0, -1, 0)) + end + ) it('throws appropriate error messages when setting <unique> maps', function() - meths.set_keymap('l', 'lhs', 'rhs', {}) - eq('E227: mapping already exists for lhs', - pcall_err(meths.set_keymap, 'l', 'lhs', 'rhs', {unique = true})) + api.nvim_set_keymap('l', 'lhs', 'rhs', {}) + eq( + 'E227: mapping already exists for lhs', + pcall_err(api.nvim_set_keymap, 'l', 'lhs', 'rhs', { unique = true }) + ) -- different mapmode, no error should be thrown - meths.set_keymap('t', 'lhs', 'rhs', {unique = true}) + api.nvim_set_keymap('t', 'lhs', 'rhs', { unique = true }) end) it('can set <expr> mappings whose RHS change dynamically', function() @@ -723,50 +814,50 @@ describe('nvim_set_keymap, nvim_del_keymap', function() return g:flip endfunction ]]) - eq(1, meths.call_function('FlipFlop', {})) - eq(0, meths.call_function('FlipFlop', {})) - eq(1, meths.call_function('FlipFlop', {})) - eq(0, meths.call_function('FlipFlop', {})) + eq(1, api.nvim_call_function('FlipFlop', {})) + eq(0, api.nvim_call_function('FlipFlop', {})) + eq(1, api.nvim_call_function('FlipFlop', {})) + eq(0, api.nvim_call_function('FlipFlop', {})) - meths.set_keymap('i', 'lhs', 'FlipFlop()', {expr = true}) + api.nvim_set_keymap('i', 'lhs', 'FlipFlop()', { expr = true }) command('normal ilhs') - eq({'1'}, curbufmeths.get_lines(0, -1, 0)) + eq({ '1' }, api.nvim_buf_get_lines(0, 0, -1, 0)) command('normal! ggVGd') command('normal ilhs') - eq({'0'}, curbufmeths.get_lines(0, -1, 0)) + eq({ '0' }, api.nvim_buf_get_lines(0, 0, -1, 0)) end) it('can set mappings that do trigger other mappings', function() - meths.set_keymap('i', 'mhs', 'rhs', {}) - meths.set_keymap('i', 'lhs', 'mhs', {}) + api.nvim_set_keymap('i', 'mhs', 'rhs', {}) + api.nvim_set_keymap('i', 'lhs', 'mhs', {}) command('normal imhs') - eq({'rhs'}, curbufmeths.get_lines(0, -1, 0)) + eq({ 'rhs' }, api.nvim_buf_get_lines(0, 0, -1, 0)) command('normal! ggVGd') command('normal ilhs') - eq({'rhs'}, curbufmeths.get_lines(0, -1, 0)) + eq({ 'rhs' }, api.nvim_buf_get_lines(0, 0, -1, 0)) end) it("can set noremap mappings that don't trigger other mappings", function() - meths.set_keymap('i', 'mhs', 'rhs', {}) - meths.set_keymap('i', 'lhs', 'mhs', {noremap = true}) + api.nvim_set_keymap('i', 'mhs', 'rhs', {}) + api.nvim_set_keymap('i', 'lhs', 'mhs', { noremap = true }) command('normal imhs') - eq({'rhs'}, curbufmeths.get_lines(0, -1, 0)) + eq({ 'rhs' }, api.nvim_buf_get_lines(0, 0, -1, 0)) command('normal! ggVGd') - command('normal ilhs') -- shouldn't trigger mhs-to-rhs mapping - eq({'mhs'}, curbufmeths.get_lines(0, -1, 0)) + command('normal ilhs') -- shouldn't trigger mhs-to-rhs mapping + eq({ 'mhs' }, api.nvim_buf_get_lines(0, 0, -1, 0)) end) - it("can set nowait mappings that fire without waiting", function() - meths.set_keymap('i', '123456', 'longer', {}) - meths.set_keymap('i', '123', 'shorter', {nowait = true}) + it('can set nowait mappings that fire without waiting', function() + api.nvim_set_keymap('i', '123456', 'longer', {}) + api.nvim_set_keymap('i', '123', 'shorter', { nowait = true }) -- feed keys one at a time; if all keys arrive atomically, the longer -- mapping will trigger @@ -775,84 +866,99 @@ describe('nvim_set_keymap, nvim_del_keymap', function() feed(c) sleep(5) end - eq({'shorter456'}, curbufmeths.get_lines(0, -1, 0)) + eq({ 'shorter456' }, api.nvim_buf_get_lines(0, 0, -1, 0)) end) -- Perform exhaustive tests of basic functionality - local mapmodes = {'n', 'v', 'x', 's', 'o', '!', 'i', 'l', 'c', 't', '', 'ia', 'ca', '!a'} + local mapmodes = { 'n', 'v', 'x', 's', 'o', '!', 'i', 'l', 'c', 't', '', 'ia', 'ca', '!a' } for _, mapmode in ipairs(mapmodes) do - it('can set/unset normal mappings in mapmode '..mapmode, function() - meths.set_keymap(mapmode, 'lhs', 'rhs', {}) - eq(generate_mapargs(mapmode, 'lhs', 'rhs'), - get_mapargs(mapmode, 'lhs')) + it('can set/unset normal mappings in mapmode ' .. mapmode, function() + api.nvim_set_keymap(mapmode, 'lhs', 'rhs', {}) + eq(generate_mapargs(mapmode, 'lhs', 'rhs'), get_mapargs(mapmode, 'lhs')) -- some mapmodes (like 'o') will prevent other mapmodes (like '!') from -- taking effect, so unmap after each mapping - meths.del_keymap(mapmode, 'lhs') + api.nvim_del_keymap(mapmode, 'lhs') eq({}, get_mapargs(mapmode, 'lhs')) end) end for _, mapmode in ipairs(mapmodes) do - it('can set/unset noremap mappings using mapmode '..mapmode, function() - meths.set_keymap(mapmode, 'lhs', 'rhs', {noremap = true}) - eq(generate_mapargs(mapmode, 'lhs', 'rhs', {noremap = true}), - get_mapargs(mapmode, 'lhs')) + it('can set/unset noremap mappings using mapmode ' .. mapmode, function() + api.nvim_set_keymap(mapmode, 'lhs', 'rhs', { noremap = true }) + eq(generate_mapargs(mapmode, 'lhs', 'rhs', { noremap = true }), get_mapargs(mapmode, 'lhs')) - meths.del_keymap(mapmode, 'lhs') + api.nvim_del_keymap(mapmode, 'lhs') eq({}, get_mapargs(mapmode, 'lhs')) end) end -- Test map-arguments, using optnames from above -- remove some map arguments that are harder to test, or were already tested - optnames = {'nowait', 'silent', 'expr', 'noremap'} + optnames = { 'nowait', 'silent', 'expr', 'noremap' } for _, mapmode in ipairs(mapmodes) do -- Test with single mappings for _, maparg in ipairs(optnames) do - it('can set/unset '..mapmode..'-mappings with maparg: '..maparg, - function() - meths.set_keymap(mapmode, 'lhs', 'rhs', {[maparg] = true}) - eq(generate_mapargs(mapmode, 'lhs', 'rhs', {[maparg] = true}), - get_mapargs(mapmode, 'lhs')) - meths.del_keymap(mapmode, 'lhs') - eq({}, get_mapargs(mapmode, 'lhs')) - end) - it ('can set/unset '..mapmode..'-mode mappings with maparg '.. - maparg..', whose value is false', function() - meths.set_keymap(mapmode, 'lhs', 'rhs', {[maparg] = false}) - eq(generate_mapargs(mapmode, 'lhs', 'rhs'), - get_mapargs(mapmode, 'lhs')) - meths.del_keymap(mapmode, 'lhs') + it('can set/unset ' .. mapmode .. '-mappings with maparg: ' .. maparg, function() + api.nvim_set_keymap(mapmode, 'lhs', 'rhs', { [maparg] = true }) + eq( + generate_mapargs(mapmode, 'lhs', 'rhs', { [maparg] = true }), + get_mapargs(mapmode, 'lhs') + ) + api.nvim_del_keymap(mapmode, 'lhs') eq({}, get_mapargs(mapmode, 'lhs')) end) + it( + 'can set/unset ' + .. mapmode + .. '-mode mappings with maparg ' + .. maparg + .. ', whose value is false', + function() + api.nvim_set_keymap(mapmode, 'lhs', 'rhs', { [maparg] = false }) + eq(generate_mapargs(mapmode, 'lhs', 'rhs'), get_mapargs(mapmode, 'lhs')) + api.nvim_del_keymap(mapmode, 'lhs') + eq({}, get_mapargs(mapmode, 'lhs')) + end + ) end -- Test with triplets of mappings, one of which is false for i = 1, (#optnames - 2) do local opt1, opt2, opt3 = optnames[i], optnames[i + 1], optnames[i + 2] - it('can set/unset '..mapmode..'-mode mappings with mapargs '.. - opt1..', '..opt2..', '..opt3, function() - local opts = {[opt1] = true, [opt2] = false, [opt3] = true} - meths.set_keymap(mapmode, 'lhs', 'rhs', opts) - eq(generate_mapargs(mapmode, 'lhs', 'rhs', opts), - get_mapargs(mapmode, 'lhs')) - meths.del_keymap(mapmode, 'lhs') - eq({}, get_mapargs(mapmode, 'lhs')) - end) + it( + 'can set/unset ' + .. mapmode + .. '-mode mappings with mapargs ' + .. opt1 + .. ', ' + .. opt2 + .. ', ' + .. opt3, + function() + local opts = { [opt1] = true, [opt2] = false, [opt3] = true } + api.nvim_set_keymap(mapmode, 'lhs', 'rhs', opts) + eq(generate_mapargs(mapmode, 'lhs', 'rhs', opts), get_mapargs(mapmode, 'lhs')) + api.nvim_del_keymap(mapmode, 'lhs') + eq({}, get_mapargs(mapmode, 'lhs')) + end + ) end end it('can make lua mappings', function() - eq(0, exec_lua [[ + eq( + 0, + exec_lua [[ GlobalCount = 0 vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) return GlobalCount - ]]) + ]] + ) feed('asdf\n') - eq(1, exec_lua[[return GlobalCount]]) + eq(1, exec_lua [[return GlobalCount]]) end) it(':map command shows lua mapping correctly', function() @@ -861,8 +967,8 @@ describe('nvim_set_keymap, nvim_del_keymap', function() ]] assert.truthy( string.match( - exec_lua[[return vim.api.nvim_exec2(':nmap asdf', { output = true }).output]], - "^\nn asdf <Lua %d+>" + exec_lua [[return vim.api.nvim_exec2(':nmap asdf', { output = true }).output]], + '^\nn asdf <Lua %d+>' ) ) end) @@ -871,29 +977,34 @@ describe('nvim_set_keymap, nvim_del_keymap', function() exec_lua [[ vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() print('jkl;') end }) ]] - assert.truthy(string.match(funcs.mapcheck('asdf', 'n'), - "^<Lua %d+>")) + assert.truthy(string.match(fn.mapcheck('asdf', 'n'), '^<Lua %d+>')) end) it('maparg() returns lua mapping correctly', function() - eq(0, exec_lua([[ + eq( + 0, + exec_lua([[ GlobalCount = 0 vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) return GlobalCount - ]])) + ]]) + ) - assert.truthy(string.match(funcs.maparg('asdf', 'n'), "^<Lua %d+>")) + assert.truthy(string.match(fn.maparg('asdf', 'n'), '^<Lua %d+>')) - local mapargs = funcs.maparg('asdf', 'n', false, true) + local mapargs = fn.maparg('asdf', 'n', false, true) mapargs.callback = nil mapargs.lhsraw = nil mapargs.lhsrawalt = nil - eq(generate_mapargs('n', 'asdf', nil, {sid=sid_lua}), mapargs) + eq(generate_mapargs('n', 'asdf', nil, { sid = sid_lua }), mapargs) - eq(1, exec_lua([[ + eq( + 1, + exec_lua([[ vim.fn.maparg('asdf', 'n', false, true).callback() return GlobalCount - ]])) + ]]) + ) exec([[ call maparg('asdf', 'n', v:false, v:true).callback() @@ -908,7 +1019,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function() feed('aa') - eq({'π<M-π>foo<'}, meths.buf_get_lines(0, 0, -1, false)) + eq({ 'π<M-π>foo<' }, api.nvim_buf_get_lines(0, 0, -1, false)) end) it('can make lua expr mappings without replacing keycodes', function() @@ -918,7 +1029,7 @@ describe('nvim_set_keymap, nvim_del_keymap', function() feed('iaa<esc>') - eq({'<space>'}, meths.buf_get_lines(0, 0, -1, false)) + eq({ '<space>' }, api.nvim_buf_get_lines(0, 0, -1, false)) end) it('lua expr mapping returning nil is equivalent to returning an empty string', function() @@ -928,41 +1039,50 @@ describe('nvim_set_keymap, nvim_del_keymap', function() feed('iaa<esc>') - eq({''}, meths.buf_get_lines(0, 0, -1, false)) + eq({ '' }, api.nvim_buf_get_lines(0, 0, -1, false)) end) it('does not reset pum in lua mapping', function() - eq(0, exec_lua [[ + eq( + 0, + exec_lua [[ VisibleCount = 0 vim.api.nvim_set_keymap('i', '<F2>', '', {callback = function() VisibleCount = VisibleCount + vim.fn.pumvisible() end}) return VisibleCount - ]]) + ]] + ) feed('i<C-X><C-V><F2><F2><esc>') - eq(2, exec_lua[[return VisibleCount]]) + eq(2, exec_lua [[return VisibleCount]]) end) it('redo of lua mappings in op-pending mode work', function() - eq(0, exec_lua [[ + eq( + 0, + exec_lua [[ OpCount = 0 vim.api.nvim_set_keymap('o', '<F2>', '', {callback = function() OpCount = OpCount + 1 end}) return OpCount - ]]) + ]] + ) feed('d<F2>') - eq(1, exec_lua[[return OpCount]]) + eq(1, exec_lua [[return OpCount]]) feed('.') - eq(2, exec_lua[[return OpCount]]) + eq(2, exec_lua [[return OpCount]]) end) it('can overwrite lua mappings', function() - eq(0, exec_lua [[ + eq( + 0, + exec_lua [[ GlobalCount = 0 vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) return GlobalCount - ]]) + ]] + ) feed('asdf\n') - eq(1, exec_lua[[return GlobalCount]]) + eq(1, exec_lua [[return GlobalCount]]) exec_lua [[ vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount - 1 end }) @@ -970,19 +1090,22 @@ describe('nvim_set_keymap, nvim_del_keymap', function() feed('asdf\n') - eq(0, exec_lua[[return GlobalCount]]) + eq(0, exec_lua [[return GlobalCount]]) end) it('can unmap lua mappings', function() - eq(0, exec_lua [[ + eq( + 0, + exec_lua [[ GlobalCount = 0 vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) return GlobalCount - ]]) + ]] + ) feed('asdf\n') - eq(1, exec_lua[[return GlobalCount]]) + eq(1, exec_lua [[return GlobalCount]]) exec_lua [[ vim.api.nvim_del_keymap('n', 'asdf' ) @@ -990,20 +1113,23 @@ describe('nvim_set_keymap, nvim_del_keymap', function() feed('asdf\n') - eq(1, exec_lua[[return GlobalCount]]) + eq(1, exec_lua [[return GlobalCount]]) eq('\nNo mapping found', helpers.exec_capture('nmap asdf')) end) it('no double-free when unmapping simplifiable lua mappings', function() - eq(0, exec_lua [[ + eq( + 0, + exec_lua [[ GlobalCount = 0 vim.api.nvim_set_keymap('n', '<C-I>', '', {callback = function() GlobalCount = GlobalCount + 1 end }) return GlobalCount - ]]) + ]] + ) feed('<C-I>\n') - eq(1, exec_lua[[return GlobalCount]]) + eq(1, exec_lua [[return GlobalCount]]) exec_lua [[ vim.api.nvim_del_keymap('n', '<C-I>') @@ -1011,15 +1137,14 @@ describe('nvim_set_keymap, nvim_del_keymap', function() feed('<C-I>\n') - eq(1, exec_lua[[return GlobalCount]]) + eq(1, exec_lua [[return GlobalCount]]) eq('\nNo mapping found', helpers.exec_capture('nmap <C-I>')) end) it('can set descriptions on mappings', function() - meths.set_keymap('n', 'lhs', 'rhs', {desc="map description"}) - eq(generate_mapargs('n', 'lhs', 'rhs', {desc="map description"}), get_mapargs('n', 'lhs')) - eq("\nn lhs rhs\n map description", - helpers.exec_capture("nmap lhs")) + api.nvim_set_keymap('n', 'lhs', 'rhs', { desc = 'map description' }) + eq(generate_mapargs('n', 'lhs', 'rhs', { desc = 'map description' }), get_mapargs('n', 'lhs')) + eq('\nn lhs rhs\n map description', helpers.exec_capture('nmap lhs')) end) it('can define !-mode abbreviations with lua callbacks', function() @@ -1032,10 +1157,10 @@ describe('nvim_set_keymap, nvim_del_keymap', function() ]] feed 'iThe foo and the bar and the foo again<esc>' - eq('The 1 and the bar and the 2 again', meths.get_current_line()) + eq('The 1 and the bar and the 2 again', api.nvim_get_current_line()) feed ':let x = "The foo is the one"<cr>' - eq('The 3 is the one', meths.eval'x') + eq('The 3 is the one', api.nvim_eval 'x') end) it('can define insert mode abbreviations with lua callbacks', function() @@ -1048,10 +1173,10 @@ describe('nvim_set_keymap, nvim_del_keymap', function() ]] feed 'iThe foo and the bar and the foo again<esc>' - eq('The 1 and the bar and the 2 again', meths.get_current_line()) + eq('The 1 and the bar and the 2 again', api.nvim_get_current_line()) feed ':let x = "The foo is the one"<cr>' - eq('The foo is the one', meths.eval'x') + eq('The foo is the one', api.nvim_eval 'x') end) it('can define cmdline mode abbreviations with lua callbacks', function() @@ -1064,10 +1189,10 @@ describe('nvim_set_keymap, nvim_del_keymap', function() ]] feed 'iThe foo and the bar and the foo again<esc>' - eq('The foo and the bar and the foo again', meths.get_current_line()) + eq('The foo and the bar and the foo again', api.nvim_get_current_line()) feed ':let x = "The foo is the one"<cr>' - eq('The 1 is the one', meths.eval'x') + eq('The 1 is the one', api.nvim_eval 'x') end) end) @@ -1081,7 +1206,7 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function() -- switch to the given buffer, abandoning any changes in the current buffer local function switch_to_buf(bufnr) - command(bufnr..'buffer!') + command(bufnr .. 'buffer!') end -- `set hidden`, then create two buffers and return their bufnr's @@ -1090,10 +1215,10 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function() local function make_two_buffers(start_from_first) command('set hidden') - local first_buf = meths.call_function('bufnr', {'%'}) + local first_buf = api.nvim_call_function('bufnr', { '%' }) command('new') - local second_buf = meths.call_function('bufnr', {'%'}) - neq(second_buf, first_buf) -- sanity check + local second_buf = api.nvim_call_function('bufnr', { '%' }) + neq(second_buf, first_buf) -- sanity check if start_from_first then switch_to_buf(first_buf) @@ -1103,80 +1228,84 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function() end it('rejects negative bufnr values', function() - eq('Wrong type for argument 1 when calling nvim_buf_set_keymap, expecting Buffer', - pcall_err(bufmeths.set_keymap, -1, '', 'lhs', 'rhs', {})) + eq( + 'Wrong type for argument 1 when calling nvim_buf_set_keymap, expecting Buffer', + pcall_err(api.nvim_buf_set_keymap, -1, '', 'lhs', 'rhs', {}) + ) end) it('can set mappings active in the current buffer but not others', function() local first, second = make_two_buffers(true) - bufmeths.set_keymap(0, '', 'lhs', 'irhs<Esc>', {}) + api.nvim_buf_set_keymap(0, '', 'lhs', 'irhs<Esc>', {}) command('normal lhs') - eq({'rhs'}, bufmeths.get_lines(0, 0, 1, 1)) + eq({ 'rhs' }, api.nvim_buf_get_lines(0, 0, 1, 1)) -- mapping should have no effect in new buffer switch_to_buf(second) command('normal lhs') - eq({''}, bufmeths.get_lines(0, 0, 1, 1)) + eq({ '' }, api.nvim_buf_get_lines(0, 0, 1, 1)) -- mapping should remain active in old buffer switch_to_buf(first) command('normal ^lhs') - eq({'rhsrhs'}, bufmeths.get_lines(0, 0, 1, 1)) + eq({ 'rhsrhs' }, api.nvim_buf_get_lines(0, 0, 1, 1)) end) it('can set local mappings in buffer other than current', function() local first = make_two_buffers(false) - bufmeths.set_keymap(first, '', 'lhs', 'irhs<Esc>', {}) + api.nvim_buf_set_keymap(first, '', 'lhs', 'irhs<Esc>', {}) -- shouldn't do anything command('normal lhs') - eq({''}, bufmeths.get_lines(0, 0, 1, 1)) + eq({ '' }, api.nvim_buf_get_lines(0, 0, 1, 1)) -- should take effect switch_to_buf(first) command('normal lhs') - eq({'rhs'}, bufmeths.get_lines(0, 0, 1, 1)) + eq({ 'rhs' }, api.nvim_buf_get_lines(0, 0, 1, 1)) end) it('can disable mappings made in another buffer, inside that buffer', function() local first = make_two_buffers(false) - bufmeths.set_keymap(first, '', 'lhs', 'irhs<Esc>', {}) - bufmeths.del_keymap(first, '', 'lhs') + api.nvim_buf_set_keymap(first, '', 'lhs', 'irhs<Esc>', {}) + api.nvim_buf_del_keymap(first, '', 'lhs') switch_to_buf(first) -- shouldn't do anything command('normal lhs') - eq({''}, bufmeths.get_lines(0, 0, 1, 1)) + eq({ '' }, api.nvim_buf_get_lines(0, 0, 1, 1)) end) it("can't disable mappings given wrong buffer handle", function() local first, second = make_two_buffers(false) - bufmeths.set_keymap(first, '', 'lhs', 'irhs<Esc>', {}) - eq('E31: No such mapping', - pcall_err(bufmeths.del_keymap, second, '', 'lhs')) + api.nvim_buf_set_keymap(first, '', 'lhs', 'irhs<Esc>', {}) + eq('E31: No such mapping', pcall_err(api.nvim_buf_del_keymap, second, '', 'lhs')) -- should still work switch_to_buf(first) command('normal lhs') - eq({'rhs'}, bufmeths.get_lines(0, 0, 1, 1)) + eq({ 'rhs' }, api.nvim_buf_get_lines(0, 0, 1, 1)) end) - it("does not crash when setting mapping in a non-existing buffer #13541", function() - pcall_err(bufmeths.set_keymap, 100, '', 'lsh', 'irhs<Esc>', {}) + it('does not crash when setting mapping in a non-existing buffer #13541', function() + pcall_err(api.nvim_buf_set_keymap, 100, '', 'lsh', 'irhs<Esc>', {}) helpers.assert_alive() end) it('can make lua mappings', function() - eq(0, exec_lua [[ + eq( + 0, + exec_lua [[ GlobalCount = 0 vim.api.nvim_buf_set_keymap(0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) return GlobalCount - ]]) + ]] + ) feed('asdf\n') - eq(1, exec_lua[[return GlobalCount]]) + eq(1, exec_lua [[return GlobalCount]]) end) it('can make lua expr mappings replacing keycodes', function() @@ -1186,7 +1315,7 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function() feed('aa') - eq({'π<M-π>foo<'}, meths.buf_get_lines(0, 0, -1, false)) + eq({ 'π<M-π>foo<' }, api.nvim_buf_get_lines(0, 0, -1, false)) end) it('can make lua expr mappings without replacing keycodes', function() @@ -1196,20 +1325,22 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function() feed('iaa<esc>') - eq({'<space>'}, meths.buf_get_lines(0, 0, -1, false)) + eq({ '<space>' }, api.nvim_buf_get_lines(0, 0, -1, false)) end) - it('can overwrite lua mappings', function() - eq(0, exec_lua [[ + eq( + 0, + exec_lua [[ GlobalCount = 0 vim.api.nvim_buf_set_keymap(0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) return GlobalCount - ]]) + ]] + ) feed('asdf\n') - eq(1, exec_lua[[return GlobalCount]]) + eq(1, exec_lua [[return GlobalCount]]) exec_lua [[ vim.api.nvim_buf_set_keymap(0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount - 1 end }) @@ -1217,19 +1348,22 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function() feed('asdf\n') - eq(0, exec_lua[[return GlobalCount]]) + eq(0, exec_lua [[return GlobalCount]]) end) it('can unmap lua mappings', function() - eq(0, exec_lua [[ + eq( + 0, + exec_lua [[ GlobalCount = 0 vim.api.nvim_buf_set_keymap(0, 'n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) return GlobalCount - ]]) + ]] + ) feed('asdf\n') - eq(1, exec_lua[[return GlobalCount]]) + eq(1, exec_lua [[return GlobalCount]]) exec_lua [[ vim.api.nvim_buf_del_keymap(0, 'n', 'asdf' ) @@ -1237,20 +1371,23 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function() feed('asdf\n') - eq(1, exec_lua[[return GlobalCount]]) + eq(1, exec_lua [[return GlobalCount]]) eq('\nNo mapping found', helpers.exec_capture('nmap asdf')) end) it('no double-free when unmapping simplifiable lua mappings', function() - eq(0, exec_lua [[ + eq( + 0, + exec_lua [[ GlobalCount = 0 vim.api.nvim_buf_set_keymap(0, 'n', '<C-I>', '', {callback = function() GlobalCount = GlobalCount + 1 end }) return GlobalCount - ]]) + ]] + ) feed('<C-I>\n') - eq(1, exec_lua[[return GlobalCount]]) + eq(1, exec_lua [[return GlobalCount]]) exec_lua [[ vim.api.nvim_buf_del_keymap(0, 'n', '<C-I>') @@ -1258,7 +1395,7 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function() feed('<C-I>\n') - eq(1, exec_lua[[return GlobalCount]]) + eq(1, exec_lua [[return GlobalCount]]) eq('\nNo mapping found', helpers.exec_capture('nmap <C-I>')) end) end) diff --git a/test/functional/api/menu_spec.lua b/test/functional/api/menu_spec.lua index 34a92477f3..44b9039393 100644 --- a/test/functional/api/menu_spec.lua +++ b/test/functional/api/menu_spec.lua @@ -5,8 +5,7 @@ local clear = helpers.clear local command = helpers.command local feed = helpers.feed -describe("update_menu notification", function() - +describe('update_menu notification', function() local screen before_each(function() @@ -16,23 +15,26 @@ describe("update_menu notification", function() end) local function expect_sent(expected) - screen:expect{condition=function() - if screen.update_menu ~= expected then - if expected then - error('update_menu was expected but not sent') - else - error('update_menu was sent unexpectedly') + screen:expect { + condition = function() + if screen.update_menu ~= expected then + if expected then + error('update_menu was expected but not sent') + else + error('update_menu was sent unexpectedly') + end end - end - end, unchanged=(not expected)} + end, + unchanged = not expected, + } end - it("should be sent when adding a menu", function() + it('should be sent when adding a menu', function() command('menu Test.Test :') expect_sent(true) end) - it("should be sent when deleting a menu", function() + it('should be sent when deleting a menu', function() command('menu Test.Test :') screen.update_menu = false @@ -40,9 +42,8 @@ describe("update_menu notification", function() expect_sent(true) end) - it("should not be sent unnecessarily", function() + it('should not be sent unnecessarily', function() feed('i12345<ESC>:redraw<CR>') expect_sent(false) end) - end) diff --git a/test/functional/api/proc_spec.lua b/test/functional/api/proc_spec.lua index 20edea3feb..50c441792c 100644 --- a/test/functional/api/proc_spec.lua +++ b/test/functional/api/proc_spec.lua @@ -2,12 +2,12 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local eq = helpers.eq -local funcs = helpers.funcs +local fn = helpers.fn local neq = helpers.neq local nvim_argv = helpers.nvim_argv local request = helpers.request local retry = helpers.retry -local NIL = helpers.NIL +local NIL = vim.NIL local is_os = helpers.is_os describe('API', function() @@ -15,44 +15,44 @@ describe('API', function() describe('nvim_get_proc_children', function() it('returns child process ids', function() - local this_pid = funcs.getpid() + local this_pid = fn.getpid() -- Might be non-zero already (left-over from some other test?), -- but this is not what is tested here. local initial_children = request('nvim_get_proc_children', this_pid) - local job1 = funcs.jobstart(nvim_argv) + local job1 = fn.jobstart(nvim_argv) retry(nil, nil, function() eq(#initial_children + 1, #request('nvim_get_proc_children', this_pid)) end) - local job2 = funcs.jobstart(nvim_argv) + local job2 = fn.jobstart(nvim_argv) retry(nil, nil, function() eq(#initial_children + 2, #request('nvim_get_proc_children', this_pid)) end) - funcs.jobstop(job1) + fn.jobstop(job1) retry(nil, nil, function() eq(#initial_children + 1, #request('nvim_get_proc_children', this_pid)) end) - funcs.jobstop(job2) + fn.jobstop(job2) retry(nil, nil, function() eq(#initial_children, #request('nvim_get_proc_children', this_pid)) end) end) it('validation', function() - local status, rv = pcall(request, "nvim_get_proc_children", -1) + local status, rv = pcall(request, 'nvim_get_proc_children', -1) eq(false, status) - eq("Invalid 'pid': -1", string.match(rv, "Invalid.*")) + eq("Invalid 'pid': -1", string.match(rv, 'Invalid.*')) - status, rv = pcall(request, "nvim_get_proc_children", 0) + status, rv = pcall(request, 'nvim_get_proc_children', 0) eq(false, status) - eq("Invalid 'pid': 0", string.match(rv, "Invalid.*")) + eq("Invalid 'pid': 0", string.match(rv, 'Invalid.*')) -- Assume PID 99999 does not exist. - status, rv = pcall(request, "nvim_get_proc_children", 99999) + status, rv = pcall(request, 'nvim_get_proc_children', 99999) eq(true, status) eq({}, rv) end) @@ -60,7 +60,7 @@ describe('API', function() describe('nvim_get_proc', function() it('returns process info', function() - local pid = funcs.getpid() + local pid = fn.getpid() local pinfo = request('nvim_get_proc', pid) eq((is_os('win') and 'nvim.exe' or 'nvim'), pinfo.name) eq(pid, pinfo.pid) @@ -69,16 +69,16 @@ describe('API', function() end) it('validation', function() - local status, rv = pcall(request, "nvim_get_proc", -1) + local status, rv = pcall(request, 'nvim_get_proc', -1) eq(false, status) - eq("Invalid 'pid': -1", string.match(rv, "Invalid.*")) + eq("Invalid 'pid': -1", string.match(rv, 'Invalid.*')) - status, rv = pcall(request, "nvim_get_proc", 0) + status, rv = pcall(request, 'nvim_get_proc', 0) eq(false, status) - eq("Invalid 'pid': 0", string.match(rv, "Invalid.*")) + eq("Invalid 'pid': 0", string.match(rv, 'Invalid.*')) -- Assume PID 99999 does not exist. - status, rv = pcall(request, "nvim_get_proc", 99999) + status, rv = pcall(request, 'nvim_get_proc', 99999) eq(true, status) eq(NIL, rv) end) diff --git a/test/functional/api/rpc_fixture.lua b/test/functional/api/rpc_fixture.lua index c860a6da59..050d439a1b 100644 --- a/test/functional/api/rpc_fixture.lua +++ b/test/functional/api/rpc_fixture.lua @@ -4,8 +4,8 @@ package.path = arg[1] package.cpath = arg[2] -local StdioStream = require'test.client.uv_stream'.StdioStream -local Session = require'test.client.session' +local StdioStream = require 'test.client.uv_stream'.StdioStream +local Session = require 'test.client.session' local stdio_stream = StdioStream.open() local session = Session.new(stdio_stream) @@ -15,8 +15,8 @@ local function on_request(method, args) return 'ok' elseif method == 'write_stderr' then io.stderr:write(args[1]) - return "done!" - elseif method == "exit" then + return 'done!' + elseif method == 'exit' then session:stop() return vim.NIL end @@ -24,7 +24,7 @@ end local function on_notification(event, args) if event == 'ping' and #args == 0 then - session:notify("nvim_eval", "rpcnotify(g:channel, 'pong')") + session:notify('nvim_eval', "rpcnotify(g:channel, 'pong')") end end diff --git a/test/functional/api/server_notifications_spec.lua b/test/functional/api/server_notifications_spec.lua index bc43f6564d..d1608a951c 100644 --- a/test/functional/api/server_notifications_spec.lua +++ b/test/functional/api/server_notifications_spec.lua @@ -1,9 +1,8 @@ local helpers = require('test.functional.helpers')(after_each) local assert_log = helpers.assert_log -local eq, clear, eval, command, nvim, next_msg = - helpers.eq, helpers.clear, helpers.eval, helpers.command, helpers.nvim, - helpers.next_msg -local meths = helpers.meths +local eq, clear, eval, command, next_msg = + helpers.eq, helpers.clear, helpers.eval, helpers.command, helpers.next_msg +local api = helpers.api local exec_lua = helpers.exec_lua local retry = helpers.retry local assert_alive = helpers.assert_alive @@ -15,7 +14,7 @@ describe('notify', function() before_each(function() clear() - channel = nvim('get_api_info')[1] + channel = api.nvim_get_chan_info(0).id end) after_each(function() @@ -24,34 +23,34 @@ describe('notify', function() describe('passing a valid channel id', function() it('sends the notification/args to the corresponding channel', function() - eval('rpcnotify('..channel..', "test-event", 1, 2, 3)') - eq({'notification', 'test-event', {1, 2, 3}}, next_msg()) - command('au FileType lua call rpcnotify('..channel..', "lua!")') + eval('rpcnotify(' .. channel .. ', "test-event", 1, 2, 3)') + eq({ 'notification', 'test-event', { 1, 2, 3 } }, next_msg()) + command('au FileType lua call rpcnotify(' .. channel .. ', "lua!")') command('set filetype=lua') - eq({'notification', 'lua!', {}}, next_msg()) + eq({ 'notification', 'lua!', {} }, next_msg()) end) end) describe('passing 0 as the channel id', function() it('sends the notification/args to all subscribed channels', function() - nvim('subscribe', 'event2') + api.nvim_subscribe('event2') eval('rpcnotify(0, "event1", 1, 2, 3)') eval('rpcnotify(0, "event2", 4, 5, 6)') eval('rpcnotify(0, "event2", 7, 8, 9)') - eq({'notification', 'event2', {4, 5, 6}}, next_msg()) - eq({'notification', 'event2', {7, 8, 9}}, next_msg()) - nvim('unsubscribe', 'event2') - nvim('subscribe', 'event1') + eq({ 'notification', 'event2', { 4, 5, 6 } }, next_msg()) + eq({ 'notification', 'event2', { 7, 8, 9 } }, next_msg()) + api.nvim_unsubscribe('event2') + api.nvim_subscribe('event1') eval('rpcnotify(0, "event2", 10, 11, 12)') eval('rpcnotify(0, "event1", 13, 14, 15)') - eq({'notification', 'event1', {13, 14, 15}}, next_msg()) + eq({ 'notification', 'event1', { 13, 14, 15 } }, next_msg()) end) it('does not crash for deeply nested variable', function() - meths.set_var('l', {}) + api.nvim_set_var('l', {}) local nest_level = 1000 - meths.command(('call map(range(%u), "extend(g:, {\'l\': [g:l]})")'):format(nest_level - 1)) - eval('rpcnotify('..channel..', "event", g:l)') + command(('call map(range(%u), "extend(g:, {\'l\': [g:l]})")'):format(nest_level - 1)) + eval('rpcnotify(' .. channel .. ', "event", g:l)') local msg = next_msg() eq('notification', msg[1]) eq('event', msg[2]) @@ -77,27 +76,37 @@ describe('notify', function() end) it('unsubscribe non-existing event #8745', function() - clear{env={ - NVIM_LOG_FILE=testlog, - }} - nvim('subscribe', 'event1') - nvim('unsubscribe', 'doesnotexist') + clear { env = { + NVIM_LOG_FILE = testlog, + } } + api.nvim_subscribe('event1') + api.nvim_unsubscribe('doesnotexist') assert_log("tried to unsubscribe unknown event 'doesnotexist'", testlog, 10) - nvim('unsubscribe', 'event1') + api.nvim_unsubscribe('event1') assert_alive() end) it('cancels stale events on channel close', function() local catchan = eval("jobstart(['cat'], {'rpc': v:true})") local catpath = eval('exepath("cat")') - eq({id=catchan, argv={catpath}, stream='job', mode='rpc', client = {}}, exec_lua ([[ + eq( + { id = catchan, argv = { catpath }, stream = 'job', mode = 'rpc', client = {} }, + exec_lua( + [[ vim.rpcnotify(..., "nvim_call_function", 'chanclose', {..., 'rpc'}) vim.rpcnotify(..., "nvim_subscribe", "daily_rant") return vim.api.nvim_get_chan_info(...) - ]], catchan)) + ]], + catchan + ) + ) assert_alive() - eq({false, 'Invalid channel: '..catchan}, - exec_lua ([[ return {pcall(vim.rpcrequest, ..., 'nvim_eval', '1+1')}]], catchan)) - retry(nil, 3000, function() eq({}, meths.get_chan_info(catchan)) end) -- cat be dead :( + eq( + { false, 'Invalid channel: ' .. catchan }, + exec_lua([[ return {pcall(vim.rpcrequest, ..., 'nvim_eval', '1+1')}]], catchan) + ) + retry(nil, 3000, function() + eq({}, api.nvim_get_chan_info(catchan)) + end) -- cat be dead :( end) end) diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua index 1ad4ad3a02..298dbac217 100644 --- a/test/functional/api/server_requests_spec.lua +++ b/test/functional/api/server_requests_spec.lua @@ -2,12 +2,12 @@ -- `rpcrequest` calls we need the client event loop to be running. local helpers = require('test.functional.helpers')(after_each) -local clear, nvim, eval = helpers.clear, helpers.nvim, helpers.eval +local clear, eval = helpers.clear, helpers.eval local eq, neq, run, stop = helpers.eq, helpers.neq, helpers.run, helpers.stop -local nvim_prog, command, funcs = helpers.nvim_prog, helpers.command, helpers.funcs +local nvim_prog, command, fn = helpers.nvim_prog, helpers.command, helpers.fn local source, next_msg = helpers.source, helpers.next_msg local ok = helpers.ok -local meths = helpers.meths +local api = helpers.api local spawn, merge_args = helpers.spawn, helpers.merge_args local set_session = helpers.set_session local pcall_err = helpers.pcall_err @@ -18,18 +18,18 @@ describe('server -> client', function() before_each(function() clear() - cid = nvim('get_api_info')[1] + cid = api.nvim_get_chan_info(0).id end) it('handles unexpected closed stream while preparing RPC response', function() source([[ let g:_nvim_args = [v:progpath, '--embed', '--headless', '-n', '-u', 'NONE', '-i', 'NONE', ] let ch1 = jobstart(g:_nvim_args, {'rpc': v:true}) - let child1_ch = rpcrequest(ch1, "nvim_get_api_info")[0] + let child1_ch = rpcrequest(ch1, "nvim_get_chan_info", 0).id call rpcnotify(ch1, 'nvim_eval', 'rpcrequest('.child1_ch.', "nvim_get_api_info")') let ch2 = jobstart(g:_nvim_args, {'rpc': v:true}) - let child2_ch = rpcrequest(ch2, "nvim_get_api_info")[0] + let child2_ch = rpcrequest(ch2, "nvim_get_chan_info", 0).id call rpcnotify(ch2, 'nvim_eval', 'rpcrequest('.child2_ch.', "nvim_get_api_info")') call jobstop(ch1) @@ -40,14 +40,14 @@ describe('server -> client', function() describe('simple call', function() it('works', function() local function on_setup() - eq({4, 5, 6}, eval('rpcrequest('..cid..', "scall", 1, 2, 3)')) + eq({ 4, 5, 6 }, eval('rpcrequest(' .. cid .. ', "scall", 1, 2, 3)')) stop() end local function on_request(method, args) eq('scall', method) - eq({1, 2, 3}, args) - nvim('command', 'let g:result = [4, 5, 6]') + eq({ 1, 2, 3 }, args) + command('let g:result = [4, 5, 6]') return eval('g:result') end run(on_request, nil, on_setup) @@ -61,14 +61,14 @@ describe('server -> client', function() -- elements following the empty string. it('works', function() local function on_setup() - eq({1, 2, '', 3, 'asdf'}, eval('rpcrequest('..cid..', "nstring")')) + eq({ 1, 2, '', 3, 'asdf' }, eval('rpcrequest(' .. cid .. ', "nstring")')) stop() end local function on_request() -- No need to evaluate the args, we are only interested in -- a response that contains an array with an empty string. - return {1, 2, '', 3, 'asdf'} + return { 1, 2, '', 3, 'asdf' } end run(on_request, nil, on_setup) end) @@ -77,15 +77,15 @@ describe('server -> client', function() describe('recursive call', function() it('works', function() local function on_setup() - nvim('set_var', 'result1', 0) - nvim('set_var', 'result2', 0) - nvim('set_var', 'result3', 0) - nvim('set_var', 'result4', 0) - nvim('command', 'let g:result1 = rpcrequest('..cid..', "rcall", 2)') - eq(4, nvim('get_var', 'result1')) - eq(8, nvim('get_var', 'result2')) - eq(16, nvim('get_var', 'result3')) - eq(32, nvim('get_var', 'result4')) + api.nvim_set_var('result1', 0) + api.nvim_set_var('result2', 0) + api.nvim_set_var('result3', 0) + api.nvim_set_var('result4', 0) + command('let g:result1 = rpcrequest(' .. cid .. ', "rcall", 2)') + eq(4, api.nvim_get_var('result1')) + eq(8, api.nvim_get_var('result2')) + eq(16, api.nvim_get_var('result3')) + eq(32, api.nvim_get_var('result4')) stop() end @@ -95,13 +95,13 @@ describe('server -> client', function() if n <= 16 then local cmd if n == 4 then - cmd = 'let g:result2 = rpcrequest('..cid..', "rcall", '..n..')' + cmd = 'let g:result2 = rpcrequest(' .. cid .. ', "rcall", ' .. n .. ')' elseif n == 8 then - cmd = 'let g:result3 = rpcrequest('..cid..', "rcall", '..n..')' + cmd = 'let g:result3 = rpcrequest(' .. cid .. ', "rcall", ' .. n .. ')' elseif n == 16 then - cmd = 'let g:result4 = rpcrequest('..cid..', "rcall", '..n..')' + cmd = 'let g:result4 = rpcrequest(' .. cid .. ', "rcall", ' .. n .. ')' end - nvim('command', cmd) + command(cmd) end return n end @@ -113,18 +113,18 @@ describe('server -> client', function() it('does not delay notifications during pending request', function() local received = false local function on_setup() - eq("retval", funcs.rpcrequest(cid, "doit")) + eq('retval', fn.rpcrequest(cid, 'doit')) stop() end local function on_request(method) - if method == "doit" then - funcs.rpcnotify(cid, "headsup") - eq(true,received) - return "retval" + if method == 'doit' then + fn.rpcnotify(cid, 'headsup') + eq(true, received) + return 'retval' end end local function on_notification(method) - if method == "headsup" then + if method == 'headsup' then received = true end end @@ -148,28 +148,28 @@ describe('server -> client', function() -- of nvim's request stack). pending('will close connection if not properly synchronized', function() local function on_setup() - eq('notified!', eval('rpcrequest('..cid..', "notify")')) + eq('notified!', eval('rpcrequest(' .. cid .. ', "notify")')) end local function on_request(method) - if method == "notify" then - eq(1, eval('rpcnotify('..cid..', "notification")')) + if method == 'notify' then + eq(1, eval('rpcnotify(' .. cid .. ', "notification")')) return 'notified!' - elseif method == "nested" then + elseif method == 'nested' then -- do some busywork, so the first request will return -- before this one for _ = 1, 5 do assert_alive() end - eq(1, eval('rpcnotify('..cid..', "nested_done")')) + eq(1, eval('rpcnotify(' .. cid .. ', "nested_done")')) return 'done!' end end local function on_notification(method) - if method == "notification" then - eq('done!', eval('rpcrequest('..cid..', "nested")')) - elseif method == "nested_done" then + if method == 'notification' then + eq('done!', eval('rpcrequest(' .. cid .. ', "nested")')) + elseif method == 'nested_done' then ok(false, 'never sent', 'sent') end end @@ -182,49 +182,57 @@ describe('server -> client', function() describe('recursive (child) nvim client', function() before_each(function() - command("let vim = rpcstart('"..nvim_prog.."', ['-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--embed', '--headless'])") + command( + "let vim = rpcstart('" + .. nvim_prog + .. "', ['-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--embed', '--headless'])" + ) neq(0, eval('vim')) end) - after_each(function() command('call rpcstop(vim)') end) + after_each(function() + command('call rpcstop(vim)') + end) it('can send/receive notifications and make requests', function() - nvim('command', "call rpcnotify(vim, 'vim_set_current_line', 'SOME TEXT')") + command("call rpcnotify(vim, 'vim_set_current_line', 'SOME TEXT')") -- Wait for the notification to complete. - nvim('command', "call rpcrequest(vim, 'vim_eval', '0')") + command("call rpcrequest(vim, 'vim_eval', '0')") eq('SOME TEXT', eval("rpcrequest(vim, 'vim_get_current_line')")) end) it('can communicate buffers, tabpages, and windows', function() - eq({1}, eval("rpcrequest(vim, 'nvim_list_tabpages')")) + eq({ 1 }, eval("rpcrequest(vim, 'nvim_list_tabpages')")) -- Window IDs start at 1000 (LOWEST_WIN_ID in window.h) - eq({1000}, eval("rpcrequest(vim, 'nvim_list_wins')")) + eq({ 1000 }, eval("rpcrequest(vim, 'nvim_list_wins')")) local buf = eval("rpcrequest(vim, 'nvim_list_bufs')")[1] eq(1, buf) - eval("rpcnotify(vim, 'buffer_set_line', "..buf..", 0, 'SOME TEXT')") - nvim('command', "call rpcrequest(vim, 'vim_eval', '0')") -- wait + eval("rpcnotify(vim, 'buffer_set_line', " .. buf .. ", 0, 'SOME TEXT')") + command("call rpcrequest(vim, 'vim_eval', '0')") -- wait - eq('SOME TEXT', eval("rpcrequest(vim, 'buffer_get_line', "..buf..", 0)")) + eq('SOME TEXT', eval("rpcrequest(vim, 'buffer_get_line', " .. buf .. ', 0)')) -- Call get_lines(buf, range [0,0], strict_indexing) - eq({'SOME TEXT'}, eval("rpcrequest(vim, 'buffer_get_lines', "..buf..", 0, 1, 1)")) + eq({ 'SOME TEXT' }, eval("rpcrequest(vim, 'buffer_get_lines', " .. buf .. ', 0, 1, 1)')) end) it('returns an error if the request failed', function() - eq("Vim:Error invoking 'does-not-exist' on channel 3:\nInvalid method: does-not-exist", - pcall_err(eval, "rpcrequest(vim, 'does-not-exist')")) + eq( + "Vim:Error invoking 'does-not-exist' on channel 3:\nInvalid method: does-not-exist", + pcall_err(eval, "rpcrequest(vim, 'does-not-exist')") + ) end) end) describe('jobstart()', function() local jobid before_each(function() - local channel = nvim('get_api_info')[1] - nvim('set_var', 'channel', channel) + local channel = api.nvim_get_chan_info(0).id + api.nvim_set_var('channel', channel) source([[ function! s:OnEvent(id, data, event) call rpcnotify(g:channel, a:event, 0, a:data) @@ -236,64 +244,67 @@ describe('server -> client', function() \ 'rpc': v:true \ } ]]) - meths.set_var("args", { - nvim_prog, '-ll', + api.nvim_set_var('args', { + nvim_prog, + '-ll', 'test/functional/api/rpc_fixture.lua', package.path, package.cpath, }) - jobid = eval("jobstart(g:args, g:job_opts)") + jobid = eval('jobstart(g:args, g:job_opts)') neq(0, jobid) end) after_each(function() - pcall(funcs.jobstop, jobid) + pcall(fn.jobstop, jobid) end) - if helpers.skip(helpers.is_os('win')) then return end + if helpers.skip(helpers.is_os('win')) then + return + end it('rpc and text stderr can be combined', function() - local status, rv = pcall(funcs.rpcrequest, jobid, 'poll') + local status, rv = pcall(fn.rpcrequest, jobid, 'poll') if not status then error(string.format('missing nvim Lua module? (%s)', rv)) end eq('ok', rv) - funcs.rpcnotify(jobid, "ping") - eq({'notification', 'pong', {}}, next_msg()) - eq("done!",funcs.rpcrequest(jobid, "write_stderr", "fluff\n")) - eq({'notification', 'stderr', {0, {'fluff', ''}}}, next_msg()) - pcall(funcs.rpcrequest, jobid, "exit") - eq({'notification', 'stderr', {0, {''}}}, next_msg()) - eq({'notification', 'exit', {0, 0}}, next_msg()) + fn.rpcnotify(jobid, 'ping') + eq({ 'notification', 'pong', {} }, next_msg()) + eq('done!', fn.rpcrequest(jobid, 'write_stderr', 'fluff\n')) + eq({ 'notification', 'stderr', { 0, { 'fluff', '' } } }, next_msg()) + pcall(fn.rpcrequest, jobid, 'exit') + eq({ 'notification', 'stderr', { 0, { '' } } }, next_msg()) + eq({ 'notification', 'exit', { 0, 0 } }, next_msg()) end) end) describe('connecting to another (peer) nvim', function() - local nvim_argv = merge_args(helpers.nvim_argv, {'--headless'}) + local nvim_argv = merge_args(helpers.nvim_argv, { '--headless' }) local function connect_test(server, mode, address) - local serverpid = funcs.getpid() + local serverpid = fn.getpid() local client = spawn(nvim_argv, false, nil, true) set_session(client) - local clientpid = funcs.getpid() + local clientpid = fn.getpid() neq(serverpid, clientpid) - local id = funcs.sockconnect(mode, address, {rpc=true}) + local id = fn.sockconnect(mode, address, { rpc = true }) ok(id > 0) - funcs.rpcrequest(id, 'nvim_set_current_line', 'hello') - local client_id = funcs.rpcrequest(id, 'nvim_get_api_info')[1] + fn.rpcrequest(id, 'nvim_set_current_line', 'hello') + local client_id = fn.rpcrequest(id, 'nvim_get_chan_info', 0).id set_session(server) - eq(serverpid, funcs.getpid()) - eq('hello', meths.get_current_line()) + eq(serverpid, fn.getpid()) + eq('hello', api.nvim_get_current_line()) -- method calls work both ways - funcs.rpcrequest(client_id, 'nvim_set_current_line', 'howdy!') - eq(id, funcs.rpcrequest(client_id, 'nvim_get_api_info')[1]) + fn.rpcrequest(client_id, 'nvim_set_current_line', 'howdy!') + eq(id, fn.rpcrequest(client_id, 'nvim_get_chan_info', 0).id) set_session(client) - eq(clientpid, funcs.getpid()) - eq('howdy!', meths.get_current_line()) + eq(clientpid, fn.getpid()) + eq('howdy!', api.nvim_get_current_line()) server:close() client:close() @@ -302,8 +313,8 @@ describe('server -> client', function() it('via named pipe', function() local server = spawn(nvim_argv) set_session(server) - local address = funcs.serverlist()[1] - local first = string.sub(address,1,1) + local address = fn.serverlist()[1] + local first = string.sub(address, 1, 1) ok(first == '/' or first == '\\') connect_test(server, 'pipe', address) end) @@ -311,42 +322,42 @@ describe('server -> client', function() it('via ipv4 address', function() local server = spawn(nvim_argv) set_session(server) - local status, address = pcall(funcs.serverstart, "127.0.0.1:") + local status, address = pcall(fn.serverstart, '127.0.0.1:') if not status then pending('no ipv4 stack') end - eq('127.0.0.1:', string.sub(address,1,10)) + eq('127.0.0.1:', string.sub(address, 1, 10)) connect_test(server, 'tcp', address) end) it('via ipv6 address', function() local server = spawn(nvim_argv) set_session(server) - local status, address = pcall(funcs.serverstart, '::1:') + local status, address = pcall(fn.serverstart, '::1:') if not status then pending('no ipv6 stack') end - eq('::1:', string.sub(address,1,4)) + eq('::1:', string.sub(address, 1, 4)) connect_test(server, 'tcp', address) end) it('via hostname', function() local server = spawn(nvim_argv) set_session(server) - local address = funcs.serverstart("localhost:") - eq('localhost:', string.sub(address,1,10)) + local address = fn.serverstart('localhost:') + eq('localhost:', string.sub(address, 1, 10)) connect_test(server, 'tcp', address) end) it('does not crash on receiving UI events', function() local server = spawn(nvim_argv) set_session(server) - local address = funcs.serverlist()[1] + local address = fn.serverlist()[1] local client = spawn(nvim_argv, false, nil, true) set_session(client) - local id = funcs.sockconnect('pipe', address, {rpc=true}) - funcs.rpcrequest(id, 'nvim_ui_attach', 80, 24, {}) + local id = fn.sockconnect('pipe', address, { rpc = true }) + fn.rpcrequest(id, 'nvim_ui_attach', 80, 24, {}) assert_alive() server:close() @@ -356,18 +367,18 @@ describe('server -> client', function() describe('connecting to its own pipe address', function() it('does not deadlock', function() - local address = funcs.serverlist()[1] - local first = string.sub(address,1,1) + local address = fn.serverlist()[1] + local first = string.sub(address, 1, 1) ok(first == '/' or first == '\\') - local serverpid = funcs.getpid() + local serverpid = fn.getpid() - local id = funcs.sockconnect('pipe', address, {rpc=true}) + local id = fn.sockconnect('pipe', address, { rpc = true }) - funcs.rpcrequest(id, 'nvim_set_current_line', 'hello') - eq('hello', meths.get_current_line()) - eq(serverpid, funcs.rpcrequest(id, "nvim_eval", "getpid()")) + fn.rpcrequest(id, 'nvim_set_current_line', 'hello') + eq('hello', api.nvim_get_current_line()) + eq(serverpid, fn.rpcrequest(id, 'nvim_eval', 'getpid()')) - eq(id, funcs.rpcrequest(id, 'nvim_get_api_info')[1]) + eq(id, fn.rpcrequest(id, 'nvim_get_chan_info', 0).id) end) end) end) diff --git a/test/functional/api/tabpage_spec.lua b/test/functional/api/tabpage_spec.lua index 20b3163d95..36955c4ace 100644 --- a/test/functional/api/tabpage_spec.lua +++ b/test/functional/api/tabpage_spec.lua @@ -1,11 +1,9 @@ local helpers = require('test.functional.helpers')(after_each) -local clear, nvim, tabpage, curtab, eq, ok = - helpers.clear, helpers.nvim, helpers.tabpage, helpers.curtab, helpers.eq, - helpers.ok -local curtabmeths = helpers.curtabmeths -local funcs = helpers.funcs +local clear, eq, ok = helpers.clear, helpers.eq, helpers.ok +local api = helpers.api +local fn = helpers.fn local request = helpers.request -local NIL = helpers.NIL +local NIL = vim.NIL local pcall_err = helpers.pcall_err local command = helpers.command @@ -14,48 +12,108 @@ describe('api/tabpage', function() describe('list_wins and get_win', function() it('works', function() - nvim('command', 'tabnew') - nvim('command', 'vsplit') - local tab1, tab2 = unpack(nvim('list_tabpages')) - local win1, win2, win3 = unpack(nvim('list_wins')) - eq({win1}, tabpage('list_wins', tab1)) - eq({win2, win3}, tabpage('list_wins', tab2)) - eq(win2, tabpage('get_win', tab2)) - nvim('set_current_win', win3) - eq(win3, tabpage('get_win', tab2)) + command('tabnew') + command('vsplit') + local tab1, tab2 = unpack(api.nvim_list_tabpages()) + local win1, win2, win3 = unpack(api.nvim_list_wins()) + eq({ win1 }, api.nvim_tabpage_list_wins(tab1)) + eq(win1, api.nvim_tabpage_get_win(tab1)) + eq({ win2, win3 }, api.nvim_tabpage_list_wins(tab2)) + eq(win2, api.nvim_tabpage_get_win(tab2)) + api.nvim_set_current_win(win3) + eq(win3, api.nvim_tabpage_get_win(tab2)) + command('tabprev') + eq(win1, api.nvim_tabpage_get_win(tab1)) + eq(win3, api.nvim_tabpage_get_win(tab2)) end) it('validates args', function() - eq('Invalid tabpage id: 23', pcall_err(tabpage, 'list_wins', 23)) + eq('Invalid tabpage id: 23', pcall_err(api.nvim_tabpage_list_wins, 23)) + end) + end) + + describe('set_win', function() + it('works', function() + command('tabnew') + command('vsplit') + local tab1, tab2 = unpack(api.nvim_list_tabpages()) + local win1, win2, win3 = unpack(api.nvim_list_wins()) + eq({ win1 }, api.nvim_tabpage_list_wins(tab1)) + eq({ win2, win3 }, api.nvim_tabpage_list_wins(tab2)) + eq(win2, api.nvim_tabpage_get_win(tab2)) + api.nvim_tabpage_set_win(tab2, win3) + eq(win3, api.nvim_tabpage_get_win(tab2)) + end) + + it('works in non-current tabpages', function() + command('tabnew') + command('vsplit') + local tab1, tab2 = unpack(api.nvim_list_tabpages()) + local win1, win2, win3 = unpack(api.nvim_list_wins()) + eq({ win1 }, api.nvim_tabpage_list_wins(tab1)) + eq({ win2, win3 }, api.nvim_tabpage_list_wins(tab2)) + eq(win2, api.nvim_tabpage_get_win(tab2)) + eq(win2, api.nvim_get_current_win()) + + command('tabprev') + + eq(tab1, api.nvim_get_current_tabpage()) + + eq(win2, api.nvim_tabpage_get_win(tab2)) + api.nvim_tabpage_set_win(tab2, win3) + eq(win3, api.nvim_tabpage_get_win(tab2)) + + command('tabnext') + eq(win3, api.nvim_get_current_win()) + end) + + it('throws an error when the window does not belong to the tabpage', function() + command('tabnew') + command('vsplit') + local tab1, tab2 = unpack(api.nvim_list_tabpages()) + local win1, win2, win3 = unpack(api.nvim_list_wins()) + eq({ win1 }, api.nvim_tabpage_list_wins(tab1)) + eq({ win2, win3 }, api.nvim_tabpage_list_wins(tab2)) + eq(win2, api.nvim_get_current_win()) + + eq( + string.format('Window does not belong to tabpage %d', tab2), + pcall_err(api.nvim_tabpage_set_win, tab2, win1) + ) + + eq( + string.format('Window does not belong to tabpage %d', tab1), + pcall_err(api.nvim_tabpage_set_win, tab1, win3) + ) end) end) describe('{get,set,del}_var', function() it('works', function() - curtab('set_var', 'lua', {1, 2, {['3'] = 1}}) - eq({1, 2, {['3'] = 1}}, curtab('get_var', 'lua')) - eq({1, 2, {['3'] = 1}}, nvim('eval', 't:lua')) - eq(1, funcs.exists('t:lua')) - curtabmeths.del_var('lua') - eq(0, funcs.exists('t:lua')) - eq('Key not found: lua', pcall_err(curtabmeths.del_var, 'lua')) - curtabmeths.set_var('lua', 1) + api.nvim_tabpage_set_var(0, 'lua', { 1, 2, { ['3'] = 1 } }) + eq({ 1, 2, { ['3'] = 1 } }, api.nvim_tabpage_get_var(0, 'lua')) + eq({ 1, 2, { ['3'] = 1 } }, api.nvim_eval('t:lua')) + eq(1, fn.exists('t:lua')) + api.nvim_tabpage_del_var(0, 'lua') + eq(0, fn.exists('t:lua')) + eq('Key not found: lua', pcall_err(api.nvim_tabpage_del_var, 0, 'lua')) + api.nvim_tabpage_set_var(0, 'lua', 1) command('lockvar t:lua') - eq('Key is locked: lua', pcall_err(curtabmeths.del_var, 'lua')) - eq('Key is locked: lua', pcall_err(curtabmeths.set_var, 'lua', 1)) + eq('Key is locked: lua', pcall_err(api.nvim_tabpage_del_var, 0, 'lua')) + eq('Key is locked: lua', pcall_err(api.nvim_tabpage_set_var, 0, 'lua', 1)) end) it('tabpage_set_var returns the old value', function() - local val1 = {1, 2, {['3'] = 1}} - local val2 = {4, 7} + local val1 = { 1, 2, { ['3'] = 1 } } + local val2 = { 4, 7 } eq(NIL, request('tabpage_set_var', 0, 'lua', val1)) eq(val1, request('tabpage_set_var', 0, 'lua', val2)) end) it('tabpage_del_var returns the old value', function() - local val1 = {1, 2, {['3'] = 1}} - local val2 = {4, 7} - eq(NIL, request('tabpage_set_var', 0, 'lua', val1)) + local val1 = { 1, 2, { ['3'] = 1 } } + local val2 = { 4, 7 } + eq(NIL, request('tabpage_set_var', 0, 'lua', val1)) eq(val1, request('tabpage_set_var', 0, 'lua', val2)) eq(val2, request('tabpage_del_var', 0, 'lua')) end) @@ -63,28 +121,28 @@ describe('api/tabpage', function() describe('get_number', function() it('works', function() - local tabs = nvim('list_tabpages') - eq(1, tabpage('get_number', tabs[1])) + local tabs = api.nvim_list_tabpages() + eq(1, api.nvim_tabpage_get_number(tabs[1])) - nvim('command', 'tabnew') - local tab1, tab2 = unpack(nvim('list_tabpages')) - eq(1, tabpage('get_number', tab1)) - eq(2, tabpage('get_number', tab2)) + command('tabnew') + local tab1, tab2 = unpack(api.nvim_list_tabpages()) + eq(1, api.nvim_tabpage_get_number(tab1)) + eq(2, api.nvim_tabpage_get_number(tab2)) - nvim('command', '-tabmove') - eq(2, tabpage('get_number', tab1)) - eq(1, tabpage('get_number', tab2)) + command('-tabmove') + eq(2, api.nvim_tabpage_get_number(tab1)) + eq(1, api.nvim_tabpage_get_number(tab2)) end) end) describe('is_valid', function() it('works', function() - nvim('command', 'tabnew') - local tab = nvim('list_tabpages')[2] - nvim('set_current_tabpage', tab) - ok(tabpage('is_valid', tab)) - nvim('command', 'tabclose') - ok(not tabpage('is_valid', tab)) + command('tabnew') + local tab = api.nvim_list_tabpages()[2] + api.nvim_set_current_tabpage(tab) + ok(api.nvim_tabpage_is_valid(tab)) + command('tabclose') + ok(not api.nvim_tabpage_is_valid(tab)) end) end) end) diff --git a/test/functional/api/ui_spec.lua b/test/functional/api/ui_spec.lua index 6efb6726fe..3e1f1ec965 100644 --- a/test/functional/api/ui_spec.lua +++ b/test/functional/api/ui_spec.lua @@ -6,7 +6,7 @@ local eq = helpers.eq local eval = helpers.eval local exec = helpers.exec local feed = helpers.feed -local meths = helpers.meths +local api = helpers.api local request = helpers.request local pcall_err = helpers.pcall_err @@ -23,42 +23,56 @@ describe('nvim_ui_attach()', function() end) it('validation', function() - eq('No such UI option: foo', - pcall_err(meths.ui_attach, 80, 24, { foo={'foo'} })) + eq('No such UI option: foo', pcall_err(api.nvim_ui_attach, 80, 24, { foo = { 'foo' } })) - eq("Invalid 'ext_linegrid': expected Boolean, got Array", - pcall_err(meths.ui_attach, 80, 24, { ext_linegrid={} })) - eq("Invalid 'override': expected Boolean, got Array", - pcall_err(meths.ui_attach, 80, 24, { override={} })) - eq("Invalid 'rgb': expected Boolean, got Array", - pcall_err(meths.ui_attach, 80, 24, { rgb={} })) - eq("Invalid 'term_name': expected String, got Boolean", - pcall_err(meths.ui_attach, 80, 24, { term_name=true })) - eq("Invalid 'term_colors': expected Integer, got Boolean", - pcall_err(meths.ui_attach, 80, 24, { term_colors=true })) - eq("Invalid 'stdin_fd': expected Integer, got String", - pcall_err(meths.ui_attach, 80, 24, { stdin_fd='foo' })) - eq("Invalid 'stdin_tty': expected Boolean, got String", - pcall_err(meths.ui_attach, 80, 24, { stdin_tty='foo' })) - eq("Invalid 'stdout_tty': expected Boolean, got String", - pcall_err(meths.ui_attach, 80, 24, { stdout_tty='foo' })) + eq( + "Invalid 'ext_linegrid': expected Boolean, got Array", + pcall_err(api.nvim_ui_attach, 80, 24, { ext_linegrid = {} }) + ) + eq( + "Invalid 'override': expected Boolean, got Array", + pcall_err(api.nvim_ui_attach, 80, 24, { override = {} }) + ) + eq( + "Invalid 'rgb': expected Boolean, got Array", + pcall_err(api.nvim_ui_attach, 80, 24, { rgb = {} }) + ) + eq( + "Invalid 'term_name': expected String, got Boolean", + pcall_err(api.nvim_ui_attach, 80, 24, { term_name = true }) + ) + eq( + "Invalid 'term_colors': expected Integer, got Boolean", + pcall_err(api.nvim_ui_attach, 80, 24, { term_colors = true }) + ) + eq( + "Invalid 'stdin_fd': expected Integer, got String", + pcall_err(api.nvim_ui_attach, 80, 24, { stdin_fd = 'foo' }) + ) + eq( + "Invalid 'stdin_tty': expected Boolean, got String", + pcall_err(api.nvim_ui_attach, 80, 24, { stdin_tty = 'foo' }) + ) + eq( + "Invalid 'stdout_tty': expected Boolean, got String", + pcall_err(api.nvim_ui_attach, 80, 24, { stdout_tty = 'foo' }) + ) - eq('UI not attached to channel: 1', - pcall_err(request, 'nvim_ui_try_resize', 40, 10)) - eq('UI not attached to channel: 1', - pcall_err(request, 'nvim_ui_set_option', 'rgb', true)) - eq('UI not attached to channel: 1', - pcall_err(request, 'nvim_ui_detach')) + eq('UI not attached to channel: 1', pcall_err(request, 'nvim_ui_try_resize', 40, 10)) + eq('UI not attached to channel: 1', pcall_err(request, 'nvim_ui_set_option', 'rgb', true)) + eq('UI not attached to channel: 1', pcall_err(request, 'nvim_ui_detach')) local screen = Screen.new() - screen:attach({rgb=false}) - eq('UI already attached to channel: 1', - pcall_err(request, 'nvim_ui_attach', 40, 10, { rgb=false })) + screen:attach({ rgb = false }) + eq( + 'UI already attached to channel: 1', + pcall_err(request, 'nvim_ui_attach', 40, 10, { rgb = false }) + ) end) end) it('autocmds UIEnter/UILeave', function() - clear{args_rm={'--headless'}} + clear { args_rm = { '--headless' } } exec([[ let g:evs = [] autocmd UIEnter * call add(g:evs, "UIEnter") | let g:uienter_ev = deepcopy(v:event) @@ -67,9 +81,9 @@ it('autocmds UIEnter/UILeave', function() ]]) local screen = Screen.new() screen:attach() - eq({chan=1}, eval('g:uienter_ev')) + eq({ chan = 1 }, eval('g:uienter_ev')) screen:detach() - eq({chan=1}, eval('g:uileave_ev')) + eq({ chan = 1 }, eval('g:uileave_ev')) eq({ 'VimEnter', 'UIEnter', @@ -89,29 +103,37 @@ it('autocmds VimSuspend/VimResume #22041', function() eq(false, screen.suspended) feed('<C-Z>') - screen:expect(function() eq(true, screen.suspended) end) + screen:expect(function() + eq(true, screen.suspended) + end) eq({ 's' }, eval('g:ev')) screen.suspended = false feed('<Ignore>') eq({ 's', 'r' }, eval('g:ev')) command('suspend') - screen:expect(function() eq(true, screen.suspended) end) + screen:expect(function() + eq(true, screen.suspended) + end) eq({ 's', 'r', 's' }, eval('g:ev')) screen.suspended = false - meths.input_mouse('move', '', '', 0, 0, 0) + api.nvim_input_mouse('move', '', '', 0, 0, 0) eq({ 's', 'r', 's', 'r' }, eval('g:ev')) feed('<C-Z><C-Z><C-Z>') - screen:expect(function() eq(true, screen.suspended) end) - meths.ui_set_focus(false) + screen:expect(function() + eq(true, screen.suspended) + end) + api.nvim_ui_set_focus(false) eq({ 's', 'r', 's', 'r', 's' }, eval('g:ev')) screen.suspended = false - meths.ui_set_focus(true) + api.nvim_ui_set_focus(true) eq({ 's', 'r', 's', 'r', 's', 'r' }, eval('g:ev')) command('suspend | suspend | suspend') - screen:expect(function() eq(true, screen.suspended) end) + screen:expect(function() + eq(true, screen.suspended) + end) screen:detach() eq({ 's', 'r', 's', 'r', 's', 'r', 's' }, eval('g:ev')) screen.suspended = false diff --git a/test/functional/api/version_spec.lua b/test/functional/api/version_spec.lua index 6d466b0cc1..c304f1aa88 100644 --- a/test/functional/api/version_spec.lua +++ b/test/functional/api/version_spec.lua @@ -1,8 +1,6 @@ local helpers = require('test.functional.helpers')(after_each) -local mpack = require('mpack') -local clear, funcs, eq = helpers.clear, helpers.funcs, helpers.eq -local call = helpers.call -local meths = helpers.meths +local clear, fn, eq = helpers.clear, helpers.fn, helpers.eq +local api = helpers.api local function read_mpack_file(fname) local fd = io.open(fname, 'rb') @@ -12,48 +10,47 @@ local function read_mpack_file(fname) local data = fd:read('*a') fd:close() - local unpack = mpack.Unpacker() + local unpack = vim.mpack.Unpacker() return unpack(data) end describe("api_info()['version']", function() before_each(clear) - it("returns API level", function() - local version = call('api_info')['version'] + it('returns API level', function() + local version = fn.api_info()['version'] local current = version['api_level'] - local compat = version['api_compatible'] - eq("number", type(current)) - eq("number", type(compat)) + local compat = version['api_compatible'] + eq('number', type(current)) + eq('number', type(compat)) assert(current >= compat) end) - it("returns Nvim version", function() - local version = call('api_info')['version'] - local major = version['major'] - local minor = version['minor'] - local patch = version['patch'] + it('returns Nvim version', function() + local version = fn.api_info()['version'] + local major = version['major'] + local minor = version['minor'] + local patch = version['patch'] local prerelease = version['prerelease'] - local build = version['build'] - eq("number", type(major)) - eq("number", type(minor)) - eq("number", type(patch)) - eq("boolean", type(prerelease)) - eq(1, funcs.has("nvim-"..major.."."..minor.."."..patch)) - eq(0, funcs.has("nvim-"..major.."."..minor.."."..(patch + 1))) - eq(0, funcs.has("nvim-"..major.."."..(minor + 1).."."..patch)) - eq(0, funcs.has("nvim-"..(major + 1).."."..minor.."."..patch)) + local build = version['build'] + eq('number', type(major)) + eq('number', type(minor)) + eq('number', type(patch)) + eq('boolean', type(prerelease)) + eq(1, fn.has('nvim-' .. major .. '.' .. minor .. '.' .. patch)) + eq(0, fn.has('nvim-' .. major .. '.' .. minor .. '.' .. (patch + 1))) + eq(0, fn.has('nvim-' .. major .. '.' .. (minor + 1) .. '.' .. patch)) + eq(0, fn.has('nvim-' .. (major + 1) .. '.' .. minor .. '.' .. patch)) assert(build == nil or type(build) == 'string') end) end) - -describe("api metadata", function() +describe('api metadata', function() before_each(clear) local function name_table(entries) local by_name = {} - for _,e in ipairs(entries) do + for _, e in ipairs(entries) do by_name[e.name] = e end return by_name @@ -63,10 +60,10 @@ describe("api metadata", function() local function filter_function_metadata(f) f.deprecated_since = nil for idx, _ in ipairs(f.parameters) do - f.parameters[idx][2] = '' -- Remove parameter name. + f.parameters[idx][2] = '' -- Remove parameter name. end - if string.sub(f.name, 1, 4) ~= "nvim" then + if string.sub(f.name, 1, 4) ~= 'nvim' then f.method = nil end return f @@ -76,7 +73,7 @@ describe("api metadata", function() -- check types of existing params are the same -- adding parameters is ok, but removing params is not (gives nil error) eq(old_e.since, new_e.since, old_e.name) - for i,p in ipairs(old_e.parameters) do + for i, p in ipairs(old_e.parameters) do eq(new_e.parameters[i][1], p[1], old_e.name) end end @@ -92,28 +89,30 @@ describe("api metadata", function() end end - local api, compat, stable, api_level + local api_info, compat, stable, api_level local old_api = {} setup(function() - clear() -- Ensure a session before requesting api_info. - api = meths.get_api_info()[2] - compat = api.version.api_compatible - api_level = api.version.api_level - if api.version.api_prerelease then - stable = api_level-1 + clear() -- Ensure a session before requesting api_info. + api_info = api.nvim_get_api_info()[2] + compat = api_info.version.api_compatible + api_level = api_info.version.api_level + if api_info.version.api_prerelease then + stable = api_level - 1 else stable = api_level end for level = compat, stable do - local path = ('test/functional/fixtures/api_level_'.. - tostring(level)..'.mpack') + local path = ('test/functional/fixtures/api_level_' .. tostring(level) .. '.mpack') old_api[level] = read_mpack_file(path) if old_api[level] == nil then - local errstr = "missing metadata fixture for stable level "..level..". " - if level == api_level and not api.version.api_prerelease then - errstr = (errstr.."If NVIM_API_CURRENT was bumped, ".. - "don't forget to set NVIM_API_PRERELEASE to true.") + local errstr = 'missing metadata fixture for stable level ' .. level .. '. ' + if level == api_level and not api_info.version.api_prerelease then + errstr = ( + errstr + .. 'If NVIM_API_CURRENT was bumped, ' + .. "don't forget to set NVIM_API_PRERELEASE to true." + ) end error(errstr) end @@ -124,60 +123,76 @@ describe("api metadata", function() end end) - it("functions are compatible with old metadata or have new level", function() - local funcs_new = name_table(api.functions) + it('functions are compatible with old metadata or have new level', function() + local funcs_new = name_table(api_info.functions) local funcs_compat = {} for level = compat, stable do - for _,f in ipairs(old_api[level].functions) do + for _, f in ipairs(old_api[level].functions) do if funcs_new[f.name] == nil then if f.since >= compat then - error('function '..f.name..' was removed but exists in level '.. - f.since..' which nvim should be compatible with') + error( + 'function ' + .. f.name + .. ' was removed but exists in level ' + .. f.since + .. ' which nvim should be compatible with' + ) end else - eq(filter_function_metadata(f), - filter_function_metadata(funcs_new[f.name])) + eq(filter_function_metadata(f), filter_function_metadata(funcs_new[f.name])) end end funcs_compat[level] = name_table(old_api[level].functions) end - for _,f in ipairs(api.functions) do + for _, f in ipairs(api_info.functions) do if f.since <= stable then local f_old = funcs_compat[f.since][f.name] if f_old == nil then - if string.sub(f.name, 1, 4) == "nvim" then - local errstr = ("function "..f.name.." has too low since value. ".. - "For new functions set it to "..(stable+1)..".") - if not api.version.api_prerelease then - errstr = (errstr.." Also bump NVIM_API_CURRENT and set ".. - "NVIM_API_PRERELEASE to true in CMakeLists.txt.") + if string.sub(f.name, 1, 4) == 'nvim' then + local errstr = ( + 'function ' + .. f.name + .. ' has too low since value. ' + .. 'For new functions set it to ' + .. (stable + 1) + .. '.' + ) + if not api_info.version.api_prerelease then + errstr = ( + errstr + .. ' Also bump NVIM_API_CURRENT and set ' + .. 'NVIM_API_PRERELEASE to true in CMakeLists.txt.' + ) end error(errstr) else - error("function name '"..f.name.."' doesn't begin with 'nvim_'") + error("function name '" .. f.name .. "' doesn't begin with 'nvim_'") end end elseif f.since > api_level then - if api.version.api_prerelease then - error("New function "..f.name.." should use since value ".. - api_level) + if api_info.version.api_prerelease then + error('New function ' .. f.name .. ' should use since value ' .. api_level) else - error("function "..f.name.." has since value > api_level. ".. - "Bump NVIM_API_CURRENT and set ".. - "NVIM_API_PRERELEASE to true in CMakeLists.txt.") + error( + 'function ' + .. f.name + .. ' has since value > api_level. ' + .. 'Bump NVIM_API_CURRENT and set ' + .. 'NVIM_API_PRERELEASE to true in CMakeLists.txt.' + ) end end end end) - it("UI events are compatible with old metadata or have new level", function() - local ui_events_new = name_table(api.ui_events) + it('UI events are compatible with old metadata or have new level', function() + local ui_events_new = name_table(api_info.ui_events) local ui_events_compat = {} -- UI events were formalized in level 3 for level = 3, stable do - for _,e in ipairs(old_api[level].ui_events) do + for _, e in ipairs(old_api[level].ui_events) do local new_e = ui_events_new[e.name] if new_e ~= nil then check_ui_event_compatible(e, new_e) @@ -186,41 +201,53 @@ describe("api metadata", function() ui_events_compat[level] = name_table(old_api[level].ui_events) end - for _,e in ipairs(api.ui_events) do + for _, e in ipairs(api_info.ui_events) do if e.since <= stable then local e_old = ui_events_compat[e.since][e.name] if e_old == nil then - local errstr = ("UI event "..e.name.." has too low since value. ".. - "For new events set it to "..(stable+1)..".") - if not api.version.api_prerelease then - errstr = (errstr.." Also bump NVIM_API_CURRENT and set ".. - "NVIM_API_PRERELEASE to true in CMakeLists.txt.") + local errstr = ( + 'UI event ' + .. e.name + .. ' has too low since value. ' + .. 'For new events set it to ' + .. (stable + 1) + .. '.' + ) + if not api_info.version.api_prerelease then + errstr = ( + errstr + .. ' Also bump NVIM_API_CURRENT and set ' + .. 'NVIM_API_PRERELEASE to true in CMakeLists.txt.' + ) end error(errstr) end elseif e.since > api_level then - if api.version.api_prerelease then - error("New UI event "..e.name.." should use since value ".. - api_level) + if api_info.version.api_prerelease then + error('New UI event ' .. e.name .. ' should use since value ' .. api_level) else - error("UI event "..e.name.." has since value > api_level. ".. - "Bump NVIM_API_CURRENT and set ".. - "NVIM_API_PRERELEASE to true in CMakeLists.txt.") + error( + 'UI event ' + .. e.name + .. ' has since value > api_level. ' + .. 'Bump NVIM_API_CURRENT and set ' + .. 'NVIM_API_PRERELEASE to true in CMakeLists.txt.' + ) end end end end) - it("ui_options are preserved from older levels", function() + it('ui_options are preserved from older levels', function() local available_options = {} - for _, option in ipairs(api.ui_options) do + for _, option in ipairs(api_info.ui_options) do available_options[option] = true end -- UI options were versioned from level 4 for level = 4, stable do for _, option in ipairs(old_api[level].ui_options) do if not available_options[option] then - error("UI option "..option.." from stable metadata is missing") + error('UI option ' .. option .. ' from stable metadata is missing') end end end diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 8bbadda9b0..9a4a457637 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1,22 +1,25 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local luv = require('luv') +local uv = vim.uv local fmt = string.format +local dedent = helpers.dedent local assert_alive = helpers.assert_alive -local NIL = helpers.NIL -local clear, nvim, eq, neq = helpers.clear, helpers.nvim, helpers.eq, helpers.neq +local NIL = vim.NIL +local clear, eq, neq = helpers.clear, helpers.eq, helpers.neq local command = helpers.command +local command_output = helpers.api.nvim_command_output local exec = helpers.exec local exec_capture = helpers.exec_capture local eval = helpers.eval local expect = helpers.expect -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local matches = helpers.matches -local pesc = helpers.pesc +local pesc = vim.pesc local mkdir_p = helpers.mkdir_p local ok, nvim_async, feed = helpers.ok, helpers.nvim_async, helpers.feed +local async_meths = helpers.async_meths local is_os = helpers.is_os local parse_context = helpers.parse_context local request = helpers.request @@ -31,203 +34,273 @@ local insert = helpers.insert local skip = helpers.skip local pcall_err = helpers.pcall_err -local format_string = helpers.format_string +local format_string = require('test.format_string').format_string local intchar2lua = helpers.intchar2lua local mergedicts_copy = helpers.mergedicts_copy -local endswith = helpers.endswith +local endswith = vim.endswith describe('API', function() before_each(clear) it('validates requests', function() -- RPC - matches('Invalid method: bogus$', - pcall_err(request, 'bogus')) - matches('Invalid method: … の り 。…$', - pcall_err(request, '… の り 。…')) - matches('Invalid method: <empty>$', - pcall_err(request, '')) + matches('Invalid method: bogus$', pcall_err(request, 'bogus')) + matches('Invalid method: … の り 。…$', pcall_err(request, '… の り 。…')) + matches('Invalid method: <empty>$', pcall_err(request, '')) -- Non-RPC: rpcrequest(v:servername) uses internal channel. - matches('Invalid method: … の り 。…$', - pcall_err(request, 'nvim_eval', - [=[rpcrequest(sockconnect('pipe', v:servername, {'rpc':1}), '… の り 。…')]=])) - matches('Invalid method: bogus$', - pcall_err(request, 'nvim_eval', - [=[rpcrequest(sockconnect('pipe', v:servername, {'rpc':1}), 'bogus')]=])) + matches( + 'Invalid method: … の り 。…$', + pcall_err( + request, + 'nvim_eval', + [=[rpcrequest(sockconnect('pipe', v:servername, {'rpc':1}), '… の り 。…')]=] + ) + ) + matches( + 'Invalid method: bogus$', + pcall_err( + request, + 'nvim_eval', + [=[rpcrequest(sockconnect('pipe', v:servername, {'rpc':1}), 'bogus')]=] + ) + ) -- XXX: This must be the last one, else next one will fail: -- "Packer instance already working. Use another Packer ..." - matches("can't serialize object of type .$", - pcall_err(request, nil)) + matches("can't serialize object of type .$", pcall_err(request, nil)) end) it('handles errors in async requests', function() - local error_types = meths.get_api_info()[2].error_types + local error_types = api.nvim_get_api_info()[2].error_types nvim_async('bogus') - eq({'notification', 'nvim_error_event', - {error_types.Exception.id, 'Invalid method: nvim_bogus'}}, next_msg()) + eq({ + 'notification', + 'nvim_error_event', + { error_types.Exception.id, 'Invalid method: bogus' }, + }, next_msg()) -- error didn't close channel. assert_alive() end) it('failed async request emits nvim_error_event', function() - local error_types = meths.get_api_info()[2].error_types - nvim_async('command', 'bogus') - eq({'notification', 'nvim_error_event', - {error_types.Exception.id, 'Vim:E492: Not an editor command: bogus'}}, - next_msg()) + local error_types = api.nvim_get_api_info()[2].error_types + async_meths.nvim_command('bogus') + eq({ + 'notification', + 'nvim_error_event', + { error_types.Exception.id, 'Vim:E492: Not an editor command: bogus' }, + }, next_msg()) -- error didn't close channel. assert_alive() end) + it('input is processed first when followed immediately by non-fast events', function() + api.nvim_set_current_line('ab') + async_meths.nvim_input('x') + async_meths.nvim_exec_lua('_G.res1 = vim.api.nvim_get_current_line()', {}) + async_meths.nvim_exec_lua('_G.res2 = vim.api.nvim_get_current_line()', {}) + eq({ 'b', 'b' }, exec_lua('return { _G.res1, _G.res2 }')) + end) + it('does not set CA_COMMAND_BUSY #7254', function() - nvim('command', 'split') - nvim('command', 'autocmd WinEnter * startinsert') - nvim('command', 'wincmd w') - eq({mode='i', blocking=false}, nvim("get_mode")) + command('split') + command('autocmd WinEnter * startinsert') + command('wincmd w') + eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) end) describe('nvim_exec2', function() it('always returns table', function() -- In built version this results into `vim.empty_dict()` - eq({}, nvim('exec2', 'echo "Hello"', {})) - eq({}, nvim('exec2', 'echo "Hello"', { output = false })) - eq({ output = 'Hello' }, nvim('exec2', 'echo "Hello"', { output = true })) + eq({}, api.nvim_exec2('echo "Hello"', {})) + eq({}, api.nvim_exec2('echo "Hello"', { output = false })) + eq({ output = 'Hello' }, api.nvim_exec2('echo "Hello"', { output = true })) end) it('default options', function() -- Should be equivalent to { output = false } - nvim('exec2', "let x0 = 'a'", {}) - eq('a', nvim('get_var', 'x0')) + api.nvim_exec2("let x0 = 'a'", {}) + eq('a', api.nvim_get_var('x0')) end) it('one-line input', function() - nvim('exec2', "let x1 = 'a'", { output = false }) - eq('a', nvim('get_var', 'x1')) + api.nvim_exec2("let x1 = 'a'", { output = false }) + eq('a', api.nvim_get_var('x1')) end) it(':verbose set {option}?', function() - nvim('exec2', 'set nowrap', { output = false }) - eq({ output = 'nowrap\n\tLast set from anonymous :source' }, - nvim('exec2', 'verbose set wrap?', { output = true })) + api.nvim_exec2('set nowrap', { output = false }) + eq( + { output = 'nowrap\n\tLast set from anonymous :source' }, + api.nvim_exec2('verbose set wrap?', { output = true }) + ) -- Using script var to force creation of a script item - nvim('exec2', [[ + api.nvim_exec2( + [[ let s:a = 1 set nowrap - ]], { output = false }) - eq({ output = 'nowrap\n\tLast set from anonymous :source (script id 1)' }, - nvim('exec2', 'verbose set wrap?', { output = true })) + ]], + { output = false } + ) + eq( + { output = 'nowrap\n\tLast set from anonymous :source (script id 1)' }, + api.nvim_exec2('verbose set wrap?', { output = true }) + ) end) it('multiline input', function() -- Heredoc + empty lines. - nvim('exec2', "let x2 = 'a'\n", { output = false }) - eq('a', nvim('get_var', 'x2')) - nvim('exec2','lua <<EOF\n\n\n\ny=3\n\n\nEOF', { output = false }) - eq(3, nvim('eval', "luaeval('y')")) + api.nvim_exec2("let x2 = 'a'\n", { output = false }) + eq('a', api.nvim_get_var('x2')) + api.nvim_exec2('lua <<EOF\n\n\n\ny=3\n\n\nEOF', { output = false }) + eq(3, api.nvim_eval("luaeval('y')")) - eq({}, nvim('exec2', 'lua <<EOF\ny=3\nEOF', { output = false })) - eq(3, nvim('eval', "luaeval('y')")) + eq({}, api.nvim_exec2('lua <<EOF\ny=3\nEOF', { output = false })) + eq(3, api.nvim_eval("luaeval('y')")) -- Multiple statements - nvim('exec2', 'let x1=1\nlet x2=2\nlet x3=3\n', { output = false }) - eq(1, nvim('eval', 'x1')) - eq(2, nvim('eval', 'x2')) - eq(3, nvim('eval', 'x3')) + api.nvim_exec2('let x1=1\nlet x2=2\nlet x3=3\n', { output = false }) + eq(1, api.nvim_eval('x1')) + eq(2, api.nvim_eval('x2')) + eq(3, api.nvim_eval('x3')) -- Functions - nvim('exec2', 'function Foo()\ncall setline(1,["xxx"])\nendfunction', { output = false }) - eq('', nvim('get_current_line')) - nvim('exec2', 'call Foo()', { output = false }) - eq('xxx', nvim('get_current_line')) + api.nvim_exec2('function Foo()\ncall setline(1,["xxx"])\nendfunction', { output = false }) + eq('', api.nvim_get_current_line()) + api.nvim_exec2('call Foo()', { output = false }) + eq('xxx', api.nvim_get_current_line()) -- Autocmds - nvim('exec2','autocmd BufAdd * :let x1 = "Hello"', { output = false }) - nvim('command', 'new foo') + api.nvim_exec2('autocmd BufAdd * :let x1 = "Hello"', { output = false }) + command('new foo') eq('Hello', request('nvim_eval', 'g:x1')) -- Line continuations - nvim('exec2', [[ + api.nvim_exec2( + [[ let abc = #{ \ a: 1, "\ b: 2, \ c: 3 - \ }]], { output = false }) - eq({a = 1, c = 3}, request('nvim_eval', 'g:abc')) + \ }]], + { output = false } + ) + eq({ a = 1, c = 3 }, request('nvim_eval', 'g:abc')) -- try no spaces before continuations to catch off-by-one error - nvim('exec2', 'let ab = #{\n\\a: 98,\n"\\ b: 2\n\\}', { output = false }) - eq({a = 98}, request('nvim_eval', 'g:ab')) + api.nvim_exec2('let ab = #{\n\\a: 98,\n"\\ b: 2\n\\}', { output = false }) + eq({ a = 98 }, request('nvim_eval', 'g:ab')) -- Script scope (s:) - eq({ output = 'ahoy! script-scoped varrrrr' }, nvim('exec2', [[ + eq( + { output = 'ahoy! script-scoped varrrrr' }, + api.nvim_exec2( + [[ let s:pirate = 'script-scoped varrrrr' function! s:avast_ye_hades(s) abort return a:s .. ' ' .. s:pirate endfunction echo <sid>avast_ye_hades('ahoy!') - ]], { output = true })) - - eq({ output = "{'output': 'ahoy! script-scoped varrrrr'}" }, nvim('exec2', [[ + ]], + { output = true } + ) + ) + + eq( + { output = "{'output': 'ahoy! script-scoped varrrrr'}" }, + api.nvim_exec2( + [[ let s:pirate = 'script-scoped varrrrr' function! Avast_ye_hades(s) abort return a:s .. ' ' .. s:pirate endfunction echo nvim_exec2('echo Avast_ye_hades(''ahoy!'')', {'output': v:true}) - ]], { output = true })) - - matches('Vim%(echo%):E121: Undefined variable: s:pirate$', - pcall_err(request, 'nvim_exec2', [[ + ]], + { output = true } + ) + ) + + matches( + 'Vim%(echo%):E121: Undefined variable: s:pirate$', + pcall_err( + request, + 'nvim_exec2', + [[ let s:pirate = 'script-scoped varrrrr' call nvim_exec2('echo s:pirate', {'output': v:true}) - ]], { output = false })) + ]], + { output = false } + ) + ) -- Script items are created only on script var access - eq({ output = '1\n0' }, nvim('exec2', [[ + eq( + { output = '1\n0' }, + api.nvim_exec2( + [[ echo expand("<SID>")->empty() let s:a = 123 echo expand("<SID>")->empty() - ]], { output = true })) - - eq({ output = '1\n0' }, nvim('exec2', [[ + ]], + { output = true } + ) + ) + + eq( + { output = '1\n0' }, + api.nvim_exec2( + [[ echo expand("<SID>")->empty() function s:a() abort endfunction echo expand("<SID>")->empty() - ]], { output = true })) + ]], + { output = true } + ) + ) end) it('non-ASCII input', function() - nvim('exec2', [=[ + api.nvim_exec2( + [=[ new exe "normal! i ax \n Ax " :%s/ax/--a1234--/g | :%s/Ax/--A1234--/g - ]=], { output = false }) - nvim('command', '1') - eq(' --a1234-- ', nvim('get_current_line')) - nvim('command', '2') - eq(' --A1234-- ', nvim('get_current_line')) - - nvim('exec2', [[ + ]=], + { output = false } + ) + command('1') + eq(' --a1234-- ', api.nvim_get_current_line()) + command('2') + eq(' --A1234-- ', api.nvim_get_current_line()) + + api.nvim_exec2( + [[ new call setline(1,['xxx']) call feedkeys('r') call feedkeys('ñ', 'xt') - ]], { output = false }) - eq('ñxx', nvim('get_current_line')) + ]], + { output = false } + ) + eq('ñxx', api.nvim_get_current_line()) end) it('execution error', function() - eq('nvim_exec2(): Vim:E492: Not an editor command: bogus_command', - pcall_err(request, 'nvim_exec2', 'bogus_command', {})) - eq('', nvim('eval', 'v:errmsg')) -- v:errmsg was not updated. + eq( + 'nvim_exec2(): Vim:E492: Not an editor command: bogus_command', + pcall_err(request, 'nvim_exec2', 'bogus_command', {}) + ) + eq('', api.nvim_eval('v:errmsg')) -- v:errmsg was not updated. eq('', eval('v:exception')) - eq('nvim_exec2(): Vim(buffer):E86: Buffer 23487 does not exist', - pcall_err(request, 'nvim_exec2', 'buffer 23487', {})) - eq('', eval('v:errmsg')) -- v:errmsg was not updated. + eq( + 'nvim_exec2(): Vim(buffer):E86: Buffer 23487 does not exist', + pcall_err(request, 'nvim_exec2', 'buffer 23487', {}) + ) + eq('', eval('v:errmsg')) -- v:errmsg was not updated. eq('', eval('v:exception')) end) @@ -240,7 +313,7 @@ describe('API', function() request('nvim_exec2', [[ let x2 = substitute('foo','o','X','g') let x4 = 'should be overwritten' - call nvim_exec2("source ]]..fname..[[\nlet x3 = substitute('foo','foo','set by recursive nvim_exec2','g')\nlet x5='overwritten'\nlet x4=x5\n", {'output': v:false}) + call nvim_exec2("source ]] .. fname .. [[\nlet x3 = substitute('foo','foo','set by recursive nvim_exec2','g')\nlet x5='overwritten'\nlet x4=x5\n", {'output': v:false}) ]], { output = false }) eq('set from :source file', request('nvim_get_var', 'x1')) eq('fXX', request('nvim_get_var', 'x2')) @@ -254,86 +327,108 @@ describe('API', function() local fname = tmpname() write_file(fname, 'echo "hello"\n') local sourcing_fname = tmpname() - write_file(sourcing_fname, 'call nvim_exec2("source '..fname..'", {"output": v:false})\n') - meths.exec2('set verbose=2', { output = false }) - local traceback_output = 'line 0: sourcing "'..sourcing_fname..'"\n'.. - 'line 0: sourcing "'..fname..'"\n'.. - 'hello\n'.. - 'finished sourcing '..fname..'\n'.. - 'continuing in nvim_exec2() called at '..sourcing_fname..':1\n'.. - 'finished sourcing '..sourcing_fname..'\n'.. - 'continuing in nvim_exec2() called at nvim_exec2():0' - eq({ output = traceback_output }, - meths.exec2('call nvim_exec2("source '..sourcing_fname..'", {"output": v:false})', { output = true })) + write_file(sourcing_fname, 'call nvim_exec2("source ' .. fname .. '", {"output": v:false})\n') + api.nvim_exec2('set verbose=2', { output = false }) + local traceback_output = dedent([[ + line 0: sourcing "%s" + line 0: sourcing "%s" + hello + finished sourcing %s + continuing in nvim_exec2() called at %s:1 + finished sourcing %s + continuing in nvim_exec2() called at nvim_exec2():0]]):format( + sourcing_fname, + fname, + fname, + sourcing_fname, + sourcing_fname + ) + eq( + { output = traceback_output }, + api.nvim_exec2( + 'call nvim_exec2("source ' .. sourcing_fname .. '", {"output": v:false})', + { output = true } + ) + ) os.remove(fname) os.remove(sourcing_fname) end) it('returns output', function() - eq({ output = 'this is spinal tap' }, - nvim('exec2', 'lua <<EOF\n\n\nprint("this is spinal tap")\n\n\nEOF', { output = true })) - eq({ output = '' }, nvim('exec2', 'echo', { output = true })) - eq({ output = 'foo 42' }, nvim('exec2', 'echo "foo" 42', { output = true })) + eq( + { output = 'this is spinal tap' }, + api.nvim_exec2('lua <<EOF\n\n\nprint("this is spinal tap")\n\n\nEOF', { output = true }) + ) + eq({ output = '' }, api.nvim_exec2('echo', { output = true })) + eq({ output = 'foo 42' }, api.nvim_exec2('echo "foo" 42', { output = true })) end) it('displays messages when opts.output=false', function() local screen = Screen.new(40, 8) screen:attach() screen:set_default_attr_ids({ - [0] = {bold=true, foreground=Screen.colors.Blue}, + [0] = { bold = true, foreground = Screen.colors.Blue }, }) - meths.exec2("echo 'hello'", { output = false }) - screen:expect{grid=[[ + api.nvim_exec2("echo 'hello'", { output = false }) + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 hello | - ]]} + ]], + } end) - it('doesn\'t display messages when output=true', function() + it("doesn't display messages when output=true", function() local screen = Screen.new(40, 6) screen:attach() screen:set_default_attr_ids({ - [0] = {bold=true, foreground=Screen.colors.Blue}, + [0] = { bold = true, foreground = Screen.colors.Blue }, }) - meths.exec2("echo 'hello'", { output = true }) - screen:expect{grid=[[ + api.nvim_exec2("echo 'hello'", { output = true }) + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | - ]]} + ]], + } exec([[ func Print() call nvim_exec2('echo "hello"', { 'output': v:true }) endfunc ]]) feed([[:echon 1 | call Print() | echon 5<CR>]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 15 | - ]]} + ]], + } + end) + + it('errors properly when command too recursive', function() + exec_lua([[ + _G.success = false + vim.api.nvim_create_user_command('Test', function() + vim.api.nvim_exec2('Test', {}) + _G.success = true + end, {}) + ]]) + pcall_err(command, 'Test') + assert_alive() + eq(false, exec_lua('return _G.success')) end) end) describe('nvim_command', function() it('works', function() local fname = tmpname() - nvim('command', 'new') - nvim('command', 'edit '..fname) - nvim('command', 'normal itesting\napi') - nvim('command', 'w') + command('new') + command('edit ' .. fname) + command('normal itesting\napi') + command('w') local f = assert(io.open(fname)) if is_os('win') then eq('testing\r\napi\r\n', f:read('*a')) @@ -345,158 +440,166 @@ describe('API', function() end) it('Vimscript validation error: fails with specific error', function() - local status, rv = pcall(nvim, "command", "bogus_command") - eq(false, status) -- nvim_command() failed. - eq("E492:", string.match(rv, "E%d*:")) -- Vimscript error was returned. - eq('', nvim('eval', 'v:errmsg')) -- v:errmsg was not updated. + local status, rv = pcall(command, 'bogus_command') + eq(false, status) -- nvim_command() failed. + eq('E492:', string.match(rv, 'E%d*:')) -- Vimscript error was returned. + eq('', api.nvim_eval('v:errmsg')) -- v:errmsg was not updated. eq('', eval('v:exception')) end) it('Vimscript execution error: fails with specific error', function() - local status, rv = pcall(nvim, "command", "buffer 23487") - eq(false, status) -- nvim_command() failed. - eq("E86: Buffer 23487 does not exist", string.match(rv, "E%d*:.*")) - eq('', eval('v:errmsg')) -- v:errmsg was not updated. + local status, rv = pcall(command, 'buffer 23487') + eq(false, status) -- nvim_command() failed. + eq('E86: Buffer 23487 does not exist', string.match(rv, 'E%d*:.*')) + eq('', eval('v:errmsg')) -- v:errmsg was not updated. eq('', eval('v:exception')) end) it('gives E493 instead of prompting on backwards range', function() command('split') - eq('Vim(windo):E493: Backwards range given: 2,1windo echo', - pcall_err(command, '2,1windo echo')) + eq( + 'Vim(windo):E493: Backwards range given: 2,1windo echo', + pcall_err(command, '2,1windo echo') + ) end) end) describe('nvim_command_output', function() it('does not induce hit-enter prompt', function() - nvim("ui_attach", 80, 20, {}) + api.nvim_ui_attach(80, 20, {}) -- Induce a hit-enter prompt use nvim_input (non-blocking). - nvim('command', 'set cmdheight=1') - nvim('input', [[:echo "hi\nhi2"<CR>]]) + command('set cmdheight=1') + api.nvim_input([[:echo "hi\nhi2"<CR>]]) -- Verify hit-enter prompt. - eq({mode='r', blocking=true}, nvim("get_mode")) - nvim('input', [[<C-c>]]) + eq({ mode = 'r', blocking = true }, api.nvim_get_mode()) + api.nvim_input([[<C-c>]]) -- Verify NO hit-enter prompt. - nvim('command_output', [[echo "hi\nhi2"]]) - eq({mode='n', blocking=false}, nvim("get_mode")) + command_output([[echo "hi\nhi2"]]) + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) end) it('captures command output', function() - eq('this is\nspinal tap', - nvim('command_output', [[echo "this is\nspinal tap"]])) - eq('no line ending!', - nvim('command_output', [[echon "no line ending!"]])) + eq('this is\nspinal tap', command_output([[echo "this is\nspinal tap"]])) + eq('no line ending!', command_output([[echon "no line ending!"]])) end) it('captures empty command output', function() - eq('', nvim('command_output', 'echo')) + eq('', command_output('echo')) end) it('captures single-char command output', function() - eq('x', nvim('command_output', 'echo "x"')) + eq('x', command_output('echo "x"')) end) it('captures multiple commands', function() - eq('foo\n 1 %a "[No Name]" line 1', - nvim('command_output', 'echo "foo" | ls')) + eq('foo\n 1 %a "[No Name]" line 1', command_output('echo "foo" | ls')) end) it('captures nested execute()', function() - eq('\nnested1\nnested2\n 1 %a "[No Name]" line 1', - nvim('command_output', - [[echo execute('echo "nested1\nnested2"') | ls]])) + eq( + '\nnested1\nnested2\n 1 %a "[No Name]" line 1', + command_output([[echo execute('echo "nested1\nnested2"') | ls]]) + ) end) it('captures nested nvim_command_output()', function() - eq('nested1\nnested2\n 1 %a "[No Name]" line 1', - nvim('command_output', - [[echo nvim_command_output('echo "nested1\nnested2"') | ls]])) + eq( + 'nested1\nnested2\n 1 %a "[No Name]" line 1', + command_output([[echo nvim_command_output('echo "nested1\nnested2"') | ls]]) + ) end) it('returns shell |:!| output', function() local win_lf = is_os('win') and '\r' or '' - eq(':!echo foo\r\n\nfoo'..win_lf..'\n', nvim('command_output', [[!echo foo]])) + eq(':!echo foo\r\n\nfoo' .. win_lf .. '\n', command_output([[!echo foo]])) end) it('Vimscript validation error: fails with specific error', function() - local status, rv = pcall(nvim, "command_output", "bogus commannnd") - eq(false, status) -- nvim_command_output() failed. - eq("E492: Not an editor command: bogus commannnd", - string.match(rv, "E%d*:.*")) - eq('', eval('v:errmsg')) -- v:errmsg was not updated. + local status, rv = pcall(command_output, 'bogus commannnd') + eq(false, status) -- nvim_command_output() failed. + eq('E492: Not an editor command: bogus commannnd', string.match(rv, 'E%d*:.*')) + eq('', eval('v:errmsg')) -- v:errmsg was not updated. -- Verify NO hit-enter prompt. - eq({mode='n', blocking=false}, nvim("get_mode")) + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) end) it('Vimscript execution error: fails with specific error', function() - local status, rv = pcall(nvim, "command_output", "buffer 42") - eq(false, status) -- nvim_command_output() failed. - eq("E86: Buffer 42 does not exist", string.match(rv, "E%d*:.*")) - eq('', eval('v:errmsg')) -- v:errmsg was not updated. + local status, rv = pcall(command_output, 'buffer 42') + eq(false, status) -- nvim_command_output() failed. + eq('E86: Buffer 42 does not exist', string.match(rv, 'E%d*:.*')) + eq('', eval('v:errmsg')) -- v:errmsg was not updated. -- Verify NO hit-enter prompt. - eq({mode='n', blocking=false}, nvim("get_mode")) + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) end) it('does not cause heap buffer overflow with large output', function() - eq(eval('string(range(1000000))'), - nvim('command_output', 'echo range(1000000)')) + eq(eval('string(range(1000000))'), command_output('echo range(1000000)')) end) end) describe('nvim_eval', function() it('works', function() - nvim('command', 'let g:v1 = "a"') - nvim('command', 'let g:v2 = [1, 2, {"v3": 3}]') - eq({v1 = 'a', v2 = { 1, 2, { v3 = 3 } } }, nvim('eval', 'g:')) + command('let g:v1 = "a"') + command('let g:v2 = [1, 2, {"v3": 3}]') + eq({ v1 = 'a', v2 = { 1, 2, { v3 = 3 } } }, api.nvim_eval('g:')) end) it('handles NULL-initialized strings correctly', function() - eq(1, nvim('eval',"matcharg(1) == ['', '']")) - eq({'', ''}, nvim('eval','matcharg(1)')) + eq(1, api.nvim_eval("matcharg(1) == ['', '']")) + eq({ '', '' }, api.nvim_eval('matcharg(1)')) end) it('works under deprecated name', function() - eq(2, request("vim_eval", "1+1")) + eq(2, request('vim_eval', '1+1')) end) - it("Vimscript error: returns error details, does NOT update v:errmsg", function() - eq('Vim:E121: Undefined variable: bogus', - pcall_err(request, 'nvim_eval', 'bogus expression')) - eq('', eval('v:errmsg')) -- v:errmsg was not updated. + it('Vimscript error: returns error details, does NOT update v:errmsg', function() + eq('Vim:E121: Undefined variable: bogus', pcall_err(request, 'nvim_eval', 'bogus expression')) + eq('', eval('v:errmsg')) -- v:errmsg was not updated. end) end) describe('nvim_call_function', function() it('works', function() - nvim('call_function', 'setqflist', { { { filename = 'something', lnum = 17 } }, 'r' }) - eq(17, nvim('call_function', 'getqflist', {})[1].lnum) - eq(17, nvim('call_function', 'eval', {17})) - eq('foo', nvim('call_function', 'simplify', {'this/./is//redundant/../../../foo'})) - end) - - it("Vimscript validation error: returns specific error, does NOT update v:errmsg", function() - eq('Vim:E117: Unknown function: bogus function', - pcall_err(request, 'nvim_call_function', 'bogus function', {'arg1'})) - eq('Vim:E119: Not enough arguments for function: atan', - pcall_err(request, 'nvim_call_function', 'atan', {})) + api.nvim_call_function('setqflist', { { { filename = 'something', lnum = 17 } }, 'r' }) + eq(17, api.nvim_call_function('getqflist', {})[1].lnum) + eq(17, api.nvim_call_function('eval', { 17 })) + eq('foo', api.nvim_call_function('simplify', { 'this/./is//redundant/../../../foo' })) + end) + + it('Vimscript validation error: returns specific error, does NOT update v:errmsg', function() + eq( + 'Vim:E117: Unknown function: bogus function', + pcall_err(request, 'nvim_call_function', 'bogus function', { 'arg1' }) + ) + eq( + 'Vim:E119: Not enough arguments for function: atan', + pcall_err(request, 'nvim_call_function', 'atan', {}) + ) eq('', eval('v:exception')) - eq('', eval('v:errmsg')) -- v:errmsg was not updated. - end) - - it("Vimscript error: returns error details, does NOT update v:errmsg", function() - eq('Vim:E808: Number or Float required', - pcall_err(request, 'nvim_call_function', 'atan', {'foo'})) - eq('Vim:Invalid channel stream "xxx"', - pcall_err(request, 'nvim_call_function', 'chanclose', {999, 'xxx'})) - eq('Vim:E900: Invalid channel id', - pcall_err(request, 'nvim_call_function', 'chansend', {999, 'foo'})) + eq('', eval('v:errmsg')) -- v:errmsg was not updated. + end) + + it('Vimscript error: returns error details, does NOT update v:errmsg', function() + eq( + 'Vim:E808: Number or Float required', + pcall_err(request, 'nvim_call_function', 'atan', { 'foo' }) + ) + eq( + 'Vim:Invalid channel stream "xxx"', + pcall_err(request, 'nvim_call_function', 'chanclose', { 999, 'xxx' }) + ) + eq( + 'Vim:E900: Invalid channel id', + pcall_err(request, 'nvim_call_function', 'chansend', { 999, 'foo' }) + ) eq('', eval('v:exception')) - eq('', eval('v:errmsg')) -- v:errmsg was not updated. + eq('', eval('v:errmsg')) -- v:errmsg was not updated. end) - it("Vimscript exception: returns exception details, does NOT update v:errmsg", function() + it('Vimscript exception: returns exception details, does NOT update v:errmsg', function() source([[ function! Foo() abort throw 'wtf' @@ -504,10 +607,11 @@ describe('API', function() ]]) eq('function Foo, line 1: wtf', pcall_err(request, 'nvim_call_function', 'Foo', {})) eq('', eval('v:exception')) - eq('', eval('v:errmsg')) -- v:errmsg was not updated. + eq('', eval('v:errmsg')) -- v:errmsg was not updated. end) it('validation', function() + -- stylua: ignore local too_many_args = { 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x' } source([[ function! Foo(...) abort @@ -515,8 +619,10 @@ describe('API', function() endfunction ]]) -- E740 - eq('Function called with too many arguments', - pcall_err(request, 'nvim_call_function', 'Foo', too_many_args)) + eq( + 'Function called with too many arguments', + pcall_err(request, 'nvim_call_function', 'Foo', too_many_args) + ) end) end) @@ -535,40 +641,55 @@ describe('API', function() ]]) -- :help Dictionary-function - eq('Hello, World!', nvim('call_dict_function', 'g:test_dict_fn', 'F', {'World'})) + eq('Hello, World!', api.nvim_call_dict_function('g:test_dict_fn', 'F', { 'World' })) -- Funcref is sent as NIL over RPC. - eq({ greeting = 'Hello', F = NIL }, nvim('get_var', 'test_dict_fn')) + eq({ greeting = 'Hello', F = NIL }, api.nvim_get_var('test_dict_fn')) -- :help numbered-function - eq('Hi, Moon ...', nvim('call_dict_function', 'g:test_dict_fn2', 'F2', {'Moon'})) + eq('Hi, Moon ...', api.nvim_call_dict_function('g:test_dict_fn2', 'F2', { 'Moon' })) -- Funcref is sent as NIL over RPC. - eq({ greeting = 'Hi', F2 = NIL }, nvim('get_var', 'test_dict_fn2')) + eq({ greeting = 'Hi', F2 = NIL }, api.nvim_get_var('test_dict_fn2')) -- Function specified via RPC dict. source('function! G() dict\n return "@".(self.result)."@"\nendfunction') - eq('@it works@', nvim('call_dict_function', { result = 'it works', G = 'G'}, 'G', {})) + eq('@it works@', api.nvim_call_dict_function({ result = 'it works', G = 'G' }, 'G', {})) end) it('validation', function() command('let g:d={"baz":"zub","meep":[]}') - eq('Not found: bogus', - pcall_err(request, 'nvim_call_dict_function', 'g:d', 'bogus', {1,2})) - eq('Not a function: baz', - pcall_err(request, 'nvim_call_dict_function', 'g:d', 'baz', {1,2})) - eq('Not a function: meep', - pcall_err(request, 'nvim_call_dict_function', 'g:d', 'meep', {1,2})) - eq('Vim:E117: Unknown function: f', - pcall_err(request, 'nvim_call_dict_function', { f = '' }, 'f', {1,2})) - eq('Not a function: f', - pcall_err(request, 'nvim_call_dict_function', "{ 'f': '' }", 'f', {1,2})) - eq('dict argument type must be String or Dictionary', - pcall_err(request, 'nvim_call_dict_function', 42, 'f', {1,2})) - eq('Failed to evaluate dict expression', - pcall_err(request, 'nvim_call_dict_function', 'foo', 'f', {1,2})) - eq('dict not found', - pcall_err(request, 'nvim_call_dict_function', '42', 'f', {1,2})) - eq('Invalid (empty) function name', - pcall_err(request, 'nvim_call_dict_function', "{ 'f': '' }", '', {1,2})) + eq( + 'Not found: bogus', + pcall_err(request, 'nvim_call_dict_function', 'g:d', 'bogus', { 1, 2 }) + ) + eq( + 'Not a function: baz', + pcall_err(request, 'nvim_call_dict_function', 'g:d', 'baz', { 1, 2 }) + ) + eq( + 'Not a function: meep', + pcall_err(request, 'nvim_call_dict_function', 'g:d', 'meep', { 1, 2 }) + ) + eq( + 'Vim:E117: Unknown function: f', + pcall_err(request, 'nvim_call_dict_function', { f = '' }, 'f', { 1, 2 }) + ) + eq( + 'Not a function: f', + pcall_err(request, 'nvim_call_dict_function', "{ 'f': '' }", 'f', { 1, 2 }) + ) + eq( + 'dict argument type must be String or Dictionary', + pcall_err(request, 'nvim_call_dict_function', 42, 'f', { 1, 2 }) + ) + eq( + 'Failed to evaluate dict expression', + pcall_err(request, 'nvim_call_dict_function', 'foo', 'f', { 1, 2 }) + ) + eq('dict not found', pcall_err(request, 'nvim_call_dict_function', '42', 'f', { 1, 2 })) + eq( + 'Invalid (empty) function name', + pcall_err(request, 'nvim_call_dict_function', "{ 'f': '' }", '', { 1, 2 }) + ) end) end) @@ -576,85 +697,95 @@ describe('API', function() local start_dir before_each(function() - funcs.mkdir("Xtestdir") - start_dir = funcs.getcwd() + fn.mkdir('Xtestdir') + start_dir = fn.getcwd() end) after_each(function() - helpers.rmdir("Xtestdir") + helpers.rmdir('Xtestdir') end) it('works', function() - meths.set_current_dir("Xtestdir") - eq(funcs.getcwd(), start_dir .. helpers.get_pathsep() .. "Xtestdir") + api.nvim_set_current_dir('Xtestdir') + eq(fn.getcwd(), start_dir .. helpers.get_pathsep() .. 'Xtestdir') end) it('sets previous directory', function() - meths.set_current_dir("Xtestdir") + api.nvim_set_current_dir('Xtestdir') command('cd -') - eq(funcs.getcwd(), start_dir) + eq(fn.getcwd(), start_dir) end) end) describe('nvim_exec_lua', function() it('works', function() - meths.exec_lua('vim.api.nvim_set_var("test", 3)', {}) - eq(3, meths.get_var('test')) + api.nvim_exec_lua('vim.api.nvim_set_var("test", 3)', {}) + eq(3, api.nvim_get_var('test')) - eq(17, meths.exec_lua('a, b = ...\nreturn a + b', {10,7})) + eq(17, api.nvim_exec_lua('a, b = ...\nreturn a + b', { 10, 7 })) - eq(NIL, meths.exec_lua('function xx(a,b)\nreturn a..b\nend',{})) - eq("xy", meths.exec_lua('return xx(...)', {'x','y'})) + eq(NIL, api.nvim_exec_lua('function xx(a,b)\nreturn a..b\nend', {})) + eq('xy', api.nvim_exec_lua('return xx(...)', { 'x', 'y' })) -- Deprecated name: nvim_execute_lua. - eq("xy", meths.execute_lua('return xx(...)', {'x','y'})) + eq('xy', api.nvim_execute_lua('return xx(...)', { 'x', 'y' })) end) it('reports errors', function() - eq([[Error loading lua: [string "<nvim>"]:0: '=' expected near '+']], - pcall_err(meths.exec_lua, 'a+*b', {})) + eq( + [[Error loading lua: [string "<nvim>"]:0: '=' expected near '+']], + pcall_err(api.nvim_exec_lua, 'a+*b', {}) + ) - eq([[Error loading lua: [string "<nvim>"]:0: unexpected symbol near '1']], - pcall_err(meths.exec_lua, '1+2', {})) + eq( + [[Error loading lua: [string "<nvim>"]:0: unexpected symbol near '1']], + pcall_err(api.nvim_exec_lua, '1+2', {}) + ) - eq([[Error loading lua: [string "<nvim>"]:0: unexpected symbol]], - pcall_err(meths.exec_lua, 'aa=bb\0', {})) + eq( + [[Error loading lua: [string "<nvim>"]:0: unexpected symbol]], + pcall_err(api.nvim_exec_lua, 'aa=bb\0', {}) + ) - eq([[attempt to call global 'bork' (a nil value)]], - pcall_err(meths.exec_lua, 'bork()', {})) + eq( + [[attempt to call global 'bork' (a nil value)]], + pcall_err(api.nvim_exec_lua, 'bork()', {}) + ) - eq('did\nthe\nfail', - pcall_err(meths.exec_lua, 'error("did\\nthe\\nfail")', {})) + eq('did\nthe\nfail', pcall_err(api.nvim_exec_lua, 'error("did\\nthe\\nfail")', {})) end) it('uses native float values', function() - eq(2.5, meths.exec_lua("return select(1, ...)", {2.5})) - eq("2.5", meths.exec_lua("return vim.inspect(...)", {2.5})) + eq(2.5, api.nvim_exec_lua('return select(1, ...)', { 2.5 })) + eq('2.5', api.nvim_exec_lua('return vim.inspect(...)', { 2.5 })) -- "special" float values are still accepted as return values. - eq(2.5, meths.exec_lua("return vim.api.nvim_eval('2.5')", {})) - eq("{\n [false] = 2.5,\n [true] = 3\n}", meths.exec_lua("return vim.inspect(vim.api.nvim_eval('2.5'))", {})) + eq(2.5, api.nvim_exec_lua("return vim.api.nvim_eval('2.5')", {})) + eq( + '{\n [false] = 2.5,\n [true] = 3\n}', + api.nvim_exec_lua("return vim.inspect(vim.api.nvim_eval('2.5'))", {}) + ) end) end) describe('nvim_notify', function() it('can notify a info message', function() - nvim("notify", "hello world", 2, {}) + api.nvim_notify('hello world', 2, {}) end) it('can be overridden', function() - command("lua vim.notify = function(...) return 42 end") - eq(42, meths.exec_lua("return vim.notify('Hello world')", {})) - nvim("notify", "hello world", 4, {}) + command('lua vim.notify = function(...) return 42 end') + eq(42, api.nvim_exec_lua("return vim.notify('Hello world')", {})) + api.nvim_notify('hello world', 4, {}) end) end) describe('nvim_input', function() - it("Vimscript error: does NOT fail, updates v:errmsg", function() - local status, _ = pcall(nvim, "input", ":call bogus_fn()<CR>") - local v_errnum = string.match(nvim("eval", "v:errmsg"), "E%d*:") - eq(true, status) -- nvim_input() did not fail. - eq("E117:", v_errnum) -- v:errmsg was updated. + it('Vimscript error: does NOT fail, updates v:errmsg', function() + local status, _ = pcall(api.nvim_input, ':call bogus_fn()<CR>') + local v_errnum = string.match(api.nvim_eval('v:errmsg'), 'E%d*:') + eq(true, status) -- nvim_input() did not fail. + eq('E117:', v_errnum) -- v:errmsg was updated. end) it('does not crash even if trans_special result is largest #11788, #12287', function() @@ -665,30 +796,28 @@ describe('API', function() describe('nvim_paste', function() it('validation', function() - eq("Invalid 'phase': -2", - pcall_err(request, 'nvim_paste', 'foo', true, -2)) - eq("Invalid 'phase': 4", - pcall_err(request, 'nvim_paste', 'foo', true, 4)) + eq("Invalid 'phase': -2", pcall_err(request, 'nvim_paste', 'foo', true, -2)) + eq("Invalid 'phase': 4", pcall_err(request, 'nvim_paste', 'foo', true, 4)) end) local function run_streamed_paste_tests() it('stream: multiple chunks form one undo-block', function() - nvim('paste', '1/chunk 1 (start)\n', true, 1) - nvim('paste', '1/chunk 2 (end)\n', true, 3) + api.nvim_paste('1/chunk 1 (start)\n', true, 1) + api.nvim_paste('1/chunk 2 (end)\n', true, 3) local expected1 = [[ 1/chunk 1 (start) 1/chunk 2 (end) ]] expect(expected1) - nvim('paste', '2/chunk 1 (start)\n', true, 1) - nvim('paste', '2/chunk 2\n', true, 2) + api.nvim_paste('2/chunk 1 (start)\n', true, 1) + api.nvim_paste('2/chunk 2\n', true, 2) expect([[ 1/chunk 1 (start) 1/chunk 2 (end) 2/chunk 1 (start) 2/chunk 2 ]]) - nvim('paste', '2/chunk 3\n', true, 2) - nvim('paste', '2/chunk 4 (end)\n', true, 3) + api.nvim_paste('2/chunk 3\n', true, 2) + api.nvim_paste('2/chunk 4 (end)\n', true, 3) expect([[ 1/chunk 1 (start) 1/chunk 2 (end) @@ -697,17 +826,17 @@ describe('API', function() 2/chunk 3 2/chunk 4 (end) ]]) - feed('u') -- Undo. + feed('u') -- Undo. expect(expected1) end) it('stream: Insert mode', function() -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. feed('afoo<Esc>u') feed('i') - nvim('paste', 'aaaaaa', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) + api.nvim_paste('aaaaaa', false, 1) + api.nvim_paste('bbbbbb', false, 2) + api.nvim_paste('cccccc', false, 2) + api.nvim_paste('dddddd', false, 3) expect('aaaaaabbbbbbccccccdddddd') feed('<Esc>u') expect('') @@ -723,17 +852,17 @@ describe('API', function() expect('') end) it('pasting one line', function() - nvim('paste', 'aaaaaa', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) + api.nvim_paste('aaaaaa', false, 1) + api.nvim_paste('bbbbbb', false, 2) + api.nvim_paste('cccccc', false, 2) + api.nvim_paste('dddddd', false, 3) expect('aaaaaabbbbbbccccccdddddd') end) it('pasting multiple lines', function() - nvim('paste', 'aaaaaa\n', false, 1) - nvim('paste', 'bbbbbb\n', false, 2) - nvim('paste', 'cccccc\n', false, 2) - nvim('paste', 'dddddd', false, 3) + api.nvim_paste('aaaaaa\n', false, 1) + api.nvim_paste('bbbbbb\n', false, 2) + api.nvim_paste('cccccc\n', false, 2) + api.nvim_paste('dddddd', false, 3) expect([[ aaaaaa bbbbbb @@ -753,17 +882,17 @@ describe('API', function() expect('||') end) it('pasting one line', function() - nvim('paste', 'aaaaaa', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) + api.nvim_paste('aaaaaa', false, 1) + api.nvim_paste('bbbbbb', false, 2) + api.nvim_paste('cccccc', false, 2) + api.nvim_paste('dddddd', false, 3) expect('|aaaaaabbbbbbccccccdddddd|') end) it('pasting multiple lines', function() - nvim('paste', 'aaaaaa\n', false, 1) - nvim('paste', 'bbbbbb\n', false, 2) - nvim('paste', 'cccccc\n', false, 2) - nvim('paste', 'dddddd', false, 3) + api.nvim_paste('aaaaaa\n', false, 1) + api.nvim_paste('bbbbbb\n', false, 2) + api.nvim_paste('cccccc\n', false, 2) + api.nvim_paste('dddddd', false, 3) expect([[ |aaaaaa bbbbbb @@ -783,17 +912,17 @@ describe('API', function() expect('||') end) it('pasting one line', function() - nvim('paste', 'aaaaaa', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) + api.nvim_paste('aaaaaa', false, 1) + api.nvim_paste('bbbbbb', false, 2) + api.nvim_paste('cccccc', false, 2) + api.nvim_paste('dddddd', false, 3) expect('||aaaaaabbbbbbccccccdddddd') end) it('pasting multiple lines', function() - nvim('paste', 'aaaaaa\n', false, 1) - nvim('paste', 'bbbbbb\n', false, 2) - nvim('paste', 'cccccc\n', false, 2) - nvim('paste', 'dddddd', false, 3) + api.nvim_paste('aaaaaa\n', false, 1) + api.nvim_paste('bbbbbb\n', false, 2) + api.nvim_paste('cccccc\n', false, 2) + api.nvim_paste('dddddd', false, 3) expect([[ ||aaaaaa bbbbbb @@ -817,24 +946,24 @@ describe('API', function() xxx|]]) end) it('with non-empty chunks', function() - nvim('paste', 'aaaaaa', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) + api.nvim_paste('aaaaaa', false, 1) + api.nvim_paste('bbbbbb', false, 2) + api.nvim_paste('cccccc', false, 2) + api.nvim_paste('dddddd', false, 3) expect('|aaaaaabbbbbbccccccdddddd|') end) it('with empty first chunk', function() - nvim('paste', '', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) + api.nvim_paste('', false, 1) + api.nvim_paste('bbbbbb', false, 2) + api.nvim_paste('cccccc', false, 2) + api.nvim_paste('dddddd', false, 3) expect('|bbbbbbccccccdddddd|') end) it('with all chunks empty', function() - nvim('paste', '', false, 1) - nvim('paste', '', false, 2) - nvim('paste', '', false, 2) - nvim('paste', '', false, 3) + api.nvim_paste('', false, 1) + api.nvim_paste('', false, 2) + api.nvim_paste('', false, 2) + api.nvim_paste('', false, 3) expect('||') end) end) @@ -852,17 +981,17 @@ describe('API', function() xxx]]) end) it('with non-empty chunks', function() - nvim('paste', 'aaaaaa', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) + api.nvim_paste('aaaaaa', false, 1) + api.nvim_paste('bbbbbb', false, 2) + api.nvim_paste('cccccc', false, 2) + api.nvim_paste('dddddd', false, 3) expect('||aaaaaabbbbbbccccccdddddd') end) it('with empty first chunk', function() - nvim('paste', '', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) + api.nvim_paste('', false, 1) + api.nvim_paste('bbbbbb', false, 2) + api.nvim_paste('cccccc', false, 2) + api.nvim_paste('dddddd', false, 3) expect('||bbbbbbccccccdddddd') end) end) @@ -880,17 +1009,17 @@ describe('API', function() xxx]]) end) it('with non-empty chunks', function() - nvim('paste', 'aaaaaa', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) + api.nvim_paste('aaaaaa', false, 1) + api.nvim_paste('bbbbbb', false, 2) + api.nvim_paste('cccccc', false, 2) + api.nvim_paste('dddddd', false, 3) expect('||aaaaaabbbbbbccccccdddddd') end) it('with empty first chunk', function() - nvim('paste', '', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) + api.nvim_paste('', false, 1) + api.nvim_paste('bbbbbb', false, 2) + api.nvim_paste('cccccc', false, 2) + api.nvim_paste('dddddd', false, 3) expect('||bbbbbbccccccdddddd') end) end) @@ -913,10 +1042,10 @@ describe('API', function() feed('ggV') end) it('pasting text without final new line', function() - nvim('paste', 'aaaaaa\n', false, 1) - nvim('paste', 'bbbbbb\n', false, 2) - nvim('paste', 'cccccc\n', false, 2) - nvim('paste', 'dddddd', false, 3) + api.nvim_paste('aaaaaa\n', false, 1) + api.nvim_paste('bbbbbb\n', false, 2) + api.nvim_paste('cccccc\n', false, 2) + api.nvim_paste('dddddd', false, 3) expect([[ aaaaaa bbbbbb @@ -925,10 +1054,10 @@ describe('API', function() 123456789]]) end) it('pasting text with final new line', function() - nvim('paste', 'aaaaaa\n', false, 1) - nvim('paste', 'bbbbbb\n', false, 2) - nvim('paste', 'cccccc\n', false, 2) - nvim('paste', 'dddddd\n', false, 3) + api.nvim_paste('aaaaaa\n', false, 1) + api.nvim_paste('bbbbbb\n', false, 2) + api.nvim_paste('cccccc\n', false, 2) + api.nvim_paste('dddddd\n', false, 3) expect([[ aaaaaa bbbbbb @@ -943,10 +1072,10 @@ describe('API', function() feed('2ggV') end) it('pasting text without final new line', function() - nvim('paste', 'aaaaaa\n', false, 1) - nvim('paste', 'bbbbbb\n', false, 2) - nvim('paste', 'cccccc\n', false, 2) - nvim('paste', 'dddddd', false, 3) + api.nvim_paste('aaaaaa\n', false, 1) + api.nvim_paste('bbbbbb\n', false, 2) + api.nvim_paste('cccccc\n', false, 2) + api.nvim_paste('dddddd', false, 3) expect([[ 123456789 aaaaaa @@ -955,10 +1084,10 @@ describe('API', function() dddddd123456789]]) end) it('pasting text with final new line', function() - nvim('paste', 'aaaaaa\n', false, 1) - nvim('paste', 'bbbbbb\n', false, 2) - nvim('paste', 'cccccc\n', false, 2) - nvim('paste', 'dddddd\n', false, 3) + api.nvim_paste('aaaaaa\n', false, 1) + api.nvim_paste('bbbbbb\n', false, 2) + api.nvim_paste('cccccc\n', false, 2) + api.nvim_paste('dddddd\n', false, 3) expect([[ 123456789 aaaaaa @@ -973,10 +1102,10 @@ describe('API', function() feed('3ggV') end) it('pasting text without final new line', function() - nvim('paste', 'aaaaaa\n', false, 1) - nvim('paste', 'bbbbbb\n', false, 2) - nvim('paste', 'cccccc\n', false, 2) - nvim('paste', 'dddddd', false, 3) + api.nvim_paste('aaaaaa\n', false, 1) + api.nvim_paste('bbbbbb\n', false, 2) + api.nvim_paste('cccccc\n', false, 2) + api.nvim_paste('dddddd', false, 3) expect([[ 123456789 987654321 @@ -986,10 +1115,10 @@ describe('API', function() dddddd]]) end) it('pasting text with final new line', function() - nvim('paste', 'aaaaaa\n', false, 1) - nvim('paste', 'bbbbbb\n', false, 2) - nvim('paste', 'cccccc\n', false, 2) - nvim('paste', 'dddddd\n', false, 3) + api.nvim_paste('aaaaaa\n', false, 1) + api.nvim_paste('bbbbbb\n', false, 2) + api.nvim_paste('cccccc\n', false, 2) + api.nvim_paste('dddddd\n', false, 3) expect([[ 123456789 987654321 @@ -1005,10 +1134,10 @@ describe('API', function() feed('ggVG') end) it('pasting text without final new line', function() - nvim('paste', 'aaaaaa\n', false, 1) - nvim('paste', 'bbbbbb\n', false, 2) - nvim('paste', 'cccccc\n', false, 2) - nvim('paste', 'dddddd', false, 3) + api.nvim_paste('aaaaaa\n', false, 1) + api.nvim_paste('bbbbbb\n', false, 2) + api.nvim_paste('cccccc\n', false, 2) + api.nvim_paste('dddddd', false, 3) expect([[ aaaaaa bbbbbb @@ -1016,10 +1145,10 @@ describe('API', function() dddddd]]) end) it('pasting text with final new line', function() - nvim('paste', 'aaaaaa\n', false, 1) - nvim('paste', 'bbbbbb\n', false, 2) - nvim('paste', 'cccccc\n', false, 2) - nvim('paste', 'dddddd\n', false, 3) + api.nvim_paste('aaaaaa\n', false, 1) + api.nvim_paste('bbbbbb\n', false, 2) + api.nvim_paste('cccccc\n', false, 2) + api.nvim_paste('dddddd\n', false, 3) expect([[ aaaaaa bbbbbb @@ -1041,71 +1170,71 @@ describe('API', function() end) it('non-streaming', function() -- With final "\n". - nvim('paste', 'line 1\nline 2\nline 3\n', true, -1) + api.nvim_paste('line 1\nline 2\nline 3\n', true, -1) expect([[ line 1 line 2 line 3 ]]) - eq({0,4,1,0}, funcs.getpos('.')) -- Cursor follows the paste. - eq(false, nvim('get_option_value', 'paste', {})) + eq({ 0, 4, 1, 0 }, fn.getpos('.')) -- Cursor follows the paste. + eq(false, api.nvim_get_option_value('paste', {})) command('%delete _') -- Without final "\n". - nvim('paste', 'line 1\nline 2\nline 3', true, -1) + api.nvim_paste('line 1\nline 2\nline 3', true, -1) expect([[ line 1 line 2 line 3]]) - eq({0,3,6,0}, funcs.getpos('.')) + eq({ 0, 3, 6, 0 }, fn.getpos('.')) command('%delete _') -- CRLF #10872 - nvim('paste', 'line 1\r\nline 2\r\nline 3\r\n', true, -1) + api.nvim_paste('line 1\r\nline 2\r\nline 3\r\n', true, -1) expect([[ line 1 line 2 line 3 ]]) - eq({0,4,1,0}, funcs.getpos('.')) + eq({ 0, 4, 1, 0 }, fn.getpos('.')) command('%delete _') -- CRLF without final "\n". - nvim('paste', 'line 1\r\nline 2\r\nline 3\r', true, -1) + api.nvim_paste('line 1\r\nline 2\r\nline 3\r', true, -1) expect([[ line 1 line 2 line 3 ]]) - eq({0,4,1,0}, funcs.getpos('.')) + eq({ 0, 4, 1, 0 }, fn.getpos('.')) command('%delete _') -- CRLF without final "\r\n". - nvim('paste', 'line 1\r\nline 2\r\nline 3', true, -1) + api.nvim_paste('line 1\r\nline 2\r\nline 3', true, -1) expect([[ line 1 line 2 line 3]]) - eq({0,3,6,0}, funcs.getpos('.')) + eq({ 0, 3, 6, 0 }, fn.getpos('.')) command('%delete _') -- Various other junk. - nvim('paste', 'line 1\r\n\r\rline 2\nline 3\rline 4\r', true, -1) + api.nvim_paste('line 1\r\n\r\rline 2\nline 3\rline 4\r', true, -1) expect('line 1\n\n\nline 2\nline 3\nline 4\n') - eq({0,7,1,0}, funcs.getpos('.')) - eq(false, nvim('get_option_value', 'paste', {})) + eq({ 0, 7, 1, 0 }, fn.getpos('.')) + eq(false, api.nvim_get_option_value('paste', {})) end) it('Replace-mode', function() -- Within single line - nvim('put', {'aabbccdd', 'eeffgghh', 'iijjkkll'}, "c", true, false) + api.nvim_put({ 'aabbccdd', 'eeffgghh', 'iijjkkll' }, 'c', true, false) command('normal l') command('startreplace') - nvim('paste', '123456', true, -1) + api.nvim_paste('123456', true, -1) expect([[ a123456d eeffgghh iijjkkll]]) command('%delete _') -- Across lines - nvim('put', {'aabbccdd', 'eeffgghh', 'iijjkkll'}, "c", true, false) + api.nvim_put({ 'aabbccdd', 'eeffgghh', 'iijjkkll' }, 'c', true, false) command('normal l') command('startreplace') - nvim('paste', '123\n456', true, -1) + api.nvim_paste('123\n456', true, -1) expect([[ a123 456d @@ -1114,34 +1243,33 @@ describe('API', function() end) it('when searching in Visual mode', function() feed('v/') - nvim('paste', 'aabbccdd', true, -1) - eq('aabbccdd', funcs.getcmdline()) + api.nvim_paste('aabbccdd', true, -1) + eq('aabbccdd', fn.getcmdline()) expect('') end) it('mappings are disabled in Cmdline mode', function() command('cnoremap a b') feed(':') - nvim('paste', 'a', true, -1) - eq('a', funcs.getcmdline()) + api.nvim_paste('a', true, -1) + eq('a', fn.getcmdline()) end) it('pasted text is saved in cmdline history when <CR> comes from mapping #20957', function() command('cnoremap <CR> <CR>') feed(':') - nvim('paste', 'echo', true, -1) - eq('', funcs.histget(':')) + api.nvim_paste('echo', true, -1) + eq('', fn.histget(':')) feed('<CR>') - eq('echo', funcs.histget(':')) + eq('echo', fn.histget(':')) end) it('pasting with empty last chunk in Cmdline mode', function() local screen = Screen.new(20, 4) screen:attach() feed(':') - nvim('paste', 'Foo', true, 1) - nvim('paste', '', true, 3) + api.nvim_paste('Foo', true, 1) + api.nvim_paste('', true, 3) screen:expect([[ | - ~ | - ~ | + ~ |*2 :Foo^ | ]]) end) @@ -1149,112 +1277,113 @@ describe('API', function() local screen = Screen.new(20, 4) screen:attach() feed(':') - nvim('paste', 'normal! \023\022\006\027', true, -1) + api.nvim_paste('normal! \023\022\006\027', true, -1) screen:expect([[ | - ~ | - ~ | + ~ |*2 :normal! ^W^V^F^[^ | ]]) end) it('crlf=false does not break lines at CR, CRLF', function() - nvim('paste', 'line 1\r\n\r\rline 2\nline 3\rline 4\r', false, -1) + api.nvim_paste('line 1\r\n\r\rline 2\nline 3\rline 4\r', false, -1) expect('line 1\r\n\r\rline 2\nline 3\rline 4\r') - eq({0,3,14,0}, funcs.getpos('.')) + eq({ 0, 3, 14, 0 }, fn.getpos('.')) end) it('vim.paste() failure', function() - nvim('exec_lua', 'vim.paste = (function(lines, phase) error("fake fail") end)', {}) - eq('fake fail', - pcall_err(request, 'nvim_paste', 'line 1\nline 2\nline 3', false, 1)) + api.nvim_exec_lua('vim.paste = (function(lines, phase) error("fake fail") end)', {}) + eq('fake fail', pcall_err(request, 'nvim_paste', 'line 1\nline 2\nline 3', false, 1)) end) end) describe('nvim_put', function() it('validation', function() - eq("Invalid 'line': expected String, got Integer", - pcall_err(request, 'nvim_put', {42}, 'l', false, false)) - eq("Invalid 'type': 'x'", - pcall_err(request, 'nvim_put', {'foo'}, 'x', false, false)) + eq( + "Invalid 'line': expected String, got Integer", + pcall_err(request, 'nvim_put', { 42 }, 'l', false, false) + ) + eq("Invalid 'type': 'x'", pcall_err(request, 'nvim_put', { 'foo' }, 'x', false, false)) end) it("fails if 'nomodifiable'", function() command('set nomodifiable') - eq([[Vim:E21: Cannot make changes, 'modifiable' is off]], - pcall_err(request, 'nvim_put', {'a','b'}, 'l', true, true)) + eq( + [[Vim:E21: Cannot make changes, 'modifiable' is off]], + pcall_err(request, 'nvim_put', { 'a', 'b' }, 'l', true, true) + ) end) it('inserts text', function() -- linewise - nvim('put', {'line 1','line 2','line 3'}, 'l', true, true) + api.nvim_put({ 'line 1', 'line 2', 'line 3' }, 'l', true, true) expect([[ line 1 line 2 line 3]]) - eq({0,4,1,0}, funcs.getpos('.')) + eq({ 0, 4, 1, 0 }, fn.getpos('.')) command('%delete _') -- charwise - nvim('put', {'line 1','line 2','line 3'}, 'c', true, false) + api.nvim_put({ 'line 1', 'line 2', 'line 3' }, 'c', true, false) expect([[ line 1 line 2 line 3]]) - eq({0,1,1,0}, funcs.getpos('.')) -- follow=false + eq({ 0, 1, 1, 0 }, fn.getpos('.')) -- follow=false -- blockwise - nvim('put', {'AA','BB'}, 'b', true, true) + api.nvim_put({ 'AA', 'BB' }, 'b', true, true) expect([[ lAAine 1 lBBine 2 line 3]]) - eq({0,2,4,0}, funcs.getpos('.')) + eq({ 0, 2, 4, 0 }, fn.getpos('.')) command('%delete _') -- Empty lines list. - nvim('put', {}, 'c', true, true) - eq({0,1,1,0}, funcs.getpos('.')) + api.nvim_put({}, 'c', true, true) + eq({ 0, 1, 1, 0 }, fn.getpos('.')) expect([[]]) -- Single empty line. - nvim('put', {''}, 'c', true, true) - eq({0,1,1,0}, funcs.getpos('.')) + api.nvim_put({ '' }, 'c', true, true) + eq({ 0, 1, 1, 0 }, fn.getpos('.')) expect([[ ]]) - nvim('put', {'AB'}, 'c', true, true) + api.nvim_put({ 'AB' }, 'c', true, true) -- after=false, follow=true - nvim('put', {'line 1','line 2'}, 'c', false, true) + api.nvim_put({ 'line 1', 'line 2' }, 'c', false, true) expect([[ Aline 1 line 2B]]) - eq({0,2,7,0}, funcs.getpos('.')) + eq({ 0, 2, 7, 0 }, fn.getpos('.')) command('%delete _') - nvim('put', {'AB'}, 'c', true, true) + api.nvim_put({ 'AB' }, 'c', true, true) -- after=false, follow=false - nvim('put', {'line 1','line 2'}, 'c', false, false) + api.nvim_put({ 'line 1', 'line 2' }, 'c', false, false) expect([[ Aline 1 line 2B]]) - eq({0,1,2,0}, funcs.getpos('.')) - eq('', nvim('eval', 'v:errmsg')) + eq({ 0, 1, 2, 0 }, fn.getpos('.')) + eq('', api.nvim_eval('v:errmsg')) end) it('detects charwise/linewise text (empty {type})', function() -- linewise (final item is empty string) - nvim('put', {'line 1','line 2','line 3',''}, '', true, true) + api.nvim_put({ 'line 1', 'line 2', 'line 3', '' }, '', true, true) expect([[ line 1 line 2 line 3]]) - eq({0,4,1,0}, funcs.getpos('.')) + eq({ 0, 4, 1, 0 }, fn.getpos('.')) command('%delete _') -- charwise (final item is non-empty) - nvim('put', {'line 1','line 2','line 3'}, '', true, true) + api.nvim_put({ 'line 1', 'line 2', 'line 3' }, '', true, true) expect([[ line 1 line 2 line 3]]) - eq({0,3,6,0}, funcs.getpos('.')) + eq({ 0, 3, 6, 0 }, fn.getpos('.')) end) it('allows block width', function() -- behave consistently with setreg(); support "\022{NUM}" return by getregtype() - meths.put({'line 1','line 2','line 3'}, 'l', false, false) + api.nvim_put({ 'line 1', 'line 2', 'line 3' }, 'l', false, false) expect([[ line 1 line 2 @@ -1262,67 +1391,69 @@ describe('API', function() ]]) -- larger width create spaces - meths.put({'a', 'bc'}, 'b3', false, false) + api.nvim_put({ 'a', 'bc' }, 'b3', false, false) expect([[ a line 1 bc line 2 line 3 ]]) -- smaller width is ignored - meths.put({'xxx', 'yyy'}, '\0221', false, true) + api.nvim_put({ 'xxx', 'yyy' }, '\0221', false, true) expect([[ xxxa line 1 yyybc line 2 line 3 ]]) - eq("Invalid 'type': 'bx'", - pcall_err(meths.put, {'xxx', 'yyy'}, 'bx', false, true)) - eq("Invalid 'type': 'b3x'", - pcall_err(meths.put, {'xxx', 'yyy'}, 'b3x', false, true)) + eq("Invalid 'type': 'bx'", pcall_err(api.nvim_put, { 'xxx', 'yyy' }, 'bx', false, true)) + eq("Invalid 'type': 'b3x'", pcall_err(api.nvim_put, { 'xxx', 'yyy' }, 'b3x', false, true)) end) end) describe('nvim_strwidth', function() it('works', function() - eq(3, nvim('strwidth', 'abc')) + eq(3, api.nvim_strwidth('abc')) -- 6 + (neovim) -- 19 * 2 (each japanese character occupies two cells) - eq(44, nvim('strwidth', 'neovimのデザインかなりまともなのになってる。')) + eq(44, api.nvim_strwidth('neovimのデザインかなりまともなのになってる。')) end) it('cannot handle NULs', function() - eq(0, nvim('strwidth', '\0abc')) + eq(0, api.nvim_strwidth('\0abc')) end) end) describe('nvim_get_current_line, nvim_set_current_line', function() it('works', function() - eq('', nvim('get_current_line')) - nvim('set_current_line', 'abc') - eq('abc', nvim('get_current_line')) + eq('', api.nvim_get_current_line()) + api.nvim_set_current_line('abc') + eq('abc', api.nvim_get_current_line()) end) end) describe('set/get/del variables', function() it('validation', function() - eq('Key not found: bogus', pcall_err(meths.get_var, 'bogus')) - eq('Key not found: bogus', pcall_err(meths.del_var, 'bogus')) + eq('Key not found: bogus', pcall_err(api.nvim_get_var, 'bogus')) + eq('Key not found: bogus', pcall_err(api.nvim_del_var, 'bogus')) end) it('nvim_get_var, nvim_set_var, nvim_del_var', function() - nvim('set_var', 'lua', {1, 2, {['3'] = 1}}) - eq({1, 2, {['3'] = 1}}, nvim('get_var', 'lua')) - eq({1, 2, {['3'] = 1}}, nvim('eval', 'g:lua')) - eq(1, funcs.exists('g:lua')) - meths.del_var('lua') - eq(0, funcs.exists('g:lua')) - eq("Key not found: lua", pcall_err(meths.del_var, 'lua')) - meths.set_var('lua', 1) + api.nvim_set_var('lua', { 1, 2, { ['3'] = 1 } }) + eq({ 1, 2, { ['3'] = 1 } }, api.nvim_get_var('lua')) + eq({ 1, 2, { ['3'] = 1 } }, api.nvim_eval('g:lua')) + eq(1, fn.exists('g:lua')) + api.nvim_del_var('lua') + eq(0, fn.exists('g:lua')) + eq('Key not found: lua', pcall_err(api.nvim_del_var, 'lua')) + api.nvim_set_var('lua', 1) + + -- Empty keys are allowed in Vim dicts (and msgpack). + api.nvim_set_var('dict_empty_key', { [''] = 'empty key' }) + eq({ [''] = 'empty key' }, api.nvim_get_var('dict_empty_key')) -- Set locked g: var. command('lockvar lua') - eq('Key is locked: lua', pcall_err(meths.del_var, 'lua')) - eq('Key is locked: lua', pcall_err(meths.set_var, 'lua', 1)) + eq('Key is locked: lua', pcall_err(api.nvim_del_var, 'lua')) + eq('Key is locked: lua', pcall_err(api.nvim_set_var, 'lua', 1)) exec([[ function Test() @@ -1332,260 +1463,281 @@ describe('API', function() let g:Unknown_func = function('Test') let g:Unknown_script_func = function('s:Test') ]]) - eq(NIL, meths.get_var('Unknown_func')) - eq(NIL, meths.get_var('Unknown_script_func')) + eq(NIL, api.nvim_get_var('Unknown_func')) + eq(NIL, api.nvim_get_var('Unknown_script_func')) -- Check if autoload works properly local pathsep = helpers.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) + 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]]) + write_file(autoload_file, [[let testload#value = 2]]) - clear{ args_rm={'-u'}, env={ XDG_CONFIG_HOME=xconfig, XDG_DATA_HOME=xdata } } - eq(2, meths.get_var('testload#value')) + clear { args_rm = { '-u' }, env = { XDG_CONFIG_HOME = xconfig, XDG_DATA_HOME = xdata } } + eq(2, api.nvim_get_var('testload#value')) rmdir('Xhome') end) it('nvim_get_vvar, nvim_set_vvar', function() eq('Key is read-only: count', pcall_err(request, 'nvim_set_vvar', 'count', 42)) eq('Dictionary is locked', pcall_err(request, 'nvim_set_vvar', 'nosuchvar', 42)) - meths.set_vvar('errmsg', 'set by API') - eq('set by API', meths.get_vvar('errmsg')) - meths.set_vvar('errmsg', 42) + api.nvim_set_vvar('errmsg', 'set by API') + eq('set by API', api.nvim_get_vvar('errmsg')) + api.nvim_set_vvar('errmsg', 42) eq('42', eval('v:errmsg')) - meths.set_vvar('oldfiles', { 'one', 'two' }) + api.nvim_set_vvar('oldfiles', { 'one', 'two' }) eq({ 'one', 'two' }, eval('v:oldfiles')) - meths.set_vvar('oldfiles', {}) + api.nvim_set_vvar('oldfiles', {}) eq({}, eval('v:oldfiles')) - eq('Setting v:oldfiles to value with wrong type', pcall_err(meths.set_vvar, 'oldfiles', 'a')) + eq( + 'Setting v:oldfiles to value with wrong type', + pcall_err(api.nvim_set_vvar, '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, 1 }, api.nvim_win_get_cursor(0)) eq(1, eval('v:searchforward')) feed('n') - eq({1, 5}, meths.win_get_cursor(0)) - meths.set_vvar('searchforward', 0) + eq({ 1, 5 }, api.nvim_win_get_cursor(0)) + api.nvim_set_vvar('searchforward', 0) eq(0, eval('v:searchforward')) feed('n') - eq({1, 1}, meths.win_get_cursor(0)) - meths.set_vvar('searchforward', 1) + eq({ 1, 1 }, api.nvim_win_get_cursor(0)) + api.nvim_set_vvar('searchforward', 1) eq(1, eval('v:searchforward')) feed('n') - eq({1, 5}, meths.win_get_cursor(0)) + eq({ 1, 5 }, api.nvim_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}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { background = Screen.colors.Yellow }, }) screen:attach() eq(1, eval('v:hlsearch')) - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:foo} {1:^foo} {1:foo} | {0:~ }| | - ]]} - meths.set_vvar('hlsearch', 0) + ]], + } + api.nvim_set_vvar('hlsearch', 0) eq(0, eval('v:hlsearch')) - screen:expect{grid=[[ + screen:expect { + grid = [[ foo ^foo foo | {0:~ }| | - ]]} - meths.set_vvar('hlsearch', 1) + ]], + } + api.nvim_set_vvar('hlsearch', 1) eq(1, eval('v:hlsearch')) - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:foo} {1:^foo} {1:foo} | {0:~ }| | - ]]} + ]], + } end) it('vim_set_var returns the old value', function() - local val1 = {1, 2, {['3'] = 1}} - local val2 = {4, 7} + local val1 = { 1, 2, { ['3'] = 1 } } + local val2 = { 4, 7 } eq(NIL, request('vim_set_var', 'lua', val1)) eq(val1, request('vim_set_var', 'lua', val2)) end) it('vim_del_var returns the old value', function() - local val1 = {1, 2, {['3'] = 1}} - local val2 = {4, 7} - eq(NIL, request('vim_set_var', 'lua', val1)) + local val1 = { 1, 2, { ['3'] = 1 } } + local val2 = { 4, 7 } + eq(NIL, request('vim_set_var', 'lua', val1)) eq(val1, request('vim_set_var', 'lua', val2)) eq(val2, request('vim_del_var', 'lua')) end) it('truncates values with NULs in them', function() - nvim('set_var', 'xxx', 'ab\0cd') - eq('ab', nvim('get_var', 'xxx')) + api.nvim_set_var('xxx', 'ab\0cd') + eq('ab', api.nvim_get_var('xxx')) end) end) describe('nvim_get_option_value, nvim_set_option_value', function() it('works', function() - ok(nvim('get_option_value', 'equalalways', {})) - nvim('set_option_value', 'equalalways', false, {}) - ok(not nvim('get_option_value', 'equalalways', {})) + ok(api.nvim_get_option_value('equalalways', {})) + api.nvim_set_option_value('equalalways', false, {}) + ok(not api.nvim_get_option_value('equalalways', {})) end) it('works to get global value of local options', function() - eq(false, nvim('get_option_value', 'lisp', {})) - eq(8, nvim('get_option_value', 'shiftwidth', {})) + eq(false, api.nvim_get_option_value('lisp', {})) + eq(8, api.nvim_get_option_value('shiftwidth', {})) end) it('works to set global value of local options', function() - nvim('set_option_value', 'lisp', true, {scope='global'}) - eq(true, nvim('get_option_value', 'lisp', {scope='global'})) - eq(false, nvim('get_option_value', 'lisp', {})) - eq(nil, nvim('command_output', 'setglobal lisp?'):match('nolisp')) - eq('nolisp', nvim('command_output', 'setlocal lisp?'):match('nolisp')) - nvim('set_option_value', 'shiftwidth', 20, {scope='global'}) - eq('20', nvim('command_output', 'setglobal shiftwidth?'):match('%d+')) - eq('8', nvim('command_output', 'setlocal shiftwidth?'):match('%d+')) + api.nvim_set_option_value('lisp', true, { scope = 'global' }) + eq(true, api.nvim_get_option_value('lisp', { scope = 'global' })) + eq(false, api.nvim_get_option_value('lisp', {})) + eq(nil, command_output('setglobal lisp?'):match('nolisp')) + eq('nolisp', command_output('setlocal lisp?'):match('nolisp')) + api.nvim_set_option_value('shiftwidth', 20, { scope = 'global' }) + eq('20', command_output('setglobal shiftwidth?'):match('%d+')) + eq('8', command_output('setlocal shiftwidth?'):match('%d+')) end) it('updates where the option was last set from', function() - nvim('set_option_value', 'equalalways', false, {}) - local status, rv = pcall(nvim, 'command_output', - 'verbose set equalalways?') + api.nvim_set_option_value('equalalways', false, {}) + local status, rv = pcall(command_output, 'verbose set equalalways?') eq(true, status) - ok(nil ~= string.find(rv, 'noequalalways\n'.. - '\tLast set from API client %(channel id %d+%)')) + ok( + nil ~= string.find(rv, 'noequalalways\n' .. '\tLast set from API client %(channel id %d+%)') + ) - nvim('exec_lua', 'vim.api.nvim_set_option_value("equalalways", true, {})', {}) - status, rv = pcall(nvim, 'command_output', - 'verbose set equalalways?') + api.nvim_exec_lua('vim.api.nvim_set_option_value("equalalways", true, {})', {}) + status, rv = pcall(command_output, 'verbose set equalalways?') eq(true, status) eq(' equalalways\n\tLast set from Lua', rv) end) it('updates whether the option has ever been set #25025', function() - eq(false, nvim('get_option_info2', 'autochdir', {}).was_set) - nvim('set_option_value', 'autochdir', true, {}) - eq(true, nvim('get_option_info2', 'autochdir', {}).was_set) + eq(false, api.nvim_get_option_info2('autochdir', {}).was_set) + api.nvim_set_option_value('autochdir', true, {}) + eq(true, api.nvim_get_option_info2('autochdir', {}).was_set) - eq(false, nvim('get_option_info2', 'cmdwinheight', {}).was_set) - nvim('set_option_value', 'cmdwinheight', 10, {}) - eq(true, nvim('get_option_info2', 'cmdwinheight', {}).was_set) + eq(false, api.nvim_get_option_info2('cmdwinheight', {}).was_set) + api.nvim_set_option_value('cmdwinheight', 10, {}) + eq(true, api.nvim_get_option_info2('cmdwinheight', {}).was_set) - eq(false, nvim('get_option_info2', 'debug', {}).was_set) - nvim('set_option_value', 'debug', 'beep', {}) - eq(true, nvim('get_option_info2', 'debug', {}).was_set) + eq(false, api.nvim_get_option_info2('debug', {}).was_set) + api.nvim_set_option_value('debug', 'beep', {}) + eq(true, api.nvim_get_option_info2('debug', {}).was_set) end) it('validation', function() - eq("Invalid 'scope': expected 'local' or 'global'", - pcall_err(nvim, 'get_option_value', 'scrolloff', {scope = 'bogus'})) - eq("Invalid 'scope': expected 'local' or 'global'", - pcall_err(nvim, 'set_option_value', 'scrolloff', 1, {scope = 'bogus'})) - eq("Invalid 'scope': expected String, got Integer", - pcall_err(nvim, 'get_option_value', 'scrolloff', {scope = 42})) - eq("Invalid 'value': expected valid option type, got Array", - pcall_err(nvim, 'set_option_value', 'scrolloff', {}, {})) - eq("Invalid value for option 'scrolloff': expected Number, got Boolean true", - pcall_err(nvim, 'set_option_value', 'scrolloff', true, {})) - eq("Invalid value for option 'scrolloff': expected Number, got String \"wrong\"", - pcall_err(nvim, 'set_option_value', 'scrolloff', 'wrong', {})) + eq( + "Invalid 'scope': expected 'local' or 'global'", + pcall_err(api.nvim_get_option_value, 'scrolloff', { scope = 'bogus' }) + ) + eq( + "Invalid 'scope': expected 'local' or 'global'", + pcall_err(api.nvim_set_option_value, 'scrolloff', 1, { scope = 'bogus' }) + ) + eq( + "Invalid 'scope': expected String, got Integer", + pcall_err(api.nvim_get_option_value, 'scrolloff', { scope = 42 }) + ) + eq( + "Invalid 'value': expected valid option type, got Array", + pcall_err(api.nvim_set_option_value, 'scrolloff', {}, {}) + ) + eq( + "Invalid value for option 'scrolloff': expected number, got boolean true", + pcall_err(api.nvim_set_option_value, 'scrolloff', true, {}) + ) + eq( + 'Invalid value for option \'scrolloff\': expected number, got string "wrong"', + pcall_err(api.nvim_set_option_value, 'scrolloff', 'wrong', {}) + ) end) it('can get local values when global value is set', function() - eq(0, nvim('get_option_value', 'scrolloff', {})) - eq(-1, nvim('get_option_value', 'scrolloff', {scope = 'local'})) + eq(0, api.nvim_get_option_value('scrolloff', {})) + eq(-1, api.nvim_get_option_value('scrolloff', { scope = 'local' })) end) it('can set global and local values', function() - nvim('set_option_value', 'makeprg', 'hello', {}) - eq('hello', nvim('get_option_value', 'makeprg', {})) - eq('', nvim('get_option_value', 'makeprg', {scope = 'local'})) - nvim('set_option_value', 'makeprg', 'world', {scope = 'local'}) - eq('world', nvim('get_option_value', 'makeprg', {scope = 'local'})) - nvim('set_option_value', 'makeprg', 'goodbye', {scope = 'global'}) - eq('goodbye', nvim('get_option_value', 'makeprg', {scope = 'global'})) - nvim('set_option_value', 'makeprg', 'hello', {}) - eq('hello', nvim('get_option_value', 'makeprg', {scope = 'global'})) - eq('hello', nvim('get_option_value', 'makeprg', {})) - eq('', nvim('get_option_value', 'makeprg', {scope = 'local'})) + api.nvim_set_option_value('makeprg', 'hello', {}) + eq('hello', api.nvim_get_option_value('makeprg', {})) + eq('', api.nvim_get_option_value('makeprg', { scope = 'local' })) + api.nvim_set_option_value('makeprg', 'world', { scope = 'local' }) + eq('world', api.nvim_get_option_value('makeprg', { scope = 'local' })) + api.nvim_set_option_value('makeprg', 'goodbye', { scope = 'global' }) + eq('goodbye', api.nvim_get_option_value('makeprg', { scope = 'global' })) + api.nvim_set_option_value('makeprg', 'hello', {}) + eq('hello', api.nvim_get_option_value('makeprg', { scope = 'global' })) + eq('hello', api.nvim_get_option_value('makeprg', {})) + eq('', api.nvim_get_option_value('makeprg', { scope = 'local' })) end) it('clears the local value of an option with nil', function() -- Set global value - nvim('set_option_value', 'shiftwidth', 42, {}) - eq(42, nvim('get_option_value', 'shiftwidth', {})) + api.nvim_set_option_value('shiftwidth', 42, {}) + eq(42, api.nvim_get_option_value('shiftwidth', {})) -- Set local value - nvim('set_option_value', 'shiftwidth', 8, {scope = 'local'}) - eq(8, nvim('get_option_value', 'shiftwidth', {})) - eq(8, nvim('get_option_value', 'shiftwidth', {scope = 'local'})) - eq(42, nvim('get_option_value', 'shiftwidth', {scope = 'global'})) + api.nvim_set_option_value('shiftwidth', 8, { scope = 'local' }) + eq(8, api.nvim_get_option_value('shiftwidth', {})) + eq(8, api.nvim_get_option_value('shiftwidth', { scope = 'local' })) + eq(42, api.nvim_get_option_value('shiftwidth', { scope = 'global' })) -- Clear value without scope - nvim('set_option_value', 'shiftwidth', NIL, {}) - eq(42, nvim('get_option_value', 'shiftwidth', {})) - eq(42, nvim('get_option_value', 'shiftwidth', {scope = 'local'})) + api.nvim_set_option_value('shiftwidth', NIL, {}) + eq(42, api.nvim_get_option_value('shiftwidth', {})) + eq(42, api.nvim_get_option_value('shiftwidth', { scope = 'local' })) -- Clear value with explicit scope - nvim('set_option_value', 'shiftwidth', 8, {scope = 'local'}) - nvim('set_option_value', 'shiftwidth', NIL, {scope = 'local'}) - eq(42, nvim('get_option_value', 'shiftwidth', {})) - eq(42, nvim('get_option_value', 'shiftwidth', {scope = 'local'})) + api.nvim_set_option_value('shiftwidth', 8, { scope = 'local' }) + api.nvim_set_option_value('shiftwidth', NIL, { scope = 'local' }) + eq(42, api.nvim_get_option_value('shiftwidth', {})) + eq(42, api.nvim_get_option_value('shiftwidth', { scope = 'local' })) -- Now try with options with a special "local is unset" value (e.g. 'undolevels') - nvim('set_option_value', 'undolevels', 1000, {}) - nvim('set_option_value', 'undolevels', 1200, {scope = 'local'}) - eq(1200, nvim('get_option_value', 'undolevels', {scope = 'local'})) - nvim('set_option_value', 'undolevels', NIL, {scope = 'local'}) - eq(-123456, nvim('get_option_value', 'undolevels', {scope = 'local'})) - eq(1000, nvim('get_option_value', 'undolevels', {})) + api.nvim_set_option_value('undolevels', 1000, {}) + api.nvim_set_option_value('undolevels', 1200, { scope = 'local' }) + eq(1200, api.nvim_get_option_value('undolevels', { scope = 'local' })) + api.nvim_set_option_value('undolevels', NIL, { scope = 'local' }) + eq(-123456, api.nvim_get_option_value('undolevels', { scope = 'local' })) + eq(1000, api.nvim_get_option_value('undolevels', {})) - nvim('set_option_value', 'autoread', true, {}) - nvim('set_option_value', 'autoread', false, {scope = 'local'}) - eq(false, nvim('get_option_value', 'autoread', {scope = 'local'})) - nvim('set_option_value', 'autoread', NIL, {scope = 'local'}) - eq(NIL, nvim('get_option_value', 'autoread', {scope = 'local'})) - eq(true, nvim('get_option_value', 'autoread', {})) + api.nvim_set_option_value('autoread', true, {}) + api.nvim_set_option_value('autoread', false, { scope = 'local' }) + eq(false, api.nvim_get_option_value('autoread', { scope = 'local' })) + api.nvim_set_option_value('autoread', NIL, { scope = 'local' }) + eq(NIL, api.nvim_get_option_value('autoread', { scope = 'local' })) + eq(true, api.nvim_get_option_value('autoread', {})) end) it('set window options', function() - nvim('set_option_value', 'colorcolumn', '4,3', {}) - eq('4,3', nvim('get_option_value', 'colorcolumn', {scope = 'local'})) - command("set modified hidden") - command("enew") -- edit new buffer, window option is preserved - eq('4,3', nvim('get_option_value', 'colorcolumn', {scope = 'local'})) + api.nvim_set_option_value('colorcolumn', '4,3', {}) + eq('4,3', api.nvim_get_option_value('colorcolumn', { scope = 'local' })) + command('set modified hidden') + command('enew') -- edit new buffer, window option is preserved + eq('4,3', api.nvim_get_option_value('colorcolumn', { scope = 'local' })) end) it('set local window options', function() - nvim('set_option_value', 'colorcolumn', '4,3', {win=0, scope='local'}) - eq('4,3', nvim('get_option_value', 'colorcolumn', {win = 0, scope = 'local'})) - command("set modified hidden") - command("enew") -- edit new buffer, window option is reset - eq('', nvim('get_option_value', 'colorcolumn', {win = 0, scope = 'local'})) + api.nvim_set_option_value('colorcolumn', '4,3', { win = 0, scope = 'local' }) + eq('4,3', api.nvim_get_option_value('colorcolumn', { win = 0, scope = 'local' })) + command('set modified hidden') + command('enew') -- edit new buffer, window option is reset + eq('', api.nvim_get_option_value('colorcolumn', { win = 0, scope = 'local' })) end) it('get buffer or window-local options', function() - nvim('command', 'new') - local buf = nvim('get_current_buf').id - nvim('set_option_value', 'tagfunc', 'foobar', {buf=buf}) - eq('foobar', nvim('get_option_value', 'tagfunc', {buf = buf})) + command('new') + local buf = api.nvim_get_current_buf() + api.nvim_set_option_value('tagfunc', 'foobar', { buf = buf }) + eq('foobar', api.nvim_get_option_value('tagfunc', { buf = buf })) - local win = nvim('get_current_win').id - nvim('set_option_value', 'number', true, {win=win}) - eq(true, nvim('get_option_value', 'number', {win = win})) + local win = api.nvim_get_current_win() + api.nvim_set_option_value('number', true, { win = win }) + eq(true, api.nvim_get_option_value('number', { win = win })) end) it('getting current buffer option does not adjust cursor #19381', function() - nvim('command', 'new') - local buf = nvim('get_current_buf').id - local win = nvim('get_current_win').id + command('new') + local buf = api.nvim_get_current_buf() + print(vim.inspect(api.nvim_get_current_buf())) + local win = api.nvim_get_current_win() insert('some text') feed('0v$') - eq({1, 9}, nvim('win_get_cursor', win)) - nvim('get_option_value', 'filetype', {buf = buf}) - eq({1, 9}, nvim('win_get_cursor', win)) + eq({ 1, 9 }, api.nvim_win_get_cursor(win)) + api.nvim_get_option_value('filetype', { buf = buf }) + eq({ 1, 9 }, api.nvim_win_get_cursor(win)) end) it('can get default option values for filetypes', function() @@ -1593,158 +1745,160 @@ describe('API', function() for ft, opts in pairs { lua = { commentstring = '-- %s' }, vim = { commentstring = '"%s' }, - man = { tagfunc = 'v:lua.require\'man\'.goto_tag' }, - xml = { formatexpr = 'xmlformat#Format()' } + man = { tagfunc = "v:lua.require'man'.goto_tag" }, + xml = { formatexpr = 'xmlformat#Format()' }, } do for option, value in pairs(opts) do - eq(value, nvim('get_option_value', option, { filetype = ft })) + eq(value, api.nvim_get_option_value(option, { filetype = ft })) end end - command'au FileType lua setlocal commentstring=NEW\\ %s' + command 'au FileType lua setlocal commentstring=NEW\\ %s' - eq('NEW %s', nvim('get_option_value', 'commentstring', { filetype = 'lua' })) + eq('NEW %s', api.nvim_get_option_value('commentstring', { filetype = 'lua' })) end) it('errors for bad FileType autocmds', function() - command'au FileType lua setlocal commentstring=BAD' - eq([[FileType Autocommands for "lua": Vim(setlocal):E537: 'commentstring' must be empty or contain %s: commentstring=BAD]], - pcall_err(nvim, 'get_option_value', 'commentstring', { filetype = 'lua' })) + command 'au FileType lua setlocal commentstring=BAD' + eq( + [[FileType Autocommands for "lua": Vim(setlocal):E537: 'commentstring' must be empty or contain %s: commentstring=BAD]], + pcall_err(api.nvim_get_option_value, 'commentstring', { filetype = 'lua' }) + ) end) it("value of 'modified' is always false for scratch buffers", function() - nvim('set_current_buf', nvim('create_buf', true, true)) + api.nvim_set_current_buf(api.nvim_create_buf(true, true)) insert([[ foo bar baz ]]) - eq(false, nvim('get_option_value', 'modified', {})) + eq(false, api.nvim_get_option_value('modified', {})) end) end) describe('nvim_{get,set}_current_buf, nvim_list_bufs', function() it('works', function() - eq(1, #nvim('list_bufs')) - eq(nvim('list_bufs')[1], nvim('get_current_buf')) - nvim('command', 'new') - eq(2, #nvim('list_bufs')) - eq(nvim('list_bufs')[2], nvim('get_current_buf')) - nvim('set_current_buf', nvim('list_bufs')[1]) - eq(nvim('list_bufs')[1], nvim('get_current_buf')) + eq(1, #api.nvim_list_bufs()) + eq(api.nvim_list_bufs()[1], api.nvim_get_current_buf()) + command('new') + eq(2, #api.nvim_list_bufs()) + eq(api.nvim_list_bufs()[2], api.nvim_get_current_buf()) + api.nvim_set_current_buf(api.nvim_list_bufs()[1]) + eq(api.nvim_list_bufs()[1], api.nvim_get_current_buf()) end) end) describe('nvim_{get,set}_current_win, nvim_list_wins', function() it('works', function() - eq(1, #nvim('list_wins')) - eq(nvim('list_wins')[1], nvim('get_current_win')) - nvim('command', 'vsplit') - nvim('command', 'split') - eq(3, #nvim('list_wins')) - eq(nvim('list_wins')[1], nvim('get_current_win')) - nvim('set_current_win', nvim('list_wins')[2]) - eq(nvim('list_wins')[2], nvim('get_current_win')) + eq(1, #api.nvim_list_wins()) + eq(api.nvim_list_wins()[1], api.nvim_get_current_win()) + command('vsplit') + command('split') + eq(3, #api.nvim_list_wins()) + eq(api.nvim_list_wins()[1], api.nvim_get_current_win()) + api.nvim_set_current_win(api.nvim_list_wins()[2]) + eq(api.nvim_list_wins()[2], api.nvim_get_current_win()) end) end) describe('nvim_{get,set}_current_tabpage, nvim_list_tabpages', function() it('works', function() - eq(1, #nvim('list_tabpages')) - eq(nvim('list_tabpages')[1], nvim('get_current_tabpage')) - nvim('command', 'tabnew') - eq(2, #nvim('list_tabpages')) - eq(2, #nvim('list_wins')) - eq(nvim('list_wins')[2], nvim('get_current_win')) - eq(nvim('list_tabpages')[2], nvim('get_current_tabpage')) - nvim('set_current_win', nvim('list_wins')[1]) + eq(1, #api.nvim_list_tabpages()) + eq(api.nvim_list_tabpages()[1], api.nvim_get_current_tabpage()) + command('tabnew') + eq(2, #api.nvim_list_tabpages()) + eq(2, #api.nvim_list_wins()) + eq(api.nvim_list_wins()[2], api.nvim_get_current_win()) + eq(api.nvim_list_tabpages()[2], api.nvim_get_current_tabpage()) + api.nvim_set_current_win(api.nvim_list_wins()[1]) -- Switching window also switches tabpages if necessary - eq(nvim('list_tabpages')[1], nvim('get_current_tabpage')) - eq(nvim('list_wins')[1], nvim('get_current_win')) - nvim('set_current_tabpage', nvim('list_tabpages')[2]) - eq(nvim('list_tabpages')[2], nvim('get_current_tabpage')) - eq(nvim('list_wins')[2], nvim('get_current_win')) + eq(api.nvim_list_tabpages()[1], api.nvim_get_current_tabpage()) + eq(api.nvim_list_wins()[1], api.nvim_get_current_win()) + api.nvim_set_current_tabpage(api.nvim_list_tabpages()[2]) + eq(api.nvim_list_tabpages()[2], api.nvim_get_current_tabpage()) + eq(api.nvim_list_wins()[2], api.nvim_get_current_win()) end) end) describe('nvim_get_mode', function() - it("during normal-mode `g` returns blocking=true", function() - nvim("input", "o") -- add a line - eq({mode='i', blocking=false}, nvim("get_mode")) - nvim("input", [[<C-\><C-N>]]) - eq(2, nvim("eval", "line('.')")) - eq({mode='n', blocking=false}, nvim("get_mode")) + it('during normal-mode `g` returns blocking=true', function() + api.nvim_input('o') -- add a line + eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) + api.nvim_input([[<C-\><C-N>]]) + eq(2, api.nvim_eval("line('.')")) + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) - nvim("input", "g") - eq({mode='n', blocking=true}, nvim("get_mode")) + api.nvim_input('g') + eq({ mode = 'n', blocking = true }, api.nvim_get_mode()) - nvim("input", "k") -- complete the operator - eq(1, nvim("eval", "line('.')")) -- verify the completed operator - eq({mode='n', blocking=false}, nvim("get_mode")) + api.nvim_input('k') -- complete the operator + eq(1, api.nvim_eval("line('.')")) -- verify the completed operator + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) end) - it("returns the correct result multiple consecutive times", function() - for _ = 1,5 do - eq({mode='n', blocking=false}, nvim("get_mode")) + it('returns the correct result multiple consecutive times', function() + for _ = 1, 5 do + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) end - nvim("input", "g") - for _ = 1,4 do - eq({mode='n', blocking=true}, nvim("get_mode")) + api.nvim_input('g') + for _ = 1, 4 do + eq({ mode = 'n', blocking = true }, api.nvim_get_mode()) end - nvim("input", "g") - for _ = 1,7 do - eq({mode='n', blocking=false}, nvim("get_mode")) + api.nvim_input('g') + for _ = 1, 7 do + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) end end) - it("during normal-mode CTRL-W, returns blocking=true", function() - nvim("input", "<C-W>") - eq({mode='n', blocking=true}, nvim("get_mode")) + it('during normal-mode CTRL-W, returns blocking=true', function() + api.nvim_input('<C-W>') + eq({ mode = 'n', blocking = true }, api.nvim_get_mode()) - nvim("input", "s") -- complete the operator - eq(2, nvim("eval", "winnr('$')")) -- verify the completed operator - eq({mode='n', blocking=false}, nvim("get_mode")) + api.nvim_input('s') -- complete the operator + eq(2, api.nvim_eval("winnr('$')")) -- verify the completed operator + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) end) - it("during press-enter prompt without UI returns blocking=false", function() - eq({mode='n', blocking=false}, nvim("get_mode")) + it('during press-enter prompt without UI returns blocking=false', function() + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) command("echom 'msg1'") command("echom 'msg2'") command("echom 'msg3'") command("echom 'msg4'") command("echom 'msg5'") - eq({mode='n', blocking=false}, nvim("get_mode")) - nvim("input", ":messages<CR>") - eq({mode='n', blocking=false}, nvim("get_mode")) + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) + api.nvim_input(':messages<CR>') + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) end) - it("during press-enter prompt returns blocking=true", function() - nvim("ui_attach", 80, 20, {}) - eq({mode='n', blocking=false}, nvim("get_mode")) + it('during press-enter prompt returns blocking=true', function() + api.nvim_ui_attach(80, 20, {}) + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) command("echom 'msg1'") command("echom 'msg2'") command("echom 'msg3'") command("echom 'msg4'") command("echom 'msg5'") - eq({mode='n', blocking=false}, nvim("get_mode")) - nvim("input", ":messages<CR>") - eq({mode='r', blocking=true}, nvim("get_mode")) + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) + api.nvim_input(':messages<CR>') + eq({ mode = 'r', blocking = true }, api.nvim_get_mode()) end) - it("during getchar() returns blocking=false", function() - nvim("input", ":let g:test_input = nr2char(getchar())<CR>") + it('during getchar() returns blocking=false', function() + api.nvim_input(':let g:test_input = nr2char(getchar())<CR>') -- Events are enabled during getchar(), RPC calls are *not* blocked. #5384 - eq({mode='n', blocking=false}, nvim("get_mode")) - eq(0, nvim("eval", "exists('g:test_input')")) - nvim("input", "J") - eq("J", nvim("eval", "g:test_input")) - eq({mode='n', blocking=false}, nvim("get_mode")) + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) + eq(0, api.nvim_eval("exists('g:test_input')")) + api.nvim_input('J') + eq('J', api.nvim_eval('g:test_input')) + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) end) -- TODO: bug #6247#issuecomment-286403810 - it("batched with input", function() - nvim("ui_attach", 80, 20, {}) - eq({mode='n', blocking=false}, nvim("get_mode")) + it('batched with input', function() + api.nvim_ui_attach(80, 20, {}) + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) command("echom 'msg1'") command("echom 'msg2'") command("echom 'msg3'") @@ -1752,44 +1906,48 @@ describe('API', function() command("echom 'msg5'") local req = { - {'nvim_get_mode', {}}, - {'nvim_input', {':messages<CR>'}}, - {'nvim_get_mode', {}}, - {'nvim_eval', {'1'}}, + { 'nvim_get_mode', {} }, + { 'nvim_input', { ':messages<CR>' } }, + { 'nvim_get_mode', {} }, + { 'nvim_eval', { '1' } }, } - eq({ { {mode='n', blocking=false}, - 13, - {mode='n', blocking=false}, -- TODO: should be blocked=true ? - 1 }, - NIL}, meths.call_atomic(req)) - eq({mode='r', blocking=true}, nvim("get_mode")) + eq({ + { + { mode = 'n', blocking = false }, + 13, + { mode = 'n', blocking = false }, -- TODO: should be blocked=true ? + 1, + }, + NIL, + }, api.nvim_call_atomic(req)) + eq({ mode = 'r', blocking = true }, api.nvim_get_mode()) end) - it("during insert-mode map-pending, returns blocking=true #6166", function() - command("inoremap xx foo") - nvim("input", "ix") - eq({mode='i', blocking=true}, nvim("get_mode")) + it('during insert-mode map-pending, returns blocking=true #6166', function() + command('inoremap xx foo') + api.nvim_input('ix') + eq({ mode = 'i', blocking = true }, api.nvim_get_mode()) end) - it("during normal-mode gU, returns blocking=false #6166", function() - nvim("input", "gu") - eq({mode='no', blocking=false}, nvim("get_mode")) + it('during normal-mode gU, returns blocking=false #6166', function() + api.nvim_input('gu') + eq({ mode = 'no', blocking = false }, api.nvim_get_mode()) end) it("at '-- More --' prompt returns blocking=true #11899", function() command('set more') feed(':digraphs<cr>') - eq({mode='rm', blocking=true}, nvim("get_mode")) + eq({ mode = 'rm', blocking = true }, api.nvim_get_mode()) end) it('after <Nop> mapping returns blocking=false #17257', function() command('nnoremap <F2> <Nop>') feed('<F2>') - eq({mode='n', blocking=false}, nvim("get_mode")) + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) end) it('after empty string <expr> mapping returns blocking=false #17257', function() command('nnoremap <expr> <F2> ""') feed('<F2>') - eq({mode='n', blocking=false}, nvim("get_mode")) + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) end) end) @@ -1798,16 +1956,16 @@ describe('API', function() helpers.insert([[ FIRST LINE SECOND LINE]]) - nvim('input', 'gg') - nvim('input', 'gu') + api.nvim_input('gg') + api.nvim_input('gu') -- Make any RPC request (can be non-async: op-pending does not block). - nvim('get_current_buf') + api.nvim_get_current_buf() -- Buffer should not change. expect([[ FIRST LINE SECOND LINE]]) -- Now send input to complete the operator. - nvim('input', 'j') + api.nvim_input('j') expect([[ first line second line]]) @@ -1821,7 +1979,7 @@ describe('API', function() feed('ia<cr>b<cr>c<cr><Esc>kkk') feed('d') -- Make any RPC request (can be non-async: op-pending does not block). - nvim('get_current_buf') + api.nvim_get_current_buf() screen:expect([[ ^a$ | b$ | @@ -1835,12 +1993,12 @@ describe('API', function() helpers.insert([[ FIRST LINE SECOND LINE]]) - nvim('input', 'gg') - nvim('input', 'd') + api.nvim_input('gg') + api.nvim_input('d') -- Make any RPC request (must be async, because map-pending blocks). - nvim('get_api_info') + api.nvim_get_api_info() -- Send input to complete the mapping. - nvim('input', 'd') + api.nvim_input('d') expect([[ FIRST LINE SECOND LINE]]) @@ -1853,11 +2011,11 @@ describe('API', function() helpers.insert([[ FIRST LINE SECOND LINE]]) - nvim('input', 'ix') + api.nvim_input('ix') -- Make any RPC request (must be async, because map-pending blocks). - nvim('get_api_info') + api.nvim_get_api_info() -- Send input to complete the mapping. - nvim('input', 'x') + api.nvim_input('x') expect([[ FIRST LINE SECOND LINfooE]]) @@ -1865,158 +2023,168 @@ describe('API', function() it('does not interrupt Insert mode i_CTRL-O #10035', function() feed('iHello World<c-o>') - eq({mode='niI', blocking=false}, meths.get_mode()) -- fast event - eq(2, eval('1+1')) -- causes K_EVENT key - eq({mode='niI', blocking=false}, meths.get_mode()) -- still in ctrl-o mode + eq({ mode = 'niI', blocking = false }, api.nvim_get_mode()) -- fast event + eq(2, eval('1+1')) -- causes K_EVENT key + eq({ mode = 'niI', blocking = false }, api.nvim_get_mode()) -- still in ctrl-o mode feed('dd') - eq({mode='i', blocking=false}, meths.get_mode()) -- left ctrl-o mode + eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) -- left ctrl-o mode expect('') -- executed the command end) it('does not interrupt Select mode v_CTRL-O #15688', function() feed('iHello World<esc>gh<c-o>') - eq({mode='vs', blocking=false}, meths.get_mode()) -- fast event - eq({mode='vs', blocking=false}, meths.get_mode()) -- again #15288 - eq(2, eval('1+1')) -- causes K_EVENT key - eq({mode='vs', blocking=false}, meths.get_mode()) -- still in ctrl-o mode + eq({ mode = 'vs', blocking = false }, api.nvim_get_mode()) -- fast event + eq({ mode = 'vs', blocking = false }, api.nvim_get_mode()) -- again #15288 + eq(2, eval('1+1')) -- causes K_EVENT key + eq({ mode = 'vs', blocking = false }, api.nvim_get_mode()) -- still in ctrl-o mode feed('^') - eq({mode='s', blocking=false}, meths.get_mode()) -- left ctrl-o mode + eq({ mode = 's', blocking = false }, api.nvim_get_mode()) -- left ctrl-o mode feed('h') - eq({mode='i', blocking=false}, meths.get_mode()) -- entered insert mode - expect('h') -- selection is the whole line and is replaced + eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) -- entered insert mode + expect('h') -- selection is the whole line and is replaced end) it('does not interrupt Insert mode i_0_CTRL-D #13997', function() command('set timeoutlen=9999') feed('i<Tab><Tab>a0') - eq(2, eval('1+1')) -- causes K_EVENT key + eq(2, eval('1+1')) -- causes K_EVENT key feed('<C-D>') - expect('a') -- recognized i_0_CTRL-D + expect('a') -- recognized i_0_CTRL-D end) it("does not interrupt with 'digraph'", function() command('set digraph') feed('i,') - eq(2, eval('1+1')) -- causes K_EVENT key + eq(2, eval('1+1')) -- causes K_EVENT key feed('<BS>') - eq(2, eval('1+1')) -- causes K_EVENT key + eq(2, eval('1+1')) -- causes K_EVENT key feed('.') - expect('…') -- digraph ",." worked + expect('…') -- digraph ",." worked feed('<Esc>') feed(':,') - eq(2, eval('1+1')) -- causes K_EVENT key + eq(2, eval('1+1')) -- causes K_EVENT key feed('<BS>') - eq(2, eval('1+1')) -- causes K_EVENT key + eq(2, eval('1+1')) -- causes K_EVENT key feed('.') - eq('…', funcs.getcmdline()) -- digraph ",." worked + eq('…', fn.getcmdline()) -- digraph ",." worked end) end) describe('nvim_get_context', function() it('validation', function() - eq("Invalid key: 'blah'", - pcall_err(nvim, 'get_context', {blah={}})) - eq("Invalid 'types': expected Array, got Integer", - pcall_err(nvim, 'get_context', {types=42})) - eq("Invalid 'type': 'zub'", - pcall_err(nvim, 'get_context', {types={'jumps', 'zub', 'zam',}})) + eq("Invalid key: 'blah'", pcall_err(api.nvim_get_context, { blah = {} })) + eq( + "Invalid 'types': expected Array, got Integer", + pcall_err(api.nvim_get_context, { types = 42 }) + ) + eq( + "Invalid 'type': 'zub'", + pcall_err(api.nvim_get_context, { types = { 'jumps', 'zub', 'zam' } }) + ) end) it('returns map of current editor state', function() - local opts = {types={'regs', 'jumps', 'bufs', 'gvars'}} - eq({}, parse_context(nvim('get_context', {}))) + local opts = { types = { 'regs', 'jumps', 'bufs', 'gvars' } } + eq({}, parse_context(api.nvim_get_context({}))) feed('i1<cr>2<cr>3<c-[>ddddddqahjklquuu') feed('gg') feed('G') command('edit! BUF1') command('edit BUF2') - nvim('set_var', 'one', 1) - nvim('set_var', 'Two', 2) - nvim('set_var', 'THREE', 3) + api.nvim_set_var('one', 1) + api.nvim_set_var('Two', 2) + api.nvim_set_var('THREE', 3) local expected_ctx = { ['regs'] = { - {['rt'] = 1, ['rc'] = {'1'}, ['n'] = 49, ['ru'] = true}, - {['rt'] = 1, ['rc'] = {'2'}, ['n'] = 50}, - {['rt'] = 1, ['rc'] = {'3'}, ['n'] = 51}, - {['rc'] = {'hjkl'}, ['n'] = 97}, + { ['rt'] = 1, ['rc'] = { '1' }, ['n'] = 49, ['ru'] = true }, + { ['rt'] = 1, ['rc'] = { '2' }, ['n'] = 50 }, + { ['rt'] = 1, ['rc'] = { '3' }, ['n'] = 51 }, + { ['rc'] = { 'hjkl' }, ['n'] = 97 }, }, - ['jumps'] = eval(([[ + ['jumps'] = eval((([[ filter(map(add( getjumplist()[0], { 'bufnr': bufnr('%'), 'lnum': getcurpos()[1] }), 'filter( { "f": expand("#".v:val.bufnr.":p"), "l": v:val.lnum }, { k, v -> k != "l" || v != 1 })'), '!empty(v:val.f)') - ]]):gsub('\n', '')), + ]]):gsub('\n', ''))), ['bufs'] = eval([[ filter(map(getbufinfo(), '{ "f": v:val.name }'), '!empty(v:val.f)') ]]), - ['gvars'] = {{'one', 1}, {'Two', 2}, {'THREE', 3}}, + ['gvars'] = { { 'one', 1 }, { 'Two', 2 }, { 'THREE', 3 } }, } - eq(expected_ctx, parse_context(nvim('get_context', opts))) - eq(expected_ctx, parse_context(nvim('get_context', {}))) - eq(expected_ctx, parse_context(nvim('get_context', {types={}}))) + eq(expected_ctx, parse_context(api.nvim_get_context(opts))) + eq(expected_ctx, parse_context(api.nvim_get_context({}))) + eq(expected_ctx, parse_context(api.nvim_get_context({ types = {} }))) end) end) describe('nvim_load_context', function() it('sets current editor state to given context dictionary', function() - local opts = {types={'regs', 'jumps', 'bufs', 'gvars'}} - eq({}, parse_context(nvim('get_context', opts))) + local opts = { types = { 'regs', 'jumps', 'bufs', 'gvars' } } + eq({}, parse_context(api.nvim_get_context(opts))) - nvim('set_var', 'one', 1) - nvim('set_var', 'Two', 2) - nvim('set_var', 'THREE', 3) - local ctx = nvim('get_context', opts) - nvim('set_var', 'one', 'a') - nvim('set_var', 'Two', 'b') - nvim('set_var', 'THREE', 'c') - eq({'a', 'b' ,'c'}, eval('[g:one, g:Two, g:THREE]')) - nvim('load_context', ctx) - eq({1, 2 ,3}, eval('[g:one, g:Two, g:THREE]')) + api.nvim_set_var('one', 1) + api.nvim_set_var('Two', 2) + api.nvim_set_var('THREE', 3) + local ctx = api.nvim_get_context(opts) + api.nvim_set_var('one', 'a') + api.nvim_set_var('Two', 'b') + api.nvim_set_var('THREE', 'c') + eq({ 'a', 'b', 'c' }, eval('[g:one, g:Two, g:THREE]')) + api.nvim_load_context(ctx) + eq({ 1, 2, 3 }, eval('[g:one, g:Two, g:THREE]')) end) it('errors when context dictionary is invalid', function() - eq('E474: Failed to convert list to msgpack string buffer', - pcall_err(nvim, 'load_context', { regs = { {} }, jumps = { {} } })) - eq("Empty dictionary keys aren't allowed", - pcall_err(nvim, 'load_context', { regs = { { [''] = '' } } })) + eq( + 'E474: Failed to convert list to msgpack string buffer', + pcall_err(api.nvim_load_context, { regs = { {} }, jumps = { {} } }) + ) + eq( + 'E474: Failed to convert list to msgpack string buffer', + pcall_err(api.nvim_load_context, { regs = { { [''] = '' } } }) + ) end) end) describe('nvim_replace_termcodes', function() it('escapes K_SPECIAL as K_SPECIAL KS_SPECIAL KE_FILLER', function() - eq('\128\254X', helpers.nvim('replace_termcodes', '\128', true, true, true)) + eq('\128\254X', helpers.api.nvim_replace_termcodes('\128', true, true, true)) end) it('leaves non-K_SPECIAL string unchanged', function() - eq('abc', helpers.nvim('replace_termcodes', 'abc', true, true, true)) + eq('abc', helpers.api.nvim_replace_termcodes('abc', true, true, true)) end) it('converts <expressions>', function() - eq('\\', helpers.nvim('replace_termcodes', '<Leader>', true, true, true)) + eq('\\', helpers.api.nvim_replace_termcodes('<Leader>', true, true, true)) end) it('converts <LeftMouse> to K_SPECIAL KS_EXTRA KE_LEFTMOUSE', function() -- K_SPECIAL KS_EXTRA KE_LEFTMOUSE -- 0x80 0xfd 0x2c -- 128 253 44 - eq('\128\253\44', helpers.nvim('replace_termcodes', - '<LeftMouse>', true, true, true)) + eq('\128\253\44', helpers.api.nvim_replace_termcodes('<LeftMouse>', true, true, true)) end) it('converts keycodes', function() - eq('\nx\27x\rx<x', helpers.nvim('replace_termcodes', - '<NL>x<Esc>x<CR>x<lt>x', true, true, true)) + eq( + '\nx\27x\rx<x', + helpers.api.nvim_replace_termcodes('<NL>x<Esc>x<CR>x<lt>x', true, true, true) + ) end) it('does not convert keycodes if special=false', function() - eq('<NL>x<Esc>x<CR>x<lt>x', helpers.nvim('replace_termcodes', - '<NL>x<Esc>x<CR>x<lt>x', true, true, false)) + eq( + '<NL>x<Esc>x<CR>x<lt>x', + helpers.api.nvim_replace_termcodes('<NL>x<Esc>x<CR>x<lt>x', true, true, false) + ) end) it('does not crash when transforming an empty string', function() @@ -2027,13 +2195,13 @@ describe('API', function() -- then `return str` in vim_replace_termcodes body will make Neovim free -- `str.data` twice: once when freeing arguments, then when freeing return -- value. - eq('', meths.replace_termcodes('', true, true, true)) + eq('', api.nvim_replace_termcodes('', true, true, true)) end) -- Not exactly the case, as nvim_replace_termcodes() escapes K_SPECIAL in Unicode it('translates the result of keytrans() on string with 0x80 byte back', function() local s = 'ff\128\253\097tt' - eq(s, meths.replace_termcodes(funcs.keytrans(s), true, true, true)) + eq(s, api.nvim_replace_termcodes(fn.keytrans(s), true, true, true)) end) end) @@ -2041,15 +2209,15 @@ describe('API', function() it('K_SPECIAL escaping', function() local function on_setup() -- notice the special char(…) \xe2\80\xa6 - nvim('feedkeys', ':let x1="…"\n', '', true) + api.nvim_feedkeys(':let x1="…"\n', '', true) -- Both nvim_replace_termcodes and nvim_feedkeys escape \x80 - local inp = helpers.nvim('replace_termcodes', ':let x2="…"<CR>', true, true, true) - nvim('feedkeys', inp, '', true) -- escape_ks=true + local inp = helpers.api.nvim_replace_termcodes(':let x2="…"<CR>', true, true, true) + api.nvim_feedkeys(inp, '', true) -- escape_ks=true -- nvim_feedkeys with K_SPECIAL escaping disabled - inp = helpers.nvim('replace_termcodes', ':let x3="…"<CR>', true, true, true) - nvim('feedkeys', inp, '', false) -- escape_ks=false + inp = helpers.api.nvim_replace_termcodes(':let x3="…"<CR>', true, true, true) + api.nvim_feedkeys(inp, '', false) -- escape_ks=false helpers.stop() end @@ -2057,10 +2225,10 @@ describe('API', function() -- spin the loop a bit helpers.run(nil, nil, on_setup) - eq('…', nvim('get_var', 'x1')) + eq('…', api.nvim_get_var('x1')) -- Because of the double escaping this is neq - neq('…', nvim('get_var', 'x2')) - eq('…', nvim('get_var', 'x3')) + neq('…', api.nvim_get_var('x2')) + eq('…', api.nvim_get_var('x3')) end) end) @@ -2071,10 +2239,10 @@ describe('API', function() screen = Screen.new(40, 8) screen:attach() screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, - [1] = {bold = true, foreground = Screen.colors.SeaGreen}, - [2] = {bold = true, reverse = true}, - [3] = {foreground = Screen.colors.Blue}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { bold = true, foreground = Screen.colors.SeaGreen }, + [2] = { bold = true, reverse = true }, + [3] = { foreground = Screen.colors.Blue }, }) end) @@ -2095,47 +2263,48 @@ describe('API', function() silent! call nvim_out_write("\n") redir END ]]) - eq('\naaa\n' .. ('a'):rep(5002) .. '\naaa', meths.get_var('out')) + eq('\naaa\n' .. ('a'):rep(5002) .. '\naaa', api.nvim_get_var('out')) end) it('blank line in message', function() feed([[:call nvim_out_write("\na\n")<CR>]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {2: }| | a | {1:Press ENTER or type command to continue}^ | - ]]} + ]], + } feed('<CR>') feed([[:call nvim_out_write("b\n\nc\n")<CR>]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {2: }| b | | c | {1:Press ENTER or type command to continue}^ | - ]]} + ]], + } end) it('NUL bytes in message', function() feed([[:lua vim.api.nvim_out_write('aaa\0bbb\0\0ccc\nddd\0\0\0eee\n')<CR>]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {2: }| aaa{3:^@}bbb{3:^@^@}ccc | ddd{3:^@^@^@}eee | {1:Press ENTER or type command to continue}^ | - ]]} + ]], + } end) end) @@ -2146,34 +2315,27 @@ describe('API', function() screen = Screen.new(40, 8) screen:attach() screen:set_default_attr_ids({ - [0] = {bold=true, foreground=Screen.colors.Blue}, - [1] = {foreground = Screen.colors.White, background = Screen.colors.Red}, - [2] = {bold = true, foreground = Screen.colors.SeaGreen}, - [3] = {bold = true, reverse = true}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { foreground = Screen.colors.White, background = Screen.colors.Red }, + [2] = { bold = true, foreground = Screen.colors.SeaGreen }, + [3] = { bold = true, reverse = true }, }) end) it('can show one line', function() - nvim_async('err_write', 'has bork\n') + async_meths.nvim_err_write('has bork\n') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 {1:has bork} | ]]) end) it('shows return prompt when more than &cmdheight lines', function() - nvim_async('err_write', 'something happened\nvery bad\n') + async_meths.nvim_err_write('something happened\nvery bad\n') screen:expect([[ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3: }| {1:something happened} | {1:very bad} | @@ -2182,7 +2344,7 @@ describe('API', function() end) it('shows return prompt after all lines are shown', function() - nvim_async('err_write', 'FAILURE\nERROR\nEXCEPTION\nTRACEBACK\n') + async_meths.nvim_err_write('FAILURE\nERROR\nEXCEPTION\nTRACEBACK\n') screen:expect([[ | {0:~ }| @@ -2197,47 +2359,40 @@ describe('API', function() it('handles multiple calls', function() -- without linebreak text is joined to one line - nvim_async('err_write', 'very ') - nvim_async('err_write', 'fail\n') + async_meths.nvim_err_write('very ') + async_meths.nvim_err_write('fail\n') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 {1:very fail} | ]]) helpers.poke_eventloop() -- shows up to &cmdheight lines - nvim_async('err_write', 'more fail\ntoo fail\n') + async_meths.nvim_err_write('more fail\ntoo fail\n') screen:expect([[ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3: }| {1:more fail} | {1:too fail} | {2:Press ENTER or type command to continue}^ | ]]) - feed('<cr>') -- exit the press ENTER screen + feed('<cr>') -- exit the press ENTER screen end) it('NUL bytes in message', function() - nvim_async('err_write', 'aaa\0bbb\0\0ccc\nddd\0\0\0eee\n') - screen:expect{grid=[[ + async_meths.nvim_err_write('aaa\0bbb\0\0ccc\nddd\0\0\0eee\n') + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3: }| {1:aaa^@bbb^@^@ccc} | {1:ddd^@^@^@eee} | {2:Press ENTER or type command to continue}^ | - ]]} + ]], + } end) end) @@ -2248,15 +2403,15 @@ describe('API', function() screen = Screen.new(40, 8) screen:attach() screen:set_default_attr_ids({ - [0] = {bold=true, foreground=Screen.colors.Blue}, - [1] = {foreground = Screen.colors.White, background = Screen.colors.Red}, - [2] = {bold = true, foreground = Screen.colors.SeaGreen}, - [3] = {bold = true, reverse = true}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { foreground = Screen.colors.White, background = Screen.colors.Red }, + [2] = { bold = true, foreground = Screen.colors.SeaGreen }, + [3] = { bold = true, reverse = true }, }) end) it('shows only one return prompt after all lines are shown', function() - nvim_async('err_writeln', 'FAILURE\nERROR\nEXCEPTION\nTRACEBACK') + async_meths.nvim_err_writeln('FAILURE\nERROR\nEXCEPTION\nTRACEBACK') screen:expect([[ | {0:~ }| @@ -2270,12 +2425,7 @@ describe('API', function() feed('<CR>') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 | ]]) end) @@ -2299,116 +2449,126 @@ describe('API', function() } it('returns {} for invalid channel', function() - eq({}, meths.get_chan_info(0)) - eq({}, meths.get_chan_info(-1)) + eq({}, api.nvim_get_chan_info(-1)) -- more preallocated numbers might be added, try something high - eq({}, meths.get_chan_info(10)) + eq({}, api.nvim_get_chan_info(10)) end) it('stream=stdio channel', function() - eq({[1]=testinfo,[2]=stderr}, meths.list_chans()) - eq(testinfo, meths.get_chan_info(1)) - eq(stderr, meths.get_chan_info(2)) - - meths.set_client_info("functionaltests", - {major=0, minor=3, patch=17}, - 'ui', - {do_stuff={n_args={2,3}}}, - {license= 'Apache2'}) + eq({ [1] = testinfo, [2] = stderr }, api.nvim_list_chans()) + -- 0 should return current channel + eq(testinfo, api.nvim_get_chan_info(0)) + eq(testinfo, api.nvim_get_chan_info(1)) + eq(stderr, api.nvim_get_chan_info(2)) + + api.nvim_set_client_info( + 'functionaltests', + { major = 0, minor = 3, patch = 17 }, + 'ui', + { do_stuff = { n_args = { 2, 3 } } }, + { license = 'Apache2' } + ) local info = { stream = 'stdio', id = 1, mode = 'rpc', client = { - name='functionaltests', - version={major=0, minor=3, patch=17}, - type='ui', - methods={do_stuff={n_args={2,3}}}, - attributes={license='Apache2'}, + name = 'functionaltests', + version = { major = 0, minor = 3, patch = 17 }, + type = 'ui', + methods = { do_stuff = { n_args = { 2, 3 } } }, + attributes = { license = 'Apache2' }, }, } - eq({info=info}, meths.get_var("info_event")) - eq({[1]=info, [2]=stderr}, meths.list_chans()) - eq(info, meths.get_chan_info(1)) + eq({ info = info }, api.nvim_get_var('info_event')) + eq({ [1] = info, [2] = stderr }, api.nvim_list_chans()) + eq(info, api.nvim_get_chan_info(1)) end) it('stream=job channel', function() eq(3, eval("jobstart(['cat'], {'rpc': v:true})")) local catpath = eval('exepath("cat")') local info = { - stream='job', - id=3, - argv={ catpath }, - mode='rpc', - client={}, + stream = 'job', + id = 3, + argv = { catpath }, + mode = 'rpc', + client = {}, } - eq({info=info}, meths.get_var("opened_event")) - eq({[1]=testinfo,[2]=stderr,[3]=info}, meths.list_chans()) - eq(info, meths.get_chan_info(3)) - eval('rpcrequest(3, "nvim_set_client_info", "amazing-cat", {}, "remote",'.. - '{"nvim_command":{"n_args":1}},'.. -- and so on - '{"description":"The Amazing Cat"})') + eq({ info = info }, api.nvim_get_var('opened_event')) + eq({ [1] = testinfo, [2] = stderr, [3] = info }, api.nvim_list_chans()) + eq(info, api.nvim_get_chan_info(3)) + eval( + 'rpcrequest(3, "nvim_set_client_info", "amazing-cat", {}, "remote",' + .. '{"nvim_command":{"n_args":1}},' -- and so on + .. '{"description":"The Amazing Cat"})' + ) info = { - stream='job', - id=3, - argv={ catpath }, - mode='rpc', + stream = 'job', + id = 3, + argv = { catpath }, + mode = 'rpc', client = { - name='amazing-cat', - version={major=0}, - type='remote', - methods={nvim_command={n_args=1}}, - attributes={description="The Amazing Cat"}, + name = 'amazing-cat', + version = { major = 0 }, + type = 'remote', + methods = { nvim_command = { n_args = 1 } }, + attributes = { description = 'The Amazing Cat' }, }, } - eq({info=info}, meths.get_var("info_event")) - eq({[1]=testinfo,[2]=stderr,[3]=info}, meths.list_chans()) + eq({ info = info }, api.nvim_get_var('info_event')) + eq({ [1] = testinfo, [2] = stderr, [3] = info }, api.nvim_list_chans()) - eq("Vim:Error invoking 'nvim_set_current_buf' on channel 3 (amazing-cat):\nWrong type for argument 1 when calling nvim_set_current_buf, expecting Buffer", - pcall_err(eval, 'rpcrequest(3, "nvim_set_current_buf", -1)')) + eq( + "Vim:Error invoking 'nvim_set_current_buf' on channel 3 (amazing-cat):\nWrong type for argument 1 when calling nvim_set_current_buf, expecting Buffer", + pcall_err(eval, 'rpcrequest(3, "nvim_set_current_buf", -1)') + ) + eq(info, eval('rpcrequest(3, "nvim_get_chan_info", 0)')) end) it('stream=job :terminal channel', function() command(':terminal') - eq({id=1}, meths.get_current_buf()) - eq(3, meths.get_option_value('channel', {buf=1})) + eq(1, api.nvim_get_current_buf()) + eq(3, api.nvim_get_option_value('channel', { buf = 1 })) local info = { - stream='job', - id=3, - argv={ eval('exepath(&shell)') }, - mode='terminal', + stream = 'job', + id = 3, + argv = { eval('exepath(&shell)') }, + mode = 'terminal', buffer = 1, - pty='?', + pty = '?', } - local event = meths.get_var("opened_event") + local event = api.nvim_get_var('opened_event') if not is_os('win') then info.pty = event.info.pty - neq(nil, string.match(info.pty, "^/dev/")) + neq(nil, string.match(info.pty, '^/dev/')) end - eq({info=info}, event) - info.buffer = {id=1} - eq({[1]=testinfo,[2]=stderr,[3]=info}, meths.list_chans()) - eq(info, meths.get_chan_info(3)) + eq({ info = info }, event) + info.buffer = 1 + eq({ [1] = testinfo, [2] = stderr, [3] = info }, api.nvim_list_chans()) + eq(info, api.nvim_get_chan_info(3)) -- :terminal with args + running process. - command(':exe "terminal" shellescape(v:progpath) "-u NONE -i NONE"') - eq(-1, eval('jobwait([&channel], 0)[0]')) -- Running? + command('enew') + local progpath_esc = eval('shellescape(v:progpath)') + fn.termopen(('%s -u NONE -i NONE'):format(progpath_esc), { + env = { VIMRUNTIME = os.getenv('VIMRUNTIME') }, + }) + eq(-1, eval('jobwait([&channel], 0)[0]')) -- Running? local expected2 = { stream = 'job', id = 4, - argv = ( - is_os('win') and { - eval('&shell'), - '/s', - '/c', - fmt('"%s -u NONE -i NONE"', eval('shellescape(v:progpath)')), - } or { - eval('&shell'), - eval('&shellcmdflag'), - fmt('%s -u NONE -i NONE', eval('shellescape(v:progpath)')), - } - ), + argv = (is_os('win') and { + eval('&shell'), + '/s', + '/c', + fmt('"%s -u NONE -i NONE"', progpath_esc), + } or { + eval('&shell'), + eval('&shellcmdflag'), + fmt('%s -u NONE -i NONE', progpath_esc), + }), mode = 'terminal', buffer = 2, pty = '?', @@ -2419,163 +2579,172 @@ describe('API', function() -- :terminal with args + stopped process. eq(1, eval('jobstop(&channel)')) - eval('jobwait([&channel], 1000)') -- Wait. - expected2.pty = (is_os('win') and '?' or '') -- pty stream was closed. + eval('jobwait([&channel], 1000)') -- Wait. + expected2.pty = (is_os('win') and '?' or '') -- pty stream was closed. eq(expected2, eval('nvim_get_chan_info(&channel)')) end) end) describe('nvim_call_atomic', function() it('works', function() - meths.buf_set_lines(0, 0, -1, true, {'first'}) + api.nvim_buf_set_lines(0, 0, -1, true, { 'first' }) local req = { - {'nvim_get_current_line', {}}, - {'nvim_set_current_line', {'second'}}, + { 'nvim_get_current_line', {} }, + { 'nvim_set_current_line', { 'second' } }, } - eq({{'first', NIL}, NIL}, meths.call_atomic(req)) - eq({'second'}, meths.buf_get_lines(0, 0, -1, true)) + eq({ { 'first', NIL }, NIL }, api.nvim_call_atomic(req)) + eq({ 'second' }, api.nvim_buf_get_lines(0, 0, -1, true)) end) it('allows multiple return values', function() local req = { - {'nvim_set_var', {'avar', true}}, - {'nvim_set_var', {'bvar', 'string'}}, - {'nvim_get_var', {'avar'}}, - {'nvim_get_var', {'bvar'}}, + { 'nvim_set_var', { 'avar', true } }, + { 'nvim_set_var', { 'bvar', 'string' } }, + { 'nvim_get_var', { 'avar' } }, + { 'nvim_get_var', { 'bvar' } }, } - eq({{NIL, NIL, true, 'string'}, NIL}, meths.call_atomic(req)) + eq({ { NIL, NIL, true, 'string' }, NIL }, api.nvim_call_atomic(req)) end) it('is aborted by errors in call', function() - local error_types = meths.get_api_info()[2].error_types + local error_types = api.nvim_get_api_info()[2].error_types local req = { - {'nvim_set_var', {'one', 1}}, - {'nvim_buf_set_lines', {}}, - {'nvim_set_var', {'two', 2}}, + { 'nvim_set_var', { 'one', 1 } }, + { 'nvim_buf_set_lines', {} }, + { 'nvim_set_var', { 'two', 2 } }, } - eq({{NIL}, {1, error_types.Exception.id, - 'Wrong number of arguments: expecting 5 but got 0'}}, - meths.call_atomic(req)) - eq(1, meths.get_var('one')) - eq(false, pcall(meths.get_var, 'two')) + eq({ + { NIL }, + { + 1, + error_types.Exception.id, + 'Wrong number of arguments: expecting 5 but got 0', + }, + }, api.nvim_call_atomic(req)) + eq(1, api.nvim_get_var('one')) + eq(false, pcall(api.nvim_get_var, 'two')) -- still returns all previous successful calls req = { - {'nvim_set_var', {'avar', 5}}, - {'nvim_set_var', {'bvar', 'string'}}, - {'nvim_get_var', {'avar'}}, - {'nvim_buf_get_lines', {0, 10, 20, true}}, - {'nvim_get_var', {'bvar'}}, + { 'nvim_set_var', { 'avar', 5 } }, + { 'nvim_set_var', { 'bvar', 'string' } }, + { 'nvim_get_var', { 'avar' } }, + { 'nvim_buf_get_lines', { 0, 10, 20, true } }, + { 'nvim_get_var', { 'bvar' } }, } - eq({{NIL, NIL, 5}, {3, error_types.Validation.id, 'Index out of bounds'}}, - meths.call_atomic(req)) + eq( + { { NIL, NIL, 5 }, { 3, error_types.Validation.id, 'Index out of bounds' } }, + api.nvim_call_atomic(req) + ) req = { - {'i_am_not_a_method', {'xx'}}, - {'nvim_set_var', {'avar', 10}}, + { 'i_am_not_a_method', { 'xx' } }, + { 'nvim_set_var', { 'avar', 10 } }, } - eq({{}, {0, error_types.Exception.id, 'Invalid method: i_am_not_a_method'}}, - meths.call_atomic(req)) - eq(5, meths.get_var('avar')) + eq( + { {}, { 0, error_types.Exception.id, 'Invalid method: i_am_not_a_method' } }, + api.nvim_call_atomic(req) + ) + eq(5, api.nvim_get_var('avar')) end) it('validation', function() local req = { - {'nvim_set_var', {'avar', 1}}, - {'nvim_set_var'}, - {'nvim_set_var', {'avar', 2}}, + { 'nvim_set_var', { 'avar', 1 } }, + { 'nvim_set_var' }, + { 'nvim_set_var', { 'avar', 2 } }, } - eq("Invalid 'calls' item: expected 2-item Array", - pcall_err(meths.call_atomic, req)) + eq("Invalid 'calls' item: expected 2-item Array", pcall_err(api.nvim_call_atomic, req)) -- call before was done, but not after - eq(1, meths.get_var('avar')) + eq(1, api.nvim_get_var('avar')) req = { { 'nvim_set_var', { 'bvar', { 2, 3 } } }, 12, } - eq("Invalid 'calls' item: expected Array, got Integer", - pcall_err(meths.call_atomic, req)) - eq({2,3}, meths.get_var('bvar')) + eq("Invalid 'calls' item: expected Array, got Integer", pcall_err(api.nvim_call_atomic, req)) + eq({ 2, 3 }, api.nvim_get_var('bvar')) req = { - {'nvim_set_current_line', 'little line'}, - {'nvim_set_var', {'avar', 3}}, + { 'nvim_set_current_line', 'little line' }, + { 'nvim_set_var', { 'avar', 3 } }, } - eq("Invalid call args: expected Array, got String", - pcall_err(meths.call_atomic, req)) + eq('Invalid call args: expected Array, got String', pcall_err(api.nvim_call_atomic, req)) -- call before was done, but not after - eq(1, meths.get_var('avar')) - eq({''}, meths.buf_get_lines(0, 0, -1, true)) + eq(1, api.nvim_get_var('avar')) + eq({ '' }, api.nvim_buf_get_lines(0, 0, -1, true)) end) end) describe('nvim_list_runtime_paths', function() setup(function() local pathsep = helpers.get_pathsep() - mkdir_p('Xtest'..pathsep..'a') - mkdir_p('Xtest'..pathsep..'b') + mkdir_p('Xtest' .. pathsep .. 'a') + mkdir_p('Xtest' .. pathsep .. 'b') end) teardown(function() rmdir 'Xtest' end) before_each(function() - meths.set_current_dir 'Xtest' + api.nvim_set_current_dir 'Xtest' end) it('returns nothing with empty &runtimepath', function() - meths.set_option_value('runtimepath', '', {}) - eq({}, meths.list_runtime_paths()) + api.nvim_set_option_value('runtimepath', '', {}) + eq({}, api.nvim_list_runtime_paths()) end) it('returns single runtimepath', function() - meths.set_option_value('runtimepath', 'a', {}) - eq({'a'}, meths.list_runtime_paths()) + api.nvim_set_option_value('runtimepath', 'a', {}) + eq({ 'a' }, api.nvim_list_runtime_paths()) end) it('returns two runtimepaths', function() - meths.set_option_value('runtimepath', 'a,b', {}) - eq({'a', 'b'}, meths.list_runtime_paths()) + api.nvim_set_option_value('runtimepath', 'a,b', {}) + eq({ 'a', 'b' }, api.nvim_list_runtime_paths()) end) it('returns empty strings when appropriate', function() - meths.set_option_value('runtimepath', 'a,,b', {}) - eq({'a', '', 'b'}, meths.list_runtime_paths()) - meths.set_option_value('runtimepath', ',a,b', {}) - eq({'', 'a', 'b'}, meths.list_runtime_paths()) + api.nvim_set_option_value('runtimepath', 'a,,b', {}) + eq({ 'a', '', 'b' }, api.nvim_list_runtime_paths()) + api.nvim_set_option_value('runtimepath', ',a,b', {}) + eq({ '', 'a', 'b' }, api.nvim_list_runtime_paths()) -- Trailing "," is ignored. Use ",," if you really really want CWD. - meths.set_option_value('runtimepath', 'a,b,', {}) - eq({'a', 'b'}, meths.list_runtime_paths()) - meths.set_option_value('runtimepath', 'a,b,,', {}) - eq({'a', 'b', ''}, meths.list_runtime_paths()) + api.nvim_set_option_value('runtimepath', 'a,b,', {}) + eq({ 'a', 'b' }, api.nvim_list_runtime_paths()) + api.nvim_set_option_value('runtimepath', 'a,b,,', {}) + eq({ 'a', 'b', '' }, api.nvim_list_runtime_paths()) end) it('truncates too long paths', function() local long_path = ('/a'):rep(8192) - meths.set_option_value('runtimepath', long_path, {}) - local paths_list = meths.list_runtime_paths() + api.nvim_set_option_value('runtimepath', long_path, {}) + local paths_list = api.nvim_list_runtime_paths() eq({}, paths_list) end) end) it('can throw exceptions', function() - local status, err = pcall(nvim, 'get_option_value', 'invalid-option', {}) + local status, err = pcall(api.nvim_get_option_value, 'invalid-option', {}) eq(false, status) ok(err:match("Unknown option 'invalid%-option'") ~= nil) end) it('does not truncate error message <1 MB #5984', function() - local very_long_name = 'A'..('x'):rep(10000)..'Z' - local status, err = pcall(nvim, 'get_option_value', very_long_name, {}) + local very_long_name = 'A' .. ('x'):rep(10000) .. 'Z' + local status, err = pcall(api.nvim_get_option_value, very_long_name, {}) eq(false, status) eq(very_long_name, err:match('Ax+Z?')) end) - it("does not leak memory on incorrect argument types", function() - local status, err = pcall(nvim, 'set_current_dir',{'not', 'a', 'dir'}) + it('does not leak memory on incorrect argument types', function() + local status, err = pcall(api.nvim_set_current_dir, { 'not', 'a', 'dir' }) eq(false, status) - ok(err:match(': Wrong type for argument 1 when calling nvim_set_current_dir, expecting String') ~= nil) + ok( + err:match(': Wrong type for argument 1 when calling nvim_set_current_dir, expecting String') + ~= nil + ) end) describe('nvim_parse_expression', function() before_each(function() - meths.set_option_value('isident', '', {}) + api.nvim_set_option_value('isident', '', {}) end) local function simplify_east_api_node(line, east_api_node) @@ -2589,21 +2758,26 @@ describe('API', function() end local typ = east_api_node.type if typ == 'Register' then - typ = typ .. ('(name=%s)'):format( - tostring(intchar2lua(east_api_node.name))) + typ = typ .. ('(name=%s)'):format(tostring(intchar2lua(east_api_node.name))) east_api_node.name = nil elseif typ == 'PlainIdentifier' then - typ = typ .. ('(scope=%s,ident=%s)'):format( - tostring(intchar2lua(east_api_node.scope)), east_api_node.ident) + typ = typ + .. ('(scope=%s,ident=%s)'):format( + tostring(intchar2lua(east_api_node.scope)), + east_api_node.ident + ) east_api_node.scope = nil east_api_node.ident = nil elseif typ == 'PlainKey' then typ = typ .. ('(key=%s)'):format(east_api_node.ident) east_api_node.ident = nil elseif typ == 'Comparison' then - typ = typ .. ('(type=%s,inv=%u,ccs=%s)'):format( - east_api_node.cmp_type, east_api_node.invert and 1 or 0, - east_api_node.ccs_strategy) + typ = typ + .. ('(type=%s,inv=%u,ccs=%s)'):format( + east_api_node.cmp_type, + east_api_node.invert and 1 or 0, + east_api_node.ccs_strategy + ) east_api_node.ccs_strategy = nil east_api_node.cmp_type = nil east_api_node.invert = nil @@ -2620,7 +2794,8 @@ describe('API', function() typ = ('%s(scope=%s,ident=%s)'):format( typ, tostring(intchar2lua(east_api_node.scope)), - east_api_node.ident) + east_api_node.ident + ) east_api_node.ident = nil east_api_node.scope = nil elseif typ == 'Environment' then @@ -2628,24 +2803,30 @@ describe('API', function() east_api_node.ident = nil elseif typ == 'Assignment' then local aug = east_api_node.augmentation - if aug == '' then aug = 'Plain' end + if aug == '' then + aug = 'Plain' + end typ = ('%s(%s)'):format(typ, aug) east_api_node.augmentation = nil end typ = ('%s:%u:%u:%s'):format( - typ, east_api_node.start[1], east_api_node.start[2], - line:sub(east_api_node.start[2] + 1, - east_api_node.start[2] + 1 + east_api_node.len - 1)) + typ, + east_api_node.start[1], + east_api_node.start[2], + line:sub(east_api_node.start[2] + 1, east_api_node.start[2] + 1 + east_api_node.len - 1) + ) assert(east_api_node.start[2] + east_api_node.len - 1 <= #line) for k, _ in pairs(east_api_node.start) do - assert(({true, true})[k]) + assert(({ true, true })[k]) end east_api_node.start = nil east_api_node.type = nil east_api_node.len = nil local can_simplify = true for _, _ in pairs(east_api_node) do - if can_simplify then can_simplify = false end + if can_simplify then + can_simplify = false + end end if can_simplify then return typ @@ -2662,7 +2843,7 @@ describe('API', function() east_api.err.message = nil end if east_api.ast then - east_api.ast = {simplify_east_api_node(line, east_api.ast)} + east_api.ast = { simplify_east_api_node(line, east_api.ast) } if #east_api.ast == 0 then east_api.ast = nil end @@ -2674,26 +2855,21 @@ describe('API', function() end local function simplify_east_hl(line, east_hl) for i, v in ipairs(east_hl) do - east_hl[i] = ('%s:%u:%u:%s'):format( - v[4], - v[1], - v[2], - line:sub(v[2] + 1, v[3])) + east_hl[i] = ('%s:%u:%u:%s'):format(v[4], v[1], v[2], line:sub(v[2] + 1, v[3])) end return east_hl end local FLAGS_TO_STR = { - [0] = "", - [1] = "m", - [2] = "E", - [3] = "mE", - [4] = "l", - [5] = "lm", - [6] = "lE", - [7] = "lmE", + [0] = '', + [1] = 'm', + [2] = 'E', + [3] = 'mE', + [4] = 'l', + [5] = 'lm', + [6] = 'lE', + [7] = 'lmE', } - local function _check_parsing(opts, str, exp_ast, exp_highlighting_fs, - nz_flags_exps) + local function _check_parsing(opts, str, exp_ast, exp_highlighting_fs, nz_flags_exps) if type(str) ~= 'string' then return end @@ -2701,7 +2877,7 @@ describe('API', function() nz_flags_exps = nz_flags_exps or {} for _, flags in ipairs(opts.flags) do local err, msg = pcall(function() - local east_api = meths.parse_expression(str, FLAGS_TO_STR[flags], true) + local east_api = api.nvim_parse_expression(str, FLAGS_TO_STR[flags], true) local east_hl = east_api.highlight east_api.highlight = nil local ast = simplify_east_api(str, east_api) @@ -2734,37 +2910,39 @@ describe('API', function() end) if not err then if type(msg) == 'table' then - local merr, new_msg = pcall( - format_string, 'table error:\n%s\n\n(%r)', msg.message, msg) + local merr, new_msg = pcall(format_string, 'table error:\n%s\n\n(%r)', msg.message, msg) if merr then msg = new_msg else - msg = format_string('table error without .message:\n(%r)', - msg) + msg = format_string('table error without .message:\n(%r)', msg) end elseif type(msg) ~= 'string' then msg = format_string('non-string non-table error:\n%r', msg) end - error(format_string('Error while processing test (%r, %s):\n%s', - str, FLAGS_TO_STR[flags], msg)) + error( + format_string( + 'Error while processing test (%r, %s):\n%s', + str, + FLAGS_TO_STR[flags], + msg + ) + ) end end end local function hl(group, str, shift) return function(next_col) local col = next_col + (shift or 0) - return (('%s:%u:%u:%s'):format( - 'Nvim' .. group, - 0, - col, - str)), (col + #str) + return (('%s:%u:%u:%s'):format('Nvim' .. group, 0, col, str)), (col + #str) end end local function fmtn(typ, args, rest) - if (typ == 'UnknownFigure' - or typ == 'DictLiteral' - or typ == 'CurlyBracesIdentifier' - or typ == 'Lambda') then + if + typ == 'UnknownFigure' + or typ == 'DictLiteral' + or typ == 'CurlyBracesIdentifier' + or typ == 'Lambda' + then return ('%s%s'):format(typ, rest) elseif typ == 'DoubleQuotedString' or typ == 'SingleQuotedString' then if args:sub(-4) == 'NULL' then @@ -2773,18 +2951,17 @@ describe('API', function() return ('%s(%s)%s'):format(typ, args, rest) end end - require('test.unit.viml.expressions.parser_tests')( - it, _check_parsing, hl, fmtn) + require('test.unit.viml.expressions.parser_tests')(it, _check_parsing, hl, fmtn) end) describe('nvim_list_uis', function() it('returns empty if --headless', function() -- Test runner defaults to --headless. - eq({}, nvim("list_uis")) + eq({}, api.nvim_list_uis()) end) it('returns attached UIs', function() local screen = Screen.new(20, 4) - screen:attach({override=true}) + screen:attach({ override = true }) local expected = { { chan = 1, @@ -2806,10 +2983,10 @@ describe('API', function() term_colors = 0, term_name = '', width = 20, - } + }, } - eq(expected, nvim("list_uis")) + eq(expected, api.nvim_list_uis()) screen:detach() screen = Screen.new(44, 99) @@ -2818,96 +2995,102 @@ describe('API', function() expected[1].override = false expected[1].width = 44 expected[1].height = 99 - eq(expected, nvim("list_uis")) + eq(expected, api.nvim_list_uis()) end) end) describe('nvim_create_namespace', function() it('works', function() - eq({}, meths.get_namespaces()) - eq(1, meths.create_namespace("ns-1")) - eq(2, meths.create_namespace("ns-2")) - eq(1, meths.create_namespace("ns-1")) - eq({["ns-1"]=1, ["ns-2"]=2}, meths.get_namespaces()) - eq(3, meths.create_namespace("")) - eq(4, meths.create_namespace("")) - eq({["ns-1"]=1, ["ns-2"]=2}, meths.get_namespaces()) + eq({}, api.nvim_get_namespaces()) + eq(1, api.nvim_create_namespace('ns-1')) + eq(2, api.nvim_create_namespace('ns-2')) + eq(1, api.nvim_create_namespace('ns-1')) + eq({ ['ns-1'] = 1, ['ns-2'] = 2 }, api.nvim_get_namespaces()) + eq(3, api.nvim_create_namespace('')) + eq(4, api.nvim_create_namespace('')) + eq({ ['ns-1'] = 1, ['ns-2'] = 2 }, api.nvim_get_namespaces()) end) end) describe('nvim_create_buf', function() it('works', function() - eq({id=2}, meths.create_buf(true, false)) - eq({id=3}, meths.create_buf(false, false)) - eq(' 1 %a "[No Name]" line 1\n'.. - ' 2 h "[No Name]" line 0', - meths.command_output("ls")) + eq(2, api.nvim_create_buf(true, false)) + eq(3, api.nvim_create_buf(false, false)) + eq( + ' 1 %a "[No Name]" line 1\n' + .. ' 2 h "[No Name]" line 0', + command_output('ls') + ) -- current buffer didn't change - eq({id=1}, meths.get_current_buf()) + eq(1, api.nvim_get_current_buf()) local screen = Screen.new(20, 4) screen:attach() - meths.buf_set_lines(2, 0, -1, true, {"some text"}) - meths.set_current_buf(2) - screen:expect([[ + api.nvim_buf_set_lines(2, 0, -1, true, { 'some text' }) + api.nvim_set_current_buf(2) + screen:expect( + [[ ^some text | - {1:~ }| - {1:~ }| + {1:~ }|*2 | - ]], { - [1] = {bold = true, foreground = Screen.colors.Blue1}, - }) + ]], + { + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + } + ) end) it('can change buftype before visiting', function() - meths.set_option_value("hidden", false, {}) - eq({id=2}, meths.create_buf(true, false)) - meths.set_option_value("buftype", "nofile", {buf=2}) - meths.buf_set_lines(2, 0, -1, true, {"test text"}) - command("split | buffer 2") - eq({id=2}, meths.get_current_buf()) + api.nvim_set_option_value('hidden', false, {}) + eq(2, api.nvim_create_buf(true, false)) + api.nvim_set_option_value('buftype', 'nofile', { buf = 2 }) + api.nvim_buf_set_lines(2, 0, -1, true, { 'test text' }) + command('split | buffer 2') + eq(2, api.nvim_get_current_buf()) -- if the buf_set_option("buftype") didn't work, this would error out. - command("close") - eq({id=1}, meths.get_current_buf()) + command('close') + eq(1, api.nvim_get_current_buf()) end) - it("does not trigger BufEnter, BufWinEnter", function() - command("let g:fired = v:false") - command("au BufEnter,BufWinEnter * let g:fired = v:true") + it('does not trigger BufEnter, BufWinEnter', function() + command('let g:fired = v:false') + command('au BufEnter,BufWinEnter * let g:fired = v:true') - eq({id=2}, meths.create_buf(true, false)) - meths.buf_set_lines(2, 0, -1, true, {"test", "text"}) + eq(2, api.nvim_create_buf(true, false)) + api.nvim_buf_set_lines(2, 0, -1, true, { 'test', 'text' }) eq(false, eval('g:fired')) end) it('TextChanged and TextChangedI do not trigger without changes', function() - local buf = meths.create_buf(true, false) + local buf = api.nvim_create_buf(true, false) command([[let g:changed = '']]) - meths.create_autocmd({'TextChanged', 'TextChangedI'}, { + api.nvim_create_autocmd({ 'TextChanged', 'TextChangedI' }, { buffer = buf, command = 'let g:changed ..= mode()', }) - meths.set_current_buf(buf) + api.nvim_set_current_buf(buf) feed('i') - eq('', meths.get_var('changed')) + eq('', api.nvim_get_var('changed')) end) it('scratch-buffer', function() - eq({id=2}, meths.create_buf(false, true)) - eq({id=3}, meths.create_buf(true, true)) - eq({id=4}, meths.create_buf(true, true)) + eq(2, api.nvim_create_buf(false, true)) + eq(3, api.nvim_create_buf(true, true)) + eq(4, api.nvim_create_buf(true, true)) local scratch_bufs = { 2, 3, 4 } - eq(' 1 %a "[No Name]" line 1\n'.. - ' 3 h "[Scratch]" line 0\n'.. - ' 4 h "[Scratch]" line 0', - exec_capture('ls')) + eq( + ' 1 %a "[No Name]" line 1\n' + .. ' 3 h "[Scratch]" line 0\n' + .. ' 4 h "[Scratch]" line 0', + exec_capture('ls') + ) -- current buffer didn't change - eq({id=1}, meths.get_current_buf()) + eq(1, api.nvim_get_current_buf()) local screen = Screen.new(20, 4) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, }) screen:attach() @@ -2915,35 +3098,33 @@ describe('API', function() -- Editing a scratch-buffer does NOT change its properties. -- local edited_buf = 2 - meths.buf_set_lines(edited_buf, 0, -1, true, {"some text"}) - for _,b in ipairs(scratch_bufs) do - eq('nofile', meths.get_option_value('buftype', {buf=b})) - eq('hide', meths.get_option_value('bufhidden', {buf=b})) - eq(false, meths.get_option_value('swapfile', {buf=b})) - eq(false, meths.get_option_value('modeline', {buf=b})) + api.nvim_buf_set_lines(edited_buf, 0, -1, true, { 'some text' }) + for _, b in ipairs(scratch_bufs) do + eq('nofile', api.nvim_get_option_value('buftype', { buf = b })) + eq('hide', api.nvim_get_option_value('bufhidden', { buf = b })) + eq(false, api.nvim_get_option_value('swapfile', { buf = b })) + eq(false, api.nvim_get_option_value('modeline', { buf = b })) end -- -- Visiting a scratch-buffer DOES NOT change its properties. -- - meths.set_current_buf(edited_buf) + api.nvim_set_current_buf(edited_buf) screen:expect([[ ^some text | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) - eq('nofile', meths.get_option_value('buftype', {buf=edited_buf})) - eq('hide', meths.get_option_value('bufhidden', {buf=edited_buf})) - eq(false, meths.get_option_value('swapfile', {buf=edited_buf})) - eq(false, meths.get_option_value('modeline', {buf=edited_buf})) + eq('nofile', api.nvim_get_option_value('buftype', { buf = edited_buf })) + eq('hide', api.nvim_get_option_value('bufhidden', { buf = edited_buf })) + eq(false, api.nvim_get_option_value('swapfile', { buf = edited_buf })) + eq(false, api.nvim_get_option_value('modeline', { buf = edited_buf })) -- Scratch buffer can be wiped without error. command('bwipe') screen:expect([[ ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) end) @@ -2959,117 +3140,121 @@ describe('API', function() describe('nvim_get_runtime_file', function() local p = helpers.alter_slashes it('can find files', function() - eq({}, meths.get_runtime_file("bork.borkbork", false)) - eq({}, meths.get_runtime_file("bork.borkbork", true)) - eq(1, #meths.get_runtime_file("autoload/msgpack.vim", false)) - eq(1, #meths.get_runtime_file("autoload/msgpack.vim", true)) - local val = meths.get_runtime_file("autoload/remote/*.vim", true) + eq({}, api.nvim_get_runtime_file('bork.borkbork', false)) + eq({}, api.nvim_get_runtime_file('bork.borkbork', true)) + eq(1, #api.nvim_get_runtime_file('autoload/msgpack.vim', false)) + eq(1, #api.nvim_get_runtime_file('autoload/msgpack.vim', true)) + local val = api.nvim_get_runtime_file('autoload/remote/*.vim', true) eq(2, #val) - if endswith(val[1], "define.vim") then - ok(endswith(val[1], p"autoload/remote/define.vim")) - ok(endswith(val[2], p"autoload/remote/host.vim")) + if endswith(val[1], 'define.vim') then + ok(endswith(val[1], p 'autoload/remote/define.vim')) + ok(endswith(val[2], p 'autoload/remote/host.vim')) else - ok(endswith(val[1], p"autoload/remote/host.vim")) - ok(endswith(val[2], p"autoload/remote/define.vim")) + ok(endswith(val[1], p 'autoload/remote/host.vim')) + ok(endswith(val[2], p 'autoload/remote/define.vim')) end - val = meths.get_runtime_file("autoload/remote/*.vim", false) + val = api.nvim_get_runtime_file('autoload/remote/*.vim', false) eq(1, #val) - ok(endswith(val[1], p"autoload/remote/define.vim") - or endswith(val[1], p"autoload/remote/host.vim")) + ok( + endswith(val[1], p 'autoload/remote/define.vim') + or endswith(val[1], p 'autoload/remote/host.vim') + ) - val = meths.get_runtime_file("lua", true) + val = api.nvim_get_runtime_file('lua', true) eq(1, #val) - ok(endswith(val[1], p"lua")) + ok(endswith(val[1], p 'lua')) - val = meths.get_runtime_file("lua/vim", true) + val = api.nvim_get_runtime_file('lua/vim', true) eq(1, #val) - ok(endswith(val[1], p"lua/vim")) + ok(endswith(val[1], p 'lua/vim')) end) it('can find directories', function() - local val = meths.get_runtime_file("lua/", true) + local val = api.nvim_get_runtime_file('lua/', true) eq(1, #val) - ok(endswith(val[1], p"lua/")) + ok(endswith(val[1], p 'lua/')) - val = meths.get_runtime_file("lua/vim/", true) + val = api.nvim_get_runtime_file('lua/vim/', true) eq(1, #val) - ok(endswith(val[1], p"lua/vim/")) + ok(endswith(val[1], p 'lua/vim/')) - eq({}, meths.get_runtime_file("foobarlang/", true)) + eq({}, api.nvim_get_runtime_file('foobarlang/', true)) end) it('can handle bad patterns', function() skip(is_os('win')) - eq("Vim:E220: Missing }.", pcall_err(meths.get_runtime_file, "{", false)) + eq('Vim:E220: Missing }.', pcall_err(api.nvim_get_runtime_file, '{', false)) - eq('Vim(echo):E5555: API call: Vim:E220: Missing }.', - exc_exec("echo nvim_get_runtime_file('{', v:false)")) + eq( + 'Vim(echo):E5555: API call: Vim:E220: Missing }.', + exc_exec("echo nvim_get_runtime_file('{', v:false)") + ) end) end) describe('nvim_get_all_options_info', function() it('should have key value pairs of option names', function() - local options_info = meths.get_all_options_info() + local options_info = api.nvim_get_all_options_info() neq(nil, options_info.listchars) neq(nil, options_info.tabstop) - eq(meths.get_option_info'winhighlight', options_info.winhighlight) + eq(api.nvim_get_option_info 'winhighlight', options_info.winhighlight) end) it('should not crash when echoed', function() - meths.exec2("echo nvim_get_all_options_info()", { output = true }) + api.nvim_exec2('echo nvim_get_all_options_info()', { output = true }) end) end) describe('nvim_get_option_info', function() it('should error for unknown options', function() - eq("Invalid option (not found): 'bogus'", pcall_err(meths.get_option_info, 'bogus')) + eq("Invalid option (not found): 'bogus'", pcall_err(api.nvim_get_option_info, 'bogus')) end) it('should return the same options for short and long name', function() - eq(meths.get_option_info'winhl', meths.get_option_info'winhighlight') + eq(api.nvim_get_option_info 'winhl', api.nvim_get_option_info 'winhighlight') end) it('should have information about window options', function() eq({ allows_duplicates = false, - commalist = true; - default = ""; - flaglist = false; - global_local = false; - last_set_chan = 0; - last_set_linenr = 0; - last_set_sid = 0; - name = "winhighlight"; - scope = "win"; - shortname = "winhl"; - type = "string"; - was_set = false; - }, meths.get_option_info'winhl') + commalist = true, + default = '', + flaglist = false, + global_local = false, + last_set_chan = 0, + last_set_linenr = 0, + last_set_sid = 0, + name = 'winhighlight', + scope = 'win', + shortname = 'winhl', + type = 'string', + was_set = false, + }, api.nvim_get_option_info 'winhl') end) it('should have information about buffer options', function() eq({ allows_duplicates = true, commalist = false, - default = "", + default = '', flaglist = false, global_local = false, last_set_chan = 0, last_set_linenr = 0, last_set_sid = 0, - name = "filetype", - scope = "buf", - shortname = "ft", - type = "string", - was_set = false - }, meths.get_option_info'filetype') + name = 'filetype', + scope = 'buf', + shortname = 'ft', + type = 'string', + was_set = false, + }, api.nvim_get_option_info 'filetype') end) it('should have information about global options', function() -- precondition: the option was changed from its default -- in test setup. - eq(false, meths.get_option_value('showcmd', {})) + eq(false, api.nvim_get_option_value('showcmd', {})) eq({ allows_duplicates = true, @@ -3080,14 +3265,14 @@ describe('API', function() last_set_chan = 0, last_set_linenr = 0, last_set_sid = -2, - name = "showcmd", - scope = "global", - shortname = "sc", - type = "boolean", - was_set = true - }, meths.get_option_info'showcmd') + name = 'showcmd', + scope = 'global', + shortname = 'sc', + type = 'boolean', + was_set = true, + }, api.nvim_get_option_info 'showcmd') - meths.set_option_value('showcmd', true, {}) + api.nvim_set_option_value('showcmd', true, {}) eq({ allows_duplicates = true, @@ -3098,12 +3283,12 @@ describe('API', function() last_set_chan = 1, last_set_linenr = 0, last_set_sid = -9, - name = "showcmd", - scope = "global", - shortname = "sc", - type = "boolean", - was_set = true - }, meths.get_option_info'showcmd') + name = 'showcmd', + scope = 'global', + shortname = 'sc', + type = 'boolean', + was_set = true, + }, api.nvim_get_option_info 'showcmd') end) end) @@ -3114,7 +3299,9 @@ describe('API', function() before_each(function() fname = tmpname() - write_file(fname, [[ + write_file( + fname, + [[ setglobal dictionary=mydict " 1, global-local (buffer) setlocal formatprg=myprg " 2, global-local (buffer) setglobal equalprg=prg1 " 3, global-local (buffer) @@ -3124,21 +3311,22 @@ describe('API', function() setglobal showbreak=aaa " 7, global-local (window) setlocal showbreak=bbb " 8, global-local (window) setglobal completeopt=menu " 9, global - ]]) + ]] + ) exec_lua 'vim.cmd.vsplit()' - meths.create_buf(false, false) + api.nvim_create_buf(false, false) - bufs = meths.list_bufs() - wins = meths.list_wins() + bufs = api.nvim_list_bufs() + wins = api.nvim_list_wins() - meths.win_set_buf(wins[1].id, bufs[1].id) - meths.win_set_buf(wins[2].id, bufs[2].id) + api.nvim_win_set_buf(wins[1], bufs[1]) + api.nvim_win_set_buf(wins[2], bufs[2]) - meths.set_current_win(wins[2].id) - meths.exec('source ' .. fname, false) + api.nvim_set_current_win(wins[2]) + api.nvim_exec('source ' .. fname, false) - meths.set_current_win(wins[1].id) + api.nvim_set_current_win(wins[1]) end) after_each(function() @@ -3146,12 +3334,13 @@ describe('API', function() end) it('should return option information', function() - eq(meths.get_option_info('dictionary'), meths.get_option_info2('dictionary', {})) -- buffer - eq(meths.get_option_info('fillchars'), meths.get_option_info2('fillchars', {})) -- window - eq(meths.get_option_info('completeopt'), meths.get_option_info2('completeopt', {})) -- global + eq(api.nvim_get_option_info('dictionary'), api.nvim_get_option_info2('dictionary', {})) -- buffer + eq(api.nvim_get_option_info('fillchars'), api.nvim_get_option_info2('fillchars', {})) -- window + eq(api.nvim_get_option_info('completeopt'), api.nvim_get_option_info2('completeopt', {})) -- global end) describe('last set', function() + -- stylua: ignore local tests = { {desc="(buf option, global requested, global set) points to global", linenr=1, sid=1, args={'dictionary', {scope='global'}}}, {desc="(buf option, global requested, local set) is not set", linenr=0, sid=0, args={'formatprg', {scope='global'}}}, @@ -3179,21 +3368,21 @@ describe('API', function() for _, t in pairs(tests) do it(t.desc, function() -- Switch to the target buffer/window so that curbuf/curwin are used. - meths.set_current_win(wins[2].id) - local info = meths.get_option_info2(unpack(t.args)) + api.nvim_set_current_win(wins[2]) + local info = api.nvim_get_option_info2(unpack(t.args)) eq(t.linenr, info.last_set_linenr) eq(t.sid, info.last_set_sid) end) end it('is provided for cross-buffer requests', function() - local info = meths.get_option_info2('formatprg', {buf=bufs[2].id}) + local info = api.nvim_get_option_info2('formatprg', { buf = bufs[2] }) eq(2, info.last_set_linenr) eq(1, info.last_set_sid) end) it('is provided for cross-window requests', function() - local info = meths.get_option_info2('listchars', {win=wins[2].id}) + local info = api.nvim_get_option_info2('listchars', { win = wins[2] }) eq(6, info.last_set_linenr) eq(1, info.last_set_sid) end) @@ -3207,11 +3396,11 @@ describe('API', function() screen = Screen.new(40, 8) screen:attach() screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, - [1] = {bold = true, foreground = Screen.colors.SeaGreen}, - [2] = {bold = true, reverse = true}, - [3] = {foreground = Screen.colors.Brown, bold = true}, -- Statement - [4] = {foreground = Screen.colors.SlateBlue}, -- Special + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { bold = true, foreground = Screen.colors.SeaGreen }, + [2] = { bold = true, reverse = true }, + [3] = { foreground = Screen.colors.Brown, bold = true }, -- Statement + [4] = { foreground = Screen.colors.SlateBlue }, -- Special }) command('highlight Statement gui=bold guifg=Brown') command('highlight Special guifg=SlateBlue') @@ -3219,60 +3408,57 @@ describe('API', function() it('should clear cmdline message before echo', function() feed(':call nvim_echo([["msg"]], v:false, {})<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 msg | - ]]} + ]], + } end) it('can show highlighted line', function() - nvim_async("echo", {{"msg_a"}, {"msg_b", "Statement"}, {"msg_c", "Special"}}, true, {}) - screen:expect{grid=[[ + async_meths.nvim_echo( + { { 'msg_a' }, { 'msg_b', 'Statement' }, { 'msg_c', 'Special' } }, + true, + {} + ) + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 msg_a{3:msg_b}{4:msg_c} | - ]]} + ]], + } end) it('can show highlighted multiline', function() - nvim_async("echo", {{"msg_a\nmsg_a", "Statement"}, {"msg_b", "Special"}}, true, {}) - screen:expect{grid=[[ + async_meths.nvim_echo({ { 'msg_a\nmsg_a', 'Statement' }, { 'msg_b', 'Special' } }, true, {}) + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {2: }| {3:msg_a} | {3:msg_a}{4:msg_b} | {1:Press ENTER or type command to continue}^ | - ]]} + ]], + } end) it('can save message history', function() - nvim('command', 'set cmdheight=2') -- suppress Press ENTER - nvim("echo", {{"msg\nmsg"}, {"msg"}}, true, {}) - eq("msg\nmsgmsg", exec_capture('messages')) + command('set cmdheight=2') -- suppress Press ENTER + api.nvim_echo({ { 'msg\nmsg' }, { 'msg' } }, true, {}) + eq('msg\nmsgmsg', exec_capture('messages')) end) it('can disable saving message history', function() - nvim('command', 'set cmdheight=2') -- suppress Press ENTER - nvim_async("echo", {{"msg\nmsg"}, {"msg"}}, false, {}) - eq("", exec_capture('messages')) + command('set cmdheight=2') -- suppress Press ENTER + async_meths.nvim_echo({ { 'msg\nmsg' }, { 'msg' } }, false, {}) + eq('', exec_capture('messages')) end) end) - describe('nvim_open_term', function() local screen @@ -3280,24 +3466,37 @@ describe('API', function() screen = Screen.new(100, 35) screen:attach() screen:set_default_attr_ids({ - [0] = {bold=true, foreground=Screen.colors.Blue}, - [1] = {background = Screen.colors.Plum1}; - [2] = {background = tonumber('0xffff40'), bg_indexed = true}; - [3] = {background = Screen.colors.Plum1, fg_indexed = true, foreground = tonumber('0x00e000')}; - [4] = {bold = true, reverse = true, background = Screen.colors.Plum1}; - [5] = {foreground = Screen.colors.Blue, background = Screen.colors.LightMagenta, bold = true}; - [6] = {bold = true}; - [7] = {reverse = true, background = Screen.colors.LightMagenta}; + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { background = Screen.colors.Plum1 }, + [2] = { background = tonumber('0xffff40'), bg_indexed = true }, + [3] = { + background = Screen.colors.Plum1, + fg_indexed = true, + foreground = tonumber('0x00e000'), + }, + [4] = { bold = true, reverse = true, background = Screen.colors.Plum1 }, + [5] = { + foreground = Screen.colors.Blue, + background = Screen.colors.LightMagenta, + bold = true, + }, + [6] = { bold = true }, + [7] = { reverse = true, background = Screen.colors.LightMagenta }, }) end) it('can batch process sequences', function() - local b = meths.create_buf(true,true) - meths.open_win(b, false, {width=79, height=31, row=1, col=1, relative='editor'}) - local t = meths.open_term(b, {}) - - meths.chan_send(t, io.open("test/functional/fixtures/smile2.cat", "r"):read("*a")) - screen:expect{grid=[[ + local b = api.nvim_create_buf(true, true) + api.nvim_open_win( + b, + false, + { width = 79, height = 31, row = 1, col = 1, relative = 'editor' } + ) + local t = api.nvim_open_term(b, {}) + + api.nvim_chan_send(t, io.open('test/functional/fixtures/smile2.cat', 'r'):read('*a')) + screen:expect { + grid = [[ ^ | {0:~}{1::smile }{0: }| {0:~}{1: }{2:oooo$$$$$$$$$$$$oooo}{1: }{0: }| @@ -3330,15 +3529,17 @@ describe('API', function() {0:~}{3:Press ENTER or type command to continue}{1: }{0: }| {0:~}{4:term://~/config2/docs/pres//32693:vim --clean +smile 29,39 All}{0: }| {0:~}{1::call nvim__screenshot("smile2.cat") }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]]} + ]], + } end) it('can handle input', function() screen:try_resize(50, 10) - eq({3, 2}, exec_lua [[ + eq( + { 3, 2 }, + exec_lua [[ buf = vim.api.nvim_create_buf(1,1) stream = '' @@ -3354,251 +3555,297 @@ describe('API', function() term = vim.api.nvim_open_term(buf, {on_input=input}) vim.api.nvim_open_win(buf, true, {width=40, height=5, row=1, col=1, relative='editor'}) return {term, buf} - ]]) + ]] + ) - screen:expect{grid=[[ + screen:expect { + grid = [[ | {0:~}{1:^ }{0: }| - {0:~}{1: }{0: }| - {0:~}{1: }{0: }| - {0:~}{1: }{0: }| - {0:~}{1: }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~}{1: }{0: }|*4 + {0:~ }|*3 | - ]]} + ]], + } feed 'iba<c-x>bla' - screen:expect{grid=[[ + screen:expect { + grid = [[ | {0:~}{7: }{1: }{0: }| - {0:~}{1: }{0: }| - {0:~}{1: }{0: }| - {0:~}{1: }{0: }| - {0:~}{1: }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~}{1: }{0: }|*4 + {0:~ }|*3 {6:-- TERMINAL --} | - ]]} + ]], + } eq('ba\024bla', exec_lua [[ return stream ]]) - eq({3,2}, exec_lua [[ return vals ]]) + eq({ 3, 2 }, exec_lua [[ return vals ]]) exec_lua [[ do_the_echo = true ]] feed 'herrejösses!' - screen:expect{grid=[[ + screen:expect { + grid = [[ | {0:~}{1:herrejösses!}{7: }{1: }{0: }| - {0:~}{1: }{0: }| - {0:~}{1: }{0: }| - {0:~}{1: }{0: }| - {0:~}{1: }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~}{1: }{0: }|*4 + {0:~ }|*3 {6:-- TERMINAL --} | - ]]} + ]], + } eq('ba\024blaherrejösses!', exec_lua [[ return stream ]]) end) end) describe('nvim_del_mark', function() it('works', function() - local buf = meths.create_buf(false,true) - meths.buf_set_lines(buf, -1, -1, true, {'a', 'bit of', 'text'}) - eq(true, meths.buf_set_mark(buf, 'F', 2, 2, {})) - eq(true, meths.del_mark('F')) - eq({0, 0}, meths.buf_get_mark(buf, 'F')) + local buf = api.nvim_create_buf(false, true) + api.nvim_buf_set_lines(buf, -1, -1, true, { 'a', 'bit of', 'text' }) + eq(true, api.nvim_buf_set_mark(buf, 'F', 2, 2, {})) + eq(true, api.nvim_del_mark('F')) + eq({ 0, 0 }, api.nvim_buf_get_mark(buf, 'F')) end) it('validation', function() - eq("Invalid mark name (must be file/uppercase): 'f'", pcall_err(meths.del_mark, 'f')) - eq("Invalid mark name (must be file/uppercase): '!'", pcall_err(meths.del_mark, '!')) - eq("Invalid mark name (must be a single char): 'fail'", pcall_err(meths.del_mark, 'fail')) + eq("Invalid mark name (must be file/uppercase): 'f'", pcall_err(api.nvim_del_mark, 'f')) + eq("Invalid mark name (must be file/uppercase): '!'", pcall_err(api.nvim_del_mark, '!')) + eq("Invalid mark name (must be a single char): 'fail'", pcall_err(api.nvim_del_mark, 'fail')) end) end) describe('nvim_get_mark', function() it('works', function() - local buf = meths.create_buf(false,true) - meths.buf_set_lines(buf, -1, -1, true, {'a', 'bit of', 'text'}) - meths.buf_set_mark(buf, 'F', 2, 2, {}) - meths.buf_set_name(buf, "mybuf") - local mark = meths.get_mark('F', {}) + local buf = api.nvim_create_buf(false, true) + api.nvim_buf_set_lines(buf, -1, -1, true, { 'a', 'bit of', 'text' }) + api.nvim_buf_set_mark(buf, 'F', 2, 2, {}) + api.nvim_buf_set_name(buf, 'mybuf') + local mark = api.nvim_get_mark('F', {}) -- Compare the path tail only - assert(string.find(mark[4], "mybuf$")) - eq({2, 2, buf.id, mark[4]}, mark) + assert(string.find(mark[4], 'mybuf$')) + eq({ 2, 2, buf, mark[4] }, mark) end) it('validation', function() - eq("Invalid mark name (must be file/uppercase): 'f'", pcall_err(meths.get_mark, 'f', {})) - eq("Invalid mark name (must be file/uppercase): '!'", pcall_err(meths.get_mark, '!', {})) - eq("Invalid mark name (must be a single char): 'fail'", pcall_err(meths.get_mark, 'fail', {})) + eq("Invalid mark name (must be file/uppercase): 'f'", pcall_err(api.nvim_get_mark, 'f', {})) + eq("Invalid mark name (must be file/uppercase): '!'", pcall_err(api.nvim_get_mark, '!', {})) + eq( + "Invalid mark name (must be a single char): 'fail'", + pcall_err(api.nvim_get_mark, 'fail', {}) + ) end) it('returns the expected when mark is not set', function() - eq(true, meths.del_mark('A')) - eq({0, 0, 0, ''}, meths.get_mark('A', {})) + eq(true, api.nvim_del_mark('A')) + eq({ 0, 0, 0, '' }, api.nvim_get_mark('A', {})) end) it('works with deleted buffers', function() local fname = tmpname() write_file(fname, 'a\nbit of\text') - nvim("command", "edit " .. fname) - local buf = meths.get_current_buf() + command('edit ' .. fname) + local buf = api.nvim_get_current_buf() - meths.buf_set_mark(buf, 'F', 2, 2, {}) - nvim("command", "new") -- Create new buf to avoid :bd failing - nvim("command", "bd! " .. buf.id) + api.nvim_buf_set_mark(buf, 'F', 2, 2, {}) + command('new') -- Create new buf to avoid :bd failing + command('bd! ' .. buf) os.remove(fname) - local mark = meths.get_mark('F', {}) + local mark = api.nvim_get_mark('F', {}) -- To avoid comparing relative vs absolute path local mfname = mark[4] local tail_patt = [[[\/][^\/]*$]] -- tail of paths should be equals eq(fname:match(tail_patt), mfname:match(tail_patt)) - eq({2, 2, buf.id, mark[4]}, mark) + eq({ 2, 2, buf, mark[4] }, mark) end) end) + describe('nvim_eval_statusline', function() it('works', function() eq({ - str = '%StatusLineStringWithHighlights', - width = 31 - }, - meths.eval_statusline( - '%%StatusLineString%#WarningMsg#WithHighlights', - {})) + str = '%StatusLineStringWithHighlights', + width = 31, + }, api.nvim_eval_statusline('%%StatusLineString%#WarningMsg#WithHighlights', {})) end) - it('doesn\'t exceed maxwidth', function() + + it("doesn't exceed maxwidth", function() eq({ - str = 'Should be trun>', - width = 15 - }, - meths.eval_statusline( - 'Should be truncated%<', - { maxwidth = 15 })) - end) - it('supports ASCII fillchar', function() - eq({ str = 'a~~~b', width = 5 }, - meths.eval_statusline('a%=b', { fillchar = '~', maxwidth = 5 })) - end) - it('supports single-width multibyte fillchar', function() - eq({ str = 'a━━━b', width = 5 }, - meths.eval_statusline('a%=b', { fillchar = '━', maxwidth = 5 })) - end) - it('treats double-width fillchar as single-width', function() - eq({ str = 'a哦哦哦b', width = 5 }, - meths.eval_statusline('a%=b', { fillchar = '哦', maxwidth = 5 })) - end) - it('treats control character fillchar as single-width', function() - eq({ str = 'a\031\031\031b', width = 5 }, - meths.eval_statusline('a%=b', { fillchar = '\031', maxwidth = 5 })) - end) + str = 'Should be trun>', + width = 15, + }, api.nvim_eval_statusline('Should be truncated%<', { maxwidth = 15 })) + end) + + it('has correct default fillchar', function() + local oldwin = api.nvim_get_current_win() + command('set fillchars=stl:#,stlnc:$,wbr:%') + command('new') + eq({ str = 'a###b', width = 5 }, api.nvim_eval_statusline('a%=b', { maxwidth = 5 })) + eq( + { str = 'a$$$b', width = 5 }, + api.nvim_eval_statusline('a%=b', { winid = oldwin, maxwidth = 5 }) + ) + eq( + { str = 'a%%%b', width = 5 }, + api.nvim_eval_statusline('a%=b', { use_winbar = true, maxwidth = 5 }) + ) + eq( + { str = 'a b', width = 5 }, + api.nvim_eval_statusline('a%=b', { use_tabline = true, maxwidth = 5 }) + ) + eq( + { str = 'a b', width = 5 }, + api.nvim_eval_statusline('a%=b', { use_statuscol_lnum = 1, maxwidth = 5 }) + ) + end) + + for fc, desc in pairs({ + ['~'] = 'supports ASCII fillchar', + ['━'] = 'supports single-width multibyte fillchar', + ['c̳'] = 'supports single-width fillchar with composing', + ['哦'] = 'treats double-width fillchar as single-width', + ['\031'] = 'treats control character fillchar as single-width', + }) do + it(desc, function() + eq( + { str = 'a' .. fc:rep(3) .. 'b', width = 5 }, + api.nvim_eval_statusline('a%=b', { fillchar = fc, maxwidth = 5 }) + ) + eq( + { str = 'a' .. fc:rep(3) .. 'b', width = 5 }, + api.nvim_eval_statusline('a%=b', { fillchar = fc, use_winbar = true, maxwidth = 5 }) + ) + eq( + { str = 'a' .. fc:rep(3) .. 'b', width = 5 }, + api.nvim_eval_statusline('a%=b', { fillchar = fc, use_tabline = true, maxwidth = 5 }) + ) + eq( + { str = 'a' .. fc:rep(3) .. 'b', width = 5 }, + api.nvim_eval_statusline('a%=b', { fillchar = fc, use_statuscol_lnum = 1, maxwidth = 5 }) + ) + end) + end + it('rejects multiple-character fillchar', function() - eq("Invalid 'fillchar': expected single character", - pcall_err(meths.eval_statusline, '', { fillchar = 'aa' })) + eq( + "Invalid 'fillchar': expected single character", + pcall_err(api.nvim_eval_statusline, '', { fillchar = 'aa' }) + ) end) + it('rejects empty string fillchar', function() - eq("Invalid 'fillchar': expected single character", - pcall_err(meths.eval_statusline, '', { fillchar = '' })) + eq( + "Invalid 'fillchar': expected single character", + pcall_err(api.nvim_eval_statusline, '', { fillchar = '' }) + ) end) + it('rejects non-string fillchar', function() - eq("Invalid 'fillchar': expected String, got Integer", - pcall_err(meths.eval_statusline, '', { fillchar = 1 })) + eq( + "Invalid 'fillchar': expected String, got Integer", + pcall_err(api.nvim_eval_statusline, '', { fillchar = 1 }) + ) end) + it('rejects invalid string', function() - eq('E539: Illegal character <}>', - pcall_err(meths.eval_statusline, '%{%}', {})) + eq('E539: Illegal character <}>', pcall_err(api.nvim_eval_statusline, '%{%}', {})) end) + it('supports various items', function() - eq({ str = '0', width = 1 }, - meths.eval_statusline('%l', { maxwidth = 5 })) + eq({ str = '0', width = 1 }, api.nvim_eval_statusline('%l', { maxwidth = 5 })) command('set readonly') - eq({ str = '[RO]', width = 4 }, - meths.eval_statusline('%r', { maxwidth = 5 })) + eq({ str = '[RO]', width = 4 }, api.nvim_eval_statusline('%r', { maxwidth = 5 })) local screen = Screen.new(80, 24) screen:attach() command('set showcmd') feed('1234') - screen:expect({any = '1234'}) - eq({ str = '1234', width = 4 }, - meths.eval_statusline('%S', { maxwidth = 5 })) + screen:expect({ any = '1234' }) + eq({ str = '1234', width = 4 }, api.nvim_eval_statusline('%S', { maxwidth = 5 })) feed('56') - screen:expect({any = '123456'}) - eq({ str = '<3456', width = 5 }, - meths.eval_statusline('%S', { maxwidth = 5 })) + screen:expect({ any = '123456' }) + eq({ str = '<3456', width = 5 }, api.nvim_eval_statusline('%S', { maxwidth = 5 })) end) + describe('highlight parsing', function() it('works', function() - eq({ - str = "TextWithWarningHighlightTextWithUserHighlight", + eq( + { + str = 'TextWithWarningHighlightTextWithUserHighlight', width = 45, highlights = { { start = 0, group = 'WarningMsg' }, - { start = 24, group = 'User1' } + { start = 24, group = 'User1' }, }, }, - meths.eval_statusline( + api.nvim_eval_statusline( '%#WarningMsg#TextWithWarningHighlight%1*TextWithUserHighlight', - { highlights = true })) + { highlights = true } + ) + ) end) + it('works with no highlight', function() eq({ - str = "TextWithNoHighlight", - width = 19, - highlights = { - { start = 0, group = 'StatusLine' }, - }, + str = 'TextWithNoHighlight', + width = 19, + highlights = { + { start = 0, group = 'StatusLine' }, }, - meths.eval_statusline( - 'TextWithNoHighlight', - { highlights = true })) + }, api.nvim_eval_statusline('TextWithNoHighlight', { highlights = true })) end) + it('works with inactive statusline', function() command('split') - - eq({ + eq( + { str = 'TextWithNoHighlightTextWithWarningHighlight', width = 43, highlights = { { start = 0, group = 'StatusLineNC' }, - { start = 19, group = 'WarningMsg' } - } + { start = 19, group = 'WarningMsg' }, + }, }, - meths.eval_statusline( + api.nvim_eval_statusline( 'TextWithNoHighlight%#WarningMsg#TextWithWarningHighlight', - { winid = meths.list_wins()[2].id, highlights = true })) + { winid = api.nvim_list_wins()[2], highlights = true } + ) + ) end) + it('works with tabline', function() - eq({ + eq( + { str = 'TextWithNoHighlightTextWithWarningHighlight', width = 43, highlights = { { start = 0, group = 'TabLineFill' }, - { start = 19, group = 'WarningMsg' } - } + { start = 19, group = 'WarningMsg' }, + }, }, - meths.eval_statusline( + api.nvim_eval_statusline( 'TextWithNoHighlight%#WarningMsg#TextWithWarningHighlight', - { use_tabline = true, highlights = true })) + { use_tabline = true, highlights = true } + ) + ) end) + it('works with winbar', function() - eq({ + eq( + { str = 'TextWithNoHighlightTextWithWarningHighlight', width = 43, highlights = { { start = 0, group = 'WinBar' }, - { start = 19, group = 'WarningMsg' } - } + { start = 19, group = 'WarningMsg' }, + }, }, - meths.eval_statusline( + api.nvim_eval_statusline( 'TextWithNoHighlight%#WarningMsg#TextWithWarningHighlight', - { use_winbar = true, highlights = true })) + { use_winbar = true, highlights = true } + ) + ) end) + it('works with statuscolumn', function() exec([[ let &stc='%C%s%=%l ' - set cul nu nuw=3 scl=yes:2 fdc=2 + " should not use "stl" from 'fillchars' + set cul nu nuw=3 scl=yes:2 fdc=2 fillchars=stl:# call setline(1, repeat(['aaaaa'], 5)) let g:ns = nvim_create_namespace('') call sign_define('a', {'text':'aa', 'texthl':'IncSearch', 'numhl':'Normal'}) @@ -3615,28 +3862,31 @@ describe('API', function() { group = 'Normal', start = 6 }, { group = 'IncSearch', start = 6 }, { group = 'ErrorMsg', start = 8 }, - { group = 'Normal', start = 10 } - } - }, meths.eval_statusline('%C%s%=%l ', { use_statuscol_lnum = 4, highlights = true })) - eq({ - str = '3 ' , - width = 2, - highlights = { - { group = 'LineNr', start = 0 }, - { group = 'ErrorMsg', start = 1 } - } - }, meths.eval_statusline('%l%#ErrorMsg# ', { use_statuscol_lnum = 3, highlights = true })) + { group = 'Normal', start = 10 }, + }, + }, api.nvim_eval_statusline( + '%C%s%=%l ', + { use_statuscol_lnum = 4, highlights = true } + )) + eq( + { + str = '3 ', + width = 2, + highlights = { + { group = 'LineNr', start = 0 }, + { group = 'ErrorMsg', start = 1 }, + }, + }, + api.nvim_eval_statusline('%l%#ErrorMsg# ', { use_statuscol_lnum = 3, highlights = true }) + ) end) + it('no memory leak with click functions', function() - meths.eval_statusline('%@ClickFunc@StatusLineStringWithClickFunc%T', {}) + api.nvim_eval_statusline('%@ClickFunc@StatusLineStringWithClickFunc%T', {}) eq({ - str = 'StatusLineStringWithClickFunc', - width = 29 - }, - meths.eval_statusline( - '%@ClickFunc@StatusLineStringWithClickFunc%T', - {}) - ) + str = 'StatusLineStringWithClickFunc', + width = 29, + }, api.nvim_eval_statusline('%@ClickFunc@StatusLineStringWithClickFunc%T', {})) end) end) end) @@ -3649,8 +3899,8 @@ describe('API', function() bang = false, addr = 'none', magic = { - file = false, - bar = false + file = false, + bar = false, }, nargs = '*', nextcmd = '', @@ -3659,8 +3909,8 @@ describe('API', function() confirm = false, emsg_silent = false, filter = { - pattern = "", - force = false + pattern = '', + force = false, }, hide = false, horizontal = false, @@ -3673,13 +3923,13 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - split = "", + split = '', tab = -1, unsilent = false, verbose = -1, vertical = false, - } - }, meths.parse_cmd('echo foo', {})) + }, + }, api.nvim_parse_cmd('echo foo', {})) end) it('works with ranges', function() eq({ @@ -3689,8 +3939,8 @@ describe('API', function() range = { 4, 6 }, addr = 'line', magic = { - file = false, - bar = false + file = false, + bar = false, }, nargs = '*', nextcmd = '', @@ -3699,8 +3949,8 @@ describe('API', function() confirm = false, emsg_silent = false, filter = { - pattern = "", - force = false + pattern = '', + force = false, }, hide = false, horizontal = false, @@ -3713,13 +3963,13 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - split = "", + split = '', tab = -1, unsilent = false, verbose = -1, vertical = false, - } - }, meths.parse_cmd('4,6s/math.random/math.max/', {})) + }, + }, api.nvim_parse_cmd('4,6s/math.random/math.max/', {})) end) it('works with count', function() eq({ @@ -3730,8 +3980,8 @@ describe('API', function() count = 1, addr = 'buf', magic = { - file = false, - bar = true + file = false, + bar = true, }, nargs = '*', nextcmd = '', @@ -3740,8 +3990,8 @@ describe('API', function() confirm = false, emsg_silent = false, filter = { - pattern = "", - force = false + pattern = '', + force = false, }, hide = false, horizontal = false, @@ -3754,13 +4004,13 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - split = "", + split = '', tab = -1, unsilent = false, verbose = -1, vertical = false, - } - }, meths.parse_cmd('buffer 1', {})) + }, + }, api.nvim_parse_cmd('buffer 1', {})) end) it('works with register', function() eq({ @@ -3771,8 +4021,8 @@ describe('API', function() reg = '+', addr = 'line', magic = { - file = false, - bar = true + file = false, + bar = true, }, nargs = '0', nextcmd = '', @@ -3781,8 +4031,8 @@ describe('API', function() confirm = false, emsg_silent = false, filter = { - pattern = "", - force = false + pattern = '', + force = false, }, hide = false, horizontal = false, @@ -3795,13 +4045,13 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - split = "", + split = '', tab = -1, unsilent = false, verbose = -1, vertical = false, - } - }, meths.parse_cmd('put +', {})) + }, + }, api.nvim_parse_cmd('put +', {})) eq({ cmd = 'put', args = {}, @@ -3810,8 +4060,8 @@ describe('API', function() reg = '', addr = 'line', magic = { - file = false, - bar = true + file = false, + bar = true, }, nargs = '0', nextcmd = '', @@ -3820,8 +4070,8 @@ describe('API', function() confirm = false, emsg_silent = false, filter = { - pattern = "", - force = false + pattern = '', + force = false, }, hide = false, horizontal = false, @@ -3834,13 +4084,13 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - split = "", + split = '', tab = -1, unsilent = false, verbose = -1, vertical = false, - } - }, meths.parse_cmd('put', {})) + }, + }, api.nvim_parse_cmd('put', {})) end) it('works with range, count and register', function() eq({ @@ -3852,8 +4102,8 @@ describe('API', function() reg = '*', addr = 'line', magic = { - file = false, - bar = true + file = false, + bar = true, }, nargs = '0', nextcmd = '', @@ -3862,8 +4112,8 @@ describe('API', function() confirm = false, emsg_silent = false, filter = { - pattern = "", - force = false + pattern = '', + force = false, }, hide = false, horizontal = false, @@ -3876,13 +4126,13 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - split = "", + split = '', tab = -1, unsilent = false, verbose = -1, vertical = false, - } - }, meths.parse_cmd('1,3delete * 5', {})) + }, + }, api.nvim_parse_cmd('1,3delete * 5', {})) end) it('works with bang', function() eq({ @@ -3892,8 +4142,8 @@ describe('API', function() range = {}, addr = 'line', magic = { - file = true, - bar = true + file = true, + bar = true, }, nargs = '?', nextcmd = '', @@ -3902,8 +4152,8 @@ describe('API', function() confirm = false, emsg_silent = false, filter = { - pattern = "", - force = false + pattern = '', + force = false, }, hide = false, horizontal = false, @@ -3916,91 +4166,103 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - split = "", + split = '', tab = -1, unsilent = false, verbose = -1, vertical = false, }, - }, meths.parse_cmd('w!', {})) + }, api.nvim_parse_cmd('w!', {})) end) it('works with modifiers', function() - eq({ - cmd = 'split', - args = { 'foo.txt' }, - bang = false, - range = {}, - addr = '?', - magic = { + eq( + { + cmd = 'split', + args = { 'foo.txt' }, + bang = false, + range = {}, + addr = '?', + magic = { file = true, - bar = true - }, - nargs = '?', - nextcmd = '', - mods = { - browse = false, - confirm = false, - emsg_silent = true, - filter = { - pattern = "foo", - force = false + bar = true, + }, + nargs = '?', + nextcmd = '', + mods = { + browse = false, + confirm = false, + emsg_silent = true, + filter = { + pattern = 'foo', + force = false, + }, + hide = false, + horizontal = true, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = true, + split = 'topleft', + tab = 1, + unsilent = false, + verbose = 15, + vertical = false, }, - hide = false, - horizontal = true, - keepalt = false, - keepjumps = false, - keepmarks = false, - keeppatterns = false, - lockmarks = false, - noautocmd = false, - noswapfile = false, - sandbox = false, - silent = true, - split = "topleft", - tab = 1, - unsilent = false, - verbose = 15, - vertical = false, }, - }, meths.parse_cmd('15verbose silent! horizontal topleft tab filter /foo/ split foo.txt', {})) - eq({ - cmd = 'split', - args = { 'foo.txt' }, - bang = false, - range = {}, - addr = '?', - magic = { + api.nvim_parse_cmd( + '15verbose silent! horizontal topleft tab filter /foo/ split foo.txt', + {} + ) + ) + eq( + { + cmd = 'split', + args = { 'foo.txt' }, + bang = false, + range = {}, + addr = '?', + magic = { file = true, - bar = true - }, - nargs = '?', - nextcmd = '', - mods = { - browse = false, - confirm = true, - emsg_silent = false, - filter = { - pattern = "foo", - force = true + bar = true, + }, + nargs = '?', + nextcmd = '', + mods = { + browse = false, + confirm = true, + emsg_silent = false, + filter = { + pattern = 'foo', + force = true, + }, + hide = false, + horizontal = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + split = 'botright', + tab = 0, + unsilent = true, + verbose = 0, + vertical = false, }, - hide = false, - horizontal = false, - keepalt = false, - keepjumps = false, - keepmarks = false, - keeppatterns = false, - lockmarks = false, - noautocmd = false, - noswapfile = false, - sandbox = false, - silent = false, - split = "botright", - tab = 0, - unsilent = true, - verbose = 0, - vertical = false, }, - }, meths.parse_cmd('0verbose unsilent botright 0tab confirm filter! /foo/ split foo.txt', {})) + api.nvim_parse_cmd( + '0verbose unsilent botright 0tab confirm filter! /foo/ split foo.txt', + {} + ) + ) end) it('works with user commands', function() command('command -bang -nargs=+ -range -addr=lines MyCommand echo foo') @@ -4011,8 +4273,8 @@ describe('API', function() range = { 4, 6 }, addr = 'line', magic = { - file = false, - bar = false + file = false, + bar = false, }, nargs = '+', nextcmd = '', @@ -4021,8 +4283,8 @@ describe('API', function() confirm = false, emsg_silent = false, filter = { - pattern = "", - force = false + pattern = '', + force = false, }, hide = false, horizontal = false, @@ -4035,13 +4297,13 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - split = "", + split = '', tab = -1, unsilent = false, verbose = -1, vertical = false, - } - }, meths.parse_cmd('4,6MyCommand! test it', {})) + }, + }, api.nvim_parse_cmd('4,6MyCommand! test it', {})) end) it('works for commands separated by bar', function() eq({ @@ -4051,8 +4313,8 @@ describe('API', function() range = {}, addr = 'arg', magic = { - file = true, - bar = true + file = true, + bar = true, }, nargs = '*', nextcmd = 'argadd b.txt', @@ -4061,8 +4323,8 @@ describe('API', function() confirm = false, emsg_silent = false, filter = { - pattern = "", - force = false + pattern = '', + force = false, }, hide = false, horizontal = false, @@ -4075,13 +4337,13 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - split = "", + split = '', tab = -1, unsilent = false, verbose = -1, vertical = false, - } - }, meths.parse_cmd('argadd a.txt | argadd b.txt', {})) + }, + }, api.nvim_parse_cmd('argadd a.txt | argadd b.txt', {})) end) it('works for nargs=1', function() command('command -nargs=1 MyCommand echo <q-args>') @@ -4091,8 +4353,8 @@ describe('API', function() bang = false, addr = 'none', magic = { - file = false, - bar = false + file = false, + bar = false, }, nargs = '1', nextcmd = '', @@ -4101,8 +4363,8 @@ describe('API', function() confirm = false, emsg_silent = false, filter = { - pattern = "", - force = false + pattern = '', + force = false, }, hide = false, horizontal = false, @@ -4115,33 +4377,41 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - split = "", + split = '', tab = -1, unsilent = false, verbose = -1, vertical = false, - } - }, meths.parse_cmd('MyCommand test it', {})) + }, + }, api.nvim_parse_cmd('MyCommand test it', {})) end) it('validates command', function() - eq('Error while parsing command line', pcall_err(meths.parse_cmd, '', {})) - eq('Error while parsing command line', pcall_err(meths.parse_cmd, '" foo', {})) - eq('Error while parsing command line: E492: Not an editor command: Fubar', - pcall_err(meths.parse_cmd, 'Fubar', {})) + eq('Error while parsing command line', pcall_err(api.nvim_parse_cmd, '', {})) + eq('Error while parsing command line', pcall_err(api.nvim_parse_cmd, '" foo', {})) + eq( + 'Error while parsing command line: E492: Not an editor command: Fubar', + pcall_err(api.nvim_parse_cmd, 'Fubar', {}) + ) command('command! Fubar echo foo') - eq('Error while parsing command line: E477: No ! allowed', - pcall_err(meths.parse_cmd, 'Fubar!', {})) - eq('Error while parsing command line: E481: No range allowed', - pcall_err(meths.parse_cmd, '4,6Fubar', {})) + eq( + 'Error while parsing command line: E477: No ! allowed', + pcall_err(api.nvim_parse_cmd, 'Fubar!', {}) + ) + eq( + 'Error while parsing command line: E481: No range allowed', + pcall_err(api.nvim_parse_cmd, '4,6Fubar', {}) + ) command('command! Foobar echo foo') - eq('Error while parsing command line: E464: Ambiguous use of user-defined command', - pcall_err(meths.parse_cmd, 'F', {})) + eq( + 'Error while parsing command line: E464: Ambiguous use of user-defined command', + pcall_err(api.nvim_parse_cmd, 'F', {}) + ) end) it('does not interfere with printing line in Ex mode #19400', function() local screen = Screen.new(60, 7) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {bold = true, reverse = true}, -- MsgSeparator + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { bold = true, reverse = true }, -- MsgSeparator }) screen:attach() insert([[ @@ -4151,13 +4421,12 @@ describe('API', function() screen:expect([[ foo | bar | - {0:~ }| - {0:~ }| + {0:~ }|*2 {1: }| Entering Ex mode. Type "visual" to go to Normal mode. | :1^ | ]]) - eq('Error while parsing command line', pcall_err(meths.parse_cmd, '', {})) + eq('Error while parsing command line', pcall_err(api.nvim_parse_cmd, '', {})) feed('<CR>') screen:expect([[ foo | @@ -4170,16 +4439,16 @@ describe('API', function() ]]) end) it('does not move cursor or change search history/pattern #19878 #19890', function() - meths.buf_set_lines(0, 0, -1, true, {'foo', 'bar', 'foo', 'bar'}) - eq({1, 0}, meths.win_get_cursor(0)) - eq('', funcs.getreg('/')) - eq('', funcs.histget('search')) - feed(':') -- call the API in cmdline mode to test whether it changes search history + api.nvim_buf_set_lines(0, 0, -1, true, { 'foo', 'bar', 'foo', 'bar' }) + eq({ 1, 0 }, api.nvim_win_get_cursor(0)) + eq('', fn.getreg('/')) + eq('', fn.histget('search')) + feed(':') -- call the API in cmdline mode to test whether it changes search history eq({ cmd = 'normal', - args = {'x'}, + args = { 'x' }, bang = true, - range = {3, 4}, + range = { 3, 4 }, addr = 'line', magic = { file = false, @@ -4192,7 +4461,7 @@ describe('API', function() confirm = false, emsg_silent = false, filter = { - pattern = "", + pattern = '', force = false, }, hide = false, @@ -4206,101 +4475,134 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - split = "", + split = '', tab = -1, unsilent = false, verbose = -1, vertical = false, - } - }, meths.parse_cmd('+2;/bar/normal! x', {})) - eq({1, 0}, meths.win_get_cursor(0)) - eq('', funcs.getreg('/')) - eq('', funcs.histget('search')) + }, + }, api.nvim_parse_cmd('+2;/bar/normal! x', {})) + eq({ 1, 0 }, api.nvim_win_get_cursor(0)) + eq('', fn.getreg('/')) + eq('', fn.histget('search')) end) it('result can be used directly by nvim_cmd #20051', function() - eq("foo", meths.cmd(meths.parse_cmd('echo "foo"', {}), { output = true })) - meths.cmd(meths.parse_cmd("set cursorline", {}), {}) - eq(true, meths.get_option_value("cursorline", {})) + eq('foo', api.nvim_cmd(api.nvim_parse_cmd('echo "foo"', {}), { output = true })) + api.nvim_cmd(api.nvim_parse_cmd('set cursorline', {}), {}) + eq(true, api.nvim_get_option_value('cursorline', {})) end) it('no side-effects (error messages) in pcall() #20339', function() - eq({ false, 'Error while parsing command line: E16: Invalid range' }, - exec_lua([=[return {pcall(vim.api.nvim_parse_cmd, "'<,'>n", {})}]=])) + eq( + { false, 'Error while parsing command line: E16: Invalid range' }, + exec_lua([=[return {pcall(vim.api.nvim_parse_cmd, "'<,'>n", {})}]=]) + ) eq('', eval('v:errmsg')) end) end) describe('nvim_cmd', function() - it('works', function () - meths.cmd({ cmd = "set", args = { "cursorline" } }, {}) - eq(true, meths.get_option_value("cursorline", {})) + it('works', function() + api.nvim_cmd({ cmd = 'set', args = { 'cursorline' } }, {}) + eq(true, api.nvim_get_option_value('cursorline', {})) end) it('validation', function() - eq("Invalid 'cmd': expected non-empty String", - pcall_err(meths.cmd, { cmd = ""}, {})) - eq("Invalid 'cmd': expected String, got Array", - pcall_err(meths.cmd, { cmd = {}}, {})) - eq("Invalid 'args': expected Array, got Boolean", - pcall_err(meths.cmd, { cmd = "set", args = true }, {})) - eq("Invalid command arg: expected non-whitespace", - pcall_err(meths.cmd, { cmd = "set", args = {' '}, }, {})) - eq("Invalid command arg: expected valid type, got Array", - pcall_err(meths.cmd, { cmd = "set", args = {{}}, }, {})) - eq("Wrong number of arguments", - pcall_err(meths.cmd, { cmd = "aboveleft", args = {}, }, {})) - eq("Command cannot accept bang: print", - pcall_err(meths.cmd, { cmd = "print", args = {}, bang = true }, {})) - - eq("Command cannot accept range: set", - pcall_err(meths.cmd, { cmd = "set", args = {}, range = {1} }, {})) - eq("Invalid 'range': expected Array, got Boolean", - pcall_err(meths.cmd, { cmd = "print", args = {}, range = true }, {})) - eq("Invalid 'range': expected <=2 elements", - pcall_err(meths.cmd, { cmd = "print", args = {}, range = {1,2,3,4} }, {})) - eq("Invalid range element: expected non-negative Integer", - pcall_err(meths.cmd, { cmd = "print", args = {}, range = {-1} }, {})) - - eq("Command cannot accept count: set", - pcall_err(meths.cmd, { cmd = "set", args = {}, count = 1 }, {})) - eq("Invalid 'count': expected Integer, got Boolean", - pcall_err(meths.cmd, { cmd = "print", args = {}, count = true }, {})) - eq("Invalid 'count': expected non-negative Integer", - pcall_err(meths.cmd, { cmd = "print", args = {}, count = -1 }, {})) - - eq("Command cannot accept register: set", - pcall_err(meths.cmd, { cmd = "set", args = {}, reg = 'x' }, {})) - eq('Cannot use register "=', - pcall_err(meths.cmd, { cmd = "put", args = {}, reg = '=' }, {})) - eq("Invalid 'reg': expected single character, got xx", - pcall_err(meths.cmd, { cmd = "put", args = {}, reg = 'xx' }, {})) + eq("Invalid 'cmd': expected non-empty String", pcall_err(api.nvim_cmd, { cmd = '' }, {})) + eq("Invalid 'cmd': expected String, got Array", pcall_err(api.nvim_cmd, { cmd = {} }, {})) + eq( + "Invalid 'args': expected Array, got Boolean", + pcall_err(api.nvim_cmd, { cmd = 'set', args = true }, {}) + ) + eq( + 'Invalid command arg: expected non-whitespace', + pcall_err(api.nvim_cmd, { cmd = 'set', args = { ' ' } }, {}) + ) + eq( + 'Invalid command arg: expected valid type, got Array', + pcall_err(api.nvim_cmd, { cmd = 'set', args = { {} } }, {}) + ) + eq('Wrong number of arguments', pcall_err(api.nvim_cmd, { cmd = 'aboveleft', args = {} }, {})) + eq( + 'Command cannot accept bang: print', + pcall_err(api.nvim_cmd, { cmd = 'print', args = {}, bang = true }, {}) + ) + + eq( + 'Command cannot accept range: set', + pcall_err(api.nvim_cmd, { cmd = 'set', args = {}, range = { 1 } }, {}) + ) + eq( + "Invalid 'range': expected Array, got Boolean", + pcall_err(api.nvim_cmd, { cmd = 'print', args = {}, range = true }, {}) + ) + eq( + "Invalid 'range': expected <=2 elements", + pcall_err(api.nvim_cmd, { cmd = 'print', args = {}, range = { 1, 2, 3, 4 } }, {}) + ) + eq( + 'Invalid range element: expected non-negative Integer', + pcall_err(api.nvim_cmd, { cmd = 'print', args = {}, range = { -1 } }, {}) + ) + + eq( + 'Command cannot accept count: set', + pcall_err(api.nvim_cmd, { cmd = 'set', args = {}, count = 1 }, {}) + ) + eq( + "Invalid 'count': expected Integer, got Boolean", + pcall_err(api.nvim_cmd, { cmd = 'print', args = {}, count = true }, {}) + ) + eq( + "Invalid 'count': expected non-negative Integer", + pcall_err(api.nvim_cmd, { cmd = 'print', args = {}, count = -1 }, {}) + ) + + eq( + 'Command cannot accept register: set', + pcall_err(api.nvim_cmd, { cmd = 'set', args = {}, reg = 'x' }, {}) + ) + eq( + 'Cannot use register "=', + pcall_err(api.nvim_cmd, { cmd = 'put', args = {}, reg = '=' }, {}) + ) + eq( + "Invalid 'reg': expected single character, got xx", + pcall_err(api.nvim_cmd, { cmd = 'put', args = {}, reg = 'xx' }, {}) + ) -- #20681 - eq('Invalid command: "win_getid"', pcall_err(meths.cmd, { cmd = 'win_getid'}, {})) - eq('Invalid command: "echo "hi""', pcall_err(meths.cmd, { cmd = 'echo "hi"'}, {})) + eq('Invalid command: "win_getid"', pcall_err(api.nvim_cmd, { cmd = 'win_getid' }, {})) + eq('Invalid command: "echo "hi""', pcall_err(api.nvim_cmd, { cmd = 'echo "hi"' }, {})) eq('Invalid command: "win_getid"', pcall_err(exec_lua, [[return vim.cmd.win_getid{}]])) -- Lua call allows empty {} for dict item. eq('', exec_lua([[return vim.cmd{ cmd = "set", args = {}, magic = {} }]])) eq('', exec_lua([[return vim.cmd{ cmd = "set", args = {}, mods = {} }]])) - eq('', meths.cmd({ cmd = "set", args = {}, magic = {} }, {})) + eq('', api.nvim_cmd({ cmd = 'set', args = {}, magic = {} }, {})) -- Lua call does not allow non-empty list-like {} for dict item. - eq("Invalid 'magic': Expected Dict-like Lua table", - pcall_err(exec_lua, [[return vim.cmd{ cmd = "set", args = {}, magic = { 'a' } }]])) - eq("Invalid key: 'bogus'", - pcall_err(exec_lua, [[return vim.cmd{ cmd = "set", args = {}, magic = { bogus = true } }]])) - eq("Invalid key: 'bogus'", - pcall_err(exec_lua, [[return vim.cmd{ cmd = "set", args = {}, mods = { bogus = true } }]])) + eq( + "Invalid 'magic': Expected Dict-like Lua table", + pcall_err(exec_lua, [[return vim.cmd{ cmd = "set", args = {}, magic = { 'a' } }]]) + ) + eq( + "Invalid key: 'bogus'", + pcall_err(exec_lua, [[return vim.cmd{ cmd = "set", args = {}, magic = { bogus = true } }]]) + ) + eq( + "Invalid key: 'bogus'", + pcall_err(exec_lua, [[return vim.cmd{ cmd = "set", args = {}, mods = { bogus = true } }]]) + ) end) it('captures output', function() - eq("foo", meths.cmd({ cmd = "echo", args = { '"foo"' } }, { output = true })) + eq('foo', api.nvim_cmd({ cmd = 'echo', args = { '"foo"' } }, { output = true })) end) it('sets correct script context', function() - meths.cmd({ cmd = "set", args = { "cursorline" } }, {}) + api.nvim_cmd({ cmd = 'set', args = { 'cursorline' } }, {}) local str = exec_capture([[verbose set cursorline?]]) - neq(nil, str:find("cursorline\n\tLast set from API client %(channel id %d+%)")) + neq(nil, str:find('cursorline\n\tLast set from API client %(channel id %d+%)')) end) it('works with range', function() @@ -4313,7 +4615,7 @@ describe('API', function() line5 line6 ]] - meths.cmd({ cmd = "del", range = {2, 4} }, {}) + api.nvim_cmd({ cmd = 'del', range = { 2, 4 } }, {}) expect [[ line1 you didn't expect this @@ -4321,6 +4623,7 @@ describe('API', function() line6 ]] end) + it('works with count', function() insert [[ line1 @@ -4331,13 +4634,14 @@ describe('API', function() line5 line6 ]] - meths.cmd({ cmd = "del", range = { 2 }, count = 4 }, {}) + api.nvim_cmd({ cmd = 'del', range = { 2 }, count = 4 }, {}) expect [[ line1 line5 line6 ]] end) + it('works with register', function() insert [[ line1 @@ -4348,7 +4652,7 @@ describe('API', function() line5 line6 ]] - meths.cmd({ cmd = "del", range = { 2, 4 }, reg = 'a' }, {}) + api.nvim_cmd({ cmd = 'del', range = { 2, 4 }, reg = 'a' }, {}) command('1put a') expect [[ line1 @@ -4360,192 +4664,293 @@ describe('API', function() line6 ]] end) - it('works with bang', function () - meths.create_user_command("Foo", 'echo "<bang>"', { bang = true }) - eq("!", meths.cmd({ cmd = "Foo", bang = true }, { output = true })) - eq("", meths.cmd({ cmd = "Foo", bang = false }, { output = true })) + + it('works with bang', function() + api.nvim_create_user_command('Foo', 'echo "<bang>"', { bang = true }) + eq('!', api.nvim_cmd({ cmd = 'Foo', bang = true }, { output = true })) + eq('', api.nvim_cmd({ cmd = 'Foo', bang = false }, { output = true })) end) + it('works with modifiers', function() -- with silent = true output is still captured - eq('1', - meths.cmd({ cmd = 'echomsg', args = { '1' }, mods = { silent = true } }, - { output = true })) + eq( + '1', + api.nvim_cmd( + { cmd = 'echomsg', args = { '1' }, mods = { silent = true } }, + { output = true } + ) + ) -- but message isn't added to message history - eq('', meths.cmd({ cmd = 'messages' }, { output = true })) - - meths.create_user_command("Foo", 'set verbose', {}) - eq(" verbose=1", meths.cmd({ cmd = "Foo", mods = { verbose = 1 } }, { output = true })) - - meths.create_user_command("Mods", "echo '<mods>'", {}) - eq('keepmarks keeppatterns silent 3verbose aboveleft horizontal', - meths.cmd({ cmd = "Mods", mods = { - horizontal = true, - keepmarks = true, - keeppatterns = true, - silent = true, - split = 'aboveleft', - verbose = 3, - } }, { output = true })) - eq(0, meths.get_option_value("verbose", {})) + eq('', api.nvim_cmd({ cmd = 'messages' }, { output = true })) + + api.nvim_create_user_command('Foo', 'set verbose', {}) + eq(' verbose=1', api.nvim_cmd({ cmd = 'Foo', mods = { verbose = 1 } }, { output = true })) + + api.nvim_create_user_command('Mods', "echo '<mods>'", {}) + eq( + 'keepmarks keeppatterns silent 3verbose aboveleft horizontal', + api.nvim_cmd({ + cmd = 'Mods', + mods = { + horizontal = true, + keepmarks = true, + keeppatterns = true, + silent = true, + split = 'aboveleft', + verbose = 3, + }, + }, { output = true }) + ) + eq(0, api.nvim_get_option_value('verbose', {})) command('edit foo.txt | edit bar.txt') - eq(' 1 #h "foo.txt" line 1', - meths.cmd({ cmd = "buffers", mods = { filter = { pattern = "foo", force = false } } }, - { output = true })) - eq(' 2 %a "bar.txt" line 1', - meths.cmd({ cmd = "buffers", mods = { filter = { pattern = "foo", force = true } } }, - { output = true })) + eq( + ' 1 #h "foo.txt" line 1', + api.nvim_cmd( + { cmd = 'buffers', mods = { filter = { pattern = 'foo', force = false } } }, + { output = true } + ) + ) + eq( + ' 2 %a "bar.txt" line 1', + api.nvim_cmd( + { cmd = 'buffers', mods = { filter = { pattern = 'foo', force = true } } }, + { output = true } + ) + ) -- with emsg_silent = true error is suppressed feed([[:lua vim.api.nvim_cmd({ cmd = 'call', mods = { emsg_silent = true } }, {})<CR>]]) - eq('', meths.cmd({ cmd = 'messages' }, { output = true })) + eq('', api.nvim_cmd({ cmd = 'messages' }, { output = true })) -- error from the next command typed is not suppressed #21420 feed(':call<CR><CR>') - eq('E471: Argument required', meths.cmd({ cmd = 'messages' }, { output = true })) + eq('E471: Argument required', api.nvim_cmd({ cmd = 'messages' }, { output = true })) end) + it('works with magic.file', function() exec_lua([[ vim.api.nvim_create_user_command("Foo", function(opts) vim.api.nvim_echo({{ opts.fargs[1] }}, false, {}) end, { nargs = 1 }) ]]) - eq(luv.cwd(), - meths.cmd({ cmd = "Foo", args = { '%:p:h' }, magic = { file = true } }, - { output = true })) + eq( + uv.cwd(), + api.nvim_cmd( + { cmd = 'Foo', args = { '%:p:h' }, magic = { file = true } }, + { output = true } + ) + ) end) + it('splits arguments correctly', function() exec([[ function! FooFunc(...) echo a:000 endfunction ]]) - meths.create_user_command("Foo", "call FooFunc(<f-args>)", { nargs = '+' }) - eq([=[['a quick', 'brown fox', 'jumps over the', 'lazy dog']]=], - meths.cmd({ cmd = "Foo", args = { "a quick", "brown fox", "jumps over the", "lazy dog"}}, - { output = true })) - eq([=[['test \ \\ \"""\', 'more\ tests\" ']]=], - meths.cmd({ cmd = "Foo", args = { [[test \ \\ \"""\]], [[more\ tests\" ]] } }, - { output = true })) + api.nvim_create_user_command('Foo', 'call FooFunc(<f-args>)', { nargs = '+' }) + eq( + [=[['a quick', 'brown fox', 'jumps over the', 'lazy dog']]=], + api.nvim_cmd( + { cmd = 'Foo', args = { 'a quick', 'brown fox', 'jumps over the', 'lazy dog' } }, + { output = true } + ) + ) + eq( + [=[['test \ \\ \"""\', 'more\ tests\" ']]=], + api.nvim_cmd( + { cmd = 'Foo', args = { [[test \ \\ \"""\]], [[more\ tests\" ]] } }, + { output = true } + ) + ) end) + it('splits arguments correctly for Lua callback', function() - meths.exec_lua([[ + api.nvim_exec_lua( + [[ local function FooFunc(opts) vim.print(opts.fargs) end vim.api.nvim_create_user_command("Foo", FooFunc, { nargs = '+' }) - ]], {}) - eq([[{ "a quick", "brown fox", "jumps over the", "lazy dog" }]], - meths.cmd({ cmd = "Foo", args = { "a quick", "brown fox", "jumps over the", "lazy dog"}}, - { output = true })) - eq([[{ 'test \\ \\\\ \\"""\\', 'more\\ tests\\" ' }]], - meths.cmd({ cmd = "Foo", args = { [[test \ \\ \"""\]], [[more\ tests\" ]] } }, - { output = true })) + ]], + {} + ) + eq( + [[{ "a quick", "brown fox", "jumps over the", "lazy dog" }]], + api.nvim_cmd( + { cmd = 'Foo', args = { 'a quick', 'brown fox', 'jumps over the', 'lazy dog' } }, + { output = true } + ) + ) + eq( + [[{ 'test \\ \\\\ \\"""\\', 'more\\ tests\\" ' }]], + api.nvim_cmd( + { cmd = 'Foo', args = { [[test \ \\ \"""\]], [[more\ tests\" ]] } }, + { output = true } + ) + ) end) + it('works with buffer names', function() - command("edit foo.txt | edit bar.txt") - meths.cmd({ cmd = "buffer", args = { "foo.txt" } }, {}) - eq("foo.txt", funcs.fnamemodify(meths.buf_get_name(0), ":t")) - meths.cmd({ cmd = "buffer", args = { "bar.txt" } }, {}) - eq("bar.txt", funcs.fnamemodify(meths.buf_get_name(0), ":t")) + command('edit foo.txt | edit bar.txt') + api.nvim_cmd({ cmd = 'buffer', args = { 'foo.txt' } }, {}) + eq('foo.txt', fn.fnamemodify(api.nvim_buf_get_name(0), ':t')) + api.nvim_cmd({ cmd = 'buffer', args = { 'bar.txt' } }, {}) + eq('bar.txt', fn.fnamemodify(api.nvim_buf_get_name(0), ':t')) end) + it('triggers CmdUndefined event if command is not found', function() - meths.exec_lua([[ + api.nvim_exec_lua( + [[ vim.api.nvim_create_autocmd("CmdUndefined", { pattern = "Foo", callback = function() vim.api.nvim_create_user_command("Foo", "echo 'foo'", {}) end }) - ]], {}) - eq("foo", meths.cmd({ cmd = "Foo" }, { output = true })) + ]], + {} + ) + eq('foo', api.nvim_cmd({ cmd = 'Foo' }, { output = true })) end) + it('errors if command is not implemented', function() - eq("Command not implemented: winpos", pcall_err(meths.cmd, { cmd = "winpos" }, {})) + eq('Command not implemented: winpos', pcall_err(api.nvim_cmd, { cmd = 'winpos' }, {})) end) + it('works with empty arguments list', function() - meths.cmd({ cmd = "update" }, {}) - meths.cmd({ cmd = "buffer", count = 0 }, {}) + api.nvim_cmd({ cmd = 'update' }, {}) + api.nvim_cmd({ cmd = 'buffer', count = 0 }, {}) end) - it('doesn\'t suppress errors when used in keymapping', function() - meths.exec_lua([[ + + it("doesn't suppress errors when used in keymapping", function() + api.nvim_exec_lua( + [[ vim.keymap.set("n", "[l", function() vim.api.nvim_cmd({ cmd = "echo", args = {"foo"} }, {}) end) - ]], {}) - feed("[l") - neq(nil, string.find(eval("v:errmsg"), "E5108:")) + ]], + {} + ) + feed('[l') + neq(nil, string.find(eval('v:errmsg'), 'E5108:')) end) + it('handles 0 range #19608', function() - meths.buf_set_lines(0, 0, -1, false, { "aa" }) - meths.cmd({ cmd = 'delete', range = { 0 } }, {}) + api.nvim_buf_set_lines(0, 0, -1, false, { 'aa' }) + api.nvim_cmd({ cmd = 'delete', range = { 0 } }, {}) command('undo') - eq({'aa'}, meths.buf_get_lines(0, 0, 1, false)) + eq({ 'aa' }, api.nvim_buf_get_lines(0, 0, 1, false)) assert_alive() end) + it('supports filename expansion', function() - meths.cmd({ cmd = 'argadd', args = { '%:p:h:t', '%:p:h:t' } }, {}) - local arg = funcs.expand('%:p:h:t') - eq({ arg, arg }, funcs.argv()) + api.nvim_cmd({ cmd = 'argadd', args = { '%:p:h:t', '%:p:h:t' } }, {}) + local arg = fn.expand('%:p:h:t') + eq({ arg, arg }, fn.argv()) end) - it("'make' command works when argument count isn't 1 #19696", function() + + it(":make command works when argument count isn't 1 #19696", function() command('set makeprg=echo') command('set shellquote=') - matches('^:!echo ', - meths.cmd({ cmd = 'make' }, { output = true })) + matches('^:!echo ', api.nvim_cmd({ cmd = 'make' }, { output = true })) assert_alive() - matches('^:!echo foo bar', - meths.cmd({ cmd = 'make', args = { 'foo', 'bar' } }, { output = true })) + matches( + '^:!echo foo bar', + api.nvim_cmd({ cmd = 'make', args = { 'foo', 'bar' } }, { output = true }) + ) assert_alive() - local arg_pesc = pesc(funcs.expand('%:p:h:t')) - matches(('^:!echo %s %s'):format(arg_pesc, arg_pesc), - meths.cmd({ cmd = 'make', args = { '%:p:h:t', '%:p:h:t' } }, { output = true })) + local arg_pesc = pesc(fn.expand('%:p:h:t')) + matches( + ('^:!echo %s %s'):format(arg_pesc, arg_pesc), + api.nvim_cmd({ cmd = 'make', args = { '%:p:h:t', '%:p:h:t' } }, { output = true }) + ) assert_alive() end) - it('doesn\'t display messages when output=true', function() + + it("doesn't display messages when output=true", function() local screen = Screen.new(40, 6) screen:attach() screen:set_default_attr_ids({ - [0] = {bold=true, foreground=Screen.colors.Blue}, + [0] = { bold = true, foreground = Screen.colors.Blue }, }) - meths.cmd({cmd = 'echo', args = {[['hello']]}}, {output = true}) - screen:expect{grid=[[ + api.nvim_cmd({ cmd = 'echo', args = { [['hello']] } }, { output = true }) + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | - ]]} + ]], + } exec([[ func Print() call nvim_cmd(#{cmd: 'echo', args: ['"hello"']}, #{output: v:true}) endfunc ]]) feed([[:echon 1 | call Print() | echon 5<CR>]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 15 | - ]]} + ]], + } end) + it('works with non-String args', function() - eq('2', meths.cmd({cmd = 'echo', args = {2}}, {output = true})) - eq('1', meths.cmd({cmd = 'echo', args = {true}}, {output = true})) + eq('2', api.nvim_cmd({ cmd = 'echo', args = { 2 } }, { output = true })) + eq('1', api.nvim_cmd({ cmd = 'echo', args = { true } }, { output = true })) end) + describe('first argument as count', function() it('works', function() command('vsplit | enew') - meths.cmd({cmd = 'bdelete', args = {meths.get_current_buf()}}, {}) - eq(1, meths.get_current_buf().id) + api.nvim_cmd({ cmd = 'bdelete', args = { api.nvim_get_current_buf() } }, {}) + eq(1, api.nvim_get_current_buf()) end) + it('works with :sleep using milliseconds', function() - local start = luv.now() - meths.cmd({cmd = 'sleep', args = {'100m'}}, {}) - ok(luv.now() - start <= 300) + local start = uv.now() + api.nvim_cmd({ cmd = 'sleep', args = { '100m' } }, {}) + ok(uv.now() - start <= 300) end) end) + + it(':call with unknown function does not crash #26289', function() + eq( + 'Vim:E117: Unknown function: UnknownFunc', + pcall_err(api.nvim_cmd, { cmd = 'call', args = { 'UnknownFunc()' } }, {}) + ) + end) + + it(':throw does not crash #24556', function() + eq('42', pcall_err(api.nvim_cmd, { cmd = 'throw', args = { '42' } }, {})) + end) + + it('can use :return #24556', function() + exec([[ + func Foo() + let g:pos = 'before' + call nvim_cmd({'cmd': 'return', 'args': ['[1, 2, 3]']}, {}) + let g:pos = 'after' + endfunc + let g:result = Foo() + ]]) + eq('before', api.nvim_get_var('pos')) + eq({ 1, 2, 3 }, api.nvim_get_var('result')) + end) + + it('errors properly when command too recursive #27210', function() + exec_lua([[ + _G.success = false + vim.api.nvim_create_user_command('Test', function() + vim.api.nvim_cmd({ cmd = 'Test' }, {}) + _G.success = true + end, {}) + ]]) + pcall_err(command, 'Test') + assert_alive() + eq(false, exec_lua('return _G.success')) + end) end) end) diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua index 6737c2d15b..097a546ef2 100644 --- a/test/functional/api/window_spec.lua +++ b/test/functional/api/window_spec.lua @@ -1,17 +1,24 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local clear, nvim, curbuf, curbuf_contents, window, curwin, eq, neq, - ok, feed, insert, eval, tabpage = helpers.clear, helpers.nvim, helpers.curbuf, - helpers.curbuf_contents, helpers.window, helpers.curwin, helpers.eq, - helpers.neq, helpers.ok, helpers.feed, helpers.insert, helpers.eval, - helpers.tabpage +local clear, curbuf, curbuf_contents, curwin, eq, neq, matches, ok, feed, insert, eval = + helpers.clear, + helpers.api.nvim_get_current_buf, + helpers.curbuf_contents, + helpers.api.nvim_get_current_win, + helpers.eq, + helpers.neq, + helpers.matches, + helpers.ok, + helpers.feed, + helpers.insert, + helpers.eval local poke_eventloop = helpers.poke_eventloop -local curwinmeths = helpers.curwinmeths local exec = helpers.exec -local funcs = helpers.funcs +local exec_lua = helpers.exec_lua +local fn = helpers.fn local request = helpers.request -local NIL = helpers.NIL -local meths = helpers.meths +local NIL = vim.NIL +local api = helpers.api local command = helpers.command local pcall_err = helpers.pcall_err local assert_alive = helpers.assert_alive @@ -21,201 +28,229 @@ describe('API/win', function() describe('get_buf', function() it('works', function() - eq(curbuf(), window('get_buf', nvim('list_wins')[1])) - nvim('command', 'new') - nvim('set_current_win', nvim('list_wins')[2]) - eq(curbuf(), window('get_buf', nvim('list_wins')[2])) - neq(window('get_buf', nvim('list_wins')[1]), - window('get_buf', nvim('list_wins')[2])) + eq(curbuf(), api.nvim_win_get_buf(api.nvim_list_wins()[1])) + command('new') + api.nvim_set_current_win(api.nvim_list_wins()[2]) + eq(curbuf(), api.nvim_win_get_buf(api.nvim_list_wins()[2])) + neq( + api.nvim_win_get_buf(api.nvim_list_wins()[1]), + api.nvim_win_get_buf(api.nvim_list_wins()[2]) + ) end) end) describe('set_buf', function() it('works', function() - nvim('command', 'new') - local windows = nvim('list_wins') - neq(window('get_buf', windows[2]), window('get_buf', windows[1])) - window('set_buf', windows[2], window('get_buf', windows[1])) - eq(window('get_buf', windows[2]), window('get_buf', windows[1])) + command('new') + local windows = api.nvim_list_wins() + neq(api.nvim_win_get_buf(windows[2]), api.nvim_win_get_buf(windows[1])) + api.nvim_win_set_buf(windows[2], api.nvim_win_get_buf(windows[1])) + eq(api.nvim_win_get_buf(windows[2]), api.nvim_win_get_buf(windows[1])) end) it('validates args', function() - eq('Invalid buffer id: 23', pcall_err(window, 'set_buf', nvim('get_current_win'), 23)) - eq('Invalid window id: 23', pcall_err(window, 'set_buf', 23, nvim('get_current_buf'))) + eq('Invalid buffer id: 23', pcall_err(api.nvim_win_set_buf, api.nvim_get_current_win(), 23)) + eq('Invalid window id: 23', pcall_err(api.nvim_win_set_buf, 23, api.nvim_get_current_buf())) end) - it('disallowed in cmdwin if win={old_}curwin or buf=curbuf', function() - local new_buf = meths.create_buf(true, true) - local old_win = meths.get_current_win() - local new_win = meths.open_win(new_buf, false, { - relative='editor', row=10, col=10, width=50, height=10, + it('disallowed in cmdwin if win=cmdwin_{old_cur}win or buf=cmdwin_buf', function() + local new_buf = api.nvim_create_buf(true, true) + local old_win = api.nvim_get_current_win() + local new_win = api.nvim_open_win(new_buf, false, { + relative = 'editor', + row = 10, + col = 10, + width = 50, + height = 10, }) feed('q:') - eq('E11: Invalid in command-line window; <CR> executes, CTRL-C quits', - pcall_err(meths.win_set_buf, 0, new_buf)) - eq('E11: Invalid in command-line window; <CR> executes, CTRL-C quits', - pcall_err(meths.win_set_buf, old_win, new_buf)) - eq('E11: Invalid in command-line window; <CR> executes, CTRL-C quits', - pcall_err(meths.win_set_buf, new_win, 0)) - - local next_buf = meths.create_buf(true, true) - meths.win_set_buf(new_win, next_buf) - eq(next_buf, meths.win_get_buf(new_win)) + eq( + 'E11: Invalid in command-line window; <CR> executes, CTRL-C quits', + pcall_err(api.nvim_win_set_buf, 0, new_buf) + ) + eq( + 'E11: Invalid in command-line window; <CR> executes, CTRL-C quits', + pcall_err(api.nvim_win_set_buf, old_win, new_buf) + ) + eq( + 'E11: Invalid in command-line window; <CR> executes, CTRL-C quits', + pcall_err(api.nvim_win_set_buf, new_win, 0) + ) + matches( + 'E11: Invalid in command%-line window; <CR> executes, CTRL%-C quits$', + pcall_err( + exec_lua, + [[ + local cmdwin_buf = vim.api.nvim_get_current_buf() + local new_win, new_buf = ... + vim.api.nvim_buf_call(new_buf, function() + vim.api.nvim_win_set_buf(new_win, cmdwin_buf) + end) + ]], + new_win, + new_buf + ) + ) + matches( + 'E11: Invalid in command%-line window; <CR> executes, CTRL%-C quits$', + pcall_err( + exec_lua, + [[ + local cmdwin_win = vim.api.nvim_get_current_win() + local new_win, new_buf = ... + vim.api.nvim_win_call(new_win, function() + vim.api.nvim_win_set_buf(cmdwin_win, new_buf) + end) + ]], + new_win, + new_buf + ) + ) + + local next_buf = api.nvim_create_buf(true, true) + api.nvim_win_set_buf(new_win, next_buf) + eq(next_buf, api.nvim_win_get_buf(new_win)) end) end) describe('{get,set}_cursor', function() it('works', function() - eq({1, 0}, curwin('get_cursor')) - nvim('command', 'normal ityping\027o some text') + eq({ 1, 0 }, api.nvim_win_get_cursor(0)) + command('normal ityping\027o some text') eq('typing\n some text', curbuf_contents()) - eq({2, 10}, curwin('get_cursor')) - curwin('set_cursor', {2, 6}) - nvim('command', 'normal i dumb') + eq({ 2, 10 }, api.nvim_win_get_cursor(0)) + api.nvim_win_set_cursor(0, { 2, 6 }) + command('normal i dumb') eq('typing\n some dumb text', curbuf_contents()) end) it('does not leak memory when using invalid window ID with invalid pos', function() - eq('Invalid window id: 1', pcall_err(meths.win_set_cursor, 1, {"b\na"})) + eq('Invalid window id: 1', pcall_err(api.nvim_win_set_cursor, 1, { 'b\na' })) end) it('updates the screen, and also when the window is unfocused', function() local screen = Screen.new(30, 9) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue}, - [2] = {bold = true, reverse = true}; - [3] = {reverse = true}; + [1] = { bold = true, foreground = Screen.colors.Blue }, + [2] = { bold = true, reverse = true }, + [3] = { reverse = true }, }) screen:attach() - insert("prologue") + insert('prologue') feed('100o<esc>') - insert("epilogue") + insert('epilogue') local win = curwin() feed('gg') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^prologue | - | - | - | - | - | - | - | - | - ]]} + |*8 + ]], + } -- cursor position is at beginning - eq({1, 0}, window('get_cursor', win)) + eq({ 1, 0 }, api.nvim_win_get_cursor(win)) -- move cursor to end - window('set_cursor', win, {101, 0}) - screen:expect{grid=[[ - | - | - | - | - | - | - | + api.nvim_win_set_cursor(win, { 101, 0 }) + screen:expect { + grid = [[ + |*7 ^epilogue | | - ]]} + ]], + } -- move cursor to the beginning again - window('set_cursor', win, {1, 0}) - screen:expect{grid=[[ + api.nvim_win_set_cursor(win, { 1, 0 }) + screen:expect { + grid = [[ ^prologue | - | - | - | - | - | - | - | - | - ]]} + |*8 + ]], + } -- move focus to new window - nvim('command',"new") + command('new') neq(win, curwin()) -- sanity check, cursor position is kept - eq({1, 0}, window('get_cursor', win)) - screen:expect{grid=[[ + eq({ 1, 0 }, api.nvim_win_get_cursor(win)) + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:[No Name] }| prologue | - | - | + |*2 {3:[No Name] [+] }| | - ]]} + ]], + } -- move cursor to end - window('set_cursor', win, {101, 0}) - screen:expect{grid=[[ + api.nvim_win_set_cursor(win, { 101, 0 }) + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:[No Name] }| - | - | + |*2 epilogue | {3:[No Name] [+] }| | - ]]} + ]], + } -- move cursor to the beginning again - window('set_cursor', win, {1, 0}) - screen:expect{grid=[[ + api.nvim_win_set_cursor(win, { 1, 0 }) + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:[No Name] }| prologue | - | - | + |*2 {3:[No Name] [+] }| | - ]]} + ]], + } -- curwin didn't change back neq(win, curwin()) end) it('remembers what column it wants to be in', function() - insert("first line") + insert('first line') feed('o<esc>') - insert("second line") + insert('second line') feed('gg') poke_eventloop() -- let nvim process the 'gg' command -- cursor position is at beginning local win = curwin() - eq({1, 0}, window('get_cursor', win)) + eq({ 1, 0 }, api.nvim_win_get_cursor(win)) -- move cursor to column 5 - window('set_cursor', win, {1, 5}) + api.nvim_win_set_cursor(win, { 1, 5 }) -- move down a line feed('j') poke_eventloop() -- let nvim process the 'j' command -- cursor is still in column 5 - eq({2, 5}, window('get_cursor', win)) + eq({ 2, 5 }, api.nvim_win_get_cursor(win)) end) it('updates cursorline and statusline ruler in non-current window', function() local screen = Screen.new(60, 8) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [2] = {background = Screen.colors.Grey90}, -- CursorLine - [3] = {bold = true, reverse = true}, -- StatusLine - [4] = {reverse = true}, -- StatusLineNC + [1] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [2] = { background = Screen.colors.Grey90 }, -- CursorLine + [3] = { bold = true, reverse = true }, -- StatusLine + [4] = { reverse = true }, -- StatusLineNC }) screen:attach() command('set ruler') @@ -232,19 +267,17 @@ describe('API/win', function() bbb │bbb | ccc │ccc | {2:dd^d }│{2:ddd }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*2 {3:[No Name] [+] 4,3 All }{4:[No Name] [+] 4,3 All}| | ]]) - window('set_cursor', oldwin, {1, 0}) + api.nvim_win_set_cursor(oldwin, { 1, 0 }) screen:expect([[ aaa │{2:aaa }| bbb │bbb | ccc │ccc | {2:dd^d }│ddd | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*2 {3:[No Name] [+] 4,3 All }{4:[No Name] [+] 1,1 All}| | ]]) @@ -253,10 +286,10 @@ describe('API/win', function() it('updates cursorcolumn in non-current window', function() local screen = Screen.new(60, 8) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [2] = {background = Screen.colors.Grey90}, -- CursorColumn - [3] = {bold = true, reverse = true}, -- StatusLine - [4] = {reverse = true}, -- StatusLineNC + [1] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [2] = { background = Screen.colors.Grey90 }, -- CursorColumn + [3] = { bold = true, reverse = true }, -- StatusLine + [4] = { reverse = true }, -- StatusLineNC }) screen:attach() command('set cursorcolumn') @@ -272,19 +305,17 @@ describe('API/win', function() bb{2:b} │bb{2:b} | cc{2:c} │cc{2:c} | dd^d │ddd | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*2 {3:[No Name] [+] }{4:[No Name] [+] }| | ]]) - window('set_cursor', oldwin, {2, 0}) + api.nvim_win_set_cursor(oldwin, { 2, 0 }) screen:expect([[ aa{2:a} │{2:a}aa | bb{2:b} │bbb | cc{2:c} │{2:c}cc | dd^d │{2:d}dd | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*2 {3:[No Name] [+] }{4:[No Name] [+] }| | ]]) @@ -293,31 +324,35 @@ describe('API/win', function() describe('{get,set}_height', function() it('works', function() - nvim('command', 'vsplit') - eq(window('get_height', nvim('list_wins')[2]), - window('get_height', nvim('list_wins')[1])) - nvim('set_current_win', nvim('list_wins')[2]) - nvim('command', 'split') - eq(window('get_height', nvim('list_wins')[2]), - math.floor(window('get_height', nvim('list_wins')[1]) / 2)) - window('set_height', nvim('list_wins')[2], 2) - eq(2, window('get_height', nvim('list_wins')[2])) + command('vsplit') + eq( + api.nvim_win_get_height(api.nvim_list_wins()[2]), + api.nvim_win_get_height(api.nvim_list_wins()[1]) + ) + api.nvim_set_current_win(api.nvim_list_wins()[2]) + command('split') + eq( + api.nvim_win_get_height(api.nvim_list_wins()[2]), + math.floor(api.nvim_win_get_height(api.nvim_list_wins()[1]) / 2) + ) + api.nvim_win_set_height(api.nvim_list_wins()[2], 2) + eq(2, api.nvim_win_get_height(api.nvim_list_wins()[2])) end) it('correctly handles height=1', function() - nvim('command', 'split') - nvim('set_current_win', nvim('list_wins')[1]) - window('set_height', nvim('list_wins')[2], 1) - eq(1, window('get_height', nvim('list_wins')[2])) + command('split') + api.nvim_set_current_win(api.nvim_list_wins()[1]) + api.nvim_win_set_height(api.nvim_list_wins()[2], 1) + eq(1, api.nvim_win_get_height(api.nvim_list_wins()[2])) end) it('correctly handles height=1 with a winbar', function() - nvim('command', 'set winbar=foobar') - nvim('command', 'set winminheight=0') - nvim('command', 'split') - nvim('set_current_win', nvim('list_wins')[1]) - window('set_height', nvim('list_wins')[2], 1) - eq(1, window('get_height', nvim('list_wins')[2])) + command('set winbar=foobar') + command('set winminheight=0') + command('split') + api.nvim_set_current_win(api.nvim_list_wins()[1]) + api.nvim_win_set_height(api.nvim_list_wins()[2], 1) + eq(1, api.nvim_win_get_height(api.nvim_list_wins()[2])) end) it('do not cause ml_get errors with foldmethod=expr #19989', function() @@ -333,21 +368,25 @@ describe('API/win', function() call nvim_win_set_height(w, 5) ]]) feed('l') - eq('', meths.get_vvar('errmsg')) + eq('', api.nvim_get_vvar('errmsg')) end) end) describe('{get,set}_width', function() it('works', function() - nvim('command', 'split') - eq(window('get_width', nvim('list_wins')[2]), - window('get_width', nvim('list_wins')[1])) - nvim('set_current_win', nvim('list_wins')[2]) - nvim('command', 'vsplit') - eq(window('get_width', nvim('list_wins')[2]), - math.floor(window('get_width', nvim('list_wins')[1]) / 2)) - window('set_width', nvim('list_wins')[2], 2) - eq(2, window('get_width', nvim('list_wins')[2])) + command('split') + eq( + api.nvim_win_get_width(api.nvim_list_wins()[2]), + api.nvim_win_get_width(api.nvim_list_wins()[1]) + ) + api.nvim_set_current_win(api.nvim_list_wins()[2]) + command('vsplit') + eq( + api.nvim_win_get_width(api.nvim_list_wins()[2]), + math.floor(api.nvim_win_get_width(api.nvim_list_wins()[1]) / 2) + ) + api.nvim_win_set_width(api.nvim_list_wins()[2], 2) + eq(2, api.nvim_win_get_width(api.nvim_list_wins()[2])) end) it('do not cause ml_get errors with foldmethod=expr #19989', function() @@ -363,36 +402,36 @@ describe('API/win', function() call nvim_win_set_width(w, 5) ]]) feed('l') - eq('', meths.get_vvar('errmsg')) + eq('', api.nvim_get_vvar('errmsg')) end) end) describe('{get,set,del}_var', function() it('works', function() - curwin('set_var', 'lua', {1, 2, {['3'] = 1}}) - eq({1, 2, {['3'] = 1}}, curwin('get_var', 'lua')) - eq({1, 2, {['3'] = 1}}, nvim('eval', 'w:lua')) - eq(1, funcs.exists('w:lua')) - curwinmeths.del_var('lua') - eq(0, funcs.exists('w:lua')) - eq('Key not found: lua', pcall_err(curwinmeths.del_var, 'lua')) - curwinmeths.set_var('lua', 1) + api.nvim_win_set_var(0, 'lua', { 1, 2, { ['3'] = 1 } }) + eq({ 1, 2, { ['3'] = 1 } }, api.nvim_win_get_var(0, 'lua')) + eq({ 1, 2, { ['3'] = 1 } }, api.nvim_eval('w:lua')) + eq(1, fn.exists('w:lua')) + api.nvim_win_del_var(0, 'lua') + eq(0, fn.exists('w:lua')) + eq('Key not found: lua', pcall_err(api.nvim_win_del_var, 0, 'lua')) + api.nvim_win_set_var(0, 'lua', 1) command('lockvar w:lua') - eq('Key is locked: lua', pcall_err(curwinmeths.del_var, 'lua')) - eq('Key is locked: lua', pcall_err(curwinmeths.set_var, 'lua', 1)) + eq('Key is locked: lua', pcall_err(api.nvim_win_del_var, 0, 'lua')) + eq('Key is locked: lua', pcall_err(api.nvim_win_set_var, 0, 'lua', 1)) end) it('window_set_var returns the old value', function() - local val1 = {1, 2, {['3'] = 1}} - local val2 = {4, 7} + local val1 = { 1, 2, { ['3'] = 1 } } + local val2 = { 4, 7 } eq(NIL, request('window_set_var', 0, 'lua', val1)) eq(val1, request('window_set_var', 0, 'lua', val2)) end) it('window_del_var returns the old value', function() - local val1 = {1, 2, {['3'] = 1}} - local val2 = {4, 7} - eq(NIL, request('window_set_var', 0, 'lua', val1)) + local val1 = { 1, 2, { ['3'] = 1 } } + local val2 = { 4, 7 } + eq(NIL, request('window_set_var', 0, 'lua', val1)) eq(val1, request('window_set_var', 0, 'lua', val2)) eq(val2, request('window_del_var', 0, 'lua')) end) @@ -400,53 +439,51 @@ describe('API/win', function() describe('nvim_get_option_value, nvim_set_option_value', function() it('works', function() - nvim('set_option_value', 'colorcolumn', '4,3', {}) - eq('4,3', nvim('get_option_value', 'colorcolumn', {})) - command("set modified hidden") - command("enew") -- edit new buffer, window option is preserved - eq('4,3', nvim('get_option_value', 'colorcolumn', {})) + api.nvim_set_option_value('colorcolumn', '4,3', {}) + eq('4,3', api.nvim_get_option_value('colorcolumn', {})) + command('set modified hidden') + command('enew') -- edit new buffer, window option is preserved + eq('4,3', api.nvim_get_option_value('colorcolumn', {})) -- global-local option - nvim('set_option_value', 'statusline', 'window-status', {win=0}) - eq('window-status', nvim('get_option_value', 'statusline', {win=0})) - eq('', nvim('get_option_value', 'statusline', {scope='global'})) - command("set modified") - command("enew") -- global-local: not preserved in new buffer + api.nvim_set_option_value('statusline', 'window-status', { win = 0 }) + eq('window-status', api.nvim_get_option_value('statusline', { win = 0 })) + eq('', api.nvim_get_option_value('statusline', { scope = 'global' })) + command('set modified') + command('enew') -- global-local: not preserved in new buffer -- confirm local value was not copied - eq('', nvim('get_option_value', 'statusline', {win = 0})) + eq('', api.nvim_get_option_value('statusline', { win = 0 })) eq('', eval('&l:statusline')) end) it('after switching windows #15390', function() - nvim('command', 'tabnew') - local tab1 = unpack(nvim('list_tabpages')) - local win1 = unpack(tabpage('list_wins', tab1)) - nvim('set_option_value', 'statusline', 'window-status', {win=win1.id}) - nvim('command', 'split') - nvim('command', 'wincmd J') - nvim('command', 'wincmd j') - eq('window-status', nvim('get_option_value', 'statusline', {win = win1.id})) + command('tabnew') + local tab1 = unpack(api.nvim_list_tabpages()) + local win1 = unpack(api.nvim_tabpage_list_wins(tab1)) + api.nvim_set_option_value('statusline', 'window-status', { win = win1 }) + command('split') + command('wincmd J') + command('wincmd j') + eq('window-status', api.nvim_get_option_value('statusline', { win = win1 })) assert_alive() end) it('returns values for unset local options', function() - eq(-1, nvim('get_option_value', 'scrolloff', {win=0, scope='local'})) + eq(-1, api.nvim_get_option_value('scrolloff', { win = 0, scope = 'local' })) end) end) describe('get_position', function() it('works', function() - local height = window('get_height', nvim('list_wins')[1]) - local width = window('get_width', nvim('list_wins')[1]) - nvim('command', 'split') - nvim('command', 'vsplit') - eq({0, 0}, window('get_position', nvim('list_wins')[1])) + local height = api.nvim_win_get_height(api.nvim_list_wins()[1]) + local width = api.nvim_win_get_width(api.nvim_list_wins()[1]) + command('split') + command('vsplit') + eq({ 0, 0 }, api.nvim_win_get_position(api.nvim_list_wins()[1])) local vsplit_pos = math.floor(width / 2) local split_pos = math.floor(height / 2) - local win2row, win2col = - unpack(window('get_position', nvim('list_wins')[2])) - local win3row, win3col = - unpack(window('get_position', nvim('list_wins')[3])) + local win2row, win2col = unpack(api.nvim_win_get_position(api.nvim_list_wins()[2])) + local win3row, win3col = unpack(api.nvim_win_get_position(api.nvim_list_wins()[3])) eq(0, win2row) eq(0, win3col) ok(vsplit_pos - 1 <= win2col and win2col <= vsplit_pos + 1) @@ -456,239 +493,362 @@ describe('API/win', function() describe('get_position', function() it('works', function() - nvim('command', 'tabnew') - nvim('command', 'vsplit') - eq(window('get_tabpage', - nvim('list_wins')[1]), nvim('list_tabpages')[1]) - eq(window('get_tabpage', - nvim('list_wins')[2]), nvim('list_tabpages')[2]) - eq(window('get_tabpage', - nvim('list_wins')[3]), nvim('list_tabpages')[2]) + command('tabnew') + command('vsplit') + eq(api.nvim_win_get_tabpage(api.nvim_list_wins()[1]), api.nvim_list_tabpages()[1]) + eq(api.nvim_win_get_tabpage(api.nvim_list_wins()[2]), api.nvim_list_tabpages()[2]) + eq(api.nvim_win_get_tabpage(api.nvim_list_wins()[3]), api.nvim_list_tabpages()[2]) end) end) describe('get_number', function() it('works', function() - local wins = nvim('list_wins') - eq(1, window('get_number', wins[1])) + local wins = api.nvim_list_wins() + eq(1, api.nvim_win_get_number(wins[1])) - nvim('command', 'split') - local win1, win2 = unpack(nvim('list_wins')) - eq(1, window('get_number', win1)) - eq(2, window('get_number', win2)) + command('split') + local win1, win2 = unpack(api.nvim_list_wins()) + eq(1, api.nvim_win_get_number(win1)) + eq(2, api.nvim_win_get_number(win2)) - nvim('command', 'wincmd J') - eq(2, window('get_number', win1)) - eq(1, window('get_number', win2)) + command('wincmd J') + eq(2, api.nvim_win_get_number(win1)) + eq(1, api.nvim_win_get_number(win2)) - nvim('command', 'tabnew') - local win3 = nvim('list_wins')[3] + command('tabnew') + local win3 = api.nvim_list_wins()[3] -- First tab page - eq(2, window('get_number', win1)) - eq(1, window('get_number', win2)) + eq(2, api.nvim_win_get_number(win1)) + eq(1, api.nvim_win_get_number(win2)) -- Second tab page - eq(1, window('get_number', win3)) + eq(1, api.nvim_win_get_number(win3)) end) end) describe('is_valid', function() it('works', function() - nvim('command', 'split') - local win = nvim('list_wins')[2] - nvim('set_current_win', win) - ok(window('is_valid', win)) - nvim('command', 'close') - ok(not window('is_valid', win)) + command('split') + local win = api.nvim_list_wins()[2] + api.nvim_set_current_win(win) + ok(api.nvim_win_is_valid(win)) + command('close') + ok(not api.nvim_win_is_valid(win)) end) end) describe('close', function() it('can close current window', function() - local oldwin = meths.get_current_win() + local oldwin = api.nvim_get_current_win() command('split') - local newwin = meths.get_current_win() - meths.win_close(newwin,false) - eq({oldwin}, meths.list_wins()) + local newwin = api.nvim_get_current_win() + api.nvim_win_close(newwin, false) + eq({ oldwin }, api.nvim_list_wins()) end) it('can close noncurrent window', function() - local oldwin = meths.get_current_win() + local oldwin = api.nvim_get_current_win() command('split') - local newwin = meths.get_current_win() - meths.win_close(oldwin,false) - eq({newwin}, meths.list_wins()) + local newwin = api.nvim_get_current_win() + api.nvim_win_close(oldwin, false) + eq({ newwin }, api.nvim_list_wins()) end) it("handles changed buffer when 'hidden' is unset", function() command('set nohidden') - local oldwin = meths.get_current_win() + local oldwin = api.nvim_get_current_win() insert('text') command('new') - local newwin = meths.get_current_win() - eq("Vim:E37: No write since last change (add ! to override)", - pcall_err(meths.win_close, oldwin,false)) - eq({newwin,oldwin}, meths.list_wins()) + local newwin = api.nvim_get_current_win() + eq( + 'Vim:E37: No write since last change (add ! to override)', + pcall_err(api.nvim_win_close, oldwin, false) + ) + eq({ newwin, oldwin }, api.nvim_list_wins()) end) it('handles changed buffer with force', function() - local oldwin = meths.get_current_win() + local oldwin = api.nvim_get_current_win() insert('text') command('new') - local newwin = meths.get_current_win() - meths.win_close(oldwin,true) - eq({newwin}, meths.list_wins()) + local newwin = api.nvim_get_current_win() + api.nvim_win_close(oldwin, true) + eq({ newwin }, api.nvim_list_wins()) end) it('in cmdline-window #9767', function() command('split') - eq(2, #meths.list_wins()) - local oldwin = meths.get_current_win() - local otherwin = meths.open_win(0, false, { - relative='editor', row=10, col=10, width=10, height=10, + eq(2, #api.nvim_list_wins()) + local oldbuf = api.nvim_get_current_buf() + local oldwin = api.nvim_get_current_win() + local otherwin = api.nvim_open_win(0, false, { + relative = 'editor', + row = 10, + col = 10, + width = 10, + height = 10, }) -- Open cmdline-window. feed('q:') - eq(4, #meths.list_wins()) - eq(':', funcs.getcmdwintype()) + eq(4, #api.nvim_list_wins()) + eq(':', fn.getcmdwintype()) -- Not allowed to close previous window from cmdline-window. - eq('E11: Invalid in command-line window; <CR> executes, CTRL-C quits', - pcall_err(meths.win_close, oldwin, true)) + eq( + 'E11: Invalid in command-line window; <CR> executes, CTRL-C quits', + pcall_err(api.nvim_win_close, oldwin, true) + ) -- Closing other windows is fine. - meths.win_close(otherwin, true) - eq(false, meths.win_is_valid(otherwin)) + api.nvim_win_close(otherwin, true) + eq(false, api.nvim_win_is_valid(otherwin)) -- Close cmdline-window. - meths.win_close(0, true) - eq(2, #meths.list_wins()) - eq('', funcs.getcmdwintype()) + api.nvim_win_close(0, true) + eq(2, #api.nvim_list_wins()) + eq('', fn.getcmdwintype()) + + -- Closing curwin in context of a different window shouldn't close cmdwin. + otherwin = api.nvim_open_win(0, false, { + relative = 'editor', + row = 10, + col = 10, + width = 10, + height = 10, + }) + feed('q:') + exec_lua( + [[ + vim.api.nvim_win_call(..., function() + vim.api.nvim_win_close(0, true) + end) + ]], + otherwin + ) + eq(false, api.nvim_win_is_valid(otherwin)) + eq(':', fn.getcmdwintype()) + -- Closing cmdwin in context of a non-previous window is still OK. + otherwin = api.nvim_open_win(oldbuf, false, { + relative = 'editor', + row = 10, + col = 10, + width = 10, + height = 10, + }) + exec_lua( + [[ + local otherwin, cmdwin = ... + vim.api.nvim_win_call(otherwin, function() + vim.api.nvim_win_close(cmdwin, true) + end) + ]], + otherwin, + api.nvim_get_current_win() + ) + eq('', fn.getcmdwintype()) + eq(true, api.nvim_win_is_valid(otherwin)) end) it('closing current (float) window of another tabpage #15313', function() command('tabedit') command('botright split') - local prevwin = curwin().id + local prevwin = curwin() eq(2, eval('tabpagenr()')) - local win = meths.open_win(0, true, { - relative='editor', row=10, col=10, width=50, height=10 + local win = api.nvim_open_win(0, true, { + relative = 'editor', + row = 10, + col = 10, + width = 50, + height = 10, }) local tab = eval('tabpagenr()') command('tabprevious') eq(1, eval('tabpagenr()')) - meths.win_close(win, false) + api.nvim_win_close(win, false) - eq(prevwin, meths.tabpage_get_win(tab).id) + eq(prevwin, api.nvim_tabpage_get_win(tab)) assert_alive() end) end) describe('hide', function() it('can hide current window', function() - local oldwin = meths.get_current_win() + local oldwin = api.nvim_get_current_win() command('split') - local newwin = meths.get_current_win() - meths.win_hide(newwin) - eq({oldwin}, meths.list_wins()) + local newwin = api.nvim_get_current_win() + api.nvim_win_hide(newwin) + eq({ oldwin }, api.nvim_list_wins()) end) it('can hide noncurrent window', function() - local oldwin = meths.get_current_win() + local oldwin = api.nvim_get_current_win() command('split') - local newwin = meths.get_current_win() - meths.win_hide(oldwin) - eq({newwin}, meths.list_wins()) + local newwin = api.nvim_get_current_win() + api.nvim_win_hide(oldwin) + eq({ newwin }, api.nvim_list_wins()) end) it('does not close the buffer', function() - local oldwin = meths.get_current_win() - local oldbuf = meths.get_current_buf() - local buf = meths.create_buf(true, false) - local newwin = meths.open_win(buf, true, { - relative='win', row=3, col=3, width=12, height=3 + local oldwin = api.nvim_get_current_win() + local oldbuf = api.nvim_get_current_buf() + local buf = api.nvim_create_buf(true, false) + local newwin = api.nvim_open_win(buf, true, { + relative = 'win', + row = 3, + col = 3, + width = 12, + height = 3, }) - meths.win_hide(newwin) - eq({oldwin}, meths.list_wins()) - eq({oldbuf, buf}, meths.list_bufs()) + api.nvim_win_hide(newwin) + eq({ oldwin }, api.nvim_list_wins()) + eq({ oldbuf, buf }, api.nvim_list_bufs()) end) it('deletes the buffer when bufhidden=wipe', function() - local oldwin = meths.get_current_win() - local oldbuf = meths.get_current_buf() - local buf = meths.create_buf(true, false).id - local newwin = meths.open_win(buf, true, { - relative='win', row=3, col=3, width=12, height=3 + local oldwin = api.nvim_get_current_win() + local oldbuf = api.nvim_get_current_buf() + local buf = api.nvim_create_buf(true, false) + local newwin = api.nvim_open_win(buf, true, { + relative = 'win', + row = 3, + col = 3, + width = 12, + height = 3, }) - meths.set_option_value('bufhidden', 'wipe', {buf=buf}) - meths.win_hide(newwin) - eq({oldwin}, meths.list_wins()) - eq({oldbuf}, meths.list_bufs()) + api.nvim_set_option_value('bufhidden', 'wipe', { buf = buf }) + api.nvim_win_hide(newwin) + eq({ oldwin }, api.nvim_list_wins()) + eq({ oldbuf }, api.nvim_list_bufs()) end) it('in the cmdwin', function() feed('q:') -- Can close the cmdwin. - meths.win_hide(0) - eq('', funcs.getcmdwintype()) - - local old_win = meths.get_current_win() - local other_win = meths.open_win(0, false, { - relative='win', row=3, col=3, width=12, height=3 + api.nvim_win_hide(0) + eq('', fn.getcmdwintype()) + + local old_buf = api.nvim_get_current_buf() + local old_win = api.nvim_get_current_win() + local other_win = api.nvim_open_win(0, false, { + relative = 'win', + row = 3, + col = 3, + width = 12, + height = 3, }) feed('q:') -- Cannot close the previous window. - eq('E11: Invalid in command-line window; <CR> executes, CTRL-C quits', - pcall_err(meths.win_hide, old_win)) + eq( + 'E11: Invalid in command-line window; <CR> executes, CTRL-C quits', + pcall_err(api.nvim_win_hide, old_win) + ) -- Can close other windows. - meths.win_hide(other_win) - eq(false, meths.win_is_valid(other_win)) + api.nvim_win_hide(other_win) + eq(false, api.nvim_win_is_valid(other_win)) + + -- Closing curwin in context of a different window shouldn't close cmdwin. + other_win = api.nvim_open_win(old_buf, false, { + relative = 'editor', + row = 10, + col = 10, + width = 10, + height = 10, + }) + exec_lua( + [[ + vim.api.nvim_win_call(..., function() + vim.api.nvim_win_hide(0) + end) + ]], + other_win + ) + eq(false, api.nvim_win_is_valid(other_win)) + eq(':', fn.getcmdwintype()) + -- Closing cmdwin in context of a non-previous window is still OK. + other_win = api.nvim_open_win(old_buf, false, { + relative = 'editor', + row = 10, + col = 10, + width = 10, + height = 10, + }) + exec_lua( + [[ + local otherwin, cmdwin = ... + vim.api.nvim_win_call(otherwin, function() + vim.api.nvim_win_hide(cmdwin) + end) + ]], + other_win, + api.nvim_get_current_win() + ) + eq('', fn.getcmdwintype()) + eq(true, api.nvim_win_is_valid(other_win)) end) end) describe('text_height', function() it('validation', function() - local X = meths.get_vvar('maxcol') + local X = api.nvim_get_vvar('maxcol') insert([[ aaa bbb ccc ddd eee]]) - eq("Invalid window id: 23", - pcall_err(meths.win_text_height, 23, {})) - eq("Line index out of bounds", - pcall_err(curwinmeths.text_height, { start_row = 5 })) - eq("Line index out of bounds", - pcall_err(curwinmeths.text_height, { start_row = -6 })) - eq("Line index out of bounds", - pcall_err(curwinmeths.text_height, { end_row = 5 })) - eq("Line index out of bounds", - pcall_err(curwinmeths.text_height, { end_row = -6 })) - eq("'start_row' is higher than 'end_row'", - pcall_err(curwinmeths.text_height, { start_row = 3, end_row = 1 })) - eq("'start_vcol' specified without 'start_row'", - pcall_err(curwinmeths.text_height, { end_row = 2, start_vcol = 0 })) - eq("'end_vcol' specified without 'end_row'", - pcall_err(curwinmeths.text_height, { start_row = 2, end_vcol = 0 })) - eq("Invalid 'start_vcol': out of range", - pcall_err(curwinmeths.text_height, { start_row = 2, start_vcol = -1 })) - eq("Invalid 'start_vcol': out of range", - pcall_err(curwinmeths.text_height, { start_row = 2, start_vcol = X + 1 })) - eq("Invalid 'end_vcol': out of range", - pcall_err(curwinmeths.text_height, { end_row = 2, end_vcol = -1 })) - eq("Invalid 'end_vcol': out of range", - pcall_err(curwinmeths.text_height, { end_row = 2, end_vcol = X + 1 })) - eq("'start_vcol' is higher than 'end_vcol'", - pcall_err(curwinmeths.text_height, { start_row = 2, end_row = 2, start_vcol = 10, end_vcol = 5 })) + eq('Invalid window id: 23', pcall_err(api.nvim_win_text_height, 23, {})) + eq('Line index out of bounds', pcall_err(api.nvim_win_text_height, 0, { start_row = 5 })) + eq('Line index out of bounds', pcall_err(api.nvim_win_text_height, 0, { start_row = -6 })) + eq('Line index out of bounds', pcall_err(api.nvim_win_text_height, 0, { end_row = 5 })) + eq('Line index out of bounds', pcall_err(api.nvim_win_text_height, 0, { end_row = -6 })) + eq( + "'start_row' is higher than 'end_row'", + pcall_err(api.nvim_win_text_height, 0, { start_row = 3, end_row = 1 }) + ) + eq( + "'start_vcol' specified without 'start_row'", + pcall_err(api.nvim_win_text_height, 0, { end_row = 2, start_vcol = 0 }) + ) + eq( + "'end_vcol' specified without 'end_row'", + pcall_err(api.nvim_win_text_height, 0, { start_row = 2, end_vcol = 0 }) + ) + eq( + "Invalid 'start_vcol': out of range", + pcall_err(api.nvim_win_text_height, 0, { start_row = 2, start_vcol = -1 }) + ) + eq( + "Invalid 'start_vcol': out of range", + pcall_err(api.nvim_win_text_height, 0, { start_row = 2, start_vcol = X + 1 }) + ) + eq( + "Invalid 'end_vcol': out of range", + pcall_err(api.nvim_win_text_height, 0, { end_row = 2, end_vcol = -1 }) + ) + eq( + "Invalid 'end_vcol': out of range", + pcall_err(api.nvim_win_text_height, 0, { end_row = 2, end_vcol = X + 1 }) + ) + eq( + "'start_vcol' is higher than 'end_vcol'", + pcall_err( + api.nvim_win_text_height, + 0, + { start_row = 2, end_row = 2, start_vcol = 10, end_vcol = 5 } + ) + ) end) it('with two diff windows', function() - local X = meths.get_vvar('maxcol') + local X = api.nvim_get_vvar('maxcol') local screen = Screen.new(45, 22) screen:set_default_attr_ids({ - [0] = {foreground = Screen.colors.Blue1, bold = true}; - [1] = {foreground = Screen.colors.Blue4, background = Screen.colors.Grey}; - [2] = {foreground = Screen.colors.Brown}; - [3] = {foreground = Screen.colors.Blue1, background = Screen.colors.LightCyan1, bold = true}; - [4] = {background = Screen.colors.LightBlue}; - [5] = {foreground = Screen.colors.Blue4, background = Screen.colors.LightGrey}; - [6] = {background = Screen.colors.Plum1}; - [7] = {background = Screen.colors.Red, bold = true}; - [8] = {reverse = true}; - [9] = {bold = true, reverse = true}; + [0] = { foreground = Screen.colors.Blue1, bold = true }, + [1] = { foreground = Screen.colors.Blue4, background = Screen.colors.Grey }, + [2] = { foreground = Screen.colors.Brown }, + [3] = { + foreground = Screen.colors.Blue1, + background = Screen.colors.LightCyan1, + bold = true, + }, + [4] = { background = Screen.colors.LightBlue }, + [5] = { foreground = Screen.colors.Blue4, background = Screen.colors.LightGrey }, + [6] = { background = Screen.colors.Plum1 }, + [7] = { background = Screen.colors.Red, bold = true }, + [8] = { reverse = true }, + [9] = { bold = true, reverse = true }, }) screen:attach() exec([[ @@ -700,7 +860,8 @@ describe('API/win', function() windo diffthis ]]) feed('24gg') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: }{2: }{3:----------------}│{1: }{2: 1 }{4:00000001! }| {1: }{2: }{3:----------------}│{1: }{2: 2 }{4:00000002!! }| {1: }{2: 1 }00000003!!! │{1: }{2: 3 }00000003!!! | @@ -723,68 +884,117 @@ describe('API/win', function() {1: }{2: 41 }{4:00000050!!!!!!!!}│{1: }{2: }{3:----------------}| {8:[No Name] [+] }{9:[No Name] [+] }| | - ]]} + ]], + } screen:try_resize(45, 3) - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: }{2: 19 }00000028!!!!!!!!│{1: }{2: 24 }^00000028!!!!!!!!| {8:[No Name] [+] }{9:[No Name] [+] }| | - ]]} - eq({ all = 20, fill = 5 }, meths.win_text_height(1000, {})) - eq({ all = 20, fill = 5 }, meths.win_text_height(1001, {})) - eq({ all = 20, fill = 5 }, meths.win_text_height(1000, { start_row = 0 })) - eq({ all = 20, fill = 5 }, meths.win_text_height(1001, { start_row = 0 })) - eq({ all = 15, fill = 0 }, meths.win_text_height(1000, { end_row = -1 })) - eq({ all = 15, fill = 0 }, meths.win_text_height(1000, { end_row = 40 })) - eq({ all = 20, fill = 5 }, meths.win_text_height(1001, { end_row = -1 })) - eq({ all = 20, fill = 5 }, meths.win_text_height(1001, { end_row = 40 })) - eq({ all = 10, fill = 5 }, meths.win_text_height(1000, { start_row = 23 })) - eq({ all = 13, fill = 3 }, meths.win_text_height(1001, { start_row = 18 })) - eq({ all = 11, fill = 0 }, meths.win_text_height(1000, { end_row = 23 })) - eq({ all = 11, fill = 5 }, meths.win_text_height(1001, { end_row = 18 })) - eq({ all = 11, fill = 0 }, meths.win_text_height(1000, { start_row = 3, end_row = 39 })) - eq({ all = 11, fill = 3 }, meths.win_text_height(1001, { start_row = 1, end_row = 34 })) - eq({ all = 9, fill = 0 }, meths.win_text_height(1000, { start_row = 4, end_row = 38 })) - eq({ all = 9, fill = 3 }, meths.win_text_height(1001, { start_row = 2, end_row = 33 })) - eq({ all = 9, fill = 0 }, meths.win_text_height(1000, { start_row = 5, end_row = 37 })) - eq({ all = 9, fill = 3 }, meths.win_text_height(1001, { start_row = 3, end_row = 32 })) - eq({ all = 9, fill = 0 }, meths.win_text_height(1000, { start_row = 17, end_row = 25 })) - eq({ all = 9, fill = 3 }, meths.win_text_height(1001, { start_row = 15, end_row = 20 })) - eq({ all = 7, fill = 0 }, meths.win_text_height(1000, { start_row = 18, end_row = 24 })) - eq({ all = 7, fill = 3 }, meths.win_text_height(1001, { start_row = 16, end_row = 19 })) - eq({ all = 6, fill = 5 }, meths.win_text_height(1000, { start_row = -1 })) - eq({ all = 5, fill = 5 }, meths.win_text_height(1000, { start_row = -1, start_vcol = X })) - eq({ all = 0, fill = 0 }, meths.win_text_height(1000, { start_row = -1, start_vcol = X, end_row = -1 })) - eq({ all = 0, fill = 0 }, meths.win_text_height(1000, { start_row = -1, start_vcol = X, end_row = -1, end_vcol = X })) - eq({ all = 1, fill = 0 }, meths.win_text_height(1000, { start_row = -1, start_vcol = 0, end_row = -1, end_vcol = X })) - eq({ all = 3, fill = 2 }, meths.win_text_height(1001, { end_row = 0 })) - eq({ all = 2, fill = 2 }, meths.win_text_height(1001, { end_row = 0, end_vcol = 0 })) - eq({ all = 2, fill = 2 }, meths.win_text_height(1001, { start_row = 0, end_row = 0, end_vcol = 0 })) - eq({ all = 0, fill = 0 }, meths.win_text_height(1001, { start_row = 0, start_vcol = 0, end_row = 0, end_vcol = 0 })) - eq({ all = 1, fill = 0 }, meths.win_text_height(1001, { start_row = 0, start_vcol = 0, end_row = 0, end_vcol = X })) - eq({ all = 11, fill = 5 }, meths.win_text_height(1001, { end_row = 18 })) - eq({ all = 9, fill = 3 }, meths.win_text_height(1001, { start_row = 0, start_vcol = 0, end_row = 18 })) - eq({ all = 10, fill = 5 }, meths.win_text_height(1001, { end_row = 18, end_vcol = 0 })) - eq({ all = 8, fill = 3 }, meths.win_text_height(1001, { start_row = 0, start_vcol = 0, end_row = 18, end_vcol = 0 })) + ]], + } + eq({ all = 20, fill = 5 }, api.nvim_win_text_height(1000, {})) + eq({ all = 20, fill = 5 }, api.nvim_win_text_height(1001, {})) + eq({ all = 20, fill = 5 }, api.nvim_win_text_height(1000, { start_row = 0 })) + eq({ all = 20, fill = 5 }, api.nvim_win_text_height(1001, { start_row = 0 })) + eq({ all = 15, fill = 0 }, api.nvim_win_text_height(1000, { end_row = -1 })) + eq({ all = 15, fill = 0 }, api.nvim_win_text_height(1000, { end_row = 40 })) + eq({ all = 20, fill = 5 }, api.nvim_win_text_height(1001, { end_row = -1 })) + eq({ all = 20, fill = 5 }, api.nvim_win_text_height(1001, { end_row = 40 })) + eq({ all = 10, fill = 5 }, api.nvim_win_text_height(1000, { start_row = 23 })) + eq({ all = 13, fill = 3 }, api.nvim_win_text_height(1001, { start_row = 18 })) + eq({ all = 11, fill = 0 }, api.nvim_win_text_height(1000, { end_row = 23 })) + eq({ all = 11, fill = 5 }, api.nvim_win_text_height(1001, { end_row = 18 })) + eq({ all = 11, fill = 0 }, api.nvim_win_text_height(1000, { start_row = 3, end_row = 39 })) + eq({ all = 11, fill = 3 }, api.nvim_win_text_height(1001, { start_row = 1, end_row = 34 })) + eq({ all = 9, fill = 0 }, api.nvim_win_text_height(1000, { start_row = 4, end_row = 38 })) + eq({ all = 9, fill = 3 }, api.nvim_win_text_height(1001, { start_row = 2, end_row = 33 })) + eq({ all = 9, fill = 0 }, api.nvim_win_text_height(1000, { start_row = 5, end_row = 37 })) + eq({ all = 9, fill = 3 }, api.nvim_win_text_height(1001, { start_row = 3, end_row = 32 })) + eq({ all = 9, fill = 0 }, api.nvim_win_text_height(1000, { start_row = 17, end_row = 25 })) + eq({ all = 9, fill = 3 }, api.nvim_win_text_height(1001, { start_row = 15, end_row = 20 })) + eq({ all = 7, fill = 0 }, api.nvim_win_text_height(1000, { start_row = 18, end_row = 24 })) + eq({ all = 7, fill = 3 }, api.nvim_win_text_height(1001, { start_row = 16, end_row = 19 })) + eq({ all = 6, fill = 5 }, api.nvim_win_text_height(1000, { start_row = -1 })) + eq({ all = 5, fill = 5 }, api.nvim_win_text_height(1000, { start_row = -1, start_vcol = X })) + eq( + { all = 0, fill = 0 }, + api.nvim_win_text_height(1000, { start_row = -1, start_vcol = X, end_row = -1 }) + ) + eq( + { all = 0, fill = 0 }, + api.nvim_win_text_height( + 1000, + { start_row = -1, start_vcol = X, end_row = -1, end_vcol = X } + ) + ) + eq( + { all = 1, fill = 0 }, + api.nvim_win_text_height( + 1000, + { start_row = -1, start_vcol = 0, end_row = -1, end_vcol = X } + ) + ) + eq({ all = 3, fill = 2 }, api.nvim_win_text_height(1001, { end_row = 0 })) + eq({ all = 2, fill = 2 }, api.nvim_win_text_height(1001, { end_row = 0, end_vcol = 0 })) + eq( + { all = 2, fill = 2 }, + api.nvim_win_text_height(1001, { start_row = 0, end_row = 0, end_vcol = 0 }) + ) + eq( + { all = 0, fill = 0 }, + api.nvim_win_text_height(1001, { start_row = 0, start_vcol = 0, end_row = 0, end_vcol = 0 }) + ) + eq( + { all = 1, fill = 0 }, + api.nvim_win_text_height(1001, { start_row = 0, start_vcol = 0, end_row = 0, end_vcol = X }) + ) + eq({ all = 11, fill = 5 }, api.nvim_win_text_height(1001, { end_row = 18 })) + eq( + { all = 9, fill = 3 }, + api.nvim_win_text_height(1001, { start_row = 0, start_vcol = 0, end_row = 18 }) + ) + eq({ all = 10, fill = 5 }, api.nvim_win_text_height(1001, { end_row = 18, end_vcol = 0 })) + eq( + { all = 8, fill = 3 }, + api.nvim_win_text_height( + 1001, + { start_row = 0, start_vcol = 0, end_row = 18, end_vcol = 0 } + ) + ) end) it('with wrapped lines', function() - local X = meths.get_vvar('maxcol') + local X = api.nvim_get_vvar('maxcol') local screen = Screen.new(45, 22) screen:set_default_attr_ids({ - [0] = {foreground = Screen.colors.Blue1, bold = true}; - [1] = {foreground = Screen.colors.Brown}; - [2] = {background = Screen.colors.Yellow}; + [0] = { foreground = Screen.colors.Blue1, bold = true }, + [1] = { foreground = Screen.colors.Brown }, + [2] = { background = Screen.colors.Yellow }, }) screen:attach() exec([[ set number cpoptions+=n call setline(1, repeat([repeat('foobar-', 36)], 3)) ]]) - local ns = meths.create_namespace('') - meths.buf_set_extmark(0, ns, 1, 100, { virt_text = {{('?'):rep(15), 'Search'}}, virt_text_pos = 'inline' }) - meths.buf_set_extmark(0, ns, 2, 200, { virt_text = {{('!'):rep(75), 'Search'}}, virt_text_pos = 'inline' }) - screen:expect{grid=[[ + local ns = api.nvim_create_namespace('') + api.nvim_buf_set_extmark( + 0, + ns, + 1, + 100, + { virt_text = { { ('?'):rep(15), 'Search' } }, virt_text_pos = 'inline' } + ) + api.nvim_buf_set_extmark( + 0, + ns, + 2, + 200, + { virt_text = { { ('!'):rep(75), 'Search' } }, virt_text_pos = 'inline' } + ) + screen:expect { + grid = [[ {1: 1 }^foobar-foobar-foobar-foobar-foobar-foobar| -foobar-foobar-foobar-foobar-foobar-foobar-fo| obar-foobar-foobar-foobar-foobar-foobar-fooba| @@ -807,133 +1017,897 @@ describe('API/win', function() {2:!!!!!!!!!}ar-foobar-foobar-foobar-foobar-fooba| r-foobar-foobar- | | - ]]} + ]], + } screen:try_resize(45, 2) - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: 1 }^foobar-foobar-foobar-foobar-foobar-foobar| | - ]]} - eq({ all = 21, fill = 0 }, meths.win_text_height(0, {})) - eq({ all = 6, fill = 0 }, meths.win_text_height(0, { start_row = 0, end_row = 0 })) - eq({ all = 7, fill = 0 }, meths.win_text_height(0, { start_row = 1, end_row = 1 })) - eq({ all = 8, fill = 0 }, meths.win_text_height(0, { start_row = 2, end_row = 2 })) - eq({ all = 0, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 0 })) - eq({ all = 1, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 41 })) - eq({ all = 2, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 42 })) - eq({ all = 2, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 86 })) - eq({ all = 3, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 87 })) - eq({ all = 6, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 266 })) - eq({ all = 7, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 267 })) - eq({ all = 7, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 311 })) - eq({ all = 7, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 312 })) - eq({ all = 7, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = X })) - eq({ all = 7, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 40, end_row = 1, end_vcol = X })) - eq({ all = 6, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 41, end_row = 1, end_vcol = X })) - eq({ all = 6, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 85, end_row = 1, end_vcol = X })) - eq({ all = 5, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 86, end_row = 1, end_vcol = X })) - eq({ all = 2, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 265, end_row = 1, end_vcol = X })) - eq({ all = 1, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 266, end_row = 1, end_vcol = X })) - eq({ all = 1, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 310, end_row = 1, end_vcol = X })) - eq({ all = 0, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 311, end_row = 1, end_vcol = X })) - eq({ all = 1, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 86, end_row = 1, end_vcol = 131 })) - eq({ all = 1, fill = 0 }, meths.win_text_height(0, { start_row = 1, start_vcol = 221, end_row = 1, end_vcol = 266 })) - eq({ all = 18, fill = 0 }, meths.win_text_height(0, { start_row = 0, start_vcol = 131 })) - eq({ all = 19, fill = 0 }, meths.win_text_height(0, { start_row = 0, start_vcol = 130 })) - eq({ all = 20, fill = 0 }, meths.win_text_height(0, { end_row = 2, end_vcol = 311 })) - eq({ all = 21, fill = 0 }, meths.win_text_height(0, { end_row = 2, end_vcol = 312 })) - eq({ all = 17, fill = 0 }, meths.win_text_height(0, { start_row = 0, start_vcol = 131, end_row = 2, end_vcol = 311 })) - eq({ all = 19, fill = 0 }, meths.win_text_height(0, { start_row = 0, start_vcol = 130, end_row = 2, end_vcol = 312 })) - eq({ all = 16, fill = 0 }, meths.win_text_height(0, { start_row = 0, start_vcol = 221 })) - eq({ all = 17, fill = 0 }, meths.win_text_height(0, { start_row = 0, start_vcol = 220 })) - eq({ all = 14, fill = 0 }, meths.win_text_height(0, { end_row = 2, end_vcol = 41 })) - eq({ all = 15, fill = 0 }, meths.win_text_height(0, { end_row = 2, end_vcol = 42 })) - eq({ all = 9, fill = 0 }, meths.win_text_height(0, { start_row = 0, start_vcol = 221, end_row = 2, end_vcol = 41 })) - eq({ all = 11, fill = 0 }, meths.win_text_height(0, { start_row = 0, start_vcol = 220, end_row = 2, end_vcol = 42 })) + ]], + } + eq({ all = 21, fill = 0 }, api.nvim_win_text_height(0, {})) + eq({ all = 6, fill = 0 }, api.nvim_win_text_height(0, { start_row = 0, end_row = 0 })) + eq({ all = 7, fill = 0 }, api.nvim_win_text_height(0, { start_row = 1, end_row = 1 })) + eq({ all = 8, fill = 0 }, api.nvim_win_text_height(0, { start_row = 2, end_row = 2 })) + eq( + { all = 0, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 0 }) + ) + eq( + { all = 1, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 41 }) + ) + eq( + { all = 2, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 42 }) + ) + eq( + { all = 2, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 86 }) + ) + eq( + { all = 3, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 87 }) + ) + eq( + { all = 6, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 266 }) + ) + eq( + { all = 7, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 267 }) + ) + eq( + { all = 7, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 311 }) + ) + eq( + { all = 7, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = 312 }) + ) + eq( + { all = 7, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 1, start_vcol = 0, end_row = 1, end_vcol = X }) + ) + eq( + { all = 7, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 1, start_vcol = 40, end_row = 1, end_vcol = X }) + ) + eq( + { all = 6, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 1, start_vcol = 41, end_row = 1, end_vcol = X }) + ) + eq( + { all = 6, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 1, start_vcol = 85, end_row = 1, end_vcol = X }) + ) + eq( + { all = 5, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 1, start_vcol = 86, end_row = 1, end_vcol = X }) + ) + eq( + { all = 2, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 1, start_vcol = 265, end_row = 1, end_vcol = X }) + ) + eq( + { all = 1, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 1, start_vcol = 266, end_row = 1, end_vcol = X }) + ) + eq( + { all = 1, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 1, start_vcol = 310, end_row = 1, end_vcol = X }) + ) + eq( + { all = 0, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 1, start_vcol = 311, end_row = 1, end_vcol = X }) + ) + eq( + { all = 1, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 1, start_vcol = 86, end_row = 1, end_vcol = 131 }) + ) + eq( + { all = 1, fill = 0 }, + api.nvim_win_text_height( + 0, + { start_row = 1, start_vcol = 221, end_row = 1, end_vcol = 266 } + ) + ) + eq({ all = 18, fill = 0 }, api.nvim_win_text_height(0, { start_row = 0, start_vcol = 131 })) + eq({ all = 19, fill = 0 }, api.nvim_win_text_height(0, { start_row = 0, start_vcol = 130 })) + eq({ all = 20, fill = 0 }, api.nvim_win_text_height(0, { end_row = 2, end_vcol = 311 })) + eq({ all = 21, fill = 0 }, api.nvim_win_text_height(0, { end_row = 2, end_vcol = 312 })) + eq( + { all = 17, fill = 0 }, + api.nvim_win_text_height( + 0, + { start_row = 0, start_vcol = 131, end_row = 2, end_vcol = 311 } + ) + ) + eq( + { all = 19, fill = 0 }, + api.nvim_win_text_height( + 0, + { start_row = 0, start_vcol = 130, end_row = 2, end_vcol = 312 } + ) + ) + eq({ all = 16, fill = 0 }, api.nvim_win_text_height(0, { start_row = 0, start_vcol = 221 })) + eq({ all = 17, fill = 0 }, api.nvim_win_text_height(0, { start_row = 0, start_vcol = 220 })) + eq({ all = 14, fill = 0 }, api.nvim_win_text_height(0, { end_row = 2, end_vcol = 41 })) + eq({ all = 15, fill = 0 }, api.nvim_win_text_height(0, { end_row = 2, end_vcol = 42 })) + eq( + { all = 9, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 0, start_vcol = 221, end_row = 2, end_vcol = 41 }) + ) + eq( + { all = 11, fill = 0 }, + api.nvim_win_text_height(0, { start_row = 0, start_vcol = 220, end_row = 2, end_vcol = 42 }) + ) end) end) describe('open_win', function() it('noautocmd option works', function() command('autocmd BufEnter,BufLeave,BufWinEnter * let g:fired = 1') - meths.open_win(meths.create_buf(true, true), true, { - relative='win', row=3, col=3, width=12, height=3, noautocmd=true + api.nvim_open_win(api.nvim_create_buf(true, true), true, { + relative = 'win', + row = 3, + col = 3, + width = 12, + height = 3, + noautocmd = true, }) - eq(0, funcs.exists('g:fired')) - meths.open_win(meths.create_buf(true, true), true, { - relative='win', row=3, col=3, width=12, height=3 + eq(0, fn.exists('g:fired')) + api.nvim_open_win(api.nvim_create_buf(true, true), true, { + relative = 'win', + row = 3, + col = 3, + width = 12, + height = 3, }) - eq(1, funcs.exists('g:fired')) + eq(1, fn.exists('g:fired')) end) - it('disallowed in cmdwin if enter=true or buf=curbuf', function() - local new_buf = meths.create_buf(true, true) + it('disallowed in cmdwin if enter=true or buf=cmdwin_buf', function() + local new_buf = api.nvim_create_buf(true, true) feed('q:') - eq('E11: Invalid in command-line window; <CR> executes, CTRL-C quits', - pcall_err(meths.open_win, new_buf, true, { - relative='editor', row=5, col=5, width=5, height=5, - })) - eq('E11: Invalid in command-line window; <CR> executes, CTRL-C quits', - pcall_err(meths.open_win, 0, false, { - relative='editor', row=5, col=5, width=5, height=5, - })) - - eq(new_buf, meths.win_get_buf(meths.open_win(new_buf, false, { - relative='editor', row=5, col=5, width=5, height=5, - }))) + eq( + 'E11: Invalid in command-line window; <CR> executes, CTRL-C quits', + pcall_err(api.nvim_open_win, new_buf, true, { + relative = 'editor', + row = 5, + col = 5, + width = 5, + height = 5, + }) + ) + eq( + 'E11: Invalid in command-line window; <CR> executes, CTRL-C quits', + pcall_err(api.nvim_open_win, 0, false, { + relative = 'editor', + row = 5, + col = 5, + width = 5, + height = 5, + }) + ) + matches( + 'E11: Invalid in command%-line window; <CR> executes, CTRL%-C quits$', + pcall_err( + exec_lua, + [[ + local cmdwin_buf = vim.api.nvim_get_current_buf() + vim.api.nvim_buf_call(vim.api.nvim_create_buf(false, true), function() + vim.api.nvim_open_win(cmdwin_buf, false, { + relative='editor', row=5, col=5, width=5, height=5, + }) + end) + ]] + ) + ) + + eq( + new_buf, + api.nvim_win_get_buf(api.nvim_open_win(new_buf, false, { + relative = 'editor', + row = 5, + col = 5, + width = 5, + height = 5, + })) + ) end) it('aborts if buffer is invalid', function() - local wins_before = meths.list_wins() - eq('Invalid buffer id: 1337', pcall_err(meths.open_win, 1337, false, { - relative='editor', row=5, col=5, width=5, height=5, - })) - eq(wins_before, meths.list_wins()) + local wins_before = api.nvim_list_wins() + eq( + 'Invalid buffer id: 1337', + pcall_err(api.nvim_open_win, 1337, false, { + relative = 'editor', + row = 5, + col = 5, + width = 5, + height = 5, + }) + ) + eq(wins_before, api.nvim_list_wins()) + end) + + it('creates a split window', function() + local win = api.nvim_open_win(0, true, { + vertical = false, + }) + eq('', api.nvim_win_get_config(win).relative) + end) + + it('creates split windows in the correct direction', function() + local initial_win = api.nvim_get_current_win() + local win = api.nvim_open_win(0, true, { + vertical = true, + }) + eq('', api.nvim_win_get_config(win).relative) + + local layout = fn.winlayout() + + eq({ + 'row', + { + { 'leaf', win }, + { 'leaf', initial_win }, + }, + }, layout) + end) + + it("respects the 'split' option", function() + local initial_win = api.nvim_get_current_win() + local win = api.nvim_open_win(0, true, { + split = 'below', + }) + eq('', api.nvim_win_get_config(win).relative) + + local layout = fn.winlayout() + + eq({ + 'col', + { + { 'leaf', initial_win }, + { 'leaf', win }, + }, + }, layout) + end) + + it( + "doesn't change tp_curwin when splitting window in non-current tab with enter=false", + function() + local tab1 = api.nvim_get_current_tabpage() + local tab1_win = api.nvim_get_current_win() + + helpers.command('tabnew') + local tab2 = api.nvim_get_current_tabpage() + local tab2_win = api.nvim_get_current_win() + + eq({ tab1_win, tab2_win }, api.nvim_list_wins()) + eq({ tab1, tab2 }, api.nvim_list_tabpages()) + + api.nvim_set_current_tabpage(tab1) + eq(tab1_win, api.nvim_get_current_win()) + + local tab2_prevwin = fn.tabpagewinnr(tab2, '#') + + -- split in tab2 whine in tab2, with enter = false + local tab2_win2 = api.nvim_open_win(api.nvim_create_buf(false, true), false, { + win = tab2_win, + split = 'right', + }) + eq(tab1_win, api.nvim_get_current_win()) -- we should still be in the first tp + eq(tab1_win, api.nvim_tabpage_get_win(tab1)) + + eq(tab2_win, api.nvim_tabpage_get_win(tab2)) -- tab2's tp_curwin should not have changed + eq(tab2_prevwin, fn.tabpagewinnr(tab2, '#')) -- tab2's tp_prevwin should not have changed + eq({ tab1_win, tab2_win, tab2_win2 }, api.nvim_list_wins()) + eq({ tab2_win, tab2_win2 }, api.nvim_tabpage_list_wins(tab2)) + end + ) + + it('creates splits in the correct location', function() + local first_win = api.nvim_get_current_win() + -- specifying window 0 should create a split next to the current window + local win = api.nvim_open_win(0, true, { + vertical = false, + }) + local layout = fn.winlayout() + eq({ + 'col', + { + { 'leaf', win }, + { 'leaf', first_win }, + }, + }, layout) + -- not specifying a window should create a top-level split + local win2 = api.nvim_open_win(0, true, { + split = 'left', + win = -1, + }) + layout = fn.winlayout() + eq({ + 'row', + { + { 'leaf', win2 }, + { + 'col', + { + { 'leaf', win }, + { 'leaf', first_win }, + }, + }, + }, + }, layout) + + -- specifying a window should create a split next to that window + local win3 = api.nvim_open_win(0, true, { + win = win, + vertical = false, + }) + layout = fn.winlayout() + eq({ + 'row', + { + { 'leaf', win2 }, + { + 'col', + { + { 'leaf', win3 }, + { 'leaf', win }, + { 'leaf', first_win }, + }, + }, + }, + }, layout) + end) + end) + + describe('set_config', function() + it('moves a split into a float', function() + local win = api.nvim_open_win(0, true, { + vertical = false, + }) + eq('', api.nvim_win_get_config(win).relative) + api.nvim_win_set_config(win, { + relative = 'editor', + row = 5, + col = 5, + width = 5, + height = 5, + }) + eq('editor', api.nvim_win_get_config(win).relative) + end) + + it('throws error when attempting to move the last window', function() + local err = pcall_err(api.nvim_win_set_config, 0, { + vertical = false, + }) + eq('Cannot move last window', err) + end) + + it('passing retval of get_config results in no-op', function() + -- simple split layout + local win = api.nvim_open_win(0, true, { + split = 'left', + }) + local layout = fn.winlayout() + local config = api.nvim_win_get_config(win) + api.nvim_win_set_config(win, config) + eq(layout, fn.winlayout()) + + -- nested split layout + local win2 = api.nvim_open_win(0, true, { + vertical = true, + }) + local win3 = api.nvim_open_win(0, true, { + win = win2, + vertical = false, + }) + layout = fn.winlayout() + config = api.nvim_win_get_config(win2) + api.nvim_win_set_config(win2, config) + eq(layout, fn.winlayout()) + + config = api.nvim_win_get_config(win3) + api.nvim_win_set_config(win3, config) + eq(layout, fn.winlayout()) + end) + + it('moves a float into a split', function() + local layout = fn.winlayout() + eq('leaf', layout[1]) + local win = api.nvim_open_win(0, true, { + relative = 'editor', + row = 5, + col = 5, + width = 5, + height = 5, + }) + api.nvim_win_set_config(win, { + split = 'below', + win = -1, + }) + eq('', api.nvim_win_get_config(win).relative) + layout = fn.winlayout() + eq('col', layout[1]) + eq(2, #layout[2]) + eq(win, layout[2][2][2]) + end) + + it('respects the "split" option', function() + local layout = fn.winlayout() + eq('leaf', layout[1]) + local first_win = layout[2] + local win = api.nvim_open_win(0, true, { + relative = 'editor', + row = 5, + col = 5, + width = 5, + height = 5, + }) + api.nvim_win_set_config(win, { + split = 'right', + win = first_win, + }) + layout = fn.winlayout() + eq('row', layout[1]) + eq(2, #layout[2]) + eq(win, layout[2][2][2]) + local config = api.nvim_win_get_config(win) + eq('', config.relative) + eq('right', config.split) + api.nvim_win_set_config(win, { + split = 'below', + win = first_win, + }) + layout = fn.winlayout() + eq('col', layout[1]) + eq(2, #layout[2]) + eq(win, layout[2][2][2]) + config = api.nvim_win_get_config(win) + eq('', config.relative) + eq('below', config.split) + end) + + it('creates top-level splits', function() + local win = api.nvim_open_win(0, true, { + vertical = false, + }) + local win2 = api.nvim_open_win(0, true, { + vertical = true, + win = -1, + }) + local layout = fn.winlayout() + eq('row', layout[1]) + eq(2, #layout[2]) + eq(win2, layout[2][1][2]) + api.nvim_win_set_config(win, { + split = 'below', + win = -1, + }) + layout = fn.winlayout() + eq('col', layout[1]) + eq(2, #layout[2]) + eq('row', layout[2][1][1]) + eq(win, layout[2][2][2]) + end) + + it('moves splits to other tabpages', function() + local curtab = api.nvim_get_current_tabpage() + local win = api.nvim_open_win(0, false, { split = 'left' }) + command('tabnew') + local tabnr = api.nvim_get_current_tabpage() + command('tabprev') -- return to the initial tab + + api.nvim_win_set_config(win, { + split = 'right', + win = api.nvim_tabpage_get_win(tabnr), + }) + + eq(tabnr, api.nvim_win_get_tabpage(win)) + -- we are changing the config, the current tabpage should not change + eq(curtab, api.nvim_get_current_tabpage()) + + command('tabnext') -- switch to the new tabpage so we can get the layout + local layout = fn.winlayout() + + eq({ + 'row', + { + { 'leaf', api.nvim_tabpage_get_win(tabnr) }, + { 'leaf', win }, + }, + }, layout) + end) + + it('correctly moves curwin when moving curwin to a different tabpage', function() + local curtab = api.nvim_get_current_tabpage() + command('tabnew') + local tab2 = api.nvim_get_current_tabpage() + local tab2_win = api.nvim_get_current_win() + + command('tabprev') -- return to the initial tab + + local neighbor = api.nvim_get_current_win() + + -- create and enter a new split + local win = api.nvim_open_win(0, true, { + vertical = false, + }) + + eq(curtab, api.nvim_win_get_tabpage(win)) + + eq({ win, neighbor }, api.nvim_tabpage_list_wins(curtab)) + + -- move the current win to a different tabpage + api.nvim_win_set_config(win, { + split = 'right', + win = api.nvim_tabpage_get_win(tab2), + }) + + eq(curtab, api.nvim_get_current_tabpage()) + + -- win should have moved to tab2 + eq(tab2, api.nvim_win_get_tabpage(win)) + -- tp_curwin of tab2 should not have changed + eq(tab2_win, api.nvim_tabpage_get_win(tab2)) + -- win lists should be correct + eq({ tab2_win, win }, api.nvim_tabpage_list_wins(tab2)) + eq({ neighbor }, api.nvim_tabpage_list_wins(curtab)) + + -- current win should have moved to neighboring win + eq(neighbor, api.nvim_tabpage_get_win(curtab)) + end) + + it('splits windows in non-current tabpage', function() + local curtab = api.nvim_get_current_tabpage() + command('tabnew') + local tabnr = api.nvim_get_current_tabpage() + command('tabprev') -- return to the initial tab + + local win = api.nvim_open_win(0, false, { + vertical = false, + win = api.nvim_tabpage_get_win(tabnr), + }) + + eq(tabnr, api.nvim_win_get_tabpage(win)) + -- since enter = false, the current tabpage should not change + eq(curtab, api.nvim_get_current_tabpage()) + end) + + it('moves the current split window', function() + local initial_win = api.nvim_get_current_win() + local win = api.nvim_open_win(0, true, { + vertical = true, + }) + local win2 = api.nvim_open_win(0, true, { + vertical = true, + }) + api.nvim_set_current_win(win) + eq({ + 'row', + { + { 'leaf', win2 }, + { 'leaf', win }, + { 'leaf', initial_win }, + }, + }, fn.winlayout()) + + api.nvim_win_set_config(0, { + vertical = false, + win = 0, + }) + eq(win, api.nvim_get_current_win()) + eq({ + 'col', + { + { 'leaf', win }, + { + 'row', + { + { 'leaf', win2 }, + { 'leaf', initial_win }, + }, + }, + }, + }, fn.winlayout()) + + api.nvim_set_current_win(win2) + local win3 = api.nvim_open_win(0, true, { + vertical = true, + }) + eq(win3, api.nvim_get_current_win()) + + eq({ + 'col', + { + { 'leaf', win }, + { + 'row', + { + { 'leaf', win3 }, + { 'leaf', win2 }, + { 'leaf', initial_win }, + }, + }, + }, + }, fn.winlayout()) + + api.nvim_win_set_config(0, { + vertical = false, + win = 0, + }) + + eq(win3, api.nvim_get_current_win()) + eq({ + 'col', + { + { 'leaf', win }, + { + 'row', + { + { + 'col', + { + { 'leaf', win3 }, + { 'leaf', win2 }, + }, + }, + { 'leaf', initial_win }, + }, + }, + }, + }, fn.winlayout()) end) end) describe('get_config', function() it('includes border', function() local b = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' } - local win = meths.open_win(0, true, { - relative='win', row=3, col=3, width=12, height=3, + local win = api.nvim_open_win(0, true, { + relative = 'win', + row = 3, + col = 3, + width = 12, + height = 3, border = b, }) - local cfg = meths.win_get_config(win) + local cfg = api.nvim_win_get_config(win) eq(b, cfg.border) end) it('includes border with highlight group', function() local b = { - {'a', 'Normal'}, - {'b', 'Special'}, - {'c', 'String'}, - {'d', 'Comment'}, - {'e', 'Visual'}, - {'f', 'Error'}, - {'g', 'Constant'}, - {'h', 'PreProc'}, + { 'a', 'Normal' }, + { 'b', 'Special' }, + { 'c', 'String' }, + { 'd', 'Comment' }, + { 'e', 'Visual' }, + { 'f', 'Error' }, + { 'g', 'Constant' }, + { 'h', 'PreProc' }, } - local win = meths.open_win(0, true, { - relative='win', row=3, col=3, width=12, height=3, + local win = api.nvim_open_win(0, true, { + relative = 'win', + row = 3, + col = 3, + width = 12, + height = 3, border = b, }) - local cfg = meths.win_get_config(win) + local cfg = api.nvim_win_get_config(win) eq(b, cfg.border) end) it('includes title and footer', function() - local title = { {'A', {'StatusLine', 'TabLine'}}, {'B'}, {'C', 'WinBar'} } - local footer = { {'A', 'WinBar'}, {'B'}, {'C', {'StatusLine', 'TabLine'}} } - local win = meths.open_win(0, true, { - relative='win', row=3, col=3, width=12, height=3, - border = 'single', title = title, footer = footer, + local title = { { 'A', { 'StatusLine', 'TabLine' } }, { 'B' }, { 'C', 'WinBar' } } + local footer = { { 'A', 'WinBar' }, { 'B' }, { 'C', { 'StatusLine', 'TabLine' } } } + local win = api.nvim_open_win(0, true, { + relative = 'win', + row = 3, + col = 3, + width = 12, + height = 3, + border = 'single', + title = title, + footer = footer, }) - local cfg = meths.win_get_config(win) + local cfg = api.nvim_win_get_config(win) eq(title, cfg.title) eq(footer, cfg.footer) end) + + it('includes split for normal windows', function() + local win = api.nvim_open_win(0, true, { + vertical = true, + win = -1, + }) + eq('left', api.nvim_win_get_config(win).split) + api.nvim_win_set_config(win, { + vertical = false, + win = -1, + }) + eq('above', api.nvim_win_get_config(win).split) + api.nvim_win_set_config(win, { + split = 'below', + win = -1, + }) + eq('below', api.nvim_win_get_config(win).split) + end) + + it('includes split when splitting with ex commands', function() + local win = api.nvim_get_current_win() + eq('left', api.nvim_win_get_config(win).split) + + command('vsplit') + local win2 = api.nvim_get_current_win() + + -- initial window now be marked as right split + -- since it was split with a vertical split + -- and 'splitright' is false by default + eq('right', api.nvim_win_get_config(win).split) + eq('left', api.nvim_win_get_config(win2).split) + + api.nvim_set_option_value('splitbelow', true, { + scope = 'global', + }) + api.nvim_win_close(win, true) + command('split') + local win3 = api.nvim_get_current_win() + eq('below', api.nvim_win_get_config(win3).split) + end) + + it("includes the correct 'split' option in complex layouts", function() + local initial_win = api.nvim_get_current_win() + local win = api.nvim_open_win(0, false, { + split = 'right', + win = -1, + }) + + local win2 = api.nvim_open_win(0, false, { + split = 'below', + win = win, + }) + + api.nvim_win_set_config(win2, { + width = 50, + }) + + api.nvim_win_set_config(win, { + split = 'left', + win = -1, + }) + + local win3 = api.nvim_open_win(0, false, { + split = 'above', + win = -1, + }) + local float = api.nvim_open_win(0, false, { + relative = 'editor', + width = 40, + height = 20, + col = 20, + row = 10, + }) + api.nvim_win_set_config(float, { + split = 'right', + win = -1, + }) + + local layout = fn.winlayout() + + eq({ + 'row', + { + { + 'col', + { + { 'leaf', win3 }, + { + 'row', + { + { 'leaf', win }, + { 'leaf', initial_win }, + { 'leaf', win2 }, + }, + }, + }, + }, + { + 'leaf', + float, + }, + }, + }, layout) + + eq('above', api.nvim_win_get_config(win3).split) + eq('left', api.nvim_win_get_config(win).split) + eq('left', api.nvim_win_get_config(initial_win).split) + eq('right', api.nvim_win_get_config(win2).split) + eq('right', api.nvim_win_get_config(float).split) + end) + end) + + describe('set_config', function() + it('no crash with invalid title', function() + local win = api.nvim_open_win(0, true, { + width = 10, + height = 10, + relative = 'editor', + row = 10, + col = 10, + title = { { 'test' } }, + border = 'single', + }) + eq( + 'title/footer cannot be an empty array', + pcall_err(api.nvim_win_set_config, win, { title = {} }) + ) + command('redraw!') + assert_alive() + end) + + it('no crash with invalid footer', function() + local win = api.nvim_open_win(0, true, { + width = 10, + height = 10, + relative = 'editor', + row = 10, + col = 10, + footer = { { 'test' } }, + border = 'single', + }) + eq( + 'title/footer cannot be an empty array', + pcall_err(api.nvim_win_set_config, win, { footer = {} }) + ) + command('redraw!') + assert_alive() + end) + end) + + describe('set_config', function() + it('no crash with invalid title', function() + local win = api.nvim_open_win(0, true, { + width = 10, + height = 10, + relative = 'editor', + row = 10, + col = 10, + title = { { 'test' } }, + border = 'single', + }) + eq( + 'title/footer cannot be an empty array', + pcall_err(api.nvim_win_set_config, win, { title = {} }) + ) + command('redraw!') + assert_alive() + end) + + it('no crash with invalid footer', function() + local win = api.nvim_open_win(0, true, { + width = 10, + height = 10, + relative = 'editor', + row = 10, + col = 10, + footer = { { 'test' } }, + border = 'single', + }) + eq( + 'title/footer cannot be an empty array', + pcall_err(api.nvim_win_set_config, win, { footer = {} }) + ) + command('redraw!') + assert_alive() + end) end) end) diff --git a/test/functional/autocmd/autocmd_oldtest_spec.lua b/test/functional/autocmd/autocmd_oldtest_spec.lua index dfd746a06e..0243674f2d 100644 --- a/test/functional/autocmd/autocmd_oldtest_spec.lua +++ b/test/functional/autocmd/autocmd_oldtest_spec.lua @@ -3,8 +3,8 @@ local Screen = require('test.functional.ui.screen') local clear = helpers.clear local eq = helpers.eq -local meths = helpers.meths -local funcs = helpers.funcs +local api = helpers.api +local fn = helpers.fn local exec = helpers.exec local feed = helpers.feed @@ -12,7 +12,7 @@ describe('oldtests', function() before_each(clear) local exec_lines = function(str) - return funcs.split(funcs.execute(str), "\n") + return fn.split(fn.execute(str), '\n') end local add_an_autocmd = function() @@ -23,7 +23,7 @@ describe('oldtests', function() ]] eq(3, #exec_lines('au vimBarTest')) - eq(1, #meths.get_autocmds({ group = 'vimBarTest' })) + eq(1, #api.nvim_get_autocmds({ group = 'vimBarTest' })) end it('should recognize a bar before the {event}', function() @@ -31,14 +31,13 @@ describe('oldtests', function() add_an_autocmd() exec [[ augroup vimBarTest | au! | augroup END ]] eq(1, #exec_lines('au vimBarTest')) - eq({}, meths.get_autocmds({ group = 'vimBarTest' })) + eq({}, api.nvim_get_autocmds({ group = 'vimBarTest' })) -- Sad spacing add_an_autocmd() exec [[ augroup vimBarTest| au!| augroup END ]] eq(1, #exec_lines('au vimBarTest')) - -- test that a bar is recognized after the {event} add_an_autocmd() exec [[ augroup vimBarTest| au!BufReadCmd| augroup END ]] @@ -50,8 +49,8 @@ describe('oldtests', function() end) it('should fire on unload buf', function() - funcs.writefile({'Test file Xxx1'}, 'Xxx1') - funcs.writefile({'Test file Xxx2'}, 'Xxx2') + fn.writefile({ 'Test file Xxx1' }, 'Xxx1') + fn.writefile({ 'Test file Xxx2' }, 'Xxx2') local fname = 'Xtest_functional_autocmd_unload' local content = [[ @@ -72,16 +71,16 @@ describe('oldtests', function() q ]] - funcs.writefile(funcs.split(content, "\n"), fname) + fn.writefile(fn.split(content, '\n'), fname) - funcs.delete('Xout') - funcs.system(string.format('%s -u NORC -i NONE -N -S %s', meths.get_vvar('progpath'), fname)) - eq(1, funcs.filereadable('Xout')) + fn.delete('Xout') + fn.system(string.format('%s --clean -N -S %s', api.nvim_get_vvar('progpath'), fname)) + eq(1, fn.filereadable('Xout')) - funcs.delete('Xxx1') - funcs.delete('Xxx2') - funcs.delete(fname) - funcs.delete('Xout') + fn.delete('Xxx1') + fn.delete('Xxx2') + fn.delete(fname) + fn.delete('Xout') end) -- oldtest: Test_delete_ml_get_errors() @@ -89,7 +88,7 @@ describe('oldtests', function() local screen = Screen.new(75, 10) screen:attach() screen:set_default_attr_ids({ - [1] = {background = Screen.colors.Cyan}; + [1] = { background = Screen.colors.Cyan }, }) exec([[ set noshowcmd noruler scrolloff=0 @@ -97,7 +96,8 @@ describe('oldtests', function() edit test/old/testdir/samples/box.txt ]]) feed('249GV<C-End>d') - screen:expect{grid=[[ + screen:expect { + grid = [[ const auto themeEmoji = _forPeer->themeEmoji(); | if (themeEmoji.isEmpty()) { | return nonCustom; | @@ -108,9 +108,11 @@ describe('oldtests', function() return nonCustom; | {1:^}} | 353 fewer lines | - ]]} + ]], + } feed('<PageUp>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | auto BackgroundBox::Inner::resolveResetCustomPaper() const | -> std::optional<Data::WallPaper> { | @@ -121,6 +123,7 @@ describe('oldtests', function() const auto themeEmoji = _forPeer->themeEmoji(); | ^if (themeEmoji.isEmpty()) { | 353 fewer lines | - ]]} + ]], + } end) end) diff --git a/test/functional/autocmd/autocmd_spec.lua b/test/functional/autocmd/autocmd_spec.lua index 63a487c8bc..5fffb70095 100644 --- a/test/functional/autocmd/autocmd_spec.lua +++ b/test/functional/autocmd/autocmd_spec.lua @@ -10,14 +10,13 @@ local eval = helpers.eval local feed = helpers.feed local clear = helpers.clear local matches = helpers.matches -local meths = helpers.meths +local api = helpers.api local pcall_err = helpers.pcall_err -local funcs = helpers.funcs +local fn = helpers.fn local expect = helpers.expect local command = helpers.command local exc_exec = helpers.exc_exec local exec_lua = helpers.exec_lua -local curbufmeths = helpers.curbufmeths local retry = helpers.retry local source = helpers.source @@ -26,23 +25,23 @@ describe('autocmd', function() it(':tabnew, :split, :close events order, <afile>', function() local expected = { - {'WinLeave', ''}, - {'TabLeave', ''}, - {'WinEnter', ''}, - {'TabNew', 'testfile1'}, -- :tabnew - {'TabEnter', ''}, - {'BufLeave', ''}, - {'BufEnter', 'testfile1'}, -- :split - {'WinLeave', 'testfile1'}, - {'WinEnter', 'testfile1'}, - {'WinLeave', 'testfile1'}, - {'WinClosed', '1002'}, -- :close, WinClosed <afile> = window-id - {'WinEnter', 'testfile1'}, - {'WinLeave', 'testfile1'}, -- :bdelete - {'WinEnter', 'testfile1'}, - {'BufLeave', 'testfile1'}, - {'BufEnter', 'testfile2'}, - {'WinClosed', '1000'}, + { 'WinLeave', '' }, + { 'TabLeave', '' }, + { 'WinEnter', '' }, + { 'TabNew', 'testfile1' }, -- :tabnew + { 'TabEnter', '' }, + { 'BufLeave', '' }, + { 'BufEnter', 'testfile1' }, -- :split + { 'WinLeave', 'testfile1' }, + { 'WinEnter', 'testfile1' }, + { 'WinLeave', 'testfile1' }, + { 'WinClosed', '1002' }, -- :close, WinClosed <afile> = window-id + { 'WinEnter', 'testfile1' }, + { 'WinLeave', 'testfile1' }, -- :bdelete + { 'WinEnter', 'testfile1' }, + { 'BufLeave', 'testfile1' }, + { 'BufEnter', 'testfile2' }, + { 'WinClosed', '1000' }, } command('let g:evs = []') command('autocmd BufEnter * :call add(g:evs, ["BufEnter", expand("<afile>")])') @@ -63,10 +62,10 @@ describe('autocmd', function() it('first edit causes BufUnload on NoName', function() local expected = { - {'BufUnload', ''}, - {'BufDelete', ''}, - {'BufWipeout', ''}, - {'BufEnter', 'testfile1'}, + { 'BufUnload', '' }, + { 'BufDelete', '' }, + { 'BufWipeout', '' }, + { 'BufEnter', 'testfile1' }, } command('let g:evs = []') command('autocmd BufEnter * :call add(g:evs, ["BufEnter", expand("<afile>")])') @@ -106,20 +105,23 @@ describe('autocmd', function() local buf1 = eval("bufnr('%')") command('new') local buf2 = eval("bufnr('%')") - command('autocmd WinClosed <buffer> :call add(g:evs, ["WinClosed", expand("<abuf>")])' - -- Attempt recursion. - ..' | bdelete '..buf2) + command( + 'autocmd WinClosed <buffer> :call add(g:evs, ["WinClosed", expand("<abuf>")])' + -- Attempt recursion. + .. ' | bdelete ' + .. buf2 + ) command('tabedit testfile2') command('tabedit testfile3') - command('bdelete '..buf2) + command('bdelete ' .. buf2) -- Non-recursive: only triggered once. eq({ - {'WinClosed', '2'}, + { 'WinClosed', '2' }, }, eval('g:evs')) - command('bdelete '..buf1) + command('bdelete ' .. buf1) eq({ - {'WinClosed', '2'}, - {'WinClosed', '1'}, + { 'WinClosed', '2' }, + { 'WinClosed', '1' }, }, eval('g:evs')) end) @@ -130,7 +132,7 @@ describe('autocmd', function() command('new') command('close') eq({ - {'WinClosed', '1001'}, + { 'WinClosed', '1001' }, }, eval('g:evs')) end) @@ -139,16 +141,15 @@ describe('autocmd', function() end) describe('BufLeave autocommand', function() - it('can wipe out the buffer created by :edit which triggered autocmd', - function() - meths.set_option_value('hidden', true, {}) - curbufmeths.set_lines(0, 1, false, { + it('can wipe out the buffer created by :edit which triggered autocmd', function() + api.nvim_set_option_value('hidden', true, {}) + api.nvim_buf_set_lines(0, 0, 1, false, { 'start of test file xx', - 'end of test file xx'}) + 'end of test file xx', + }) command('autocmd BufLeave * bwipeout yy') - eq('Vim(edit):E143: Autocommands unexpectedly deleted new buffer yy', - exc_exec('edit yy')) + eq('Vim(edit):E143: Autocommands unexpectedly deleted new buffer yy', exc_exec('edit yy')) expect([[ start of test file xx @@ -156,7 +157,7 @@ describe('autocmd', function() end) end) - it('++once', function() -- :help autocmd-once + it('++once', function() -- :help autocmd-once -- -- ":autocmd ... ++once" executes its handler once, then removes the handler. -- @@ -177,7 +178,8 @@ describe('autocmd', function() command('autocmd TabNew * ++once :call add(g:foo, "Once2")') command('autocmd TabNew * :call add(g:foo, "Many2")') command('autocmd TabNew * ++once :call add(g:foo, "Once3")') - eq(dedent([[ + eq( + dedent([[ --- Autocommands --- TabNew @@ -186,18 +188,21 @@ describe('autocmd', function() :call add(g:foo, "Once2") :call add(g:foo, "Many2") :call add(g:foo, "Once3")]]), - funcs.execute('autocmd Tabnew')) + fn.execute('autocmd Tabnew') + ) command('tabnew') command('tabnew') command('tabnew') eq(expected, eval('g:foo')) - eq(dedent([[ + eq( + dedent([[ --- Autocommands --- TabNew * :call add(g:foo, "Many1") :call add(g:foo, "Many2")]]), - funcs.execute('autocmd Tabnew')) + fn.execute('autocmd Tabnew') + ) -- -- ":autocmd ... ++once" handlers can be deleted. @@ -218,7 +223,9 @@ describe('autocmd', function() } command('let g:foo = []') command('autocmd OptionSet binary ++nested ++once :call add(g:foo, "OptionSet-Once")') - command('autocmd CursorMoved <buffer> ++once ++nested setlocal binary|:call add(g:foo, "CursorMoved-Once")') + command( + 'autocmd CursorMoved <buffer> ++once ++nested setlocal binary|:call add(g:foo, "CursorMoved-Once")' + ) command("put ='foo bar baz'") feed('0llhlh') eq(expected, eval('g:foo')) @@ -231,15 +238,17 @@ describe('autocmd', function() 'Once2', } command('let g:foo = []') - command('autocmd! TabNew') -- Clear all TabNew handlers. + command('autocmd! TabNew') -- Clear all TabNew handlers. command('autocmd TabNew * ++once :call add(g:foo, "Once1")') command('autocmd TabNew * ++once :call add(g:foo, "Once2")') command('tabnew') eq(expected, eval('g:foo')) - eq(dedent([[ + eq( + dedent([[ --- Autocommands ---]]), - funcs.execute('autocmd Tabnew')) + fn.execute('autocmd Tabnew') + ) end) it('internal `aucmd_win` window', function() @@ -250,9 +259,13 @@ describe('autocmd', function() local screen = Screen.new(50, 10) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {background = Screen.colors.LightMagenta}, - [3] = {background = Screen.colors.LightMagenta, bold = true, foreground = Screen.colors.Blue1}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { background = Screen.colors.LightMagenta }, + [3] = { + background = Screen.colors.LightMagenta, + bold = true, + foreground = Screen.colors.Blue1, + }, }) source([[ @@ -272,96 +285,67 @@ describe('autocmd', function() ]]) screen:expect([[ ^bb | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 | ]]) - feed(":enew | doautoall User<cr>") + feed(':enew | doautoall User<cr>') screen:expect([[ {2:bb }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {3:~ }|*4 + {1:~ }|*4 ^:enew | doautoall User | ]]) feed('<cr>') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 13 | ]]) eq(7, eval('g:test')) -- API calls are blocked when aucmd_win is not in scope - eq('Vim(call):E5555: API call: Invalid window id: 1001', - pcall_err(command, "call nvim_set_current_win(g:winid)")) + eq( + 'Vim(call):E5555: API call: Invalid window id: 1001', + pcall_err(command, 'call nvim_set_current_win(g:winid)') + ) -- second time aucmd_win is needed, a different code path is invoked -- to reuse the same window, so check again - command("let g:test = v:null") - command("let g:had_value = v:null") - feed(":doautoall User<cr>") + command('let g:test = v:null') + command('let g:had_value = v:null') + feed(':doautoall User<cr>') screen:expect([[ {2:bb }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {3:~ }|*4 + {1:~ }|*4 ^:doautoall User | ]]) feed('<cr>') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 13 | ]]) -- win vars in aucmd_win should have been reset eq(0, eval('g:had_value')) eq(7, eval('g:test')) - eq('Vim(call):E5555: API call: Invalid window id: 1001', - pcall_err(command, "call nvim_set_current_win(g:winid)")) + eq( + 'Vim(call):E5555: API call: Invalid window id: 1001', + pcall_err(command, 'call nvim_set_current_win(g:winid)') + ) end) - it("`aucmd_win` cannot be changed into a normal window #13699", function() + it('`aucmd_win` cannot be changed into a normal window #13699', function() local screen = Screen.new(50, 10) screen:attach() screen:set_default_attr_ids { - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {reverse = true}, - [3] = {bold = true, reverse = true}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { reverse = true }, + [3] = { bold = true, reverse = true }, } -- Create specific layout and ensure it's left unchanged. @@ -373,11 +357,7 @@ describe('autocmd', function() ]] screen:expect [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {3:[No Name] }| | {2:[No Name] }| @@ -408,13 +388,16 @@ describe('autocmd', function() -- After all of our messing around, aucmd_win should still be floating. -- Use :only to ensure _G.buf is hidden again (so the aucmd_win is used). - eq("editor", exec_lua [[ + eq( + 'editor', + exec_lua [[ vim.cmd "only" vim.api.nvim_buf_call(_G.buf, function() _G.config = vim.api.nvim_win_get_config(0) end) return _G.config.relative - ]]) + ]] + ) end) describe('closing last non-floating window in tab from `aucmd_win`', function() @@ -425,14 +408,22 @@ describe('autocmd', function() end) it('gives E814 when there are no other floating windows', function() - eq('BufAdd Autocommands for "Xa.txt": Vim(close):E814: Cannot close window, only autocmd window would remain', - pcall_err(command, 'doautoall BufAdd')) + eq( + 'BufAdd Autocommands for "Xa.txt": Vim(close):E814: Cannot close window, only autocmd window would remain', + pcall_err(command, 'doautoall BufAdd') + ) end) it('gives E814 when there are other floating windows', function() - meths.open_win(0, true, {width = 10, height = 10, relative = 'editor', row = 10, col = 10}) - eq('BufAdd Autocommands for "Xa.txt": Vim(close):E814: Cannot close window, only autocmd window would remain', - pcall_err(command, 'doautoall BufAdd')) + api.nvim_open_win( + 0, + true, + { width = 10, height = 10, relative = 'editor', row = 10, col = 10 } + ) + eq( + 'BufAdd Autocommands for "Xa.txt": Vim(close):E814: Cannot close window, only autocmd window would remain', + pcall_err(command, 'doautoall BufAdd') + ) end) end) @@ -441,84 +432,116 @@ describe('autocmd', function() vim.cmd('tabnew') _G.buf = vim.api.nvim_create_buf(true, true) ]]) - matches('Vim:E813: Cannot close autocmd window$', pcall_err(exec_lua, [[ + matches( + 'Vim:E813: Cannot close autocmd window$', + pcall_err( + exec_lua, + [[ vim.api.nvim_buf_call(_G.buf, function() local win = vim.api.nvim_get_current_win() vim.api.nvim_win_close(win, true) end) - ]])) - matches('Vim:E813: Cannot close autocmd window$', pcall_err(exec_lua, [[ + ]] + ) + ) + matches( + 'Vim:E813: Cannot close autocmd window$', + pcall_err( + exec_lua, + [[ vim.api.nvim_buf_call(_G.buf, function() local win = vim.api.nvim_get_current_win() vim.cmd('tabnext') vim.api.nvim_win_close(win, true) end) - ]])) - matches('Vim:E813: Cannot close autocmd window$', pcall_err(exec_lua, [[ + ]] + ) + ) + matches( + 'Vim:E813: Cannot close autocmd window$', + pcall_err( + exec_lua, + [[ vim.api.nvim_buf_call(_G.buf, function() local win = vim.api.nvim_get_current_win() vim.api.nvim_win_hide(win) end) - ]])) - matches('Vim:E813: Cannot close autocmd window$', pcall_err(exec_lua, [[ + ]] + ) + ) + matches( + 'Vim:E813: Cannot close autocmd window$', + pcall_err( + exec_lua, + [[ vim.api.nvim_buf_call(_G.buf, function() local win = vim.api.nvim_get_current_win() vim.cmd('tabnext') vim.api.nvim_win_hide(win) end) - ]])) + ]] + ) + ) end) it(':doautocmd does not warn "No matching autocommands" #10689', function() local screen = Screen.new(32, 3) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, }) feed(':doautocmd User Foo<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | {1:~ }| :doautocmd User Foo | - ]]} + ]], + } feed(':autocmd! SessionLoadPost<cr>') feed(':doautocmd SessionLoadPost<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | {1:~ }| :doautocmd SessionLoadPost | - ]]} + ]], + } end) describe('v:event is readonly #18063', function() it('during ChanOpen event', function() command('autocmd ChanOpen * let v:event.info.id = 0') - funcs.jobstart({'cat'}) + fn.jobstart({ 'cat' }) retry(nil, nil, function() - eq('E46: Cannot change read-only variable "v:event.info"', meths.get_vvar('errmsg')) + eq('E46: Cannot change read-only variable "v:event.info"', api.nvim_get_vvar('errmsg')) end) end) it('during ChanOpen event', function() command('autocmd ChanInfo * let v:event.info.id = 0') - meths.set_client_info('foo', {}, 'remote', {}, {}) + api.nvim_set_client_info('foo', {}, 'remote', {}, {}) retry(nil, nil, function() - eq('E46: Cannot change read-only variable "v:event.info"', meths.get_vvar('errmsg')) + eq('E46: Cannot change read-only variable "v:event.info"', api.nvim_get_vvar('errmsg')) end) end) it('during RecordingLeave event', function() command([[autocmd RecordingLeave * let v:event.regname = '']]) - eq('RecordingLeave Autocommands for "*": Vim(let):E46: Cannot change read-only variable "v:event.regname"', - pcall_err(command, 'normal! qqq')) + eq( + 'RecordingLeave Autocommands for "*": Vim(let):E46: Cannot change read-only variable "v:event.regname"', + pcall_err(command, 'normal! qqq') + ) end) it('during TermClose event', function() command('autocmd TermClose * let v:event.status = 0') command('terminal') - eq('TermClose Autocommands for "*": Vim(let):E46: Cannot change read-only variable "v:event.status"', - pcall_err(command, 'bdelete!')) + eq( + 'TermClose Autocommands for "*": Vim(let):E46: Cannot change read-only variable "v:event.status"', + pcall_err(command, 'bdelete!') + ) end) end) @@ -554,7 +577,7 @@ describe('autocmd', function() call assert_fails('au WinNew * ++once ++once echo bad', 'E983:') ]] - meths.set_var('did_split', 0) + api.nvim_set_var('did_split', 0) source [[ augroup Testing @@ -566,11 +589,11 @@ describe('autocmd', function() split ]] - eq(2, meths.get_var('did_split')) - eq(1, funcs.exists('#WinNew')) + eq(2, api.nvim_get_var('did_split')) + eq(1, fn.exists('#WinNew')) -- Now with once - meths.set_var('did_split', 0) + api.nvim_set_var('did_split', 0) source [[ augroup Testing @@ -582,13 +605,16 @@ describe('autocmd', function() split ]] - eq(1, meths.get_var('did_split')) - eq(0, funcs.exists('#WinNew')) + eq(1, api.nvim_get_var('did_split')) + eq(0, fn.exists('#WinNew')) -- call assert_fails('au WinNew * ++once ++once echo bad', 'E983:') - local ok, msg = pcall(source, [[ + local ok, msg = pcall( + source, + [[ au WinNew * ++once ++once echo bad - ]]) + ]] + ) eq(false, ok) eq(true, not not string.find(msg, 'E983:')) @@ -596,7 +622,7 @@ describe('autocmd', function() it('should have autocmds in filetypedetect group', function() source [[filetype on]] - neq({}, meths.get_autocmds { group = "filetypedetect" }) + neq({}, api.nvim_get_autocmds { group = 'filetypedetect' }) end) it('should allow comma-separated patterns', function() @@ -608,7 +634,7 @@ describe('autocmd', function() augroup END ]] - eq(4, #meths.get_autocmds { event = "BufReadCmd", group = "TestingPatterns" }) + eq(4, #api.nvim_get_autocmds { event = 'BufReadCmd', group = 'TestingPatterns' }) end) end) @@ -627,7 +653,7 @@ describe('autocmd', function() }) vim.cmd "tabnew" ]] - eq(1, eval('g:count')) -- Added autocommands should not be executed + eq(1, eval('g:count')) -- Added autocommands should not be executed end) it('no crash when clearing a group inside a callback #23355', function() diff --git a/test/functional/autocmd/bufenter_spec.lua b/test/functional/autocmd/bufenter_spec.lua index 47f4adb0d6..af0dd887fa 100644 --- a/test/functional/autocmd/bufenter_spec.lua +++ b/test/functional/autocmd/bufenter_spec.lua @@ -12,9 +12,9 @@ describe('autocmd BufEnter', function() it("triggered by nvim_command('edit <dir>')", function() command("autocmd BufEnter * if isdirectory(expand('<afile>')) | let g:dir_bufenter = 1 | endif") - request("nvim_command", "split .") - eq(1, eval("exists('g:dir_bufenter')")) -- Did BufEnter for the directory. - eq(2, eval("bufnr('%')")) -- Switched to the dir buffer. + request('nvim_command', 'split .') + eq(1, eval("exists('g:dir_bufenter')")) -- Did BufEnter for the directory. + eq(2, eval("bufnr('%')")) -- Switched to the dir buffer. end) it('triggered by "try|:split <dir>|endtry" in a function', function() @@ -27,21 +27,20 @@ describe('autocmd BufEnter', function() endtry endfunction ]]) - command("call Test()") - eq(1, eval("exists('g:dir_bufenter')")) -- Did BufEnter for the directory. - eq(2, eval("bufnr('%')")) -- Switched to the dir buffer. + command('call Test()') + eq(1, eval("exists('g:dir_bufenter')")) -- Did BufEnter for the directory. + eq(2, eval("bufnr('%')")) -- Switched to the dir buffer. end) it('triggered by ":split normal|:help|:bw"', function() helpers.add_builddir_to_rtp() - command("split normal") - command("wincmd j") - command("help") - command("wincmd L") - command("autocmd BufEnter normal let g:bufentered = 1") - command("bw") + command('split normal') + command('wincmd j') + command('help') + command('wincmd L') + command('autocmd BufEnter normal let g:bufentered = 1') + command('bw') eq(1, eval('bufnr("%")')) -- The cursor is back to the bottom window eq(0, eval("exists('g:bufentered')")) -- The autocmd hasn't been triggered end) - end) diff --git a/test/functional/autocmd/bufmodifiedset_spec.lua b/test/functional/autocmd/bufmodifiedset_spec.lua index c566361e37..27fe9fcc94 100644 --- a/test/functional/autocmd/bufmodifiedset_spec.lua +++ b/test/functional/autocmd/bufmodifiedset_spec.lua @@ -14,9 +14,9 @@ describe('BufModified', function() let g:modified = 0 autocmd BufModifiedSet * let g:modified += 1 ]]) - request("nvim_command", [[normal! aa\<Esc>]]) + request('nvim_command', [[normal! aa\<Esc>]]) eq(1, eval('g:modified')) - request("nvim_command", [[normal! u]]) + request('nvim_command', [[normal! u]]) eq(2, eval('g:modified')) end) end) diff --git a/test/functional/autocmd/cmdline_spec.lua b/test/functional/autocmd/cmdline_spec.lua index 82fb9b9444..7428456656 100644 --- a/test/functional/autocmd/cmdline_spec.lua +++ b/test/functional/autocmd/cmdline_spec.lua @@ -8,14 +8,14 @@ local expect = helpers.expect local eval = helpers.eval local next_msg = helpers.next_msg local feed = helpers.feed -local meths = helpers.meths +local api = helpers.api describe('cmdline autocommands', function() local channel before_each(function() clear() - channel = meths.get_api_info()[1] - meths.set_var("channel",channel) + channel = api.nvim_get_chan_info(0).id + api.nvim_set_var('channel', channel) command("autocmd CmdlineEnter * call rpcnotify(g:channel, 'CmdlineEnter', v:event)") command("autocmd CmdlineLeave * call rpcnotify(g:channel, 'CmdlineLeave', v:event)") command("autocmd CmdWinEnter * call rpcnotify(g:channel, 'CmdWinEnter', v:event)") @@ -24,23 +24,27 @@ describe('cmdline autocommands', function() it('works', function() feed(':') - eq({'notification', 'CmdlineEnter', {{cmdtype=':', cmdlevel=1}}}, next_msg()) + eq({ 'notification', 'CmdlineEnter', { { cmdtype = ':', cmdlevel = 1 } } }, next_msg()) feed('redraw<cr>') - eq({'notification', 'CmdlineLeave', - {{cmdtype=':', cmdlevel=1, abort=false}}}, next_msg()) + eq( + { 'notification', 'CmdlineLeave', { { cmdtype = ':', cmdlevel = 1, abort = false } } }, + next_msg() + ) feed(':') - eq({'notification', 'CmdlineEnter', {{cmdtype=':', cmdlevel=1}}}, next_msg()) + eq({ 'notification', 'CmdlineEnter', { { cmdtype = ':', cmdlevel = 1 } } }, next_msg()) -- note: feed('bork<c-c>') might not consume 'bork' -- due to out-of-band interrupt handling feed('bork<esc>') - eq({'notification', 'CmdlineLeave', - {{cmdtype=':', cmdlevel=1, abort=true}}}, next_msg()) + eq( + { 'notification', 'CmdlineLeave', { { cmdtype = ':', cmdlevel = 1, abort = true } } }, + next_msg() + ) end) it('can abort cmdline', function() - command("autocmd CmdlineLeave * let v:event.abort= len(getcmdline())>15") + command('autocmd CmdlineLeave * let v:event.abort= len(getcmdline())>15') feed(":put! ='ok'<cr>") expect([[ ok @@ -57,10 +61,10 @@ describe('cmdline autocommands', function() local screen = Screen.new(72, 8) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [3] = {bold = true, foreground = Screen.colors.SeaGreen4}, - [4] = {bold = true, reverse = true}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [3] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [4] = { bold = true, reverse = true }, }) command("autocmd CmdlineEnter * echoerr 'FAIL'") command("autocmd CmdlineLeave * echoerr 'very error'") @@ -68,9 +72,7 @@ describe('cmdline autocommands', function() feed(':') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {4: }| : | {2:CmdlineEnter Autocommands for "*": Vim(echoerr):FAIL} | @@ -94,18 +96,14 @@ describe('cmdline autocommands', function() screen:expect([[ | ^lorem ipsum | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | ]]) command("autocmd CmdlineChanged * echoerr 'change erreor'") -- history recall still works - feed(":<c-p>") + feed(':<c-p>') screen:expect([[ | lorem ipsum | @@ -117,7 +115,7 @@ describe('cmdline autocommands', function() :put ='lorem ipsum'^ | ]]) - feed("<left>") + feed('<left>') screen:expect([[ | lorem ipsum | @@ -130,7 +128,7 @@ describe('cmdline autocommands', function() ]]) -- edit still works - feed(".") + feed('.') screen:expect([[ {4: }| : | @@ -160,72 +158,104 @@ describe('cmdline autocommands', function() | lorem ipsum | ^lorem ipsum. | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]) end) it('works with nested cmdline', function() feed(':') - eq({'notification', 'CmdlineEnter', {{cmdtype=':', cmdlevel=1}}}, next_msg()) + eq({ 'notification', 'CmdlineEnter', { { cmdtype = ':', cmdlevel = 1 } } }, next_msg()) feed('<c-r>=') - eq({'notification', 'CmdlineEnter', {{cmdtype='=', cmdlevel=2}}}, next_msg()) + eq({ 'notification', 'CmdlineEnter', { { cmdtype = '=', cmdlevel = 2 } } }, next_msg()) feed('<c-f>') - eq({'notification', 'CmdWinEnter', {{}}}, next_msg()) + eq({ 'notification', 'CmdWinEnter', { {} } }, next_msg()) feed(':') - eq({'notification', 'CmdlineEnter', {{cmdtype=':', cmdlevel=3}}}, next_msg()) + eq({ 'notification', 'CmdlineEnter', { { cmdtype = ':', cmdlevel = 3 } } }, next_msg()) feed('<c-c>') - eq({'notification', 'CmdlineLeave', {{cmdtype=':', cmdlevel=3, abort=true}}}, next_msg()) + eq( + { 'notification', 'CmdlineLeave', { { cmdtype = ':', cmdlevel = 3, abort = true } } }, + next_msg() + ) feed('<c-c>') - eq({'notification', 'CmdWinLeave', {{}}}, next_msg()) + eq({ 'notification', 'CmdWinLeave', { {} } }, next_msg()) feed('1+2<cr>') - eq({'notification', 'CmdlineLeave', {{cmdtype='=', cmdlevel=2, abort=false}}}, next_msg()) + eq( + { 'notification', 'CmdlineLeave', { { cmdtype = '=', cmdlevel = 2, abort = false } } }, + next_msg() + ) end) it('no crash with recursive use of v:event #19484', function() command('autocmd CmdlineEnter * normal :') feed(':') - eq({'notification', 'CmdlineEnter', {{cmdtype=':', cmdlevel=1}}}, next_msg()) + eq({ 'notification', 'CmdlineEnter', { { cmdtype = ':', cmdlevel = 1 } } }, next_msg()) feed('<CR>') - eq({'notification', 'CmdlineLeave', {{cmdtype=':', cmdlevel=1, abort=false}}}, next_msg()) + eq( + { 'notification', 'CmdlineLeave', { { cmdtype = ':', cmdlevel = 1, abort = false } } }, + next_msg() + ) end) - it('supports CmdlineChanged' ,function() - command("autocmd CmdlineChanged * call rpcnotify(g:channel, 'CmdlineChanged', v:event, getcmdline())") + it('supports CmdlineChanged', function() + command( + "autocmd CmdlineChanged * call rpcnotify(g:channel, 'CmdlineChanged', v:event, getcmdline())" + ) feed(':') - eq({'notification', 'CmdlineEnter', {{cmdtype=':', cmdlevel=1}}}, next_msg()) + eq({ 'notification', 'CmdlineEnter', { { cmdtype = ':', cmdlevel = 1 } } }, next_msg()) feed('l') - eq({'notification', 'CmdlineChanged', {{cmdtype=':', cmdlevel=1}, "l"}}, next_msg()) + eq({ 'notification', 'CmdlineChanged', { { cmdtype = ':', cmdlevel = 1 }, 'l' } }, next_msg()) feed('e') - eq({'notification', 'CmdlineChanged', {{cmdtype=':', cmdlevel=1}, "le"}}, next_msg()) + eq({ 'notification', 'CmdlineChanged', { { cmdtype = ':', cmdlevel = 1 }, 'le' } }, next_msg()) feed('t') - eq({'notification', 'CmdlineChanged', {{cmdtype=':', cmdlevel=1}, "let"}}, next_msg()) + eq({ 'notification', 'CmdlineChanged', { { cmdtype = ':', cmdlevel = 1 }, 'let' } }, next_msg()) feed('<space>') - eq({'notification', 'CmdlineChanged', {{cmdtype=':', cmdlevel=1}, "let "}}, next_msg()) + eq( + { 'notification', 'CmdlineChanged', { { cmdtype = ':', cmdlevel = 1 }, 'let ' } }, + next_msg() + ) feed('x') - eq({'notification', 'CmdlineChanged', {{cmdtype=':', cmdlevel=1}, "let x"}}, next_msg()) + eq( + { 'notification', 'CmdlineChanged', { { cmdtype = ':', cmdlevel = 1 }, 'let x' } }, + next_msg() + ) feed('<space>') - eq({'notification', 'CmdlineChanged', {{cmdtype=':', cmdlevel=1}, "let x "}}, next_msg()) + eq( + { 'notification', 'CmdlineChanged', { { cmdtype = ':', cmdlevel = 1 }, 'let x ' } }, + next_msg() + ) feed('=') - eq({'notification', 'CmdlineChanged', {{cmdtype=':', cmdlevel=1}, "let x ="}}, next_msg()) + eq( + { 'notification', 'CmdlineChanged', { { cmdtype = ':', cmdlevel = 1 }, 'let x =' } }, + next_msg() + ) feed('<space>') - eq({'notification', 'CmdlineChanged', {{cmdtype=':', cmdlevel=1}, "let x = "}}, next_msg()) + eq( + { 'notification', 'CmdlineChanged', { { cmdtype = ':', cmdlevel = 1 }, 'let x = ' } }, + next_msg() + ) feed('<c-r>=') - eq({'notification', 'CmdlineEnter', {{cmdtype='=', cmdlevel=2}}}, next_msg()) + eq({ 'notification', 'CmdlineEnter', { { cmdtype = '=', cmdlevel = 2 } } }, next_msg()) feed('1') - eq({'notification', 'CmdlineChanged', {{cmdtype='=', cmdlevel=2}, "1"}}, next_msg()) + eq({ 'notification', 'CmdlineChanged', { { cmdtype = '=', cmdlevel = 2 }, '1' } }, next_msg()) feed('+') - eq({'notification', 'CmdlineChanged', {{cmdtype='=', cmdlevel=2}, "1+"}}, next_msg()) + eq({ 'notification', 'CmdlineChanged', { { cmdtype = '=', cmdlevel = 2 }, '1+' } }, next_msg()) feed('1') - eq({'notification', 'CmdlineChanged', {{cmdtype='=', cmdlevel=2}, "1+1"}}, next_msg()) + eq({ 'notification', 'CmdlineChanged', { { cmdtype = '=', cmdlevel = 2 }, '1+1' } }, next_msg()) feed('<cr>') - eq({'notification', 'CmdlineLeave', {{cmdtype='=', cmdlevel=2, abort=false}}}, next_msg()) - eq({'notification', 'CmdlineChanged', {{cmdtype=':', cmdlevel=1}, "let x = 2"}}, next_msg()) + eq( + { 'notification', 'CmdlineLeave', { { cmdtype = '=', cmdlevel = 2, abort = false } } }, + next_msg() + ) + eq( + { 'notification', 'CmdlineChanged', { { cmdtype = ':', cmdlevel = 1 }, 'let x = 2' } }, + next_msg() + ) feed('<cr>') - eq({'notification', 'CmdlineLeave', {{cmdtype=':', cmdlevel=1, abort=false}}}, next_msg()) + eq( + { 'notification', 'CmdlineLeave', { { cmdtype = ':', cmdlevel = 1, abort = false } } }, + next_msg() + ) eq(2, eval('x')) end) end) diff --git a/test/functional/autocmd/cursorhold_spec.lua b/test/functional/autocmd/cursorhold_spec.lua index e6bcb19682..fc2b65f53a 100644 --- a/test/functional/autocmd/cursorhold_spec.lua +++ b/test/functional/autocmd/cursorhold_spec.lua @@ -5,8 +5,8 @@ local eq = helpers.eq local feed = helpers.feed local retry = helpers.retry local exec = helpers.source -local sleep = helpers.sleep -local meths = helpers.meths +local sleep = vim.uv.sleep +local api = helpers.api before_each(clear) @@ -26,39 +26,47 @@ describe('CursorHold', function() -- if testing with small 'updatetime' fails, double its value and test again retry(10, nil, function() ut = ut * 2 - meths.set_option_value('updatetime', ut, {}) - feed('0') -- reset did_cursorhold - meths.set_var('cursorhold', 0) + api.nvim_set_option_value('updatetime', ut, {}) + feed('0') -- reset did_cursorhold + api.nvim_set_var('cursorhold', 0) sleep(ut / 4) fn() - eq(0, meths.get_var('cursorhold')) + eq(0, api.nvim_get_var('cursorhold')) sleep(ut / 2) fn() - eq(0, meths.get_var('cursorhold')) + eq(0, api.nvim_get_var('cursorhold')) sleep(ut / 2) - eq(early, meths.get_var('cursorhold')) + eq(early, api.nvim_get_var('cursorhold')) sleep(ut / 4 * 3) - eq(1, meths.get_var('cursorhold')) + eq(1, api.nvim_get_var('cursorhold')) end) end - local ignore_key = meths.replace_termcodes('<Ignore>', true, true, true) + local ignore_key = api.nvim_replace_termcodes('<Ignore>', true, true, true) test_cursorhold(function() end, 1) - test_cursorhold(function() feed('') end, 1) - test_cursorhold(function() meths.feedkeys('', 'n', true) end, 1) - test_cursorhold(function() feed('<Ignore>') end, 0) - test_cursorhold(function() meths.feedkeys(ignore_key, 'n', true) end, 0) + test_cursorhold(function() + feed('') + end, 1) + test_cursorhold(function() + api.nvim_feedkeys('', 'n', true) + end, 1) + test_cursorhold(function() + feed('<Ignore>') + end, 0) + test_cursorhold(function() + api.nvim_feedkeys(ignore_key, 'n', true) + end, 0) end) it("reducing 'updatetime' while waiting for CursorHold #20241", function() - meths.set_option_value('updatetime', 10000, {}) - feed('0') -- reset did_cursorhold - meths.set_var('cursorhold', 0) + api.nvim_set_option_value('updatetime', 10000, {}) + feed('0') -- reset did_cursorhold + api.nvim_set_var('cursorhold', 0) sleep(50) - eq(0, meths.get_var('cursorhold')) - meths.set_option_value('updatetime', 20, {}) + eq(0, api.nvim_get_var('cursorhold')) + api.nvim_set_option_value('updatetime', 20, {}) sleep(10) - eq(1, meths.get_var('cursorhold')) + eq(1, api.nvim_get_var('cursorhold')) end) end) @@ -77,7 +85,7 @@ describe('CursorHoldI', function() feed('ifoo') retry(5, nil, function() sleep(1) - eq(1, meths.get_var('cursorhold')) + eq(1, api.nvim_get_var('cursorhold')) end) end) end) diff --git a/test/functional/autocmd/cursormoved_spec.lua b/test/functional/autocmd/cursormoved_spec.lua index 854e14b088..302afe87b8 100644 --- a/test/functional/autocmd/cursormoved_spec.lua +++ b/test/functional/autocmd/cursormoved_spec.lua @@ -3,7 +3,7 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local eq = helpers.eq local eval = helpers.eval -local meths = helpers.meths +local api = helpers.api local source = helpers.source local command = helpers.command @@ -19,9 +19,9 @@ describe('CursorMoved', function() ]]) eq({}, eval('g:log')) command('new') - eq({'BufEnter2', 'CursorMoved2'}, eval('g:log')) + eq({ 'BufEnter2', 'CursorMoved2' }, eval('g:log')) command('wincmd w') - eq({'BufEnter2', 'CursorMoved2', 'BufEnter1', 'CursorMoved1'}, eval('g:log')) + eq({ 'BufEnter2', 'CursorMoved2', 'BufEnter1', 'CursorMoved1' }, eval('g:log')) end) it('is not triggered by temporarily switching window', function() @@ -41,13 +41,13 @@ describe('CursorMoved', function() vsplit foo autocmd CursorMoved * let g:cursormoved += 1 ]]) - meths.buf_set_lines(eval('g:buf'), 0, -1, true, {'aaa'}) + api.nvim_buf_set_lines(eval('g:buf'), 0, -1, true, { 'aaa' }) eq(0, eval('g:cursormoved')) - eq({'aaa'}, meths.buf_get_lines(eval('g:buf'), 0, -1, true)) + eq({ 'aaa' }, api.nvim_buf_get_lines(eval('g:buf'), 0, -1, true)) eq(0, eval('g:cursormoved')) end) - it("is not triggered by cursor movement prior to first CursorMoved instantiation", function() + it('is not triggered by cursor movement prior to first CursorMoved instantiation', function() source([[ let g:cursormoved = 0 autocmd! CursorMoved diff --git a/test/functional/autocmd/dirchanged_spec.lua b/test/functional/autocmd/dirchanged_spec.lua index 20aa07d058..7ad529891f 100644 --- a/test/functional/autocmd/dirchanged_spec.lua +++ b/test/functional/autocmd/dirchanged_spec.lua @@ -1,4 +1,3 @@ -local luv = require('luv') local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear @@ -9,7 +8,7 @@ local request = helpers.request local is_os = helpers.is_os describe('autocmd DirChanged and DirChangedPre', function() - local curdir = string.gsub(luv.cwd(), '\\', '/') + local curdir = vim.uv.cwd():gsub('\\', '/') local dirs = { curdir .. '/Xtest-functional-autocmd-dirchanged.dir1', curdir .. '/Xtest-functional-autocmd-dirchanged.dir2', @@ -21,41 +20,55 @@ describe('autocmd DirChanged and DirChangedPre', function() curdir .. '\\XTEST-FUNCTIONAL-AUTOCMD-DIRCHANGED.DIR3', } - setup(function() for _, dir in pairs(dirs) do helpers.mkdir(dir) end end) - teardown(function() for _, dir in pairs(dirs) do helpers.rmdir(dir) end end) + setup(function() + for _, dir in pairs(dirs) do + helpers.mkdir(dir) + end + end) + teardown(function() + for _, dir in pairs(dirs) do + helpers.rmdir(dir) + end + end) before_each(function() clear() - command('autocmd DirChangedPre * let [g:evpre, g:amatchpre, g:cdprecount] ' - ..'= [copy(v:event), expand("<amatch>"), 1 + get(g:, "cdprecount", 0)]') - command('autocmd DirChanged * let [g:getcwd, g:ev, g:amatch, g:cdcount] ' - ..'= [getcwd(), copy(v:event), expand("<amatch>"), 1 + get(g:, "cdcount", 0)]') + command( + 'autocmd DirChangedPre * let [g:evpre, g:amatchpre, g:cdprecount] ' + .. '= [copy(v:event), expand("<amatch>"), 1 + get(g:, "cdprecount", 0)]' + ) + command( + 'autocmd DirChanged * let [g:getcwd, g:ev, g:amatch, g:cdcount] ' + .. '= [getcwd(), copy(v:event), expand("<amatch>"), 1 + get(g:, "cdcount", 0)]' + ) -- Normalize path separators. - command([[autocmd DirChangedPre * let g:evpre['directory'] = substitute(g:evpre['directory'], '\\', '/', 'g')]]) + command( + [[autocmd DirChangedPre * let g:evpre['directory'] = substitute(g:evpre['directory'], '\\', '/', 'g')]] + ) command([[autocmd DirChanged * let g:ev['cwd'] = substitute(g:ev['cwd'], '\\', '/', 'g')]]) command([[autocmd DirChanged * let g:getcwd = substitute(g:getcwd, '\\', '/', 'g')]]) end) it('set v:event and <amatch>', function() - command('lcd '..dirs[1]) - eq({directory=dirs[1], scope='window', changed_window=false}, eval('g:evpre')) - eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev')) + command('lcd ' .. dirs[1]) + eq({ directory = dirs[1], scope = 'window', changed_window = false }, eval('g:evpre')) + eq({ cwd = dirs[1], scope = 'window', changed_window = false }, eval('g:ev')) eq('window', eval('g:amatchpre')) eq('window', eval('g:amatch')) eq(1, eval('g:cdprecount')) eq(1, eval('g:cdcount')) - command('tcd '..dirs[2]) - eq({directory=dirs[2], scope='tabpage', changed_window=false}, eval('g:evpre')) - eq({cwd=dirs[2], scope='tabpage', changed_window=false}, eval('g:ev')) + command('tcd ' .. dirs[2]) + eq({ directory = dirs[2], scope = 'tabpage', changed_window = false }, eval('g:evpre')) + eq({ cwd = dirs[2], scope = 'tabpage', changed_window = false }, eval('g:ev')) eq('tabpage', eval('g:amatchpre')) eq('tabpage', eval('g:amatch')) eq(2, eval('g:cdprecount')) eq(2, eval('g:cdcount')) - command('cd '..dirs[3]) - eq({directory=dirs[3], scope='global', changed_window=false}, eval('g:evpre')) - eq({cwd=dirs[3], scope='global', changed_window=false}, eval('g:ev')) + command('cd ' .. dirs[3]) + eq({ directory = dirs[3], scope = 'global', changed_window = false }, eval('g:evpre')) + eq({ cwd = dirs[3], scope = 'global', changed_window = false }, eval('g:ev')) eq('global', eval('g:amatchpre')) eq('global', eval('g:amatch')) eq(3, eval('g:cdprecount')) @@ -63,22 +76,22 @@ describe('autocmd DirChanged and DirChangedPre', function() end) it('DirChanged set getcwd() during event #6260', function() - command('lcd '..dirs[1]) + command('lcd ' .. dirs[1]) eq(dirs[1], eval('g:getcwd')) - command('tcd '..dirs[2]) + command('tcd ' .. dirs[2]) eq(dirs[2], eval('g:getcwd')) - command('cd '..dirs[3]) + command('cd ' .. dirs[3]) eq(dirs[3], eval('g:getcwd')) end) it('disallow recursion', function() command('set shellslash') -- Set up a _nested_ handler. - command('autocmd DirChanged * nested lcd '..dirs[3]) - command('lcd '..dirs[1]) - eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev')) + command('autocmd DirChanged * nested lcd ' .. dirs[3]) + command('lcd ' .. dirs[1]) + eq({ cwd = dirs[1], scope = 'window', changed_window = false }, eval('g:ev')) eq(1, eval('g:cdcount')) -- autocmd changed to dirs[3], but did NOT trigger another DirChanged. eq(dirs[3], eval('getcwd()')) @@ -89,27 +102,36 @@ describe('autocmd DirChanged and DirChangedPre', function() command('let g:cdcount = 0') local status1, err1 = pcall(function() - command('lcd '..dirs[1]..'/doesnotexist') + command('lcd ' .. dirs[1] .. '/doesnotexist') end) - eq({directory=dirs[1]..'/doesnotexist', scope='window', changed_window=false}, eval('g:evpre')) + eq( + { directory = dirs[1] .. '/doesnotexist', scope = 'window', changed_window = false }, + eval('g:evpre') + ) eq({}, eval('g:ev')) eq('window', eval('g:amatchpre')) eq(1, eval('g:cdprecount')) eq(0, eval('g:cdcount')) local status2, err2 = pcall(function() - command('lcd '..dirs[2]..'/doesnotexist') + command('lcd ' .. dirs[2] .. '/doesnotexist') end) - eq({directory=dirs[2]..'/doesnotexist', scope='window', changed_window=false}, eval('g:evpre')) + eq( + { directory = dirs[2] .. '/doesnotexist', scope = 'window', changed_window = false }, + eval('g:evpre') + ) eq({}, eval('g:ev')) eq('window', eval('g:amatchpre')) eq(2, eval('g:cdprecount')) eq(0, eval('g:cdcount')) local status3, err3 = pcall(function() - command('lcd '..dirs[3]..'/doesnotexist') + command('lcd ' .. dirs[3] .. '/doesnotexist') end) - eq({directory=dirs[3]..'/doesnotexist', scope='window', changed_window=false}, eval('g:evpre')) + eq( + { directory = dirs[3] .. '/doesnotexist', scope = 'window', changed_window = false }, + eval('g:evpre') + ) eq({}, eval('g:ev')) eq('window', eval('g:amatchpre')) eq(3, eval('g:cdprecount')) @@ -119,93 +141,93 @@ describe('autocmd DirChanged and DirChangedPre', function() eq(false, status2) eq(false, status3) - eq('E344:', string.match(err1, "E%d*:")) - eq('E344:', string.match(err2, "E%d*:")) - eq('E344:', string.match(err3, "E%d*:")) + eq('E344:', string.match(err1, 'E%d*:')) + eq('E344:', string.match(err2, 'E%d*:')) + eq('E344:', string.match(err3, 'E%d*:')) end) it("are triggered by 'autochdir'", function() command('set autochdir') - command('split '..dirs[1]..'/foo') - eq({directory=dirs[1], scope='window', changed_window=false}, eval('g:evpre')) - eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev')) + command('split ' .. dirs[1] .. '/foo') + eq({ directory = dirs[1], scope = 'window', changed_window = false }, eval('g:evpre')) + eq({ cwd = dirs[1], scope = 'window', changed_window = false }, eval('g:ev')) eq('auto', eval('g:amatchpre')) eq('auto', eval('g:amatch')) eq(1, eval('g:cdprecount')) eq(1, eval('g:cdcount')) - command('split '..dirs[2]..'/bar') - eq({directory=dirs[2], scope='window', changed_window=false}, eval('g:evpre')) - eq({cwd=dirs[2], scope='window', changed_window=false}, eval('g:ev')) + command('split ' .. dirs[2] .. '/bar') + eq({ directory = dirs[2], scope = 'window', changed_window = false }, eval('g:evpre')) + eq({ cwd = dirs[2], scope = 'window', changed_window = false }, eval('g:ev')) eq('auto', eval('g:amatch')) eq(2, eval('g:cdprecount')) eq(2, eval('g:cdcount')) end) it('do not trigger if directory has not changed', function() - command('lcd '..dirs[1]) - eq({directory=dirs[1], scope='window', changed_window=false}, eval('g:evpre')) - eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev')) + command('lcd ' .. dirs[1]) + eq({ directory = dirs[1], scope = 'window', changed_window = false }, eval('g:evpre')) + eq({ cwd = dirs[1], scope = 'window', changed_window = false }, eval('g:ev')) eq('window', eval('g:amatchpre')) eq('window', eval('g:amatch')) eq(1, eval('g:cdprecount')) eq(1, eval('g:cdcount')) command('let g:evpre = {}') command('let g:ev = {}') - command('lcd '..dirs[1]) + command('lcd ' .. dirs[1]) eq({}, eval('g:evpre')) eq({}, eval('g:ev')) eq(1, eval('g:cdprecount')) eq(1, eval('g:cdcount')) if is_os('win') then - command('lcd '..win_dirs[1]) + command('lcd ' .. win_dirs[1]) eq({}, eval('g:evpre')) eq({}, eval('g:ev')) eq(1, eval('g:cdprecount')) eq(1, eval('g:cdcount')) end - command('tcd '..dirs[2]) - eq({directory=dirs[2], scope='tabpage', changed_window=false}, eval('g:evpre')) - eq({cwd=dirs[2], scope='tabpage', changed_window=false}, eval('g:ev')) + command('tcd ' .. dirs[2]) + eq({ directory = dirs[2], scope = 'tabpage', changed_window = false }, eval('g:evpre')) + eq({ cwd = dirs[2], scope = 'tabpage', changed_window = false }, eval('g:ev')) eq('tabpage', eval('g:amatchpre')) eq('tabpage', eval('g:amatch')) eq(2, eval('g:cdprecount')) eq(2, eval('g:cdcount')) command('let g:evpre = {}') command('let g:ev = {}') - command('tcd '..dirs[2]) + command('tcd ' .. dirs[2]) eq({}, eval('g:evpre')) eq({}, eval('g:ev')) eq(2, eval('g:cdprecount')) eq(2, eval('g:cdcount')) if is_os('win') then - command('tcd '..win_dirs[2]) + command('tcd ' .. win_dirs[2]) eq({}, eval('g:evpre')) eq({}, eval('g:ev')) eq(2, eval('g:cdprecount')) eq(2, eval('g:cdcount')) end - command('cd '..dirs[3]) - eq({directory=dirs[3], scope='global', changed_window=false}, eval('g:evpre')) - eq({cwd=dirs[3], scope='global', changed_window=false}, eval('g:ev')) + command('cd ' .. dirs[3]) + eq({ directory = dirs[3], scope = 'global', changed_window = false }, eval('g:evpre')) + eq({ cwd = dirs[3], scope = 'global', changed_window = false }, eval('g:ev')) eq('global', eval('g:amatch')) eq(3, eval('g:cdprecount')) eq(3, eval('g:cdcount')) command('let g:evpre = {}') command('let g:ev = {}') - command('cd '..dirs[3]) + command('cd ' .. dirs[3]) eq({}, eval('g:evpre')) eq({}, eval('g:ev')) eq(3, eval('g:cdprecount')) eq(3, eval('g:cdcount')) if is_os('win') then - command('cd '..win_dirs[3]) + command('cd ' .. win_dirs[3]) eq({}, eval('g:evpre')) eq({}, eval('g:ev')) eq(3, eval('g:cdprecount')) @@ -214,23 +236,23 @@ describe('autocmd DirChanged and DirChangedPre', function() command('set autochdir') - command('split '..dirs[1]..'/foo') - eq({directory=dirs[1], scope='window', changed_window=false}, eval('g:evpre')) - eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev')) + command('split ' .. dirs[1] .. '/foo') + eq({ directory = dirs[1], scope = 'window', changed_window = false }, eval('g:evpre')) + eq({ cwd = dirs[1], scope = 'window', changed_window = false }, eval('g:ev')) eq('auto', eval('g:amatchpre')) eq('auto', eval('g:amatch')) eq(4, eval('g:cdprecount')) eq(4, eval('g:cdcount')) command('let g:evpre = {}') command('let g:ev = {}') - command('split '..dirs[1]..'/bar') + command('split ' .. dirs[1] .. '/bar') eq({}, eval('g:evpre')) eq({}, eval('g:ev')) eq(4, eval('g:cdprecount')) eq(4, eval('g:cdcount')) if is_os('win') then - command('split '..win_dirs[1]..'/baz') + command('split ' .. win_dirs[1] .. '/baz') eq({}, eval('g:evpre')) eq({}, eval('g:ev')) eq(4, eval('g:cdprecount')) @@ -238,93 +260,93 @@ describe('autocmd DirChanged and DirChangedPre', function() end end) - it("are triggered by switching to win/tab with different CWD #6054", function() - command('lcd '..dirs[3]) -- window 3 - command('split '..dirs[2]..'/foo') -- window 2 - command('lcd '..dirs[2]) - command('split '..dirs[1]..'/bar') -- window 1 - command('lcd '..dirs[1]) + it('are triggered by switching to win/tab with different CWD #6054', function() + command('lcd ' .. dirs[3]) -- window 3 + command('split ' .. dirs[2] .. '/foo') -- window 2 + command('lcd ' .. dirs[2]) + command('split ' .. dirs[1] .. '/bar') -- window 1 + command('lcd ' .. dirs[1]) - command('2wincmd w') -- window 2 - eq({directory=dirs[2], scope='window', changed_window=true}, eval('g:evpre')) - eq({cwd=dirs[2], scope='window', changed_window=true}, eval('g:ev')) + command('2wincmd w') -- window 2 + eq({ directory = dirs[2], scope = 'window', changed_window = true }, eval('g:evpre')) + eq({ cwd = dirs[2], scope = 'window', changed_window = true }, eval('g:ev')) eq('window', eval('g:amatchpre')) eq('window', eval('g:amatch')) eq(4, eval('g:cdprecount')) eq(4, eval('g:cdcount')) - command('tabnew') -- tab 2 (tab-local CWD) - eq(4, eval('g:cdprecount')) -- same CWD, no DirChangedPre event - eq(4, eval('g:cdcount')) -- same CWD, no DirChanged event - command('tcd '..dirs[3]) - command('tabnext') -- tab 1 (no tab-local CWD) - eq({directory=dirs[2], scope='window', changed_window=true}, eval('g:evpre')) - eq({cwd=dirs[2], scope='window', changed_window=true}, eval('g:ev')) + command('tabnew') -- tab 2 (tab-local CWD) + eq(4, eval('g:cdprecount')) -- same CWD, no DirChangedPre event + eq(4, eval('g:cdcount')) -- same CWD, no DirChanged event + command('tcd ' .. dirs[3]) + command('tabnext') -- tab 1 (no tab-local CWD) + eq({ directory = dirs[2], scope = 'window', changed_window = true }, eval('g:evpre')) + eq({ cwd = dirs[2], scope = 'window', changed_window = true }, eval('g:ev')) eq('window', eval('g:amatchpre')) eq('window', eval('g:amatch')) - command('tabnext') -- tab 2 - eq({directory=dirs[3], scope='tabpage', changed_window=true}, eval('g:evpre')) - eq({cwd=dirs[3], scope='tabpage', changed_window=true}, eval('g:ev')) + command('tabnext') -- tab 2 + eq({ directory = dirs[3], scope = 'tabpage', changed_window = true }, eval('g:evpre')) + eq({ cwd = dirs[3], scope = 'tabpage', changed_window = true }, eval('g:ev')) eq('tabpage', eval('g:amatchpre')) eq('tabpage', eval('g:amatch')) eq(7, eval('g:cdprecount')) eq(7, eval('g:cdcount')) - command('tabnext') -- tab 1 - command('3wincmd w') -- window 3 + command('tabnext') -- tab 1 + command('3wincmd w') -- window 3 eq(9, eval('g:cdprecount')) eq(9, eval('g:cdcount')) - command('tabnext') -- tab 2 (has the *same* CWD) - eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event - eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event + command('tabnext') -- tab 2 (has the *same* CWD) + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event + eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event if is_os('win') then - command('tabnew') -- tab 3 - eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event - eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event - command('tcd '..win_dirs[3]) - eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event - eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event - command('tabnext') -- tab 1 - eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event - eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event - command('tabprevious') -- tab 3 - eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event - eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event - command('tabprevious') -- tab 2 - eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event - eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event - command('tabprevious') -- tab 1 - eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event - eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event - command('lcd '..win_dirs[3]) -- window 3 - eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event - eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event - command('tabnext') -- tab 2 - eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event - eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event - command('tabnext') -- tab 3 - eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event - eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event - command('tabnext') -- tab 1 - eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event - eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event - command('tabprevious') -- tab 3 - eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event - eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event + command('tabnew') -- tab 3 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event + eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event + command('tcd ' .. win_dirs[3]) + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event + eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event + command('tabnext') -- tab 1 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event + eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event + command('tabprevious') -- tab 3 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event + eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event + command('tabprevious') -- tab 2 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event + eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event + command('tabprevious') -- tab 1 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event + eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event + command('lcd ' .. win_dirs[3]) -- window 3 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event + eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event + command('tabnext') -- tab 2 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event + eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event + command('tabnext') -- tab 3 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event + eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event + command('tabnext') -- tab 1 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event + eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event + command('tabprevious') -- tab 3 + eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event + eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event end end) it('are triggered by nvim_set_current_dir()', function() request('nvim_set_current_dir', dirs[1]) - eq({directory=dirs[1], scope='global', changed_window=false}, eval('g:evpre')) - eq({cwd=dirs[1], scope='global', changed_window=false}, eval('g:ev')) + eq({ directory = dirs[1], scope = 'global', changed_window = false }, eval('g:evpre')) + eq({ cwd = dirs[1], scope = 'global', changed_window = false }, eval('g:ev')) eq(1, eval('g:cdprecount')) eq(1, eval('g:cdcount')) request('nvim_set_current_dir', dirs[2]) - eq({directory=dirs[2], scope='global', changed_window=false}, eval('g:evpre')) - eq({cwd=dirs[2], scope='global', changed_window=false}, eval('g:ev')) + eq({ directory = dirs[2], scope = 'global', changed_window = false }, eval('g:evpre')) + eq({ cwd = dirs[2], scope = 'global', changed_window = false }, eval('g:ev')) eq(2, eval('g:cdprecount')) eq(2, eval('g:cdcount')) @@ -333,7 +355,7 @@ describe('autocmd DirChanged and DirChangedPre', function() end) eq(false, status) eq('Failed to change directory', string.match(err, ': (.*)')) - eq({directory='/doesnotexist', scope='global', changed_window=false}, eval('g:evpre')) + eq({ directory = '/doesnotexist', scope = 'global', changed_window = false }, eval('g:evpre')) eq(3, eval('g:cdprecount')) eq(2, eval('g:cdcount')) end) @@ -343,7 +365,7 @@ describe('autocmd DirChanged and DirChangedPre', function() command('let g:triggered = 0') command('autocmd DirChangedPre <buffer> let g:triggeredpre = 1') command('autocmd DirChanged <buffer> let g:triggered = 1') - command('cd '..dirs[1]) + command('cd ' .. dirs[1]) eq(1, eval('g:triggeredpre')) eq(1, eval('g:triggered')) end) diff --git a/test/functional/autocmd/filetype_spec.lua b/test/functional/autocmd/filetype_spec.lua index a571f6ee3b..648f830f27 100644 --- a/test/functional/autocmd/filetype_spec.lua +++ b/test/functional/autocmd/filetype_spec.lua @@ -5,13 +5,13 @@ local clear = helpers.clear local command = helpers.command describe('autocmd FileType', function() - before_each(clear) + before_each(clear) - it("is triggered by :help only once", function() - helpers.add_builddir_to_rtp() - command("let g:foo = 0") - command("autocmd FileType help let g:foo = g:foo + 1") - command("help help") - assert.same(1, eval('g:foo')) - end) + it('is triggered by :help only once', function() + helpers.add_builddir_to_rtp() + command('let g:foo = 0') + command('autocmd FileType help let g:foo = g:foo + 1') + command('help help') + assert.same(1, eval('g:foo')) + end) end) diff --git a/test/functional/autocmd/focus_spec.lua b/test/functional/autocmd/focus_spec.lua index 33e4d88c7b..4f4a036ba8 100644 --- a/test/functional/autocmd/focus_spec.lua +++ b/test/functional/autocmd/focus_spec.lua @@ -1,12 +1,12 @@ local helpers = require('test.functional.helpers')(after_each) local thelpers = require('test.functional.terminal.helpers') -local luv = require('luv') local clear = helpers.clear -local nvim_prog = helpers.nvim_prog local feed_command = helpers.feed_command local feed_data = thelpers.feed_data -if helpers.skip(helpers.is_os('win')) then return end +if helpers.skip(helpers.is_os('win')) then + return +end describe('autoread TUI FocusGained/FocusLost', function() local f1 = 'xtest-foo' @@ -14,8 +14,16 @@ describe('autoread TUI FocusGained/FocusLost', function() before_each(function() clear() - screen = thelpers.screen_setup(0, '["'..nvim_prog - ..'", "-u", "NONE", "-i", "NONE", "--cmd", "set noswapfile noshowcmd noruler"]') + screen = thelpers.setup_child_nvim({ + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + 'colorscheme vim', + '--cmd', + 'set noswapfile noshowcmd noruler notermguicolors', + }) end) teardown(function() @@ -33,51 +41,54 @@ describe('autoread TUI FocusGained/FocusLost', function() helpers.write_file(path, '') local atime = os.time() - 10 - luv.fs_utime(path, atime, atime) + vim.uv.fs_utime(path, atime, atime) - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| | {3:-- TERMINAL --} | - ]]} - feed_command('edit '..path) - screen:expect{grid=[[ + ]], + } + feed_command('edit ' .. path) + screen:expect { + grid = [[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:xtest-foo }| :edit xtest-foo | {3:-- TERMINAL --} | - ]]} + ]], + } feed_data('\027[O') feed_data('\027[O') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:xtest-foo }| :edit xtest-foo | {3:-- TERMINAL --} | - ]], unchanged=true} + ]], + unchanged = true, + } helpers.write_file(path, expected_addition) feed_data('\027[I') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:l}ine 1 | line 2 | line 3 | line 4 | {5:xtest-foo }| - "xtest-foo" 4L, 28B | + :edit xtest-foo | {3:-- TERMINAL --} | - ]]} + ]], + } end) end) diff --git a/test/functional/autocmd/modechanged_spec.lua b/test/functional/autocmd/modechanged_spec.lua index 69a722a0e9..8ad914a597 100644 --- a/test/functional/autocmd/modechanged_spec.lua +++ b/test/functional/autocmd/modechanged_spec.lua @@ -17,15 +17,15 @@ describe('ModeChanged', function() feed('i') eq({ old_mode = 'nt', - new_mode = 't' + new_mode = 't', }, eval('g:event')) feed('<c-\\><c-n>') eq({ old_mode = 't', - new_mode = 'nt' + new_mode = 'nt', }, eval('g:event')) eq(3, eval('g:count')) - command("bd!") + command('bd!') -- v:event is cleared after the autocommand is done eq({}, eval('v:event')) diff --git a/test/functional/autocmd/safestate_spec.lua b/test/functional/autocmd/safestate_spec.lua index 73693749e4..b5b7ab2f95 100644 --- a/test/functional/autocmd/safestate_spec.lua +++ b/test/functional/autocmd/safestate_spec.lua @@ -3,7 +3,7 @@ local clear = helpers.clear local eq = helpers.eq local exec = helpers.exec local feed = helpers.feed -local meths = helpers.meths +local api = helpers.api before_each(clear) @@ -18,40 +18,40 @@ describe('SafeState autocommand', function() it('with pending operator', function() feed('d') create_autocmd() - eq(0, meths.get_var('safe')) + eq(0, api.nvim_get_var('safe')) feed('d') - eq(1, meths.get_var('safe')) + eq(1, api.nvim_get_var('safe')) end) it('with specified register', function() feed('"r') create_autocmd() - eq(0, meths.get_var('safe')) + eq(0, api.nvim_get_var('safe')) feed('x') - eq(1, meths.get_var('safe')) + eq(1, api.nvim_get_var('safe')) end) it('with i_CTRL-O', function() feed('i<C-O>') create_autocmd() - eq(0, meths.get_var('safe')) + eq(0, api.nvim_get_var('safe')) feed('x') - eq(1, meths.get_var('safe')) + eq(1, api.nvim_get_var('safe')) end) it('with Insert mode completion', function() feed('i<C-X><C-V>') create_autocmd() - eq(0, meths.get_var('safe')) + eq(0, api.nvim_get_var('safe')) feed('<C-X><C-Z>') - eq(1, meths.get_var('safe')) + eq(1, api.nvim_get_var('safe')) end) it('with Cmdline completion', function() feed(':<Tab>') create_autocmd() - eq(0, meths.get_var('safe')) + eq(0, api.nvim_get_var('safe')) feed('<C-E>') - eq(1, meths.get_var('safe')) + eq(1, api.nvim_get_var('safe')) end) end) diff --git a/test/functional/autocmd/searchwrapped_spec.lua b/test/functional/autocmd/searchwrapped_spec.lua index 46c2c99b3d..0705b2d5de 100644 --- a/test/functional/autocmd/searchwrapped_spec.lua +++ b/test/functional/autocmd/searchwrapped_spec.lua @@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local command = helpers.command -local curbufmeths = helpers.curbufmeths +local api = helpers.api local eq = helpers.eq local eval = helpers.eval local feed = helpers.feed @@ -13,9 +13,10 @@ describe('autocmd SearchWrapped', function() command('set ignorecase') command('let g:test = 0') command('autocmd! SearchWrapped * let g:test += 1') - curbufmeths.set_lines(0, 1, false, { + api.nvim_buf_set_lines(0, 0, 1, false, { 'The quick brown fox', - 'jumps over the lazy dog'}) + 'jumps over the lazy dog', + }) end) it('gets triggered when search wraps the end', function() diff --git a/test/functional/autocmd/show_spec.lua b/test/functional/autocmd/show_spec.lua index 9e0a5b819a..1a9dc8a337 100644 --- a/test/functional/autocmd/show_spec.lua +++ b/test/functional/autocmd/show_spec.lua @@ -5,29 +5,30 @@ local clear = helpers.clear local command = helpers.command local dedent = helpers.dedent local eq = helpers.eq -local funcs = helpers.funcs +local fn = helpers.fn local eval = helpers.eval local exec = helpers.exec local feed = helpers.feed -describe(":autocmd", function() +describe(':autocmd', function() before_each(function() - clear({'-u', 'NONE'}) + clear({ '-u', 'NONE' }) end) - it("should not segfault when you just do autocmd", function() - command ":autocmd" + it('should not segfault when you just do autocmd', function() + command ':autocmd' end) - it("should filter based on ++once", function() - command "autocmd! BufEnter" + it('should filter based on ++once', function() + command 'autocmd! BufEnter' command "autocmd BufEnter * :echo 'Hello'" command [[augroup TestingOne]] command [[ autocmd BufEnter * :echo "Line 1"]] command [[ autocmd BufEnter * :echo "Line 2"]] command [[augroup END]] - eq(dedent([[ + eq( + dedent([[ --- Autocommands --- BufEnter @@ -35,15 +36,16 @@ describe(":autocmd", function() TestingOne BufEnter * :echo "Line 1" :echo "Line 2"]]), - funcs.execute('autocmd BufEnter')) + fn.execute('autocmd BufEnter') + ) end) it('should not show group information if interrupted', function() local screen = Screen.new(50, 6) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, -- NonText - [2] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg - [3] = {bold = true, foreground = Screen.colors.Magenta}, -- Title + [1] = { bold = true, foreground = Screen.colors.Blue1 }, -- NonText + [2] = { bold = true, foreground = Screen.colors.SeaGreen }, -- MoreMsg + [3] = { bold = true, foreground = Screen.colors.Magenta }, -- Title }) screen:attach() exec([[ @@ -79,10 +81,7 @@ describe(":autocmd", function() feed('q') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]) end) @@ -112,7 +111,8 @@ describe(":autocmd", function() autocmd User foo call Func() doautocmd User foo ]]) - eq(dedent([[ + eq( + dedent([[ --- Autocommands --- test_1 BufEnter @@ -122,7 +122,9 @@ describe(":autocmd", function() test_3 BufEnter D echo 'D' E echo 'E' - F echo 'F']]), eval('g:output')) + F echo 'F']]), + eval('g:output') + ) end) it('can filter by pattern #17973', function() @@ -148,7 +150,8 @@ describe(":autocmd", function() autocmd User B echo "B3" augroup END ]]) - eq(dedent([[ + eq( + dedent([[ --- Autocommands --- test_1 User @@ -156,8 +159,11 @@ describe(":autocmd", function() test_2 User A echo "A2" test_3 User - A echo "A3"]]), funcs.execute('autocmd User A')) - eq(dedent([[ + A echo "A3"]]), + fn.execute('autocmd User A') + ) + eq( + dedent([[ --- Autocommands --- test_1 BufEnter @@ -171,14 +177,19 @@ describe(":autocmd", function() test_2 User B echo "B2" test_3 User - B echo "B3"]]), funcs.execute('autocmd * B')) - eq(dedent([[ + B echo "B3"]]), + fn.execute('autocmd * B') + ) + eq( + dedent([[ --- Autocommands --- test_3 BufEnter B echo "B3" test_3 User - B echo "B3"]]), funcs.execute('autocmd test_3 * B')) + B echo "B3"]]), + fn.execute('autocmd test_3 * B') + ) end) it('should skip consecutive patterns', function() @@ -203,7 +214,8 @@ describe(":autocmd", function() let g:output = execute('autocmd BufEnter') ]]) - eq(dedent([[ + eq( + dedent([[ --- Autocommands --- test_1 BufEnter @@ -219,6 +231,8 @@ describe(":autocmd", function() echo 'C' D echo 'D' echo 'E' - echo 'F']]), eval('g:output')) + echo 'F']]), + eval('g:output') + ) end) end) diff --git a/test/functional/autocmd/signal_spec.lua b/test/functional/autocmd/signal_spec.lua index 738064090a..c7087254e7 100644 --- a/test/functional/autocmd/signal_spec.lua +++ b/test/functional/autocmd/signal_spec.lua @@ -3,15 +3,17 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local command = helpers.command local eq = helpers.eq -local funcs = helpers.funcs +local fn = helpers.fn local next_msg = helpers.next_msg local is_os = helpers.is_os local skip = helpers.skip -if skip(is_os('win'), 'Only applies to POSIX systems') then return end +if skip(is_os('win'), 'Only applies to POSIX systems') then + return +end local function posix_kill(signame, pid) - os.execute('kill -s '..signame..' -- '..pid..' >/dev/null') + os.execute('kill -s ' .. signame .. ' -- ' .. pid .. ' >/dev/null') end describe('autocmd Signal', function() @@ -19,25 +21,25 @@ describe('autocmd Signal', function() it('matches *', function() command('autocmd Signal * call rpcnotify(1, "foo")') - posix_kill('USR1', funcs.getpid()) - eq({'notification', 'foo', {}}, next_msg()) + posix_kill('USR1', fn.getpid()) + eq({ 'notification', 'foo', {} }, next_msg()) end) it('matches SIGUSR1', function() command('autocmd Signal SIGUSR1 call rpcnotify(1, "foo")') - posix_kill('USR1', funcs.getpid()) - eq({'notification', 'foo', {}}, next_msg()) + posix_kill('USR1', fn.getpid()) + eq({ 'notification', 'foo', {} }, next_msg()) end) it('matches SIGWINCH', function() command('autocmd Signal SIGWINCH call rpcnotify(1, "foo")') - posix_kill('WINCH', funcs.getpid()) - eq({'notification', 'foo', {}}, next_msg()) + posix_kill('WINCH', fn.getpid()) + eq({ 'notification', 'foo', {} }, next_msg()) end) it('does not match unknown patterns', function() command('autocmd Signal SIGUSR2 call rpcnotify(1, "foo")') - posix_kill('USR1', funcs.getpid()) + posix_kill('USR1', fn.getpid()) eq(nil, next_msg(500)) end) end) diff --git a/test/functional/autocmd/tabclose_spec.lua b/test/functional/autocmd/tabclose_spec.lua index 92d860c628..d0b2ac6a8d 100644 --- a/test/functional/autocmd/tabclose_spec.lua +++ b/test/functional/autocmd/tabclose_spec.lua @@ -1,5 +1,7 @@ local helpers = require('test.functional.helpers')(after_each) -local clear, nvim, eq = helpers.clear, helpers.nvim, helpers.eq +local clear, eq = helpers.clear, helpers.eq +local api = helpers.api +local command = helpers.command describe('TabClosed', function() before_each(clear) @@ -7,62 +9,71 @@ describe('TabClosed', function() describe('au TabClosed', function() describe('with * as <afile>', function() it('matches when closing any tab', function() - nvim('command', 'au! TabClosed * echom "tabclosed:".expand("<afile>").":".expand("<amatch>").":".tabpagenr()') + command( + 'au! TabClosed * echom "tabclosed:".expand("<afile>").":".expand("<amatch>").":".tabpagenr()' + ) repeat - nvim('command', 'tabnew') - until nvim('eval', 'tabpagenr()') == 6 -- current tab is now 6 - eq("tabclosed:6:6:5", nvim('exec', 'tabclose', true)) -- close last 6, current tab is now 5 - eq("tabclosed:5:5:4", nvim('exec', 'close', true)) -- close last window on tab, closes tab - eq("tabclosed:2:2:3", nvim('exec', '2tabclose', true)) -- close tab 2, current tab is now 3 - eq("tabclosed:1:1:2\ntabclosed:1:1:1", nvim('exec', 'tabonly', true)) -- close tabs 1 and 2 + command('tabnew') + until api.nvim_eval('tabpagenr()') == 6 -- current tab is now 6 + eq('tabclosed:6:6:5', api.nvim_exec('tabclose', true)) -- close last 6, current tab is now 5 + eq('tabclosed:5:5:4', api.nvim_exec('close', true)) -- close last window on tab, closes tab + eq('tabclosed:2:2:3', api.nvim_exec('2tabclose', true)) -- close tab 2, current tab is now 3 + eq('tabclosed:1:1:2\ntabclosed:1:1:1', api.nvim_exec('tabonly', true)) -- close tabs 1 and 2 end) it('is triggered when closing a window via bdelete from another tab', function() - nvim('command', 'au! TabClosed * echom "tabclosed:".expand("<afile>").":".expand("<amatch>").":".tabpagenr()') - nvim('command', '1tabedit Xtestfile') - nvim('command', '1tabedit Xtestfile') - nvim('command', 'normal! 1gt') - eq({1, 3}, nvim('eval', '[tabpagenr(), tabpagenr("$")]')) - eq("tabclosed:2:2:1\ntabclosed:2:2:1", nvim('exec', 'bdelete Xtestfile', true)) - eq({1, 1}, nvim('eval', '[tabpagenr(), tabpagenr("$")]')) + command( + 'au! TabClosed * echom "tabclosed:".expand("<afile>").":".expand("<amatch>").":".tabpagenr()' + ) + command('1tabedit Xtestfile') + command('1tabedit Xtestfile') + command('normal! 1gt') + eq({ 1, 3 }, api.nvim_eval('[tabpagenr(), tabpagenr("$")]')) + eq('tabclosed:2:2:1\ntabclosed:2:2:1', api.nvim_exec('bdelete Xtestfile', true)) + eq({ 1, 1 }, api.nvim_eval('[tabpagenr(), tabpagenr("$")]')) end) it('is triggered when closing a window via bdelete from current tab', function() - nvim('command', 'au! TabClosed * echom "tabclosed:".expand("<afile>").":".expand("<amatch>").":".tabpagenr()') - nvim('command', 'file Xtestfile1') - nvim('command', '1tabedit Xtestfile2') - nvim('command', '1tabedit Xtestfile2') + command( + 'au! TabClosed * echom "tabclosed:".expand("<afile>").":".expand("<amatch>").":".tabpagenr()' + ) + command('file Xtestfile1') + command('1tabedit Xtestfile2') + command('1tabedit Xtestfile2') -- Only one tab is closed, and the alternate file is used for the other. - eq({2, 3}, nvim('eval', '[tabpagenr(), tabpagenr("$")]')) - eq("tabclosed:2:2:2", nvim('exec', 'bdelete Xtestfile2', true)) - eq('Xtestfile1', nvim('eval', 'bufname("")')) + eq({ 2, 3 }, api.nvim_eval('[tabpagenr(), tabpagenr("$")]')) + eq('tabclosed:2:2:2', api.nvim_exec('bdelete Xtestfile2', true)) + eq('Xtestfile1', api.nvim_eval('bufname("")')) end) end) describe('with NR as <afile>', function() it('matches when closing a tab whose index is NR', function() - nvim('command', 'au! TabClosed * echom "tabclosed:".expand("<afile>").":".expand("<amatch>").":".tabpagenr()') - nvim('command', 'au! TabClosed 2 echom "tabclosed:match"') + command( + 'au! TabClosed * echom "tabclosed:".expand("<afile>").":".expand("<amatch>").":".tabpagenr()' + ) + command('au! TabClosed 2 echom "tabclosed:match"') repeat - nvim('command', 'tabnew') - until nvim('eval', 'tabpagenr()') == 7 -- current tab is now 7 + command('tabnew') + until api.nvim_eval('tabpagenr()') == 7 -- current tab is now 7 -- sanity check, we shouldn't match on tabs with numbers other than 2 - eq("tabclosed:7:7:6", nvim('exec', 'tabclose', true)) + eq('tabclosed:7:7:6', api.nvim_exec('tabclose', true)) -- close tab page 2, current tab is now 5 - eq("tabclosed:2:2:5\ntabclosed:match", nvim('exec', '2tabclose', true)) + eq('tabclosed:2:2:5\ntabclosed:match', api.nvim_exec('2tabclose', true)) end) end) describe('with close', function() it('is triggered', function() - nvim('command', 'au! TabClosed * echom "tabclosed:".expand("<afile>").":".expand("<amatch>").":".tabpagenr()') - nvim('command', 'tabedit Xtestfile') - eq({2, 2}, nvim('eval', '[tabpagenr(), tabpagenr("$")]')) - eq("tabclosed:2:2:1", nvim('exec', 'close', true)) - eq({1, 1}, nvim('eval', '[tabpagenr(), tabpagenr("$")]')) + command( + 'au! TabClosed * echom "tabclosed:".expand("<afile>").":".expand("<amatch>").":".tabpagenr()' + ) + command('tabedit Xtestfile') + eq({ 2, 2 }, api.nvim_eval('[tabpagenr(), tabpagenr("$")]')) + eq('tabclosed:2:2:1', api.nvim_exec('close', true)) + eq({ 1, 1 }, api.nvim_eval('[tabpagenr(), tabpagenr("$")]')) end) end) end) end) - diff --git a/test/functional/autocmd/tabnewentered_spec.lua b/test/functional/autocmd/tabnewentered_spec.lua index 6e167dd55c..b888845e3b 100644 --- a/test/functional/autocmd/tabnewentered_spec.lua +++ b/test/functional/autocmd/tabnewentered_spec.lua @@ -6,7 +6,7 @@ local dedent = helpers.dedent local eval = helpers.eval local eq = helpers.eq local feed = helpers.feed -local nvim = helpers.nvim +local api = helpers.api local exec_capture = helpers.exec_capture describe('TabNewEntered', function() @@ -14,33 +14,33 @@ describe('TabNewEntered', function() describe('with * as <afile>', function() it('matches when entering any new tab', function() clear() - nvim('command', 'au! TabNewEntered * echom "tabnewentered:".tabpagenr().":".bufnr("")') - eq("tabnewentered:2:2", nvim('exec', 'tabnew', true)) - eq("tabnewentered:3:3", nvim('exec', 'tabnew test.x2', true)) - end) + command('au! TabNewEntered * echom "tabnewentered:".tabpagenr().":".bufnr("")') + eq('tabnewentered:2:2', api.nvim_exec('tabnew', true)) + eq('tabnewentered:3:3', api.nvim_exec('tabnew test.x2', true)) + end) end) describe('with FILE as <afile>', function() it('matches when opening a new tab for FILE', function() clear() - nvim('command', 'au! TabNewEntered Xtest-tabnewentered echom "tabnewentered:match"') - eq('tabnewentered:match', nvim('exec', 'tabnew Xtest-tabnewentered', true)) - end) + command('au! TabNewEntered Xtest-tabnewentered echom "tabnewentered:match"') + eq('tabnewentered:match', api.nvim_exec('tabnew Xtest-tabnewentered', true)) + end) end) describe('with CTRL-W T', function() it('works when opening a new tab with CTRL-W T', function() clear() - nvim('command', 'au! TabNewEntered * echom "entered"') - nvim('command', 'tabnew test.x2') - nvim('command', 'split') - eq('entered', nvim('exec', 'execute "normal \\<C-W>T"', true)) + command('au! TabNewEntered * echom "entered"') + command('tabnew test.x2') + command('split') + eq('entered', api.nvim_exec('execute "normal \\<C-W>T"', true)) end) end) describe('with tab split #4334', function() it('works when create a tab by using tab split command', function() clear() - nvim('command', 'au! TabNewEntered * let b:entered = "entered"') - nvim('command', 'tab split') - eq('entered', nvim('exec', 'echo b:entered', true)) + command('au! TabNewEntered * let b:entered = "entered"') + command('tab split') + eq('entered', api.nvim_exec('echo b:entered', true)) end) end) end) @@ -49,22 +49,22 @@ end) describe('TabEnter', function() before_each(clear) it('has correct previous tab when entering any new tab', function() - command('augroup TEMP') - nvim('command', 'au! TabEnter * echom "tabenter:".tabpagenr().":".tabpagenr(\'#\')') - command('augroup END') - eq("tabenter:2:1", nvim('exec', 'tabnew', true)) - eq("tabenter:3:2", nvim('exec', 'tabnew test.x2', true)) - command('augroup! TEMP') + command('augroup TEMP') + command('au! TabEnter * echom "tabenter:".tabpagenr().":".tabpagenr(\'#\')') + command('augroup END') + eq('tabenter:2:1', api.nvim_exec('tabnew', true)) + eq('tabenter:3:2', api.nvim_exec('tabnew test.x2', true)) + command('augroup! TEMP') end) it('has correct previous tab when entering any preexisting tab', function() - command('tabnew') - command('tabnew') - command('augroup TEMP') - nvim('command', 'au! TabEnter * echom "tabenter:".tabpagenr().":".tabpagenr(\'#\')') - command('augroup END') - eq("tabenter:1:3", nvim('exec', 'tabnext', true)) - eq("tabenter:2:1", nvim('exec', 'tabnext', true)) - command('augroup! TEMP') + command('tabnew') + command('tabnew') + command('augroup TEMP') + command('au! TabEnter * echom "tabenter:".tabpagenr().":".tabpagenr(\'#\')') + command('augroup END') + eq('tabenter:1:3', api.nvim_exec('tabnext', true)) + eq('tabenter:2:1', api.nvim_exec('tabnext', true)) + command('augroup! TEMP') end) end) @@ -72,18 +72,19 @@ describe('tabpage/previous', function() before_each(clear) local function switches_to_previous_after_new_tab_creation_at_end(characters) return function() - -- Add three tabs for a total of four - command('tabnew') - command('tabnew') - command('tabnew') + -- Add three tabs for a total of four + command('tabnew') + command('tabnew') + command('tabnew') - -- The previous tab is now the third. - eq(3, eval('tabpagenr(\'#\')')) + -- The previous tab is now the third. + eq(3, eval("tabpagenr('#')")) - -- Switch to the previous (third) tab - feed(characters) + -- Switch to the previous (third) tab + feed(characters) - eq(dedent([=[ + eq( + dedent([=[ Tab page 1 [No Name] @@ -93,18 +94,29 @@ describe('tabpage/previous', function() > [No Name] Tab page 4 # [No Name]]=]), - exec_capture('tabs') - ) + exec_capture('tabs') + ) - -- The previous tab is now the fourth. - eq(4, eval('tabpagenr(\'#\')')) + -- The previous tab is now the fourth. + eq(4, eval("tabpagenr('#')")) end end - it('switches to previous via g<Tab> after new tab creation at end', - switches_to_previous_after_new_tab_creation_at_end('g<Tab>')) - it('switches to previous via <C-W>g<Tab>. after new tab creation at end', switches_to_previous_after_new_tab_creation_at_end('<C-W>g<Tab>')) - it('switches to previous via <C-Tab>. after new tab creation at end', switches_to_previous_after_new_tab_creation_at_end('<C-Tab>')) - it('switches to previous via :tabn #<CR>. after new tab creation at end', switches_to_previous_after_new_tab_creation_at_end(':tabn #<CR>')) + it( + 'switches to previous via g<Tab> after new tab creation at end', + switches_to_previous_after_new_tab_creation_at_end('g<Tab>') + ) + it( + 'switches to previous via <C-W>g<Tab>. after new tab creation at end', + switches_to_previous_after_new_tab_creation_at_end('<C-W>g<Tab>') + ) + it( + 'switches to previous via <C-Tab>. after new tab creation at end', + switches_to_previous_after_new_tab_creation_at_end('<C-Tab>') + ) + it( + 'switches to previous via :tabn #<CR>. after new tab creation at end', + switches_to_previous_after_new_tab_creation_at_end(':tabn #<CR>') + ) local function switches_to_previous_after_new_tab_creation_in_middle(characters) return function() @@ -118,11 +130,12 @@ describe('tabpage/previous', function() command('tabnew') -- The previous tab is now the second. - eq(2, eval('tabpagenr(\'#\')')) + eq(2, eval("tabpagenr('#')")) -- Switch to the previous (second) tab feed(characters) - eq(dedent([=[ + eq( + dedent([=[ Tab page 1 [No Name] @@ -134,21 +147,29 @@ describe('tabpage/previous', function() [No Name] Tab page 5 [No Name]]=]), - exec_capture('tabs') + exec_capture('tabs') ) -- The previous tab is now the third. - eq(3, eval('tabpagenr(\'#\')')) + eq(3, eval("tabpagenr('#')")) end end - it('switches to previous via g<Tab> after new tab creation in middle', - switches_to_previous_after_new_tab_creation_in_middle('g<Tab>')) - it('switches to previous via <C-W>g<Tab> after new tab creation in middle', - switches_to_previous_after_new_tab_creation_in_middle('<C-W>g<Tab>')) - it('switches to previous via <C-Tab> after new tab creation in middle', - switches_to_previous_after_new_tab_creation_in_middle('<C-Tab>')) - it('switches to previous via :tabn #<CR> after new tab creation in middle', - switches_to_previous_after_new_tab_creation_in_middle(':tabn #<CR>')) + it( + 'switches to previous via g<Tab> after new tab creation in middle', + switches_to_previous_after_new_tab_creation_in_middle('g<Tab>') + ) + it( + 'switches to previous via <C-W>g<Tab> after new tab creation in middle', + switches_to_previous_after_new_tab_creation_in_middle('<C-W>g<Tab>') + ) + it( + 'switches to previous via <C-Tab> after new tab creation in middle', + switches_to_previous_after_new_tab_creation_in_middle('<C-Tab>') + ) + it( + 'switches to previous via :tabn #<CR> after new tab creation in middle', + switches_to_previous_after_new_tab_creation_in_middle(':tabn #<CR>') + ) local function switches_to_previous_after_switching_to_next_tab(characters) return function() @@ -160,12 +181,13 @@ describe('tabpage/previous', function() command('tabnext') -- The previous tab is now the fourth. - eq(4, eval('tabpagenr(\'#\')')) + eq(4, eval("tabpagenr('#')")) -- Switch to the previous (fourth) tab feed(characters) - eq(dedent([=[ + eq( + dedent([=[ Tab page 1 # [No Name] @@ -175,21 +197,29 @@ describe('tabpage/previous', function() [No Name] Tab page 4 > [No Name]]=]), - exec_capture('tabs') + exec_capture('tabs') ) -- The previous tab is now the first. - eq(1, eval('tabpagenr(\'#\')')) + eq(1, eval("tabpagenr('#')")) end end - it('switches to previous via g<Tab> after switching to next tab', - switches_to_previous_after_switching_to_next_tab('g<Tab>')) - it('switches to previous via <C-W>g<Tab> after switching to next tab', - switches_to_previous_after_switching_to_next_tab('<C-W>g<Tab>')) - it('switches to previous via <C-Tab> after switching to next tab', - switches_to_previous_after_switching_to_next_tab('<C-Tab>')) - it('switches to previous via :tabn #<CR> after switching to next tab', - switches_to_previous_after_switching_to_next_tab(':tabn #<CR>')) + it( + 'switches to previous via g<Tab> after switching to next tab', + switches_to_previous_after_switching_to_next_tab('g<Tab>') + ) + it( + 'switches to previous via <C-W>g<Tab> after switching to next tab', + switches_to_previous_after_switching_to_next_tab('<C-W>g<Tab>') + ) + it( + 'switches to previous via <C-Tab> after switching to next tab', + switches_to_previous_after_switching_to_next_tab('<C-Tab>') + ) + it( + 'switches to previous via :tabn #<CR> after switching to next tab', + switches_to_previous_after_switching_to_next_tab(':tabn #<CR>') + ) local function switches_to_previous_after_switching_to_last_tab(characters) return function() @@ -203,12 +233,13 @@ describe('tabpage/previous', function() command('tablast') -- The previous tab is now the second. - eq(1, eval('tabpagenr(\'#\')')) + eq(1, eval("tabpagenr('#')")) -- Switch to the previous (second) tab feed(characters) - eq(dedent([=[ + eq( + dedent([=[ Tab page 1 > [No Name] @@ -218,21 +249,29 @@ describe('tabpage/previous', function() [No Name] Tab page 4 # [No Name]]=]), - exec_capture('tabs') + exec_capture('tabs') ) -- The previous tab is now the fourth. - eq(4, eval('tabpagenr(\'#\')')) + eq(4, eval("tabpagenr('#')")) end end - it('switches to previous after switching to last tab', - switches_to_previous_after_switching_to_last_tab('g<Tab>')) - it('switches to previous after switching to last tab', - switches_to_previous_after_switching_to_last_tab('<C-W>g<Tab>')) - it('switches to previous after switching to last tab', - switches_to_previous_after_switching_to_last_tab('<C-Tab>')) - it('switches to previous after switching to last tab', - switches_to_previous_after_switching_to_last_tab(':tabn #<CR>')) + it( + 'switches to previous after switching to last tab', + switches_to_previous_after_switching_to_last_tab('g<Tab>') + ) + it( + 'switches to previous after switching to last tab', + switches_to_previous_after_switching_to_last_tab('<C-W>g<Tab>') + ) + it( + 'switches to previous after switching to last tab', + switches_to_previous_after_switching_to_last_tab('<C-Tab>') + ) + it( + 'switches to previous after switching to last tab', + switches_to_previous_after_switching_to_last_tab(':tabn #<CR>') + ) local function switches_to_previous_after_switching_to_previous_tab(characters) return function() @@ -244,12 +283,13 @@ describe('tabpage/previous', function() command('tabprevious') -- The previous tab is now the fourth. - eq(4, eval('tabpagenr(\'#\')')) + eq(4, eval("tabpagenr('#')")) -- Switch to the previous (fourth) tab feed(characters) - eq(dedent([=[ + eq( + dedent([=[ Tab page 1 [No Name] @@ -259,21 +299,29 @@ describe('tabpage/previous', function() # [No Name] Tab page 4 > [No Name]]=]), - exec_capture('tabs') + exec_capture('tabs') ) -- The previous tab is now the third. - eq(3, eval('tabpagenr(\'#\')')) + eq(3, eval("tabpagenr('#')")) end end - it('switches to previous via g<Tab> after switching to previous tab', - switches_to_previous_after_switching_to_previous_tab('g<Tab>')) - it('switches to previous via <C-W>g<Tab> after switching to previous tab', - switches_to_previous_after_switching_to_previous_tab('<C-W>g<Tab>')) - it('switches to previous via <C-Tab> after switching to previous tab', - switches_to_previous_after_switching_to_previous_tab('<C-Tab>')) - it('switches to previous via :tabn #<CR> after switching to previous tab', - switches_to_previous_after_switching_to_previous_tab(':tabn #<CR>')) + it( + 'switches to previous via g<Tab> after switching to previous tab', + switches_to_previous_after_switching_to_previous_tab('g<Tab>') + ) + it( + 'switches to previous via <C-W>g<Tab> after switching to previous tab', + switches_to_previous_after_switching_to_previous_tab('<C-W>g<Tab>') + ) + it( + 'switches to previous via <C-Tab> after switching to previous tab', + switches_to_previous_after_switching_to_previous_tab('<C-Tab>') + ) + it( + 'switches to previous via :tabn #<CR> after switching to previous tab', + switches_to_previous_after_switching_to_previous_tab(':tabn #<CR>') + ) local function switches_to_previous_after_switching_to_first_tab(characters) return function() @@ -287,12 +335,13 @@ describe('tabpage/previous', function() command('tabfirst') -- The previous tab is now the third. - eq(3, eval('tabpagenr(\'#\')')) + eq(3, eval("tabpagenr('#')")) -- Switch to the previous (third) tab feed(characters) - eq(dedent([=[ + eq( + dedent([=[ Tab page 1 # [No Name] @@ -302,21 +351,29 @@ describe('tabpage/previous', function() > [No Name] Tab page 4 [No Name]]=]), - exec_capture('tabs') + exec_capture('tabs') ) -- The previous tab is now the first. - eq(1, eval('tabpagenr(\'#\')')) + eq(1, eval("tabpagenr('#')")) end end - it('switches to previous via g<Tab> after switching to first tab', - switches_to_previous_after_switching_to_first_tab('g<Tab>')) - it('switches to previous via <C-W>g<Tab> after switching to first tab', - switches_to_previous_after_switching_to_first_tab('<C-W>g<Tab>')) - it('switches to previous via <C-Tab> after switching to first tab', - switches_to_previous_after_switching_to_first_tab('<C-Tab>')) - it('switches to previous via :tabn #<CR> after switching to first tab', - switches_to_previous_after_switching_to_first_tab(':tabn #<CR>')) + it( + 'switches to previous via g<Tab> after switching to first tab', + switches_to_previous_after_switching_to_first_tab('g<Tab>') + ) + it( + 'switches to previous via <C-W>g<Tab> after switching to first tab', + switches_to_previous_after_switching_to_first_tab('<C-W>g<Tab>') + ) + it( + 'switches to previous via <C-Tab> after switching to first tab', + switches_to_previous_after_switching_to_first_tab('<C-Tab>') + ) + it( + 'switches to previous via :tabn #<CR> after switching to first tab', + switches_to_previous_after_switching_to_first_tab(':tabn #<CR>') + ) local function switches_to_previous_after_numbered_tab_switch(characters) return function() @@ -328,12 +385,13 @@ describe('tabpage/previous', function() command('tabnext 2') -- The previous tab is now the fourth. - eq(4, eval('tabpagenr(\'#\')')) + eq(4, eval("tabpagenr('#')")) -- Switch to the previous (fourth) tab feed(characters) - eq(dedent([=[ + eq( + dedent([=[ Tab page 1 [No Name] @@ -343,21 +401,29 @@ describe('tabpage/previous', function() [No Name] Tab page 4 > [No Name]]=]), - exec_capture('tabs') + exec_capture('tabs') ) -- The previous tab is now the second. - eq(2, eval('tabpagenr(\'#\')')) + eq(2, eval("tabpagenr('#')")) end end - it('switches to previous via g<Tab> after numbered tab switch', - switches_to_previous_after_numbered_tab_switch('g<Tab>')) - it('switches to previous via <C-W>g<Tab> after numbered tab switch', - switches_to_previous_after_numbered_tab_switch('<C-W>g<Tab>')) - it('switches to previous via <C-Tab> after numbered tab switch', - switches_to_previous_after_numbered_tab_switch('<C-Tab>')) - it('switches to previous via :tabn #<CR> after numbered tab switch', - switches_to_previous_after_numbered_tab_switch(':tabn #<CR>')) + it( + 'switches to previous via g<Tab> after numbered tab switch', + switches_to_previous_after_numbered_tab_switch('g<Tab>') + ) + it( + 'switches to previous via <C-W>g<Tab> after numbered tab switch', + switches_to_previous_after_numbered_tab_switch('<C-W>g<Tab>') + ) + it( + 'switches to previous via <C-Tab> after numbered tab switch', + switches_to_previous_after_numbered_tab_switch('<C-Tab>') + ) + it( + 'switches to previous via :tabn #<CR> after numbered tab switch', + switches_to_previous_after_numbered_tab_switch(':tabn #<CR>') + ) local function switches_to_previous_after_switching_to_previous(characters1, characters2) return function() @@ -371,12 +437,13 @@ describe('tabpage/previous', function() feed(characters1) -- The previous tab is now the second. - eq(2, eval('tabpagenr(\'#\')')) + eq(2, eval("tabpagenr('#')")) -- Switch to the previous (second) tab feed(characters2) - eq(dedent([=[ + eq( + dedent([=[ Tab page 1 [No Name] @@ -386,45 +453,77 @@ describe('tabpage/previous', function() [No Name] Tab page 4 # [No Name]]=]), - exec_capture('tabs') + exec_capture('tabs') ) -- The previous tab is now the fourth. - eq(4, eval('tabpagenr(\'#\')')) + eq(4, eval("tabpagenr('#')")) end end - it('switches to previous via g<Tab> after switching to previous via g<Tab>', - switches_to_previous_after_switching_to_previous('g<Tab>', 'g<Tab>')) - it('switches to previous via <C-W>g<Tab> after switching to previous via g<Tab>', - switches_to_previous_after_switching_to_previous('g<Tab>', '<C-W>g<Tab>')) - it('switches to previous via <C-Tab> after switching to previous via g<Tab>', - switches_to_previous_after_switching_to_previous('g<Tab>', '<C-Tab>')) - it('switches to previous via :tabn #<CR> after switching to previous via g<Tab>', - switches_to_previous_after_switching_to_previous('g<Tab>', ':tabn #<CR>')) - it('switches to previous via g<Tab> after switching to previous via <C-W>g<Tab>', - switches_to_previous_after_switching_to_previous('<C-W>g<Tab>', 'g<Tab>')) - it('switches to previous via <C-W>g<Tab> after switching to previous via <C-W>g<Tab>', - switches_to_previous_after_switching_to_previous('<C-W>g<Tab>', '<C-W>g<Tab>')) - it('switches to previous via <C-Tab> after switching to previous via <C-W>g<Tab>', - switches_to_previous_after_switching_to_previous('<C-W>g<Tab>', '<C-Tab>')) - it('switches to previous via :tabn #<CR> after switching to previous via <C-W>g<Tab>', - switches_to_previous_after_switching_to_previous('<C-W>g<Tab>', ':tabn #<CR>')) - it('switches to previous via g<Tab> after switching to previous via <C-Tab>', - switches_to_previous_after_switching_to_previous('<C-Tab>', 'g<Tab>')) - it('switches to previous via <C-W>g<Tab> after switching to previous via <C-Tab>', - switches_to_previous_after_switching_to_previous('<C-Tab>', '<C-W>g<Tab>')) - it('switches to previous via <C-Tab> after switching to previous via <C-Tab>', - switches_to_previous_after_switching_to_previous('<C-Tab>', '<C-Tab>')) - it('switches to previous via :tabn #<CR> after switching to previous via <C-Tab>', - switches_to_previous_after_switching_to_previous('<C-Tab>', ':tabn #<CR>')) - it('switches to previous via g<Tab> after switching to previous via :tabn #<CR>', - switches_to_previous_after_switching_to_previous(':tabn #<CR>', 'g<Tab>')) - it('switches to previous via <C-W>g<Tab> after switching to previous via :tabn #<CR>', - switches_to_previous_after_switching_to_previous(':tabn #<CR>', '<C-W>g<Tab>')) - it('switches to previous via <C-Tab> after switching to previous via <C-Tab>', - switches_to_previous_after_switching_to_previous(':tabn #<CR>', '<C-Tab>')) - it('switches to previous via :tabn #<CR> after switching to previous via :tabn #<CR>', - switches_to_previous_after_switching_to_previous(':tabn #<CR>', ':tabn #<CR>')) + it( + 'switches to previous via g<Tab> after switching to previous via g<Tab>', + switches_to_previous_after_switching_to_previous('g<Tab>', 'g<Tab>') + ) + it( + 'switches to previous via <C-W>g<Tab> after switching to previous via g<Tab>', + switches_to_previous_after_switching_to_previous('g<Tab>', '<C-W>g<Tab>') + ) + it( + 'switches to previous via <C-Tab> after switching to previous via g<Tab>', + switches_to_previous_after_switching_to_previous('g<Tab>', '<C-Tab>') + ) + it( + 'switches to previous via :tabn #<CR> after switching to previous via g<Tab>', + switches_to_previous_after_switching_to_previous('g<Tab>', ':tabn #<CR>') + ) + it( + 'switches to previous via g<Tab> after switching to previous via <C-W>g<Tab>', + switches_to_previous_after_switching_to_previous('<C-W>g<Tab>', 'g<Tab>') + ) + it( + 'switches to previous via <C-W>g<Tab> after switching to previous via <C-W>g<Tab>', + switches_to_previous_after_switching_to_previous('<C-W>g<Tab>', '<C-W>g<Tab>') + ) + it( + 'switches to previous via <C-Tab> after switching to previous via <C-W>g<Tab>', + switches_to_previous_after_switching_to_previous('<C-W>g<Tab>', '<C-Tab>') + ) + it( + 'switches to previous via :tabn #<CR> after switching to previous via <C-W>g<Tab>', + switches_to_previous_after_switching_to_previous('<C-W>g<Tab>', ':tabn #<CR>') + ) + it( + 'switches to previous via g<Tab> after switching to previous via <C-Tab>', + switches_to_previous_after_switching_to_previous('<C-Tab>', 'g<Tab>') + ) + it( + 'switches to previous via <C-W>g<Tab> after switching to previous via <C-Tab>', + switches_to_previous_after_switching_to_previous('<C-Tab>', '<C-W>g<Tab>') + ) + it( + 'switches to previous via <C-Tab> after switching to previous via <C-Tab>', + switches_to_previous_after_switching_to_previous('<C-Tab>', '<C-Tab>') + ) + it( + 'switches to previous via :tabn #<CR> after switching to previous via <C-Tab>', + switches_to_previous_after_switching_to_previous('<C-Tab>', ':tabn #<CR>') + ) + it( + 'switches to previous via g<Tab> after switching to previous via :tabn #<CR>', + switches_to_previous_after_switching_to_previous(':tabn #<CR>', 'g<Tab>') + ) + it( + 'switches to previous via <C-W>g<Tab> after switching to previous via :tabn #<CR>', + switches_to_previous_after_switching_to_previous(':tabn #<CR>', '<C-W>g<Tab>') + ) + it( + 'switches to previous via <C-Tab> after switching to previous via <C-Tab>', + switches_to_previous_after_switching_to_previous(':tabn #<CR>', '<C-Tab>') + ) + it( + 'switches to previous via :tabn #<CR> after switching to previous via :tabn #<CR>', + switches_to_previous_after_switching_to_previous(':tabn #<CR>', ':tabn #<CR>') + ) local function does_not_switch_to_previous_after_closing_current_tab(characters) return function() @@ -436,13 +535,14 @@ describe('tabpage/previous', function() command('wincmd c') -- The previous tab is now the "zeroth" -- there isn't one. - eq(0, eval('tabpagenr(\'#\')')) + eq(0, eval("tabpagenr('#')")) -- At this point, switching to the "previous" (i.e. fourth) tab would mean -- switching to either a dangling or a null pointer. feed(characters) - eq(dedent([=[ + eq( + dedent([=[ Tab page 1 [No Name] @@ -450,21 +550,29 @@ describe('tabpage/previous', function() [No Name] Tab page 3 > [No Name]]=]), - exec_capture('tabs') + exec_capture('tabs') ) -- The previous tab is now the "zero". - eq(0, eval('tabpagenr(\'#\')')) + eq(0, eval("tabpagenr('#')")) end end - it('does not switch to previous via g<Tab> after closing current tab', - does_not_switch_to_previous_after_closing_current_tab('g<Tab>')) - it('does not switch to previous via <C-W>g<Tab> after closing current tab', - does_not_switch_to_previous_after_closing_current_tab('<C-W>g<Tab>')) - it('does not switch to previous via <C-Tab> after closing current tab', - does_not_switch_to_previous_after_closing_current_tab('<C-Tab>')) - it('does not switch to previous via :tabn #<CR> after closing current tab', - does_not_switch_to_previous_after_closing_current_tab(':tabn #<CR>')) + it( + 'does not switch to previous via g<Tab> after closing current tab', + does_not_switch_to_previous_after_closing_current_tab('g<Tab>') + ) + it( + 'does not switch to previous via <C-W>g<Tab> after closing current tab', + does_not_switch_to_previous_after_closing_current_tab('<C-W>g<Tab>') + ) + it( + 'does not switch to previous via <C-Tab> after closing current tab', + does_not_switch_to_previous_after_closing_current_tab('<C-Tab>') + ) + it( + 'does not switch to previous via :tabn #<CR> after closing current tab', + does_not_switch_to_previous_after_closing_current_tab(':tabn #<CR>') + ) local function does_not_switch_to_previous_after_entering_operator_pending(characters) return function() @@ -474,7 +582,7 @@ describe('tabpage/previous', function() command('tabnew') -- The previous tab is now the third. - eq(3, eval('tabpagenr(\'#\')')) + eq(3, eval("tabpagenr('#')")) -- Enter operator pending mode. feed('d') @@ -491,11 +599,13 @@ describe('tabpage/previous', function() eq(4, eval('tabpagenr()')) -- The previous tab is still the third. - eq(3, eval('tabpagenr(\'#\')')) + eq(3, eval("tabpagenr('#')")) end end - it('does not switch to previous via g<Tab> after entering operator pending', - does_not_switch_to_previous_after_entering_operator_pending('g<Tab>')) + it( + 'does not switch to previous via g<Tab> after entering operator pending', + does_not_switch_to_previous_after_entering_operator_pending('g<Tab>') + ) -- NOTE: When in operator pending mode, attempting to switch to previous has -- the following effect: -- - Ctrl-W exits operator pending mode @@ -506,8 +616,10 @@ describe('tabpage/previous', function() -- be the same as the normal mode command to switch to the previous tab. -- it('does not switch to previous via <C-W>g<Tab> after entering operator pending', -- does_not_switch_to_previous_after_entering_operator_pending('<C-W>g<Tab>')) - it('does not switch to previous via <C-Tab> after entering operator pending', - does_not_switch_to_previous_after_entering_operator_pending('<C-Tab>')) + it( + 'does not switch to previous via <C-Tab> after entering operator pending', + does_not_switch_to_previous_after_entering_operator_pending('<C-Tab>') + ) -- NOTE: When in operator pending mode, pressing : leaves operator pending -- mode and enters command mode, so :tabn #<CR> does in fact switch -- tabs. @@ -522,7 +634,7 @@ describe('tabpage/previous', function() command('tabnew') -- The previous tab is now the third. - eq(3, eval('tabpagenr(\'#\')')) + eq(3, eval("tabpagenr('#')")) -- Edit : command line in command-line window feed('q:') @@ -540,31 +652,34 @@ describe('tabpage/previous', function() eq(4, eval('tabpagenr()')) -- The previous tab is still the third. - eq(3, eval('tabpagenr(\'#\')')) + eq(3, eval("tabpagenr('#')")) end end - it('cmdline-win prevents tab switch via g<Tab>', - cmdline_win_prevents_tab_switch('g<Tab>', 0)) - it('cmdline-win prevents tab switch via <C-W>g<Tab>', - cmdline_win_prevents_tab_switch('<C-W>g<Tab>', 1)) - it('cmdline-win prevents tab switch via <C-Tab>', - cmdline_win_prevents_tab_switch('<C-Tab>', 0)) - it('cmdline-win prevents tab switch via :tabn #<CR>', - cmdline_win_prevents_tab_switch(':tabn #<CR>', 0)) + it('cmdline-win prevents tab switch via g<Tab>', cmdline_win_prevents_tab_switch('g<Tab>', 0)) + it( + 'cmdline-win prevents tab switch via <C-W>g<Tab>', + cmdline_win_prevents_tab_switch('<C-W>g<Tab>', 1) + ) + it('cmdline-win prevents tab switch via <C-Tab>', cmdline_win_prevents_tab_switch('<C-Tab>', 0)) + it( + 'cmdline-win prevents tab switch via :tabn #<CR>', + cmdline_win_prevents_tab_switch(':tabn #<CR>', 0) + ) it(':tabs indicates correct prevtab curwin', function() - -- Add three tabs for a total of four - command('tabnew') - command('tabnew') - command('split') - command('vsplit') - feed('<C-w>p') - command('tabnew') + -- Add three tabs for a total of four + command('tabnew') + command('tabnew') + command('split') + command('vsplit') + feed('<C-w>p') + command('tabnew') - -- The previous tab is now the three. - eq(3, eval('tabpagenr(\'#\')')) + -- The previous tab is now the three. + eq(3, eval("tabpagenr('#')")) - eq(dedent([=[ + eq( + dedent([=[ Tab page 1 [No Name] @@ -576,7 +691,7 @@ describe('tabpage/previous', function() [No Name] Tab page 4 > [No Name]]=]), - exec_capture('tabs') - ) + exec_capture('tabs') + ) end) end) diff --git a/test/functional/autocmd/termxx_spec.lua b/test/functional/autocmd/termxx_spec.lua index 332a936e3f..982edfa06a 100644 --- a/test/functional/autocmd/termxx_spec.lua +++ b/test/functional/autocmd/termxx_spec.lua @@ -1,15 +1,13 @@ -local luv = require('luv') +local uv = vim.uv local helpers = require('test.functional.helpers')(after_each) local thelpers = require('test.functional.terminal.helpers') -local clear, command, nvim, testprg = - helpers.clear, helpers.command, helpers.nvim, helpers.testprg -local eval, eq, neq, retry = - helpers.eval, helpers.eq, helpers.neq, helpers.retry +local clear, command, testprg = helpers.clear, helpers.command, helpers.testprg +local eval, eq, neq, retry = helpers.eval, helpers.eq, helpers.neq, helpers.retry local matches = helpers.matches local ok = helpers.ok local feed = helpers.feed -local meths = helpers.meths +local api = helpers.api local pcall_err = helpers.pcall_err local assert_alive = helpers.assert_alive local skip = helpers.skip @@ -18,17 +16,19 @@ local is_os = helpers.is_os describe('autocmd TermClose', function() before_each(function() clear() - nvim('set_option_value', 'shell', testprg('shell-test'), {}) + api.nvim_set_option_value('shell', testprg('shell-test'), {}) command('set shellcmdflag=EXE shellredir= shellpipe= shellquote= shellxquote=') end) local function test_termclose_delete_own_buf() -- The terminal process needs to keep running so that TermClose isn't triggered immediately. - nvim('set_option_value', 'shell', string.format('"%s" INTERACT', testprg('shell-test')), {}) + api.nvim_set_option_value('shell', string.format('"%s" INTERACT', testprg('shell-test')), {}) command('autocmd TermClose * bdelete!') command('terminal') - matches('^TermClose Autocommands for "%*": Vim%(bdelete%):E937: Attempt to delete a buffer that is in use: term://', - pcall_err(command, 'bdelete!')) + matches( + '^TermClose Autocommands for "%*": Vim%(bdelete%):E937: Attempt to delete a buffer that is in use: term://', + pcall_err(command, 'bdelete!') + ) assert_alive() end @@ -46,58 +46,76 @@ describe('autocmd TermClose', function() command('autocmd TermClose * let g:test_termclose = 23') command('terminal') -- shell-test exits immediately. - retry(nil, nil, function() neq(-1, eval('jobwait([&channel], 0)[0]')) end) - retry(nil, nil, function() eq(23, eval('g:test_termclose')) end) + retry(nil, nil, function() + neq(-1, eval('jobwait([&channel], 0)[0]')) + end) + retry(nil, nil, function() + eq(23, eval('g:test_termclose')) + end) end) it('triggers when long-running terminal job gets stopped', function() skip(is_os('win')) - nvim('set_option_value', 'shell', is_os('win') and 'cmd.exe' or 'sh', {}) + api.nvim_set_option_value('shell', is_os('win') and 'cmd.exe' or 'sh', {}) command('autocmd TermClose * let g:test_termclose = 23') command('terminal') command('call jobstop(b:terminal_job_id)') - retry(nil, nil, function() eq(23, eval('g:test_termclose')) end) + retry(nil, nil, function() + eq(23, eval('g:test_termclose')) + end) end) it('kills job trapping SIGTERM', function() skip(is_os('win')) - nvim('set_option_value', 'shell', 'sh', {}) - nvim('set_option_value', 'shellcmdflag', '-c', {}) - command([[ let g:test_job = jobstart('trap "" TERM && echo 1 && sleep 60', { ]] - .. [[ 'on_stdout': {-> execute('let g:test_job_started = 1')}, ]] - .. [[ 'on_exit': {-> execute('let g:test_job_exited = 1')}}) ]]) - retry(nil, nil, function() eq(1, eval('get(g:, "test_job_started", 0)')) end) - - luv.update_time() - local start = luv.now() + api.nvim_set_option_value('shell', 'sh', {}) + api.nvim_set_option_value('shellcmdflag', '-c', {}) + command( + [[ let g:test_job = jobstart('trap "" TERM && echo 1 && sleep 60', { ]] + .. [[ 'on_stdout': {-> execute('let g:test_job_started = 1')}, ]] + .. [[ 'on_exit': {-> execute('let g:test_job_exited = 1')}}) ]] + ) + retry(nil, nil, function() + eq(1, eval('get(g:, "test_job_started", 0)')) + end) + + uv.update_time() + local start = uv.now() command('call jobstop(g:test_job)') - retry(nil, nil, function() eq(1, eval('get(g:, "test_job_exited", 0)')) end) - luv.update_time() - local duration = luv.now() - start + retry(nil, nil, function() + eq(1, eval('get(g:, "test_job_exited", 0)')) + end) + uv.update_time() + local duration = uv.now() - start -- Nvim begins SIGTERM after KILL_TIMEOUT_MS. ok(duration >= 2000) - ok(duration <= 4000) -- Epsilon for slow CI + ok(duration <= 4000) -- Epsilon for slow CI end) it('kills PTY job trapping SIGHUP and SIGTERM', function() skip(is_os('win')) - nvim('set_option_value', 'shell', 'sh', {}) - nvim('set_option_value', 'shellcmdflag', '-c', {}) - command([[ let g:test_job = jobstart('trap "" HUP TERM && echo 1 && sleep 60', { ]] - .. [[ 'pty': 1,]] - .. [[ 'on_stdout': {-> execute('let g:test_job_started = 1')}, ]] - .. [[ 'on_exit': {-> execute('let g:test_job_exited = 1')}}) ]]) - retry(nil, nil, function() eq(1, eval('get(g:, "test_job_started", 0)')) end) - - luv.update_time() - local start = luv.now() + api.nvim_set_option_value('shell', 'sh', {}) + api.nvim_set_option_value('shellcmdflag', '-c', {}) + command( + [[ let g:test_job = jobstart('trap "" HUP TERM && echo 1 && sleep 60', { ]] + .. [[ 'pty': 1,]] + .. [[ 'on_stdout': {-> execute('let g:test_job_started = 1')}, ]] + .. [[ 'on_exit': {-> execute('let g:test_job_exited = 1')}}) ]] + ) + retry(nil, nil, function() + eq(1, eval('get(g:, "test_job_started", 0)')) + end) + + uv.update_time() + local start = uv.now() command('call jobstop(g:test_job)') - retry(nil, nil, function() eq(1, eval('get(g:, "test_job_exited", 0)')) end) - luv.update_time() - local duration = luv.now() - start + retry(nil, nil, function() + eq(1, eval('get(g:, "test_job_exited", 0)')) + end) + uv.update_time() + local duration = uv.now() - start -- Nvim begins SIGKILL after (2 * KILL_TIMEOUT_MS). ok(duration >= 4000) - ok(duration <= 7000) -- Epsilon for slow CI + ok(duration <= 7000) -- Epsilon for slow CI end) it('reports the correct <abuf>', function() @@ -109,13 +127,19 @@ describe('autocmd TermClose', function() eq(2, eval('bufnr("%")')) command('terminal ls') - retry(nil, nil, function() eq(3, eval('bufnr("%")')) end) + retry(nil, nil, function() + eq(3, eval('bufnr("%")')) + end) command('buffer 1') - retry(nil, nil, function() eq(1, eval('bufnr("%")')) end) + retry(nil, nil, function() + eq(1, eval('bufnr("%")')) + end) command('3bdelete!') - retry(nil, nil, function() eq('3', eval('g:abuf')) end) + retry(nil, nil, function() + eq('3', eval('g:abuf')) + end) feed('<c-c>:qa!<cr>') end) @@ -124,10 +148,14 @@ describe('autocmd TermClose', function() command('autocmd TermClose * let g:status = v:event.status') command('terminal 0') - retry(nil, nil, function() eq(0, eval('g:status')) end) + retry(nil, nil, function() + eq(0, eval('g:status')) + end) command('terminal 42') - retry(nil, nil, function() eq(42, eval('g:status')) end) + retry(nil, nil, function() + eq(42, eval('g:status')) + end) end) end) @@ -141,27 +169,30 @@ it('autocmd TermEnter, TermLeave', function() command('terminal') feed('i') - eq({ {'TermOpen', 'n'}, {'TermEnter', 't'}, }, eval('g:evs')) + eq({ { 'TermOpen', 'n' }, { 'TermEnter', 't' } }, eval('g:evs')) feed([[<C-\><C-n>]]) feed('A') - eq({ {'TermOpen', 'n'}, {'TermEnter', 't'}, {'TermLeave', 'n'}, {'TermEnter', 't'}, }, eval('g:evs')) + eq( + { { 'TermOpen', 'n' }, { 'TermEnter', 't' }, { 'TermLeave', 'n' }, { 'TermEnter', 't' } }, + eval('g:evs') + ) -- TermLeave is also triggered by :quit. command('split foo') - feed('<Ignore>') -- Add input to separate two RPC requests + feed('<Ignore>') -- Add input to separate two RPC requests command('wincmd w') feed('i') command('q!') - feed('<Ignore>') -- Add input to separate two RPC requests + feed('<Ignore>') -- Add input to separate two RPC requests eq({ - {'TermOpen', 'n'}, - {'TermEnter', 't'}, - {'TermLeave', 'n'}, - {'TermEnter', 't'}, - {'TermLeave', 'n'}, - {'TermEnter', 't'}, - {'TermClose', 't'}, - {'TermLeave', 'n'}, + { 'TermOpen', 'n' }, + { 'TermEnter', 't' }, + { 'TermLeave', 'n' }, + { 'TermEnter', 't' }, + { 'TermLeave', 'n' }, + { 'TermEnter', 't' }, + { 'TermClose', 't' }, + { 'TermLeave', 'n' }, }, eval('g:evs')) end) @@ -172,13 +203,18 @@ describe('autocmd TextChangedT', function() it('works', function() command('autocmd TextChangedT * ++once let g:called = 1') thelpers.feed_data('a') - retry(nil, nil, function() eq(1, meths.get_var('called')) end) + retry(nil, nil, function() + eq(1, api.nvim_get_var('called')) + end) end) it('cannot delete terminal buffer', function() command([[autocmd TextChangedT * call nvim_input('<CR>') | bwipe!]]) thelpers.feed_data('a') - screen:expect({any = 'E937: '}) - matches('^E937: Attempt to delete a buffer that is in use: term://', meths.get_vvar('errmsg')) + screen:expect({ any = 'E937: ' }) + matches( + '^E937: Attempt to delete a buffer that is in use: term://', + api.nvim_get_vvar('errmsg') + ) end) end) diff --git a/test/functional/autocmd/textchanged_spec.lua b/test/functional/autocmd/textchanged_spec.lua index b621eb36bf..d501560dc1 100644 --- a/test/functional/autocmd/textchanged_spec.lua +++ b/test/functional/autocmd/textchanged_spec.lua @@ -88,7 +88,7 @@ it('TextChangedI and TextChangedP autocommands', function() eq('IIPPPP', eval('g:autocmd')) feed('<esc>') - eq({'foo', 'bar', 'foobar', 'foo'}, eval('getline(1, "$")')) + eq({ 'foo', 'bar', 'foobar', 'foo' }, eval('getline(1, "$")')) end) -- oldtest: Test_TextChangedI_with_setline() @@ -172,11 +172,22 @@ it('TextChangedI and TextChanged', function() eq('', eval('g:autocmd_n')) end - validate_mixed_textchangedi({'o', '<esc>'}) - validate_mixed_textchangedi({'O', '<esc>'}) - validate_mixed_textchangedi({'ciw', '<esc>'}) - validate_mixed_textchangedi({'cc', '<esc>'}) - validate_mixed_textchangedi({'C', '<esc>'}) - validate_mixed_textchangedi({'s', '<esc>'}) - validate_mixed_textchangedi({'S', '<esc>'}) + validate_mixed_textchangedi({ 'o', '<esc>' }) + validate_mixed_textchangedi({ 'O', '<esc>' }) + validate_mixed_textchangedi({ 'ciw', '<esc>' }) + validate_mixed_textchangedi({ 'cc', '<esc>' }) + validate_mixed_textchangedi({ 'C', '<esc>' }) + validate_mixed_textchangedi({ 's', '<esc>' }) + validate_mixed_textchangedi({ 'S', '<esc>' }) +end) + +-- oldtest: Test_TextChanged_with_norm() +it('TextChanged is triggered after :norm that enters Insert mode', function() + exec([[ + let g:a = 0 + au TextChanged * let g:a += 1 + ]]) + eq(0, eval('g:a')) + feed(':norm! ia<CR>') + eq(1, eval('g:a')) end) diff --git a/test/functional/autocmd/textyankpost_spec.lua b/test/functional/autocmd/textyankpost_spec.lua index 1640916ad8..29cd62f586 100644 --- a/test/functional/autocmd/textyankpost_spec.lua +++ b/test/functional/autocmd/textyankpost_spec.lua @@ -1,7 +1,7 @@ local helpers = require('test.functional.helpers')(after_each) local clear, eval, eq = helpers.clear, helpers.eval, helpers.eq local feed, command, expect = helpers.feed, helpers.command, helpers.expect -local curbufmeths, funcs, neq = helpers.curbufmeths, helpers.funcs, helpers.neq +local api, fn, neq = helpers.api, helpers.fn, helpers.neq describe('TextYankPost', function() before_each(function() @@ -14,7 +14,7 @@ describe('TextYankPost', function() command('autocmd TextYankPost * let g:event = copy(v:event)') command('autocmd TextYankPost * let g:count += 1') - curbufmeths.set_lines(0, -1, true, { + api.nvim_buf_set_lines(0, 0, -1, true, { 'foo\0bar', 'baz text', }) @@ -28,7 +28,7 @@ describe('TextYankPost', function() regcontents = { 'foo\nbar' }, regname = '', regtype = 'V', - visual = false + visual = false, }, eval('g:event')) eq(1, eval('g:count')) @@ -42,7 +42,7 @@ describe('TextYankPost', function() regcontents = { 'baz ' }, regname = '', regtype = 'v', - visual = false + visual = false, }, eval('g:event')) eq(2, eval('g:count')) @@ -52,8 +52,8 @@ describe('TextYankPost', function() operator = 'y', regcontents = { 'foo', 'baz' }, regname = '', - regtype = "\0223", -- ^V + block width - visual = true + regtype = '\0223', -- ^V + block width + visual = true, }, eval('g:event')) eq(3, eval('g:count')) end) @@ -66,25 +66,25 @@ describe('TextYankPost', function() regcontents = { 'foo\nbar' }, regname = '', regtype = 'V', - visual = false + visual = false, }, eval('g:event')) command('set debug=msg') -- the regcontents should not be changed without copy. - local status, err = pcall(command,'call extend(g:event.regcontents, ["more text"])') - eq(status,false) + local status, err = pcall(command, 'call extend(g:event.regcontents, ["more text"])') + eq(status, false) neq(nil, string.find(err, ':E742:')) -- can't mutate keys inside the autocommand command('autocmd! TextYankPost * let v:event.regcontents = 0') - status, err = pcall(command,'normal yy') - eq(status,false) + status, err = pcall(command, 'normal yy') + eq(status, false) neq(nil, string.find(err, ':E46:')) -- can't add keys inside the autocommand command('autocmd! TextYankPost * let v:event.mykey = 0') - status, err = pcall(command,'normal yy') - eq(status,false) + status, err = pcall(command, 'normal yy') + eq(status, false) neq(nil, string.find(err, ':E742:')) end) @@ -97,10 +97,10 @@ describe('TextYankPost', function() regcontents = { 'foo\nbar' }, regname = '', regtype = 'V', - visual = false + visual = false, }, eval('g:event')) eq(1, eval('g:count')) - eq({ 'foo\nbar' }, funcs.getreg('+',1,1)) + eq({ 'foo\nbar' }, fn.getreg('+', 1, 1)) end) it('is executed after delete and change', function() @@ -111,7 +111,7 @@ describe('TextYankPost', function() regcontents = { 'foo' }, regname = '', regtype = 'v', - visual = false + visual = false, }, eval('g:event')) eq(1, eval('g:count')) @@ -122,7 +122,7 @@ describe('TextYankPost', function() regcontents = { '\nbar' }, regname = '', regtype = 'V', - visual = false + visual = false, }, eval('g:event')) eq(2, eval('g:count')) @@ -133,7 +133,7 @@ describe('TextYankPost', function() regcontents = { 'baz' }, regname = '', regtype = 'v', - visual = false + visual = false, }, eval('g:event')) eq(3, eval('g:count')) end) @@ -162,7 +162,7 @@ describe('TextYankPost', function() regcontents = { 'bar' }, regname = 'b', regtype = 'v', - visual = false + visual = false, }, eval('g:event')) feed('"*yy') @@ -172,10 +172,10 @@ describe('TextYankPost', function() regcontents = { 'foo\nbar' }, regname = '*', regtype = 'V', - visual = false + visual = false, }, eval('g:event')) - command("set clipboard=unnamed") + command('set clipboard=unnamed') -- regname still shows the name the user requested feed('yy') @@ -185,7 +185,7 @@ describe('TextYankPost', function() regcontents = { 'foo\nbar' }, regname = '', regtype = 'V', - visual = false + visual = false, }, eval('g:event')) feed('"*yy') @@ -195,7 +195,7 @@ describe('TextYankPost', function() regcontents = { 'foo\nbar' }, regname = '*', regtype = 'V', - visual = false + visual = false, }, eval('g:event')) end) @@ -207,7 +207,7 @@ describe('TextYankPost', function() regcontents = { 'foo\nbar' }, regname = '+', regtype = 'V', - visual = false + visual = false, }, eval('g:event')) eq(1, eval('g:count')) @@ -218,7 +218,7 @@ describe('TextYankPost', function() regcontents = { 'baz text' }, regname = '', regtype = 'V', - visual = false + visual = false, }, eval('g:event')) eq(2, eval('g:count')) @@ -229,7 +229,7 @@ describe('TextYankPost', function() regcontents = { 'baz ' }, regname = '', regtype = 'v', - visual = false + visual = false, }, eval('g:event')) eq(3, eval('g:count')) @@ -240,7 +240,7 @@ describe('TextYankPost', function() regcontents = { 'baz text' }, regname = '', regtype = 'V', - visual = false + visual = false, }, eval('g:event')) eq(4, eval('g:count')) end) diff --git a/test/functional/autocmd/win_scrolled_resized_spec.lua b/test/functional/autocmd/win_scrolled_resized_spec.lua index e6fdd9560d..d40dc37103 100644 --- a/test/functional/autocmd/win_scrolled_resized_spec.lua +++ b/test/functional/autocmd/win_scrolled_resized_spec.lua @@ -7,7 +7,7 @@ local eval = helpers.eval local exec = helpers.exec local command = helpers.command local feed = helpers.feed -local meths = helpers.meths +local api = helpers.api local assert_alive = helpers.assert_alive before_each(clear) @@ -32,12 +32,29 @@ describe('WinResized', function() -- increase window height, two windows will be reported feed('<C-W>+') eq(1, eval('g:resized')) - eq({windows = {1002, 1001}}, eval('g:v_event')) + eq({ windows = { 1002, 1001 } }, eval('g:v_event')) -- increase window width, three windows will be reported feed('<C-W>>') eq(2, eval('g:resized')) - eq({windows = {1002, 1001, 1000}}, eval('g:v_event')) + eq({ windows = { 1002, 1001, 1000 } }, eval('g:v_event')) + end) + + it('is triggered in terminal mode #21197 #27207', function() + exec([[ + autocmd TermOpen * startinsert + let g:resized = 0 + autocmd WinResized * let g:resized += 1 + ]]) + eq(0, eval('g:resized')) + + command('vsplit term://') + eq({ mode = 't', blocking = false }, api.nvim_get_mode()) + eq(1, eval('g:resized')) + + command('split') + eq({ mode = 't', blocking = false }, api.nvim_get_mode()) + eq(2, eval('g:resized')) end) end) @@ -45,7 +62,7 @@ describe('WinScrolled', function() local win_id before_each(function() - win_id = meths.get_current_win().id + win_id = api.nvim_get_current_win() command(string.format('autocmd WinScrolled %d let g:matched = v:true', win_id)) exec([[ let g:scrolled = 0 @@ -63,104 +80,104 @@ describe('WinScrolled', function() end) it('is triggered by scrolling vertically', function() - local lines = {'123', '123'} - meths.buf_set_lines(0, 0, -1, true, lines) + local lines = { '123', '123' } + api.nvim_buf_set_lines(0, 0, -1, true, lines) eq(0, eval('g:scrolled')) feed('<C-E>') eq(1, eval('g:scrolled')) eq({ - all = {leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0}, - ['1000'] = {leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0}, + all = { leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0 }, + ['1000'] = { leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0 }, }, eval('g:v_event')) feed('<C-Y>') eq(2, eval('g:scrolled')) eq({ - all = {leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0}, - ['1000'] = {leftcol = 0, topline = -1, topfill = 0, width = 0, height = 0, skipcol = 0}, + all = { leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0 }, + ['1000'] = { leftcol = 0, topline = -1, topfill = 0, width = 0, height = 0, skipcol = 0 }, }, eval('g:v_event')) end) it('is triggered by scrolling horizontally', function() command('set nowrap') - local width = meths.win_get_width(0) + local width = api.nvim_win_get_width(0) local line = '123' .. ('*'):rep(width * 2) - local lines = {line, line} - meths.buf_set_lines(0, 0, -1, true, lines) + local lines = { line, line } + api.nvim_buf_set_lines(0, 0, -1, true, lines) eq(0, eval('g:scrolled')) feed('zl') eq(1, eval('g:scrolled')) eq({ - all = {leftcol = 1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0}, - ['1000'] = {leftcol = 1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0}, + all = { leftcol = 1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0 }, + ['1000'] = { leftcol = 1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0 }, }, eval('g:v_event')) feed('zh') eq(2, eval('g:scrolled')) eq({ - all = {leftcol = 1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0}, - ['1000'] = {leftcol = -1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0}, + all = { leftcol = 1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0 }, + ['1000'] = { leftcol = -1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0 }, }, eval('g:v_event')) end) it('is triggered by horizontal scrolling from cursor move', function() command('set nowrap') - local lines = {'', '', 'Foo'} - meths.buf_set_lines(0, 0, -1, true, lines) - meths.win_set_cursor(0, {3, 0}) + local lines = { '', '', 'Foo' } + api.nvim_buf_set_lines(0, 0, -1, true, lines) + api.nvim_win_set_cursor(0, { 3, 0 }) eq(0, eval('g:scrolled')) feed('zl') eq(1, eval('g:scrolled')) eq({ - all = {leftcol = 1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0}, - ['1000'] = {leftcol = 1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0}, + all = { leftcol = 1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0 }, + ['1000'] = { leftcol = 1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0 }, }, eval('g:v_event')) feed('zl') eq(2, eval('g:scrolled')) eq({ - all = {leftcol = 1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0}, - ['1000'] = {leftcol = 1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0}, + all = { leftcol = 1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0 }, + ['1000'] = { leftcol = 1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0 }, }, eval('g:v_event')) feed('h') eq(3, eval('g:scrolled')) eq({ - all = {leftcol = 1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0}, - ['1000'] = {leftcol = -1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0}, + all = { leftcol = 1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0 }, + ['1000'] = { leftcol = -1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0 }, }, eval('g:v_event')) feed('zh') eq(4, eval('g:scrolled')) eq({ - all = {leftcol = 1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0}, - ['1000'] = {leftcol = -1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0}, + all = { leftcol = 1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0 }, + ['1000'] = { leftcol = -1, topline = 0, topfill = 0, width = 0, height = 0, skipcol = 0 }, }, eval('g:v_event')) end) -- oldtest: Test_WinScrolled_long_wrapped() it('is triggered by scrolling on a long wrapped line #19968', function() - local height = meths.win_get_height(0) - local width = meths.win_get_width(0) - meths.buf_set_lines(0, 0, -1, true, {('foo'):rep(height * width)}) - meths.win_set_cursor(0, {1, height * width - 1}) + local height = api.nvim_win_get_height(0) + local width = api.nvim_win_get_width(0) + api.nvim_buf_set_lines(0, 0, -1, true, { ('foo'):rep(height * width) }) + api.nvim_win_set_cursor(0, { 1, height * width - 1 }) eq(0, eval('g:scrolled')) feed('gj') eq(1, eval('g:scrolled')) eq({ - all = {leftcol = 0, topline = 0, topfill = 0, width = 0, height = 0, skipcol = width}, - ['1000'] = {leftcol = 0, topline = 0, topfill = 0, width = 0, height = 0, skipcol = width}, + all = { leftcol = 0, topline = 0, topfill = 0, width = 0, height = 0, skipcol = width }, + ['1000'] = { leftcol = 0, topline = 0, topfill = 0, width = 0, height = 0, skipcol = width }, }, eval('g:v_event')) feed('0') eq(2, eval('g:scrolled')) eq({ - all = {leftcol = 0, topline = 0, topfill = 0, width = 0, height = 0, skipcol = width}, - ['1000'] = {leftcol = 0, topline = 0, topfill = 0, width = 0, height = 0, skipcol = -width}, + all = { leftcol = 0, topline = 0, topfill = 0, width = 0, height = 0, skipcol = width }, + ['1000'] = { leftcol = 0, topline = 0, topfill = 0, width = 0, height = 0, skipcol = -width }, }, eval('g:v_event')) feed('$') @@ -168,12 +185,12 @@ describe('WinScrolled', function() end) it('is triggered when the window scrolls in Insert mode', function() - local height = meths.win_get_height(0) + local height = api.nvim_win_get_height(0) local lines = {} for i = 1, height * 2 do lines[i] = tostring(i) end - meths.buf_set_lines(0, 0, -1, true, lines) + api.nvim_buf_set_lines(0, 0, -1, true, lines) feed('M') eq(0, eval('g:scrolled')) @@ -181,15 +198,15 @@ describe('WinScrolled', function() feed('i<C-X><C-E><Esc>') eq(1, eval('g:scrolled')) eq({ - all = {leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0}, - ['1000'] = {leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0}, + all = { leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0 }, + ['1000'] = { leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0 }, }, eval('g:v_event')) feed('i<C-X><C-Y><Esc>') eq(2, eval('g:scrolled')) eq({ - all = {leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0}, - ['1000'] = {leftcol = 0, topline = -1, topfill = 0, width = 0, height = 0, skipcol = 0}, + all = { leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0 }, + ['1000'] = { leftcol = 0, topline = -1, topfill = 0, width = 0, height = 0, skipcol = 0 }, }, eval('g:v_event')) feed('L') @@ -198,8 +215,8 @@ describe('WinScrolled', function() feed('A<CR><Esc>') eq(3, eval('g:scrolled')) eq({ - all = {leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0}, - ['1000'] = {leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0}, + all = { leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0 }, + ['1000'] = { leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0 }, }, eval('g:v_event')) end) end) @@ -220,12 +237,12 @@ describe('WinScrolled', function() eq(0, eval('g:scrolled')) -- With the upper split focused, send a scroll-down event to the unfocused one. - meths.input_mouse('wheel', 'down', '', 0, 6, 0) + api.nvim_input_mouse('wheel', 'down', '', 0, 6, 0) eq(1, eval('g:scrolled')) -- Again, but this time while we're in insert mode. feed('i') - meths.input_mouse('wheel', 'down', '', 0, 6, 0) + api.nvim_input_mouse('wheel', 'down', '', 0, 6, 0) feed('<Esc>') eq(2, eval('g:scrolled')) end) @@ -257,30 +274,30 @@ describe('WinScrolled', function() feed('<C-E>') eq({ - all = {leftcol = 0, topline = 1, topfill = 1, width = 0, height = 0, skipcol = 0}, - ['1000'] = {leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0}, - ['1001'] = {leftcol = 0, topline = 0, topfill = -1, width = 0, height = 0, skipcol = 0}, + all = { leftcol = 0, topline = 1, topfill = 1, width = 0, height = 0, skipcol = 0 }, + ['1000'] = { leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0 }, + ['1001'] = { leftcol = 0, topline = 0, topfill = -1, width = 0, height = 0, skipcol = 0 }, }, eval('g:v_event')) feed('2<C-E>') eq({ - all = {leftcol = 0, topline = 2, topfill = 2, width = 0, height = 0, skipcol = 0}, - ['1000'] = {leftcol = 0, topline = 2, topfill = 0, width = 0, height = 0, skipcol = 0}, - ['1001'] = {leftcol = 0, topline = 0, topfill = -2, width = 0, height = 0, skipcol = 0}, + all = { leftcol = 0, topline = 2, topfill = 2, width = 0, height = 0, skipcol = 0 }, + ['1000'] = { leftcol = 0, topline = 2, topfill = 0, width = 0, height = 0, skipcol = 0 }, + ['1001'] = { leftcol = 0, topline = 0, topfill = -2, width = 0, height = 0, skipcol = 0 }, }, eval('g:v_event')) feed('<C-E>') eq({ - all = {leftcol = 0, topline = 2, topfill = 0, width = 0, height = 0, skipcol = 0}, - ['1000'] = {leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0}, - ['1001'] = {leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0}, + all = { leftcol = 0, topline = 2, topfill = 0, width = 0, height = 0, skipcol = 0 }, + ['1000'] = { leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0 }, + ['1001'] = { leftcol = 0, topline = 1, topfill = 0, width = 0, height = 0, skipcol = 0 }, }, eval('g:v_event')) feed('2<C-Y>') eq({ - all = {leftcol = 0, topline = 3, topfill = 1, width = 0, height = 0, skipcol = 0}, - ['1000'] = {leftcol = 0, topline = -2, topfill = 0, width = 0, height = 0, skipcol = 0}, - ['1001'] = {leftcol = 0, topline = -1, topfill = 1, width = 0, height = 0, skipcol = 0}, + all = { leftcol = 0, topline = 3, topfill = 1, width = 0, height = 0, skipcol = 0 }, + ['1000'] = { leftcol = 0, topline = -2, topfill = 0, width = 0, height = 0, skipcol = 0 }, + ['1001'] = { leftcol = 0, topline = -1, topfill = 1, width = 0, height = 0, skipcol = 0 }, }, eval('g:v_event')) end) @@ -296,35 +313,41 @@ describe('WinScrolled', function() ]]) eq(0, eval('g:scrolled')) - local buf = meths.create_buf(true, true) - meths.buf_set_lines(buf, 0, -1, false, {'@', 'b', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'}) - local win = meths.open_win(buf, false, { + local buf = api.nvim_create_buf(true, true) + api.nvim_buf_set_lines( + buf, + 0, + -1, + false, + { '@', 'b', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n' } + ) + local win = api.nvim_open_win(buf, false, { height = 5, width = 10, col = 0, row = 1, relative = 'editor', - style = 'minimal' + style = 'minimal', }) screen:expect({ any = '@' }) - local winid_str = tostring(win.id) + local winid_str = tostring(win) -- WinScrolled should not be triggered when creating a new floating window eq(0, eval('g:scrolled')) - meths.input_mouse('wheel', 'down', '', 0, 3, 3) + api.nvim_input_mouse('wheel', 'down', '', 0, 3, 3) eq(1, eval('g:scrolled')) eq(winid_str, eval('g:amatch')) eq({ - all = {leftcol = 0, topline = 3, topfill = 0, width = 0, height = 0, skipcol = 0}, - [winid_str] = {leftcol = 0, topline = 3, topfill = 0, width = 0, height = 0, skipcol = 0}, + all = { leftcol = 0, topline = 3, topfill = 0, width = 0, height = 0, skipcol = 0 }, + [winid_str] = { leftcol = 0, topline = 3, topfill = 0, width = 0, height = 0, skipcol = 0 }, }, eval('g:v_event')) - meths.input_mouse('wheel', 'up', '', 0, 3, 3) + api.nvim_input_mouse('wheel', 'up', '', 0, 3, 3) eq(2, eval('g:scrolled')) - eq(tostring(win.id), eval('g:amatch')) + eq(tostring(win), eval('g:amatch')) eq({ - all = {leftcol = 0, topline = 3, topfill = 0, width = 0, height = 0, skipcol = 0}, - [winid_str] = {leftcol = 0, topline = -3, topfill = 0, width = 0, height = 0, skipcol = 0}, + all = { leftcol = 0, topline = 3, topfill = 0, width = 0, height = 0, skipcol = 0 }, + [winid_str] = { leftcol = 0, topline = -3, topfill = 0, width = 0, height = 0, skipcol = 0 }, }, eval('g:v_event')) end) end) diff --git a/test/functional/core/channels_spec.lua b/test/functional/core/channels_spec.lua index 5771ddcb94..56a2f5a571 100644 --- a/test/functional/core/channels_spec.lua +++ b/test/functional/core/channels_spec.lua @@ -1,10 +1,10 @@ local helpers = require('test.functional.helpers')(after_each) -local clear, eq, eval, next_msg, ok, source = helpers.clear, helpers.eq, - helpers.eval, helpers.next_msg, helpers.ok, helpers.source -local command, funcs, meths = helpers.command, helpers.funcs, helpers.meths -local sleep = helpers.sleep +local clear, eq, eval, next_msg, ok, source = + helpers.clear, helpers.eq, helpers.eval, helpers.next_msg, helpers.ok, helpers.source +local command, fn, api = helpers.command, helpers.fn, helpers.api +local sleep = vim.uv.sleep local spawn, nvim_argv = helpers.spawn, helpers.nvim_argv -local set_session = helpers.set_session +local get_session, set_session = helpers.get_session, helpers.set_session local nvim_prog = helpers.nvim_prog local is_os = helpers.is_os local retry = helpers.retry @@ -33,31 +33,67 @@ describe('channels', function() pending('can connect to socket', function() local server = spawn(nvim_argv, nil, nil, true) set_session(server) - local address = funcs.serverlist()[1] + local address = fn.serverlist()[1] local client = spawn(nvim_argv, nil, nil, true) set_session(client) source(init) - meths.set_var('address', address) + api.nvim_set_var('address', address) command("let g:id = sockconnect('pipe', address, {'on_data':'OnEvent'})") - local id = eval("g:id") + local id = eval('g:id') ok(id > 0) command("call chansend(g:id, msgpackdump([[2,'nvim_set_var',['code',23]]]))") set_session(server) retry(nil, 1000, function() - eq(23, meths.get_var('code')) + eq(23, api.nvim_get_var('code')) end) set_session(client) command("call chansend(g:id, msgpackdump([[0,0,'nvim_eval',['2+3']]]))") - - local res = eval("msgpackdump([[1,0,v:null,5]])") - eq({"\148\001\n\192\005"}, res) - eq({'notification', 'data', {id, res}}, next_msg()) + local res = eval('msgpackdump([[1,0,v:null,5]])') + eq({ '\148\001\n\192\005' }, res) + eq({ 'notification', 'data', { id, res } }, next_msg()) command("call chansend(g:id, msgpackdump([[2,'nvim_command',['quit']]]))") - eq({'notification', 'data', {id, {''}}}, next_msg()) + eq({ 'notification', 'data', { id, { '' } } }, next_msg()) + end) + + it('dont crash due to garbage in rpc #23781', function() + local client = get_session() + local server = spawn(nvim_argv, nil, nil, true) + set_session(server) + local address = fn.serverlist()[1] + set_session(client) + + api.nvim_set_var('address', address) + command("let g:id = sockconnect('pipe', address, {'on_data':'OnEvent'})") + local id = eval('g:id') + ok(id > 0) + + command("call chansend(g:id, 'F')") + eq({ 'notification', 'data', { id, { '' } } }, next_msg()) + set_session(server) + assert_alive() + + set_session(client) + command('call chanclose(g:id)') + command("let g:id = sockconnect('pipe', address, {'on_data':'OnEvent'})") + id = eval('g:id') + ok(id > 0) + + command("call chansend(g:id, msgpackdump([[2, 'redraw', 'F']], 'B')[:-4])") + set_session(server) + assert_alive() + set_session(client) + command("call chansend(g:id, 'F')") + eq({ 'notification', 'data', { id, { '' } } }, next_msg()) + + set_session(server) + assert_alive() + set_session(client) + command('call chanclose(g:id)') + server:close() end) it('can use stdio channel', function() @@ -68,8 +104,10 @@ describe('channels', function() \ 'on_exit': function('OnEvent'), \ } ]]) - meths.set_var("nvim_prog", nvim_prog) - meths.set_var("code", [[ + api.nvim_set_var('nvim_prog', nvim_prog) + api.nvim_set_var( + 'code', + [[ function! OnEvent(id, data, event) dict let text = string([a:id, a:data, a:event]) call chansend(g:x, text) @@ -81,25 +119,31 @@ describe('channels', function() endfunction let g:x = stdioopen({'on_stdin':'OnEvent'}) call chansend(x, "hello") - ]]) - command("let g:id = jobstart([ g:nvim_prog, '-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--headless', '--cmd', g:code], g:job_opts)") - local id = eval("g:id") + ]] + ) + command( + "let g:id = jobstart([ g:nvim_prog, '-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--headless', '--cmd', g:code], g:job_opts)" + ) + local id = eval('g:id') ok(id > 0) - eq({ "notification", "stdout", {id, { "hello" } } }, next_msg()) + eq({ 'notification', 'stdout', { id, { 'hello' } } }, next_msg()) command("call chansend(id, 'howdy')") - eq({"notification", "stdout", {id, {"[1, ['howdy'], 'stdin']"}}}, next_msg()) + eq({ 'notification', 'stdout', { id, { "[1, ['howdy'], 'stdin']" } } }, next_msg()) - command("call chansend(id, 0z686f6c61)") - eq({"notification", "stdout", {id, {"[1, ['hola'], 'stdin']"}}}, next_msg()) + command('call chansend(id, 0z686f6c61)') + eq({ 'notification', 'stdout', { id, { "[1, ['hola'], 'stdin']" } } }, next_msg()) command("call chanclose(id, 'stdin')") - expect_twostreams({{"notification", "stdout", {id, {"[1, [''], 'stdin']"}}}, - {'notification', 'stdout', {id, {''}}}}, - {{"notification", "stderr", {id, {"*dies*"}}}, - {'notification', 'stderr', {id, {''}}}}) - eq({"notification", "exit", {3,0}}, next_msg()) + expect_twostreams({ + { 'notification', 'stdout', { id, { "[1, [''], 'stdin']" } } }, + { 'notification', 'stdout', { id, { '' } } }, + }, { + { 'notification', 'stderr', { id, { '*dies*' } } }, + { 'notification', 'stderr', { id, { '' } } }, + }) + eq({ 'notification', 'exit', { 3, 0 } }, next_msg()) end) it('can use stdio channel and on_print callback', function() @@ -110,8 +154,10 @@ describe('channels', function() \ 'on_exit': function('OnEvent'), \ } ]]) - meths.set_var("nvim_prog", nvim_prog) - meths.set_var("code", [[ + api.nvim_set_var('nvim_prog', nvim_prog) + api.nvim_set_var( + 'code', + [[ function! OnStdin(id, data, event) dict echo string([a:id, a:data, a:event]) if a:data == [''] @@ -123,24 +169,27 @@ describe('channels', function() endfunction let g:x = stdioopen({'on_stdin': funcref('OnStdin'), 'on_print':'OnPrint'}) call chansend(x, "hello") - ]]) - command("let g:id = jobstart([ g:nvim_prog, '-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--headless', '--cmd', g:code], g:job_opts)") - local id = eval("g:id") + ]] + ) + command( + "let g:id = jobstart([ g:nvim_prog, '-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--headless', '--cmd', g:code], g:job_opts)" + ) + local id = eval('g:id') ok(id > 0) - eq({ "notification", "stdout", {id, { "hello" } } }, next_msg()) + eq({ 'notification', 'stdout', { id, { 'hello' } } }, next_msg()) command("call chansend(id, 'howdy')") - eq({"notification", "stdout", {id, {"OnPrint:[1, ['howdy'], 'stdin']"}}}, next_msg()) + eq({ 'notification', 'stdout', { id, { "OnPrint:[1, ['howdy'], 'stdin']" } } }, next_msg()) end) local function expect_twoline(id, stream, line1, line2, nobr) local msg = next_msg() - local joined = nobr and {line1..line2} or {line1, line2} - if not pcall(eq, {"notification", stream, {id, joined}}, msg) then - local sep = (not nobr) and "" or nil - eq({"notification", stream, {id, {line1, sep}}}, msg) - eq({"notification", stream, {id, {line2}}}, next_msg()) + local joined = nobr and { line1 .. line2 } or { line1, line2 } + if not pcall(eq, { 'notification', stream, { id, joined } }, msg) then + local sep = (not nobr) and '' or nil + eq({ 'notification', stream, { id, { line1, sep } } }, msg) + eq({ 'notification', stream, { id, { line2 } } }, next_msg()) end end @@ -153,50 +202,52 @@ describe('channels', function() \ 'pty': v:true, \ } ]]) - meths.set_var("nvim_prog", nvim_prog) - meths.set_var("code", [[ + api.nvim_set_var('nvim_prog', nvim_prog) + api.nvim_set_var( + 'code', + [[ function! OnEvent(id, data, event) dict let text = string([a:id, a:data, a:event]) call chansend(g:x, text) endfunction let g:x = stdioopen({'on_stdin':'OnEvent'}) - ]]) - command("let g:id = jobstart([ g:nvim_prog, '-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--headless', '--cmd', g:code], g:job_opts)") - local id = eval("g:id") + ]] + ) + command( + "let g:id = jobstart([ g:nvim_prog, '-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--headless', '--cmd', g:code], g:job_opts)" + ) + local id = eval('g:id') ok(id > 0) command("call chansend(id, 'TEXT\n')") - expect_twoline(id, "stdout", "TEXT\r", "[1, ['TEXT', ''], 'stdin']") + expect_twoline(id, 'stdout', 'TEXT\r', "[1, ['TEXT', ''], 'stdin']") - command("call chansend(id, 0z426c6f6273210a)") - expect_twoline(id, "stdout", "Blobs!\r", "[1, ['Blobs!', ''], 'stdin']") + command('call chansend(id, 0z426c6f6273210a)') + expect_twoline(id, 'stdout', 'Blobs!\r', "[1, ['Blobs!', ''], 'stdin']") command("call chansend(id, 'neovan')") - eq({"notification", "stdout", {id, {"neovan"}}}, next_msg()) + eq({ 'notification', 'stdout', { id, { 'neovan' } } }, next_msg()) command("call chansend(id, '\127\127im\n')") - expect_twoline(id, "stdout", "\b \b\b \bim\r", "[1, ['neovim', ''], 'stdin']") + expect_twoline(id, 'stdout', '\b \b\b \bim\r', "[1, ['neovim', ''], 'stdin']") command("call chansend(id, 'incomplet\004')") local bsdlike = is_os('bsd') or is_os('mac') - local extra = bsdlike and "^D\008\008" or "" - expect_twoline(id, "stdout", - "incomplet"..extra, "[1, ['incomplet'], 'stdin']", true) - + local extra = bsdlike and '^D\008\008' or '' + expect_twoline(id, 'stdout', 'incomplet' .. extra, "[1, ['incomplet'], 'stdin']", true) command("call chansend(id, '\004')") if bsdlike then - expect_twoline(id, "stdout", extra, "[1, [''], 'stdin']", true) + expect_twoline(id, 'stdout', extra, "[1, [''], 'stdin']", true) else - eq({"notification", "stdout", {id, {"[1, [''], 'stdin']"}}}, next_msg()) + eq({ 'notification', 'stdout', { id, { "[1, [''], 'stdin']" } } }, next_msg()) end -- channel is still open command("call chansend(id, 'hi again!\n')") - eq({"notification", "stdout", {id, {"hi again!\r", ""}}}, next_msg()) + eq({ 'notification', 'stdout', { id, { 'hi again!\r', '' } } }, next_msg()) end) - it('stdio channel can use rpc and stderr simultaneously', function() skip(is_os('win')) source([[ @@ -206,31 +257,37 @@ describe('channels', function() \ 'rpc': v:true, \ } ]]) - meths.set_var("nvim_prog", nvim_prog) - meths.set_var("code", [[ + api.nvim_set_var('nvim_prog', nvim_prog) + api.nvim_set_var( + 'code', + [[ let id = stdioopen({'rpc':v:true}) call rpcnotify(id,"nvim_call_function", "rpcnotify", [1, "message", "hi there!", id]) call chansend(v:stderr, "trouble!") - ]]) - command("let id = jobstart([ g:nvim_prog, '-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--headless', '--cmd', g:code], g:job_opts)") - eq({"notification", "message", {"hi there!", 1}}, next_msg()) - eq({"notification", "stderr", {3, {"trouble!"}}}, next_msg()) + ]] + ) + command( + "let id = jobstart([ g:nvim_prog, '-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--headless', '--cmd', g:code], g:job_opts)" + ) + eq({ 'notification', 'message', { 'hi there!', 1 } }, next_msg()) + eq({ 'notification', 'stderr', { 3, { 'trouble!' } } }, next_msg()) eq(30, eval("rpcrequest(id, 'nvim_eval', '[chansend(v:stderr, \"math??\"), 5*6][1]')")) - eq({"notification", "stderr", {3, {"math??"}}}, next_msg()) + eq({ 'notification', 'stderr', { 3, { 'math??' } } }, next_msg()) - local _, err = pcall(command,"call rpcrequest(id, 'nvim_command', 'call chanclose(v:stderr, \"stdin\")')") - ok(string.find(err,"E906: invalid stream for channel") ~= nil) + local _, err = + pcall(command, "call rpcrequest(id, 'nvim_command', 'call chanclose(v:stderr, \"stdin\")')") + ok(string.find(err, 'E906: invalid stream for channel') ~= nil) eq(1, eval("rpcrequest(id, 'nvim_eval', 'chanclose(v:stderr, \"stderr\")')")) - eq({"notification", "stderr", {3, {""}}}, next_msg()) + eq({ 'notification', 'stderr', { 3, { '' } } }, next_msg()) command("call rpcnotify(id, 'nvim_command', 'quit')") - eq({"notification", "exit", {3, 0}}, next_msg()) + eq({ 'notification', 'exit', { 3, 0 } }, next_msg()) end) it('can use buffered output mode', function() - skip(funcs.executable('grep') == 0, 'missing "grep" command') + skip(fn.executable('grep') == 0, 'missing "grep" command') source([[ let g:job_opts = { \ 'on_stdout': function('OnEvent'), @@ -239,31 +296,33 @@ describe('channels', function() \ } ]]) command("let id = jobstart(['grep', '^[0-9]'], g:job_opts)") - local id = eval("g:id") + local id = eval('g:id') command([[call chansend(id, "stuff\n10 PRINT \"NVIM\"\nxx")]]) sleep(10) command([[call chansend(id, "xx\n20 GOTO 10\nzz\n")]]) command("call chanclose(id, 'stdin')") - eq({"notification", "stdout", {id, {'10 PRINT "NVIM"', - '20 GOTO 10', ''}}}, next_msg()) - eq({"notification", "exit", {id, 0}}, next_msg()) + eq({ + 'notification', + 'stdout', + { id, { '10 PRINT "NVIM"', '20 GOTO 10', '' } }, + }, next_msg()) + eq({ 'notification', 'exit', { id, 0 } }, next_msg()) command("let id = jobstart(['grep', '^[0-9]'], g:job_opts)") - id = eval("g:id") + id = eval('g:id') command([[call chansend(id, "is no number\nnot at all")]]) command("call chanclose(id, 'stdin')") -- works correctly with no output - eq({"notification", "stdout", {id, {''}}}, next_msg()) - eq({"notification", "exit", {id, 1}}, next_msg()) - + eq({ 'notification', 'stdout', { id, { '' } } }, next_msg()) + eq({ 'notification', 'exit', { id, 1 } }, next_msg()) end) it('can use buffered output mode with no stream callback', function() - skip(funcs.executable('grep') == 0, 'missing "grep" command') + skip(fn.executable('grep') == 0, 'missing "grep" command') source([[ function! OnEvent(id, data, event) dict call rpcnotify(1, a:event, a:id, a:data, self.stdout) @@ -274,31 +333,40 @@ describe('channels', function() \ } ]]) command("let id = jobstart(['grep', '^[0-9]'], g:job_opts)") - local id = eval("g:id") + local id = eval('g:id') command([[call chansend(id, "stuff\n10 PRINT \"NVIM\"\nxx")]]) sleep(10) command([[call chansend(id, "xx\n20 GOTO 10\nzz\n")]]) command("call chanclose(id, 'stdin')") - eq({"notification", "exit", {id, 0, {'10 PRINT "NVIM"', - '20 GOTO 10', ''}}}, next_msg()) + eq({ + 'notification', + 'exit', + { id, 0, { '10 PRINT "NVIM"', '20 GOTO 10', '' } }, + }, next_msg()) -- if dict is reused the new value is not stored, -- but nvim also does not crash command("let id = jobstart(['cat'], g:job_opts)") - id = eval("g:id") + id = eval('g:id') command([[call chansend(id, "cat text\n")]]) sleep(10) command("call chanclose(id, 'stdin')") -- old value was not overwritten - eq({"notification", "exit", {id, 0, {'10 PRINT "NVIM"', - '20 GOTO 10', ''}}}, next_msg()) + eq({ + 'notification', + 'exit', + { id, 0, { '10 PRINT "NVIM"', '20 GOTO 10', '' } }, + }, next_msg()) -- and an error was thrown. - eq("E5210: dict key 'stdout' already set for buffered stream in channel "..id, eval('v:errmsg')) + eq( + "E5210: dict key 'stdout' already set for buffered stream in channel " .. id, + eval('v:errmsg') + ) -- reset dictionary source([[ @@ -308,13 +376,13 @@ describe('channels', function() \ } ]]) command("let id = jobstart(['grep', '^[0-9]'], g:job_opts)") - id = eval("g:id") + id = eval('g:id') command([[call chansend(id, "is no number\nnot at all")]]) command("call chanclose(id, 'stdin')") -- works correctly with no output - eq({"notification", "exit", {id, 1, {''}}}, next_msg()) + eq({ 'notification', 'exit', { id, 1, { '' } } }, next_msg()) end) end) @@ -325,8 +393,10 @@ describe('loopback', function() end) it('does not crash when sending raw data', function() - eq("Vim(call):Can't send raw data to rpc channel", - pcall_err(command, "call chansend(chan, 'test')")) + eq( + "Vim(call):Can't send raw data to rpc channel", + pcall_err(command, "call chansend(chan, 'test')") + ) assert_alive() end) diff --git a/test/functional/core/exit_spec.lua b/test/functional/core/exit_spec.lua index d474b77806..d9e3cc3f31 100644 --- a/test/functional/core/exit_spec.lua +++ b/test/functional/core/exit_spec.lua @@ -7,7 +7,7 @@ local feed = helpers.feed local eval = helpers.eval local eq = helpers.eq local run = helpers.run -local funcs = helpers.funcs +local fn = helpers.fn local nvim_prog = helpers.nvim_prog local pcall_err = helpers.pcall_err local exec_capture = helpers.exec_capture @@ -18,7 +18,7 @@ describe('v:exiting', function() before_each(function() helpers.clear() - cid = helpers.nvim('get_api_info')[1] + cid = helpers.api.nvim_get_chan_info(0).id end) it('defaults to v:null', function() @@ -27,8 +27,8 @@ describe('v:exiting', function() local function test_exiting(setup_fn) local function on_setup() - command('autocmd VimLeavePre * call rpcrequest('..cid..', "exit", "VimLeavePre")') - command('autocmd VimLeave * call rpcrequest('..cid..', "exit", "VimLeave")') + command('autocmd VimLeavePre * call rpcrequest(' .. cid .. ', "exit", "VimLeavePre")') + command('autocmd VimLeave * call rpcrequest(' .. cid .. ', "exit", "VimLeave")') setup_fn() end local requests_args = {} @@ -39,7 +39,7 @@ describe('v:exiting', function() return '' end run(on_request, nil, on_setup) - eq({{'VimLeavePre'}, {'VimLeave'}}, requests_args) + eq({ { 'VimLeavePre' }, { 'VimLeave' } }, requests_args) end it('is 0 on normal exit', function() @@ -59,11 +59,16 @@ end) describe(':cquit', function() local function test_cq(cmdline, exit_code, redir_msg) if redir_msg then - eq(redir_msg, pcall_err(function() return exec_capture(cmdline) end)) + eq( + redir_msg, + pcall_err(function() + return exec_capture(cmdline) + end) + ) poke_eventloop() assert_alive() else - funcs.system({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless', '--cmd', cmdline}) + fn.system({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless', '--cmd', cmdline }) eq(exit_code, eval('v:shell_error')) end end diff --git a/test/functional/core/fileio_spec.lua b/test/functional/core/fileio_spec.lua index 65f947132e..928cab525c 100644 --- a/test/functional/core/fileio_spec.lua +++ b/test/functional/core/fileio_spec.lua @@ -1,4 +1,4 @@ -local luv = require('luv') +local uv = vim.uv local helpers = require('test.functional.helpers')(after_each) local assert_log = helpers.assert_log @@ -9,18 +9,18 @@ local eq = helpers.eq local neq = helpers.neq local ok = helpers.ok local feed = helpers.feed -local funcs = helpers.funcs +local fn = helpers.fn local nvim_prog = helpers.nvim_prog local request = helpers.request local retry = helpers.retry local rmdir = helpers.rmdir local matches = helpers.matches -local meths = helpers.meths +local api = helpers.api local mkdir = helpers.mkdir -local sleep = helpers.sleep +local sleep = vim.uv.sleep local read_file = helpers.read_file -local trim = helpers.trim -local currentdir = helpers.funcs.getcwd +local trim = vim.trim +local currentdir = helpers.fn.getcwd local assert_alive = helpers.assert_alive local check_close = helpers.check_close local expect_exit = helpers.expect_exit @@ -30,10 +30,11 @@ local feed_command = helpers.feed_command local skip = helpers.skip local is_os = helpers.is_os local is_ci = helpers.is_ci +local spawn = helpers.spawn +local set_session = helpers.set_session describe('fileio', function() - before_each(function() - end) + before_each(function() end) after_each(function() check_close() os.remove('Xtest_startup_shada') @@ -49,54 +50,91 @@ describe('fileio', function() rmdir('Xtest_backupdir with spaces') end) - it('fsync() codepaths #8304', function() - clear({ args={ '-i', 'Xtest_startup_shada', - '--cmd', 'set nofsync', - '--cmd', 'set directory=Xtest_startup_swapdir' } }) + local args = { nvim_prog, '--clean', '--cmd', 'set nofsync directory=Xtest_startup_swapdir' } + --- Starts a new nvim session and returns an attached screen. + local function startup(extra_args) + extra_args = extra_args or {} + local argv = vim.tbl_flatten({ args, '--embed', extra_args }) + local screen_nvim = spawn(argv) + set_session(screen_nvim) + local screen = Screen.new(70, 10) + screen:attach() + screen:set_default_attr_ids({ + [1] = { foreground = Screen.colors.NvimDarkGrey4 }, + [2] = { background = Screen.colors.NvimDarkGrey1, foreground = Screen.colors.NvimLightGrey3 }, + [3] = { foreground = Screen.colors.NvimLightCyan }, + }) + return screen + end + + it("fsync() with 'nofsync' #8304", function() + clear({ args = { '--cmd', 'set nofsync directory=Xtest_startup_swapdir' } }) -- These cases ALWAYS force fsync (regardless of 'fsync' option): -- 1. Idle (CursorHold) with modified buffers (+ 'swapfile'). command('write Xtest_startup_file1') - feed('ifoo<esc>h') + feed('Afoo<esc>h') command('write') - eq(0, request('nvim__stats').fsync) -- 'nofsync' is the default. + eq(0, request('nvim__stats').fsync) command('set swapfile') command('set updatetime=1') - feed('izub<esc>h') -- File is 'modified'. - sleep(3) -- Allow 'updatetime' to expire. + feed('Azub<esc>h') -- File is 'modified'. + sleep(3) -- Allow 'updatetime' to expire. retry(3, nil, function() eq(1, request('nvim__stats').fsync) end) - command('set updatetime=9999') + command('set updatetime=100000 updatecount=100000') - -- 2. Exit caused by deadly signal (+ 'swapfile'). - local j = funcs.jobstart({ nvim_prog, '-u', 'NONE', '-i', - 'Xtest_startup_shada', '--headless', - '-c', 'set swapfile', - '-c', 'write Xtest_startup_file2', - '-c', 'put =localtime()', }) - sleep(10) -- Let Nvim start. - funcs.jobstop(j) -- Send deadly signal. - - -- 3. SIGPWR signal. - -- ?? - - -- 4. Explicit :preserve command. + -- 2. Explicit :preserve command. command('preserve') - eq(2, request('nvim__stats').fsync) + -- TODO: should be exactly 2; where is the extra fsync() is coming from? #26404 + ok(request('nvim__stats').fsync == 2 or request('nvim__stats').fsync == 3) - -- 5. Enable 'fsync' option, write file. + -- 3. Enable 'fsync' option, write file. command('set fsync') - feed('ibaz<esc>h') + feed('Abaz<esc>h') command('write') - eq(4, request('nvim__stats').fsync) + -- TODO: should be exactly 4; where is the extra fsync() is coming from? #26404 + ok(request('nvim__stats').fsync == 4 or request('nvim__stats').fsync == 5) + eq('foozubbaz', trim(read_file('Xtest_startup_file1'))) + + -- 4. Exit caused by deadly signal (+ 'swapfile'). + local j = fn.jobstart(vim.tbl_flatten({ args, '--embed' }), { rpc = true }) + fn.rpcrequest( + j, + 'nvim_exec2', + [[ + set nofsync directory=Xtest_startup_swapdir + edit Xtest_startup_file2 + write + put ='fsyncd text' + ]], + {} + ) + eq('Xtest_startup_swapdir', fn.rpcrequest(j, 'nvim_eval', '&directory')) + fn.jobstop(j) -- Send deadly signal. + + local screen = startup() + feed(':recover Xtest_startup_file2<cr>') + screen:expect({ any = [[Using swap file "Xtest_startup_swapdir[/\]Xtest_startup_file2%.swp"]] }) + feed('<cr>') + screen:expect({ any = 'fsyncd text' }) + + -- 5. SIGPWR signal. + -- oldtest: Test_signal_PWR() end) it('backup #9709', function() skip(is_ci('cirrus')) - clear({ args={ '-i', 'Xtest_startup_shada', - '--cmd', 'set directory=Xtest_startup_swapdir' } }) + clear({ + args = { + '-i', + 'Xtest_startup_shada', + '--cmd', + 'set directory=Xtest_startup_swapdir', + }, + }) command('write Xtest_startup_file1') feed('ifoo<esc>') @@ -109,8 +147,8 @@ describe('fileio', function() local foobar_contents = trim(read_file('Xtest_startup_file1')) local bar_contents = trim(read_file('Xtest_startup_file1~')) - eq('foobar', foobar_contents); - eq('foo', bar_contents); + eq('foobar', foobar_contents) + eq('foo', bar_contents) end) it('backup with full path #11214', function() @@ -126,13 +164,16 @@ describe('fileio', function() command('write') -- Backup filename = fullpath, separators replaced with "%". - local backup_file_name = string.gsub(currentdir()..'/Xtest_startup_file1', - is_os('win') and '[:/\\]' or '/', '%%') .. '~' - local foo_contents = trim(read_file('Xtest_backupdir/'..backup_file_name)) + local backup_file_name = string.gsub( + currentdir() .. '/Xtest_startup_file1', + is_os('win') and '[:/\\]' or '/', + '%%' + ) .. '~' + local foo_contents = trim(read_file('Xtest_backupdir/' .. backup_file_name)) local foobar_contents = trim(read_file('Xtest_startup_file1')) - eq('foobar', foobar_contents); - eq('foo', foo_contents); + eq('foobar', foobar_contents) + eq('foo', foo_contents) end) it('backup with full path with spaces', function() @@ -148,13 +189,16 @@ describe('fileio', function() command('write') -- Backup filename = fullpath, separators replaced with "%". - local backup_file_name = string.gsub(currentdir()..'/Xtest_startup_file1', - is_os('win') and '[:/\\]' or '/', '%%') .. '~' - local foo_contents = trim(read_file('Xtest_backupdir with spaces/'..backup_file_name)) + local backup_file_name = string.gsub( + currentdir() .. '/Xtest_startup_file1', + is_os('win') and '[:/\\]' or '/', + '%%' + ) .. '~' + local foo_contents = trim(read_file('Xtest_backupdir with spaces/' .. backup_file_name)) local foobar_contents = trim(read_file('Xtest_startup_file1')) - eq('foobar', foobar_contents); - eq('foo', foo_contents); + eq('foobar', foobar_contents) + eq('foo', foo_contents) end) it('backup symlinked files #11349', function() @@ -166,7 +210,7 @@ describe('fileio', function() local backup_file_name = link_file_name .. '~' write_file('Xtest_startup_file1', initial_content, false) - luv.fs_symlink('Xtest_startup_file1', link_file_name) + uv.fs_symlink('Xtest_startup_file1', link_file_name) command('set backup') command('set backupcopy=yes') command('edit ' .. link_file_name) @@ -174,11 +218,10 @@ describe('fileio', function() command('write') local backup_raw = read_file(backup_file_name) - neq(nil, backup_raw, "Expected backup file " .. backup_file_name .. "to exist but did not") + neq(nil, backup_raw, 'Expected backup file ' .. backup_file_name .. 'to exist but did not') eq(initial_content, trim(backup_raw), 'Expected backup to contain original contents') end) - it('backup symlinked files in first available backupdir #11349', function() skip(is_ci('cirrus')) clear() @@ -190,7 +233,7 @@ describe('fileio', function() local backup_file_name = backup_dir .. sep .. link_file_name .. '~' write_file('Xtest_startup_file1', initial_content, false) - luv.fs_symlink('Xtest_startup_file1', link_file_name) + uv.fs_symlink('Xtest_startup_file1', link_file_name) mkdir(backup_dir) command('set backup') command('set backupcopy=yes') @@ -200,7 +243,7 @@ describe('fileio', function() command('write') local backup_raw = read_file(backup_file_name) - neq(nil, backup_raw, "Expected backup file " .. backup_file_name .. " to exist but did not") + neq(nil, backup_raw, 'Expected backup file ' .. backup_file_name .. ' to exist but did not') eq(initial_content, trim(backup_raw), 'Expected backup to contain original contents') end) @@ -215,11 +258,11 @@ describe('fileio', function() '', } local fname = 'Xtest_тест.md' - funcs.writefile(text, fname, 's') + fn.writefile(text, fname, 's') table.insert(text, '') - eq(text, funcs.readfile(fname, 'b')) + eq(text, fn.readfile(fname, 'b')) end) - it('read invalid u8 over INT_MAX doesn\'t segfault', function() + it("read invalid u8 over INT_MAX doesn't segfault", function() clear() command('call writefile(0zFFFFFFFF, "Xtest-u8-int-max")') -- This should not segfault @@ -229,34 +272,32 @@ describe('fileio', function() it(':w! does not show "file has been changed" warning', function() clear() - write_file("Xtest-overwrite-forced", 'foobar') + write_file('Xtest-overwrite-forced', 'foobar') command('set nofixendofline') - local screen = Screen.new(40,4) + local screen = Screen.new(40, 4) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [3] = {bold = true, foreground = Screen.colors.SeaGreen4} + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [3] = { bold = true, foreground = Screen.colors.SeaGreen4 }, }) screen:attach() - command("set shortmess-=F") + command('set shortmess-=F') - command("e Xtest-overwrite-forced") + command('e Xtest-overwrite-forced') screen:expect([[ ^foobar | - {1:~ }| - {1:~ }| + {1:~ }|*2 "Xtest-overwrite-forced" [noeol] 1L, 6B | ]]) -- Get current unix time. - local cur_unix_time = os.time(os.date("!*t")) + local cur_unix_time = os.time(os.date('!*t')) local future_time = cur_unix_time + 999999 -- Set the file's access/update time to be -- greater than the time at which it was created. - local uv = require("luv") uv.fs_utime('Xtest-overwrite-forced', future_time, future_time) -- use async feed_command because nvim basically hangs on the prompt - feed_command("w") + feed_command('w') screen:expect([[ {2:WARNING: The file has been changed since}| {2: reading it!!!} | @@ -264,20 +305,18 @@ describe('fileio', function() ^ | ]]) - feed("n") - feed("<cr>") + feed('n') + feed('<cr>') screen:expect([[ ^foobar | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) -- Use a screen test because the warning does not set v:errmsg. - command("w!") + command('w!') screen:expect([[ ^foobar | - {1:~ }| - {1:~ }| + {1:~ }|*2 <erwrite-forced" [noeol] 1L, 6B written | ]]) end) @@ -302,13 +341,13 @@ describe('tmpdir', function() -- Tempfiles typically look like: "…/nvim.<user>/xxx/0". -- - "…/nvim.<user>/xxx/" is the per-process tmpdir, not shared with other Nvims. -- - "…/nvim.<user>/" is the tmpdir root, shared by all Nvims (normally). - local tmproot = (funcs.tempname()):match(tmproot_pat) + local tmproot = (fn.tempname()):match(tmproot_pat) ok(tmproot:len() > 4, 'tmproot like "nvim.foo"', tmproot) return tmproot end it('failure modes', function() - clear({ env={ NVIM_LOG_FILE=testlog, TMPDIR=os_tmpdir, } }) + clear({ env = { NVIM_LOG_FILE = testlog, TMPDIR = os_tmpdir } }) assert_nolog('tempdir is not a directory', testlog) assert_nolog('tempdir has invalid permissions', testlog) @@ -319,9 +358,9 @@ describe('tmpdir', function() -- "…/nvim.<user>/" is not a directory: expect_exit(command, ':qall!') rmdir(tmproot) - write_file(tmproot, '') -- Not a directory, vim_mktempdir() should skip it. - clear({ env={ NVIM_LOG_FILE=testlog, TMPDIR=os_tmpdir, } }) - matches(tmproot_pat, funcs.stdpath('run')) -- Tickle vim_mktempdir(). + write_file(tmproot, '') -- Not a directory, vim_mktempdir() should skip it. + clear({ env = { NVIM_LOG_FILE = testlog, TMPDIR = os_tmpdir } }) + matches(tmproot_pat, fn.stdpath('run')) -- Tickle vim_mktempdir(). -- Assert that broken tmpdir root was handled. assert_log('tempdir root not a directory', testlog, 100) @@ -330,9 +369,9 @@ describe('tmpdir', function() os.remove(testlog) os.remove(tmproot) mkdir(tmproot) - funcs.setfperm(tmproot, 'rwxr--r--') -- Invalid permissions, vim_mktempdir() should skip it. - clear({ env={ NVIM_LOG_FILE=testlog, TMPDIR=os_tmpdir, } }) - matches(tmproot_pat, funcs.stdpath('run')) -- Tickle vim_mktempdir(). + fn.setfperm(tmproot, 'rwxr--r--') -- Invalid permissions, vim_mktempdir() should skip it. + clear({ env = { NVIM_LOG_FILE = testlog, TMPDIR = os_tmpdir } }) + matches(tmproot_pat, fn.stdpath('run')) -- Tickle vim_mktempdir(). -- Assert that broken tmpdir root was handled. assert_log('tempdir root has invalid permissions', testlog, 100) end) @@ -340,53 +379,54 @@ describe('tmpdir', function() it('too long', function() local bigname = ('%s/%s'):format(os_tmpdir, ('x'):rep(666)) mkdir(bigname) - clear({ env={ NVIM_LOG_FILE=testlog, TMPDIR=bigname, } }) - matches(tmproot_pat, funcs.stdpath('run')) -- Tickle vim_mktempdir(). - local len = (funcs.tempname()):len() + clear({ env = { NVIM_LOG_FILE = testlog, TMPDIR = bigname } }) + matches(tmproot_pat, fn.stdpath('run')) -- Tickle vim_mktempdir(). + local len = (fn.tempname()):len() ok(len > 4 and len < 256, '4 < len < 256', tostring(len)) end) it('disappeared #1432', function() - clear({ env={ NVIM_LOG_FILE=testlog, TMPDIR=os_tmpdir, } }) + clear({ env = { NVIM_LOG_FILE = testlog, TMPDIR = os_tmpdir } }) assert_nolog('tempdir disappeared', testlog) local function rm_tmpdir() - local tmpname1 = funcs.tempname() - local tmpdir1 = funcs.fnamemodify(tmpname1, ':h') - eq(funcs.stdpath('run'), tmpdir1) + local tmpname1 = fn.tempname() + local tmpdir1 = fn.fnamemodify(tmpname1, ':h') + eq(fn.stdpath('run'), tmpdir1) rmdir(tmpdir1) retry(nil, 1000, function() - eq(0, funcs.isdirectory(tmpdir1)) + eq(0, fn.isdirectory(tmpdir1)) end) - local tmpname2 = funcs.tempname() - local tmpdir2 = funcs.fnamemodify(tmpname2, ':h') + local tmpname2 = fn.tempname() + local tmpdir2 = fn.fnamemodify(tmpname2, ':h') neq(tmpdir1, tmpdir2) end -- Your antivirus hates you... rm_tmpdir() assert_log('tempdir disappeared', testlog, 100) - funcs.tempname() - funcs.tempname() - funcs.tempname() - eq('', meths.get_vvar('errmsg')) + fn.tempname() + fn.tempname() + fn.tempname() + eq('', api.nvim_get_vvar('errmsg')) rm_tmpdir() - funcs.tempname() - funcs.tempname() - funcs.tempname() - eq('E5431: tempdir disappeared (2 times)', meths.get_vvar('errmsg')) + fn.tempname() + fn.tempname() + fn.tempname() + eq('E5431: tempdir disappeared (2 times)', api.nvim_get_vvar('errmsg')) rm_tmpdir() - eq('E5431: tempdir disappeared (3 times)', meths.get_vvar('errmsg')) + eq('E5431: tempdir disappeared (3 times)', api.nvim_get_vvar('errmsg')) end) it('$NVIM_APPNAME relative path', function() - clear({ env={ - NVIM_APPNAME='a/b', - NVIM_LOG_FILE=testlog, - TMPDIR=os_tmpdir, - } }) - matches([=[.*[/\\]a%%b%.[^/\\]+]=], funcs.tempname()) + clear({ + env = { + NVIM_APPNAME = 'a/b', + NVIM_LOG_FILE = testlog, + TMPDIR = os_tmpdir, + }, + }) + matches([=[.*[/\\]a%%b%.[^/\\]+]=], fn.tempname()) end) - end) diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua index 038368c387..13f5f9a5e1 100644 --- a/test/functional/core/job_spec.lua +++ b/test/functional/core/job_spec.lua @@ -1,17 +1,28 @@ local helpers = require('test.functional.helpers')(after_each) -local clear, eq, eval, exc_exec, feed_command, feed, insert, neq, next_msg, nvim, - testprg, ok, source, write_file, mkdir, rmdir = helpers.clear, - helpers.eq, helpers.eval, helpers.exc_exec, helpers.feed_command, helpers.feed, - helpers.insert, helpers.neq, helpers.next_msg, helpers.nvim, - helpers.testprg, helpers.ok, helpers.source, - helpers.write_file, helpers.mkdir, helpers.rmdir +local thelpers = require('test.functional.terminal.helpers') + +local clear = helpers.clear +local eq = helpers.eq +local eval = helpers.eval +local exc_exec = helpers.exc_exec +local feed_command = helpers.feed_command +local feed = helpers.feed +local insert = helpers.insert +local neq = helpers.neq +local next_msg = helpers.next_msg +local testprg = helpers.testprg +local ok = helpers.ok +local source = helpers.source +local write_file = helpers.write_file +local mkdir = helpers.mkdir +local rmdir = helpers.rmdir local assert_alive = helpers.assert_alive local command = helpers.command -local funcs = helpers.funcs +local fn = helpers.fn local os_kill = helpers.os_kill local retry = helpers.retry -local meths = helpers.meths -local NIL = helpers.NIL +local api = helpers.api +local NIL = vim.NIL local poke_eventloop = helpers.poke_eventloop local get_pathsep = helpers.get_pathsep local pathroot = helpers.pathroot @@ -31,8 +42,8 @@ describe('jobs', function() before_each(function() clear() - channel = nvim('get_api_info')[1] - nvim('set_var', 'channel', channel) + channel = api.nvim_get_chan_info(0).id + api.nvim_set_var('channel', channel) source([[ function! Normalize(data) abort " Windows: remove ^M and term escape sequences @@ -54,66 +65,60 @@ describe('jobs', function() end) it('must specify env option as a dict', function() - command("let g:job_opts.env = v:true") + command('let g:job_opts.env = v:true') local _, err = pcall(function() if is_os('win') then - nvim('command', "let j = jobstart('set', g:job_opts)") + command("let j = jobstart('set', g:job_opts)") else - nvim('command', "let j = jobstart('env', g:job_opts)") + command("let j = jobstart('env', g:job_opts)") end end) - ok(string.find(err, "E475: Invalid argument: env") ~= nil) + ok(string.find(err, 'E475: Invalid argument: env') ~= nil) end) it('append environment #env', function() - nvim('command', "let $VAR = 'abc'") - nvim('command', "let $TOTO = 'goodbye world'") - nvim('command', "let g:job_opts.env = {'TOTO': 'hello world'}") + command("let $VAR = 'abc'") + command("let $TOTO = 'goodbye world'") + command("let g:job_opts.env = {'TOTO': 'hello world'}") if is_os('win') then - nvim('command', [[call jobstart('echo %TOTO% %VAR%', g:job_opts)]]) + command([[call jobstart('echo %TOTO% %VAR%', g:job_opts)]]) else - nvim('command', [[call jobstart('echo $TOTO $VAR', g:job_opts)]]) + command([[call jobstart('echo $TOTO $VAR', g:job_opts)]]) end - expect_msg_seq( - { - {'notification', 'stdout', {0, {'hello world abc'}}}, - {'notification', 'stdout', {0, {'', ''}}}, - }, - { - {'notification', 'stdout', {0, {'hello world abc', ''}}}, - {'notification', 'stdout', {0, {''}}} - } - ) + expect_msg_seq({ + { 'notification', 'stdout', { 0, { 'hello world abc' } } }, + { 'notification', 'stdout', { 0, { '', '' } } }, + }, { + { 'notification', 'stdout', { 0, { 'hello world abc', '' } } }, + { 'notification', 'stdout', { 0, { '' } } }, + }) end) it('append environment with pty #env', function() - nvim('command', "let $VAR = 'abc'") - nvim('command', "let $TOTO = 'goodbye world'") - nvim('command', "let g:job_opts.pty = v:true") - nvim('command', "let g:job_opts.env = {'TOTO': 'hello world'}") + command("let $VAR = 'abc'") + command("let $TOTO = 'goodbye world'") + command('let g:job_opts.pty = v:true') + command("let g:job_opts.env = {'TOTO': 'hello world'}") if is_os('win') then - nvim('command', [[call jobstart('echo %TOTO% %VAR%', g:job_opts)]]) + command([[call jobstart('echo %TOTO% %VAR%', g:job_opts)]]) else - nvim('command', [[call jobstart('echo $TOTO $VAR', g:job_opts)]]) + command([[call jobstart('echo $TOTO $VAR', g:job_opts)]]) end - expect_msg_seq( - { - {'notification', 'stdout', {0, {'hello world abc'}}}, - {'notification', 'stdout', {0, {'', ''}}}, - }, - { - {'notification', 'stdout', {0, {'hello world abc', ''}}}, - {'notification', 'stdout', {0, {''}}} - } - ) + expect_msg_seq({ + { 'notification', 'stdout', { 0, { 'hello world abc' } } }, + { 'notification', 'stdout', { 0, { '', '' } } }, + }, { + { 'notification', 'stdout', { 0, { 'hello world abc', '' } } }, + { 'notification', 'stdout', { 0, { '' } } }, + }) end) it('replace environment #env', function() - nvim('command', "let $VAR = 'abc'") - nvim('command', "let $TOTO = 'goodbye world'") - nvim('command', "let g:job_opts.env = {'TOTO': 'hello world'}") - nvim('command', "let g:job_opts.clear_env = 1") + command("let $VAR = 'abc'") + command("let $TOTO = 'goodbye world'") + command("let g:job_opts.env = {'TOTO': 'hello world'}") + command('let g:job_opts.clear_env = 1') -- libuv ensures that certain "required" environment variables are -- preserved if the user doesn't provide them in a custom environment @@ -123,39 +128,39 @@ describe('jobs', function() -- Rather than expecting a completely empty environment, ensure that $VAR -- is *not* in the environment but $TOTO is. if is_os('win') then - nvim('command', [[call jobstart('echo %TOTO% %VAR%', g:job_opts)]]) + command([[call jobstart('echo %TOTO% %VAR%', g:job_opts)]]) expect_msg_seq({ - {'notification', 'stdout', {0, {'hello world %VAR%', ''}}} + { 'notification', 'stdout', { 0, { 'hello world %VAR%', '' } } }, }) else - nvim('command', "set shell=/bin/sh") - nvim('command', [[call jobstart('echo $TOTO $VAR', g:job_opts)]]) + command('set shell=/bin/sh') + command([[call jobstart('echo $TOTO $VAR', g:job_opts)]]) expect_msg_seq({ - {'notification', 'stdout', {0, {'hello world', ''}}} + { 'notification', 'stdout', { 0, { 'hello world', '' } } }, }) end end) it('handles case-insensitively matching #env vars', function() - nvim('command', "let $TOTO = 'abc'") + command("let $TOTO = 'abc'") -- Since $Toto is being set in the job, it should take precedence over the -- global $TOTO on Windows - nvim('command', "let g:job_opts = {'env': {'Toto': 'def'}, 'stdout_buffered': v:true}") + command("let g:job_opts = {'env': {'Toto': 'def'}, 'stdout_buffered': v:true}") if is_os('win') then - nvim('command', [[let j = jobstart('set | find /I "toto="', g:job_opts)]]) + command([[let j = jobstart('set | find /I "toto="', g:job_opts)]]) else - nvim('command', [[let j = jobstart('env | grep -i toto=', g:job_opts)]]) + command([[let j = jobstart('env | grep -i toto=', g:job_opts)]]) end - nvim('command', "call jobwait([j])") - nvim('command', "let g:output = Normalize(g:job_opts.stdout)") + command('call jobwait([j])') + command('let g:output = Normalize(g:job_opts.stdout)') local actual = eval('g:output') local expected if is_os('win') then -- Toto is normalized to TOTO so we can detect duplicates, and because -- Windows doesn't care about case - expected = {'TOTO=def', ''} + expected = { 'TOTO=def', '' } else - expected = {'TOTO=abc', 'Toto=def', ''} + expected = { 'TOTO=abc', 'Toto=def', '' } end table.sort(actual) table.sort(expected) @@ -163,49 +168,50 @@ describe('jobs', function() end) it('uses &shell and &shellcmdflag if passed a string', function() - nvim('command', "let $VAR = 'abc'") + command("let $VAR = 'abc'") if is_os('win') then - nvim('command', "let j = jobstart('echo %VAR%', g:job_opts)") + command("let j = jobstart('echo %VAR%', g:job_opts)") else - nvim('command', "let j = jobstart('echo $VAR', g:job_opts)") + command("let j = jobstart('echo $VAR', g:job_opts)") end - eq({'notification', 'stdout', {0, {'abc', ''}}}, next_msg()) - eq({'notification', 'stdout', {0, {''}}}, next_msg()) - eq({'notification', 'exit', {0, 0}}, next_msg()) + eq({ 'notification', 'stdout', { 0, { 'abc', '' } } }, next_msg()) + eq({ 'notification', 'stdout', { 0, { '' } } }, next_msg()) + eq({ 'notification', 'exit', { 0, 0 } }, next_msg()) end) it('changes to given / directory', function() - nvim('command', "let g:job_opts.cwd = '/'") + command("let g:job_opts.cwd = '/'") if is_os('win') then - nvim('command', "let j = jobstart('cd', g:job_opts)") + command("let j = jobstart('cd', g:job_opts)") else - nvim('command', "let j = jobstart('pwd', g:job_opts)") + command("let j = jobstart('pwd', g:job_opts)") end - eq({'notification', 'stdout', - {0, {pathroot(), ''}}}, next_msg()) - eq({'notification', 'stdout', {0, {''}}}, next_msg()) - eq({'notification', 'exit', {0, 0}}, next_msg()) + eq({ 'notification', 'stdout', { 0, { pathroot(), '' } } }, next_msg()) + eq({ 'notification', 'stdout', { 0, { '' } } }, next_msg()) + eq({ 'notification', 'exit', { 0, 0 } }, next_msg()) end) it('changes to given `cwd` directory', function() - local dir = eval("resolve(tempname())"):gsub("/", get_pathsep()) + local dir = eval('resolve(tempname())'):gsub('/', get_pathsep()) mkdir(dir) - nvim('command', "let g:job_opts.cwd = '" .. dir .. "'") + command("let g:job_opts.cwd = '" .. dir .. "'") if is_os('win') then - nvim('command', "let j = jobstart('cd', g:job_opts)") + command("let j = jobstart('cd', g:job_opts)") else - nvim('command', "let j = jobstart('pwd', g:job_opts)") + command("let j = jobstart('pwd', g:job_opts)") end expect_msg_seq( - { {'notification', 'stdout', {0, {dir, ''} } }, - {'notification', 'stdout', {0, {''} } }, - {'notification', 'exit', {0, 0} } + { + { 'notification', 'stdout', { 0, { dir, '' } } }, + { 'notification', 'stdout', { 0, { '' } } }, + { 'notification', 'exit', { 0, 0 } }, }, -- Alternative sequence: - { {'notification', 'stdout', {0, {dir} } }, - {'notification', 'stdout', {0, {'', ''} } }, - {'notification', 'stdout', {0, {''} } }, - {'notification', 'exit', {0, 0} } + { + { 'notification', 'stdout', { 0, { dir } } }, + { 'notification', 'stdout', { 0, { '', '' } } }, + { 'notification', 'stdout', { 0, { '' } } }, + { 'notification', 'exit', { 0, 0 } }, } ) rmdir(dir) @@ -214,14 +220,14 @@ describe('jobs', function() it('fails to change to invalid `cwd`', function() local dir = eval('resolve(tempname())."-bogus"') local _, err = pcall(function() - nvim('command', "let g:job_opts.cwd = '" .. dir .. "'") + command("let g:job_opts.cwd = '" .. dir .. "'") if is_os('win') then - nvim('command', "let j = jobstart('cd', g:job_opts)") + command("let j = jobstart('cd', g:job_opts)") else - nvim('command', "let j = jobstart('pwd', g:job_opts)") + command("let j = jobstart('pwd', g:job_opts)") end end) - ok(string.find(err, "E475: Invalid argument: expected valid directory$") ~= nil) + ok(string.find(err, 'E475: Invalid argument: expected valid directory$') ~= nil) end) it('error on non-executable `cwd`', function() @@ -229,17 +235,19 @@ describe('jobs', function() local dir = 'Xtest_not_executable_dir' mkdir(dir) - funcs.setfperm(dir, 'rw-------') - matches('^Vim%(call%):E903: Process failed to start: permission denied: .*', - pcall_err(nvim, 'command', "call jobstart(['pwd'], {'cwd': '"..dir.."'})")) + fn.setfperm(dir, 'rw-------') + matches( + '^Vim%(call%):E903: Process failed to start: permission denied: .*', + pcall_err(command, "call jobstart(['pwd'], {'cwd': '" .. dir .. "'})") + ) rmdir(dir) end) it('returns 0 when it fails to start', function() - eq("", eval("v:errmsg")) - feed_command("let g:test_jobid = jobstart([])") - eq(0, eval("g:test_jobid")) - eq("E474:", string.match(eval("v:errmsg"), "E%d*:")) + eq('', eval('v:errmsg')) + feed_command('let g:test_jobid = jobstart([])') + eq(0, eval('g:test_jobid')) + eq('E474:', string.match(eval('v:errmsg'), 'E%d*:')) end) it('returns -1 when target is not executable #5465', function() @@ -248,124 +256,131 @@ describe('jobs', function() end local executable_jobid = new_job() - local exe = is_os('win') and './test/functional/fixtures' or './test/functional/fixtures/non_executable.txt' - eq("Vim:E475: Invalid value for argument cmd: '"..exe.."' is not executable", - pcall_err(eval, "jobstart(['"..exe.."'])")) - eq("", eval("v:errmsg")) + local exe = is_os('win') and './test/functional/fixtures' + or './test/functional/fixtures/non_executable.txt' + eq( + "Vim:E475: Invalid value for argument cmd: '" .. exe .. "' is not executable", + pcall_err(eval, "jobstart(['" .. exe .. "'])") + ) + eq('', eval('v:errmsg')) -- Non-executable job should not increment the job ids. #5465 eq(executable_jobid + 1, new_job()) end) it('invokes callbacks when the job writes and exits', function() - nvim('command', "let g:job_opts.on_stderr = function('OnEvent')") - nvim('command', [[call jobstart(has('win32') ? 'echo:' : 'echo', g:job_opts)]]) - expect_twostreams({{'notification', 'stdout', {0, {'', ''}}}, - {'notification', 'stdout', {0, {''}}}}, - {{'notification', 'stderr', {0, {''}}}}) - eq({'notification', 'exit', {0, 0}}, next_msg()) + command("let g:job_opts.on_stderr = function('OnEvent')") + command([[call jobstart(has('win32') ? 'echo:' : 'echo', g:job_opts)]]) + expect_twostreams({ + { 'notification', 'stdout', { 0, { '', '' } } }, + { 'notification', 'stdout', { 0, { '' } } }, + }, { { 'notification', 'stderr', { 0, { '' } } } }) + eq({ 'notification', 'exit', { 0, 0 } }, next_msg()) end) it('interactive commands', function() - nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") + command("let j = jobstart(['cat', '-'], g:job_opts)") neq(0, eval('j')) - nvim('command', 'call jobsend(j, "abc\\n")') - eq({'notification', 'stdout', {0, {'abc', ''}}}, next_msg()) - nvim('command', 'call jobsend(j, "123\\nxyz\\n")') + command('call jobsend(j, "abc\\n")') + eq({ 'notification', 'stdout', { 0, { 'abc', '' } } }, next_msg()) + command('call jobsend(j, "123\\nxyz\\n")') expect_msg_seq( - { {'notification', 'stdout', {0, {'123', 'xyz', ''}}} - }, + { { 'notification', 'stdout', { 0, { '123', 'xyz', '' } } } }, -- Alternative sequence: - { {'notification', 'stdout', {0, {'123', ''}}}, - {'notification', 'stdout', {0, {'xyz', ''}}} + { + { 'notification', 'stdout', { 0, { '123', '' } } }, + { 'notification', 'stdout', { 0, { 'xyz', '' } } }, } ) - nvim('command', 'call jobsend(j, [123, "xyz", ""])') + command('call jobsend(j, [123, "xyz", ""])') expect_msg_seq( - { {'notification', 'stdout', {0, {'123', 'xyz', ''}}} - }, + { { 'notification', 'stdout', { 0, { '123', 'xyz', '' } } } }, -- Alternative sequence: - { {'notification', 'stdout', {0, {'123', ''}}}, - {'notification', 'stdout', {0, {'xyz', ''}}} + { + { 'notification', 'stdout', { 0, { '123', '' } } }, + { 'notification', 'stdout', { 0, { 'xyz', '' } } }, } ) - nvim('command', "call jobstop(j)") - eq({'notification', 'stdout', {0, {''}}}, next_msg()) - eq({'notification', 'exit', {0, 143}}, next_msg()) + command('call jobstop(j)') + eq({ 'notification', 'stdout', { 0, { '' } } }, next_msg()) + eq({ 'notification', 'exit', { 0, 143 } }, next_msg()) end) it('preserves NULs', function() -- Make a file with NULs in it. local filename = helpers.tmpname() - write_file(filename, "abc\0def\n") + write_file(filename, 'abc\0def\n') - nvim('command', "let j = jobstart(['cat', '"..filename.."'], g:job_opts)") - eq({'notification', 'stdout', {0, {'abc\ndef', ''}}}, next_msg()) - eq({'notification', 'stdout', {0, {''}}}, next_msg()) - eq({'notification', 'exit', {0, 0}}, next_msg()) + command("let j = jobstart(['cat', '" .. filename .. "'], g:job_opts)") + eq({ 'notification', 'stdout', { 0, { 'abc\ndef', '' } } }, next_msg()) + eq({ 'notification', 'stdout', { 0, { '' } } }, next_msg()) + eq({ 'notification', 'exit', { 0, 0 } }, next_msg()) os.remove(filename) -- jobsend() preserves NULs. - nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") - nvim('command', [[call jobsend(j, ["123\n456",""])]]) - eq({'notification', 'stdout', {0, {'123\n456', ''}}}, next_msg()) - nvim('command', "call jobstop(j)") + command("let j = jobstart(['cat', '-'], g:job_opts)") + command([[call jobsend(j, ["123\n456",""])]]) + eq({ 'notification', 'stdout', { 0, { '123\n456', '' } } }, next_msg()) + command('call jobstop(j)') end) - it("emits partial lines (does NOT buffer data lacking newlines)", function() - nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") - nvim('command', 'call jobsend(j, "abc\\nxyz")') - eq({'notification', 'stdout', {0, {'abc', 'xyz'}}}, next_msg()) - nvim('command', "call jobstop(j)") - eq({'notification', 'stdout', {0, {''}}}, next_msg()) - eq({'notification', 'exit', {0, 143}}, next_msg()) + it('emits partial lines (does NOT buffer data lacking newlines)', function() + command("let j = jobstart(['cat', '-'], g:job_opts)") + command('call jobsend(j, "abc\\nxyz")') + eq({ 'notification', 'stdout', { 0, { 'abc', 'xyz' } } }, next_msg()) + command('call jobstop(j)') + eq({ 'notification', 'stdout', { 0, { '' } } }, next_msg()) + eq({ 'notification', 'exit', { 0, 143 } }, next_msg()) end) it('preserves newlines', function() - nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") - nvim('command', 'call jobsend(j, "a\\n\\nc\\n\\n\\n\\nb\\n\\n")') - eq({'notification', 'stdout', - {0, {'a', '', 'c', '', '', '', 'b', '', ''}}}, next_msg()) + command("let j = jobstart(['cat', '-'], g:job_opts)") + command('call jobsend(j, "a\\n\\nc\\n\\n\\n\\nb\\n\\n")') + eq({ 'notification', 'stdout', { 0, { 'a', '', 'c', '', '', '', 'b', '', '' } } }, next_msg()) end) it('preserves NULs', function() - nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") - nvim('command', 'call jobsend(j, ["\n123\n", "abc\\nxyz\n", ""])') - eq({'notification', 'stdout', {0, {'\n123\n', 'abc\nxyz\n', ''}}}, - next_msg()) - nvim('command', "call jobstop(j)") - eq({'notification', 'stdout', {0, {''}}}, next_msg()) - eq({'notification', 'exit', {0, 143}}, next_msg()) + command("let j = jobstart(['cat', '-'], g:job_opts)") + command('call jobsend(j, ["\n123\n", "abc\\nxyz\n", ""])') + eq({ 'notification', 'stdout', { 0, { '\n123\n', 'abc\nxyz\n', '' } } }, next_msg()) + command('call jobstop(j)') + eq({ 'notification', 'stdout', { 0, { '' } } }, next_msg()) + eq({ 'notification', 'exit', { 0, 143 } }, next_msg()) end) it('avoids sending final newline', function() - nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") - nvim('command', 'call jobsend(j, ["some data", "without\nfinal nl"])') - eq({'notification', 'stdout', {0, {'some data', 'without\nfinal nl'}}}, - next_msg()) - nvim('command', "call jobstop(j)") - eq({'notification', 'stdout', {0, {''}}}, next_msg()) - eq({'notification', 'exit', {0, 143}}, next_msg()) + command("let j = jobstart(['cat', '-'], g:job_opts)") + command('call jobsend(j, ["some data", "without\nfinal nl"])') + eq({ 'notification', 'stdout', { 0, { 'some data', 'without\nfinal nl' } } }, next_msg()) + command('call jobstop(j)') + eq({ 'notification', 'stdout', { 0, { '' } } }, next_msg()) + eq({ 'notification', 'exit', { 0, 143 } }, next_msg()) end) it('closes the job streams with jobclose', function() - nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") - nvim('command', 'call jobclose(j, "stdin")') - eq({'notification', 'stdout', {0, {''}}}, next_msg()) - eq({'notification', 'exit', {0, 0}}, next_msg()) + command("let j = jobstart(['cat', '-'], g:job_opts)") + command('call jobclose(j, "stdin")') + eq({ 'notification', 'stdout', { 0, { '' } } }, next_msg()) + eq({ 'notification', 'exit', { 0, 0 } }, next_msg()) end) - it("disallows jobsend on a job that closed stdin", function() - nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") - nvim('command', 'call jobclose(j, "stdin")') - eq(false, pcall(function() - nvim('command', 'call jobsend(j, ["some data"])') - end)) + it('disallows jobsend on a job that closed stdin', function() + command("let j = jobstart(['cat', '-'], g:job_opts)") + command('call jobclose(j, "stdin")') + eq( + false, + pcall(function() + command('call jobsend(j, ["some data"])') + end) + ) command("let g:job_opts.stdin = 'null'") - nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") - eq(false, pcall(function() - nvim('command', 'call jobsend(j, ["some data"])') - end)) + command("let j = jobstart(['cat', '-'], g:job_opts)") + eq( + false, + pcall(function() + command('call jobsend(j, ["some data"])') + end) + ) end) it('disallows jobsend on a non-existent job', function() @@ -374,91 +389,99 @@ describe('jobs', function() end) it('jobstop twice on the stopped or exited job return 0', function() - nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") + command("let j = jobstart(['cat', '-'], g:job_opts)") neq(0, eval('j')) - eq(1, eval("jobstop(j)")) - eq(0, eval("jobstop(j)")) + eq(1, eval('jobstop(j)')) + eq(0, eval('jobstop(j)')) end) it('will not leak memory if we leave a job running', function() - nvim('command', "call jobstart(['cat', '-'], g:job_opts)") + command("call jobstart(['cat', '-'], g:job_opts)") end) it('can get the pid value using getpid', function() - nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") + command("let j = jobstart(['cat', '-'], g:job_opts)") local pid = eval('jobpid(j)') - neq(NIL, meths.get_proc(pid)) - nvim('command', 'call jobstop(j)') - eq({'notification', 'stdout', {0, {''}}}, next_msg()) - eq({'notification', 'exit', {0, 143}}, next_msg()) - eq(NIL, meths.get_proc(pid)) + neq(NIL, api.nvim_get_proc(pid)) + command('call jobstop(j)') + eq({ 'notification', 'stdout', { 0, { '' } } }, next_msg()) + eq({ 'notification', 'exit', { 0, 143 } }, next_msg()) + eq(NIL, api.nvim_get_proc(pid)) end) - it("disposed on Nvim exit", function() + it('disposed on Nvim exit', function() -- use sleep, which doesn't die on stdin close - nvim('command', "let g:j = jobstart(has('win32') ? ['ping', '-n', '1001', '127.0.0.1'] : ['sleep', '1000'], g:job_opts)") + command( + "let g:j = jobstart(has('win32') ? ['ping', '-n', '1001', '127.0.0.1'] : ['sleep', '1000'], g:job_opts)" + ) local pid = eval('jobpid(g:j)') - neq(NIL, meths.get_proc(pid)) + neq(NIL, api.nvim_get_proc(pid)) clear() - eq(NIL, meths.get_proc(pid)) + eq(NIL, api.nvim_get_proc(pid)) end) it('can survive the exit of nvim with "detach"', function() - nvim('command', 'let g:job_opts.detach = 1') - nvim('command', "let g:j = jobstart(has('win32') ? ['ping', '-n', '1001', '127.0.0.1'] : ['sleep', '1000'], g:job_opts)") + command('let g:job_opts.detach = 1') + command( + "let g:j = jobstart(has('win32') ? ['ping', '-n', '1001', '127.0.0.1'] : ['sleep', '1000'], g:job_opts)" + ) local pid = eval('jobpid(g:j)') - neq(NIL, meths.get_proc(pid)) + neq(NIL, api.nvim_get_proc(pid)) clear() - neq(NIL, meths.get_proc(pid)) + neq(NIL, api.nvim_get_proc(pid)) -- clean up after ourselves eq(0, os_kill(pid)) end) it('can pass user data to the callback', function() - nvim('command', 'let g:job_opts.user = {"n": 5, "s": "str", "l": [1]}') - nvim('command', [[call jobstart('echo foo', g:job_opts)]]) - local data = {n = 5, s = 'str', l = {1}} + command('let g:job_opts.user = {"n": 5, "s": "str", "l": [1]}') + command([[call jobstart('echo foo', g:job_opts)]]) + local data = { n = 5, s = 'str', l = { 1 } } expect_msg_seq( - { {'notification', 'stdout', {data, {'foo', ''}}}, - {'notification', 'stdout', {data, {''}}}, + { + { 'notification', 'stdout', { data, { 'foo', '' } } }, + { 'notification', 'stdout', { data, { '' } } }, }, -- Alternative sequence: - { {'notification', 'stdout', {data, {'foo'}}}, - {'notification', 'stdout', {data, {'', ''}}}, - {'notification', 'stdout', {data, {''}}}, + { + { 'notification', 'stdout', { data, { 'foo' } } }, + { 'notification', 'stdout', { data, { '', '' } } }, + { 'notification', 'stdout', { data, { '' } } }, } ) - eq({'notification', 'exit', {data, 0}}, next_msg()) + eq({ 'notification', 'exit', { data, 0 } }, next_msg()) end) it('can omit data callbacks', function() - nvim('command', 'unlet g:job_opts.on_stdout') - nvim('command', 'let g:job_opts.user = 5') - nvim('command', [[call jobstart('echo foo', g:job_opts)]]) - eq({'notification', 'exit', {5, 0}}, next_msg()) + command('unlet g:job_opts.on_stdout') + command('let g:job_opts.user = 5') + command([[call jobstart('echo foo', g:job_opts)]]) + eq({ 'notification', 'exit', { 5, 0 } }, next_msg()) end) it('can omit exit callback', function() - nvim('command', 'unlet g:job_opts.on_exit') - nvim('command', 'let g:job_opts.user = 5') - nvim('command', [[call jobstart('echo foo', g:job_opts)]]) + command('unlet g:job_opts.on_exit') + command('let g:job_opts.user = 5') + command([[call jobstart('echo foo', g:job_opts)]]) expect_msg_seq( - { {'notification', 'stdout', {5, {'foo', ''} } }, - {'notification', 'stdout', {5, {''} } }, + { + { 'notification', 'stdout', { 5, { 'foo', '' } } }, + { 'notification', 'stdout', { 5, { '' } } }, }, -- Alternative sequence: - { {'notification', 'stdout', {5, {'foo'} } }, - {'notification', 'stdout', {5, {'', ''} } }, - {'notification', 'stdout', {5, {''} } }, + { + { 'notification', 'stdout', { 5, { 'foo' } } }, + { 'notification', 'stdout', { 5, { '', '' } } }, + { 'notification', 'stdout', { 5, { '' } } }, } ) end) it('will pass return code with the exit event', function() - nvim('command', 'let g:job_opts.user = 5') - nvim('command', "call jobstart('exit 55', g:job_opts)") - eq({'notification', 'stdout', {5, {''}}}, next_msg()) - eq({'notification', 'exit', {5, 55}}, next_msg()) + command('let g:job_opts.user = 5') + command("call jobstart('exit 55', g:job_opts)") + eq({ 'notification', 'stdout', { 5, { '' } } }, next_msg()) + eq({ 'notification', 'exit', { 5, 55 } }, next_msg()) end) it('can receive dictionary functions', function() @@ -469,14 +492,14 @@ describe('jobs', function() endfunction call jobstart('exit 45', g:dict) ]]) - eq({'notification', 'exit', {45, 10}}, next_msg()) + eq({ 'notification', 'exit', { 45, 10 } }, next_msg()) end) it('can redefine callbacks being used by a job', function() local screen = Screen.new() screen:attach() screen:set_default_attr_ids({ - [1] = {bold=true, foreground=Screen.colors.Blue}, + [1] = { bold = true, foreground = Screen.colors.Blue }, }) source([[ function! g:JobHandler(job_id, data, event) @@ -495,16 +518,16 @@ describe('jobs', function() endfunction ]]) - eq("", eval("v:errmsg")) + eq('', eval('v:errmsg')) end) it('requires funcrefs for script-local (s:) functions', function() local screen = Screen.new(60, 5) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [3] = {bold = true, foreground = Screen.colors.SeaGreen4} + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [3] = { bold = true, foreground = Screen.colors.SeaGreen4 }, }) -- Pass job callback names _without_ `function(...)`. @@ -519,7 +542,7 @@ describe('jobs', function() \ }) ]]) - screen:expect{any="{2:E120: Using <SID> not in a script context: s:OnEvent}"} + screen:expect { any = '{2:E120: Using <SID> not in a script context: s:OnEvent}' } end) it('does not repeat output with slow output handlers', function() @@ -542,22 +565,22 @@ describe('jobs', function() call jobwait([g:id]) ]]) - local expected = {'1', '2', '3', '4', '5', ''} + local expected = { '1', '2', '3', '4', '5', '' } local chunks = eval('d.data') -- check nothing was received after exit, including EOF eq(eval('g:exit_data'), chunks) - local received = {''} + local received = { '' } for i, chunk in ipairs(chunks) do if i < #chunks then -- if chunks got joined, a spurious [''] callback was not sent - neq({''}, chunk) + neq({ '' }, chunk) else -- but EOF callback is still sent - eq({''}, chunk) + eq({ '' }, chunk) end - received[#received] = received[#received]..chunk[1] + received[#received] = received[#received] .. chunk[1] for j = 2, #chunk do - received[#received+1] = chunk[j] + received[#received + 1] = chunk[j] end end eq(expected, received) @@ -585,22 +608,22 @@ describe('jobs', function() call jobwait([g:id]) ]]) - local expected = {'1', '2', '3', '4', '5', ''} + local expected = { '1', '2', '3', '4', '5', '' } local chunks = eval('d.data') -- check nothing was received after exit, including EOF eq(eval('g:exit_data'), chunks) - local received = {''} + local received = { '' } for i, chunk in ipairs(chunks) do if i < #chunks then -- if chunks got joined, a spurious [''] callback was not sent - neq({''}, chunk) + neq({ '' }, chunk) else -- but EOF callback is still sent - eq({''}, chunk) + eq({ '' }, chunk) end - received[#received] = received[#received]..chunk[1] + received[#received] = received[#received] .. chunk[1] for j = 2, #chunk do - received[#received+1] = chunk[j] + received[#received + 1] = chunk[j] end end eq(expected, received) @@ -618,11 +641,11 @@ describe('jobs', function() call jobstart('echo some text', g:job_opts) ]]) expect_msg_seq( - { {'notification', '1', {'foo', 'bar', {'some text', ''}, 'stdout'}}, - }, + { { 'notification', '1', { 'foo', 'bar', { 'some text', '' }, 'stdout' } } }, -- Alternative sequence: - { {'notification', '1', {'foo', 'bar', {'some text'}, 'stdout'}}, - {'notification', '1', {'foo', 'bar', {'', ''}, 'stdout'}}, + { + { 'notification', '1', { 'foo', 'bar', { 'some text' }, 'stdout' } }, + { 'notification', '1', { 'foo', 'bar', { '', '' }, 'stdout' } }, } ) end) @@ -638,11 +661,11 @@ describe('jobs', function() call jobstart('echo some text', g:job_opts) ]]) expect_msg_seq( - { {'notification', '1', {'foo', 'bar', {'some text', ''}, 'stdout'}}, - }, + { { 'notification', '1', { 'foo', 'bar', { 'some text', '' }, 'stdout' } } }, -- Alternative sequence: - { {'notification', '1', {'foo', 'bar', {'some text'}, 'stdout'}}, - {'notification', '1', {'foo', 'bar', {'', ''}, 'stdout'}}, + { + { 'notification', '1', { 'foo', 'bar', { 'some text' }, 'stdout' } }, + { 'notification', '1', { 'foo', 'bar', { '', '' }, 'stdout' } }, } ) end) @@ -653,18 +676,19 @@ describe('jobs', function() call jobstart('echo some text', g:job_opts) ]]) expect_msg_seq( - { {'notification', '1', {'foo', 'bar', {'some text', ''}, 'stdout'}}, - }, + { { 'notification', '1', { 'foo', 'bar', { 'some text', '' }, 'stdout' } } }, -- Alternative sequence: - { {'notification', '1', {'foo', 'bar', {'some text'}, 'stdout'}}, - {'notification', '1', {'foo', 'bar', {'', ''}, 'stdout'}}, + { + { 'notification', '1', { 'foo', 'bar', { 'some text' }, 'stdout' } }, + { 'notification', '1', { 'foo', 'bar', { '', '' }, 'stdout' } }, } ) end) it('jobstart() environment: $NVIM, $NVIM_LISTEN_ADDRESS #11009', function() local function get_env_in_child_job(envname, env) - return exec_lua([[ + return exec_lua( + [[ local envname, env = ... local join = function(s) return vim.fn.join(s, '') end local stdout = {} @@ -676,12 +700,13 @@ describe('jobs', function() on_stderr = function(chan, data, name) stderr = data end, on_stdout = function(chan, data, name) stdout = data end, } - local j1 = vim.fn.jobstart({ vim.v.progpath, '-es', '-V1',( '+echo "%s="..getenv("%s")'):format(envname, envname), '+qa!' }, opt) + local j1 = vim.fn.jobstart({ vim.v.progpath, '-es', '-V1',('+echo "%s="..getenv("%s")'):format(envname, envname), '+qa!' }, opt) vim.fn.jobwait({ j1 }, 10000) return join({ join(stdout), join(stderr) }) ]], - envname, - env) + envname, + env + ) end local addr = eval('v:servername') @@ -689,14 +714,18 @@ describe('jobs', function() -- $NVIM is _not_ defined in the top-level Nvim process. eq('', eval('$NVIM')) -- jobstart() shares its v:servername with the child via $NVIM. - eq('NVIM='..addr, get_env_in_child_job('NVIM')) + eq('NVIM=' .. addr, get_env_in_child_job('NVIM')) -- $NVIM_LISTEN_ADDRESS is unset by server_init in the child. eq('NVIM_LISTEN_ADDRESS=v:null', get_env_in_child_job('NVIM_LISTEN_ADDRESS')) - eq('NVIM_LISTEN_ADDRESS=v:null', get_env_in_child_job('NVIM_LISTEN_ADDRESS', - { NVIM_LISTEN_ADDRESS='Xtest_jobstart_env' })) + eq( + 'NVIM_LISTEN_ADDRESS=v:null', + get_env_in_child_job('NVIM_LISTEN_ADDRESS', { NVIM_LISTEN_ADDRESS = 'Xtest_jobstart_env' }) + ) -- User can explicitly set $NVIM_LOG_FILE, $VIM, $VIMRUNTIME. - eq('NVIM_LOG_FILE=Xtest_jobstart_env', - get_env_in_child_job('NVIM_LOG_FILE', { NVIM_LOG_FILE='Xtest_jobstart_env' })) + eq( + 'NVIM_LOG_FILE=Xtest_jobstart_env', + get_env_in_child_job('NVIM_LOG_FILE', { NVIM_LOG_FILE = 'Xtest_jobstart_env' }) + ) os.remove('Xtest_jobstart_env') end) @@ -721,7 +750,7 @@ describe('jobs', function() \ jobstart('sleep 0.310; exit 7') \ ])) ]]) - eq({'notification', 'wait', {{4, 5, 6, 7}}}, next_msg()) + eq({ 'notification', 'wait', { { 4, 5, 6, 7 } } }, next_msg()) end) it('will run callbacks while waiting', function() @@ -751,8 +780,7 @@ describe('jobs', function() \ ]) call rpcnotify(g:channel, 'wait', sort(g:jobs), sort(g:exits)) ]]) - eq({'notification', 'wait', - {{3,4,5,6}, {3,4,5,6}}}, next_msg()) + eq({ 'notification', 'wait', { { 3, 4, 5, 6 }, { 3, 4, 5, 6 } } }, next_msg()) end) it('will return status codes in the order of passed ids', function() @@ -769,7 +797,7 @@ describe('jobs', function() \ jobstart('sleep 0.010; exit 7') \ ])) ]]) - eq({'notification', 'wait', {{4, 5, 6, 7}}}, next_msg()) + eq({ 'notification', 'wait', { { 4, 5, 6, 7 } } }, next_msg()) end) it('will return -3 for invalid job ids', function() @@ -779,29 +807,33 @@ describe('jobs', function() \ jobstart((has('win32') ? 'Start-Sleep -Milliseconds 100' : 'sleep 0.01').'; exit 5'), \ ])) ]]) - eq({'notification', 'wait', {{-3, 5}}}, next_msg()) + eq({ 'notification', 'wait', { { -3, 5 } } }, next_msg()) end) it('will return -2 when interrupted without timeout', function() - feed_command('call rpcnotify(g:channel, "ready") | '.. - 'call rpcnotify(g:channel, "wait", '.. - 'jobwait([jobstart("'.. - (is_os('win') and 'Start-Sleep 10' or 'sleep 10').. - '; exit 55")]))') - eq({'notification', 'ready', {}}, next_msg()) + feed_command( + 'call rpcnotify(g:channel, "ready") | ' + .. 'call rpcnotify(g:channel, "wait", ' + .. 'jobwait([jobstart("' + .. (is_os('win') and 'Start-Sleep 10' or 'sleep 10') + .. '; exit 55")]))' + ) + eq({ 'notification', 'ready', {} }, next_msg()) feed('<c-c>') - eq({'notification', 'wait', {{-2}}}, next_msg()) + eq({ 'notification', 'wait', { { -2 } } }, next_msg()) end) it('will return -2 when interrupted with timeout', function() - feed_command('call rpcnotify(g:channel, "ready") | '.. - 'call rpcnotify(g:channel, "wait", '.. - 'jobwait([jobstart("'.. - (is_os('win') and 'Start-Sleep 10' or 'sleep 10').. - '; exit 55")], 10000))') - eq({'notification', 'ready', {}}, next_msg()) + feed_command( + 'call rpcnotify(g:channel, "ready") | ' + .. 'call rpcnotify(g:channel, "wait", ' + .. 'jobwait([jobstart("' + .. (is_os('win') and 'Start-Sleep 10' or 'sleep 10') + .. '; exit 55")], 10000))' + ) + eq({ 'notification', 'ready', {} }, next_msg()) feed('<c-c>') - eq({'notification', 'wait', {{-2}}}, next_msg()) + eq({ 'notification', 'wait', { { -2 } } }, next_msg()) end) it('can be called recursively', function() @@ -844,11 +876,11 @@ describe('jobs', function() local r for i = 10, 1, -1 do r = next_msg() - eq('job '..i..' closed', r[3][1]) + eq('job ' .. i .. ' closed', r[3][1]) r = next_msg() - eq('job '..i..' exited', r[3][1]) + eq('job ' .. i .. ' exited', r[3][1]) end - eq(10, nvim('eval', 'g:counter')) + eq(10, api.nvim_eval('g:counter')) end) describe('with timeout argument', function() @@ -858,7 +890,7 @@ describe('jobs', function() \ jobstart((has('win32') ? 'Start-Sleep 10' : 'sleep 10').'; exit 5'), \ ], 100)) ]]) - eq({'notification', 'wait', {{-1}}}, next_msg()) + eq({ 'notification', 'wait', { { -1 } } }, next_msg()) end) it('can pass 0 to check if a job exists', function() @@ -871,16 +903,16 @@ describe('jobs', function() \ jobstart('sleep 0.3; exit 5'), \ ], 0)) ]]) - eq({'notification', 'wait', {{-1, -1}}}, next_msg()) + eq({ 'notification', 'wait', { { -1, -1 } } }, next_msg()) end) end) it('hides cursor and flushes messages before blocking', function() local screen = Screen.new(50, 6) screen:set_default_attr_ids({ - [0] = {foreground = Screen.colors.Blue, bold = true}; -- NonText - [1] = {bold = true, reverse = true}; -- MsgSeparator - [2] = {bold = true, foreground = Screen.colors.SeaGreen}; -- MoreMsg + [0] = { foreground = Screen.colors.Blue, bold = true }, -- NonText + [1] = { bold = true, reverse = true }, -- MsgSeparator + [2] = { bold = true, foreground = Screen.colors.SeaGreen }, -- MoreMsg }) screen:attach() command([[let g:id = jobstart([v:progpath, '--clean', '--headless'])]]) @@ -892,56 +924,66 @@ describe('jobs', function() endfunc ]]) feed_command('call PrintAndWait()') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {1: }| aaa | bbb | - ]], timeout=100} - screen:expect{grid=[[ + ]], + timeout = 100, + } + screen:expect { + grid = [[ | {1: }| aaa | bbb | ccc | {2:Press ENTER or type command to continue}^ | - ]]} + ]], + } feed('<CR>') - funcs.jobstop(meths.get_var('id')) + fn.jobstop(api.nvim_get_var('id')) end) end) pending('exit event follows stdout, stderr', function() - nvim('command', "let g:job_opts.on_stderr = function('OnEvent')") - nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") - nvim('eval', 'jobsend(j, "abcdef")') - nvim('eval', 'jobstop(j)') + command("let g:job_opts.on_stderr = function('OnEvent')") + command("let j = jobstart(['cat', '-'], g:job_opts)") + api.nvim_eval('jobsend(j, "abcdef")') + api.nvim_eval('jobstop(j)') expect_msg_seq( - { {'notification', 'stdout', {0, {'abcdef'}}}, - {'notification', 'stdout', {0, {''}}}, - {'notification', 'stderr', {0, {''}}}, + { + { 'notification', 'stdout', { 0, { 'abcdef' } } }, + { 'notification', 'stdout', { 0, { '' } } }, + { 'notification', 'stderr', { 0, { '' } } }, }, -- Alternative sequence: - { {'notification', 'stderr', {0, {''}}}, - {'notification', 'stdout', {0, {'abcdef'}}}, - {'notification', 'stdout', {0, {''}}}, + { + { 'notification', 'stderr', { 0, { '' } } }, + { 'notification', 'stdout', { 0, { 'abcdef' } } }, + { 'notification', 'stdout', { 0, { '' } } }, }, -- Alternative sequence: - { {'notification', 'stdout', {0, {'abcdef'}}}, - {'notification', 'stderr', {0, {''}}}, - {'notification', 'stdout', {0, {''}}}, + { + { 'notification', 'stdout', { 0, { 'abcdef' } } }, + { 'notification', 'stderr', { 0, { '' } } }, + { 'notification', 'stdout', { 0, { '' } } }, } ) - eq({'notification', 'exit', {0, 143}}, next_msg()) + eq({ 'notification', 'exit', { 0, 143 } }, next_msg()) end) it('cannot have both rpc and pty options', function() - command("let g:job_opts.pty = v:true") - command("let g:job_opts.rpc = v:true") + command('let g:job_opts.pty = v:true') + command('let g:job_opts.rpc = v:true') local _, err = pcall(command, "let j = jobstart(['cat', '-'], g:job_opts)") - ok(string.find(err, "E475: Invalid argument: job cannot have both 'pty' and 'rpc' options set") ~= nil) + ok( + string.find(err, "E475: Invalid argument: job cannot have both 'pty' and 'rpc' options set") + ~= nil + ) end) it('does not crash when repeatedly failing to start shell', function() @@ -954,7 +996,7 @@ describe('jobs', function() ]]) -- The crash only triggered if both jobs are cleaned up on the same event -- loop tick. This is also prevented by try-block, so feed must be used. - feed_command("call DoIt()") + feed_command('call DoIt()') feed('<cr>') -- press RETURN assert_alive() end) @@ -991,7 +1033,7 @@ describe('jobs', function() \ 'substitute(v:val, "\r", "", "")'), \ 'split(v:val, "\\s\\+")') if len(proc) == 6 - let s:procs[proc[1]] ..']]'..[[= {'name': proc[0], + let s:procs[proc[1]] .. ']]' .. [[= {'name': proc[0], \ 'Session Name': proc[2], \ 'Session': proc[3]} endif @@ -1015,15 +1057,13 @@ describe('jobs', function() endfunction ]]) end - local sleep_cmd = (is_os('win') - and 'ping -n 31 127.0.0.1' - or 'sleep 30') - local j = eval("jobstart('"..sleep_cmd..' | '..sleep_cmd..' | '..sleep_cmd.."')") - local ppid = funcs.jobpid(j) + local sleep_cmd = (is_os('win') and 'ping -n 31 127.0.0.1' or 'sleep 30') + local j = eval("jobstart('" .. sleep_cmd .. ' | ' .. sleep_cmd .. ' | ' .. sleep_cmd .. "')") + local ppid = fn.jobpid(j) local children if is_os('win') then local status, result = pcall(retry, nil, nil, function() - children = meths.get_proc_children(ppid) + children = api.nvim_get_proc_children(ppid) -- On Windows conhost.exe may exist, and -- e.g. vctip.exe might appear. #10783 ok(#children >= 3 and #children <= 5) @@ -1034,36 +1074,38 @@ describe('jobs', function() error(result) end else - retry(nil, nil, function() - children = meths.get_proc_children(ppid) + retry(nil, nil, function() + children = api.nvim_get_proc_children(ppid) eq(3, #children) end) end -- Assert that nvim_get_proc() sees the children. for _, child_pid in ipairs(children) do - local info = meths.get_proc(child_pid) + local info = api.nvim_get_proc(child_pid) -- eq((is_os('win') and 'nvim.exe' or 'nvim'), info.name) eq(ppid, info.ppid) end -- Kill the root of the tree. - eq(1, funcs.jobstop(j)) + eq(1, fn.jobstop(j)) -- Assert that the children were killed. retry(nil, nil, function() for _, child_pid in ipairs(children) do - eq(NIL, meths.get_proc(child_pid)) + eq(NIL, api.nvim_get_proc(child_pid)) end end) end) it('jobstop on same id before stopped', function() - nvim('command', 'let j = jobstart(["cat", "-"], g:job_opts)') + command('let j = jobstart(["cat", "-"], g:job_opts)') neq(0, eval('j')) - eq({1, 0}, eval('[jobstop(j), jobstop(j)]')) + eq({ 1, 0 }, eval('[jobstop(j), jobstop(j)]')) end) describe('running tty-test program', function() - if skip(is_os('win')) then return end + if skip(is_os('win')) then + return + end local function next_chunk() local rv while true do @@ -1084,7 +1126,7 @@ describe('jobs', function() local j local function send(str) -- check no nvim_chan_free double free with pty job (#14198) - meths.chan_send(j, str) + api.nvim_chan_send(j, str) end before_each(function() @@ -1095,10 +1137,10 @@ describe('jobs', function() endfunction ]]) insert(testprg('tty-test')) - nvim('command', 'let g:job_opts.pty = 1') - nvim('command', 'let exec = [expand("<cfile>:p")]') - nvim('command', "let j = jobstart(exec, g:job_opts)") - j = eval'j' + command('let g:job_opts.pty = 1') + command('let exec = [expand("<cfile>:p")]') + command('let j = jobstart(exec, g:job_opts)') + j = eval 'j' eq('tty ready', next_chunk()) end) @@ -1108,17 +1150,17 @@ describe('jobs', function() end) it('resizing window', function() - nvim('command', 'call jobresize(j, 40, 10)') + command('call jobresize(j, 40, 10)') eq('rows: 10, cols: 40', next_chunk()) - nvim('command', 'call jobresize(j, 10, 40)') + command('call jobresize(j, 10, 40)') eq('rows: 40, cols: 10', next_chunk()) end) it('jobclose() sends SIGHUP', function() - nvim('command', 'call jobclose(j)') + command('call jobclose(j)') local msg = next_msg() - msg = (msg[2] == 'stdout') and next_msg() or msg -- Skip stdout, if any. - eq({'notification', 'exit', {0, 42}}, msg) + msg = (msg[2] == 'stdout') and next_msg() or msg -- Skip stdout, if any. + eq({ 'notification', 'exit', { 0, 42 } }, msg) end) it('jobstart() does not keep ptmx file descriptor open', function() @@ -1132,7 +1174,7 @@ describe('jobs', function() -- Have to wait so that the SIGHUP can be processed by tty-test on time. -- Can't wait for the next message in case this test fails, if it fails -- there won't be any more messages, and the test would hang. - helpers.sleep(100) + vim.uv.sleep(100) local err = exc_exec('call jobpid(j)') eq('Vim(call):E900: Invalid channel id', err) @@ -1141,9 +1183,49 @@ describe('jobs', function() command('call jobstop(' .. other_jobid .. ')') end) end) + + it('does not close the same handle twice on exit #25086', function() + local filename = string.format('%s.lua', helpers.tmpname()) + write_file( + filename, + [[ + vim.api.nvim_create_autocmd('VimLeavePre', { + callback = function() + local id = vim.fn.jobstart('sleep 0') + vim.fn.jobwait({id}) + end, + }) + ]] + ) + + local screen = thelpers.setup_child_nvim({ + '--cmd', + 'set notermguicolors', + '-i', + 'NONE', + '-u', + filename, + }) + -- Wait for startup to complete, so that all terminal responses are received. + screen:expect([[ + {1: } | + ~ |*3 + {1:[No Name] 0,0-1 All}| + | + {3:-- TERMINAL --} | + ]]) + + feed(':q<CR>') + screen:expect([[ + | + [Process exited 0]{1: } | + |*4 + {3:-- TERMINAL --} | + ]]) + end) end) -describe("pty process teardown", function() +describe('pty process teardown', function() local screen before_each(function() clear() @@ -1151,31 +1233,33 @@ describe("pty process teardown", function() screen:attach() screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | + ~ |*4 | ]]) end) - it("does not prevent/delay exit. #4798 #4900", function() - skip(is_os('win')) + it('does not prevent/delay exit. #4798 #4900', function() -- Use a nested nvim (in :term) to test without --headless. - feed_command(":terminal '"..helpers.nvim_prog - .."' -u NONE -i NONE --cmd '"..nvim_set.."' " + fn.termopen({ + helpers.nvim_prog, + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + nvim_set, -- Use :term again in the _nested_ nvim to get a PTY process. -- Use `sleep` to simulate a long-running child of the PTY. - .."+terminal +'!(sleep 300 &)' +qa") + '+terminal', + '+!(sleep 300 &)', + '+qa', + }, { env = { VIMRUNTIME = os.getenv('VIMRUNTIME') } }) -- Exiting should terminate all descendants (PTY, its children, ...). screen:expect([[ ^ | [Process exited 0] | - | - | - | - | + |*4 ]]) end) end) diff --git a/test/functional/core/log_spec.lua b/test/functional/core/log_spec.lua index f682df4155..1637e683c1 100644 --- a/test/functional/core/log_spec.lua +++ b/test/functional/core/log_spec.lua @@ -23,7 +23,7 @@ describe('log', function() -- calls, that needs investigation. clear() eq(0, request('nvim__stats').log_skip) - clear{env={CDPATH='~doesnotexist'}} + clear { env = { CDPATH = '~doesnotexist' } } assert(request('nvim__stats').log_skip <= 13) end) @@ -32,14 +32,16 @@ describe('log', function() -- ERR 2022-05-29T12:30:03.800 T2 log_init:110: test log message -- ERR 2022-05-29T12:30:03.814 T2/child log_init:110: test log message - clear({env={ - NVIM_LOG_FILE=testlog, - -- TODO: remove this after nvim_log #7062 is merged. - __NVIM_TEST_LOG='1' - }}) + clear({ + env = { + NVIM_LOG_FILE = testlog, + -- TODO: remove this after nvim_log #7062 is merged. + __NVIM_TEST_LOG = '1', + }, + }) local tid = _G._nvim_test_id - assert_log(tid..'%.%d+%.%d +server_init:%d+: test log message', testlog, 100) + assert_log(tid .. '%.%d+%.%d +server_init:%d+: test log message', testlog, 100) exec_lua([[ local j1 = vim.fn.jobstart({ vim.v.progpath, '-es', '-V1', '+foochild', '+qa!' }, vim.empty_dict()) diff --git a/test/functional/core/main_spec.lua b/test/functional/core/main_spec.lua index 19c7a93730..9d8d64c82d 100644 --- a/test/functional/core/main_spec.lua +++ b/test/functional/core/main_spec.lua @@ -1,4 +1,4 @@ -local luv = require('luv') +local uv = vim.uv local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') @@ -7,7 +7,7 @@ local matches = helpers.matches local feed = helpers.feed local eval = helpers.eval local clear = helpers.clear -local funcs = helpers.funcs +local fn = helpers.fn local nvim_prog_abs = helpers.nvim_prog_abs local write_file = helpers.write_file local is_os = helpers.is_os @@ -32,28 +32,57 @@ describe('command-line option', function() end) it('treats - as stdin', function() - eq(nil, luv.fs_stat(fname)) - funcs.system( - {nvim_prog_abs(), '-u', 'NONE', '-i', 'NONE', '--headless', - '--cmd', 'set noswapfile shortmess+=IFW fileformats=unix', - '-s', '-', fname}, - {':call setline(1, "42")', ':wqall!', ''}) + eq(nil, uv.fs_stat(fname)) + fn.system({ + nvim_prog_abs(), + '-u', + 'NONE', + '-i', + 'NONE', + '--headless', + '--cmd', + 'set noswapfile shortmess+=IFW fileformats=unix', + '-s', + '-', + fname, + }, { ':call setline(1, "42")', ':wqall!', '' }) eq(0, eval('v:shell_error')) - local attrs = luv.fs_stat(fname) - eq(#('42\n'), attrs.size) + local attrs = uv.fs_stat(fname) + eq(#'42\n', attrs.size) end) it('does not expand $VAR', function() - eq(nil, luv.fs_stat(fname)) + eq(nil, uv.fs_stat(fname)) eq(true, not not dollar_fname:find('%$%w+')) write_file(dollar_fname, ':call setline(1, "100500")\n:wqall!\n') - funcs.system( - {nvim_prog_abs(), '-u', 'NONE', '-i', 'NONE', '--headless', - '--cmd', 'set noswapfile shortmess+=IFW fileformats=unix', - '-s', dollar_fname, fname}) + fn.system({ + nvim_prog_abs(), + '-u', + 'NONE', + '-i', + 'NONE', + '--headless', + '--cmd', + 'set noswapfile shortmess+=IFW fileformats=unix', + '-s', + dollar_fname, + fname, + }) + eq(0, eval('v:shell_error')) + local attrs = uv.fs_stat(fname) + eq(#'100500\n', attrs.size) + end) + + it('does not crash when run completion in ex mode', function() + fn.system({ + nvim_prog_abs(), + '--clean', + '-e', + '-s', + '--cmd', + 'exe "norm! i\\<C-X>\\<C-V>"', + }) eq(0, eval('v:shell_error')) - local attrs = luv.fs_stat(fname) - eq(#('100500\n'), attrs.size) end) it('does not crash after reading from stdin in non-headless mode', function() @@ -61,36 +90,38 @@ describe('command-line option', function() local screen = Screen.new(40, 8) screen:attach() local args = { - nvim_prog_abs(), '-u', 'NONE', '-i', 'NONE', - '--cmd', '"set noswapfile shortmess+=IFW fileformats=unix"', - '-s', '-' + nvim_prog_abs(), + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + '"set noswapfile shortmess+=IFW fileformats=unix notermguicolors"', + '-s', + '-', } -- Need to explicitly pipe to stdin so that the embedded Nvim instance doesn't try to read -- data from the terminal #18181 - funcs.termopen(string.format([[echo "" | %s]], table.concat(args, " "))) - screen:expect([[ - ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {2:[No Name] 0,0-1 All}| - | - | - ]], { - [1] = {foreground = tonumber('0x4040ff'), fg_indexed=true}, - [2] = {bold = true, reverse = true} + fn.termopen(string.format([[echo "" | %s]], table.concat(args, ' ')), { + env = { VIMRUNTIME = os.getenv('VIMRUNTIME') }, }) + screen:expect( + [[ + ^ | + ~ |*4 + {1:[No Name] 0,0-1 All}| + |*2 + ]], + { + [1] = { reverse = true }, + } + ) feed('i:cq<CR>') screen:expect([[ | [Process exited 1] | - | - | - | - | - | + |*5 -- TERMINAL -- | ]]) --[=[ Example of incorrect output: @@ -101,20 +132,29 @@ describe('command-line option', function() LENO' failed. | | [Process exited 6] | - | - | + |*2 ]]) ]=] end) it('errors out when trying to use nonexistent file with -s', function() eq( - 'Cannot open for reading: "'..nonexistent_fname..'": no such file or directory\n', - funcs.system( - {nvim_prog_abs(), '-u', 'NONE', '-i', 'NONE', '--headless', - '--cmd', 'set noswapfile shortmess+=IFW fileformats=unix', - '--cmd', 'language C', - '-s', nonexistent_fname})) + 'Cannot open for reading: "' .. nonexistent_fname .. '": no such file or directory\n', + fn.system({ + nvim_prog_abs(), + '-u', + 'NONE', + '-i', + 'NONE', + '--headless', + '--cmd', + 'set noswapfile shortmess+=IFW fileformats=unix', + '--cmd', + 'language C', + '-s', + nonexistent_fname, + }) + ) eq(2, eval('v:shell_error')) end) @@ -122,21 +162,34 @@ describe('command-line option', function() write_file(fname, ':call setline(1, "1")\n:wqall!\n') write_file(dollar_fname, ':call setline(1, "2")\n:wqall!\n') eq( - 'Attempt to open script file again: "-s '..dollar_fname..'"\n', - funcs.system( - {nvim_prog_abs(), '-u', 'NONE', '-i', 'NONE', '--headless', - '--cmd', 'set noswapfile shortmess+=IFW fileformats=unix', - '--cmd', 'language C', - '-s', fname, '-s', dollar_fname, fname_2})) + 'Attempt to open script file again: "-s ' .. dollar_fname .. '"\n', + fn.system({ + nvim_prog_abs(), + '-u', + 'NONE', + '-i', + 'NONE', + '--headless', + '--cmd', + 'set noswapfile shortmess+=IFW fileformats=unix', + '--cmd', + 'language C', + '-s', + fname, + '-s', + dollar_fname, + fname_2, + }) + ) eq(2, eval('v:shell_error')) - eq(nil, luv.fs_stat(fname_2)) + eq(nil, uv.fs_stat(fname_2)) end) end) it('nvim -v, :version', function() - matches('Run ":verbose version"', funcs.execute(':version')) - matches('Compilation: .*Run :checkhealth', funcs.execute(':verbose version')) - matches('Run "nvim %-V1 %-v"', funcs.system({nvim_prog_abs(), '-v'})) - matches('Compilation: .*Run :checkhealth', funcs.system({nvim_prog_abs(), '-V1', '-v'})) + matches('Run ":verbose version"', fn.execute(':version')) + matches('Compilation: .*Run :checkhealth', fn.execute(':verbose version')) + matches('Run "nvim %-V1 %-v"', fn.system({ nvim_prog_abs(), '-v' })) + matches('Compilation: .*Run :checkhealth', fn.system({ nvim_prog_abs(), '-V1', '-v' })) end) end) diff --git a/test/functional/core/path_spec.lua b/test/functional/core/path_spec.lua index 97c32f7de6..e98bfc0d45 100644 --- a/test/functional/core/path_spec.lua +++ b/test/functional/core/path_spec.lua @@ -4,7 +4,7 @@ local command = helpers.command local eq = helpers.eq local eval = helpers.eval local feed = helpers.feed -local funcs = helpers.funcs +local fn = helpers.fn local insert = helpers.insert local is_os = helpers.is_os local mkdir = helpers.mkdir @@ -13,7 +13,7 @@ local write_file = helpers.write_file local function join_path(...) local pathsep = (is_os('win') and '\\' or '/') - return table.concat({...}, pathsep) + return table.concat({ ... }, pathsep) end describe('path collapse', function() @@ -23,40 +23,40 @@ describe('path collapse', function() before_each(function() targetdir = join_path('test', 'functional', 'fixtures') clear() - command('edit '..join_path(targetdir, 'tty-test.c')) + command('edit ' .. join_path(targetdir, 'tty-test.c')) expected_path = eval('expand("%:p")') end) it('with /./ segment #7117', function() - command('edit '..join_path(targetdir, '.', 'tty-test.c')) + command('edit ' .. join_path(targetdir, '.', 'tty-test.c')) eq(expected_path, eval('expand("%:p")')) end) it('with ./ prefix #7117', function() - command('edit '..join_path('.', targetdir, 'tty-test.c')) + command('edit ' .. join_path('.', targetdir, 'tty-test.c')) eq(expected_path, eval('expand("%:p")')) end) it('with ./ prefix, after directory change #7117', function() - command('edit '..join_path('.', targetdir, 'tty-test.c')) + command('edit ' .. join_path('.', targetdir, 'tty-test.c')) command('cd test') eq(expected_path, eval('expand("%:p")')) end) it('with /../ segment #7117', function() - command('edit '..join_path(targetdir, '..', 'fixtures', 'tty-test.c')) + command('edit ' .. join_path(targetdir, '..', 'fixtures', 'tty-test.c')) eq(expected_path, eval('expand("%:p")')) end) it('with ../ and different starting directory #7117', function() command('cd test') - command('edit '..join_path('..', targetdir, 'tty-test.c')) + command('edit ' .. join_path('..', targetdir, 'tty-test.c')) eq(expected_path, eval('expand("%:p")')) end) it('with ./../ and different starting directory #7117', function() command('cd test') - command('edit '..join_path('.', '..', targetdir, 'tty-test.c')) + command('edit ' .. join_path('.', '..', targetdir, 'tty-test.c')) eq(expected_path, eval('expand("%:p")')) end) end) @@ -67,16 +67,16 @@ describe('expand wildcard', function() it('with special characters #24421', function() local folders = is_os('win') and { '{folder}', - 'folder$name' + 'folder$name', } or { 'folder-name', - 'folder#name' + 'folder#name', } for _, folder in ipairs(folders) do mkdir(folder) local file = join_path(folder, 'file.txt') write_file(file, '') - eq(file, eval('expand("'..folder..'/*")')) + eq(file, eval('expand("' .. folder .. '/*")')) rmdir(folder) end end) @@ -131,14 +131,30 @@ describe('file search', function() test_cfile([[c:foo]], [[c]]) -- Examples from: https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats#example-ways-to-refer-to-the-same-file test_cfile([[c:\temp\test-file.txt]], [[c:]], [[c:\temp\test-file.txt]]) - test_cfile([[\\127.0.0.1\c$\temp\test-file.txt]], [[127.0.0.1]], [[\\127.0.0.1\c$\temp\test-file.txt]]) - test_cfile([[\\LOCALHOST\c$\temp\test-file.txt]], [[LOCALHOST]], [[\\LOCALHOST\c$\temp\test-file.txt]]) + test_cfile( + [[\\127.0.0.1\c$\temp\test-file.txt]], + [[127.0.0.1]], + [[\\127.0.0.1\c$\temp\test-file.txt]] + ) + test_cfile( + [[\\LOCALHOST\c$\temp\test-file.txt]], + [[LOCALHOST]], + [[\\LOCALHOST\c$\temp\test-file.txt]] + ) -- not supported yet test_cfile([[\\.\c:\temp\test-file.txt]], [[.]], [[\\.\c]]) -- not supported yet test_cfile([[\\?\c:\temp\test-file.txt]], [[c:]], [[\\]]) - test_cfile([[\\.\UNC\LOCALHOST\c$\temp\test-file.txt]], [[.]], [[\\.\UNC\LOCALHOST\c$\temp\test-file.txt]]) - test_cfile([[\\127.0.0.1\c$\temp\test-file.txt]], [[127.0.0.1]], [[\\127.0.0.1\c$\temp\test-file.txt]]) + test_cfile( + [[\\.\UNC\LOCALHOST\c$\temp\test-file.txt]], + [[.]], + [[\\.\UNC\LOCALHOST\c$\temp\test-file.txt]] + ) + test_cfile( + [[\\127.0.0.1\c$\temp\test-file.txt]], + [[127.0.0.1]], + [[\\127.0.0.1\c$\temp\test-file.txt]] + ) end) ---@param funcname 'finddir' | 'findfile' @@ -151,7 +167,7 @@ describe('file search', function() else write_file(expected, '') end - eq(expected, funcs[funcname](item, d:gsub(' ', [[\ ]]))) + eq(expected, fn[funcname](item, d:gsub(' ', [[\ ]]))) end it('finddir()', function() diff --git a/test/functional/core/remote_spec.lua b/test/functional/core/remote_spec.lua index a0ec748446..caff06f6ab 100644 --- a/test/functional/core/remote_spec.lua +++ b/test/functional/core/remote_spec.lua @@ -6,7 +6,7 @@ local eq = helpers.eq local exec_capture = helpers.exec_capture local exec_lua = helpers.exec_lua local expect = helpers.expect -local funcs = helpers.funcs +local fn = helpers.fn local insert = helpers.insert local nvim_prog = helpers.nvim_prog local new_argv = helpers.new_argv @@ -42,7 +42,7 @@ describe('Remote', function() -- Run a `nvim --remote*` command and return { stdout, stderr } of the process local function run_remote(...) set_session(server) - local addr = funcs.serverlist()[1] + local addr = fn.serverlist()[1] -- Create an nvim instance just to run the remote-invoking nvim. We want -- to wait for the remote instance to exit and calling jobwait blocks @@ -51,7 +51,10 @@ describe('Remote', function() local client_starter = spawn(new_argv(), false, nil, true) set_session(client_starter) -- Call jobstart() and jobwait() in the same RPC request to reduce flakiness. - eq({ 0 }, exec_lua([[return vim.fn.jobwait({ vim.fn.jobstart({...}, { + eq( + { 0 }, + exec_lua( + [[return vim.fn.jobwait({ vim.fn.jobstart({...}, { stdout_buffered = true, stderr_buffered = true, on_stdout = function(_, data, _) @@ -60,7 +63,15 @@ describe('Remote', function() on_stderr = function(_, data, _) _G.Remote_stderr = table.concat(data, '\n') end, - }) })]], nvim_prog, '--clean', '--headless', '--server', addr, ...)) + }) })]], + nvim_prog, + '--clean', + '--headless', + '--server', + addr, + ... + ) + ) local res = exec_lua([[return { _G.Remote_stdout, _G.Remote_stderr }]]) client_starter:close() set_session(server) @@ -70,20 +81,20 @@ describe('Remote', function() it('edit a single file', function() eq({ '', '' }, run_remote('--remote', fname)) expect(contents) - eq(2, #funcs.getbufinfo()) + eq(1, #fn.getbufinfo()) end) it('tab edit a single file with a non-changed buffer', function() eq({ '', '' }, run_remote('--remote-tab', fname)) expect(contents) - eq(1, #funcs.gettabinfo()) + eq(1, #fn.gettabinfo()) end) it('tab edit a single file with a changed buffer', function() insert('hello') eq({ '', '' }, run_remote('--remote-tab', fname)) expect(contents) - eq(2, #funcs.gettabinfo()) + eq(2, #fn.gettabinfo()) end) it('edit multiple files', function() @@ -91,15 +102,15 @@ describe('Remote', function() expect(contents) command('next') expect(other_contents) - eq(3, #funcs.getbufinfo()) + eq(2, #fn.getbufinfo()) end) it('send keys', function() - eq({ '', '' }, run_remote('--remote-send', ':edit '..fname..'<CR><C-W>v')) + eq({ '', '' }, run_remote('--remote-send', ':edit ' .. fname .. '<CR><C-W>v')) expect(contents) - eq(2, #funcs.getwininfo()) + eq(2, #fn.getwininfo()) -- Only a single buffer as we're using edit and not drop like --remote does - eq(1, #funcs.getbufinfo()) + eq(1, #fn.getbufinfo()) end) it('evaluate expressions', function() @@ -116,7 +127,7 @@ describe('Remote', function() it('creates server if not found', function() clear('--remote', fname) expect(contents) - eq(1, #funcs.getbufinfo()) + eq(1, #fn.getbufinfo()) -- Since we didn't pass silent, we should get a complaint neq(nil, string.find(exec_capture('messages'), 'E247:')) end) @@ -124,8 +135,8 @@ describe('Remote', function() it('creates server if not found with tabs', function() clear('--remote-tab-silent', fname, other_fname) expect(contents) - eq(2, #funcs.gettabinfo()) - eq(2, #funcs.getbufinfo()) + eq(2, #fn.gettabinfo()) + eq(2, #fn.getbufinfo()) -- We passed silent, so no message should be issued about the server not being found eq(nil, string.find(exec_capture('messages'), 'E247:')) end) diff --git a/test/functional/core/spellfile_spec.lua b/test/functional/core/spellfile_spec.lua index e3a59085cf..57953b8f80 100644 --- a/test/functional/core/spellfile_spec.lua +++ b/test/functional/core/spellfile_spec.lua @@ -2,8 +2,9 @@ local helpers = require('test.functional.helpers')(after_each) local eq = helpers.eq local clear = helpers.clear -local meths = helpers.meths +local api = helpers.api local exc_exec = helpers.exc_exec +local fn = helpers.fn local rmdir = helpers.rmdir local write_file = helpers.write_file local mkdir = helpers.mkdir @@ -24,7 +25,8 @@ describe('spellfile', function() -- │ ┌ Spell file version (#VIMSPELLVERSION) local spellheader = 'VIMspell\050' it('errors out when prefcond section is truncated', function() - meths.set_option_value('runtimepath', testdir, {}) + api.nvim_set_option_value('runtimepath', testdir, {}) + -- stylua: ignore write_file(testdir .. '/spell/en.ascii.spl', -- ┌ Section identifier (#SN_PREFCOND) -- │ ┌ Section flags (#SNF_REQUIRED or zero) @@ -34,12 +36,12 @@ describe('spellfile', function() -- │ ┌ Condition length (1 byte) -- │ │ ┌ Condition regex (missing!) .. '\000\001\001') - meths.set_option_value('spelllang', 'en', {}) - eq('Vim(set):E758: Truncated spell file', - exc_exec('set spell')) + api.nvim_set_option_value('spelllang', 'en', {}) + eq('Vim(set):E758: Truncated spell file', exc_exec('set spell')) end) it('errors out when prefcond regexp contains NUL byte', function() - meths.set_option_value('runtimepath', testdir, {}) + api.nvim_set_option_value('runtimepath', testdir, {}) + -- stylua: ignore write_file(testdir .. '/spell/en.ascii.spl', -- ┌ Section identifier (#SN_PREFCOND) -- │ ┌ Section flags (#SNF_REQUIRED or zero) @@ -54,12 +56,12 @@ describe('spellfile', function() -- │ ┌ KWORDTREE tree length (4 bytes) -- │ │ ┌ PREFIXTREE tree length .. '\000\000\000\000\000\000\000\000\000\000\000\000') - meths.set_option_value('spelllang', 'en', {}) - eq('Vim(set):E759: Format error in spell file', - exc_exec('set spell')) + api.nvim_set_option_value('spelllang', 'en', {}) + eq('Vim(set):E759: Format error in spell file', exc_exec('set spell')) end) it('errors out when region contains NUL byte', function() - meths.set_option_value('runtimepath', testdir, {}) + api.nvim_set_option_value('runtimepath', testdir, {}) + -- stylua: ignore write_file(testdir .. '/spell/en.ascii.spl', -- ┌ Section identifier (#SN_REGION) -- │ ┌ Section flags (#SNF_REQUIRED or zero) @@ -71,12 +73,12 @@ describe('spellfile', function() -- │ ┌ KWORDTREE tree length (4 bytes) -- │ │ ┌ PREFIXTREE tree length .. '\000\000\000\000\000\000\000\000\000\000\000\000') - meths.set_option_value('spelllang', 'en', {}) - eq('Vim(set):E759: Format error in spell file', - exc_exec('set spell')) + api.nvim_set_option_value('spelllang', 'en', {}) + eq('Vim(set):E759: Format error in spell file', exc_exec('set spell')) end) it('errors out when SAL section contains NUL byte', function() - meths.set_option_value('runtimepath', testdir, {}) + api.nvim_set_option_value('runtimepath', testdir, {}) + -- stylua: ignore write_file(testdir .. '/spell/en.ascii.spl', -- ┌ Section identifier (#SN_SAL) -- │ ┌ Section flags (#SNF_REQUIRED or zero) @@ -95,16 +97,23 @@ describe('spellfile', function() -- │ ┌ KWORDTREE tree length (4 bytes) -- │ │ ┌ PREFIXTREE tree length .. '\000\000\000\000\000\000\000\000\000\000\000\000') - meths.set_option_value('spelllang', 'en', {}) - eq('Vim(set):E759: Format error in spell file', - exc_exec('set spell')) + api.nvim_set_option_value('spelllang', 'en', {}) + eq('Vim(set):E759: Format error in spell file', exc_exec('set spell')) end) it('errors out when spell header contains NUL bytes', function() - meths.set_option_value('runtimepath', testdir, {}) - write_file(testdir .. '/spell/en.ascii.spl', - spellheader:sub(1, -3) .. '\000\000') - meths.set_option_value('spelllang', 'en', {}) - eq('Vim(set):E757: This does not look like a spell file', - exc_exec('set spell')) + api.nvim_set_option_value('runtimepath', testdir, {}) + write_file(testdir .. '/spell/en.ascii.spl', spellheader:sub(1, -3) .. '\000\000') + api.nvim_set_option_value('spelllang', 'en', {}) + eq('Vim(set):E757: This does not look like a spell file', exc_exec('set spell')) + end) + + it('can be set to a relative path', function() + local fname = testdir .. '/spell/spell.add' + api.nvim_set_option_value('spellfile', fname, {}) + end) + + it('can be set to an absolute path', function() + local fname = fn.fnamemodify(testdir .. '/spell/spell.add', ':p') + api.nvim_set_option_value('spellfile', fname, {}) end) end) diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index 94ec3d4907..cc58226f48 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -13,8 +13,8 @@ local exec = helpers.exec local exec_capture = helpers.exec_capture local exec_lua = helpers.exec_lua local feed = helpers.feed -local funcs = helpers.funcs -local pesc = helpers.pesc +local fn = helpers.fn +local pesc = vim.pesc local mkdir = helpers.mkdir local mkdir_p = helpers.mkdir_p local nvim_prog = helpers.nvim_prog @@ -22,23 +22,37 @@ local nvim_set = helpers.nvim_set local read_file = helpers.read_file local retry = helpers.retry local rmdir = helpers.rmdir -local sleep = helpers.sleep -local startswith = helpers.startswith +local sleep = vim.uv.sleep +local startswith = vim.startswith local write_file = helpers.write_file -local meths = helpers.meths +local api = helpers.api local alter_slashes = helpers.alter_slashes local is_os = helpers.is_os local dedent = helpers.dedent -local tbl_map = helpers.tbl_map -local tbl_filter = helpers.tbl_filter -local endswith = helpers.endswith +local tbl_map = vim.tbl_map +local tbl_filter = vim.tbl_filter +local endswith = vim.endswith describe('startup', function() it('--clean', function() clear() - ok(string.find(alter_slashes(meths.get_option_value('runtimepath', {})), funcs.stdpath('config'), 1, true) ~= nil) + ok( + string.find( + alter_slashes(api.nvim_get_option_value('runtimepath', {})), + fn.stdpath('config'), + 1, + true + ) ~= nil + ) clear('--clean') - ok(string.find(alter_slashes(meths.get_option_value('runtimepath', {})), funcs.stdpath('config'), 1, true) == nil) + ok( + string.find( + alter_slashes(api.nvim_get_option_value('runtimepath', {})), + fn.stdpath('config'), + 1, + true + ) == nil + ) end) it('prevents remote UI infinite loop', function() @@ -46,11 +60,10 @@ describe('startup', function() local screen screen = Screen.new(84, 3) screen:attach() - funcs.termopen({ nvim_prog, '-u', 'NONE', '--server', eval('v:servername'), '--remote-ui' }) + fn.termopen({ nvim_prog, '-u', 'NONE', '--server', eval('v:servername'), '--remote-ui' }) screen:expect([[ ^Cannot attach UI of :terminal child to its parent. (Unset $NVIM to skip this check) | - | - | + |*2 ]]) end) @@ -59,7 +72,8 @@ describe('startup', function() finally(function() os.remove(testfile) end) - clear({ args = {'--startuptime', testfile}}) + clear({ args = { '--startuptime', testfile } }) + assert_log('Embedded', testfile, 100) assert_log('sourcing', testfile, 100) assert_log("require%('vim%._editor'%)", testfile, 100) end) @@ -69,8 +83,20 @@ describe('startup', function() local screen screen = Screen.new(60, 7) screen:attach() - command([[let g:id = termopen('"]]..nvim_prog.. - [[" -u NONE -i NONE --cmd "set noruler" -D')]]) + local id = fn.termopen({ + nvim_prog, + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + 'set noruler', + '-D', + }, { + env = { + VIMRUNTIME = os.getenv('VIMRUNTIME'), + }, + }) screen:expect([[ ^ | | @@ -80,15 +106,12 @@ describe('startup', function() > | | ]]) - command([[call chansend(g:id, "cont\n")]]) + fn.chansend(id, 'cont\n') screen:expect([[ ^ | - ~ | - ~ | - ~ | + ~ |*3 [No Name] | - | - | + |*2 ]]) end) end) @@ -102,13 +125,13 @@ describe('startup', function() vim.list_extend(args, nvim_args or {}) vim.list_extend(args, { '-l', (script or 'test/functional/fixtures/startup.lua') }) vim.list_extend(args, lua_args or {}) - local out = funcs.system(args, input):gsub('\r\n', '\n') + local out = fn.system(args, input):gsub('\r\n', '\n') return eq(dedent(expected), out) end it('failure modes', function() -- nvim -l <empty> - matches('nvim%.?e?x?e?: Argument missing after: "%-l"', funcs.system({ nvim_prog, '-l' })) + matches('nvim%.?e?x?e?: Argument missing after: "%-l"', fn.system({ nvim_prog, '-l' })) eq(1, eval('v:shell_error')) end) @@ -122,39 +145,48 @@ describe('startup', function() vim.uv.os_setenv('ASAN_OPTIONS', asan_options .. ':detect_leaks=0') ]] -- nvim -l foo.lua -arg1 -- a b c - assert_l_out([[ + assert_l_out( + [[ bufs: nvim args: 7 lua args: { "-arg1", "--exitcode", "73", "--arg2", [0] = "test/functional/fixtures/startup.lua" }]], {}, - { '-arg1', "--exitcode", "73", '--arg2' } + { '-arg1', '--exitcode', '73', '--arg2' } ) eq(73, eval('v:shell_error')) end) it('Lua-error sets Nvim exitcode', function() eq(0, eval('v:shell_error')) - matches('E5113: .* my pearls!!', - funcs.system({ nvim_prog, '-l', 'test/functional/fixtures/startup-fail.lua' })) + matches( + 'E5113: .* my pearls!!', + fn.system({ nvim_prog, '-l', 'test/functional/fixtures/startup-fail.lua' }) + ) eq(1, eval('v:shell_error')) - matches('E5113: .* %[string "error%("whoa"%)"%]:1: whoa', - funcs.system({ nvim_prog, '-l', '-' }, 'error("whoa")')) + matches( + 'E5113: .* %[string "error%("whoa"%)"%]:1: whoa', + fn.system({ nvim_prog, '-l', '-' }, 'error("whoa")') + ) eq(1, eval('v:shell_error')) end) it('executes stdin "-"', function() - assert_l_out('arg0=- args=2 whoa\n', + assert_l_out( + 'arg0=- args=2 whoa\n', nil, { 'arg1', 'arg 2' }, '-', - "print(('arg0=%s args=%d %s'):format(_G.arg[0], #_G.arg, 'whoa'))") - assert_l_out('biiig input: 1000042\n', + "print(('arg0=%s args=%d %s'):format(_G.arg[0], #_G.arg, 'whoa'))" + ) + assert_l_out( + 'biiig input: 1000042\n', nil, nil, '-', - ('print("biiig input: "..("%s"):len())'):format(string.rep('x', (1000 * 1000) + 42))) + ('print("biiig input: "..("%s"):len())'):format(string.rep('x', (1000 * 1000) + 42)) + ) eq(0, eval('v:shell_error')) end) @@ -169,7 +201,8 @@ describe('startup', function() it('sets _G.arg', function() -- nvim -l foo.lua - assert_l_out([[ + assert_l_out( + [[ bufs: nvim args: 3 lua args: { @@ -182,7 +215,8 @@ describe('startup', function() eq(0, eval('v:shell_error')) -- nvim -l foo.lua [args] - assert_l_out([[ + assert_l_out( + [[ bufs: nvim args: 7 lua args: { "-arg1", "--arg2", "--", "arg3", @@ -195,20 +229,22 @@ describe('startup', function() eq(0, eval('v:shell_error')) -- nvim file1 file2 -l foo.lua -arg1 -- file3 file4 - assert_l_out([[ + assert_l_out( + [[ bufs: file1 file2 nvim args: 10 lua args: { "-arg1", "arg 2", "--", "file3", "file4", [0] = "test/functional/fixtures/startup.lua" } ]], - { 'file1', 'file2', }, + { 'file1', 'file2' }, { '-arg1', 'arg 2', '--', 'file3', 'file4' } ) eq(0, eval('v:shell_error')) -- nvim -l foo.lua <vim args> - assert_l_out([[ + assert_l_out( + [[ bufs: nvim args: 5 lua args: { "-c", "set wrap?", @@ -239,30 +275,50 @@ describe('startup', function() end) it('disables swapfile/shada/config/plugins', function() - assert_l_out('updatecount=0 shadafile=NONE loadplugins=false scripts=1\n', + assert_l_out( + 'updatecount=0 shadafile=NONE loadplugins=false scripts=1\n', nil, nil, '-', [[print(('updatecount=%d shadafile=%s loadplugins=%s scripts=%d'):format( - vim.o.updatecount, vim.o.shadafile, tostring(vim.o.loadplugins), math.max(1, #vim.fn.getscriptinfo())))]]) + vim.o.updatecount, vim.o.shadafile, tostring(vim.o.loadplugins), math.max(1, #vim.fn.getscriptinfo())))]] + ) end) end) it('--cmd/-c/+ do not truncate long Lua print() message with --headless', function() - local out = funcs.system({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless', - '--cmd', 'lua print(("A"):rep(1234))', - '-c', 'lua print(("B"):rep(1234))', - '+lua print(("C"):rep(1234))', - '+q' }) + local out = fn.system({ + nvim_prog, + '-u', + 'NONE', + '-i', + 'NONE', + '--headless', + '--cmd', + 'lua print(("A"):rep(1234))', + '-c', + 'lua print(("B"):rep(1234))', + '+lua print(("C"):rep(1234))', + '+q', + }) eq(('A'):rep(1234) .. '\r\n' .. ('B'):rep(1234) .. '\r\n' .. ('C'):rep(1234), out) end) it('pipe at both ends: has("ttyin")==0 has("ttyout")==0', function() -- system() puts a pipe at both ends. - local out = funcs.system({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless', - '--cmd', nvim_set, - '-c', [[echo has('ttyin') has('ttyout')]], - '+q' }) + local out = fn.system({ + nvim_prog, + '-u', + 'NONE', + '-i', + 'NONE', + '--headless', + '--cmd', + nvim_set, + '-c', + [[echo has('ttyin') has('ttyout')]], + '+q', + }) eq('0 0', out) end) @@ -285,10 +341,21 @@ describe('startup', function() command([[set shellcmdflag=/s\ /c shellxquote=\"]]) end -- Running in :terminal - command([[exe printf("terminal %s -u NONE -i NONE --cmd \"]] - ..nvim_set..[[\"]] - ..[[ -c \"echo has('ttyin') has('ttyout')\""]] - ..[[, shellescape(v:progpath))]]) + fn.termopen({ + nvim_prog, + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + nvim_set, + '-c', + 'echo has("ttyin") has("ttyout")', + }, { + env = { + VIMRUNTIME = os.getenv('VIMRUNTIME'), + }, + }) screen:expect([[ ^ | ~ | @@ -306,15 +373,24 @@ describe('startup', function() os.remove('Xtest_startup_ttyout') end) -- Running in :terminal - command([[exe printf("terminal %s -u NONE -i NONE --cmd \"]] - ..nvim_set..[[\"]] - ..[[ -c \"call writefile([has('ttyin'), has('ttyout')], 'Xtest_startup_ttyout')\"]] - ..[[ -c q | cat -v"]] -- Output to a pipe. - ..[[, shellescape(v:progpath))]]) + fn.termopen( + ( + [["%s" -u NONE -i NONE --cmd "%s"]] + .. [[ -c "call writefile([has('ttyin'), has('ttyout')], 'Xtest_startup_ttyout')"]] + .. [[ -c q | cat -v]] + ):format(nvim_prog, nvim_set), + { + env = { + VIMRUNTIME = os.getenv('VIMRUNTIME'), + }, + } + ) retry(nil, 3000, function() sleep(1) - eq('1\n0\n', -- stdin is a TTY, stdout is a pipe - read_file('Xtest_startup_ttyout')) + eq( + '1\n0\n', -- stdin is a TTY, stdout is a pipe + read_file('Xtest_startup_ttyout') + ) end) end) @@ -327,16 +403,25 @@ describe('startup', function() os.remove('Xtest_startup_ttyout') end) -- Running in :terminal - command([[exe printf("terminal echo foo | ]] -- Input from a pipe. - ..[[%s -u NONE -i NONE --cmd \"]] - ..nvim_set..[[\"]] - ..[[ -c \"call writefile([has('ttyin'), has('ttyout')], 'Xtest_startup_ttyout')\"]] - ..[[ -c q -- -"]] - ..[[, shellescape(v:progpath))]]) + fn.termopen( + ( + [[echo foo | ]] -- Input from a pipe. + .. [["%s" -u NONE -i NONE --cmd "%s"]] + .. [[ -c "call writefile([has('ttyin'), has('ttyout')], 'Xtest_startup_ttyout')"]] + .. [[ -c q -- -]] + ):format(nvim_prog, nvim_set), + { + env = { + VIMRUNTIME = os.getenv('VIMRUNTIME'), + }, + } + ) retry(nil, 3000, function() sleep(1) - eq('0\n1\n', -- stdin is a pipe, stdout is a TTY - read_file('Xtest_startup_ttyout')) + eq( + '0\n1\n', -- stdin is a pipe, stdout is a TTY + read_file('Xtest_startup_ttyout') + ) end) end) @@ -347,11 +432,18 @@ describe('startup', function() command([[set shellcmdflag=/s\ /c shellxquote=\"]]) end -- Running in :terminal - command([[exe printf("terminal echo foo | ]] -- Input from a pipe. - ..[[%s -u NONE -i NONE --cmd \"]] - ..nvim_set..[[\"]] - ..[[ -c \"echo has('ttyin') has('ttyout')\""]] - ..[[, shellescape(v:progpath))]]) + fn.termopen( + ( + [[echo foo | ]] + .. [["%s" -u NONE -i NONE --cmd "%s"]] + .. [[ -c "echo has('ttyin') has('ttyout')"]] + ):format(nvim_prog, nvim_set), + { + env = { + VIMRUNTIME = os.getenv('VIMRUNTIME'), + }, + } + ) screen:expect([[ ^foo | ~ | @@ -361,28 +453,44 @@ describe('startup', function() end) it('input from pipe + file args #7679', function() - eq('ohyeah\r\n0 0 bufs=3', - funcs.system({nvim_prog, '-n', '-u', 'NONE', '-i', 'NONE', '--headless', - '+.print', - "+echo has('ttyin') has('ttyout') 'bufs='.bufnr('$')", - '+qall!', - '-', - 'test/functional/fixtures/tty-test.c', - 'test/functional/fixtures/shell-test.c', - }, - { 'ohyeah', '' })) + eq( + 'ohyeah\r\n0 0 bufs=3', + fn.system({ + nvim_prog, + '-n', + '-u', + 'NONE', + '-i', + 'NONE', + '--headless', + '+.print', + "+echo has('ttyin') has('ttyout') 'bufs='.bufnr('$')", + '+qall!', + '-', + 'test/functional/fixtures/tty-test.c', + 'test/functional/fixtures/shell-test.c', + }, { 'ohyeah', '' }) + ) end) it('if stdin is empty: selects buffer 2, deletes buffer 1 #8561', function() - eq('\r\n 2 %a "file1" line 0\r\n 3 "file2" line 0', - funcs.system({nvim_prog, '-n', '-u', 'NONE', '-i', 'NONE', '--headless', - '+ls!', - '+qall!', - '-', - 'file1', - 'file2', - }, - { '' })) + eq( + '\r\n 2 %a "file1" line 0\r\n 3 "file2" line 0', + fn.system({ + nvim_prog, + '-n', + '-u', + 'NONE', + '-i', + 'NONE', + '--headless', + '+ls!', + '+qall!', + '-', + 'file1', + 'file2', + }, { '' }) + ) end) it('stdin with -es/-Es #7679', function() @@ -392,48 +500,70 @@ describe('startup', function() -- -- -Es: read stdin as text -- - eq('partylikeits1999\n', - funcs.system({nvim_prog, '-n', '-u', 'NONE', '-i', 'NONE', '-Es', '+.print', 'test/functional/fixtures/tty-test.c' }, - { 'partylikeits1999', '' })) - eq(inputstr, - funcs.system({nvim_prog, '-i', 'NONE', '-Es', '+%print', '-' }, - input)) + eq( + 'partylikeits1999\n', + fn.system({ + nvim_prog, + '-n', + '-u', + 'NONE', + '-i', + 'NONE', + '-Es', + '+.print', + 'test/functional/fixtures/tty-test.c', + }, { 'partylikeits1999', '' }) + ) + eq(inputstr, fn.system({ nvim_prog, '-i', 'NONE', '-Es', '+%print', '-' }, input)) -- with `-u NORC` - eq('thepartycontinues\n', - funcs.system({nvim_prog, '-n', '-u', 'NORC', '-Es', '+.print' }, - { 'thepartycontinues', '' })) + eq( + 'thepartycontinues\n', + fn.system({ nvim_prog, '-n', '-u', 'NORC', '-Es', '+.print' }, { 'thepartycontinues', '' }) + ) -- without `-u` - eq('thepartycontinues\n', - funcs.system({nvim_prog, '-n', '-Es', '+.print' }, - { 'thepartycontinues', '' })) + eq( + 'thepartycontinues\n', + fn.system({ nvim_prog, '-n', '-Es', '+.print' }, { 'thepartycontinues', '' }) + ) -- -- -es: read stdin as ex-commands -- - eq(' encoding=utf-8\n', - funcs.system({nvim_prog, '-n', '-u', 'NONE', '-i', 'NONE', '-es', 'test/functional/fixtures/tty-test.c' }, - { 'set encoding', '' })) - eq('line1\nline2\n', - funcs.system({nvim_prog, '-i', 'NONE', '-es', '-' }, - input)) + eq( + ' encoding=utf-8\n', + fn.system({ + nvim_prog, + '-n', + '-u', + 'NONE', + '-i', + 'NONE', + '-es', + 'test/functional/fixtures/tty-test.c', + }, { 'set encoding', '' }) + ) + eq('line1\nline2\n', fn.system({ nvim_prog, '-i', 'NONE', '-es', '-' }, input)) -- with `-u NORC` - eq(' encoding=utf-8\n', - funcs.system({nvim_prog, '-n', '-u', 'NORC', '-es' }, - { 'set encoding', '' })) + eq( + ' encoding=utf-8\n', + fn.system({ nvim_prog, '-n', '-u', 'NORC', '-es' }, { 'set encoding', '' }) + ) -- without `-u` - eq(' encoding=utf-8\n', - funcs.system({nvim_prog, '-n', '-es' }, - { 'set encoding', '' })) + eq(' encoding=utf-8\n', fn.system({ nvim_prog, '-n', '-es' }, { 'set encoding', '' })) end) it('-es/-Es disables swapfile, user config #8540', function() - for _,arg in ipairs({'-es', '-Es'}) do - local out = funcs.system({nvim_prog, arg, - '+set swapfile? updatecount? shadafile?', - "+put =map(getscriptinfo(), {-> v:val.name})", '+%print'}) + for _, arg in ipairs({ '-es', '-Es' }) do + local out = fn.system({ + nvim_prog, + arg, + '+set swapfile? updatecount? shadafile?', + '+put =map(getscriptinfo(), {-> v:val.name})', + '+%print', + }) local line1 = string.match(out, '^.-\n') -- updatecount=0 means swapfile was disabled. - eq(" swapfile updatecount=0 shadafile=\n", line1) + eq(' swapfile updatecount=0 shadafile=\n', line1) -- Standard plugins were loaded, but not user config. ok(string.find(out, 'man.lua') ~= nil) ok(string.find(out, 'init.vim') == nil) @@ -441,20 +571,39 @@ describe('startup', function() end) it('fails on --embed with -es/-Es/-l', function() - matches('nvim[.exe]*: %-%-embed conflicts with %-es/%-Es/%-l', - funcs.system({nvim_prog, '--embed', '-es' })) - matches('nvim[.exe]*: %-%-embed conflicts with %-es/%-Es/%-l', - funcs.system({nvim_prog, '--embed', '-Es' })) - matches('nvim[.exe]*: %-%-embed conflicts with %-es/%-Es/%-l', - funcs.system({nvim_prog, '--embed', '-l', 'foo.lua' })) + matches( + 'nvim[.exe]*: %-%-embed conflicts with %-es/%-Es/%-l', + fn.system({ nvim_prog, '--embed', '-es' }) + ) + matches( + 'nvim[.exe]*: %-%-embed conflicts with %-es/%-Es/%-l', + fn.system({ nvim_prog, '--embed', '-Es' }) + ) + matches( + 'nvim[.exe]*: %-%-embed conflicts with %-es/%-Es/%-l', + fn.system({ nvim_prog, '--embed', '-l', 'foo.lua' }) + ) end) it('ENTER dismisses early message #7967', function() local screen screen = Screen.new(60, 6) screen:attach() - command([[let g:id = termopen('"]]..nvim_prog.. - [[" -u NONE -i NONE --cmd "set noruler" --cmd "let g:foo = g:bar"')]]) + local id = fn.termopen({ + nvim_prog, + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + 'set noruler', + '--cmd', + 'let g:foo = g:bar', + }, { + env = { + VIMRUNTIME = os.getenv('VIMRUNTIME'), + }, + }) screen:expect([[ ^ | | @@ -463,14 +612,12 @@ describe('startup', function() Press ENTER or type command to continue | | ]]) - command([[call chansend(g:id, "\n")]]) + fn.chansend(id, '\n') screen:expect([[ ^ | - ~ | - ~ | + ~ |*2 [No Name] | - | - | + |*2 ]]) end) @@ -505,19 +652,32 @@ describe('startup', function() expected, -- FIXME(codehex): We should really set a timeout for the system function. -- If this test fails, there will be a waiting input state. - funcs.system({nvim_prog, '-u', 'NONE', '-c', + fn.system({ + nvim_prog, + '-u', + 'NONE', + '-c', 'for i in range(1, 100) | echo i | endfor | quit', - '--headless' + '--headless', }) ) end) - it("get command line arguments from v:argv", function() - local out = funcs.system({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless', - '--cmd', nvim_set, - '-c', [[echo v:argv[-1:] len(v:argv) > 1]], - '+q' }) - eq('[\'+q\'] 1', out) + it('get command line arguments from v:argv', function() + local out = fn.system({ + nvim_prog, + '-u', + 'NONE', + '-i', + 'NONE', + '--headless', + '--cmd', + nvim_set, + '-c', + [[echo v:argv[-1:] len(v:argv) > 1]], + '+q', + }) + eq("['+q'] 1", out) end) end) @@ -549,20 +709,20 @@ describe('startup', function() clear('-e') screen:attach() -- Verify we set the proper mode both before and after :vi. - feed("put =mode(1)<CR>vi<CR>:put =mode(1)<CR>") + feed('put =mode(1)<CR>vi<CR>:put =mode(1)<CR>') screen:expect([[ cv | ^n | :put =mode(1) | ]]) - eq('cv\n', - funcs.system({nvim_prog, '-n', '-es' }, - { 'put =mode(1)', 'print', '' })) + eq('cv\n', fn.system({ nvim_prog, '-n', '-es' }, { 'put =mode(1)', 'print', '' })) end) it('-d does not diff non-arglist windows #13720 #21289', function() - write_file('Xdiff.vim', [[ + write_file( + 'Xdiff.vim', + [[ let bufnr = nvim_create_buf(0, 1) let config = { \ 'relative': 'editor', @@ -572,78 +732,92 @@ describe('startup', function() \ 'row': 3, \ 'col': 3 \ } - autocmd WinEnter * call nvim_open_win(bufnr, v:false, config)]]) + autocmd WinEnter * call nvim_open_win(bufnr, v:false, config)]] + ) finally(function() os.remove('Xdiff.vim') end) - clear{args={'-u', 'Xdiff.vim', '-d', 'Xdiff.vim', 'Xdiff.vim'}} - eq(true, meths.get_option_value('diff', {win = funcs.win_getid(1)})) - eq(true, meths.get_option_value('diff', {win = funcs.win_getid(2)})) - local float_win = funcs.win_getid(3) - eq('editor', meths.win_get_config(float_win).relative) - eq(false, meths.get_option_value('diff', {win = float_win})) + clear { args = { '-u', 'Xdiff.vim', '-d', 'Xdiff.vim', 'Xdiff.vim' } } + eq(true, api.nvim_get_option_value('diff', { win = fn.win_getid(1) })) + eq(true, api.nvim_get_option_value('diff', { win = fn.win_getid(2) })) + local float_win = fn.win_getid(3) + eq('editor', api.nvim_win_get_config(float_win).relative) + eq(false, api.nvim_get_option_value('diff', { win = float_win })) end) it('does not crash if --embed is given twice', function() - clear{args={'--embed'}} + clear { args = { '--embed' } } assert_alive() end) it('does not crash when expanding cdpath during early_init', function() - clear{env={CDPATH='~doesnotexist'}} + clear { env = { CDPATH = '~doesnotexist' } } assert_alive() eq(',~doesnotexist', eval('&cdpath')) end) it("sets 'shortmess' when loading other tabs", function() - clear({args={'-p', 'a', 'b', 'c'}}) + clear({ args = { '-p', 'a', 'b', 'c' } }) local screen = Screen.new(25, 4) screen:attach() - screen:expect({grid=[[ + screen:expect({ + grid = [[ {1: a }{2: b c }{3: }{2:X}| ^ | {4:~ }| | ]], - attr_ids={ - [1] = {bold = true}, - [2] = {background = Screen.colors.LightGrey, underline = true}, - [3] = {reverse = true}, - [4] = {bold = true, foreground = Screen.colors.Blue1}, - }}) + attr_ids = { + [1] = { bold = true }, + [2] = { background = Screen.colors.LightGrey, underline = true }, + [3] = { reverse = true }, + [4] = { bold = true, foreground = Screen.colors.Blue1 }, + }, + }) end) end) describe('startup', function() local function pack_clear(cmd) -- add packages after config dir in rtp but before config/after - clear{args={'--cmd', 'set packpath=test/functional/fixtures', '--cmd', 'let paths=split(&rtp, ",")', '--cmd', 'let &rtp = paths[0]..",test/functional/fixtures,test/functional/fixtures/middle,"..join(paths[1:],",")', '--cmd', cmd}, env={XDG_CONFIG_HOME='test/functional/fixtures/'}, - args_rm={'runtimepath'}, + clear { + args = { + '--cmd', + 'set packpath=test/functional/fixtures', + '--cmd', + 'let paths=split(&rtp, ",")', + '--cmd', + 'let &rtp = paths[0]..",test/functional/fixtures,test/functional/fixtures/middle,"..join(paths[1:],",")', + '--cmd', + cmd, + }, + env = { XDG_CONFIG_HOME = 'test/functional/fixtures/' }, + args_rm = { 'runtimepath' }, } end - it("handles &packpath during startup", function() + it('handles &packpath during startup', function() pack_clear [[ let g:x = bar#test() let g:y = leftpad#pad("heyya") ]] eq(-3, eval 'g:x') - eq(" heyya", eval 'g:y') + eq(' heyya', eval 'g:y') pack_clear [[ lua _G.y = require'bar'.doit() _G.z = require'leftpad''howdy' ]] - eq({9003, '\thowdy'}, exec_lua [[ return { _G.y, _G.z } ]]) + eq({ 9003, '\thowdy' }, exec_lua [[ return { _G.y, _G.z } ]]) end) - it("handles require from &packpath in an async handler", function() - -- NO! you cannot just speed things up by calling async functions during startup! - -- It doesn't make anything actually faster! NOOOO! + it('handles require from &packpath in an async handler', function() + -- NO! you cannot just speed things up by calling async functions during startup! + -- It doesn't make anything actually faster! NOOOO! pack_clear [[ lua require'async_leftpad'('brrrr', 'async_res') ]] -- haha, async leftpad go brrrrr eq('\tbrrrr', exec_lua [[ return _G.async_res ]]) end) - it("handles :packadd during startup", function() + it('handles :packadd during startup', function() -- control group: opt/bonus is not available by default pack_clear [[ try @@ -655,8 +829,10 @@ describe('startup', function() eq('Vim(let):E117: Unknown function: bonus#secret', eval 'g:err') pack_clear [[ lua _G.test = {pcall(function() require'bonus'.launch() end)} ]] - eq({false, [[[string ":lua"]:1: module 'bonus' not found:]]}, - exec_lua [[ _G.test[2] = string.gsub(_G.test[2], '[\r\n].*', '') return _G.test ]]) + eq( + { false, [[[string ":lua"]:1: module 'bonus' not found:]] }, + exec_lua [[ _G.test[2] = string.gsub(_G.test[2], '[\r\n].*', '') return _G.test ]] + ) -- ok, time to launch the nukes: pack_clear [[ packadd! bonus | let g:x = bonus#secret() ]] @@ -666,46 +842,77 @@ describe('startup', function() eq('CPE 1704 TKS', exec_lua [[ return _G.y ]]) end) - it("handles the correct order with start packages and after/", function() + it('handles the correct order with start packages and after/', function() pack_clear [[ lua _G.test_loadorder = {} vim.cmd "runtime! filen.lua" ]] - eq({'ordinary', 'FANCY', 'mittel', 'FANCY after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]]) + eq( + { 'ordinary', 'FANCY', 'mittel', 'FANCY after', 'ordinary after' }, + exec_lua [[ return _G.test_loadorder ]] + ) end) - it("handles the correct order with start packages and after/ after startup", function() + it('handles the correct order with start packages and after/ after startup', function() pack_clear [[ lua _G.test_loadorder = {} ]] command [[ runtime! filen.lua ]] - eq({'ordinary', 'FANCY', 'mittel', 'FANCY after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]]) + eq( + { 'ordinary', 'FANCY', 'mittel', 'FANCY after', 'ordinary after' }, + exec_lua [[ return _G.test_loadorder ]] + ) end) - it("handles the correct order with globpath(&rtp, ...)", function() + it('handles the correct order with globpath(&rtp, ...)', function() pack_clear [[ set loadplugins | lua _G.test_loadorder = {} ]] command [[ for x in globpath(&rtp, "filen.lua",1,1) call v:lua.dofile(x) endfor ]] - eq({'ordinary', 'FANCY', 'mittel', 'FANCY after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]]) + eq( + { 'ordinary', 'FANCY', 'mittel', 'FANCY after', 'ordinary after' }, + exec_lua [[ return _G.test_loadorder ]] + ) - local rtp = meths.get_option_value('rtp', {}) - ok(startswith(rtp, 'test/functional/fixtures/nvim,test/functional/fixtures/pack/*/start/*,test/functional/fixtures/start/*,test/functional/fixtures,test/functional/fixtures/middle,'), - 'startswith(…)', 'rtp='..rtp) + local rtp = api.nvim_get_option_value('rtp', {}) + ok( + startswith( + rtp, + 'test/functional/fixtures/nvim,test/functional/fixtures/pack/*/start/*,test/functional/fixtures/start/*,test/functional/fixtures,test/functional/fixtures/middle,' + ), + 'startswith(…)', + 'rtp=' .. rtp + ) end) - it("handles the correct order with opt packages and after/", function() + it('handles the correct order with opt packages and after/', function() pack_clear [[ lua _G.test_loadorder = {} vim.cmd "packadd! superspecial\nruntime! filen.lua" ]] - eq({'ordinary', 'SuperSpecial', 'FANCY', 'mittel', 'FANCY after', 'SuperSpecial after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]]) + eq({ + 'ordinary', + 'SuperSpecial', + 'FANCY', + 'mittel', + 'FANCY after', + 'SuperSpecial after', + 'ordinary after', + }, exec_lua [[ return _G.test_loadorder ]]) end) - it("handles the correct order with opt packages and after/ after startup", function() + it('handles the correct order with opt packages and after/ after startup', function() pack_clear [[ lua _G.test_loadorder = {} ]] command [[ packadd! superspecial runtime! filen.lua ]] - eq({'ordinary', 'SuperSpecial', 'FANCY', 'mittel', 'FANCY after', 'SuperSpecial after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]]) + eq({ + 'ordinary', + 'SuperSpecial', + 'FANCY', + 'mittel', + 'FANCY after', + 'SuperSpecial after', + 'ordinary after', + }, exec_lua [[ return _G.test_loadorder ]]) end) - it("handles the correct order with opt packages and globpath(&rtp, ...)", function() + it('handles the correct order with opt packages and globpath(&rtp, ...)', function() pack_clear [[ set loadplugins | lua _G.test_loadorder = {} ]] command [[ packadd! superspecial @@ -713,18 +920,40 @@ describe('startup', function() call v:lua.dofile(x) endfor ]] - eq({'ordinary', 'SuperSpecial', 'FANCY', 'mittel', 'SuperSpecial after', 'FANCY after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]]) + eq({ + 'ordinary', + 'SuperSpecial', + 'FANCY', + 'mittel', + 'SuperSpecial after', + 'FANCY after', + 'ordinary after', + }, exec_lua [[ return _G.test_loadorder ]]) end) - it("handles the correct order with a package that changes packpath", function() + it('handles the correct order with a package that changes packpath', function() pack_clear [[ lua _G.test_loadorder = {} vim.cmd "packadd! funky\nruntime! filen.lua" ]] - eq({'ordinary', 'funky!', 'FANCY', 'mittel', 'FANCY after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]]) - eq({'ordinary', 'funky!', 'mittel', 'ordinary after'}, exec_lua [[ return _G.nested_order ]]) + eq( + { 'ordinary', 'funky!', 'FANCY', 'mittel', 'FANCY after', 'ordinary after' }, + exec_lua [[ return _G.test_loadorder ]] + ) + eq({ 'ordinary', 'funky!', 'mittel', 'ordinary after' }, exec_lua [[ return _G.nested_order ]]) end) - it("handles the correct order when prepending packpath", function() - clear{args={'--cmd', 'set packpath^=test/functional/fixtures', '--cmd', [[ lua _G.test_loadorder = {} vim.cmd "runtime! filen.lua" ]]}, env={XDG_CONFIG_HOME='test/functional/fixtures/'}} - eq({'ordinary', 'FANCY', 'FANCY after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]]) + it('handles the correct order when prepending packpath', function() + clear { + args = { + '--cmd', + 'set packpath^=test/functional/fixtures', + '--cmd', + [[ lua _G.test_loadorder = {} vim.cmd "runtime! filen.lua" ]], + }, + env = { XDG_CONFIG_HOME = 'test/functional/fixtures/' }, + } + eq( + { 'ordinary', 'FANCY', 'FANCY after', 'ordinary after' }, + exec_lua [[ return _G.test_loadorder ]] + ) end) it('window widths are correct when modelines set &columns with tabpages', function() @@ -734,10 +963,10 @@ describe('startup', function() os.remove('Xtab1.noft') os.remove('Xtab2.noft') end) - clear({args = {'-p', 'Xtab1.noft', 'Xtab2.noft'}}) - eq(81, meths.win_get_width(0)) + clear({ args = { '-p', 'Xtab1.noft', 'Xtab2.noft' } }) + eq(81, api.nvim_win_get_width(0)) command('tabnext') - eq(81, meths.win_get_width(0)) + eq(81, api.nvim_win_get_width(0)) end) end) @@ -754,16 +983,22 @@ describe('sysinit', function() mkdir(xdgdir) mkdir(xdgdir .. pathsep .. 'nvim') - write_file(table.concat({xdgdir, 'nvim', 'sysinit.vim'}, pathsep), [[ + write_file( + table.concat({ xdgdir, 'nvim', 'sysinit.vim' }, pathsep), + [[ let g:loaded = get(g:, "loaded", 0) + 1 let g:xdg = 1 - ]]) + ]] + ) mkdir(vimdir) - write_file(table.concat({vimdir, 'sysinit.vim'}, pathsep), [[ + write_file( + table.concat({ vimdir, 'sysinit.vim' }, pathsep), + [[ let g:loaded = get(g:, "loaded", 0) + 1 let g:vim = 1 - ]]) + ]] + ) mkdir(xhome) end) @@ -774,23 +1009,27 @@ describe('sysinit', function() end) it('prefers XDG_CONFIG_DIRS over VIM', function() - clear{args={'--cmd', 'set nomore undodir=. directory=. belloff='}, - args_rm={'-u', '--cmd'}, - env={ HOME=xhome, - XDG_CONFIG_DIRS=xdgdir, - VIM=vimdir }} - eq('loaded 1 xdg 1 vim 0', - eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))')) + clear { + args = { '--cmd', 'set nomore undodir=. directory=. belloff=' }, + args_rm = { '-u', '--cmd' }, + env = { HOME = xhome, XDG_CONFIG_DIRS = xdgdir, VIM = vimdir }, + } + eq( + 'loaded 1 xdg 1 vim 0', + eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))') + ) end) it('uses VIM if XDG_CONFIG_DIRS unset', function() - clear{args={'--cmd', 'set nomore undodir=. directory=. belloff='}, - args_rm={'-u', '--cmd'}, - env={ HOME=xhome, - XDG_CONFIG_DIRS='', - VIM=vimdir }} - eq('loaded 1 xdg 0 vim 1', - eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))')) + clear { + args = { '--cmd', 'set nomore undodir=. directory=. belloff=' }, + args_rm = { '-u', '--cmd' }, + env = { HOME = xhome, XDG_CONFIG_DIRS = '', VIM = vimdir }, + } + eq( + 'loaded 1 xdg 0 vim 1', + eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))') + ) end) end) @@ -799,8 +1038,8 @@ describe('user config init', function() local pathsep = helpers.get_pathsep() local xconfig = xhome .. pathsep .. 'Xconfig' local xdata = xhome .. pathsep .. 'Xdata' - local init_lua_path = table.concat({xconfig, 'nvim', 'init.lua'}, pathsep) - local xenv = { XDG_CONFIG_HOME=xconfig, XDG_DATA_HOME=xdata } + local init_lua_path = table.concat({ xconfig, 'nvim', 'init.lua' }, pathsep) + local xenv = { XDG_CONFIG_HOME = xconfig, XDG_DATA_HOME = xdata } before_each(function() rmdir(xhome) @@ -808,9 +1047,12 @@ describe('user config init', function() mkdir_p(xconfig .. pathsep .. 'nvim') mkdir_p(xdata) - write_file(init_lua_path, [[ + write_file( + init_lua_path, + [[ vim.g.lua_rc = 1 - ]]) + ]] + ) end) after_each(function() @@ -818,36 +1060,51 @@ describe('user config init', function() end) it('loads init.lua from XDG config home by default', function() - clear{ args_rm={'-u'}, env=xenv } + clear { args_rm = { '-u' }, env = xenv } eq(1, eval('g:lua_rc')) - eq(funcs.fnamemodify(init_lua_path, ':p'), eval('$MYVIMRC')) + eq(fn.fnamemodify(init_lua_path, ':p'), eval('$MYVIMRC')) end) describe('loads existing', function() local exrc_path = '.exrc' local xstate = 'Xstate' - local xstateenv = { XDG_CONFIG_HOME=xconfig, XDG_DATA_HOME=xdata, XDG_STATE_HOME=xstate } + local xstateenv = { XDG_CONFIG_HOME = xconfig, XDG_DATA_HOME = xdata, XDG_STATE_HOME = xstate } local function setup_exrc_file(filename) exrc_path = filename - if string.find(exrc_path, "%.lua$") then - write_file(exrc_path, string.format([[ + if string.find(exrc_path, '%.lua$') then + write_file( + exrc_path, + string.format( + [[ vim.g.exrc_file = "%s" - ]], exrc_path)) + ]], + exrc_path + ) + ) else - write_file(exrc_path, string.format([[ + write_file( + exrc_path, + string.format( + [[ let g:exrc_file = "%s" - ]], exrc_path)) + ]], + exrc_path + ) + ) end end before_each(function() - write_file(init_lua_path, [[ + write_file( + init_lua_path, + [[ vim.o.exrc = true vim.g.exrc_file = '---' - ]]) + ]] + ) mkdir_p(xstate .. pathsep .. (is_os('win') and 'nvim-data' or 'nvim')) end) @@ -860,39 +1117,41 @@ describe('user config init', function() it(filename .. ' in cwd', function() setup_exrc_file(filename) - clear{ args_rm={'-u'}, env=xstateenv } + clear { args_rm = { '-u' }, env = xstateenv } -- The 'exrc' file is not trusted, and the prompt is skipped because there is no UI. eq('---', eval('g:exrc_file')) local screen = Screen.new(50, 8) screen:attach() - funcs.termopen({nvim_prog}) + fn.termopen({ nvim_prog }, { + env = { + VIMRUNTIME = os.getenv('VIMRUNTIME'), + }, + }) screen:expect({ any = pesc('[i]gnore, (v)iew, (d)eny, (a)llow:') }) -- `i` to enter Terminal mode, `a` to allow feed('ia') screen:expect([[ | - ~ | - ~ | - ~ | - ~ | + ~ |*4 [No Name] 0,0-1 All| | -- TERMINAL -- | ]]) feed(':echo g:exrc_file<CR>') - screen:expect(string.format([[ + screen:expect(string.format( + [[ | - ~ | - ~ | - ~ | - ~ | + ~ |*4 [No Name] 0,0-1 All| %s%s| -- TERMINAL -- | - ]], filename, string.rep(' ', 50 - #filename))) + ]], + filename, + string.rep(' ', 50 - #filename) + )) - clear{ args_rm={'-u'}, env=xstateenv } + clear { args_rm = { '-u' }, env = xstateenv } -- The 'exrc' file is now trusted. eq(filename, eval('g:exrc_file')) end) @@ -900,15 +1159,18 @@ describe('user config init', function() end) describe('with explicitly provided config', function() - local custom_lua_path = table.concat({xhome, 'custom.lua'}, pathsep) + local custom_lua_path = table.concat({ xhome, 'custom.lua' }, pathsep) before_each(function() - write_file(custom_lua_path, [[ + write_file( + custom_lua_path, + [[ vim.g.custom_lua_rc = 1 - ]]) + ]] + ) end) it('loads custom lua config and does not set $MYVIMRC', function() - clear{ args={'-u', custom_lua_path }, env=xenv } + clear { args = { '-u', custom_lua_path }, env = xenv } eq(1, eval('g:custom_lua_rc')) eq('', eval('$MYVIMRC')) end) @@ -916,14 +1178,17 @@ describe('user config init', function() describe('VIMRC also exists', function() before_each(function() - write_file(table.concat({xconfig, 'nvim', 'init.vim'}, pathsep), [[ + write_file( + table.concat({ xconfig, 'nvim', 'init.vim' }, pathsep), + [[ let g:vim_rc = 1 - ]]) + ]] + ) end) it('loads default lua config, but shows an error', function() - clear{ args_rm={'-u'}, env=xenv } - feed('<cr><c-c>') -- Dismiss "Conflicting config …" message. + clear { args_rm = { '-u' }, env = xenv } + feed('<cr><c-c>') -- Dismiss "Conflicting config …" message. eq(1, eval('g:lua_rc')) matches('^E5422: Conflicting configs', exec_capture('messages')) end) @@ -935,7 +1200,7 @@ describe('runtime:', function() local pathsep = helpers.get_pathsep() local xconfig = xhome .. pathsep .. 'Xconfig' local xdata = xhome .. pathsep .. 'Xdata' - local xenv = { XDG_CONFIG_HOME=xconfig, XDG_DATA_HOME=xdata } + local xenv = { XDG_CONFIG_HOME = xconfig, XDG_DATA_HOME = xdata } setup(function() rmdir(xhome) @@ -948,23 +1213,24 @@ describe('runtime:', function() end) it('loads plugin/*.lua from XDG config home', function() - local plugin_folder_path = table.concat({xconfig, 'nvim', 'plugin'}, pathsep) - local plugin_file_path = table.concat({plugin_folder_path, 'plugin.lua'}, pathsep) + local plugin_folder_path = table.concat({ xconfig, 'nvim', 'plugin' }, pathsep) + local plugin_file_path = table.concat({ plugin_folder_path, 'plugin.lua' }, pathsep) mkdir_p(plugin_folder_path) finally(function() rmdir(plugin_folder_path) end) write_file(plugin_file_path, [[ vim.g.lua_plugin = 1 ]]) - clear{ args_rm={'-u'}, env=xenv } + clear { args_rm = { '-u' }, env = xenv } eq(1, eval('g:lua_plugin')) end) it('loads plugin/*.lua from start packages', function() - local plugin_path = table.concat({xconfig, 'nvim', 'pack', 'category', 'start', 'test_plugin'}, pathsep) - local plugin_folder_path = table.concat({plugin_path, 'plugin'}, pathsep) - local plugin_file_path = table.concat({plugin_folder_path, 'plugin.lua'}, pathsep) + local plugin_path = + table.concat({ xconfig, 'nvim', 'pack', 'category', 'start', 'test_plugin' }, pathsep) + local plugin_folder_path = table.concat({ plugin_path, 'plugin' }, pathsep) + local plugin_file_path = table.concat({ plugin_folder_path, 'plugin.lua' }, pathsep) local profiler_file = 'test_startuptime.log' mkdir_p(plugin_folder_path) finally(function() @@ -974,12 +1240,16 @@ describe('runtime:', function() write_file(plugin_file_path, [[vim.g.lua_plugin = 2]]) - clear{ args_rm={'-u'}, args={'--startuptime', profiler_file}, env=xenv } + clear { args_rm = { '-u' }, args = { '--startuptime', profiler_file }, env = xenv } eq(2, eval('g:lua_plugin')) -- Check if plugin_file_path is listed in getscriptinfo() - local scripts = tbl_map(function(s) return s.name end, funcs.getscriptinfo()) - ok(#tbl_filter(function(s) return endswith(s, plugin_file_path) end, scripts) > 0) + local scripts = tbl_map(function(s) + return s.name + end, fn.getscriptinfo()) + ok(#tbl_filter(function(s) + return endswith(s, plugin_file_path) + end, scripts) > 0) -- Check if plugin_file_path is listed in startup profile local profile_reader = io.open(profiler_file, 'r') @@ -989,12 +1259,13 @@ describe('runtime:', function() end) it('loads plugin/*.lua from site packages', function() - local nvimdata = is_os('win') and "nvim-data" or "nvim" - local plugin_path = table.concat({xdata, nvimdata, 'site', 'pack', 'xa', 'start', 'yb'}, pathsep) - local plugin_folder_path = table.concat({plugin_path, 'plugin'}, pathsep) - local plugin_after_path = table.concat({plugin_path, 'after', 'plugin'}, pathsep) - local plugin_file_path = table.concat({plugin_folder_path, 'plugin.lua'}, pathsep) - local plugin_after_file_path = table.concat({plugin_after_path, 'helloo.lua'}, pathsep) + local nvimdata = is_os('win') and 'nvim-data' or 'nvim' + local plugin_path = + table.concat({ xdata, nvimdata, 'site', 'pack', 'xa', 'start', 'yb' }, pathsep) + local plugin_folder_path = table.concat({ plugin_path, 'plugin' }, pathsep) + local plugin_after_path = table.concat({ plugin_path, 'after', 'plugin' }, pathsep) + local plugin_file_path = table.concat({ plugin_folder_path, 'plugin.lua' }, pathsep) + local plugin_after_file_path = table.concat({ plugin_after_path, 'helloo.lua' }, pathsep) mkdir_p(plugin_folder_path) mkdir_p(plugin_after_path) finally(function() @@ -1004,49 +1275,64 @@ describe('runtime:', function() write_file(plugin_file_path, [[table.insert(_G.lista, "unos")]]) write_file(plugin_after_file_path, [[table.insert(_G.lista, "dos")]]) - clear{ args_rm={'-u'}, args={'--cmd', 'lua _G.lista = {}'}, env=xenv } + clear { args_rm = { '-u' }, args = { '--cmd', 'lua _G.lista = {}' }, env = xenv } - eq({'unos', 'dos'}, exec_lua "return _G.lista") + eq({ 'unos', 'dos' }, exec_lua 'return _G.lista') end) it('no crash setting &rtp in plugins with :packloadall called before #18315', function() - local plugin_folder_path = table.concat({xconfig, 'nvim', 'plugin'}, pathsep) + local plugin_folder_path = table.concat({ xconfig, 'nvim', 'plugin' }, pathsep) mkdir_p(plugin_folder_path) finally(function() rmdir(plugin_folder_path) end) - write_file(table.concat({plugin_folder_path, 'plugin.vim'}, pathsep), [[ + write_file( + table.concat({ plugin_folder_path, 'plugin.vim' }, pathsep), + [[ let &runtimepath = &runtimepath let g:vim_plugin = 1 - ]]) - write_file(table.concat({plugin_folder_path, 'plugin.lua'}, pathsep), [[ + ]] + ) + write_file( + table.concat({ plugin_folder_path, 'plugin.lua' }, pathsep), + [[ vim.o.runtimepath = vim.o.runtimepath vim.g.lua_plugin = 1 - ]]) + ]] + ) - clear{ args_rm={'-u'}, args = {'--cmd', 'packloadall'}, env=xenv } + clear { args_rm = { '-u' }, args = { '--cmd', 'packloadall' }, env = xenv } eq(1, eval('g:vim_plugin')) eq(1, eval('g:lua_plugin')) end) it("loads ftdetect/*.{vim,lua} respecting 'rtp' order", function() - local ftdetect_folder = table.concat({xconfig, 'nvim', 'ftdetect'}, pathsep) - local after_ftdetect_folder = table.concat({xconfig, 'nvim', 'after', 'ftdetect'}, pathsep) + local ftdetect_folder = table.concat({ xconfig, 'nvim', 'ftdetect' }, pathsep) + local after_ftdetect_folder = table.concat({ xconfig, 'nvim', 'after', 'ftdetect' }, pathsep) mkdir_p(ftdetect_folder) mkdir_p(after_ftdetect_folder) finally(function() rmdir(ftdetect_folder) rmdir(after_ftdetect_folder) end) - -- A .lua file is loaded after a .vim file if they only differ in extension. - -- All files in after/ftdetect/ are loaded after all files in ftdetect/. - write_file(table.concat({ftdetect_folder, 'new-ft.vim'}, pathsep), [[let g:seq ..= 'A']]) - write_file(table.concat({ftdetect_folder, 'new-ft.lua'}, pathsep), [[vim.g.seq = vim.g.seq .. 'B']]) - write_file(table.concat({after_ftdetect_folder, 'new-ft.vim'}, pathsep), [[let g:seq ..= 'a']]) - write_file(table.concat({after_ftdetect_folder, 'new-ft.lua'}, pathsep), [[vim.g.seq = vim.g.seq .. 'b']]) - clear{ args_rm={'-u'}, args = {'--cmd', 'let g:seq = ""'}, env=xenv } + -- A .lua file is loaded after a .vim file if they only differ in extension. + -- All files in after/ftdetect/ are loaded after all files in ftdetect/. + write_file(table.concat({ ftdetect_folder, 'new-ft.vim' }, pathsep), [[let g:seq ..= 'A']]) + write_file( + table.concat({ ftdetect_folder, 'new-ft.lua' }, pathsep), + [[vim.g.seq = vim.g.seq .. 'B']] + ) + write_file( + table.concat({ after_ftdetect_folder, 'new-ft.vim' }, pathsep), + [[let g:seq ..= 'a']] + ) + write_file( + table.concat({ after_ftdetect_folder, 'new-ft.lua' }, pathsep), + [[vim.g.seq = vim.g.seq .. 'b']] + ) + clear { args_rm = { '-u' }, args = { '--cmd', 'let g:seq = ""' }, env = xenv } eq('ABab', eval('g:seq')) end) end) @@ -1054,15 +1340,18 @@ end) describe('user session', function() local xhome = 'Xhome' local pathsep = helpers.get_pathsep() - local session_file = table.concat({xhome, 'session.lua'}, pathsep) + local session_file = table.concat({ xhome, 'session.lua' }, pathsep) before_each(function() rmdir(xhome) mkdir(xhome) - write_file(session_file, [[ + write_file( + session_file, + [[ vim.g.lua_session = 1 - ]]) + ]] + ) end) after_each(function() @@ -1070,7 +1359,45 @@ describe('user session', function() end) it('loads session from the provided lua file', function() - clear{ args={'-S', session_file }, env={ HOME=xhome }} + clear { args = { '-S', session_file }, env = { HOME = xhome } } eq(1, eval('g:lua_session')) end) end) + +describe('inccommand on ex mode', function() + it('should not preview', function() + clear() + local screen + screen = Screen.new(60, 10) + screen:attach() + local id = fn.termopen({ + nvim_prog, + '-u', + 'NONE', + '-i', + 'NONE', + '-c', + 'set termguicolors background=dark', + '-E', + 'test/README.md', + }, { + env = { VIMRUNTIME = os.getenv('VIMRUNTIME') }, + }) + fn.chansend(id, '%s/N') + screen:expect { + grid = [[ + {1:^ }| + {1: }|*6 + {1:Entering Ex mode. Type "visual" to go to Normal mode. }| + {1::%s/N }| + | + ]], + attr_ids = { + [1] = { + background = Screen.colors.NvimDarkGrey2, + foreground = Screen.colors.NvimLightGrey2, + }, + }, + } + end) +end) diff --git a/test/functional/editor/K_spec.lua b/test/functional/editor/K_spec.lua index b964fb3467..1fbdd1c142 100644 --- a/test/functional/editor/K_spec.lua +++ b/test/functional/editor/K_spec.lua @@ -1,6 +1,6 @@ local helpers = require('test.functional.helpers')(after_each) -local eq, clear, eval, feed, meths, retry = - helpers.eq, helpers.clear, helpers.eval, helpers.feed, helpers.meths, helpers.retry +local eq, clear, eval, feed, api, retry = + helpers.eq, helpers.clear, helpers.eval, helpers.feed, helpers.api, helpers.retry describe('K', function() local test_file = 'K_spec_out' @@ -30,13 +30,15 @@ describe('K', function() set keywordprg=echo\ fnord>>]]) -- K on the text "K_spec_out" resolves to `!echo fnord >> K_spec_out`. - feed('i'..test_file..'<ESC>K') - retry(nil, nil, function() eq(1, eval('filereadable("'..test_file..'")')) end) - eq({'fnord'}, eval("readfile('"..test_file.."')")) + feed('i' .. test_file .. '<ESC>K') + retry(nil, nil, function() + eq(1, eval('filereadable("' .. test_file .. '")')) + end) + eq({ 'fnord' }, eval("readfile('" .. test_file .. "')")) -- Confirm that Neovim is still in terminal mode after K is pressed (#16692). - helpers.sleep(500) + vim.uv.sleep(500) eq('t', eval('mode()')) - feed('<space>') -- Any key, not just <space>, can be used here to escape. + feed('<space>') -- Any key, not just <space>, can be used here to escape. eq('n', eval('mode()')) end) @@ -48,7 +50,7 @@ describe('K', function() -- Confirm that an arbitrary keypress doesn't escape (i.e., the process is -- still running). If the process were no longer running, an arbitrary -- keypress would escape. - helpers.sleep(500) + vim.uv.sleep(500) feed('<space>') eq('t', eval('mode()')) -- Confirm that <esc> kills the buffer for the running command. @@ -59,10 +61,9 @@ describe('K', function() end) it('empty string falls back to :help #19298', function() - meths.set_option_value('keywordprg', '', {}) - meths.buf_set_lines(0, 0, -1, true, {'doesnotexist'}) + api.nvim_set_option_value('keywordprg', '', {}) + api.nvim_buf_set_lines(0, 0, -1, true, { 'doesnotexist' }) feed('K') - eq('E149: Sorry, no help for doesnotexist', meths.get_vvar('errmsg')) + eq('E149: Sorry, no help for doesnotexist', api.nvim_get_vvar('errmsg')) end) - end) diff --git a/test/functional/editor/completion_spec.lua b/test/functional/editor/completion_spec.lua index cbaf401f06..33d0d47499 100644 --- a/test/functional/editor/completion_spec.lua +++ b/test/functional/editor/completion_spec.lua @@ -4,10 +4,9 @@ local assert_alive = helpers.assert_alive local clear, feed = helpers.clear, helpers.feed local eval, eq, neq = helpers.eval, helpers.eq, helpers.neq local feed_command, source, expect = helpers.feed_command, helpers.source, helpers.expect -local funcs = helpers.funcs -local curbufmeths = helpers.curbufmeths +local fn = helpers.fn local command = helpers.command -local meths = helpers.meths +local api = helpers.api local poke_eventloop = helpers.poke_eventloop describe('completion', function() @@ -18,17 +17,17 @@ describe('completion', function() screen = Screen.new(60, 8) screen:attach() screen:set_default_attr_ids({ - [0] = {bold=true, foreground=Screen.colors.Blue}, - [1] = {background = Screen.colors.LightMagenta}, - [2] = {background = Screen.colors.Grey}, - [3] = {bold = true}, - [4] = {bold = true, foreground = Screen.colors.SeaGreen}, - [5] = {foreground = Screen.colors.Red}, - [6] = {background = Screen.colors.Black}, - [7] = {foreground = Screen.colors.White, background = Screen.colors.Red}, - [8] = {reverse = true}, - [9] = {bold = true, reverse = true}, - [10] = {foreground = Screen.colors.Grey0, background = Screen.colors.Yellow}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { background = Screen.colors.LightMagenta }, + [2] = { background = Screen.colors.Grey }, + [3] = { bold = true }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen }, + [5] = { foreground = Screen.colors.Red }, + [6] = { background = Screen.colors.Black }, + [7] = { foreground = Screen.colors.White, background = Screen.colors.Red }, + [8] = { reverse = true }, + [9] = { bold = true, reverse = true }, + [10] = { foreground = Screen.colors.Grey0, background = Screen.colors.Yellow }, }) end) @@ -41,22 +40,14 @@ describe('completion', function() screen:expect([[ foo | foo^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- Keyword Local completion (^N^P) The only match} | ]]) feed('<C-e>') screen:expect([[ foo | ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- INSERT --} | ]]) feed('<ESC>') @@ -65,9 +56,10 @@ describe('completion', function() it('returns expected dict in normal completion', function() feed('ifoo<ESC>o<C-x><C-n>') eq('foo', eval('getline(2)')) - eq({word = 'foo', abbr = '', menu = '', - info = '', kind = '', user_data = ''}, - eval('v:completed_item')) + eq( + { word = 'foo', abbr = '', menu = '', info = '', kind = '', user_data = '' }, + eval('v:completed_item') + ) end) it('is readonly', function() screen:try_resize(80, 8) @@ -112,15 +104,17 @@ describe('completion', function() foo^ | {2:bar foobaz baz }{0: }| {1:abbr kind menu }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- Omni completion (^O^N^P) }{4:match 1 of 2} | ]]) - eq({word = 'foo', abbr = 'bar', menu = 'baz', - info = 'foobar', kind = 'foobaz', user_data = ''}, - eval('v:completed_item')) + eq({ + word = 'foo', + abbr = 'bar', + menu = 'baz', + info = 'foobar', + kind = 'foobaz', + user_data = '', + }, eval('v:completed_item')) end) end) @@ -140,11 +134,7 @@ describe('completion', function() screen:expect([[ foo | ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- INSERT --} | ]]) feed('<C-x>') @@ -152,11 +142,7 @@ describe('completion', function() screen:expect([[ foo | ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)} | ]]) feed('<C-n>') @@ -164,10 +150,7 @@ describe('completion', function() foo | foo^ | {2:foo }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- Keyword Local completion (^N^P) The only match} | ]]) feed('bar<ESC>') @@ -178,9 +161,7 @@ describe('completion', function() foobar | foo^ | {2:foo }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- INSERT --} | ]]) eq('foo', eval('getline(3)')) @@ -192,34 +173,24 @@ describe('completion', function() foo | ^ | {2:foo }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- Keyword Local completion (^N^P) The only match} | ]]) feed('<C-y>') screen:expect([[ foo | foo^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- INSERT --} | ]]) feed('<ESC>') eq('foo', eval('getline(2)')) feed('o<C-r>=TestComplete()<CR>') screen:expect([[ - foo | - foo | + foo |*2 ^ | {2:foo }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- INSERT --} | ]]) feed('<C-y><ESC>') @@ -232,21 +203,14 @@ describe('completion', function() foo | ^ | {1:foo }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- Keyword Local completion (^N^P) }{5:Back at original} | ]]) feed('b') screen:expect([[ foo | b^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- Keyword Local completion (^N^P) }{5:Back at original} | ]]) feed('ar<ESC>') @@ -257,9 +221,7 @@ describe('completion', function() bar | ^ | {1:foo }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- INSERT --} | ]]) feed('bar<ESC>') @@ -272,21 +234,14 @@ describe('completion', function() foo | ^ | {1:foo }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- Keyword Local completion (^N^P) }{5:Back at original} | ]]) feed('<ESC>') screen:expect([[ foo | ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) eq('', eval('getline(2)')) @@ -296,9 +251,7 @@ describe('completion', function() | ^ | {1:foo }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- INSERT --} | ]]) feed('<ESC>') @@ -306,10 +259,7 @@ describe('completion', function() foo | | ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) eq('', eval('getline(3)')) @@ -341,8 +291,8 @@ describe('completion', function() end) local tests = { - ['<up>, <down>, <cr>'] = {'<down><cr>', '<up><cr>'}, - ['<c-n>, <c-p>, <c-y>'] = {'<c-n><c-y>', '<c-p><c-y>'}, + ['<up>, <down>, <cr>'] = { '<down><cr>', '<up><cr>' }, + ['<c-n>, <c-p>, <c-y>'] = { '<c-n><c-y>', '<c-p><c-y>' }, } for name, seq in pairs(tests) do @@ -358,13 +308,13 @@ describe('completion', function() feed('A<right><esc>A<right><esc>') local expected = { - {'foo', 'bar', 'foo'}, - {'foo', 'bar', 'ccc'}, - {'foo', 'bar'}, - {'foo', 'bbb'}, - {'foo'}, - {'aaa'}, - {''}, + { 'foo', 'bar', 'foo' }, + { 'foo', 'bar', 'ccc' }, + { 'foo', 'bar' }, + { 'foo', 'bbb' }, + { 'foo' }, + { 'aaa' }, + { '' }, } for i = 1, #expected do @@ -384,7 +334,7 @@ describe('completion', function() end end) - describe("refresh:always", function() + describe('refresh:always', function() before_each(function() source([[ function! TestCompletion(findstart, base) abort @@ -409,9 +359,9 @@ describe('completion', function() set completeopt=menuone,noselect set completefunc=TestCompletion ]]) - end ) + end) - it('completes on each input char', function () + it('completes on each input char', function() feed('i<C-x><C-u>') screen:expect([[ ^ | @@ -438,48 +388,32 @@ describe('completion', function() screen:expect([[ ug^ | {1:August }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- User defined completion (^U^N^P) }{5:Back at original} | ]]) feed('<Down>') screen:expect([[ ug^ | {2:August }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- User defined completion (^U^N^P) The only match} | ]]) feed('<C-y>') screen:expect([[ August^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 {3:-- INSERT --} | ]]) expect('August') end) - it("repeats correctly after backspace #2674", function () + it('repeats correctly after backspace #2674', function() feed('o<C-x><C-u>Ja') screen:expect([[ | Ja^ | {1:January }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- User defined completion (^U^N^P) }{5:Back at original} | ]]) feed('<BS>') @@ -489,8 +423,7 @@ describe('completion', function() {1:January }{0: }| {1:June }{0: }| {1:July }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:-- User defined completion (^U^N^P) }{5:Back at original} | ]]) feed('<C-n>') @@ -500,8 +433,7 @@ describe('completion', function() {2:January }{0: }| {1:June }{0: }| {1:July }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:-- User defined completion (^U^N^P) }{4:match 1 of 3} | ]]) feed('<C-n>') @@ -511,19 +443,14 @@ describe('completion', function() {1:January }{0: }| {2:June }{0: }| {1:July }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:-- User defined completion (^U^N^P) }{4:match 2 of 3} | ]]) feed('<Esc>') screen:expect([[ | Jun^e | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) feed('.') @@ -531,10 +458,7 @@ describe('completion', function() | June | Jun^e | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) expect([[ @@ -552,10 +476,10 @@ describe('completion', function() return '' endfunction ]]) - feed_command("set completeopt=menuone,noselect") + feed_command('set completeopt=menuone,noselect') end) - it("works", function() + it('works', function() feed('i<C-r>=TestComplete()<CR>') screen:expect([[ ^ | @@ -705,18 +629,13 @@ describe('completion', function() feed('<cr>') screen:expect([[ 96^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 {3:-- INSERT --} | ]]) end) end) - it("does not indent until an item is selected #8345", function () + it('does not indent until an item is selected #8345', function() -- Indents on "ind", unindents on "unind". source([[ function! TestIndent() @@ -735,129 +654,106 @@ describe('completion', function() ]]) -- Give some words to complete. - feed("iinc uninc indent unindent<CR>") + feed('iinc uninc indent unindent<CR>') -- Does not indent when "ind" is typed. - feed("in<C-X><C-N>") + feed('in<C-X><C-N>') -- Completion list is generated incorrectly if we send everything at once -- via nvim_input(). So poke_eventloop() before sending <BS>. #8480 poke_eventloop() - feed("<BS>d") + feed('<BS>d') screen:expect([[ inc uninc indent unindent | ind^ | {2:indent }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- Keyword Local completion (^N^P) }{4:match 1 of 2} | ]]) -- Indents when the item is selected - feed("<C-Y>") + feed('<C-Y>') screen:expect([[ inc uninc indent unindent | indent^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- INSERT --} | ]]) -- Indents when completion is exited using ESC. - feed("<CR>in<C-N><BS>d<Esc>") + feed('<CR>in<C-N><BS>d<Esc>') screen:expect([[ inc uninc indent unindent | indent | in^d | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) -- Works for unindenting too. - feed("ounin<C-X><C-N>") - helpers.poke_eventloop() - feed("<BS>d") + feed('ounin<C-X><C-N>') + poke_eventloop() + feed('<BS>d') screen:expect([[ inc uninc indent unindent | indent | ind | unind^ | {0:~ }{2: unindent }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:-- Keyword Local completion (^N^P) }{4:match 1 of 2} | ]]) -- Works when going back and forth. - feed("<BS>c") + feed('<BS>c') screen:expect([[ inc uninc indent unindent | indent | ind | uninc^ | {0:~ }{2: uninc }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:-- Keyword Local completion (^N^P) }{4:match 1 of 2} | ]]) - feed("<BS>d") + feed('<BS>d') screen:expect([[ inc uninc indent unindent | indent | ind | unind^ | {0:~ }{2: unindent }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:-- Keyword Local completion (^N^P) }{4:match 1 of 2} | ]]) - feed("<C-N><C-N><C-Y><Esc>") + feed('<C-N><C-N><C-Y><Esc>') screen:expect([[ inc uninc indent unindent | indent | ind | uninden^t | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) end) - it('disables folding during completion', function () - feed_command("set foldmethod=indent") + it('disables folding during completion', function() + feed_command('set foldmethod=indent') feed('i<Tab>foo<CR><Tab>bar<Esc>gg') screen:expect([[ ^foo | bar | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) feed('A<C-x><C-l>') screen:expect([[ foo^ | bar | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- Whole line completion (^L^N^P) }{7:Pattern not found} | ]]) eq(-1, eval('foldclosed(1)')) end) - it('popupmenu is not interrupted by events', function () - feed_command("set complete=.") + it('popupmenu is not interrupted by events', function() + feed_command('set complete=.') feed('ifoobar fooegg<cr>f<c-p>') screen:expect([[ @@ -865,24 +761,23 @@ describe('completion', function() fooegg^ | {1:foobar }{0: }| {2:fooegg }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- Keyword completion (^N^P) }{4:match 1 of 2} | ]]) assert_alive() -- popupmenu still visible - screen:expect{grid=[[ + screen:expect { + grid = [[ foobar fooegg | fooegg^ | {1:foobar }{0: }| {2:fooegg }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- Keyword completion (^N^P) }{4:match 1 of 2} | - ]], unchanged=true} + ]], + unchanged = true, + } feed('<c-p>') -- Didn't restart completion: old matches still used @@ -891,9 +786,7 @@ describe('completion', function() foobar^ | {2:foobar }{0: }| {1:fooegg }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- Keyword completion (^N^P) }{4:match 2 of 2} | ]]) end) @@ -902,68 +795,62 @@ describe('completion', function() it('expands when there is only one match', function() feed(':lua CURRENT_TESTING_VAR = 1<CR>') feed(':lua CURRENT_TESTING_<TAB>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 :lua CURRENT_TESTING_VAR^ | - ]]} + ]], + } end) it('expands when there is only one match', function() feed(':lua CURRENT_TESTING_FOO = 1<CR>') feed(':lua CURRENT_TESTING_BAR = 1<CR>') feed(':lua CURRENT_TESTING_<TAB>') - screen:expect{ grid = [[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {10:CURRENT_TESTING_BAR}{9: CURRENT_TESTING_FOO }| :lua CURRENT_TESTING_BAR^ | - ]], unchanged = true } + ]], + unchanged = true, + } end) it('provides completion from `getcompletion()`', function() - eq({'vim'}, funcs.getcompletion('vi', 'lua')) - eq({'api'}, funcs.getcompletion('vim.ap', 'lua')) - eq({'tbl_filter'}, funcs.getcompletion('vim.tbl_fil', 'lua')) - eq({'vim'}, funcs.getcompletion('print(vi', 'lua')) + eq({ 'vim' }, fn.getcompletion('vi', 'lua')) + eq({ 'api' }, fn.getcompletion('vim.ap', 'lua')) + eq({ 'tbl_filter' }, fn.getcompletion('vim.tbl_fil', 'lua')) + eq({ 'vim' }, fn.getcompletion('print(vi', 'lua')) -- fuzzy completion is not supported, so the result should be the same command('set wildoptions+=fuzzy') - eq({'vim'}, funcs.getcompletion('vi', 'lua')) + eq({ 'vim' }, fn.getcompletion('vi', 'lua')) end) end) it('cmdline completion supports various string options', function() - eq('auto', funcs.getcompletion('set foldcolumn=', 'cmdline')[2]) - eq({'nosplit', 'split'}, funcs.getcompletion('set inccommand=', 'cmdline')) - eq({'ver:3,hor:6', 'hor:', 'ver:'}, funcs.getcompletion('set mousescroll=', 'cmdline')) - eq('BS', funcs.getcompletion('set termpastefilter=', 'cmdline')[2]) - eq('SpecialKey', funcs.getcompletion('set winhighlight=', 'cmdline')[1]) - eq('SpecialKey', funcs.getcompletion('set winhighlight=NonText:', 'cmdline')[1]) + eq('auto', fn.getcompletion('set foldcolumn=', 'cmdline')[2]) + eq({ 'nosplit', 'split' }, fn.getcompletion('set inccommand=', 'cmdline')) + eq({ 'ver:3,hor:6', 'hor:', 'ver:' }, fn.getcompletion('set mousescroll=', 'cmdline')) + eq('BS', fn.getcompletion('set termpastefilter=', 'cmdline')[2]) + eq('SpecialKey', fn.getcompletion('set winhighlight=', 'cmdline')[1]) + eq('SpecialKey', fn.getcompletion('set winhighlight=NonText:', 'cmdline')[1]) end) describe('from the commandline window', function() - it('is cleared after CTRL-C', function () + it('is cleared after CTRL-C', function() feed('q:') feed('ifoo faa fee f') screen:expect([[ | {8:[No Name] }| {0::}foo faa fee f^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {9:[Command Line] }| {3:-- INSERT --} | - ]] ) + ]]) feed('<c-x><c-n>') screen:expect([[ | @@ -980,9 +867,7 @@ describe('completion', function() | {8:[No Name] }| {0::}foo faa fee foo | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {9:[Command Line] }| :foo faa fee foo^ | ]]) @@ -997,17 +882,19 @@ describe('completion', function() return '' endfunction ]]) - meths.set_option_value('completeopt', 'menuone,noselect', {}) - meths.set_var('_complist', {{ - word=0, - abbr=1, - menu=2, - kind=3, - info=4, - icase=5, - dup=6, - empty=7, - }}) + api.nvim_set_option_value('completeopt', 'menuone,noselect', {}) + api.nvim_set_var('_complist', { + { + word = 0, + abbr = 1, + menu = 2, + kind = 3, + info = 4, + icase = 5, + dup = 6, + empty = 7, + }, + }) end) it('shows correct variant as word', function() @@ -1015,11 +902,7 @@ describe('completion', function() screen:expect([[ ^ | {1:1 3 2 }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- INSERT --} | ]]) end) @@ -1027,22 +910,24 @@ describe('completion', function() it("'ignorecase' 'infercase' CTRL-X CTRL-N #6451", function() feed_command('set ignorecase infercase') - feed_command('edit BACKERS.md') + feed_command('edit runtime/doc/backers.txt') feed('oX<C-X><C-N>') - screen:expect([[ - # Bountysource Backers | + screen:expect { + grid = [[ + *backers.txt* Nvim | Xnull^ | {2:Xnull }{6: } | - {1:Xoxomoon }{6: }ryone who backed our [Bountysource fundraise| - {1:Xu }{6: }ountysource.com/teams/neovim/fundraiser)! | + {1:Xoxomoon }{6: } | + {1:Xu }{6: } NVIM REFERENCE MANUAL | {1:Xpayn }{2: } | - {1:Xinity }{2: }d URL in BACKERS.md. | + {1:Xinity }{2: } | {3:-- Keyword Local completion (^N^P) }{4:match 1 of 7} | - ]]) + ]], + } end) it('CompleteChanged autocommand', function() - curbufmeths.set_lines(0, 1, false, { 'foo', 'bar', 'foobar', ''}) + api.nvim_buf_set_lines(0, 0, 1, false, { 'foo', 'bar', 'foobar', '' }) source([[ set complete=. completeopt=noinsert,noselect,menuone function! OnPumChange() @@ -1057,43 +942,45 @@ describe('completion', function() -- v:event.size should be set with ext_popupmenu #20646 screen:set_option('ext_popupmenu', true) feed('Sf<C-N>') - screen:expect({grid = [[ + screen:expect({ + grid = [[ foo | bar | foobar | f^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- Keyword completion (^N^P) }{5:Back at original} | - ]], popupmenu = { - anchor = { 1, 3, 0 }, - items = { { "foo", "", "", "" }, { "foobar", "", "", "" } }, - pos = -1 - }}) - eq({completed_item = {}, width = 0, - height = 2, size = 2, - col = 0, row = 4, scrollbar = false}, - eval('g:event')) + ]], + popupmenu = { + anchor = { 1, 3, 0 }, + items = { { 'foo', '', '', '' }, { 'foobar', '', '', '' } }, + pos = -1, + }, + }) + eq( + { completed_item = {}, width = 0, height = 2, size = 2, col = 0, row = 4, scrollbar = false }, + eval('g:event') + ) feed('oob') - screen:expect({grid = [[ + screen:expect({ + grid = [[ foo | bar | foobar | foob^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- Keyword completion (^N^P) }{5:Back at original} | - ]], popupmenu = { - anchor = { 1, 3, 0 }, - items = { { "foobar", "", "", "" } }, - pos = -1 - }}) - eq({completed_item = {}, width = 0, - height = 1, size = 1, - col = 0, row = 4, scrollbar = false}, - eval('g:event')) + ]], + popupmenu = { + anchor = { 1, 3, 0 }, + items = { { 'foobar', '', '', '' } }, + pos = -1, + }, + }) + eq( + { completed_item = {}, width = 0, height = 1, size = 1, col = 0, row = 4, scrollbar = false }, + eval('g:event') + ) feed('<Esc>') screen:set_option('ext_popupmenu', false) @@ -1108,10 +995,10 @@ describe('completion', function() {0:~ }| {3:-- Keyword completion (^N^P) }{5:Back at original} | ]]) - eq({completed_item = {}, width = 15, - height = 2, size = 2, - col = 0, row = 4, scrollbar = false}, - eval('g:event')) + eq( + { completed_item = {}, width = 15, height = 2, size = 2, col = 0, row = 4, scrollbar = false }, + eval('g:event') + ) feed('<C-N>') screen:expect([[ foo | @@ -1164,7 +1051,7 @@ describe('completion', function() end) it('is stopped by :stopinsert from timer #12976', function() - screen:try_resize(32,14) + screen:try_resize(32, 14) command([[call setline(1, ['hello', 'hullo', 'heeee', ''])]]) feed('Gah<c-x><c-n>') screen:expect([[ @@ -1175,36 +1062,40 @@ describe('completion', function() {2:hello }{0: }| {1:hullo }{0: }| {1:heeee }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 {3:-- }{4:match 1 of 3} | ]]) command([[call timer_start(100, { -> execute('stopinsert') })]]) - helpers.sleep(200) - feed('k') -- cursor should move up in Normal mode + vim.uv.sleep(200) + feed('k') -- cursor should move up in Normal mode screen:expect([[ hello | hullo | heee^e | hello | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 | ]]) end) - it('does not crash if text is changed by first call to complete function #17489', function() + -- oldtest: Test_complete_changed_complete_info() + it('no crash calling complete_info() in CompleteChanged', function() + source([[ + set completeopt=menuone + autocmd CompleteChanged * call complete_info(['items']) + call feedkeys("iii\<cr>\<c-p>") + ]]) + screen:expect([[ + ii | + ii^ | + {2:ii }{0: }| + {0:~ }|*4 + {3:-- Keyword completion (^N^P) The only match} | + ]]) + assert_alive() + end) + + it('no crash if text changed by first call to complete function #17489', function() source([[ func Complete(findstart, base) abort if a:findstart @@ -1223,7 +1114,7 @@ describe('completion', function() assert_alive() end) - it('does not crash when using i_CTRL-X_CTRL-V to complete non-existent colorscheme', function() + it('no crash using i_CTRL-X_CTRL-V to complete non-existent colorscheme', function() feed('icolorscheme NOSUCHCOLORSCHEME<C-X><C-V>') expect('colorscheme NOSUCHCOLORSCHEME') assert_alive() @@ -1233,28 +1124,70 @@ describe('completion', function() screen:try_resize(20, 9) command('set complete+=f | edit foo | edit bar |edit foa |edit .hidden') feed('i<C-n>') - screen:expect{grid=[[ + screen:expect { + grid = [[ foo^ | {2:foo }{0: }| {1:bar }{0: }| {1:foa }{0: }| {1:.hidden }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- }{4:match 1 of 4} | - ]]} + ]], + } feed('<Esc>ccf<C-n>') - screen:expect{grid=[[ + screen:expect { + grid = [[ foo^ | {2:foo }{0: }| {1:foa }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- }{4:match 1 of 2} | - ]]} + ]], + } + end) + + it('restores extmarks if original text is restored #23653', function() + screen:try_resize(screen._width, 4) + command([[ + call setline(1, ['aaaa']) + let ns_id = nvim_create_namespace('extmark') + let mark_id = nvim_buf_set_extmark(0, ns_id, 0, 0, { 'end_col':2, 'hl_group':'Error'}) + let mark = nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 }) + inoremap <C-x> <C-r>=Complete()<CR> + function Complete() abort + call complete(1, [{ 'word': 'aaaaa' }]) + return '' + endfunction + ]]) + feed('A<C-X><C-E><Esc>') + eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })")) + feed('A<C-N>') + eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })")) + feed('<Esc>0Yppia<Esc>ggI<C-N>') + screen:expect([[ + aaaa{7:^aa}aa | + {2:aaaa } | + {1:aaaaa } | + {3:-- Keyword completion (^N^P) }{4:match 1 of 2} | + ]]) + feed('<C-N><C-N><Esc>') + eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })")) + feed('A<C-N>') + eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })")) + feed('<C-N>') + screen:expect([[ + aaaaa^ | + {1:aaaa } | + {2:aaaaa } | + {3:-- Keyword completion (^N^P) }{4:match 2 of 2} | + ]]) + feed('<C-E>') + screen:expect([[ + {7:aa}aa^ | + aaaa | + aaaaa | + {3:-- INSERT --} | + ]]) end) end) diff --git a/test/functional/editor/ctrl_c_spec.lua b/test/functional/editor/ctrl_c_spec.lua index 4548e1aa34..e6a6ea808a 100644 --- a/test/functional/editor/ctrl_c_spec.lua +++ b/test/functional/editor/ctrl_c_spec.lua @@ -3,9 +3,9 @@ local Screen = require('test.functional.ui.screen') local clear, feed, source = helpers.clear, helpers.feed, helpers.source local command = helpers.command local poke_eventloop = helpers.poke_eventloop -local sleep = helpers.sleep +local sleep = vim.uv.sleep -describe("CTRL-C (mapped)", function() +describe('CTRL-C (mapped)', function() local screen before_each(function() @@ -14,7 +14,7 @@ describe("CTRL-C (mapped)", function() screen:attach() end) - it("interrupts :global", function() + it('interrupts :global', function() -- Crashes luajit. if helpers.skip_fragile(pending) then return @@ -25,7 +25,7 @@ describe("CTRL-C (mapped)", function() nnoremap <C-C> <NOP> ]]) - command("silent edit! test/functional/fixtures/bigfile.txt") + command('silent edit! test/functional/fixtures/bigfile.txt') screen:expect([[ ^0000;<control>;Cc;0;BN;;;;;N;NULL;;;; | @@ -37,19 +37,21 @@ describe("CTRL-C (mapped)", function() ]]) local function test_ctrl_c(ms) - feed(":global/^/p<CR>") + feed(':global/^/p<CR>') screen:sleep(ms) - feed("<C-C>") - screen:expect{any="Interrupt"} + feed('<C-C>') + screen:expect { any = 'Interrupt' } end -- The test is time-sensitive. Try different sleep values. - local ms_values = {100, 1000, 10000} + local ms_values = { 100, 1000, 10000 } for i, ms in ipairs(ms_values) do if i < #ms_values then local status, _ = pcall(test_ctrl_c, ms) - if status then break end - else -- Call the last attempt directly. + if status then + break + end + else -- Call the last attempt directly. test_ctrl_c(ms) end end @@ -58,16 +60,13 @@ describe("CTRL-C (mapped)", function() it('interrupts :sleep', function() command('nnoremap <C-C> <Nop>') feed(':sleep 100<CR>') - poke_eventloop() -- wait for :sleep to start + poke_eventloop() -- wait for :sleep to start feed('foo<C-C>') - poke_eventloop() -- wait for input buffer to be flushed + poke_eventloop() -- wait for input buffer to be flushed feed('i') screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | + ~ |*4 -- INSERT -- | ]]) end) @@ -76,16 +75,13 @@ describe("CTRL-C (mapped)", function() command('nnoremap <C-C> <Nop>') command('nmap <F2> <Ignore><F2>') feed('<F2>') - sleep(10) -- wait for the key to enter typeahead + sleep(10) -- wait for the key to enter typeahead feed('foo<C-C>') - poke_eventloop() -- wait for input buffer to be flushed + poke_eventloop() -- wait for input buffer to be flushed feed('i') screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | + ~ |*4 -- INSERT -- | ]]) end) diff --git a/test/functional/editor/fold_spec.lua b/test/functional/editor/fold_spec.lua index 424ce839a2..7950f6aea4 100644 --- a/test/functional/editor/fold_spec.lua +++ b/test/functional/editor/fold_spec.lua @@ -2,19 +2,24 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local insert = helpers.insert +local exec = helpers.exec local feed = helpers.feed local expect = helpers.expect local command = helpers.command -local funcs = helpers.funcs +local fn = helpers.fn local eq = helpers.eq local neq = helpers.neq -describe('Folds', function() +describe('Folding', function() local tempfname = 'Xtest-fold.txt' setup(clear) - before_each(function() command('bwipe! | new') end) - after_each(function() os.remove(tempfname) end) + before_each(function() + command('bwipe! | new') + end) + after_each(function() + os.remove(tempfname) + end) it('manual folding adjusts with filter', function() insert([[ @@ -71,8 +76,8 @@ describe('Folds', function() local function get_folds() local rettab = {} - for i = 1, funcs.line('$') do - table.insert(rettab, funcs.foldlevel(i)) + for i = 1, fn.line('$') do + table.insert(rettab, fn.foldlevel(i)) end return rettab end @@ -94,7 +99,8 @@ describe('Folds', function() end it('neither closes nor corrupts folds', function() - test_move_indent([[ + test_move_indent( + [[ a a a @@ -112,7 +118,9 @@ a a a a - a]], '7,12m0') + a]], + '7,12m0' + ) expect([[ a a @@ -133,25 +141,26 @@ a a a]]) -- lines are not closed, folds are correct - for i = 1,funcs.line('$') do - eq(-1, funcs.foldclosed(i)) + for i = 1, fn.line('$') do + eq(-1, fn.foldclosed(i)) if i == 1 or i == 7 or i == 13 then - eq(0, funcs.foldlevel(i)) + eq(0, fn.foldlevel(i)) elseif i == 4 then - eq(2, funcs.foldlevel(i)) + eq(2, fn.foldlevel(i)) else - eq(1, funcs.foldlevel(i)) + eq(1, fn.foldlevel(i)) end end -- folds are not corrupted feed('zM') - eq(6, funcs.foldclosedend(2)) - eq(12, funcs.foldclosedend(8)) - eq(18, funcs.foldclosedend(14)) + eq(6, fn.foldclosedend(2)) + eq(12, fn.foldclosedend(8)) + eq(18, fn.foldclosedend(14)) end) it("doesn't split a fold when the move is within it", function() - test_move_indent([[ + test_move_indent( + [[ a a a @@ -161,24 +170,30 @@ a a a a -a]], '5m6') - eq({0, 1, 1, 2, 2, 2, 2, 1, 1, 0}, get_folds()) +a]], + '5m6' + ) + eq({ 0, 1, 1, 2, 2, 2, 2, 1, 1, 0 }, get_folds()) end) it('truncates folds that end in the moved range', function() - test_move_indent([[ + test_move_indent( + [[ a a a a a a -a]], '4,5m6') - eq({0, 1, 2, 0, 0, 0, 0}, get_folds()) +a]], + '4,5m6' + ) + eq({ 0, 1, 2, 0, 0, 0, 0 }, get_folds()) end) it('moves folds that start between moved range and destination', function() - test_move_indent([[ + test_move_indent( + [[ a a a @@ -191,12 +206,15 @@ a a a a - a]], '3,4m$') - eq({0, 1, 1, 0, 0, 1, 2, 1, 0, 0, 1, 0, 0}, get_folds()) + a]], + '3,4m$' + ) + eq({ 0, 1, 1, 0, 0, 1, 2, 1, 0, 0, 1, 0, 0 }, get_folds()) end) it('does not affect folds outside changed lines', function() - test_move_indent([[ + test_move_indent( + [[ a a a @@ -205,12 +223,15 @@ a a a a - a]], '4m5') - eq({1, 1, 1, 0, 0, 0, 1, 1, 1}, get_folds()) + a]], + '4m5' + ) + eq({ 1, 1, 1, 0, 0, 0, 1, 1, 1 }, get_folds()) end) it('moves and truncates folds that start in moved range', function() - test_move_indent([[ + test_move_indent( + [[ a a a @@ -220,34 +241,43 @@ a a a a -a]], '1,3m7') - eq({0, 0, 0, 0, 0, 1, 2, 0, 0, 0}, get_folds()) +a]], + '1,3m7' + ) + eq({ 0, 0, 0, 0, 0, 1, 2, 0, 0, 0 }, get_folds()) end) it('breaks a fold when moving text into it', function() - test_move_indent([[ + test_move_indent( + [[ a a a a a a -a]], '$m4') - eq({0, 1, 2, 2, 0, 0, 0}, get_folds()) +a]], + '$m4' + ) + eq({ 0, 1, 2, 2, 0, 0, 0 }, get_folds()) end) it('adjusts correctly when moving a range backwards', function() - test_move_indent([[ + test_move_indent( + [[ a a a a -a]], '2,3m0') - eq({1, 2, 0, 0, 0}, get_folds()) +a]], + '2,3m0' + ) + eq({ 1, 2, 0, 0, 0 }, get_folds()) end) it('handles shifting all remaining folds', function() - test_move_indent([[ + test_move_indent( + [[ a a a @@ -262,18 +292,23 @@ a]], '2,3m0') a a a -a]], '13m7') - eq({1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0}, get_folds()) +a]], + '13m7' + ) + eq({ 1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0 }, get_folds()) end) end) it('updates correctly on :read', function() -- luacheck: ignore 621 - helpers.write_file(tempfname, [[ + helpers.write_file( + tempfname, + [[ a - a]]) + a]] + ) insert([[ a a @@ -295,14 +330,14 @@ a]], '13m7') a a ]]) - for i = 1,2 do - eq(1, funcs.foldlevel(i)) + for i = 1, 2 do + eq(1, fn.foldlevel(i)) end - for i = 3,5 do - eq(0, funcs.foldlevel(i)) + for i = 3, 5 do + eq(0, fn.foldlevel(i)) end - for i = 6,8 do - eq(1, funcs.foldlevel(i)) + for i = 6, 8 do + eq(1, fn.foldlevel(i)) end end) @@ -320,7 +355,7 @@ a]], '13m7') ]]) command('setlocal foldmethod=indent') command('3,5d') - eq(5, funcs.foldclosedend(1)) + eq(5, fn.foldclosedend(1)) end) it("doesn't combine folds that have a specified end", function() @@ -337,7 +372,7 @@ a]], '13m7') command('setlocal foldmethod=marker') command('3,5d') command('%foldclose') - eq(2, funcs.foldclosedend(1)) + eq(2, fn.foldclosedend(1)) end) it('splits folds according to >N and <N with foldexpr', function() @@ -356,7 +391,9 @@ a]], '13m7') return 0 endfunction ]]) - helpers.write_file(tempfname, [[ + helpers.write_file( + tempfname, + [[ b b a @@ -364,7 +401,8 @@ a]], '13m7') d a a - c]]) + c]] + ) insert([[ a a @@ -378,20 +416,56 @@ a]], '13m7') command('foldopen') command('read ' .. tempfname) command('%foldclose') - eq(2, funcs.foldclosedend(1)) - eq(0, funcs.foldlevel(3)) - eq(0, funcs.foldlevel(4)) - eq(6, funcs.foldclosedend(5)) - eq(10, funcs.foldclosedend(7)) - eq(14, funcs.foldclosedend(11)) + eq(2, fn.foldclosedend(1)) + eq(0, fn.foldlevel(3)) + eq(0, fn.foldlevel(4)) + eq(6, fn.foldclosedend(5)) + eq(10, fn.foldclosedend(7)) + eq(14, fn.foldclosedend(11)) + end) + + it('fdm=expr works correctly with :move #18668', function() + exec([[ + set foldmethod=expr foldexpr=indent(v:lnum) + let content = ['', '', 'Line1', ' Line2', ' Line3', + \ 'Line4', ' Line5', ' Line6', + \ 'Line7', ' Line8', ' Line9'] + call append(0, content) + normal! zM + call cursor(4, 1) + move 2 + move 1 + ]]) + expect([[ + + Line2 + Line3 + + Line1 + Line4 + Line5 + Line6 + Line7 + Line8 + Line9 + ]]) + eq(0, fn.foldlevel(1)) + eq(3, fn.foldclosedend(2)) + eq(0, fn.foldlevel(4)) + eq(0, fn.foldlevel(5)) + eq(0, fn.foldlevel(6)) + eq(8, fn.foldclosedend(7)) + eq(0, fn.foldlevel(9)) + eq(11, fn.foldclosedend(10)) + eq(0, fn.foldlevel(12)) end) it('no folds remain if :delete makes buffer empty #19671', function() command('setlocal foldmethod=manual') - funcs.setline(1, {'foo', 'bar', 'baz'}) + fn.setline(1, { 'foo', 'bar', 'baz' }) command('2,3fold') command('%delete') - eq(0, funcs.foldlevel(1)) + eq(0, fn.foldlevel(1)) end) it('multibyte fold markers work #20438', function() @@ -405,21 +479,21 @@ a]], '13m7') bbbbb/*«*/ bbbbb bbbbb/*»*/]]) - eq(1, funcs.foldlevel(1)) + eq(1, fn.foldlevel(1)) end) - it('updates correctly with indent method and visual blockwise insertion #22898', function() + it('fdm=indent updates correctly with visual blockwise insertion #22898', function() insert([[ a b ]]) command('setlocal foldmethod=indent shiftwidth=2') feed('gg0<C-v>jI <Esc>') -- indent both lines using visual blockwise mode - eq(1, funcs.foldlevel(1)) - eq(1, funcs.foldlevel(2)) + eq(1, fn.foldlevel(1)) + eq(1, fn.foldlevel(2)) end) - it("doesn't open folds with indent method when inserting lower foldlevel line", function() + it("fdm=indent doesn't open folds when inserting lower foldlevel line", function() insert([[ insert an unindented line under this line keep the lines under this line folded @@ -427,22 +501,22 @@ a]], '13m7') keep this line folded 2 ]]) command('set foldmethod=indent shiftwidth=2 noautoindent') - eq(1, funcs.foldlevel(1)) - eq(1, funcs.foldlevel(2)) - eq(2, funcs.foldlevel(3)) - eq(2, funcs.foldlevel(4)) + eq(1, fn.foldlevel(1)) + eq(1, fn.foldlevel(2)) + eq(2, fn.foldlevel(3)) + eq(2, fn.foldlevel(4)) feed('zo') -- open the outer fold - neq(-1, funcs.foldclosed(3)) -- make sure the inner fold is not open + neq(-1, fn.foldclosed(3)) -- make sure the inner fold is not open feed('gg0oa<Esc>') -- insert unindented line - eq(1, funcs.foldlevel(1)) --| insert an unindented line under this line - eq(0, funcs.foldlevel(2)) --|a - eq(1, funcs.foldlevel(3)) --| keep the lines under this line folded - eq(2, funcs.foldlevel(4)) --| keep this line folded 1 - eq(2, funcs.foldlevel(5)) --| keep this line folded 2 + eq(1, fn.foldlevel(1)) --| insert an unindented line under this line + eq(0, fn.foldlevel(2)) --|a + eq(1, fn.foldlevel(3)) --| keep the lines under this line folded + eq(2, fn.foldlevel(4)) --| keep this line folded 1 + eq(2, fn.foldlevel(5)) --| keep this line folded 2 - neq(-1, funcs.foldclosed(4)) -- make sure the inner fold is still not open + neq(-1, fn.foldclosed(4)) -- make sure the inner fold is still not open end) end) diff --git a/test/functional/editor/jump_spec.lua b/test/functional/editor/jump_spec.lua index dc056cb252..fe03d82164 100644 --- a/test/functional/editor/jump_spec.lua +++ b/test/functional/editor/jump_spec.lua @@ -3,16 +3,17 @@ local Screen = require('test.functional.ui.screen') local clear = helpers.clear local command = helpers.command +local dedent = helpers.dedent local eq = helpers.eq -local funcs = helpers.funcs +local fn = helpers.fn local feed = helpers.feed local exec_capture = helpers.exec_capture local write_file = helpers.write_file -local curbufmeths = helpers.curbufmeths +local api = helpers.api describe('jumplist', function() local fname1 = 'Xtest-functional-normal-jump' - local fname2 = fname1..'2' + local fname2 = fname1 .. '2' before_each(clear) after_each(function() os.remove(fname1) @@ -20,33 +21,33 @@ describe('jumplist', function() end) it('does not add a new entry on startup', function() - eq('\n jump line col file/text\n>', funcs.execute('jumps')) + eq('\n jump line col file/text\n>', fn.execute('jumps')) end) it('does not require two <C-O> strokes to jump back', function() write_file(fname1, 'first file contents') write_file(fname2, 'second file contents') - command('args '..fname1..' '..fname2) - local buf1 = funcs.bufnr(fname1) - local buf2 = funcs.bufnr(fname2) + command('args ' .. fname1 .. ' ' .. fname2) + local buf1 = fn.bufnr(fname1) + local buf2 = fn.bufnr(fname2) command('next') feed('<C-O>') - eq(buf1, funcs.bufnr('%')) + eq(buf1, fn.bufnr('%')) command('first') command('snext') feed('<C-O>') - eq(buf1, funcs.bufnr('%')) + eq(buf1, fn.bufnr('%')) feed('<C-I>') - eq(buf2, funcs.bufnr('%')) + eq(buf2, fn.bufnr('%')) feed('<C-O>') - eq(buf1, funcs.bufnr('%')) + eq(buf1, fn.bufnr('%')) - command('drop '..fname2) + command('drop ' .. fname2) feed('<C-O>') - eq(buf1, funcs.bufnr('%')) + eq(buf1, fn.bufnr('%')) end) it('<C-O> scrolls cursor halfway when switching buffer #25763', function() @@ -56,11 +57,12 @@ describe('jumplist', function() local screen = Screen.new(5, 25) screen:attach() command('set number') - command('edit '..fname1) + command('edit ' .. fname1) feed('35gg') - command('edit '..fname2) + command('edit ' .. fname2) feed('<C-O>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: 24 }foobar | {1: 25 }foobar | {1: 26 }foobar | @@ -86,9 +88,11 @@ describe('jumplist', function() {1: 46 }foobar | {1: 47 }foobar | | - ]], attr_ids={ - [1] = {foreground = Screen.colors.Brown}; - }} + ]], + attr_ids = { + [1] = { foreground = Screen.colors.Brown }, + }, + } end) end) @@ -98,9 +102,8 @@ describe("jumpoptions=stack behaves like 'tagstack'", function() feed(':clearjumps<cr>') -- Add lines so that we have locations to jump to. - for i = 1,101,1 - do - feed('iLine ' .. i .. '<cr><esc>') + for i = 1, 101, 1 do + feed('iLine ' .. i .. '<cr><esc>') end -- Jump around to add some locations to the jump list. @@ -115,82 +118,215 @@ describe("jumpoptions=stack behaves like 'tagstack'", function() end) after_each(function() - feed('set jumpoptions=') + feed('set jumpoptions=') end) it('discards the tail when navigating from the middle', function() feed('<C-O>') feed('<C-O>') - eq( '' - .. ' jump line col file/text\n' - .. ' 4 102 0 \n' - .. ' 3 1 0 Line 1\n' - .. ' 2 10 0 Line 10\n' - .. ' 1 20 0 Line 20\n' - .. '> 0 30 0 Line 30\n' - .. ' 1 40 0 Line 40\n' - .. ' 2 50 0 Line 50', - exec_capture('jumps')) + eq( + '' + .. ' jump line col file/text\n' + .. ' 4 102 0 \n' + .. ' 3 1 0 Line 1\n' + .. ' 2 10 0 Line 10\n' + .. ' 1 20 0 Line 20\n' + .. '> 0 30 0 Line 30\n' + .. ' 1 40 0 Line 40\n' + .. ' 2 50 0 Line 50', + exec_capture('jumps') + ) feed('90gg') - eq( '' - .. ' jump line col file/text\n' - .. ' 5 102 0 \n' - .. ' 4 1 0 Line 1\n' - .. ' 3 10 0 Line 10\n' - .. ' 2 20 0 Line 20\n' - .. ' 1 30 0 Line 30\n' - .. '>', - exec_capture('jumps')) + eq( + '' + .. ' jump line col file/text\n' + .. ' 5 102 0 \n' + .. ' 4 1 0 Line 1\n' + .. ' 3 10 0 Line 10\n' + .. ' 2 20 0 Line 20\n' + .. ' 1 30 0 Line 30\n' + .. '>', + exec_capture('jumps') + ) end) it('does not add the same location twice adjacently', function() feed('60gg') feed('60gg') - eq( '' - .. ' jump line col file/text\n' - .. ' 7 102 0 \n' - .. ' 6 1 0 Line 1\n' - .. ' 5 10 0 Line 10\n' - .. ' 4 20 0 Line 20\n' - .. ' 3 30 0 Line 30\n' - .. ' 2 40 0 Line 40\n' - .. ' 1 50 0 Line 50\n' - .. '>', - exec_capture('jumps')) + eq( + '' + .. ' jump line col file/text\n' + .. ' 7 102 0 \n' + .. ' 6 1 0 Line 1\n' + .. ' 5 10 0 Line 10\n' + .. ' 4 20 0 Line 20\n' + .. ' 3 30 0 Line 30\n' + .. ' 2 40 0 Line 40\n' + .. ' 1 50 0 Line 50\n' + .. '>', + exec_capture('jumps') + ) end) it('does add the same location twice nonadjacently', function() feed('10gg') feed('20gg') - eq( '' - .. ' jump line col file/text\n' - .. ' 8 102 0 \n' - .. ' 7 1 0 Line 1\n' - .. ' 6 10 0 Line 10\n' - .. ' 5 20 0 Line 20\n' - .. ' 4 30 0 Line 30\n' - .. ' 3 40 0 Line 40\n' - .. ' 2 50 0 Line 50\n' - .. ' 1 10 0 Line 10\n' - .. '>', - exec_capture('jumps')) + eq( + '' + .. ' jump line col file/text\n' + .. ' 8 102 0 \n' + .. ' 7 1 0 Line 1\n' + .. ' 6 10 0 Line 10\n' + .. ' 5 20 0 Line 20\n' + .. ' 4 30 0 Line 30\n' + .. ' 3 40 0 Line 40\n' + .. ' 2 50 0 Line 50\n' + .. ' 1 10 0 Line 10\n' + .. '>', + exec_capture('jumps') + ) end) end) -describe("jumpoptions=view", function() +describe('buffer deletion', function() + local base_file = 'Xtest-functional-buffer-deletion' + local file1 = base_file .. '1' + local file2 = base_file .. '2' + local file3 = base_file .. '3' + local base_content = 'text' + local content1 = base_content .. '1' + local content2 = base_content .. '2' + local content3 = base_content .. '3' + + local function format_jumplist(input) + return dedent(input) + :gsub('%{file1%}', file1) + :gsub('%{file2%}', file2) + :gsub('%{file3%}', file3) + :gsub('%{content1%}', content1) + :gsub('%{content2%}', content2) + :gsub('%{content3%}', content3) + end + + before_each(function() + clear() + command('clearjumps') + + write_file(file1, content1, false, false) + write_file(file2, content2, false, false) + write_file(file3, content3, false, false) + + command('edit ' .. file1) + command('edit ' .. file2) + command('edit ' .. file3) + end) + + it('deletes jump list entries when the current buffer is deleted', function() + command('edit ' .. file1) + + eq( + format_jumplist([[ + jump line col file/text + 3 1 0 {content1} + 2 1 0 {file2} + 1 1 0 {file3} + >]]), + exec_capture('jumps') + ) + + command('bwipeout') + + eq( + format_jumplist([[ + jump line col file/text + 1 1 0 {file2} + > 0 1 0 {content3}]]), + exec_capture('jumps') + ) + end) + + it('deletes jump list entries when another buffer is deleted', function() + eq( + format_jumplist([[ + jump line col file/text + 2 1 0 {file1} + 1 1 0 {file2} + >]]), + exec_capture('jumps') + ) + + command('bwipeout ' .. file2) + + eq( + format_jumplist([[ + jump line col file/text + 1 1 0 {file1} + >]]), + exec_capture('jumps') + ) + end) + + it('sets the correct jump index when the current buffer is deleted', function() + feed('<C-O>') + + eq( + format_jumplist([[ + jump line col file/text + 1 1 0 {file1} + > 0 1 0 {content2} + 1 1 0 {file3}]]), + exec_capture('jumps') + ) + + command('bw') + + eq( + format_jumplist([[ + jump line col file/text + 1 1 0 {file1} + > 0 1 0 {content3}]]), + exec_capture('jumps') + ) + end) + + it('sets the correct jump index when the another buffer is deleted', function() + feed('<C-O>') + + eq( + format_jumplist([[ + jump line col file/text + 1 1 0 {file1} + > 0 1 0 {content2} + 1 1 0 {file3}]]), + exec_capture('jumps') + ) + + command('bwipeout ' .. file1) + + eq( + format_jumplist([[ + jump line col file/text + > 0 1 0 {content2} + 1 1 0 {file3}]]), + exec_capture('jumps') + ) + end) +end) + +describe('jumpoptions=view', function() local file1 = 'Xtestfile-functional-editor-jumps' local file2 = 'Xtestfile-functional-editor-jumps-2' local function content() local c = {} - for i=1,30 do - c[i] = i .. " line" + for i = 1, 30 do + c[i] = i .. ' line' end - return table.concat(c, "\n") + return table.concat(c, '\n') end before_each(function() clear() @@ -206,9 +342,9 @@ describe("jumpoptions=view", function() it('restores the view', function() local screen = Screen.new(5, 8) screen:attach() - command("edit " .. file1) - feed("12Gztj") - feed("gg<C-o>") + command('edit ' .. file1) + feed('12Gztj') + feed('gg<C-o>') screen:expect([[ 12 line | ^13 line | @@ -224,10 +360,10 @@ describe("jumpoptions=view", function() it('restores the view across files', function() local screen = Screen.new(5, 5) screen:attach() - command("args " .. file1 .. " " .. file2) - feed("12Gzt") - command("next") - feed("G") + command('args ' .. file1 .. ' ' .. file2) + feed('12Gzt') + command('next') + feed('G') screen:expect([[ 27 line | 28 line | @@ -235,7 +371,7 @@ describe("jumpoptions=view", function() ^30 line | | ]]) - feed("<C-o><C-o>") + feed('<C-o><C-o>') screen:expect([[ ^12 line | 13 line | @@ -248,10 +384,10 @@ describe("jumpoptions=view", function() it('restores the view across files with <C-^>', function() local screen = Screen.new(5, 5) screen:attach() - command("args " .. file1 .. " " .. file2) - feed("12Gzt") - command("next") - feed("G") + command('args ' .. file1 .. ' ' .. file2) + feed('12Gzt') + command('next') + feed('G') screen:expect([[ 27 line | 28 line | @@ -259,7 +395,7 @@ describe("jumpoptions=view", function() ^30 line | | ]]) - feed("<C-^>") + feed('<C-^>') screen:expect([[ ^12 line | 13 line | @@ -269,19 +405,19 @@ describe("jumpoptions=view", function() ]]) end) - it('falls back to standard behavior when view can\'t be recovered', function() + it("falls back to standard behavior when view can't be recovered", function() local screen = Screen.new(5, 8) screen:attach() - command("edit " .. file1) - feed("7GzbG") - curbufmeths.set_lines(0, 2, true, {}) + command('edit ' .. file1) + feed('7GzbG') + api.nvim_buf_set_lines(0, 0, 2, true, {}) -- Move to line 7, and set it as the last line visible on the view with zb, meaning to recover -- the view it needs to put the cursor 7 lines from the top line. Then go to the end of the -- file, delete 2 lines before line 7, meaning the jump/mark is moved 2 lines up to line 5. -- Therefore when trying to jump back to it it's not possible to set a 7 line offset from the -- mark position to the top line, since there's only 5 lines from the mark position to line 0. -- Therefore falls back to standard behavior which is centering the view/line. - feed("<C-o>") + feed('<C-o>') screen:expect([[ 4 line | 5 line | diff --git a/test/functional/editor/lang_spec.lua b/test/functional/editor/lang_spec.lua index 24d1262f5f..ee7cfac057 100644 --- a/test/functional/editor/lang_spec.lua +++ b/test/functional/editor/lang_spec.lua @@ -9,11 +9,11 @@ describe('gu and gU', function() it('works in any locale with default casemap', function() eq('internal,keepascii', eval('&casemap')) - insert("iI") - feed("VgU") - expect("II") - feed("Vgu") - expect("ii") + insert('iI') + feed('VgU') + expect('II') + feed('Vgu') + expect('ii') end) describe('works in Turkish locale', function() @@ -21,7 +21,7 @@ describe('gu and gU', function() local err = exc_exec('lang ctype tr_TR.UTF-8') if err ~= 0 then - pending("Locale tr_TR.UTF-8 not supported", function() end) + pending('Locale tr_TR.UTF-8 not supported', function() end) return end @@ -32,29 +32,29 @@ describe('gu and gU', function() it('with default casemap', function() eq('internal,keepascii', eval('&casemap')) -- expect ASCII behavior - insert("iI") - feed("VgU") - expect("II") - feed("Vgu") - expect("ii") + insert('iI') + feed('VgU') + expect('II') + feed('Vgu') + expect('ii') end) it('with casemap=""', function() command('set casemap=') -- expect either Turkish locale behavior or ASCII behavior local iupper = eval("toupper('i')") - if iupper == "İ" then - insert("iI") - feed("VgU") - expect("İI") - feed("Vgu") - expect("iı") - elseif iupper == "I" then - insert("iI") - feed("VgU") - expect("II") - feed("Vgu") - expect("ii") + if iupper == 'İ' then + insert('iI') + feed('VgU') + expect('İI') + feed('Vgu') + expect('iı') + elseif iupper == 'I' then + insert('iI') + feed('VgU') + expect('II') + feed('Vgu') + expect('ii') else error("expected toupper('i') to be either 'I' or 'İ'") end diff --git a/test/functional/editor/langmap_spec.lua b/test/functional/editor/langmap_spec.lua index b1070ecddc..b2a4b21a89 100644 --- a/test/functional/editor/langmap_spec.lua +++ b/test/functional/editor/langmap_spec.lua @@ -4,7 +4,7 @@ local eq, neq, call = helpers.eq, helpers.neq, helpers.call local eval, feed, clear = helpers.eval, helpers.feed, helpers.clear local command, insert, expect = helpers.command, helpers.insert, helpers.expect local feed_command = helpers.feed_command -local curwin = helpers.curwin +local curwin = helpers.api.nvim_get_current_win describe("'langmap'", function() before_each(function() @@ -14,13 +14,13 @@ describe("'langmap'", function() feed('gg0') end) - it("converts keys in normal mode", function() + it('converts keys in normal mode', function() feed('ix') expect('iii ww') feed('whello<esc>') expect('iii helloww') end) - it("gives characters that are mapped by :nmap.", function() + it('gives characters that are mapped by :nmap.', function() command('map i 0x') feed('w') expect('ii www') @@ -32,20 +32,18 @@ describe("'langmap'", function() it("'langnoremap' is by default ON", function() eq(1, eval('&langnoremap')) end) - it("Results of maps are not converted when 'langnoremap' ON.", - function() + it("Results of maps are not converted when 'langnoremap' ON.", function() command('nmap x i') feed('xdl<esc>') expect('dliii www') end) - it("applies when deciding whether to map recursively", function() + it('applies when deciding whether to map recursively', function() command('nmap l i') command('nmap w j') feed('ll') expect('liii www') end) - it("does not stop applying 'langmap' on first character of a mapping", - function() + it("does not stop applying 'langmap' on first character of a mapping", function() command('1t1') command('1t1') command('goto 1') @@ -56,8 +54,7 @@ describe("'langmap'", function() iii www ihelloii www]]) end) - it("Results of maps are converted when 'langnoremap' OFF.", - function() + it("Results of maps are converted when 'langnoremap' OFF.", function() command('set nolangnoremap') command('nmap x i') feed('xdl<esc>') @@ -65,8 +62,7 @@ describe("'langmap'", function() end) end) -- e.g. CTRL-W_j , mj , 'j and "jp - it('conversions are applied to keys in middle of command', - function() + it('conversions are applied to keys in middle of command', function() -- Works in middle of window command feed('<C-w>s') local origwin = curwin() @@ -74,12 +70,12 @@ describe("'langmap'", function() neq(origwin, curwin()) -- Works when setting a mark feed('yy3p3gg0mwgg0mi') - eq({0, 3, 1, 0}, call('getpos', "'i")) - eq({0, 1, 1, 0}, call('getpos', "'w")) + eq({ 0, 3, 1, 0 }, call('getpos', "'i")) + eq({ 0, 1, 1, 0 }, call('getpos', "'w")) feed('3dd') -- Works when moving to a mark feed("'i") - eq({0, 1, 1, 0}, call('getpos', '.')) + eq({ 0, 1, 1, 0 }, call('getpos', '.')) -- Works when selecting a register feed('qillqqwhhq') eq('hh', eval('@i')) @@ -193,8 +189,7 @@ describe("'langmap'", function() eq(1, eval('gotten_one')) end) end) - it('conversions are not applied during setreg()', - function() + it('conversions are not applied during setreg()', function() call('setreg', 'i', 'ww') eq('ww', eval('@i')) end) @@ -214,12 +209,18 @@ describe("'langmap'", function() end) local function testrecording(command_string, expect_string, setup_function, expect_macro) - if setup_function then setup_function() end + if setup_function then + setup_function() + end feed('qa' .. command_string .. 'q') expect(expect_string) - eq(expect_macro or helpers.funcs.nvim_replace_termcodes(command_string, true, true, true), - eval('@a')) - if setup_function then setup_function() end + eq( + expect_macro or helpers.fn.nvim_replace_termcodes(command_string, true, true, true), + eval('@a') + ) + if setup_function then + setup_function() + end -- n.b. may need nvim_replace_termcodes() here. feed('@a') expect(expect_string) @@ -276,5 +277,4 @@ describe("'langmap'", function() testrecording('<C-w>', 'whello', local_setup, eval([["\<*C-w>"]])) testrecording('<C-i>', 'ihello', local_setup, eval([["\<*C-i>"]])) end) - end) diff --git a/test/functional/editor/macro_spec.lua b/test/functional/editor/macro_spec.lua index 53be7dcc62..c97befdf07 100644 --- a/test/functional/editor/macro_spec.lua +++ b/test/functional/editor/macro_spec.lua @@ -6,14 +6,14 @@ local feed = helpers.feed local clear = helpers.clear local expect = helpers.expect local command = helpers.command -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local insert = helpers.insert -local curbufmeths = helpers.curbufmeths - -before_each(clear) describe('macros', function() + before_each(function() + clear({ args_rm = { '--cmd' } }) + end) it('can be recorded and replayed', function() feed('qiahello<esc>q') expect('hello') @@ -40,31 +40,100 @@ hello]] feed [[gg]] feed [[qqAFOO<esc>q]] - eq({'helloFOO', 'hello', 'hello'}, curbufmeths.get_lines(0, -1, false)) + eq({ 'helloFOO', 'hello', 'hello' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[Q]] + eq({ 'helloFOOFOO', 'hello', 'hello' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[G3Q]] + eq({ 'helloFOOFOO', 'hello', 'helloFOOFOOFOO' }, api.nvim_buf_get_lines(0, 0, -1, false)) - feed[[Q]] - eq({'helloFOOFOO', 'hello', 'hello'}, curbufmeths.get_lines(0, -1, false)) + feed [[ggV3jQ]] + eq( + { 'helloFOOFOOFOO', 'helloFOO', 'helloFOOFOOFOOFOO' }, + api.nvim_buf_get_lines(0, 0, -1, false) + ) + end) - feed[[G3Q]] - eq({'helloFOOFOO', 'hello', 'helloFOOFOOFOO'}, curbufmeths.get_lines(0, -1, false)) + it('can be replayed with @', function() + insert [[hello +hello +hello]] + feed [[gg]] + + feed [[qqAFOO<esc>q]] + eq({ 'helloFOO', 'hello', 'hello' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[Q]] + eq({ 'helloFOOFOO', 'hello', 'hello' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[G3@@]] + eq({ 'helloFOOFOO', 'hello', 'helloFOOFOOFOO' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[ggV2j@@]] + eq( + { 'helloFOOFOOFOO', 'helloFOO', 'helloFOOFOOFOOFOO' }, + api.nvim_buf_get_lines(0, 0, -1, false) + ) + end) + + it('can be replayed with @q and @w', function() + insert [[hello +hello +hello]] + feed [[gg]] + + feed [[qqAFOO<esc>qu]] + eq({ 'hello', 'hello', 'hello' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[qwA123<esc>qu]] + eq({ 'hello', 'hello', 'hello' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[V3j@q]] + eq({ 'helloFOO', 'helloFOO', 'helloFOO' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[gg]] + feed [[Vj@w]] + eq({ 'helloFOO123', 'helloFOO123', 'helloFOO' }, api.nvim_buf_get_lines(0, 0, -1, false)) + end) + + it('can be replayed with @q and @w visual-block', function() + insert [[hello +hello +hello]] + feed [[gg]] + + feed [[qqAFOO<esc>qu]] + eq({ 'hello', 'hello', 'hello' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[qwA123<esc>qu]] + eq({ 'hello', 'hello', 'hello' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[<C-v>3j@q]] + eq({ 'helloFOO', 'helloFOO', 'helloFOO' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[gg]] + feed [[<C-v>j@w]] + eq({ 'helloFOO123', 'helloFOO123', 'helloFOO' }, api.nvim_buf_get_lines(0, 0, -1, false)) end) end) describe('immediately after a macro has finished executing,', function() before_each(function() + clear() command([[let @a = 'gg0']]) end) describe('reg_executing() from RPC returns an empty string', function() it('if the macro does not end with a <Nop> mapping', function() feed('@a') - eq('', funcs.reg_executing()) + eq('', fn.reg_executing()) end) it('if the macro ends with a <Nop> mapping', function() command('nnoremap 0 <Nop>') feed('@a') - eq('', funcs.reg_executing()) + eq('', fn.reg_executing()) end) end) @@ -74,16 +143,16 @@ describe('immediately after a macro has finished executing,', function() end) it('if the macro does not end with a <Nop> mapping', function() - feed('@asq') -- "q" from "s" mapping should start recording a macro instead of being no-op - eq({mode = 'n', blocking = false}, meths.get_mode()) + feed('@asq') -- "q" from "s" mapping should start recording a macro instead of being no-op + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) expect('') eq('', eval('@a')) end) it('if the macro ends with a <Nop> mapping', function() command('nnoremap 0 <Nop>') - feed('@asq') -- "q" from "s" mapping should start recording a macro instead of being no-op - eq({mode = 'n', blocking = false}, meths.get_mode()) + feed('@asq') -- "q" from "s" mapping should start recording a macro instead of being no-op + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) expect('') eq('', eval('@a')) end) @@ -91,6 +160,7 @@ describe('immediately after a macro has finished executing,', function() end) describe('reg_recorded()', function() + before_each(clear) it('returns the correct value', function() feed [[qqyyq]] eq('q', eval('reg_recorded()')) diff --git a/test/functional/editor/mark_spec.lua b/test/functional/editor/mark_spec.lua index e669d7f2bb..6b20a736c0 100644 --- a/test/functional/editor/mark_spec.lua +++ b/test/functional/editor/mark_spec.lua @@ -1,15 +1,16 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local meths = helpers.meths -local curbufmeths = helpers.curbufmeths +local api = helpers.api local clear = helpers.clear local command = helpers.command -local funcs = helpers.funcs +local fn = helpers.fn local eq = helpers.eq local feed = helpers.feed local write_file = helpers.write_file local pcall_err = helpers.pcall_err -local cursor = function() return helpers.meths.win_get_cursor(0) end +local cursor = function() + return helpers.api.nvim_win_get_cursor(0) +end describe('named marks', function() local file1 = 'Xtestfile-functional-editor-marks' @@ -24,153 +25,153 @@ describe('named marks', function() os.remove(file2) end) - it("can be set", function() - command("edit " .. file1) - command("mark a") - eq({1, 0}, curbufmeths.get_mark("a")) - feed("jmb") - eq({2, 0}, curbufmeths.get_mark("b")) - feed("jmB") - eq({3, 0}, curbufmeths.get_mark("B")) - command("4kc") - eq({4, 0}, curbufmeths.get_mark("c")) + it('can be set', function() + command('edit ' .. file1) + command('mark a') + eq({ 1, 0 }, api.nvim_buf_get_mark(0, 'a')) + feed('jmb') + eq({ 2, 0 }, api.nvim_buf_get_mark(0, 'b')) + feed('jmB') + eq({ 3, 0 }, api.nvim_buf_get_mark(0, 'B')) + command('4kc') + eq({ 4, 0 }, api.nvim_buf_get_mark(0, 'c')) end) - it("errors when set out of range with :mark", function() - command("edit " .. file1) - local err = pcall_err(helpers.exec_capture, "1000mark x") - eq("nvim_exec2(): Vim(mark):E16: Invalid range: 1000mark x", err) + it('errors when set out of range with :mark', function() + command('edit ' .. file1) + local err = pcall_err(helpers.exec_capture, '1000mark x') + eq('nvim_exec2(): Vim(mark):E16: Invalid range: 1000mark x', err) end) - it("errors when set out of range with :k", function() - command("edit " .. file1) - local err = pcall_err(helpers.exec_capture, "1000kx") - eq("nvim_exec2(): Vim(k):E16: Invalid range: 1000kx", err) + it('errors when set out of range with :k', function() + command('edit ' .. file1) + local err = pcall_err(helpers.exec_capture, '1000kx') + eq('nvim_exec2(): Vim(k):E16: Invalid range: 1000kx', err) end) - it("errors on unknown mark name with :mark", function() - command("edit " .. file1) - local err = pcall_err(helpers.exec_capture, "mark #") - eq("nvim_exec2(): Vim(mark):E191: Argument must be a letter or forward/backward quote", err) + it('errors on unknown mark name with :mark', function() + command('edit ' .. file1) + local err = pcall_err(helpers.exec_capture, 'mark #') + eq('nvim_exec2(): Vim(mark):E191: Argument must be a letter or forward/backward quote', err) end) it("errors on unknown mark name with '", function() - command("edit " .. file1) + command('edit ' .. file1) local err = pcall_err(helpers.exec_capture, "normal! '#") - eq("nvim_exec2(): Vim(normal):E78: Unknown mark", err) + eq('nvim_exec2(): Vim(normal):E78: Unknown mark', err) end) - it("errors on unknown mark name with `", function() - command("edit " .. file1) - local err = pcall_err(helpers.exec_capture, "normal! `#") - eq("nvim_exec2(): Vim(normal):E78: Unknown mark", err) + it('errors on unknown mark name with `', function() + command('edit ' .. file1) + local err = pcall_err(helpers.exec_capture, 'normal! `#') + eq('nvim_exec2(): Vim(normal):E78: Unknown mark', err) end) it("errors when moving to a mark that is not set with '", function() - command("edit " .. file1) + command('edit ' .. file1) local err = pcall_err(helpers.exec_capture, "normal! 'z") - eq("nvim_exec2(): Vim(normal):E20: Mark not set", err) + eq('nvim_exec2(): Vim(normal):E20: Mark not set', err) err = pcall_err(helpers.exec_capture, "normal! '.") - eq("nvim_exec2(): Vim(normal):E20: Mark not set", err) + eq('nvim_exec2(): Vim(normal):E20: Mark not set', err) end) - it("errors when moving to a mark that is not set with `", function() - command("edit " .. file1) - local err = pcall_err(helpers.exec_capture, "normal! `z") - eq("nvim_exec2(): Vim(normal):E20: Mark not set", err) - err = pcall_err(helpers.exec_capture, "normal! `>") - eq("nvim_exec2(): Vim(normal):E20: Mark not set", err) + it('errors when moving to a mark that is not set with `', function() + command('edit ' .. file1) + local err = pcall_err(helpers.exec_capture, 'normal! `z') + eq('nvim_exec2(): Vim(normal):E20: Mark not set', err) + err = pcall_err(helpers.exec_capture, 'normal! `>') + eq('nvim_exec2(): Vim(normal):E20: Mark not set', err) end) it("errors when moving to a global mark that is not set with '", function() - command("edit " .. file1) + command('edit ' .. file1) local err = pcall_err(helpers.exec_capture, "normal! 'Z") - eq("nvim_exec2(): Vim(normal):E20: Mark not set", err) + eq('nvim_exec2(): Vim(normal):E20: Mark not set', err) end) - it("errors when moving to a global mark that is not set with `", function() - command("edit " .. file1) - local err = pcall_err(helpers.exec_capture, "normal! `Z") - eq("nvim_exec2(): Vim(normal):E20: Mark not set", err) + it('errors when moving to a global mark that is not set with `', function() + command('edit ' .. file1) + local err = pcall_err(helpers.exec_capture, 'normal! `Z') + eq('nvim_exec2(): Vim(normal):E20: Mark not set', err) end) it("can move to them using '", function() - command("args " .. file1 .. " " .. file2) - feed("j") - feed("ma") + command('args ' .. file1 .. ' ' .. file2) + feed('j') + feed('ma') feed("G'a") - eq({2, 0}, cursor()) - feed("mA") - command("next") + eq({ 2, 0 }, cursor()) + feed('mA') + command('next') feed("'A") - eq(1, meths.get_current_buf().id) - eq({2, 0}, cursor()) + eq(1, api.nvim_get_current_buf()) + eq({ 2, 0 }, cursor()) end) - it("can move to them using `", function() - command("args " .. file1 .. " " .. file2) - feed("jll") - feed("ma") - feed("G`a") - eq({2, 2}, cursor()) - feed("mA") - command("next") - feed("`A") - eq(1, meths.get_current_buf().id) - eq({2, 2}, cursor()) + it('can move to them using `', function() + command('args ' .. file1 .. ' ' .. file2) + feed('jll') + feed('ma') + feed('G`a') + eq({ 2, 2 }, cursor()) + feed('mA') + command('next') + feed('`A') + eq(1, api.nvim_get_current_buf()) + eq({ 2, 2 }, cursor()) end) it("can move to them using g'", function() - command("args " .. file1 .. " " .. file2) - feed("jll") - feed("ma") + command('args ' .. file1 .. ' ' .. file2) + feed('jll') + feed('ma') feed("Gg'a") - eq({2, 0}, cursor()) - feed("mA") - command("next") + eq({ 2, 0 }, cursor()) + feed('mA') + command('next') feed("g'A") - eq(1, meths.get_current_buf().id) - eq({2, 0}, cursor()) + eq(1, api.nvim_get_current_buf()) + eq({ 2, 0 }, cursor()) end) - it("can move to them using g`", function() - command("args " .. file1 .. " " .. file2) - feed("jll") - feed("ma") - feed("Gg`a") - eq({2, 2}, cursor()) - feed("mA") - command("next") - feed("g`A") - eq(1, meths.get_current_buf().id) - eq({2, 2}, cursor()) + it('can move to them using g`', function() + command('args ' .. file1 .. ' ' .. file2) + feed('jll') + feed('ma') + feed('Gg`a') + eq({ 2, 2 }, cursor()) + feed('mA') + command('next') + feed('g`A') + eq(1, api.nvim_get_current_buf()) + eq({ 2, 2 }, cursor()) end) it("can move to them using :'", function() - command("args " .. file1 .. " " .. file2) - feed("j") - feed("ma") - feed("G") + command('args ' .. file1 .. ' ' .. file2) + feed('j') + feed('ma') + feed('G') command("'a") - eq({2, 0}, cursor()) - feed("mA") - command("next") + eq({ 2, 0 }, cursor()) + feed('mA') + command('next') command("'A") - eq(1, meths.get_current_buf().id) - eq({2, 0}, cursor()) + eq(1, api.nvim_get_current_buf()) + eq({ 2, 0 }, cursor()) end) it("errors when it can't find the buffer", function() - command("args " .. file1 .. " " .. file2) - feed("mA") - command("next") - command("bw! " .. file1 ) + command('args ' .. file1 .. ' ' .. file2) + feed('mA') + command('next') + command('bw! ' .. file1) local err = pcall_err(helpers.exec_capture, "normal! 'A") - eq("nvim_exec2(): Vim(normal):E92: Buffer 1 not found", err) + eq('nvim_exec2(): Vim(normal):E92: Buffer 1 not found', err) os.remove(file1) end) - it("errors when using a mark in another buffer in command range", function() + it('errors when using a mark in another buffer in command range', function() feed('ifoo<Esc>mA') command('enew') feed('ibar<Esc>') @@ -178,147 +179,147 @@ describe('named marks', function() end) it("leave a context mark when moving with '", function() - command("edit " .. file1) - feed("llmamA") - feed("10j0") -- first col, last line + command('edit ' .. file1) + feed('llmamA') + feed('10j0') -- first col, last line local pos = cursor() feed("'a") - feed("<C-o>") + feed('<C-o>') eq(pos, cursor()) feed("'A") - feed("<C-o>") + feed('<C-o>') eq(pos, cursor()) end) - it("leave a context mark when moving with `", function() - command("edit " .. file1) - feed("llmamA") - feed("10j0") -- first col, last line + it('leave a context mark when moving with `', function() + command('edit ' .. file1) + feed('llmamA') + feed('10j0') -- first col, last line local pos = cursor() - feed("`a") - feed("<C-o>") + feed('`a') + feed('<C-o>') eq(pos, cursor()) - feed("`A") - feed("<C-o>") + feed('`A') + feed('<C-o>') eq(pos, cursor()) end) it("leave a context mark when the mark changes buffer with g'", function() - command("args " .. file1 .. " " .. file2) + command('args ' .. file1 .. ' ' .. file2) local pos - feed("GmA") - command("next") + feed('GmA') + command('next') pos = cursor() - command("clearjumps") - feed("g'A") -- since the mark is in another buffer, it leaves a context mark - feed("<C-o>") + command('clearjumps') + feed("g'A") -- since the mark is in another buffer, it leaves a context mark + feed('<C-o>') eq(pos, cursor()) end) - it("leave a context mark when the mark changes buffer with g`", function() - command("args " .. file1 .. " " .. file2) + it('leave a context mark when the mark changes buffer with g`', function() + command('args ' .. file1 .. ' ' .. file2) local pos - feed("GmA") - command("next") + feed('GmA') + command('next') pos = cursor() - command("clearjumps") - feed("g`A") -- since the mark is in another buffer, it leaves a context mark - feed("<C-o>") + command('clearjumps') + feed('g`A') -- since the mark is in another buffer, it leaves a context mark + feed('<C-o>') eq(pos, cursor()) end) it("do not leave a context mark when moving with g'", function() - command("edit " .. file1) + command('edit ' .. file1) local pos - feed("ma") + feed('ma') pos = cursor() -- Mark pos - feed("10j0") -- first col, last line + feed('10j0') -- first col, last line feed("g'a") - feed("<C-o>") -- should do nothing + feed('<C-o>') -- should do nothing eq(pos, cursor()) - feed("mA") + feed('mA') pos = cursor() -- Mark pos - feed("10j0") -- first col, last line + feed('10j0') -- first col, last line feed("g'a") - feed("<C-o>") -- should do nothing + feed('<C-o>') -- should do nothing eq(pos, cursor()) end) - it("do not leave a context mark when moving with g`", function() - command("edit " .. file1) + it('do not leave a context mark when moving with g`', function() + command('edit ' .. file1) local pos - feed("ma") + feed('ma') pos = cursor() -- Mark pos - feed("10j0") -- first col, last line - feed("g`a") - feed("<C-o>") -- should do nothing + feed('10j0') -- first col, last line + feed('g`a') + feed('<C-o>') -- should do nothing eq(pos, cursor()) - feed("mA") + feed('mA') pos = cursor() -- Mark pos - feed("10j0") -- first col, last line + feed('10j0') -- first col, last line feed("g'a") - feed("<C-o>") -- should do nothing + feed('<C-o>') -- should do nothing eq(pos, cursor()) end) - it("open folds when moving to them", function() - command("edit " .. file1) - feed("jzfG") -- Fold from the second line to the end - command("3mark a") - feed("G") -- On top of the fold - assert(funcs.foldclosed('.') ~= -1) -- folded + it('open folds when moving to them', function() + command('edit ' .. file1) + feed('jzfG') -- Fold from the second line to the end + command('3mark a') + feed('G') -- On top of the fold + assert(fn.foldclosed('.') ~= -1) -- folded feed("'a") - eq(-1, funcs.foldclosed('.')) + eq(-1, fn.foldclosed('.')) - feed("zc") - assert(funcs.foldclosed('.') ~= -1) -- folded + feed('zc') + assert(fn.foldclosed('.') ~= -1) -- folded -- TODO: remove this workaround after fixing #15873 - feed("k`a") - eq(-1, funcs.foldclosed('.')) + feed('k`a') + eq(-1, fn.foldclosed('.')) - feed("zc") - assert(funcs.foldclosed('.') ~= -1) -- folded + feed('zc') + assert(fn.foldclosed('.') ~= -1) -- folded feed("kg'a") - eq(-1, funcs.foldclosed('.')) + eq(-1, fn.foldclosed('.')) - feed("zc") - assert(funcs.foldclosed('.') ~= -1) -- folded - feed("kg`a") - eq(-1, funcs.foldclosed('.')) + feed('zc') + assert(fn.foldclosed('.') ~= -1) -- folded + feed('kg`a') + eq(-1, fn.foldclosed('.')) end) it("do not open folds when moving to them doesn't move the cursor", function() - command("edit " .. file1) - feed("jzfG") -- Fold from the second line to the end - assert(funcs.foldclosed('.') == 2) -- folded - feed("ma") + command('edit ' .. file1) + feed('jzfG') -- Fold from the second line to the end + assert(fn.foldclosed('.') == 2) -- folded + feed('ma') feed("'a") - feed("`a") + feed('`a') feed("g'a") - feed("g`a") + feed('g`a') -- should still be folded - eq(2, funcs.foldclosed('.')) + eq(2, fn.foldclosed('.')) end) it("getting '{ '} '( ') does not move cursor", function() - meths.buf_set_lines(0, 0, 0, true, {'aaaaa', 'bbbbb', 'ccccc', 'ddddd', 'eeeee'}) - meths.win_set_cursor(0, {2, 0}) - funcs.getpos("'{") - eq({2, 0}, meths.win_get_cursor(0)) - funcs.getpos("'}") - eq({2, 0}, meths.win_get_cursor(0)) - funcs.getpos("'(") - eq({2, 0}, meths.win_get_cursor(0)) - funcs.getpos("')") - eq({2, 0}, meths.win_get_cursor(0)) + api.nvim_buf_set_lines(0, 0, 0, true, { 'aaaaa', 'bbbbb', 'ccccc', 'ddddd', 'eeeee' }) + api.nvim_win_set_cursor(0, { 2, 0 }) + fn.getpos("'{") + eq({ 2, 0 }, api.nvim_win_get_cursor(0)) + fn.getpos("'}") + eq({ 2, 0 }, api.nvim_win_get_cursor(0)) + fn.getpos("'(") + eq({ 2, 0 }, api.nvim_win_get_cursor(0)) + fn.getpos("')") + eq({ 2, 0 }, api.nvim_win_get_cursor(0)) end) it('in command range does not move cursor #19248', function() - meths.create_user_command('Test', ':', {range = true}) - meths.buf_set_lines(0, 0, 0, true, {'aaaaa', 'bbbbb', 'ccccc', 'ddddd', 'eeeee'}) - meths.win_set_cursor(0, {2, 0}) + api.nvim_create_user_command('Test', ':', { range = true }) + api.nvim_buf_set_lines(0, 0, 0, true, { 'aaaaa', 'bbbbb', 'ccccc', 'ddddd', 'eeeee' }) + api.nvim_win_set_cursor(0, { 2, 0 }) command([['{,'}Test]]) - eq({2, 0}, meths.win_get_cursor(0)) + eq({ 2, 0 }, api.nvim_win_get_cursor(0)) end) end) @@ -327,16 +328,16 @@ describe('named marks view', function() local file2 = 'Xtestfile-functional-editor-marks-2' local function content() local c = {} - for i=1,30 do - c[i] = i .. " line" + for i = 1, 30 do + c[i] = i .. ' line' end - return table.concat(c, "\n") + return table.concat(c, '\n') end before_each(function() clear() write_file(file1, content(), false, false) write_file(file2, content(), false, false) - command("set jumpoptions+=view") + command('set jumpoptions+=view') end) after_each(function() os.remove(file1) @@ -344,12 +345,12 @@ describe('named marks view', function() end) it('is restored in normal mode but not op-pending mode', function() - local screen = Screen.new(5, 8) - screen:attach() - command("edit " .. file1) - feed("<C-e>jWma") - feed("G'a") - local expected = [[ + local screen = Screen.new(5, 8) + screen:attach() + command('edit ' .. file1) + feed('<C-e>jWma') + feed("G'a") + local expected = [[ 2 line | ^3 line | 4 line | @@ -359,9 +360,9 @@ describe('named marks view', function() 8 line | | ]] - screen:expect({grid=expected}) - feed("G`a") - screen:expect([[ + screen:expect({ grid = expected }) + feed('G`a') + screen:expect([[ 2 line | 3 ^line | 4 line | @@ -371,9 +372,9 @@ describe('named marks view', function() 8 line | | ]]) - -- not in op-pending mode #20886 - feed("ggj=`a") - screen:expect([[ + -- not in op-pending mode #20886 + feed('ggj=`a') + screen:expect([[ 1 line | ^2 line | 3 line | @@ -388,8 +389,8 @@ describe('named marks view', function() it('is restored across files', function() local screen = Screen.new(5, 5) screen:attach() - command("args " .. file1 .. " " .. file2) - feed("<C-e>mA") + command('args ' .. file1 .. ' ' .. file2) + feed('<C-e>mA') local mark_view = [[ ^2 line | 3 line | @@ -398,7 +399,7 @@ describe('named marks view', function() | ]] screen:expect(mark_view) - command("next") + command('next') screen:expect([[ ^1 line | 2 line | @@ -410,18 +411,16 @@ describe('named marks view', function() screen:expect(mark_view) end) - it('fallback to standard behavior when view can\'t be recovered', function() - local screen = Screen.new(10, 10) - screen:attach() - command("edit " .. file1) - feed("7GzbmaG") -- Seven lines from the top - command("new") -- Screen size for window is now half the height can't be restored - feed("<C-w>p'a") - screen:expect([[ + it("fallback to standard behavior when view can't be recovered", function() + local screen = Screen.new(10, 10) + screen:attach() + command('edit ' .. file1) + feed('7GzbmaG') -- Seven lines from the top + command('new') -- Screen size for window is now half the height can't be restored + feed("<C-w>p'a") + screen:expect([[ | - ~ | - ~ | - ~ | + ~ |*3 [No Name] | 6 line | ^7 line | @@ -454,10 +453,7 @@ describe('named marks view', function() command('bwipe!') screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | + ~ |*4 | ]]) command('rshada!') diff --git a/test/functional/editor/meta_key_spec.lua b/test/functional/editor/meta_key_spec.lua index 825b20138a..b57f5c3c35 100644 --- a/test/functional/editor/meta_key_spec.lua +++ b/test/functional/editor/meta_key_spec.lua @@ -4,7 +4,7 @@ local command = helpers.command local exec_lua = helpers.exec_lua local eval = helpers.eval local expect = helpers.expect -local funcs = helpers.funcs +local fn = helpers.fn local eq = helpers.eq describe('meta-keys #8226 #13042', function() @@ -66,11 +66,11 @@ describe('meta-keys #8226 #13042', function() command('inoremap <A-j> alt-j') feed('i<M-l> xxx <A-j><M-h>a<A-h>') expect('meta-l xxx alt-j') - eq({ 0, 1, 14, 0, }, funcs.getpos('.')) + eq({ 0, 1, 14, 0 }, fn.getpos('.')) -- Unmapped ALT-chord behaves as ESC+c. command('iunmap <M-l>') feed('0i<M-l>') - eq({ 0, 1, 2, 0, }, funcs.getpos('.')) + eq({ 0, 1, 2, 0 }, fn.getpos('.')) -- Unmapped ALT-chord has same `undo` characteristics as ESC+<key> command('0,$d') feed('ahello<M-.>') @@ -101,7 +101,7 @@ describe('meta-keys #8226 #13042', function() eq(meta_l_seq .. 'yyy' .. meta_l_seq .. 'alt-j', exec_lua([[return _G.input_data]])) eq('t', eval('mode(1)')) feed('<Esc>j') - eq({ 0, 2, 1, 0, }, funcs.getpos('.')) + eq({ 0, 2, 1, 0 }, fn.getpos('.')) eq('nt', eval('mode(1)')) end) diff --git a/test/functional/editor/mode_cmdline_spec.lua b/test/functional/editor/mode_cmdline_spec.lua index d34b5a1a28..06efe53718 100644 --- a/test/functional/editor/mode_cmdline_spec.lua +++ b/test/functional/editor/mode_cmdline_spec.lua @@ -2,11 +2,11 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local clear, insert, funcs, eq, feed = - helpers.clear, helpers.insert, helpers.funcs, helpers.eq, helpers.feed +local clear, insert, fn, eq, feed = + helpers.clear, helpers.insert, helpers.fn, helpers.eq, helpers.feed local eval = helpers.eval local command = helpers.command -local meths = helpers.meths +local api = helpers.api describe('cmdline', function() before_each(clear) @@ -20,22 +20,22 @@ describe('cmdline', function() -- Yank 2 lines linewise, then paste to cmdline. feed([[<C-\><C-N>gg0yj:<C-R>0]]) -- <CR> inserted between lines, NOT after the final line. - eq('line1abc\rline2somemoretext', funcs.getcmdline()) + eq('line1abc\rline2somemoretext', fn.getcmdline()) -- Yank 2 lines charwise, then paste to cmdline. feed([[<C-\><C-N>gg05lyvj:<C-R>0]]) -- <CR> inserted between lines, NOT after the final line. - eq('abc\rline2', funcs.getcmdline()) + eq('abc\rline2', fn.getcmdline()) -- Yank 1 line linewise, then paste to cmdline. feed([[<C-\><C-N>ggyy:<C-R>0]]) -- No <CR> inserted. - eq('line1abc', funcs.getcmdline()) + eq('line1abc', fn.getcmdline()) end) it('pasting special register inserts <CR>, <NL>', function() feed([[:<C-R>="foo\nbar\rbaz"<CR>]]) - eq('foo\nbar\rbaz', funcs.getcmdline()) + eq('foo\nbar\rbaz', fn.getcmdline()) end) end) @@ -48,55 +48,59 @@ describe('cmdline', function() it('redraws statusline when toggling overstrike', function() local screen = Screen.new(60, 4) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {reverse = true, bold = true}, -- StatusLine + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { reverse = true, bold = true }, -- StatusLine }) screen:attach() command('set laststatus=2 statusline=%!mode(1)') feed(':') - screen:expect{grid=[[ + screen:expect { + grid = [[ | {0:~ }| {1:c }| :^ | - ]]} + ]], + } feed('<Insert>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | {0:~ }| {1:cr }| :^ | - ]]} + ]], + } end) describe('history', function() it('correctly clears start of the history', function() -- Regression test: check absence of the memory leak when clearing start of - -- the history using ex_getln.c/clr_history(). - eq(1, funcs.histadd(':', 'foo')) - eq(1, funcs.histdel(':')) - eq('', funcs.histget(':', -1)) + -- the history using cmdhist.c/clr_history(). + eq(1, fn.histadd(':', 'foo')) + eq(1, fn.histdel(':')) + eq('', fn.histget(':', -1)) end) it('correctly clears end of the history', function() -- Regression test: check absence of the memory leak when clearing end of - -- the history using ex_getln.c/clr_history(). - meths.set_option_value('history', 1, {}) - eq(1, funcs.histadd(':', 'foo')) - eq(1, funcs.histdel(':')) - eq('', funcs.histget(':', -1)) + -- the history using cmdhist.c/clr_history(). + api.nvim_set_option_value('history', 1, {}) + eq(1, fn.histadd(':', 'foo')) + eq(1, fn.histdel(':')) + eq('', fn.histget(':', -1)) end) it('correctly removes item from history', function() - -- Regression test: check that ex_getln.c/del_history_idx() correctly clears + -- Regression test: check that cmdhist.c/del_history_idx() correctly clears -- history index after removing history entry. If it does not then deleting -- history will result in a double free. - eq(1, funcs.histadd(':', 'foo')) - eq(1, funcs.histadd(':', 'bar')) - eq(1, funcs.histadd(':', 'baz')) - eq(1, funcs.histdel(':', -2)) - eq(1, funcs.histdel(':')) - eq('', funcs.histget(':', -1)) + eq(1, fn.histadd(':', 'foo')) + eq(1, fn.histadd(':', 'bar')) + eq(1, fn.histadd(':', 'baz')) + eq(1, fn.histdel(':', -2)) + eq(1, fn.histdel(':')) + eq('', fn.histget(':', -1)) end) end) end) diff --git a/test/functional/editor/mode_insert_spec.lua b/test/functional/editor/mode_insert_spec.lua index 37651164f5..e96813b6f7 100644 --- a/test/functional/editor/mode_insert_spec.lua +++ b/test/functional/editor/mode_insert_spec.lua @@ -53,31 +53,25 @@ describe('insert-mode', function() it('double quote is removed after hit-enter prompt #22609', function() local screen = Screen.new(60, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {foreground = Screen.colors.Blue}, -- SpecialKey - [2] = {foreground = Screen.colors.SlateBlue}, - [3] = {bold = true}, -- ModeMsg - [4] = {reverse = true, bold = true}, -- MsgSeparator - [5] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg - [6] = {foreground = Screen.colors.SeaGreen, bold = true}, -- MoreMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { foreground = Screen.colors.Blue }, -- SpecialKey + [2] = { foreground = Screen.colors.SlateBlue }, + [3] = { bold = true }, -- ModeMsg + [4] = { reverse = true, bold = true }, -- MsgSeparator + [5] = { background = Screen.colors.Red, foreground = Screen.colors.White }, -- ErrorMsg + [6] = { foreground = Screen.colors.SeaGreen, bold = true }, -- MoreMsg }) screen:attach() feed('i<C-R>') screen:expect([[ {1:^"} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- INSERT --} | ]]) feed('={}') screen:expect([[ {1:"} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ={2:{}}^ | ]]) feed('<CR>') @@ -92,10 +86,7 @@ describe('insert-mode', function() feed('<CR>') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- INSERT --} | ]]) end) @@ -196,10 +187,10 @@ describe('insert-mode', function() it('multi-char mapping updates screen properly #25626', function() local screen = Screen.new(60, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}; -- NonText - [1] = {bold = true, reverse = true}; -- StatusLine - [2] = {reverse = true}; -- StatusLineNC - [3] = {bold = true}; -- ModeMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { bold = true, reverse = true }, -- StatusLine + [2] = { reverse = true }, -- StatusLineNC + [3] = { bold = true }, -- ModeMsg }) screen:attach() command('vnew') @@ -208,22 +199,26 @@ describe('insert-mode', function() command('set timeoutlen=10000') command('inoremap jk <Esc>') feed('i<CR>βββ<Left><Left>j') - screen:expect{grid=[[ + screen:expect { + grid = [[ foo │ | foo │β^jβ | foo │{0:~ }| {0:~ }│{0:~ }| {2:[No Name] [+] }{1:[No Name] [+] }| {3:-- INSERT --} | - ]]} + ]], + } feed('k') - screen:expect{grid=[[ + screen:expect { + grid = [[ foo │ | foo │^βββ | foo │{0:~ }| {0:~ }│{0:~ }| {2:[No Name] [+] }{1:[No Name] [+] }| | - ]]} + ]], + } end) end) diff --git a/test/functional/editor/mode_normal_spec.lua b/test/functional/editor/mode_normal_spec.lua new file mode 100644 index 0000000000..89bab3f6c9 --- /dev/null +++ b/test/functional/editor/mode_normal_spec.lua @@ -0,0 +1,22 @@ +-- Normal mode tests. + +local helpers = require('test.functional.helpers')(after_each) +local clear = helpers.clear +local feed = helpers.feed +local fn = helpers.fn +local command = helpers.command +local eq = helpers.eq + +describe('Normal mode', function() + before_each(clear) + + it('setting &winhighlight or &winblend does not change curswant #27470', function() + fn.setline(1, { 'long long lone line', 'short line' }) + feed('ggfi') + local pos = fn.getcurpos() + feed('j') + command('setlocal winblend=10 winhighlight=Visual:Search') + feed('k') + eq(pos, fn.getcurpos()) + end) +end) diff --git a/test/functional/editor/put_spec.lua b/test/functional/editor/put_spec.lua index 47068470bb..414b289222 100644 --- a/test/functional/editor/put_spec.lua +++ b/test/functional/editor/put_spec.lua @@ -6,12 +6,12 @@ local insert = helpers.insert local feed = helpers.feed local expect = helpers.expect local eq = helpers.eq -local map = helpers.tbl_map -local filter = helpers.tbl_filter +local map = vim.tbl_map +local filter = vim.tbl_filter local feed_command = helpers.feed_command local command = helpers.command local curbuf_contents = helpers.curbuf_contents -local funcs = helpers.funcs +local fn = helpers.fn local dedent = helpers.dedent local function reset() @@ -21,9 +21,9 @@ local function reset() Line of words 2]]) command('goto 1') feed('itest_string.<esc>u') - funcs.setreg('a', 'test_stringa', 'V') - funcs.setreg('b', 'test_stringb\ntest_stringb\ntest_stringb', 'b') - funcs.setreg('"', 'test_string"', 'v') + fn.setreg('a', 'test_stringa', 'V') + fn.setreg('b', 'test_stringb\ntest_stringb\ntest_stringb', 'b') + fn.setreg('"', 'test_string"', 'v') end -- We check the last inserted register ". in each of these tests because it is @@ -35,12 +35,12 @@ describe('put command', function() before_each(reset) local function visual_marks_zero() - for _,v in pairs(funcs.getpos("'<")) do + for _, v in pairs(fn.getpos("'<")) do if v ~= 0 then return false end end - for _,v in pairs(funcs.getpos("'>")) do + for _, v in pairs(fn.getpos("'>")) do if v ~= 0 then return false end @@ -51,10 +51,12 @@ describe('put command', function() -- {{{ Where test definitions are run local function run_test_variations(test_variations, extra_setup) reset() - if extra_setup then extra_setup() end + if extra_setup then + extra_setup() + end local init_contents = curbuf_contents() - local init_cursorpos = funcs.getcurpos() - local assert_no_change = function (exception_table, after_undo) + local init_cursorpos = fn.getcurpos() + local assert_no_change = function(exception_table, after_undo) expect(init_contents) -- When putting the ". register forwards, undo doesn't move -- the cursor back to where it was before. @@ -63,14 +65,16 @@ describe('put command', function() -- one place to the right (unless we were at the end of the -- line when we pasted). if not (exception_table.undo_position and after_undo) then - eq(init_cursorpos, funcs.getcurpos()) + eq(init_cursorpos, fn.getcurpos()) end end for _, test in pairs(test_variations) do it(test.description, function() - if extra_setup then extra_setup() end - local orig_dotstr = funcs.getreg('.') + if extra_setup then + extra_setup() + end + local orig_dotstr = fn.getreg('.') helpers.ok(visual_marks_zero()) -- Make sure every test starts from the same conditions assert_no_change(test.exception_table, false) @@ -85,7 +89,7 @@ describe('put command', function() -- If we paste the ". register with a count we can't avoid -- changing this register, hence avoid this check. if not test.exception_table.dot_reg_changed then - eq(orig_dotstr, funcs.getreg('.')) + eq(orig_dotstr, fn.getreg('.')) end -- Doing something, undoing it, and then redoing it should @@ -101,7 +105,7 @@ describe('put command', function() end if test.exception_table.undo_position then - funcs.setpos('.', init_cursorpos) + fn.setpos('.', init_cursorpos) end if was_cli then feed('@:') @@ -115,8 +119,13 @@ describe('put command', function() end -- run_test_variations() -- }}} - local function create_test_defs(test_defs, command_base, command_creator, -- {{{ - expect_base, expect_creator) + local function create_test_defs( + test_defs, + command_base, + command_creator, -- {{{ + expect_base, + expect_creator + ) local rettab = {} local exceptions for _, v in pairs(test_defs) do @@ -125,8 +134,7 @@ describe('put command', function() else exceptions = {} end - table.insert(rettab, - { + table.insert(rettab, { test_action = command_creator(command_base, v[1]), test_assertions = expect_creator(expect_base, v[2]), description = v[3], @@ -143,10 +151,10 @@ describe('put command', function() -- it was in. -- This returns the cursor position that would leave the 'x' in that -- place if we feed 'ix<esc>' and the string existed before it. - for linenum, line in pairs(funcs.split(expect_string, '\n', 1)) do + for linenum, line in pairs(fn.split(expect_string, '\n', 1)) do local column = line:find('x') if column then - return {linenum, column}, expect_string:gsub('x', '') + return { linenum, column }, expect_string:gsub('x', '') end end end -- find_cursor_position() }}} @@ -176,17 +184,17 @@ describe('put command', function() return function(exception_table, after_redo) expect(expect_string) - -- Have to use getcurpos() instead of curwinmeths.get_cursor() in + -- Have to use getcurpos() instead of api.nvim_win_get_cursor(0) in -- order to account for virtualedit. -- We always want the curswant element in getcurpos(), which is -- sometimes different to the column element in - -- curwinmeths.get_cursor(). + -- api.nvim_win_get_cursor(0). -- NOTE: The ".gp command leaves the cursor after the pasted text -- when running, but does not when the command is redone with the -- '.' command. if not (exception_table.redo_position and after_redo) then - local actual_position = funcs.getcurpos() - eq(cursor_position, {actual_position[2], actual_position[5]}) + local actual_position = fn.getcurpos() + eq(cursor_position, { actual_position[2], actual_position[5] }) end end end -- expect_creator() }}} @@ -195,13 +203,13 @@ describe('put command', function() local function copy_def(def) local rettab = { '', {}, '', nil } rettab[1] = def[1] - for k,v in pairs(def[2]) do + for k, v in pairs(def[2]) do rettab[2][k] = v end rettab[3] = def[3] if def[4] then rettab[4] = {} - for k,v in pairs(def[4]) do + for k, v in pairs(def[4]) do rettab[4][k] = v end end @@ -211,52 +219,52 @@ describe('put command', function() local normal_command_defs = { { 'p', - {cursor_after = false, put_backwards = false, dot_register = false}, + { cursor_after = false, put_backwards = false, dot_register = false }, 'pastes after cursor with p', }, { 'gp', - {cursor_after = true, put_backwards = false, dot_register = false}, + { cursor_after = true, put_backwards = false, dot_register = false }, 'leaves cursor after text with gp', }, { '".p', - {cursor_after = false, put_backwards = false, dot_register = true}, + { cursor_after = false, put_backwards = false, dot_register = true }, 'works with the ". register', }, { '".gp', - {cursor_after = true, put_backwards = false, dot_register = true}, + { cursor_after = true, put_backwards = false, dot_register = true }, 'gp works with the ". register', - {redo_position = true}, + { redo_position = true }, }, { 'P', - {cursor_after = false, put_backwards = true, dot_register = false}, + { cursor_after = false, put_backwards = true, dot_register = false }, 'pastes before cursor with P', }, { 'gP', - {cursor_after = true, put_backwards = true, dot_register = false}, + { cursor_after = true, put_backwards = true, dot_register = false }, 'gP pastes before cursor and leaves cursor after text', }, { '".P', - {cursor_after = false, put_backwards = true, dot_register = true}, + { cursor_after = false, put_backwards = true, dot_register = true }, 'P works with ". register', }, { '".gP', - {cursor_after = true, put_backwards = true, dot_register = true}, + { cursor_after = true, put_backwards = true, dot_register = true }, 'gP works with ". register', - {redo_position = true}, + { redo_position = true }, }, } -- Add a definition applying a count for each definition above. -- Could do this for each transformation (p -> P, p -> gp etc), but I think -- it's neater this way (balance between being explicit and too verbose). - for i = 1,#normal_command_defs do + for i = 1, #normal_command_defs do local cur = normal_command_defs[i] -- Make modified copy of current definition that includes a count. @@ -279,35 +287,36 @@ describe('put command', function() local ex_command_defs = { { 'put', - {put_backwards = false, dot_register = false}, + { put_backwards = false, dot_register = false }, 'pastes linewise forwards with :put', }, { 'put!', - {put_backwards = true, dot_register = false}, + { put_backwards = true, dot_register = false }, 'pastes linewise backwards with :put!', }, { 'put .', - {put_backwards = false, dot_register = true}, + { put_backwards = false, dot_register = true }, 'pastes linewise with the dot register', }, { 'put! .', - {put_backwards = true, dot_register = true}, + { put_backwards = true, dot_register = true }, 'pastes linewise backwards with the dot register', }, } local function non_dotdefs(def_table) - return filter(function(d) return not d[2].dot_register end, def_table) + return filter(function(d) + return not d[2].dot_register + end, def_table) end -- }}} -- Conversion functions {{{ - local function convert_charwise(expect_base, conversion_table, - virtualedit_end, visual_put) + local function convert_charwise(expect_base, conversion_table, virtualedit_end, visual_put) expect_base = dedent(expect_base) -- There is no difference between 'P' and 'p' when VIsual_active if not visual_put then @@ -324,7 +333,7 @@ describe('put command', function() end if conversion_table.count > 1 then local rep_string = 'test_string"' - local extra_puts = rep_string:rep(conversion_table.count - 1) + local extra_puts = rep_string:rep(conversion_table.count - 1) expect_base = expect_base:gsub('test_stringx"', extra_puts .. 'test_stringx"') end if conversion_table.cursor_after then @@ -340,7 +349,7 @@ describe('put command', function() local prev_line local rettab = {} local string_found = false - for _, line in pairs(funcs.split(string, '\n', 1)) do + for _, line in pairs(fn.split(string, '\n', 1)) do if line:find('test_string') then string_found = true table.insert(rettab, line) @@ -395,7 +404,7 @@ describe('put command', function() indent = '' end local rep_string = indent .. p_str .. '\n' - local extra_puts = rep_string:rep(conversion_table.count - 1) + local extra_puts = rep_string:rep(conversion_table.count - 1) local orig_string, new_string if conversion_table.cursor_after then orig_string = indent .. p_str .. '\nx' @@ -420,8 +429,13 @@ describe('put command', function() return orig_line:sub(1, prev_end - 1) .. 'x' .. orig_line:sub(prev_end) end - local function convert_blockwise(expect_base, conversion_table, visual, - use_b, trailing_whitespace) + local function convert_blockwise( + expect_base, + conversion_table, + visual, + use_b, + trailing_whitespace + ) expect_base = dedent(expect_base) local p_str = 'test_string"' if use_b then @@ -452,11 +466,9 @@ describe('put command', function() if conversion_table.count and conversion_table.count > 1 then local p_pattern = p_str:gsub('%.', '%%.') - expect_base = expect_base:gsub(p_pattern, - p_str:rep(conversion_table.count)) - expect_base = expect_base:gsub('test_stringx([b".])', - p_str:rep(conversion_table.count - 1) - .. '%0') + expect_base = expect_base:gsub(p_pattern, p_str:rep(conversion_table.count)) + expect_base = + expect_base:gsub('test_stringx([b".])', p_str:rep(conversion_table.count - 1) .. '%0') end if conversion_table.cursor_after then @@ -464,7 +476,7 @@ describe('put command', function() local prev_line local rettab = {} local prev_in_block = false - for _, line in pairs(funcs.split(expect_base, '\n', 1)) do + for _, line in pairs(fn.split(expect_base, '\n', 1)) do if line:find('test_string') then if prev_line then prev_line = prev_line:gsub('x', '') @@ -496,8 +508,13 @@ describe('put command', function() -- }}} -- Convenience functions {{{ - local function run_normal_mode_tests(test_string, base_map, extra_setup, - virtualedit_end, selection_string) + local function run_normal_mode_tests( + test_string, + base_map, + extra_setup, + virtualedit_end, + selection_string + ) local function convert_closure(e, c) return convert_charwise(e, c, virtualedit_end, selection_string) end @@ -507,10 +524,10 @@ describe('put command', function() test_expect(exception_table, after_redo) if selection_string then if not conversion_table.put_backwards then - eq(selection_string, funcs.getreg('"')) + eq(selection_string, fn.getreg('"')) end else - eq('test_string"', funcs.getreg('"')) + eq('test_string"', fn.getreg('"')) end end end @@ -532,8 +549,12 @@ describe('put command', function() local function run_linewise_tests(expect_base, base_command, extra_setup) local linewise_test_defs = create_test_defs( - ex_command_defs, base_command, - create_put_action, expect_base, convert_linewiseer) + ex_command_defs, + base_command, + create_put_action, + expect_base, + convert_linewiseer + ) run_test_variations(linewise_test_defs, extra_setup) end -- run_linewise_tests() -- }}} @@ -545,7 +566,8 @@ describe('put command', function() Line of words 2]] run_normal_mode_tests(expect_string, 'p') - run_linewise_tests([[ + run_linewise_tests( + [[ Line of words 1 xtest_string" Line of words 2]], @@ -585,11 +607,12 @@ describe('put command', function() run_test_variations( create_test_defs( linewise_put_defs, - 'put a', create_put_action, - base_expect_string, convert_linewiseer + 'put a', + create_put_action, + base_expect_string, + convert_linewiseer ) ) - end) describe('blockwise register', function() @@ -600,18 +623,13 @@ describe('put command', function() test_stringb]] local function expect_block_creator(expect_base, conversion_table) - return expect_creator(function(e,c) return convert_blockwise(e,c,nil,true) end, - expect_base, conversion_table) + return expect_creator(function(e, c) + return convert_blockwise(e, c, nil, true) + end, expect_base, conversion_table) end run_test_variations( - create_test_defs( - blockwise_put_defs, - '"bp', - create_p_action, - test_base, - expect_block_creator - ) + create_test_defs(blockwise_put_defs, '"bp', create_p_action, test_base, expect_block_creator) ) end) @@ -632,17 +650,17 @@ describe('put command', function() describe('linewise paste with autoindent', function() -- luacheck: ignore - run_linewise_tests([[ + run_linewise_tests( + [[ Line of words 1 Line of words 2 xtest_string"]], - 'put' - , + 'put', function() - funcs.setline('$', ' Line of words 2') + fn.setline('$', ' Line of words 2') -- Set curswant to '8' to be at the end of the tab character -- This is where the cursor is put back after the 'u' command. - funcs.setpos('.', {0, 2, 1, 0, 8}) + fn.setpos('.', { 0, 2, 1, 0, 8 }) command('set autoindent') end ) @@ -653,9 +671,9 @@ describe('put command', function() Line of words 1 test_stringx" Line of words 2]] run_normal_mode_tests(test_string, 'p', function() - funcs.setline('$', ' Line of words 2') + fn.setline('$', ' Line of words 2') command('setlocal virtualedit=all') - funcs.setpos('.', {0, 2, 1, 2, 3}) + fn.setpos('.', { 0, 2, 1, 2, 3 }) end) end) @@ -665,9 +683,9 @@ describe('put command', function() Line of words 1 test_stringx" Line of words 2]] run_normal_mode_tests(test_string, 'p', function() - funcs.setline('$', ' Line of words 2') + fn.setline('$', ' Line of words 2') command('setlocal virtualedit=all') - funcs.setpos('.', {0, 1, 16, 1, 17}) + fn.setpos('.', { 0, 1, 16, 1, 17 }) end, true) end) @@ -679,12 +697,10 @@ describe('put command', function() run_normal_mode_tests(test_string, 'v2ep', nil, nil, 'Line of') end) describe('over trailing newline', function() - local test_string = 'Line of test_stringx"Line of words 2' + local test_string = 'Line of test_stringx"Line of words 2' run_normal_mode_tests(test_string, 'v$p', function() - funcs.setpos('.', {0, 1, 9, 0, 9}) - end, - nil, - 'words 1\n') + fn.setpos('.', { 0, 1, 9, 0, 9 }) + end, nil, 'words 1\n') end) describe('linewise mode', function() local test_string = [[ @@ -693,8 +709,7 @@ describe('put command', function() local function expect_vis_linewise(expect_base, conversion_table) return expect_creator(function(e, c) return convert_linewise(e, c, nil, nil) - end, - expect_base, conversion_table) + end, expect_base, conversion_table) end run_test_variations( create_test_defs( @@ -704,19 +719,20 @@ describe('put command', function() test_string, expect_vis_linewise ), - function() funcs.setpos('.', {0, 1, 1, 0, 1}) end + function() + fn.setpos('.', { 0, 1, 1, 0, 1 }) + end ) describe('with whitespace at bol', function() local function expect_vis_lineindented(expect_base, conversion_table) local test_expect = expect_creator(function(e, c) - return convert_linewise(e, c, nil, nil, ' ') - end, - expect_base, conversion_table) + return convert_linewise(e, c, nil, nil, ' ') + end, expect_base, conversion_table) return function(exception_table, after_redo) test_expect(exception_table, after_redo) if not conversion_table.put_backwards then - eq('Line of words 1\n', funcs.getreg('"')) + eq('Line of words 1\n', fn.getreg('"')) end end end @@ -733,11 +749,10 @@ describe('put command', function() ), function() feed('i test_string.<esc>u') - funcs.setreg('"', ' test_string"', 'v') + fn.setreg('"', ' test_string"', 'v') end ) end) - end) describe('blockwise visual mode', function() @@ -747,39 +762,37 @@ describe('put command', function() local function expect_block_creator(expect_base, conversion_table) local test_expect = expect_creator(function(e, c) - return convert_blockwise(e, c, true) - end, expect_base, conversion_table) - return function(e,c) - test_expect(e,c) + return convert_blockwise(e, c, true) + end, expect_base, conversion_table) + return function(e, c) + test_expect(e, c) if not conversion_table.put_backwards then - eq('Lin\nLin', funcs.getreg('"')) + eq('Lin\nLin', fn.getreg('"')) end end end local select_down_test_defs = create_test_defs( - normal_command_defs, - '<C-v>jllp', - create_p_action, - test_base, - expect_block_creator + normal_command_defs, + '<C-v>jllp', + create_p_action, + test_base, + expect_block_creator ) run_test_variations(select_down_test_defs) - -- Undo and redo of a visual block put leave the cursor in the top -- left of the visual block area no matter where the cursor was -- when it started. local undo_redo_no = map(function(table) - local rettab = copy_def(table) - if not rettab[4] then - rettab[4] = {} - end - rettab[4].undo_position = true - rettab[4].redo_position = true - return rettab - end, - normal_command_defs) + local rettab = copy_def(table) + if not rettab[4] then + rettab[4] = {} + end + rettab[4].undo_position = true + rettab[4].redo_position = true + return rettab + end, normal_command_defs) -- Selection direction doesn't matter run_test_variations( @@ -790,7 +803,9 @@ describe('put command', function() test_base, expect_block_creator ), - function() funcs.setpos('.', {0, 2, 1, 0, 1}) end + function() + fn.setpos('.', { 0, 2, 1, 0, 1 }) + end ) describe('blockwise cursor after undo', function() @@ -800,62 +815,45 @@ describe('put command', function() -- the same pattern as everything else. -- Here we fix this by directly checking the undo/redo position -- in the test_assertions of our test definitions. - local function assertion_creator(_,_) - return function(_,_) + local function assertion_creator(_, _) + return function(_, _) feed('u') -- Have to use feed('u') here to set curswant, because -- ex_undo() doesn't do that. - eq({0, 1, 1, 0, 1}, funcs.getcurpos()) + eq({ 0, 1, 1, 0, 1 }, fn.getcurpos()) feed('<C-r>') - eq({0, 1, 1, 0, 1}, funcs.getcurpos()) + eq({ 0, 1, 1, 0, 1 }, fn.getcurpos()) end end run_test_variations( - create_test_defs( - undo_redo_no, - '<C-v>kllp', - create_p_action, - test_base, - assertion_creator - ), - function() funcs.setpos('.', {0, 2, 1, 0, 1}) end + create_test_defs(undo_redo_no, '<C-v>kllp', create_p_action, test_base, assertion_creator), + function() + fn.setpos('.', { 0, 2, 1, 0, 1 }) + end ) end) end) - describe("with 'virtualedit'", function() describe('splitting a tab character', function() local base_expect_string = [[ Line of words 1 test_stringx" Line of words 2]] - run_normal_mode_tests( - base_expect_string, - 'vp', - function() - funcs.setline('$', ' Line of words 2') - command('setlocal virtualedit=all') - funcs.setpos('.', {0, 2, 1, 2, 3}) - end, - nil, - ' ' - ) + run_normal_mode_tests(base_expect_string, 'vp', function() + fn.setline('$', ' Line of words 2') + command('setlocal virtualedit=all') + fn.setpos('.', { 0, 2, 1, 2, 3 }) + end, nil, ' ') end) describe('after end of line', function() local base_expect_string = [[ Line of words 1 test_stringx" Line of words 2]] - run_normal_mode_tests( - base_expect_string, - 'vp', - function() - command('setlocal virtualedit=all') - funcs.setpos('.', {0, 1, 16, 2, 18}) - end, - true, - ' ' - ) + run_normal_mode_tests(base_expect_string, 'vp', function() + command('setlocal virtualedit=all') + fn.setpos('.', { 0, 1, 16, 2, 18 }) + end, true, ' ') end) end) end) @@ -873,9 +871,12 @@ describe('put command', function() Line of words 1 Line of words 2]]) feed('u1go<C-v>j".p') - eq([[ + eq( + [[ ine of words 1 - ine of words 2]], curbuf_contents()) + ine of words 2]], + curbuf_contents() + ) end) local screen @@ -891,33 +892,42 @@ describe('put command', function() end helpers.ok(not screen.bell and not screen.visualbell) actions() - screen:expect{condition=function() - if should_ring then - if not screen.bell and not screen.visualbell then - error('Bell was not rung after action') - end - else - if screen.bell or screen.visualbell then - error('Bell was rung after action') + screen:expect { + condition = function() + if should_ring then + if not screen.bell and not screen.visualbell then + error('Bell was not rung after action') + end + else + if screen.bell or screen.visualbell then + error('Bell was rung after action') + end end - end - end, unchanged=(not should_ring)} + end, + unchanged = not should_ring, + } screen.bell = false screen.visualbell = false end it('should not ring the bell with gp at end of line', function() - bell_test(function() feed('$".gp') end) + bell_test(function() + feed('$".gp') + end) -- Even if the last character is a multibyte character. reset() - funcs.setline(1, 'helloม') - bell_test(function() feed('$".gp') end) + fn.setline(1, 'helloม') + bell_test(function() + feed('$".gp') + end) end) it('should not ring the bell with gp and end of file', function() - funcs.setpos('.', {0, 2, 1, 0}) - bell_test(function() feed('$vl".gp') end) + fn.setpos('.', { 0, 2, 1, 0 }) + bell_test(function() + feed('$vl".gp') + end) end) it('should ring the bell when deleting if not appropriate', function() @@ -926,13 +936,15 @@ describe('put command', function() expect([[ ine of words 1 Line of words 2]]) - bell_test(function() feed('".P') end, true) + bell_test(function() + feed('".P') + end, true) end) it('should restore cursor position after undo of ".p', function() - local origpos = funcs.getcurpos() + local origpos = fn.getcurpos() feed('".pu') - eq(origpos, funcs.getcurpos()) + eq(origpos, fn.getcurpos()) end) it("should be unaffected by 'autoindent' with V\".2p", function() @@ -946,4 +958,3 @@ describe('put command', function() end) end) end) - diff --git a/test/functional/editor/search_spec.lua b/test/functional/editor/search_spec.lua index d5df131725..46a3e298b7 100644 --- a/test/functional/editor/search_spec.lua +++ b/test/functional/editor/search_spec.lua @@ -8,10 +8,7 @@ describe('search (/)', function() before_each(clear) it('fails with huge column (%c) value #9930', function() - eq([[Vim:E951: \% value too large]], - pcall_err(command, "/\\v%18446744071562067968c")) - eq([[Vim:E951: \% value too large]], - pcall_err(command, "/\\v%2147483648c")) + eq([[Vim:E951: \% value too large]], pcall_err(command, '/\\v%18446744071562067968c')) + eq([[Vim:E951: \% value too large]], pcall_err(command, '/\\v%2147483648c')) end) end) - diff --git a/test/functional/editor/tabpage_spec.lua b/test/functional/editor/tabpage_spec.lua index a7f629a76b..0cbc2dbf3d 100644 --- a/test/functional/editor/tabpage_spec.lua +++ b/test/functional/editor/tabpage_spec.lua @@ -8,9 +8,9 @@ local neq = helpers.neq local feed = helpers.feed local eval = helpers.eval local exec = helpers.exec -local funcs = helpers.funcs -local meths = helpers.meths -local curwin = helpers.curwin +local fn = helpers.fn +local api = helpers.api +local curwin = helpers.api.nvim_get_current_win local assert_alive = helpers.assert_alive describe('tabpage', function() @@ -58,7 +58,9 @@ describe('tabpage', function() end) it('no segfault with strange WinClosed autocommand #20290', function() - pcall(exec, [[ + pcall( + exec, + [[ set nohidden edit Xa split Xb @@ -66,45 +68,46 @@ describe('tabpage', function() new autocmd WinClosed * tabprev | bwipe! close - ]]) + ]] + ) assert_alive() end) it('nvim_win_close and nvim_win_hide update tabline #20285', function() - eq(1, #meths.list_tabpages()) - eq({1, 1}, funcs.win_screenpos(0)) - local win1 = curwin().id + eq(1, #api.nvim_list_tabpages()) + eq({ 1, 1 }, fn.win_screenpos(0)) + local win1 = curwin() command('tabnew') - eq(2, #meths.list_tabpages()) - eq({2, 1}, funcs.win_screenpos(0)) - local win2 = curwin().id + eq(2, #api.nvim_list_tabpages()) + eq({ 2, 1 }, fn.win_screenpos(0)) + local win2 = curwin() - meths.win_close(win1, true) - eq(win2, curwin().id) - eq(1, #meths.list_tabpages()) - eq({1, 1}, funcs.win_screenpos(0)) + api.nvim_win_close(win1, true) + eq(win2, curwin()) + eq(1, #api.nvim_list_tabpages()) + eq({ 1, 1 }, fn.win_screenpos(0)) command('tabnew') - eq(2, #meths.list_tabpages()) - eq({2, 1}, funcs.win_screenpos(0)) - local win3 = curwin().id - - meths.win_hide(win2) - eq(win3, curwin().id) - eq(1, #meths.list_tabpages()) - eq({1, 1}, funcs.win_screenpos(0)) + eq(2, #api.nvim_list_tabpages()) + eq({ 2, 1 }, fn.win_screenpos(0)) + local win3 = curwin() + + api.nvim_win_hide(win2) + eq(win3, curwin()) + eq(1, #api.nvim_list_tabpages()) + eq({ 1, 1 }, fn.win_screenpos(0)) end) it('switching tabpage after setting laststatus=3 #19591', function() local screen = Screen.new(40, 8) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, - [1] = {bold = true, reverse = true}, -- StatusLine - [2] = {reverse = true}, -- TabLineFill - [3] = {bold = true}, -- TabLineSel - [4] = {background = Screen.colors.LightGrey, underline = true}, -- TabLine - [5] = {bold = true, foreground = Screen.colors.Magenta}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { bold = true, reverse = true }, -- StatusLine + [2] = { reverse = true }, -- TabLineFill + [3] = { bold = true }, -- TabLineSel + [4] = { background = Screen.colors.LightGrey, underline = true }, -- TabLine + [5] = { bold = true, foreground = Screen.colors.Magenta }, }) screen:attach() @@ -116,10 +119,7 @@ describe('tabpage', function() screen:expect([[ {4: [No Name] }{3: [No Name] }{2: }{4:X}| ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {1:[No Name] }| "[No Name]" --No lines in buffer-- | ]]) @@ -127,26 +127,23 @@ describe('tabpage', function() screen:expect([[ {4: [No Name] }{3: }{5:2}{3: [No Name] }{2: }{4:X}| ^ │ | - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| + {0:~ }│{0:~ }|*4 {1:[No Name] }| "[No Name]" --No lines in buffer-- | ]]) end) - it(":tabmove handles modifiers and addr", function() + it(':tabmove handles modifiers and addr', function() command('tabnew | tabnew | tabnew') - eq(4, funcs.nvim_tabpage_get_number(0)) + eq(4, fn.nvim_tabpage_get_number(0)) command(' silent :keepalt :: ::: silent! - tabmove') - eq(3, funcs.nvim_tabpage_get_number(0)) + eq(3, fn.nvim_tabpage_get_number(0)) command(' silent :keepalt :: ::: silent! -2 tabmove') - eq(1, funcs.nvim_tabpage_get_number(0)) + eq(1, fn.nvim_tabpage_get_number(0)) end) it(':tabs does not overflow IObuff with long path with comma #20850', function() - meths.buf_set_name(0, ('x'):rep(1024) .. ',' .. ('x'):rep(1024)) + api.nvim_buf_set_name(0, ('x'):rep(1024) .. ',' .. ('x'):rep(1024)) command('tabs') assert_alive() end) diff --git a/test/functional/editor/undo_spec.lua b/test/functional/editor/undo_spec.lua index d66ab352ef..c101bf02a0 100644 --- a/test/functional/editor/undo_spec.lua +++ b/test/functional/editor/undo_spec.lua @@ -8,12 +8,12 @@ local eq = helpers.eq local feed = helpers.feed local feed_command = helpers.feed_command local insert = helpers.insert -local funcs = helpers.funcs +local fn = helpers.fn local exec = helpers.exec local exec_lua = helpers.exec_lua local function lastmessage() - local messages = funcs.split(funcs.execute('messages'), '\n') + local messages = fn.split(fn.execute('messages'), '\n') return messages[#messages] end @@ -21,15 +21,23 @@ describe('u CTRL-R g- g+', function() before_each(clear) local function create_history(num_steps) - if num_steps == 0 then return end + if num_steps == 0 then + return + end insert('1') - if num_steps == 1 then return end + if num_steps == 1 then + return + end feed('o2<esc>') feed('o3<esc>') feed('u') - if num_steps == 2 then return end + if num_steps == 2 then + return + end feed('o4<esc>') - if num_steps == 3 then return end + if num_steps == 3 then + return + end feed('u') end @@ -57,13 +65,23 @@ describe('u CTRL-R g- g+', function() undo_and_redo(2, 'g-', 'g+', '1') end) it('undoes properly around a branch point', function() - undo_and_redo(3, 'u', '<C-r>', [[ + undo_and_redo( + 3, + 'u', + '<C-r>', + [[ 1 - 2]]) - undo_and_redo(3, 'g-', 'g+', [[ + 2]] + ) + undo_and_redo( + 3, + 'g-', + 'g+', + [[ 1 2 - 3]]) + 3]] + ) end) it('can find the previous sequence after undoing to a branch', function() undo_and_redo(4, 'u', '<C-r>', '1') diff --git a/test/functional/ex_cmds/append_spec.lua b/test/functional/ex_cmds/append_spec.lua index 4134eed87e..5eb8d49c74 100644 --- a/test/functional/ex_cmds/append_spec.lua +++ b/test/functional/ex_cmds/append_spec.lua @@ -5,21 +5,20 @@ local dedent = helpers.dedent local exec = helpers.exec local feed = helpers.feed local clear = helpers.clear -local funcs = helpers.funcs +local fn = helpers.fn local command = helpers.command -local curbufmeths = helpers.curbufmeths -local meths = helpers.meths +local api = helpers.api local Screen = require('test.functional.ui.screen') local cmdtest = function(cmd, prep, ret1) describe(':' .. cmd, function() before_each(function() clear() - curbufmeths.set_lines(0, 1, true, { 'foo', 'bar', 'baz' }) + api.nvim_buf_set_lines(0, 0, 1, true, { 'foo', 'bar', 'baz' }) end) local buffer_contents = function() - return curbufmeths.get_lines(0, -1, false) + return api.nvim_buf_get_lines(0, 0, -1, false) end it(cmd .. 's' .. prep .. ' the current line by default', function() @@ -29,8 +28,7 @@ local cmdtest = function(cmd, prep, ret1) -- Used to crash because this invokes history processing which uses -- hist_char2type which after fdb68e35e4c729c7ed097d8ade1da29e5b3f4b31 -- crashed. - it(cmd .. 's' .. prep .. ' the current line by default when feeding', - function() + it(cmd .. 's' .. prep .. ' the current line by default when feeding', function() feed(':' .. cmd .. '\nabc\ndef\n.\n') eq(ret1, buffer_contents()) end) @@ -40,15 +38,15 @@ local cmdtest = function(cmd, prep, ret1) feed(':' .. hisline .. '<CR>') feed(':' .. cmd .. '<CR>abc<CR>def<C-f>') eq({ 'def' }, buffer_contents()) - eq(hisline, funcs.histget(':', -2)) - eq(cmd, funcs.histget(':')) + eq(hisline, fn.histget(':', -2)) + eq(cmd, fn.histget(':')) -- Test that command-line window was launched - eq('nofile', meths.get_option_value('buftype', {})) - eq('n', funcs.mode(1)) + eq('nofile', api.nvim_get_option_value('buftype', {})) + eq('n', fn.mode(1)) feed('<CR>') - eq('c', funcs.mode(1)) + eq('c', fn.mode(1)) feed('.<CR>') - eq('n', funcs.mode(1)) + eq('n', fn.mode(1)) eq(ret1, buffer_contents()) end) end) @@ -63,8 +61,8 @@ describe('the first line is redrawn correctly after inserting text in an empty b clear() screen = Screen.new(20, 8) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue}, - [2] = {bold = true, reverse = true}, + [1] = { bold = true, foreground = Screen.colors.Blue }, + [2] = { bold = true, reverse = true }, }) screen:attach() end) @@ -78,11 +76,7 @@ describe('the first line is redrawn correctly after inserting text in an empty b screen:expect([[ aaaaa | ^bbbbb | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | ]]) end) @@ -96,11 +90,7 @@ describe('the first line is redrawn correctly after inserting text in an empty b screen:expect([[ aaaaa | ^bbbbb | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | ]]) end) diff --git a/test/functional/ex_cmds/arg_spec.lua b/test/functional/ex_cmds/arg_spec.lua index 4dea50b53e..810b001ec0 100644 --- a/test/functional/ex_cmds/arg_spec.lua +++ b/test/functional/ex_cmds/arg_spec.lua @@ -1,30 +1,30 @@ -local helpers = require("test.functional.helpers")(after_each) -local eq, command, funcs = helpers.eq, helpers.command, helpers.funcs +local helpers = require('test.functional.helpers')(after_each) +local eq, command, fn = helpers.eq, helpers.command, helpers.fn local ok = helpers.ok local clear = helpers.clear -describe(":argument", function() +describe(':argument', function() before_each(function() clear() end) - it("does not restart :terminal buffer", function() - command("terminal") - helpers.feed([[<C-\><C-N>]]) - command("argadd") - helpers.feed([[<C-\><C-N>]]) - local bufname_before = funcs.bufname("%") - local bufnr_before = funcs.bufnr("%") - helpers.ok(nil ~= string.find(bufname_before, "^term://")) -- sanity + it('does not restart :terminal buffer', function() + command('terminal') + helpers.feed([[<C-\><C-N>]]) + command('argadd') + helpers.feed([[<C-\><C-N>]]) + local bufname_before = fn.bufname('%') + local bufnr_before = fn.bufnr('%') + helpers.ok(nil ~= string.find(bufname_before, '^term://')) -- sanity - command("argument 1") - helpers.feed([[<C-\><C-N>]]) + command('argument 1') + helpers.feed([[<C-\><C-N>]]) - local bufname_after = funcs.bufname("%") - local bufnr_after = funcs.bufnr("%") - eq("["..bufname_before.."]", helpers.eval('trim(execute("args"))')) - ok(funcs.line('$') > 1) - eq(bufname_before, bufname_after) - eq(bufnr_before, bufnr_after) + local bufname_after = fn.bufname('%') + local bufnr_after = fn.bufnr('%') + eq('[' .. bufname_before .. ']', helpers.eval('trim(execute("args"))')) + ok(fn.line('$') > 1) + eq(bufname_before, bufname_after) + eq(bufnr_before, bufnr_after) end) end) diff --git a/test/functional/ex_cmds/cd_spec.lua b/test/functional/ex_cmds/cd_spec.lua index b6a3713158..1815c672dc 100644 --- a/test/functional/ex_cmds/cd_spec.lua +++ b/test/functional/ex_cmds/cd_spec.lua @@ -1,6 +1,5 @@ -- Specs for :cd, :tcd, :lcd and getcwd() -local luv = require('luv') local helpers = require('test.functional.helpers')(after_each) local eq = helpers.eq @@ -21,18 +20,30 @@ local directories = { } -- Shorthand writing to get the current working directory -local cwd = function(...) return call('getcwd', ...) end -- effective working dir -local wcwd = function() return cwd(0) end -- window dir -local tcwd = function() return cwd(-1, 0) end -- tab dir +local cwd = function(...) + return call('getcwd', ...) +end -- effective working dir +local wcwd = function() + return cwd(0) +end -- window dir +local tcwd = function() + return cwd(-1, 0) +end -- tab dir -- Same, except these tell us if there is a working directory at all -local lwd = function(...) return call('haslocaldir', ...) end -- effective working dir -local wlwd = function() return lwd(0) end -- window dir -local tlwd = function() return lwd(-1, 0) end -- tab dir +local lwd = function(...) + return call('haslocaldir', ...) +end -- effective working dir +local wlwd = function() + return lwd(0) +end -- window dir +local tlwd = function() + return lwd(-1, 0) +end -- tab dir --local glwd = function() return eval('haslocaldir(-1, -1)') end -- global dir -- Test both the `cd` and `chdir` variants -for _, cmd in ipairs {'cd', 'chdir'} do +for _, cmd in ipairs { 'cd', 'chdir' } do describe(':' .. cmd, function() before_each(function() clear() @@ -44,7 +55,7 @@ for _, cmd in ipairs {'cd', 'chdir'} do after_each(function() for _, d in pairs(directories) do - luv.fs_rmdir(d) + vim.uv.fs_rmdir(d) end end) @@ -168,23 +179,23 @@ for _, cmd in ipairs {'cd', 'chdir'} do -- Create a new tab first and verify that is has the same working dir command('tabnew') eq(globalDir, cwd()) - eq(globalDir, tcwd()) -- has no tab-local directory + eq(globalDir, tcwd()) -- has no tab-local directory eq(0, tlwd()) - eq(globalDir, wcwd()) -- has no window-local directory + eq(globalDir, wcwd()) -- has no window-local directory eq(0, wlwd()) -- Change tab-local working directory and verify it is different command('silent t' .. cmd .. ' ' .. directories.tab) eq(globalDir .. pathsep .. directories.tab, cwd()) - eq(cwd(), tcwd()) -- working directory matches tab directory + eq(cwd(), tcwd()) -- working directory matches tab directory eq(1, tlwd()) - eq(cwd(), wcwd()) -- still no window-directory + eq(cwd(), wcwd()) -- still no window-directory eq(0, wlwd()) -- Create a new window in this tab to test `:lcd` command('new') - eq(1, tlwd()) -- Still tab-local working directory - eq(0, wlwd()) -- Still no window-local working directory + eq(1, tlwd()) -- Still tab-local working directory + eq(0, wlwd()) -- Still no window-local working directory eq(globalDir .. pathsep .. directories.tab, cwd()) command('silent l' .. cmd .. ' ../' .. directories.window) eq(globalDir .. pathsep .. directories.window, cwd()) @@ -193,13 +204,13 @@ for _, cmd in ipairs {'cd', 'chdir'} do -- Verify the first window still has the tab local directory command('wincmd w') - eq(globalDir .. pathsep .. directories.tab, cwd()) + eq(globalDir .. pathsep .. directories.tab, cwd()) eq(globalDir .. pathsep .. directories.tab, tcwd()) - eq(0, wlwd()) -- No window-local directory + eq(0, wlwd()) -- No window-local directory -- Change back to initial tab and verify working directory has stayed command('tabnext') - eq(globalDir, cwd() ) + eq(globalDir, cwd()) eq(0, tlwd()) eq(0, wlwd()) @@ -207,31 +218,31 @@ for _, cmd in ipairs {'cd', 'chdir'} do command('silent ' .. cmd .. ' ' .. directories.global) eq(globalDir .. pathsep .. directories.global, cwd()) command('tabnext') - eq(globalDir .. pathsep .. directories.tab, cwd()) + eq(globalDir .. pathsep .. directories.tab, cwd()) eq(globalDir .. pathsep .. directories.tab, tcwd()) - eq(0, wlwd()) -- Still no window-local directory in this window + eq(0, wlwd()) -- Still no window-local directory in this window -- Unless the global change happened in a tab with local directory command('silent ' .. cmd .. ' ..') - eq(globalDir, cwd() ) - eq(0 , tlwd()) - eq(0 , wlwd()) + eq(globalDir, cwd()) + eq(0, tlwd()) + eq(0, wlwd()) -- Which also affects the first tab command('tabnext') eq(globalDir, cwd()) -- But not in a window with its own local directory command('tabnext | wincmd w') - eq(globalDir .. pathsep .. directories.window, cwd() ) - eq(0 , tlwd()) + eq(globalDir .. pathsep .. directories.window, cwd()) + eq(0, tlwd()) eq(globalDir .. pathsep .. directories.window, wcwd()) end) end) end -- Test legal parameters for 'getcwd' and 'haslocaldir' -for _, cmd in ipairs {'getcwd', 'haslocaldir'} do - describe(cmd..'()', function() +for _, cmd in ipairs { 'getcwd', 'haslocaldir' } do + describe(cmd .. '()', function() before_each(function() clear() end) @@ -271,7 +282,7 @@ for _, cmd in ipairs {'getcwd', 'haslocaldir'} do end) end -describe("getcwd()", function () +describe('getcwd()', function() before_each(function() clear() mkdir(directories.global) @@ -281,11 +292,11 @@ describe("getcwd()", function () helpers.rmdir(directories.global) end) - it("returns empty string if working directory does not exist", function() + it('returns empty string if working directory does not exist', function() skip(is_os('win')) - command("cd "..directories.global) - command("call delete('../"..directories.global.."', 'd')") - eq("", helpers.eval("getcwd()")) + command('cd ' .. directories.global) + command("call delete('../" .. directories.global .. "', 'd')") + eq('', helpers.eval('getcwd()')) end) it("works with 'autochdir' after local directory was set (#9892)", function() diff --git a/test/functional/ex_cmds/cmd_map_spec.lua b/test/functional/ex_cmds/cmd_map_spec.lua index 2a2628350d..cb7d7340e2 100644 --- a/test/functional/ex_cmds/cmd_map_spec.lua +++ b/test/functional/ex_cmds/cmd_map_spec.lua @@ -4,7 +4,7 @@ local feed = helpers.feed local eq = helpers.eq local expect = helpers.expect local eval = helpers.eval -local funcs = helpers.funcs +local fn = helpers.fn local insert = helpers.insert local write_file = helpers.write_file local exc_exec = helpers.exc_exec @@ -16,24 +16,24 @@ describe('mappings with <Cmd>', function() local tmpfile = 'X_ex_cmds_cmd_map' local function cmdmap(lhs, rhs) - command('noremap '..lhs..' <Cmd>'..rhs..'<cr>') - command('noremap! '..lhs..' <Cmd>'..rhs..'<cr>') + command('noremap ' .. lhs .. ' <Cmd>' .. rhs .. '<cr>') + command('noremap! ' .. lhs .. ' <Cmd>' .. rhs .. '<cr>') end before_each(function() clear() screen = Screen.new(65, 8) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [3] = {bold = true, foreground = Screen.colors.SeaGreen4}, - [4] = {bold = true}, - [5] = {background = Screen.colors.LightGrey}, - [6] = {foreground = Screen.colors.Blue1}, - [7] = {bold = true, reverse = true}, - [8] = {background = Screen.colors.WebGray}, - [9] = {background = Screen.colors.LightMagenta}, - [10] = {foreground = Screen.colors.Red}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [3] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [4] = { bold = true }, + [5] = { foreground = Screen.colors.Black, background = Screen.colors.LightGrey }, + [6] = { foreground = Screen.colors.Blue1 }, + [7] = { bold = true, reverse = true }, + [8] = { background = Screen.colors.WebGray }, + [9] = { background = Screen.colors.LightMagenta }, + [10] = { foreground = Screen.colors.Red }, }) screen:attach() @@ -57,7 +57,7 @@ describe('mappings with <Cmd>', function() feed('gg') cmdmap('<F8>', 'startinsert') cmdmap('<F9>', 'stopinsert') - command("abbr foo <Cmd>let g:y = 17<cr>bar") + command('abbr foo <Cmd>let g:y = 17<cr>bar') end) after_each(function() @@ -69,11 +69,7 @@ describe('mappings with <Cmd>', function() screen:expect([[ ^some short lines | of test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {6:<F3>} {6:*} {6:<Cmd>}let m = mode(1){6:<CR>} | ]]) end) @@ -85,11 +81,7 @@ describe('mappings with <Cmd>', function() screen:expect([[ ^some short lines | of test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:E1136: <Cmd> mapping must end with <CR> before second <Cmd>} | ]]) @@ -98,11 +90,7 @@ describe('mappings with <Cmd>', function() screen:expect([[ ^some short lines | of test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:E1255: <Cmd> mapping must end with <CR>} | ]]) eq(0, eval('x')) @@ -114,11 +102,7 @@ describe('mappings with <Cmd>', function() screen:expect([[ some short lines | ^of test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | ]]) @@ -127,11 +111,7 @@ describe('mappings with <Cmd>', function() screen:expect([[ some short lines | of ^test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | ]]) end) @@ -141,7 +121,7 @@ describe('mappings with <Cmd>', function() feed('<F3>') eq('foo…bar', eval('g:str')) local str = eval([["foo\<D-…>bar"]]) - command([[noremap <F3> <Cmd>let g:str = ']]..str..[['<CR>]]) + command([[noremap <F3> <Cmd>let g:str = ']] .. str .. [['<CR>]]) feed('<F3>') eq(str, eval('g:str')) command([[noremap <F3> <Cmd>let g:str = 'foo<D-…>bar'<CR>]]) @@ -180,7 +160,7 @@ describe('mappings with <Cmd>', function() eq('n', eval('mode(1)')) -- operator-pending mode - feed("d<F3>") + feed('d<F3>') eq('no', eval('m')) -- did leave operator-pending mode eq('n', eval('mode(1)')) @@ -191,21 +171,21 @@ describe('mappings with <Cmd>', function() eq('i', eval('mode(1)')) -- replace mode - feed("<Ins><F3>") + feed('<Ins><F3>') eq('R', eval('m')) eq('R', eval('mode(1)')) feed('<esc>') eq('n', eval('mode(1)')) -- virtual replace mode - feed("gR<F3>") + feed('gR<F3>') eq('Rv', eval('m')) eq('Rv', eval('mode(1)')) feed('<esc>') eq('n', eval('mode(1)')) -- langmap works, but is not distinguished in mode(1) - feed(":set iminsert=1<cr>i<F3>") + feed(':set iminsert=1<cr>i<F3>') eq('i', eval('m')) eq('i', eval('mode(1)')) feed('<esc>') @@ -232,26 +212,22 @@ describe('mappings with <Cmd>', function() -- check v:count and v:register works feed('<F2>') - eq({'n', 0, '"'}, eval('s')) + eq({ 'n', 0, '"' }, eval('s')) feed('7<F2>') - eq({'n', 7, '"'}, eval('s')) + eq({ 'n', 7, '"' }, eval('s')) feed('"e<F2>') - eq({'n', 0, 'e'}, eval('s')) + eq({ 'n', 0, 'e' }, eval('s')) feed('5"k<F2>') - eq({'n', 5, 'k'}, eval('s')) + eq({ 'n', 5, 'k' }, eval('s')) feed('"+2<F2>') - eq({'n', 2, '+'}, eval('s')) + eq({ 'n', 2, '+' }, eval('s')) -- text object enters visual mode feed('<F7>') screen:expect([[ so{5:me short lines} | {5:of }^test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4:-- VISUAL --} | ]]) feed('<esc>') @@ -269,15 +245,11 @@ describe('mappings with <Cmd>', function() screen:expect([[ some short lines | of alpha^test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4:-- INSERT --} | ]]) -- feedkeys were not executed immediately - eq({'n', 'of test text'}, eval('[m,a]')) + eq({ 'n', 'of test text' }, eval('[m,a]')) eq('i', eval('mode(1)')) feed('<esc>') @@ -285,15 +257,11 @@ describe('mappings with <Cmd>', function() screen:expect([[ some short lines | of alphabet^atest text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | ]]) -- feedkeys(..., 'x') was executed immediately, but insert mode gets aborted - eq({'n', 'of alphabetatest text'}, eval('[m,b]')) + eq({ 'n', 'of alphabetatest text' }, eval('[m,b]')) eq('n', eval('mode(1)')) end) @@ -302,45 +270,39 @@ describe('mappings with <Cmd>', function() command('noremap ,f <Cmd>nosuchcommand<cr>') command('noremap ,e <Cmd>throw "very error"\\| call append(1, "yy")<cr>') command('noremap ,m <Cmd>echoerr "The message."\\| call append(1, "zz")<cr>') - command('noremap ,w <Cmd>for i in range(5)\\|if i==1\\|echoerr "Err"\\|endif\\|call append(1, i)\\|endfor<cr>') + command( + 'noremap ,w <Cmd>for i in range(5)\\|if i==1\\|echoerr "Err"\\|endif\\|call append(1, i)\\|endfor<cr>' + ) - feed(":normal ,x<cr>") + feed(':normal ,x<cr>') screen:expect([[ ^some short lines | aa | xx | of test text | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 :normal ,x | ]]) - eq('Vim:E492: Not an editor command: nosuchcommand', exc_exec("normal ,f")) - eq('very error', exc_exec("normal ,e")) - eq('Vim(echoerr):The message.', exc_exec("normal ,m")) + eq('Vim:E492: Not an editor command: nosuchcommand', exc_exec('normal ,f')) + eq('very error', exc_exec('normal ,e')) + eq('Vim(echoerr):The message.', exc_exec('normal ,m')) feed('w') screen:expect([[ some ^short lines | aa | xx | of test text | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 :normal ,x | ]]) command(':%d') - eq('Vim(echoerr):Err', exc_exec("normal ,w")) + eq('Vim(echoerr):Err', exc_exec('normal ,w')) screen:expect([[ ^ | 0 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 --No lines in buffer-- | ]]) @@ -364,27 +326,22 @@ describe('mappings with <Cmd>', function() screen:expect([[ {5:some short }^lines | of test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4:-- VISUAL --} | ]]) - eq('v', funcs.mode(1)) + eq('v', fn.mode(1)) -- can invoke operator, ending visual mode feed('<F5>') - eq('n', funcs.mode(1)) - eq({'some short l'}, funcs.getreg('a',1,1)) + eq('n', fn.mode(1)) + eq({ 'some short l' }, fn.getreg('a', 1, 1)) -- error doesn't interrupt visual mode feed('ggvw<F6>') screen:expect([[ {5:some }short lines | of test text | - {1:~ }| - {1:~ }| + {1:~ }|*2 {7: }| {2:Error detected while processing :} | {2:E605: Exception not caught: very error} | @@ -396,37 +353,25 @@ describe('mappings with <Cmd>', function() screen:expect([[ {5:some }^short lines | of test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4:-- VISUAL --} | ]]) - eq('v', funcs.mode(1)) + eq('v', fn.mode(1)) feed('<F7>') screen:expect([[ so{5:me short lines} | {5:of }^test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4:-- VISUAL --} | ]]) - eq('v', funcs.mode(1)) + eq('v', fn.mode(1)) -- startinsert gives "-- (insert) VISUAL --" mode feed('<F8>') screen:expect([[ so{5:me short lines} | {5:of }^test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4:-- (insert) VISUAL --} | ]]) eq('v', eval('mode(1)')) @@ -442,32 +387,27 @@ describe('mappings with <Cmd>', function() screen:expect([[ {5:some short }^lines | of test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4:-- SELECT --} | ]]) - eq('s', funcs.mode(1)) + eq('s', fn.mode(1)) -- visual mapping in select mode restart select mode after operator feed('<F5>') - eq('s', funcs.mode(1)) - eq({'some short l'}, funcs.getreg('a',1,1)) + eq('s', fn.mode(1)) + eq({ 'some short l' }, fn.getreg('a', 1, 1)) -- select mode mapping works, and does not restart select mode feed('<F2>') - eq('n', funcs.mode(1)) - eq({'some short l'}, funcs.getreg('b',1,1)) + eq('n', fn.mode(1)) + eq({ 'some short l' }, fn.getreg('b', 1, 1)) -- error doesn't interrupt temporary visual mode feed('<esc>ggvw<c-g><F6>') screen:expect([[ {5:some }short lines | of test text | - {1:~ }| - {1:~ }| + {1:~ }|*2 {7: }| {2:Error detected while processing :} | {2:E605: Exception not caught: very error} | @@ -479,23 +419,18 @@ describe('mappings with <Cmd>', function() screen:expect([[ {5:some }^short lines | of test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4:-- VISUAL --} | ]]) -- quirk: restoration of select mode is not performed - eq('v', funcs.mode(1)) + eq('v', fn.mode(1)) -- error doesn't interrupt select mode feed('<esc>ggvw<c-g><F1>') screen:expect([[ {5:some }short lines | of test text | - {1:~ }| - {1:~ }| + {1:~ }|*2 {7: }| {2:Error detected while processing :} | {2:E605: Exception not caught: very error} | @@ -507,39 +442,27 @@ describe('mappings with <Cmd>', function() screen:expect([[ {5:some }^short lines | of test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4:-- SELECT --} | ]]) -- quirk: restoration of select mode is not performed - eq('s', funcs.mode(1)) + eq('s', fn.mode(1)) feed('<F7>') screen:expect([[ so{5:me short lines} | {5:of }^test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4:-- SELECT --} | ]]) - eq('s', funcs.mode(1)) + eq('s', fn.mode(1)) -- startinsert gives "-- SELECT (insert) --" mode feed('<F8>') screen:expect([[ so{5:me short lines} | {5:of }^test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4:-- (insert) SELECT --} | ]]) eq('s', eval('mode(1)')) @@ -547,17 +470,16 @@ describe('mappings with <Cmd>', function() eq('i', eval('mode(1)')) end) - it('works in operator-pending mode', function() feed('d<F4>') expect([[ lines of test text]]) - eq({'some short '}, funcs.getreg('"',1,1)) + eq({ 'some short ' }, fn.getreg('"', 1, 1)) feed('.') expect([[ test text]]) - eq({'lines', 'of '}, funcs.getreg('"',1,1)) + eq({ 'lines', 'of ' }, fn.getreg('"', 1, 1)) feed('uu') expect([[ some short lines @@ -568,8 +490,7 @@ describe('mappings with <Cmd>', function() screen:expect([[ some short lines | of test text | - {1:~ }| - {1:~ }| + {1:~ }|*2 {7: }| {2:Error detected while processing :} | {2:E605: Exception not caught: very error} | @@ -584,7 +505,7 @@ describe('mappings with <Cmd>', function() feed('"bd<F7>') expect([[ soest text]]) - eq(funcs.getreg('b',1,1), {'me short lines', 'of t'}) + eq(fn.getreg('b', 1, 1), { 'me short lines', 'of t' }) -- startinsert aborts operator feed('d<F8>') @@ -594,17 +515,12 @@ describe('mappings with <Cmd>', function() end) it('works in insert mode', function() - -- works the same as <c-o>w<c-o>w feed('iindeed <F4>little ') screen:expect([[ indeed some short little ^lines | of test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4:-- INSERT --} | ]]) @@ -612,26 +528,20 @@ describe('mappings with <Cmd>', function() screen:expect([[ indeed some short little lines | of test text | - {1:~ }| - {1:~ }| + {1:~ }|*2 {7: }| {2:Error detected while processing :} | {2:E605: Exception not caught: very error} | {3:Press ENTER or type command to continue}^ | ]]) - feed('<cr>') eq('E605: Exception not caught: very error', eval('v:errmsg')) -- still in insert screen:expect([[ indeed some short little ^lines | of test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4:-- INSERT --} | ]]) eq('i', eval('mode(1)')) @@ -643,11 +553,7 @@ describe('mappings with <Cmd>', function() screen:expect([[ in{5:deed some short little lines} | {5:of stuff }^test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4:-- INSERT VISUAL --} | ]]) expect([[ @@ -655,17 +561,13 @@ describe('mappings with <Cmd>', function() of stuff test text]]) feed('<F5>') - eq(funcs.getreg('a',1,1), {'deed some short little lines', 'of stuff t'}) + eq(fn.getreg('a', 1, 1), { 'deed some short little lines', 'of stuff t' }) -- still in insert screen:expect([[ in^deed some short little lines | of stuff test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4:-- INSERT --} | ]]) eq('i', eval('mode(1)')) @@ -675,11 +577,7 @@ describe('mappings with <Cmd>', function() screen:expect([[ in bar ^deed some short little lines | of stuff test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4:-- INSERT --} | ]]) eq(17, eval('g:y')) @@ -700,9 +598,7 @@ describe('mappings with <Cmd>', function() some^ | {8:some } | {9:short }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {4:-- Keyword Local completion (^N^P) }{3:match 1 of 2} | ]]) @@ -717,9 +613,7 @@ describe('mappings with <Cmd>', function() some^ | {9:some } | {9:short }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {4:-- Keyword Local completion (^N^P) }{10:Back at original} | ]]) end) @@ -734,11 +628,7 @@ describe('mappings with <Cmd>', function() screen:expect([[ ^some short lines | of test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:E492: Not an editor command: text} | ]]) @@ -773,11 +663,7 @@ describe('mappings with <Cmd>', function() screen:expect([[ ^some short lines | of test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | ]]) eq('n', eval('mode(1)')) @@ -786,11 +672,7 @@ describe('mappings with <Cmd>', function() screen:expect([[ some short lines | of test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 :let g:x = 3^ | ]]) feed('+2<cr>') @@ -798,11 +680,7 @@ describe('mappings with <Cmd>', function() screen:expect([[ some short ^lines | of test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 :let g:x = 3+2 | ]]) eq(5, eval('g:x')) @@ -811,11 +689,7 @@ describe('mappings with <Cmd>', function() screen:expect([[ some short lines | of test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 :let g:y = 7^ | ]]) eq('c', eval('mode(1)')) @@ -824,16 +698,11 @@ describe('mappings with <Cmd>', function() screen:expect([[ some short ^lines | of test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4:-- INSERT --} | ]]) eq('i', eval('mode(1)')) eq(9, eval('g:y')) - end) it("doesn't crash when invoking cmdline mode recursively #8859", function() @@ -842,11 +711,7 @@ describe('mappings with <Cmd>', function() screen:expect([[ some short lines | of test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 :bar^ | ]]) @@ -854,27 +719,25 @@ describe('mappings with <Cmd>', function() screen:expect([[ some short lines | of test text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 :barx^ | ]]) end) - it("works with <SID> mappings", function() + it('works with <SID> mappings', function() command('new!') - write_file(tmpfile, [[ + write_file( + tmpfile, + [[ map <f2> <Cmd>call <SID>do_it()<Cr> function! s:do_it() let g:x = 10 endfunction - ]]) - command('source '..tmpfile) + ]] + ) + command('source ' .. tmpfile) feed('<f2>') eq('', eval('v:errmsg')) eq(10, eval('g:x')) end) end) - diff --git a/test/functional/ex_cmds/debug_spec.lua b/test/functional/ex_cmds/debug_spec.lua index a4d381d3f1..85327c87e6 100644 --- a/test/functional/ex_cmds/debug_spec.lua +++ b/test/functional/ex_cmds/debug_spec.lua @@ -9,10 +9,10 @@ describe(':debug', function() clear() screen = Screen.new(30, 14) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {bold = true, reverse = true}, - [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [4] = {bold = true, foreground = Screen.colors.SeaGreen4}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { bold = true, reverse = true }, + [3] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen4 }, }) screen:attach() end) @@ -20,14 +20,7 @@ describe(':debug', function() feed(':echoerr bork<cr>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 {2: }| {3:E121: Undefined variable: bork}| | @@ -38,11 +31,7 @@ describe(':debug', function() feed(':debug echo "aa"| echo "bb"<cr>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2: }| {3:E121: Undefined variable: bork}| | @@ -56,8 +45,7 @@ describe(':debug', function() feed('step<cr>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {2: }| {3:E121: Undefined variable: bork}| | @@ -92,18 +80,7 @@ describe(':debug', function() feed('<cr>') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*12 | ]]) end) diff --git a/test/functional/ex_cmds/dict_notifications_spec.lua b/test/functional/ex_cmds/dict_notifications_spec.lua index 6a0b40bd88..fc7714d16b 100644 --- a/test/functional/ex_cmds/dict_notifications_spec.lua +++ b/test/functional/ex_cmds/dict_notifications_spec.lua @@ -1,6 +1,7 @@ local helpers = require('test.functional.helpers')(after_each) local assert_alive = helpers.assert_alive -local clear, nvim, source = helpers.clear, helpers.nvim, helpers.source +local clear, source = helpers.clear, helpers.source +local api = helpers.api local insert = helpers.insert local eq, next_msg = helpers.eq, helpers.next_msg local exc_exec = helpers.exc_exec @@ -8,14 +9,13 @@ local exec_lua = helpers.exec_lua local command = helpers.command local eval = helpers.eval - describe('Vimscript dictionary notifications', function() local channel before_each(function() clear() - channel = nvim('get_api_info')[1] - nvim('set_var', 'channel', channel) + channel = api.nvim_get_chan_info(0).id + api.nvim_set_var('channel', channel) end) -- the same set of tests are applied to top-level dictionaries(g:, b:, w: and @@ -29,9 +29,9 @@ describe('Vimscript dictionary notifications', function() key = 'watched' end if opval == '' then - command(('unlet %s[\'%s\']'):format(dict_expr, key)) + command(("unlet %s['%s']"):format(dict_expr, key)) else - command(('let %s[\'%s\'] %s'):format(dict_expr, key, opval)) + command(("let %s['%s'] %s"):format(dict_expr, key, opval)) end end @@ -40,9 +40,9 @@ describe('Vimscript dictionary notifications', function() key = 'watched' end if opval == '' then - exec_lua(('vim.api.nvim_del_var(\'%s\')'):format(key)) + exec_lua(("vim.api.nvim_del_var('%s')"):format(key)) else - exec_lua(('vim.api.nvim_set_var(\'%s\', %s)'):format(key, opval)) + exec_lua(("vim.api.nvim_set_var('%s', %s)"):format(key, opval)) end end @@ -60,15 +60,15 @@ describe('Vimscript dictionary notifications', function() local function verify_echo() -- helper to verify that no notifications are sent after certain change -- to a dict - nvim('command', "call rpcnotify(g:channel, 'echo')") - eq({'notification', 'echo', {}}, next_msg()) + command("call rpcnotify(g:channel, 'echo')") + eq({ 'notification', 'echo', {} }, next_msg()) end local function verify_value(vals, key) if not key then key = 'watched' end - eq({'notification', 'values', {key, vals}}, next_msg()) + eq({ 'notification', 'values', { key, vals } }, next_msg()) end describe(dict_expr .. ' watcher', function() @@ -81,20 +81,20 @@ describe('Vimscript dictionary notifications', function() before_each(function() source([[ function! g:Changed(dict, key, value) - if a:dict isnot ]]..dict_expr..[[ | + if a:dict isnot ]] .. dict_expr .. [[ | throw 'invalid dict' endif call rpcnotify(g:channel, 'values', a:key, a:value) endfunction - call dictwatcheradd(]]..dict_expr..[[, "watched", "g:Changed") - call dictwatcheradd(]]..dict_expr..[[, "watched2", "g:Changed") + call dictwatcheradd(]] .. dict_expr .. [[, "watched", "g:Changed") + call dictwatcheradd(]] .. dict_expr .. [[, "watched2", "g:Changed") ]]) end) after_each(function() source([[ - call dictwatcherdel(]]..dict_expr..[[, "watched", "g:Changed") - call dictwatcherdel(]]..dict_expr..[[, "watched2", "g:Changed") + call dictwatcherdel(]] .. dict_expr .. [[, "watched", "g:Changed") + call dictwatcherdel(]] .. dict_expr .. [[, "watched2", "g:Changed") ]]) update('= "test"') update('= "test2"', 'watched2') @@ -134,99 +134,99 @@ describe('Vimscript dictionary notifications', function() it('is triggered by remove()', function() update('= "test"') - verify_value({new = 'test'}) - nvim('command', 'call remove('..dict_expr..', "watched")') - verify_value({old = 'test'}) + verify_value({ new = 'test' }) + command('call remove(' .. dict_expr .. ', "watched")') + verify_value({ old = 'test' }) end) if is_g then it('is triggered by remove() when updated with nvim_*_var', function() update_with_api('"test"') - verify_value({new = 'test'}) - nvim('command', 'call remove('..dict_expr..', "watched")') - verify_value({old = 'test'}) + verify_value({ new = 'test' }) + command('call remove(' .. dict_expr .. ', "watched")') + verify_value({ old = 'test' }) end) it('is triggered by remove() when updated with vim.g', function() update_with_vim_g('= "test"') - verify_value({new = 'test'}) - nvim('command', 'call remove('..dict_expr..', "watched")') - verify_value({old = 'test'}) + verify_value({ new = 'test' }) + command('call remove(' .. dict_expr .. ', "watched")') + verify_value({ old = 'test' }) end) end it('is triggered by extend()', function() update('= "xtend"') - verify_value({new = 'xtend'}) - nvim('command', [[ - call extend(]]..dict_expr..[[, {'watched': 'xtend2', 'watched2': 5, 'watched3': 'a'}) + verify_value({ new = 'xtend' }) + command([[ + call extend(]] .. dict_expr .. [[, {'watched': 'xtend2', 'watched2': 5, 'watched3': 'a'}) ]]) - verify_value({old = 'xtend', new = 'xtend2'}) - verify_value({new = 5}, 'watched2') + verify_value({ old = 'xtend', new = 'xtend2' }) + verify_value({ new = 5 }, 'watched2') update('') - verify_value({old = 'xtend2'}) + verify_value({ old = 'xtend2' }) update('', 'watched2') - verify_value({old = 5}, 'watched2') + verify_value({ old = 5 }, 'watched2') update('', 'watched3') verify_echo() end) it('is triggered with key patterns', function() source([[ - call dictwatcheradd(]]..dict_expr..[[, "wat*", "g:Changed") + call dictwatcheradd(]] .. dict_expr .. [[, "wat*", "g:Changed") ]]) update('= 1') - verify_value({new = 1}) - verify_value({new = 1}) + verify_value({ new = 1 }) + verify_value({ new = 1 }) update('= 3', 'watched2') - verify_value({new = 3}, 'watched2') - verify_value({new = 3}, 'watched2') + verify_value({ new = 3 }, 'watched2') + verify_value({ new = 3 }, 'watched2') verify_echo() source([[ - call dictwatcherdel(]]..dict_expr..[[, "wat*", "g:Changed") + call dictwatcherdel(]] .. dict_expr .. [[, "wat*", "g:Changed") ]]) -- watch every key pattern source([[ - call dictwatcheradd(]]..dict_expr..[[, "*", "g:Changed") + call dictwatcheradd(]] .. dict_expr .. [[, "*", "g:Changed") ]]) update('= 3', 'another_key') update('= 4', 'another_key') update('', 'another_key') update('= 2') - verify_value({new = 3}, 'another_key') - verify_value({old = 3, new = 4}, 'another_key') - verify_value({old = 4}, 'another_key') - verify_value({old = 1, new = 2}) - verify_value({old = 1, new = 2}) + verify_value({ new = 3 }, 'another_key') + verify_value({ old = 3, new = 4 }, 'another_key') + verify_value({ old = 4 }, 'another_key') + verify_value({ old = 1, new = 2 }) + verify_value({ old = 1, new = 2 }) verify_echo() source([[ - call dictwatcherdel(]]..dict_expr..[[, "*", "g:Changed") + call dictwatcherdel(]] .. dict_expr .. [[, "*", "g:Changed") ]]) end) it('is triggered for empty keys', function() command([[ - call dictwatcheradd(]]..dict_expr..[[, "", "g:Changed") + call dictwatcheradd(]] .. dict_expr .. [[, "", "g:Changed") ]]) update('= 1', '') - verify_value({new = 1}, '') + verify_value({ new = 1 }, '') update('= 2', '') - verify_value({old = 1, new = 2}, '') + verify_value({ old = 1, new = 2 }, '') command([[ - call dictwatcherdel(]]..dict_expr..[[, "", "g:Changed") + call dictwatcherdel(]] .. dict_expr .. [[, "", "g:Changed") ]]) end) it('is triggered for empty keys when using catch-all *', function() command([[ - call dictwatcheradd(]]..dict_expr..[[, "*", "g:Changed") + call dictwatcheradd(]] .. dict_expr .. [[, "*", "g:Changed") ]]) update('= 1', '') - verify_value({new = 1}, '') + verify_value({ new = 1 }, '') update('= 2', '') - verify_value({old = 1, new = 2}, '') + verify_value({ old = 1, new = 2 }, '') command([[ - call dictwatcherdel(]]..dict_expr..[[, "*", "g:Changed") + call dictwatcherdel(]] .. dict_expr .. [[, "*", "g:Changed") ]]) end) @@ -244,31 +244,31 @@ describe('Vimscript dictionary notifications', function() end test_updates({ - {'= 3', {new = 3}}, - {'= 6', {old = 3, new = 6}}, - {'+= 3', {old = 6, new = 9}}, - {'', {old = 9}} + { '= 3', { new = 3 } }, + { '= 6', { old = 3, new = 6 } }, + { '+= 3', { old = 6, new = 9 } }, + { '', { old = 9 } }, }) test_updates({ - {'= "str"', {new = 'str'}}, - {'= "str2"', {old = 'str', new = 'str2'}}, - {'.= "2str"', {old = 'str2', new = 'str22str'}}, - {'', {old = 'str22str'}} + { '= "str"', { new = 'str' } }, + { '= "str2"', { old = 'str', new = 'str2' } }, + { '.= "2str"', { old = 'str2', new = 'str22str' } }, + { '', { old = 'str22str' } }, }) test_updates({ - {'= [1, 2]', {new = {1, 2}}}, - {'= [1, 2, 3]', {old = {1, 2}, new = {1, 2, 3}}}, + { '= [1, 2]', { new = { 1, 2 } } }, + { '= [1, 2, 3]', { old = { 1, 2 }, new = { 1, 2, 3 } } }, -- the += will update the list in place, so old and new are the same - {'+= [4, 5]', {old = {1, 2, 3, 4, 5}, new = {1, 2, 3, 4, 5}}}, - {'', {old = {1, 2, 3, 4 ,5}}} + { '+= [4, 5]', { old = { 1, 2, 3, 4, 5 }, new = { 1, 2, 3, 4, 5 } } }, + { '', { old = { 1, 2, 3, 4, 5 } } }, }) test_updates({ - {'= {"k": "v"}', {new = {k = 'v'}}}, - {'= {"k1": 2}', {old = {k = 'v'}, new = {k1 = 2}}}, - {'', {old = {k1 = 2}}}, + { '= {"k": "v"}', { new = { k = 'v' } } }, + { '= {"k1": 2}', { old = { k = 'v' }, new = { k1 = 2 } } }, + { '', { old = { k1 = 2 } } }, }) end) end @@ -294,18 +294,18 @@ describe('Vimscript dictionary notifications', function() end) it('invokes all callbacks when the key is changed', function() - nvim('command', 'let g:key = "value"') - eq({'notification', '1', {'key', {new = 'value'}}}, next_msg()) - eq({'notification', '2', {'key', {new = 'value'}}}, next_msg()) + command('let g:key = "value"') + eq({ 'notification', '1', { 'key', { new = 'value' } } }, next_msg()) + eq({ 'notification', '2', { 'key', { new = 'value' } } }, next_msg()) end) it('only removes watchers that fully match dict, key and callback', function() - nvim('command', 'let g:key = "value"') - eq({'notification', '1', {'key', {new = 'value'}}}, next_msg()) - eq({'notification', '2', {'key', {new = 'value'}}}, next_msg()) - nvim('command', 'call dictwatcherdel(g:, "key", "g:Watcher1")') - nvim('command', 'let g:key = "v2"') - eq({'notification', '2', {'key', {old = 'value', new = 'v2'}}}, next_msg()) + command('let g:key = "value"') + eq({ 'notification', '1', { 'key', { new = 'value' } } }, next_msg()) + eq({ 'notification', '2', { 'key', { new = 'value' } } }, next_msg()) + command('call dictwatcherdel(g:, "key", "g:Watcher1")') + command('let g:key = "v2"') + eq({ 'notification', '2', { 'key', { old = 'value', new = 'v2' } } }, next_msg()) end) end) @@ -315,8 +315,10 @@ describe('Vimscript dictionary notifications', function() call rpcnotify(g:channel, '1', a:key, a:value) endfunction ]]) - eq('Vim(call):E46: Cannot change read-only variable "dictwatcheradd() argument"', - exc_exec('call dictwatcheradd(v:_null_dict, "x", "g:Watcher1")')) + eq( + 'Vim(call):E46: Cannot change read-only variable "dictwatcheradd() argument"', + exc_exec('call dictwatcheradd(v:_null_dict, "x", "g:Watcher1")') + ) end) describe('errors', function() @@ -333,13 +335,17 @@ describe('Vimscript dictionary notifications', function() -- WARNING: This suite depends on the above tests it('fails to remove if no watcher with matching callback is found', function() - eq("Vim(call):Couldn't find a watcher matching key and callback", - exc_exec('call dictwatcherdel(g:, "key", "g:Watcher1")')) + eq( + "Vim(call):Couldn't find a watcher matching key and callback", + exc_exec('call dictwatcherdel(g:, "key", "g:Watcher1")') + ) end) it('fails to remove if no watcher with matching key is found', function() - eq("Vim(call):Couldn't find a watcher matching key and callback", - exc_exec('call dictwatcherdel(g:, "invalid_key", "g:Watcher2")')) + eq( + "Vim(call):Couldn't find a watcher matching key and callback", + exc_exec('call dictwatcherdel(g:, "invalid_key", "g:Watcher2")') + ) end) it("does not fail to add/remove if the callback doesn't exist", function() @@ -348,8 +354,10 @@ describe('Vimscript dictionary notifications', function() end) it('fails to remove watcher from v:_null_dict', function() - eq("Vim(call):Couldn't find a watcher matching key and callback", - exc_exec('call dictwatcherdel(v:_null_dict, "x", "g:Watcher2")')) + eq( + "Vim(call):Couldn't find a watcher matching key and callback", + exc_exec('call dictwatcherdel(v:_null_dict, "x", "g:Watcher2")') + ) end) --[[ @@ -373,7 +381,7 @@ describe('Vimscript dictionary notifications', function() ]]) command('call g:ReplaceWatcher2()') command('let g:key = "value"') - eq({'notification', '2b', {'key', {old = 'v2', new = 'value'}}}, next_msg()) + eq({ 'notification', '2b', { 'key', { old = 'v2', new = 'value' } } }, next_msg()) end) it('does not crash when freeing a watched dictionary', function() @@ -400,7 +408,7 @@ describe('Vimscript dictionary notifications', function() call dictwatcheradd(d, 'foo', {dict, key, value -> rpcnotify(g:channel, '2', key, value)}) let d.foo = 'bar' ]]) - eq({'notification', '2', {'foo', {old = 'baz', new = 'bar'}}}, next_msg()) + eq({ 'notification', '2', { 'foo', { old = 'baz', new = 'bar' } } }, next_msg()) end) end) @@ -412,12 +420,11 @@ describe('Vimscript dictionary notifications', function() call dictwatcheradd(b:, 'changedtick', 'OnTickChanged') ]]) - insert('t'); - eq({'notification', 'SendChangeTick', {'changedtick', {old = 2, new = 3}}}, - next_msg()) + insert('t') + eq({ 'notification', 'SendChangeTick', { 'changedtick', { old = 2, new = 3 } } }, next_msg()) command([[call dictwatcherdel(b:, 'changedtick', 'OnTickChanged')]]) - insert('t'); + insert('t') assert_alive() end) @@ -479,7 +486,7 @@ describe('Vimscript dictionary notifications', function() let g:d.foo = 23 ]]) eq(23, eval('g:d.foo')) - eq({"W1"}, eval('g:calls')) + eq({ 'W1' }, eval('g:calls')) end) it('calls watcher deleted in callback', function() @@ -507,7 +514,6 @@ describe('Vimscript dictionary notifications', function() let g:d.foo = 123 ]]) eq(123, eval('g:d.foo')) - eq({"W1", "W2", "W2", "W1"}, eval('g:calls')) + eq({ 'W1', 'W2', 'W2', 'W1' }, eval('g:calls')) end) - end) diff --git a/test/functional/ex_cmds/digraphs_spec.lua b/test/functional/ex_cmds/digraphs_spec.lua index 5de2adc191..24b6f7c53b 100644 --- a/test/functional/ex_cmds/digraphs_spec.lua +++ b/test/functional/ex_cmds/digraphs_spec.lua @@ -10,13 +10,13 @@ describe(':digraphs', function() clear() screen = Screen.new(65, 8) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [3] = {bold = true, foreground = Screen.colors.SeaGreen4}, - [4] = {bold = true}, - [5] = {background = Screen.colors.LightGrey}, - [6] = {foreground = Screen.colors.Blue1}, - [7] = {bold = true, reverse = true}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [3] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [4] = { bold = true }, + [5] = { background = Screen.colors.LightGrey }, + [6] = { foreground = Screen.colors.Blue1 }, + [7] = { bold = true, reverse = true }, }) screen:attach() end) diff --git a/test/functional/ex_cmds/drop_spec.lua b/test/functional/ex_cmds/drop_spec.lua index 2537ab9cdc..cbda5aac98 100644 --- a/test/functional/ex_cmds/drop_spec.lua +++ b/test/functional/ex_cmds/drop_spec.lua @@ -3,7 +3,7 @@ local command = helpers.command local Screen = require('test.functional.ui.screen') local clear, feed, feed_command = helpers.clear, helpers.feed, helpers.feed_command -describe(":drop", function() +describe(':drop', function() local screen before_each(function() @@ -11,68 +11,52 @@ describe(":drop", function() screen = Screen.new(35, 10) screen:attach() screen:set_default_attr_ids({ - [0] = {bold=true, foreground=Screen.colors.Blue}, - [1] = {bold = true, reverse = true}, - [2] = {reverse = true}, - [3] = {bold = true}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { bold = true, reverse = true }, + [2] = { reverse = true }, + [3] = { bold = true }, }) - command("set laststatus=2 shortmess-=F") + command('set laststatus=2 shortmess-=F') end) - it("works like :e when called with only one window open", function() - feed_command("drop tmp1.vim") + it('works like :e when called with only one window open', function() + feed_command('drop tmp1.vim') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*7 {1:tmp1.vim }| "tmp1.vim" [New] | ]]) end) - it("switches to an open window showing the buffer", function() - feed_command("edit tmp1") - feed_command("vsplit") - feed_command("edit tmp2") - feed_command("drop tmp1") + it('switches to an open window showing the buffer', function() + feed_command('edit tmp1') + feed_command('vsplit') + feed_command('edit tmp2') + feed_command('drop tmp1') screen:expect([[ │^ | - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| + {0:~ }│{0:~ }|*7 {2:tmp2 }{1:tmp1 }| - :drop tmp1 | + "tmp1" [New] | ]]) end) it("splits off a new window when a buffer can't be abandoned", function() - command("set nohidden") - feed_command("edit tmp1") - feed_command("vsplit") - feed_command("edit tmp2") - feed("iABC<esc>") - feed_command("drop tmp3") + command('set nohidden') + feed_command('edit tmp1') + feed_command('vsplit') + feed_command('edit tmp2') + feed('iABC<esc>') + feed_command('drop tmp3') screen:expect([[ ^ │ | - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| + {0:~ }│{0:~ }|*3 {1:tmp3 }│{0:~ }| ABC │{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| + {0:~ }│{0:~ }|*2 {2:tmp2 [+] tmp1 }| "tmp3" [New] | ]]) end) - end) diff --git a/test/functional/ex_cmds/echo_spec.lua b/test/functional/ex_cmds/echo_spec.lua index a6be04138b..e9176a6204 100644 --- a/test/functional/ex_cmds/echo_spec.lua +++ b/test/functional/ex_cmds/echo_spec.lua @@ -1,11 +1,11 @@ local helpers = require('test.functional.helpers')(after_each) local eq = helpers.eq -local NIL = helpers.NIL +local NIL = vim.NIL local eval = helpers.eval local clear = helpers.clear -local meths = helpers.meths -local funcs = helpers.funcs +local api = helpers.api +local fn = helpers.fn local source = helpers.source local dedent = helpers.dedent local command = helpers.command @@ -14,15 +14,15 @@ local exec_capture = helpers.exec_capture local matches = helpers.matches describe(':echo :echon :echomsg :echoerr', function() - local fn_tbl = {'String', 'StringN', 'StringMsg', 'StringErr'} + local fn_tbl = { 'String', 'StringN', 'StringMsg', 'StringErr' } local function assert_same_echo_dump(expected, input, use_eval) - for _,v in pairs(fn_tbl) do - eq(expected, use_eval and eval(v..'('..input..')') or funcs[v](input)) + for _, v in pairs(fn_tbl) do + eq(expected, use_eval and eval(v .. '(' .. input .. ')') or fn[v](input)) end end local function assert_matches_echo_dump(expected, input, use_eval) - for _,v in pairs(fn_tbl) do - matches(expected, use_eval and eval(v..'('..input..')') or funcs[v](input)) + for _, v in pairs(fn_tbl) do + matches(expected, use_eval and eval(v .. '(' .. input .. ')') or fn[v](input)) end end @@ -68,31 +68,29 @@ describe(':echo :echon :echomsg :echoerr', function() eq('v:true', eval('String(v:true)')) eq('v:false', eval('String(v:false)')) eq('v:null', eval('String(v:null)')) - eq('v:true', funcs.String(true)) - eq('v:false', funcs.String(false)) - eq('v:null', funcs.String(NIL)) + eq('v:true', fn.String(true)) + eq('v:false', fn.String(false)) + eq('v:null', fn.String(NIL)) eq('v:true', eval('StringMsg(v:true)')) eq('v:false', eval('StringMsg(v:false)')) eq('v:null', eval('StringMsg(v:null)')) - eq('v:true', funcs.StringMsg(true)) - eq('v:false', funcs.StringMsg(false)) - eq('v:null', funcs.StringMsg(NIL)) + eq('v:true', fn.StringMsg(true)) + eq('v:false', fn.StringMsg(false)) + eq('v:null', fn.StringMsg(NIL)) eq('v:true', eval('StringErr(v:true)')) eq('v:false', eval('StringErr(v:false)')) eq('v:null', eval('StringErr(v:null)')) - eq('v:true', funcs.StringErr(true)) - eq('v:false', funcs.StringErr(false)) - eq('v:null', funcs.StringErr(NIL)) + eq('v:true', fn.StringErr(true)) + eq('v:false', fn.StringErr(false)) + eq('v:null', fn.StringErr(NIL)) end) - it('dumps values with at most six digits after the decimal point', - function() + it('dumps values with at most six digits after the decimal point', function() assert_same_echo_dump('1.234568e-20', 1.23456789123456789123456789e-020) assert_same_echo_dump('1.234568', 1.23456789123456789123456789) end) - it('dumps values with at most seven digits before the decimal point', - function() + it('dumps values with at most seven digits before the decimal point', function() assert_same_echo_dump('1234567.891235', 1234567.89123456789123456789) assert_same_echo_dump('1.234568e7', 12345678.9123456789123456789) end) @@ -115,8 +113,8 @@ describe(':echo :echon :echomsg :echoerr', function() end) it('dumps large values', function() - assert_same_echo_dump('2147483647', 2^31-1) - assert_same_echo_dump('-2147483648', -2^31) + assert_same_echo_dump('2147483647', 2 ^ 31 - 1) + assert_same_echo_dump('-2147483648', -2 ^ 31) end) end) @@ -198,75 +196,95 @@ describe(':echo :echon :echomsg :echoerr', function() let TestDictRef = function('TestDict', d) let d.tdr = TestDictRef ]]) - eq(dedent([[ + eq( + dedent([[ function('TestDict', {'tdr': function('TestDict', {...@1})})]]), - exec_capture('echo String(d.tdr)')) + exec_capture('echo String(d.tdr)') + ) end) it('dumps automatically created partials', function() assert_same_echo_dump( "function('<SNR>1_Test2', {'f': function('<SNR>1_Test2')})", '{"f": Test2_f}.f', - true) + true + ) assert_same_echo_dump( "function('<SNR>1_Test2', [1], {'f': function('<SNR>1_Test2', [1])})", '{"f": function(Test2_f, [1])}.f', - true) + true + ) end) it('dumps manually created partials', function() - assert_same_echo_dump("function('Test3', [1, 2], {})", - "function('Test3', [1, 2], {})", true) - assert_same_echo_dump("function('Test3', [1, 2])", - "function('Test3', [1, 2])", true) - assert_same_echo_dump("function('Test3', {})", - "function('Test3', {})", true) + assert_same_echo_dump("function('Test3', [1, 2], {})", "function('Test3', [1, 2], {})", true) + assert_same_echo_dump("function('Test3', [1, 2])", "function('Test3', [1, 2])", true) + assert_same_echo_dump("function('Test3', {})", "function('Test3', {})", true) end) - it('does not crash or halt when dumping partials with reference cycles in self', - function() - meths.set_var('d', {v=true}) - eq(dedent([[ - {'p': function('<SNR>1_Test2', {...@0}), 'f': function('<SNR>1_Test2'), 'v': v:true}]]), - exec_capture('echo String(extend(extend(g:d, {"f": g:Test2_f}), {"p": g:d.f}))')) + it('does not crash or halt when dumping partials with reference cycles in self', function() + api.nvim_set_var('d', { v = true }) + eq( + dedent( + [[ + {'p': function('<SNR>1_Test2', {...@0}), 'f': function('<SNR>1_Test2'), 'v': v:true}]] + ), + exec_capture('echo String(extend(extend(g:d, {"f": g:Test2_f}), {"p": g:d.f}))') + ) end) - it('does not show errors when dumping partials referencing the same dictionary', - function() + it('does not show errors when dumping partials referencing the same dictionary', function() command('let d = {}') -- Regression for “eval/typval_encode: Dump empty dictionary before -- checking for refcycle”, results in error. - eq('[function(\'tr\', {}), function(\'tr\', {})]', eval('String([function("tr", d), function("tr", d)])')) + eq( + "[function('tr', {}), function('tr', {})]", + eval('String([function("tr", d), function("tr", d)])') + ) -- Regression for “eval: Work with reference cycles in partials (self) -- properly”, results in crash. eval('extend(d, {"a": 1})') - eq('[function(\'tr\', {\'a\': 1}), function(\'tr\', {\'a\': 1})]', eval('String([function("tr", d), function("tr", d)])')) + eq( + "[function('tr', {'a': 1}), function('tr', {'a': 1})]", + eval('String([function("tr", d), function("tr", d)])') + ) end) - it('does not crash or halt when dumping partials with reference cycles in arguments', - function() - meths.set_var('l', {}) + it('does not crash or halt when dumping partials with reference cycles in arguments', function() + api.nvim_set_var('l', {}) eval('add(l, l)') -- Regression: the below line used to crash (add returns original list and -- there was error in dumping partials). Tested explicitly in -- test/unit/api/private_helpers_spec.lua. eval('add(l, function("Test1", l))') - eq(dedent([=[ - function('Test1', [[[...@2], function('Test1', [[...@2]])], function('Test1', [[[...@4], function('Test1', [[...@4]])]])])]=]), - exec_capture('echo String(function("Test1", l))')) - end) - - it('does not crash or halt when dumping partials with reference cycles in self and arguments', - function() - meths.set_var('d', {v=true}) - meths.set_var('l', {}) - eval('add(l, l)') - eval('add(l, function("Test1", l))') - eval('add(l, function("Test1", d))') - eq(dedent([=[ - {'p': function('<SNR>1_Test2', [[[...@3], function('Test1', [[...@3]]), function('Test1', {...@0})], function('Test1', [[[...@5], function('Test1', [[...@5]]), function('Test1', {...@0})]]), function('Test1', {...@0})], {...@0}), 'f': function('<SNR>1_Test2'), 'v': v:true}]=]), - exec_capture('echo String(extend(extend(g:d, {"f": g:Test2_f}), {"p": function(g:d.f, l)}))')) - end) + eq( + dedent( + [=[ + function('Test1', [[[...@2], function('Test1', [[...@2]])], function('Test1', [[[...@4], function('Test1', [[...@4]])]])])]=] + ), + exec_capture('echo String(function("Test1", l))') + ) + end) + + it( + 'does not crash or halt when dumping partials with reference cycles in self and arguments', + function() + api.nvim_set_var('d', { v = true }) + api.nvim_set_var('l', {}) + eval('add(l, l)') + eval('add(l, function("Test1", l))') + eval('add(l, function("Test1", d))') + eq( + dedent( + [=[ + {'p': function('<SNR>1_Test2', [[[...@3], function('Test1', [[...@3]]), function('Test1', {...@0})], function('Test1', [[[...@5], function('Test1', [[...@5]]), function('Test1', {...@0})]]), function('Test1', {...@0})], {...@0}), 'f': function('<SNR>1_Test2'), 'v': v:true}]=] + ), + exec_capture( + 'echo String(extend(extend(g:d, {"f": g:Test2_f}), {"p": function(g:d.f, l)}))' + ) + ) + end + ) end) describe('used to represent lists', function() @@ -275,25 +293,25 @@ describe(':echo :echon :echomsg :echoerr', function() end) it('dumps non-empty list', function() - assert_same_echo_dump('[1, 2]', {1,2}) + assert_same_echo_dump('[1, 2]', { 1, 2 }) end) it('dumps nested lists', function() - assert_same_echo_dump('[[[[[]]]]]', {{{{{}}}}}) + assert_same_echo_dump('[[[[[]]]]]', { { { { {} } } } }) end) it('dumps nested non-empty lists', function() - assert_same_echo_dump('[1, [[3, [[5], 4]], 2]]', {1, {{3, {{5}, 4}}, 2}}) + assert_same_echo_dump('[1, [[3, [[5], 4]], 2]]', { 1, { { 3, { { 5 }, 4 } }, 2 } }) end) it('does not error when dumping recursive lists', function() - meths.set_var('l', {}) + api.nvim_set_var('l', {}) eval('add(l, l)') eq(0, exc_exec('echo String(l)')) end) it('dumps recursive lists without error', function() - meths.set_var('l', {}) + api.nvim_set_var('l', {}) eval('add(l, l)') eq('[[...@0]]', exec_capture('echo String(l)')) eq('[[[...@1]]]', exec_capture('echo String([l])')) @@ -308,27 +326,25 @@ describe(':echo :echon :echomsg :echoerr', function() it('dumps list with two same empty dictionaries, also in partials', function() command('let d = {}') assert_same_echo_dump('[{}, {}]', '[d, d]', true) - eq('[function(\'tr\', {}), {}]', eval('String([function("tr", d), d])')) - eq('[{}, function(\'tr\', {})]', eval('String([d, function("tr", d)])')) + eq("[function('tr', {}), {}]", eval('String([function("tr", d), d])')) + eq("[{}, function('tr', {})]", eval('String([d, function("tr", d)])')) end) it('dumps non-empty dictionary', function() - assert_same_echo_dump("{'t''est': 1}", {["t'est"]=1}) + assert_same_echo_dump("{'t''est': 1}", { ["t'est"] = 1 }) end) it('does not error when dumping recursive dictionaries', function() - meths.set_var('d', {d=1}) + api.nvim_set_var('d', { d = 1 }) eval('extend(d, {"d": d})') eq(0, exc_exec('echo String(d)')) end) it('dumps recursive dictionaries without the error', function() - meths.set_var('d', {d=1}) + api.nvim_set_var('d', { d = 1 }) eval('extend(d, {"d": d})') - eq('{\'d\': {...@0}}', - exec_capture('echo String(d)')) - eq('{\'out\': {\'d\': {...@1}}}', - exec_capture('echo String({"out": d})')) + eq("{'d': {...@0}}", exec_capture('echo String(d)')) + eq("{'out': {'d': {...@1}}}", exec_capture('echo String({"out": d})')) end) end) @@ -342,43 +358,43 @@ describe(':echo :echon :echomsg :echoerr', function() it('displays hex as hex', function() -- Regression: due to missing (uint8_t) cast \x80 was represented as -- ~@<80>. - eq('<80>', funcs.String(chr(0x80))) - eq('<81>', funcs.String(chr(0x81))) - eq('<8e>', funcs.String(chr(0x8e))) - eq('<c2>', funcs.String(('«'):sub(1, 1))) - eq('«', funcs.String(('«'):sub(1, 2))) - - eq('<80>', funcs.StringMsg(chr(0x80))) - eq('<81>', funcs.StringMsg(chr(0x81))) - eq('<8e>', funcs.StringMsg(chr(0x8e))) - eq('<c2>', funcs.StringMsg(('«'):sub(1, 1))) - eq('«', funcs.StringMsg(('«'):sub(1, 2))) + eq('<80>', fn.String(chr(0x80))) + eq('<81>', fn.String(chr(0x81))) + eq('<8e>', fn.String(chr(0x8e))) + eq('<c2>', fn.String(('«'):sub(1, 1))) + eq('«', fn.String(('«'):sub(1, 2))) + + eq('<80>', fn.StringMsg(chr(0x80))) + eq('<81>', fn.StringMsg(chr(0x81))) + eq('<8e>', fn.StringMsg(chr(0x8e))) + eq('<c2>', fn.StringMsg(('«'):sub(1, 1))) + eq('«', fn.StringMsg(('«'):sub(1, 2))) end) it('displays ASCII control characters using ^X notation', function() - eq('^C', funcs.String(ctrl('c'))) - eq('^A', funcs.String(ctrl('a'))) - eq('^F', funcs.String(ctrl('f'))) - eq('^C', funcs.StringMsg(ctrl('c'))) - eq('^A', funcs.StringMsg(ctrl('a'))) - eq('^F', funcs.StringMsg(ctrl('f'))) + eq('^C', fn.String(ctrl('c'))) + eq('^A', fn.String(ctrl('a'))) + eq('^F', fn.String(ctrl('f'))) + eq('^C', fn.StringMsg(ctrl('c'))) + eq('^A', fn.StringMsg(ctrl('a'))) + eq('^F', fn.StringMsg(ctrl('f'))) end) it('prints CR, NL and tab as-is', function() - eq('\n', funcs.String('\n')) - eq('\r', funcs.String('\r')) - eq('\t', funcs.String('\t')) + eq('\n', fn.String('\n')) + eq('\r', fn.String('\r')) + eq('\t', fn.String('\t')) end) it('prints non-printable UTF-8 in <> notation', function() -- SINGLE SHIFT TWO, unicode control - eq('<8e>', funcs.String(funcs.nr2char(0x8E))) - eq('<8e>', funcs.StringMsg(funcs.nr2char(0x8E))) + eq('<8e>', fn.String(fn.nr2char(0x8E))) + eq('<8e>', fn.StringMsg(fn.nr2char(0x8E))) -- Surrogate pair: U+1F0A0 PLAYING CARD BACK is represented in UTF-16 as -- 0xD83C 0xDCA0. This is not valid in UTF-8. - eq('<d83c>', funcs.String(funcs.nr2char(0xD83C))) - eq('<dca0>', funcs.String(funcs.nr2char(0xDCA0))) - eq('<d83c><dca0>', funcs.String(funcs.nr2char(0xD83C) .. funcs.nr2char(0xDCA0))) - eq('<d83c>', funcs.StringMsg(funcs.nr2char(0xD83C))) - eq('<dca0>', funcs.StringMsg(funcs.nr2char(0xDCA0))) - eq('<d83c><dca0>', funcs.StringMsg(funcs.nr2char(0xD83C) .. funcs.nr2char(0xDCA0))) + eq('<d83c>', fn.String(fn.nr2char(0xD83C))) + eq('<dca0>', fn.String(fn.nr2char(0xDCA0))) + eq('<d83c><dca0>', fn.String(fn.nr2char(0xD83C) .. fn.nr2char(0xDCA0))) + eq('<d83c>', fn.StringMsg(fn.nr2char(0xD83C))) + eq('<dca0>', fn.StringMsg(fn.nr2char(0xDCA0))) + eq('<d83c><dca0>', fn.StringMsg(fn.nr2char(0xD83C) .. fn.nr2char(0xDCA0))) end) end) end) diff --git a/test/functional/ex_cmds/edit_spec.lua b/test/functional/ex_cmds/edit_spec.lua index 6ed500a293..b927fa418a 100644 --- a/test/functional/ex_cmds/edit_spec.lua +++ b/test/functional/ex_cmds/edit_spec.lua @@ -1,27 +1,27 @@ -local helpers = require("test.functional.helpers")(after_each) -local eq, command, funcs = helpers.eq, helpers.command, helpers.funcs +local helpers = require('test.functional.helpers')(after_each) +local eq, command, fn = helpers.eq, helpers.command, helpers.fn local ok = helpers.ok local clear = helpers.clear local feed = helpers.feed -describe(":edit", function() +describe(':edit', function() before_each(function() clear() end) - it("without arguments does not restart :terminal buffer", function() - command("terminal") - feed([[<C-\><C-N>]]) - local bufname_before = funcs.bufname("%") - local bufnr_before = funcs.bufnr("%") - helpers.ok(nil ~= string.find(bufname_before, "^term://")) -- sanity + it('without arguments does not restart :terminal buffer', function() + command('terminal') + feed([[<C-\><C-N>]]) + local bufname_before = fn.bufname('%') + local bufnr_before = fn.bufnr('%') + helpers.ok(nil ~= string.find(bufname_before, '^term://')) -- sanity - command("edit") + command('edit') - local bufname_after = funcs.bufname("%") - local bufnr_after = funcs.bufnr("%") - ok(funcs.line('$') > 1) - eq(bufname_before, bufname_after) - eq(bufnr_before, bufnr_after) + local bufname_after = fn.bufname('%') + local bufnr_after = fn.bufnr('%') + ok(fn.line('$') > 1) + eq(bufname_before, bufname_after) + eq(bufnr_before, bufnr_after) end) end) diff --git a/test/functional/ex_cmds/encoding_spec.lua b/test/functional/ex_cmds/encoding_spec.lua index 7f2bd78a47..8953fb8eaf 100644 --- a/test/functional/ex_cmds/encoding_spec.lua +++ b/test/functional/ex_cmds/encoding_spec.lua @@ -3,7 +3,6 @@ local clear, feed_command, feed = helpers.clear, helpers.feed_command, helpers.f local eq, neq, eval = helpers.eq, helpers.neq, helpers.eval describe('&encoding', function() - before_each(function() clear() -- sanity check: tests should run with encoding=utf-8 @@ -32,9 +31,9 @@ describe('&encoding', function() it('can be set to utf-8 without error', function() feed_command('set encoding=utf-8') - eq("", eval('v:errmsg')) + eq('', eval('v:errmsg')) clear('--cmd', 'set enc=utf-8') - eq("", eval('v:errmsg')) + eq('', eval('v:errmsg')) end) end) diff --git a/test/functional/ex_cmds/excmd_spec.lua b/test/functional/ex_cmds/excmd_spec.lua index a92329ede5..d16a52ee62 100644 --- a/test/functional/ex_cmds/excmd_spec.lua +++ b/test/functional/ex_cmds/excmd_spec.lua @@ -1,8 +1,8 @@ -local helpers = require("test.functional.helpers")(after_each) +local helpers = require('test.functional.helpers')(after_each) local command = helpers.command local eq = helpers.eq local clear = helpers.clear -local funcs = helpers.funcs +local fn = helpers.fn local pcall_err = helpers.pcall_err local assert_alive = helpers.assert_alive @@ -20,15 +20,25 @@ describe('Ex cmds', function() command(':later 9999999999999999999999999999999999999999') command(':echo expand("#<9999999999999999999999999999999999999999")') command(':lockvar 9999999999999999999999999999999999999999') - command(':winsize 9999999999999999999999999999999999999999 9999999999999999999999999999999999999999') - check_excmd_err(':tabnext 9999999999999999999999999999999999999999', - 'Vim(tabnext):E475: Invalid argument: 9999999999999999999999999999999999999999') - check_excmd_err(':N 9999999999999999999999999999999999999999', - 'Vim(Next):E939: Positive count required') - check_excmd_err(':bdelete 9999999999999999999999999999999999999999', - 'Vim(bdelete):E939: Positive count required') - eq('Vim(menu):E329: No menu "9999999999999999999999999999999999999999"', - pcall_err(command, ':menu 9999999999999999999999999999999999999999')) + command( + ':winsize 9999999999999999999999999999999999999999 9999999999999999999999999999999999999999' + ) + check_excmd_err( + ':tabnext 9999999999999999999999999999999999999999', + 'Vim(tabnext):E475: Invalid argument: 9999999999999999999999999999999999999999' + ) + check_excmd_err( + ':N 9999999999999999999999999999999999999999', + 'Vim(Next):E939: Positive count required' + ) + check_excmd_err( + ':bdelete 9999999999999999999999999999999999999999', + 'Vim(bdelete):E939: Positive count required' + ) + eq( + 'Vim(menu):E329: No menu "9999999999999999999999999999999999999999"', + pcall_err(command, ':menu 9999999999999999999999999999999999999999') + ) assert_alive() end) @@ -39,15 +49,15 @@ describe('Ex cmds', function() it(':def is an unknown command #23149', function() eq('Vim:E492: Not an editor command: def', pcall_err(command, 'def')) - eq(1, funcs.exists(':d')) - eq('delete', funcs.fullcommand('d')) - eq(1, funcs.exists(':de')) - eq('delete', funcs.fullcommand('de')) - eq(0, funcs.exists(':def')) - eq('', funcs.fullcommand('def')) - eq(1, funcs.exists(':defe')) - eq('defer', funcs.fullcommand('defe')) - eq(2, funcs.exists(':defer')) - eq('defer', funcs.fullcommand('defer')) + eq(1, fn.exists(':d')) + eq('delete', fn.fullcommand('d')) + eq(1, fn.exists(':de')) + eq('delete', fn.fullcommand('de')) + eq(0, fn.exists(':def')) + eq('', fn.fullcommand('def')) + eq(1, fn.exists(':defe')) + eq('defer', fn.fullcommand('defe')) + eq(2, fn.exists(':defer')) + eq('defer', fn.fullcommand('defer')) end) end) diff --git a/test/functional/ex_cmds/file_spec.lua b/test/functional/ex_cmds/file_spec.lua index 131661828e..a48c408600 100644 --- a/test/functional/ex_cmds/file_spec.lua +++ b/test/functional/ex_cmds/file_spec.lua @@ -1,14 +1,13 @@ local helpers = require('test.functional.helpers')(after_each) -local luv = require('luv') local clear = helpers.clear local command = helpers.command local eq = helpers.eq -local funcs = helpers.funcs +local fn = helpers.fn local rmdir = helpers.rmdir local mkdir = helpers.mkdir describe(':file', function() - local swapdir = luv.cwd()..'/Xtest-file_spec' + local swapdir = vim.uv.cwd() .. '/Xtest-file_spec' before_each(function() clear() rmdir(swapdir) @@ -19,18 +18,17 @@ describe(':file', function() rmdir(swapdir) end) - it("rename does not lose swapfile #6487", function() + it('rename does not lose swapfile #6487', function() local testfile = 'test-file_spec' - local testfile_renamed = testfile..'-renamed' + local testfile_renamed = testfile .. '-renamed' -- Note: `set swapfile` *must* go after `set directory`: otherwise it may -- attempt to create a swapfile in different directory. - command('set directory^='..swapdir..'//') + command('set directory^=' .. swapdir .. '//') command('set swapfile fileformat=unix undolevels=-1') - command('edit! '..testfile) + command('edit! ' .. testfile) -- Before #6487 this gave "E301: Oops, lost the swap file !!!" on Windows. - command('file '..testfile_renamed) - eq(testfile_renamed..'.swp', - string.match(funcs.execute('swapname'), '[^%%]+$')) + command('file ' .. testfile_renamed) + eq(testfile_renamed .. '.swp', string.match(fn.execute('swapname'), '[^%%]+$')) end) end) diff --git a/test/functional/ex_cmds/grep_spec.lua b/test/functional/ex_cmds/grep_spec.lua index 43ef1bd424..bf81ba2137 100644 --- a/test/functional/ex_cmds/grep_spec.lua +++ b/test/functional/ex_cmds/grep_spec.lua @@ -15,7 +15,7 @@ describe(':grep', function() -- Change to test directory so that the test does not run too long. feed_command('cd test') feed_command('grep a **/*') - feed('<cr>') -- Press ENTER - ok(eval('len(getqflist())') > 9000) -- IT'S OVER 9000!!1 + feed('<cr>') -- Press ENTER + ok(eval('len(getqflist())') > 9000) -- IT'S OVER 9000!!1 end) end) diff --git a/test/functional/ex_cmds/help_spec.lua b/test/functional/ex_cmds/help_spec.lua index aca0cbbaa6..cee33de1a6 100644 --- a/test/functional/ex_cmds/help_spec.lua +++ b/test/functional/ex_cmds/help_spec.lua @@ -3,8 +3,8 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local command = helpers.command local eq = helpers.eq -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local mkdir = helpers.mkdir local rmdir = helpers.rmdir local write_file = helpers.write_file @@ -15,19 +15,19 @@ describe(':help', function() it('window closed makes cursor return to a valid win/buf #9773', function() helpers.add_builddir_to_rtp() command('help help') - eq(1001, funcs.win_getid()) + eq(1001, fn.win_getid()) command('quit') - eq(1000, funcs.win_getid()) + eq(1000, fn.win_getid()) command('autocmd WinNew * wincmd p') command('help help') -- Window 1002 is opened, but the autocmd switches back to 1000 and -- creates the help buffer there instead. - eq(1000, funcs.win_getid()) + eq(1000, fn.win_getid()) command('quit') -- Before #9773, Nvim would crash on quitting the help window. - eq(1002, funcs.win_getid()) + eq(1002, fn.win_getid()) end) it('multibyte help tags work #23975', function() @@ -40,6 +40,6 @@ describe(':help', function() command('helptags Xhelptags/doc') command('set rtp+=Xhelptags') command('help …') - eq('*…*', meths.get_current_line()) + eq('*…*', api.nvim_get_current_line()) end) end) diff --git a/test/functional/ex_cmds/highlight_spec.lua b/test/functional/ex_cmds/highlight_spec.lua index 958dd99226..897a2997bc 100644 --- a/test/functional/ex_cmds/highlight_spec.lua +++ b/test/functional/ex_cmds/highlight_spec.lua @@ -1,11 +1,11 @@ local Screen = require('test.functional.ui.screen') -local helpers = require("test.functional.helpers")(after_each) +local helpers = require('test.functional.helpers')(after_each) local eq, command = helpers.eq, helpers.command local clear = helpers.clear local eval, exc_exec = helpers.eval, helpers.exc_exec local exec = helpers.exec -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api describe(':highlight', function() local screen @@ -17,15 +17,18 @@ describe(':highlight', function() end) it('invalid color name', function() - eq('Vim(highlight):E421: Color name or number not recognized: ctermfg=#181818', - exc_exec("highlight normal ctermfg=#181818")) - eq('Vim(highlight):E421: Color name or number not recognized: ctermbg=#181818', - exc_exec("highlight normal ctermbg=#181818")) + eq( + 'Vim(highlight):E421: Color name or number not recognized: ctermfg=#181818', + exc_exec('highlight normal ctermfg=#181818') + ) + eq( + 'Vim(highlight):E421: Color name or number not recognized: ctermbg=#181818', + exc_exec('highlight normal ctermbg=#181818') + ) end) it('invalid group name', function() - eq('Vim(highlight):E411: Highlight group not found: foo', - exc_exec("highlight foo")) + eq('Vim(highlight):E411: Highlight group not found: foo', exc_exec('highlight foo')) end) it('"Normal" foreground with red', function() @@ -50,18 +53,18 @@ describe(':highlight', function() end) it('clear', function() - meths.set_var('colors_name', 'foo') - eq(1, funcs.exists('g:colors_name')) + api.nvim_set_var('colors_name', 'foo') + eq(1, fn.exists('g:colors_name')) command('hi clear') - eq(0, funcs.exists('g:colors_name')) - meths.set_var('colors_name', 'foo') - eq(1, funcs.exists('g:colors_name')) + eq(0, fn.exists('g:colors_name')) + api.nvim_set_var('colors_name', 'foo') + eq(1, fn.exists('g:colors_name')) exec([[ func HiClear() hi clear endfunc ]]) - funcs.HiClear() - eq(0, funcs.exists('g:colors_name')) + fn.HiClear() + eq(0, fn.exists('g:colors_name')) end) end) diff --git a/test/functional/ex_cmds/ls_spec.lua b/test/functional/ex_cmds/ls_spec.lua index d02af21731..5f59402d10 100644 --- a/test/functional/ex_cmds/ls_spec.lua +++ b/test/functional/ex_cmds/ls_spec.lua @@ -4,7 +4,7 @@ local command = helpers.command local eq = helpers.eq local eval = helpers.eval local feed = helpers.feed -local nvim = helpers.nvim +local api = helpers.api local testprg = helpers.testprg local retry = helpers.retry @@ -14,7 +14,7 @@ describe(':ls', function() end) it('R, F for :terminal buffers', function() - nvim('set_option_value', 'shell', string.format('"%s" INTERACT', testprg('shell-test')), {}) + api.nvim_set_option_value('shell', string.format('"%s" INTERACT', testprg('shell-test')), {}) command('edit foo') command('set hidden') @@ -44,6 +44,4 @@ describe(':ls', function() eq('\n 3 %aF ', string.match(ls_output, '^\n *3 ... ')) end) end) - end) - diff --git a/test/functional/ex_cmds/make_spec.lua b/test/functional/ex_cmds/make_spec.lua index d82f59ddf9..dd47bdec58 100644 --- a/test/functional/ex_cmds/make_spec.lua +++ b/test/functional/ex_cmds/make_spec.lua @@ -3,40 +3,41 @@ local clear = helpers.clear local eval = helpers.eval local has_powershell = helpers.has_powershell local matches = helpers.matches -local nvim = helpers.nvim +local api = helpers.api local testprg = helpers.testprg describe(':make', function() clear() - before_each(function () + before_each(function() clear() end) describe('with powershell', function() if not has_powershell() then - pending("not tested; powershell was not found", function() end) + pending('not tested; powershell was not found', function() end) return end - before_each(function () + before_each(function() helpers.set_shell_powershell() end) - it('captures stderr & non zero exit code #14349', function () - nvim('set_option_value', 'makeprg', testprg('shell-test')..' foo', {}) + it('captures stderr & non zero exit code #14349', function() + api.nvim_set_option_value('makeprg', testprg('shell-test') .. ' foo', {}) local out = eval('execute("make")') -- Error message is captured in the file and printed in the footer - matches('[\r\n]+.*[\r\n]+Unknown first argument%: foo[\r\n]+%(1 of 1%)%: Unknown first argument%: foo', out) + matches( + '[\r\n]+.*[\r\n]+Unknown first argument%: foo[\r\n]+%(1 of 1%)%: Unknown first argument%: foo', + out + ) end) - it('captures stderr & zero exit code #14349', function () - nvim('set_option_value', 'makeprg', testprg('shell-test'), {}) + it('captures stderr & zero exit code #14349', function() + api.nvim_set_option_value('makeprg', testprg('shell-test'), {}) local out = eval('execute("make")') -- Ensure there are no "shell returned X" messages between -- command and last line (indicating zero exit) matches('LastExitCode%s+ready [$]%s+[(]', out) matches('\n.*%: ready [$]', out) end) - end) - end) diff --git a/test/functional/ex_cmds/map_spec.lua b/test/functional/ex_cmds/map_spec.lua index a580e88b93..d3b027e6f4 100644 --- a/test/functional/ex_cmds/map_spec.lua +++ b/test/functional/ex_cmds/map_spec.lua @@ -1,11 +1,11 @@ -local helpers = require("test.functional.helpers")(after_each) +local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local eq = helpers.eq local exec = helpers.exec local exec_capture = helpers.exec_capture local feed = helpers.feed -local meths = helpers.meths +local api = helpers.api local clear = helpers.clear local command = helpers.command local expect = helpers.expect @@ -16,13 +16,13 @@ describe(':*map', function() before_each(clear) it('are not affected by &isident', function() - meths.set_var('counter', 0) + api.nvim_set_var('counter', 0) command('nnoremap <C-x> :let counter+=1<CR>') - meths.set_option_value('isident', ('%u'):format(('>'):byte()), {}) + api.nvim_set_option_value('isident', ('%u'):format(('>'):byte()), {}) command('nnoremap <C-y> :let counter+=1<CR>') -- &isident used to disable keycode parsing here as well feed('\24\25<C-x><C-y>') - eq(4, meths.get_var('counter')) + eq(4, api.nvim_get_var('counter')) end) it(':imap <M-">', function() @@ -33,56 +33,60 @@ describe(':*map', function() it('shows <Nop> as mapping rhs', function() command('nmap asdf <Nop>') - eq([[ + eq( + [[ n asdf <Nop>]], - exec_capture('nmap asdf')) + exec_capture('nmap asdf') + ) end) it('mappings with description can be filtered', function() - meths.set_keymap('n', 'asdf1', 'qwert', {desc='do the one thing'}) - meths.set_keymap('n', 'asdf2', 'qwert', {desc='doesnot really do anything'}) - meths.set_keymap('n', 'asdf3', 'qwert', {desc='do the other thing'}) - eq([[ + api.nvim_set_keymap('n', 'asdf1', 'qwert', { desc = 'do the one thing' }) + api.nvim_set_keymap('n', 'asdf2', 'qwert', { desc = 'doesnot really do anything' }) + api.nvim_set_keymap('n', 'asdf3', 'qwert', { desc = 'do the other thing' }) + eq( + [[ n asdf3 qwert do the other thing n asdf1 qwert do the one thing]], - exec_capture('filter the nmap')) + exec_capture('filter the nmap') + ) end) it('<Plug> mappings ignore nore', function() command('let x = 0') - eq(0, meths.eval('x')) + eq(0, api.nvim_eval('x')) command [[ nnoremap <Plug>(Increase_x) <cmd>let x+=1<cr> nmap increase_x_remap <Plug>(Increase_x) nnoremap increase_x_noremap <Plug>(Increase_x) ]] feed('increase_x_remap') - eq(1, meths.eval('x')) + eq(1, api.nvim_eval('x')) feed('increase_x_noremap') - eq(2, meths.eval('x')) + eq(2, api.nvim_eval('x')) end) it("Doesn't auto ignore nore for keys before or after <Plug> mapping", function() command('let x = 0') - eq(0, meths.eval('x')) + eq(0, api.nvim_eval('x')) command [[ nnoremap x <nop> nnoremap <Plug>(Increase_x) <cmd>let x+=1<cr> nmap increase_x_remap x<Plug>(Increase_x)x nnoremap increase_x_noremap x<Plug>(Increase_x)x ]] - insert("Some text") + insert('Some text') eq('Some text', eval("getline('.')")) feed('increase_x_remap') - eq(1, meths.eval('x')) + eq(1, api.nvim_eval('x')) eq('Some text', eval("getline('.')")) feed('increase_x_noremap') - eq(2, meths.eval('x')) + eq(2, api.nvim_eval('x')) eq('Some te', eval("getline('.')")) end) @@ -105,25 +109,19 @@ describe('Screen', function() command('map <expr> x input("> ")') screen:expect([[ ^ | - ~ | - ~ | - ~ | + ~ |*3 | ]]) feed('x') screen:expect([[ | - ~ | - ~ | - ~ | + ~ |*3 > ^ | ]]) feed('\n') screen:expect([[ ^ | - ~ | - ~ | - ~ | + ~ |*3 > | ]]) end) @@ -133,25 +131,19 @@ describe('Screen', function() feed('i') screen:expect([[ ^ | - ~ | - ~ | - ~ | + ~ |*3 -- INSERT -- | ]]) feed('x') screen:expect([[ | - ~ | - ~ | - ~ | + ~ |*3 > ^ | ]]) feed('\n') screen:expect([[ ^ | - ~ | - ~ | - ~ | + ~ |*3 -- INSERT -- | ]]) end) @@ -161,9 +153,7 @@ describe('Screen', function() feed(':<F2>') screen:expect([[ | - ~ | - ~ | - ~ | + ~ |*3 :^ | ]]) end) @@ -201,8 +191,7 @@ describe('Screen', function() command('nmap <expr> <F2> execute("throw 42")') feed('<F2>') screen:expect([[ - | - | + |*2 Error detected while processing : | E605: Exception not caught: 42 | Press ENTER or type command to continue^ | @@ -210,9 +199,7 @@ describe('Screen', function() feed('<CR>') screen:expect([[ ^ | - ~ | - ~ | - ~ | + ~ |*3 | ]]) end) @@ -223,9 +210,7 @@ describe('Screen', function() feed(':echo "foo') screen:expect([[ | - ~ | - ~ | - ~ | + ~ |*3 :echo "foo^ | ]]) feed('<F2>') @@ -261,9 +246,7 @@ describe('Screen', function() feed(': nmap a<CR>') screen:expect([[ ^ | - ~ | - ~ | - ~ | + ~ |*3 n a b | ]]) end) diff --git a/test/functional/ex_cmds/menu_spec.lua b/test/functional/ex_cmds/menu_spec.lua index b9ed32c328..bb6ef72787 100644 --- a/test/functional/ex_cmds/menu_spec.lua +++ b/test/functional/ex_cmds/menu_spec.lua @@ -1,12 +1,10 @@ local helpers = require('test.functional.helpers')(after_each) -local clear, command, nvim = helpers.clear, helpers.command, helpers.nvim +local clear, command = helpers.clear, helpers.command local expect, feed = helpers.expect, helpers.feed local eq, eval = helpers.eq, helpers.eval -local funcs = helpers.funcs - +local fn = helpers.fn describe(':emenu', function() - before_each(function() clear() command('nnoremenu Test.Test inormal<ESC>') @@ -41,26 +39,25 @@ describe(':emenu', function() end) it('executes correct bindings in command mode', function() - feed('ithis is a sentence<esc>^yiwo<esc>') + feed('ithis is a sentence<esc>^yiwo<esc>') - -- Invoke "Edit.Paste" in normal-mode. - nvim('command', 'emenu Edit.Paste') + -- Invoke "Edit.Paste" in normal-mode. + command('emenu Edit.Paste') - -- Invoke "Edit.Paste" and "Test.Test" in command-mode. - feed(':') - nvim('command', 'emenu Edit.Paste') - nvim('command', 'emenu Test.Test') + -- Invoke "Edit.Paste" and "Test.Test" in command-mode. + feed(':') + command('emenu Edit.Paste') + command('emenu Test.Test') - expect([[ + expect([[ this is a sentence this]]) - -- Assert that Edit.Paste pasted @" into the commandline. - eq('thiscmdmode', eval('getcmdline()')) + -- Assert that Edit.Paste pasted @" into the commandline. + eq('thiscmdmode', eval('getcmdline()')) end) end) describe('menu_get', function() - before_each(function() clear() command([=[ @@ -83,12 +80,12 @@ describe('menu_get', function() end) it("path='', modes='a'", function() - local m = funcs.menu_get("","a"); + local m = fn.menu_get('', 'a') -- HINT: To print the expected table and regenerate the tests: -- print(require('vim.inspect')(m)) local expected = { { - shortcut = "T", + shortcut = 'T', hidden = 0, submenus = { { @@ -97,45 +94,45 @@ describe('menu_get', function() sid = 1, noremap = 1, enabled = 1, - rhs = "insert", - silent = 0 + rhs = 'insert', + silent = 0, }, s = { sid = 1, noremap = 1, enabled = 1, - rhs = "x", - silent = 0 + rhs = 'x', + silent = 0, }, n = { sid = 1, noremap = 1, enabled = 1, - rhs = "inormal<Esc>", - silent = 0 + rhs = 'inormal<Esc>', + silent = 0, }, v = { sid = 1, noremap = 1, enabled = 1, - rhs = "x", - silent = 0 + rhs = 'x', + silent = 0, }, c = { sid = 1, noremap = 1, enabled = 1, - rhs = "cmdmode", - silent = 0 - } + rhs = 'cmdmode', + silent = 0, + }, }, priority = 500, - name = "Test", - hidden = 0 + name = 'Test', + hidden = 0, }, { priority = 500, - name = "Nested", + name = 'Nested', submenus = { { mappings = { @@ -143,34 +140,34 @@ describe('menu_get', function() sid = 0, noremap = 0, enabled = 1, - rhs = "level1", - silent = 0 + rhs = 'level1', + silent = 0, }, v = { sid = 0, noremap = 0, enabled = 1, - rhs = "level1", - silent = 0 + rhs = 'level1', + silent = 0, }, s = { sid = 0, noremap = 0, enabled = 1, - rhs = "level1", - silent = 0 + rhs = 'level1', + silent = 0, }, n = { sid = 0, noremap = 0, enabled = 1, - rhs = "level1", - silent = 0 - } + rhs = 'level1', + silent = 0, + }, }, priority = 500, - name = "test", - hidden = 0 + name = 'test', + hidden = 0, }, { mappings = { @@ -178,67 +175,67 @@ describe('menu_get', function() sid = 0, noremap = 0, enabled = 1, - rhs = "level2", - silent = 0 + rhs = 'level2', + silent = 0, }, v = { sid = 0, noremap = 0, enabled = 1, - rhs = "level2", - silent = 0 + rhs = 'level2', + silent = 0, }, s = { sid = 0, noremap = 0, enabled = 1, - rhs = "level2", - silent = 0 + rhs = 'level2', + silent = 0, }, n = { sid = 0, noremap = 0, enabled = 1, - rhs = "level2", - silent = 0 - } + rhs = 'level2', + silent = 0, + }, }, priority = 500, - name = "Nested2", - hidden = 0 - } + name = 'Nested2', + hidden = 0, + }, }, - hidden = 0 - } + hidden = 0, + }, }, priority = 500, - name = "Test" + name = 'Test', }, { priority = 500, - name = "Export", + name = 'Export', submenus = { { - tooltip = "This is the tooltip", + tooltip = 'This is the tooltip', hidden = 0, - name = "Script", + name = 'Script', priority = 500, mappings = { n = { sid = 1, noremap = 1, enabled = 1, - rhs = "p", - silent = 0 - } - } - } + rhs = 'p', + silent = 0, + }, + }, + }, }, - hidden = 0 + hidden = 0, }, { priority = 500, - name = "Edit", + name = 'Edit', submenus = { { mappings = { @@ -246,27 +243,27 @@ describe('menu_get', function() sid = 1, noremap = 1, enabled = 1, - rhs = "<C-R>\"", - silent = 0 + rhs = '<C-R>"', + silent = 0, }, n = { sid = 1, noremap = 1, enabled = 1, - rhs = "p", - silent = 0 - } + rhs = 'p', + silent = 0, + }, }, priority = 500, - name = "Paste", - hidden = 0 - } + name = 'Paste', + hidden = 0, + }, }, - hidden = 0 + hidden = 0, }, { priority = 500, - name = "]Export", + name = ']Export', submenus = { { mappings = { @@ -274,72 +271,76 @@ describe('menu_get', function() sid = 0, noremap = 0, enabled = 1, - rhs = "thisoneshouldbehidden", - silent = 0 + rhs = 'thisoneshouldbehidden', + silent = 0, }, v = { sid = 0, noremap = 0, enabled = 1, - rhs = "thisoneshouldbehidden", - silent = 0 + rhs = 'thisoneshouldbehidden', + silent = 0, }, s = { sid = 0, noremap = 0, enabled = 1, - rhs = "thisoneshouldbehidden", - silent = 0 + rhs = 'thisoneshouldbehidden', + silent = 0, }, n = { sid = 0, noremap = 0, enabled = 1, - rhs = "thisoneshouldbehidden", - silent = 0 - } + rhs = 'thisoneshouldbehidden', + silent = 0, + }, }, priority = 500, - name = "hidden", - hidden = 0 - } + name = 'hidden', + hidden = 0, + }, }, - hidden = 1 - } + hidden = 1, + }, } eq(expected, m) end) it('matching path, all modes', function() - local m = funcs.menu_get("Export", "a") - local expected = { { - hidden = 0, - name = "Export", - priority = 500, - submenus = { { - tooltip = "This is the tooltip", + local m = fn.menu_get('Export', 'a') + local expected = { + { hidden = 0, - name = "Script", + name = 'Export', priority = 500, - mappings = { - n = { - sid = 1, - noremap = 1, - enabled = 1, - rhs = "p", - silent = 0 - } - } - } } - } } + submenus = { + { + tooltip = 'This is the tooltip', + hidden = 0, + name = 'Script', + priority = 500, + mappings = { + n = { + sid = 1, + noremap = 1, + enabled = 1, + rhs = 'p', + silent = 0, + }, + }, + }, + }, + }, + } eq(expected, m) end) it('no path, matching modes', function() - local m = funcs.menu_get("","i") + local m = fn.menu_get('', 'i') local expected = { { - shortcut = "T", + shortcut = 'T', hidden = 0, submenus = { { @@ -348,27 +349,27 @@ describe('menu_get', function() sid = 1, noremap = 1, enabled = 1, - rhs = "insert", - silent = 0 - } + rhs = 'insert', + silent = 0, + }, }, priority = 500, - name = "Test", - hidden = 0 + name = 'Test', + hidden = 0, }, }, priority = 500, - name = "Test" - } + name = 'Test', + }, } eq(expected, m) end) it('matching path and modes', function() - local m = funcs.menu_get("Test","i") + local m = fn.menu_get('Test', 'i') local expected = { { - shortcut = "T", + shortcut = 'T', submenus = { { mappings = { @@ -376,26 +377,25 @@ describe('menu_get', function() sid = 1, noremap = 1, enabled = 1, - rhs = "insert", - silent = 0 + rhs = 'insert', + silent = 0, }, }, priority = 500, - name = "Test", - hidden = 0 + name = 'Test', + hidden = 0, }, }, priority = 500, - name = "Test", - hidden = 0 - } + name = 'Test', + hidden = 0, + }, } eq(expected, m) end) end) describe('menu_get', function() - before_each(function() clear() command('aunmenu *') @@ -412,10 +412,10 @@ describe('menu_get', function() command('nnoremenu &Test.Test8 <NoP>') command('nnoremenu &Test.Test9 ""') - local m = funcs.menu_get(""); + local m = fn.menu_get('') local expected = { { - shortcut = "T", + shortcut = 'T', hidden = 0, submenus = { { @@ -425,12 +425,12 @@ describe('menu_get', function() sid = 1, noremap = 1, enabled = 1, - rhs = "inormal<Esc>", - silent = 0 - } + rhs = 'inormal<Esc>', + silent = 0, + }, }, - name = "Test", - hidden = 0 + name = 'Test', + hidden = 0, }, { priority = 500, @@ -439,12 +439,12 @@ describe('menu_get', function() sid = 1, noremap = 1, enabled = 1, - rhs = "<Tab><Esc>", - silent = 0 - } + rhs = '<Tab><Esc>', + silent = 0, + }, }, - name = "Test2", - hidden = 0 + name = 'Test2', + hidden = 0, }, { priority = 500, @@ -453,19 +453,19 @@ describe('menu_get', function() sid = 1, noremap = 1, enabled = 1, - rhs = "yA<C-R>0<Tab>xyz<Esc>", - silent = 0 + rhs = 'yA<C-R>0<Tab>xyz<Esc>', + silent = 0, }, v = { sid = 1, noremap = 1, enabled = 1, - rhs = "yA<C-R>0<Tab>xyz<Esc>", - silent = 0 - } + rhs = 'yA<C-R>0<Tab>xyz<Esc>', + silent = 0, + }, }, - name = "Test3", - hidden = 0 + name = 'Test3', + hidden = 0, }, { priority = 500, @@ -474,12 +474,12 @@ describe('menu_get', function() sid = 1, noremap = 1, enabled = 1, - rhs = "<C-R>*", - silent = 0 - } + rhs = '<C-R>*', + silent = 0, + }, }, - name = "Test4", - hidden = 0 + name = 'Test4', + hidden = 0, }, { priority = 500, @@ -488,12 +488,12 @@ describe('menu_get', function() sid = 1, noremap = 1, enabled = 1, - rhs = "<C-R>+", - silent = 0 - } + rhs = '<C-R>+', + silent = 0, + }, }, - name = "Test5", - hidden = 0 + name = 'Test5', + hidden = 0, }, { priority = 500, @@ -502,12 +502,12 @@ describe('menu_get', function() sid = 1, noremap = 1, enabled = 1, - rhs = "", - silent = 0 - } + rhs = '', + silent = 0, + }, }, - name = "Test6", - hidden = 0 + name = 'Test6', + hidden = 0, }, { priority = 500, @@ -516,12 +516,12 @@ describe('menu_get', function() sid = 1, noremap = 1, enabled = 1, - rhs = "", - silent = 0 - } + rhs = '', + silent = 0, + }, }, - name = "Test7", - hidden = 0 + name = 'Test7', + hidden = 0, }, { priority = 500, @@ -530,12 +530,12 @@ describe('menu_get', function() sid = 1, noremap = 1, enabled = 1, - rhs = "", - silent = 0 - } + rhs = '', + silent = 0, + }, }, - name = "Test8", - hidden = 0 + name = 'Test8', + hidden = 0, }, { priority = 500, @@ -544,17 +544,17 @@ describe('menu_get', function() sid = 1, noremap = 1, enabled = 1, - rhs = "\"\"", - silent = 0 - } + rhs = '""', + silent = 0, + }, }, - name = "Test9", - hidden = 0 - } + name = 'Test9', + hidden = 0, + }, }, priority = 500, - name = "Test" - } + name = 'Test', + }, } eq(m, expected) @@ -565,12 +565,12 @@ describe('menu_get', function() command('nnoremenu &Test\\ 1.Test\\ 2 Wargl') command('nnoremenu &Test4.Test<Tab>3 i space<Esc>') - local m = funcs.menu_get(""); + local m = fn.menu_get('') local expected = { { - shortcut = "T", + shortcut = 'T', hidden = 0, - actext = "Y", + actext = 'Y', submenus = { { mappings = { @@ -578,21 +578,21 @@ describe('menu_get', function() sid = 1, noremap = 1, enabled = 1, - rhs = "inormal<Alt-j>", - silent = 0 - } + rhs = 'inormal<Alt-j>', + silent = 0, + }, }, hidden = 0, - actext = "X x", + actext = 'X x', priority = 500, - name = "Test" - } + name = 'Test', + }, }, priority = 500, - name = "Test" + name = 'Test', }, { - shortcut = "T", + shortcut = 'T', hidden = 0, submenus = { { @@ -602,19 +602,19 @@ describe('menu_get', function() sid = 1, noremap = 1, enabled = 1, - rhs = "Wargl", - silent = 0 - } + rhs = 'Wargl', + silent = 0, + }, }, - name = "Test 2", - hidden = 0 - } + name = 'Test 2', + hidden = 0, + }, }, priority = 500, - name = "Test 1" + name = 'Test 1', }, { - shortcut = "T", + shortcut = 'T', hidden = 0, submenus = { { @@ -623,19 +623,19 @@ describe('menu_get', function() sid = 1, noremap = 1, enabled = 1, - rhs = "i space<Esc>", - silent = 0 - } + rhs = 'i space<Esc>', + silent = 0, + }, }, hidden = 0, - actext = "3", + actext = '3', priority = 500, - name = "Test" - } + name = 'Test', + }, }, priority = 500, - name = "Test4" - } + name = 'Test4', + }, } eq(m, expected) diff --git a/test/functional/ex_cmds/mksession_spec.lua b/test/functional/ex_cmds/mksession_spec.lua index 7522d4a99c..6f2e0be3d5 100644 --- a/test/functional/ex_cmds/mksession_spec.lua +++ b/test/functional/ex_cmds/mksession_spec.lua @@ -6,20 +6,18 @@ local command = helpers.command local get_pathsep = helpers.get_pathsep local eq = helpers.eq local neq = helpers.neq -local funcs = helpers.funcs +local fn = helpers.fn local matches = helpers.matches -local pesc = helpers.pesc +local pesc = vim.pesc local rmdir = helpers.rmdir -local sleep = helpers.sleep -local meths = helpers.meths +local sleep = vim.uv.sleep +local api = helpers.api local skip = helpers.skip local is_os = helpers.is_os local mkdir = helpers.mkdir local file_prefix = 'Xtest-functional-ex_cmds-mksession_spec' -if helpers.skip(helpers.is_os('win')) then return end - describe(':mksession', function() local session_file = file_prefix .. '.vim' local tab_dir = file_prefix .. '.d' @@ -52,8 +50,8 @@ describe(':mksession', function() -- Restore session. command('source ' .. session_file) - eq(funcs.winbufnr(1), funcs.winbufnr(2)) - neq(funcs.winbufnr(1), funcs.winbufnr(3)) + eq(fn.winbufnr(1), fn.winbufnr(2)) + neq(fn.winbufnr(1), fn.winbufnr(3)) end) -- common testing procedure for testing "sessionoptions-=terminal" @@ -68,64 +66,61 @@ describe(':mksession', function() -- Restore session. command('source ' .. session_file) - eq(expected_buf_count, #meths.list_bufs()) + eq(expected_buf_count, #api.nvim_list_bufs()) end - it( - 'do not restore :terminal if not set in sessionoptions, terminal in current window #13078', - function() - local tmpfile_base = file_prefix .. '-tmpfile' - command('edit ' .. tmpfile_base) - command('terminal') + it('do not restore :terminal if not set in sessionoptions, terminal in curwin #13078', function() + local tmpfile_base = file_prefix .. '-tmpfile' + command('edit ' .. tmpfile_base) + command('terminal') - local buf_count = #meths.list_bufs() - eq(2, buf_count) + local buf_count = #api.nvim_list_bufs() + eq(2, buf_count) - eq('terminal', meths.get_option_value('buftype', {})) + eq('terminal', api.nvim_get_option_value('buftype', {})) - test_terminal_session_disabled(2) + test_terminal_session_disabled(2) - -- no terminal should be set. As a side effect we end up with a blank buffer - eq('', meths.get_option_value('buftype', { buf = meths.list_bufs()[1] })) - eq('', meths.get_option_value('buftype', { buf = meths.list_bufs()[2] })) - end - ) + -- no terminal should be set. As a side effect we end up with a blank buffer + eq('', api.nvim_get_option_value('buftype', { buf = api.nvim_list_bufs()[1] })) + eq('', api.nvim_get_option_value('buftype', { buf = api.nvim_list_bufs()[2] })) + end) it('do not restore :terminal if not set in sessionoptions, terminal hidden #13078', function() command('terminal') - local terminal_bufnr = meths.get_current_buf() + local terminal_bufnr = api.nvim_get_current_buf() local tmpfile_base = file_prefix .. '-tmpfile' -- make terminal hidden by opening a new file command('edit ' .. tmpfile_base .. '1') - local buf_count = #meths.list_bufs() + local buf_count = #api.nvim_list_bufs() eq(2, buf_count) - eq(1, funcs.getbufinfo(terminal_bufnr)[1].hidden) + eq(1, fn.getbufinfo(terminal_bufnr)[1].hidden) test_terminal_session_disabled(1) -- no terminal should exist here - neq('', meths.buf_get_name(meths.list_bufs()[1])) + neq('', api.nvim_buf_get_name(api.nvim_list_bufs()[1])) end) it('do not restore :terminal if not set in sessionoptions, only buffer #13078', function() command('terminal') - eq('terminal', meths.get_option_value('buftype', {})) + eq('terminal', api.nvim_get_option_value('buftype', {})) - local buf_count = #meths.list_bufs() + local buf_count = #api.nvim_list_bufs() eq(1, buf_count) test_terminal_session_disabled(1) -- no terminal should be set - eq('', meths.get_option_value('buftype', {})) + eq('', api.nvim_get_option_value('buftype', {})) end) it('restores tab-local working directories', function() local tmpfile_base = file_prefix .. '-tmpfile' - local cwd_dir = funcs.getcwd() + local cwd_dir = fn.getcwd() -- :mksession does not save empty tabs, so create some buffers. command('edit ' .. tmpfile_base .. '1') @@ -141,15 +136,15 @@ describe(':mksession', function() command('source ' .. session_file) -- First tab should have the original working directory. command('tabnext 1') - eq(cwd_dir, funcs.getcwd()) + eq(cwd_dir, fn.getcwd()) -- Second tab should have the tab-local working directory. command('tabnext 2') - eq(cwd_dir .. get_pathsep() .. tab_dir, funcs.getcwd()) + eq(cwd_dir .. get_pathsep() .. tab_dir, fn.getcwd()) end) it('restores buffers with tab-local CWD', function() local tmpfile_base = file_prefix .. '-tmpfile' - local cwd_dir = funcs.getcwd() + local cwd_dir = fn.getcwd() local session_path = cwd_dir .. get_pathsep() .. session_file command('edit ' .. tmpfile_base .. '1') @@ -165,13 +160,15 @@ describe(':mksession', function() -- Use :silent to avoid press-enter prompt due to long path command('silent source ' .. session_path) command('tabnext 1') - eq(cwd_dir .. get_pathsep() .. tmpfile_base .. '1', funcs.expand('%:p')) + eq(cwd_dir .. get_pathsep() .. tmpfile_base .. '1', fn.expand('%:p')) command('tabnext 2') - eq(cwd_dir .. get_pathsep() .. tmpfile_base .. '2', funcs.expand('%:p')) + eq(cwd_dir .. get_pathsep() .. tmpfile_base .. '2', fn.expand('%:p')) end) it('restores CWD for :terminal buffers #11288', function() - local cwd_dir = funcs.fnamemodify('.', ':p:~'):gsub([[[\/]*$]], '') + skip(is_os('win'), 'causes rmdir() to fail') + + local cwd_dir = fn.fnamemodify('.', ':p:~'):gsub([[[\/]*$]], '') cwd_dir = cwd_dir:gsub([[\]], '/') -- :mksession always uses unix slashes. local session_path = cwd_dir .. '/' .. session_file @@ -189,7 +186,7 @@ describe(':mksession', function() command('silent source ' .. session_path) local expected_cwd = cwd_dir .. '/' .. tab_dir - matches('^term://' .. pesc(expected_cwd) .. '//%d+:', funcs.expand('%')) + matches('^term://' .. pesc(expected_cwd) .. '//%d+:', fn.expand('%')) command('%bwipeout!') if is_os('win') then sleep(100) -- Make sure all child processes have exited. @@ -200,7 +197,7 @@ describe(':mksession', function() skip(is_os('win'), 'N/A for Windows') local screen - local cwd_dir = funcs.fnamemodify('.', ':p:~'):gsub([[[\/]*$]], '') + local cwd_dir = fn.fnamemodify('.', ':p:~'):gsub([[[\/]*$]], '') local session_path = cwd_dir .. '/' .. session_file screen = Screen.new(50, 6) @@ -209,9 +206,7 @@ describe(':mksession', function() ^/ | | [Process exited 0] | - | - | - | + |*3 ]] command('cd /') @@ -238,7 +233,7 @@ describe(':mksession', function() local tmpfile = file_prefix .. '-tmpfile-float' command('edit ' .. tmpfile) - local buf = meths.create_buf(false, true) + local buf = api.nvim_create_buf(false, true) local config = { relative = 'editor', focusable = false, @@ -248,8 +243,8 @@ describe(':mksession', function() col = 1, style = 'minimal', } - meths.open_win(buf, false, config) - local cmdheight = meths.get_option_value('cmdheight', {}) + api.nvim_open_win(buf, false, config) + local cmdheight = api.nvim_get_option_value('cmdheight', {}) command('mksession ' .. session_file) -- Create a new test instance of Nvim. @@ -257,12 +252,12 @@ describe(':mksession', function() command('source ' .. session_file) - eq(tmpfile, funcs.expand('%')) + eq(tmpfile, fn.expand('%')) -- Check that there is only a single window, which indicates the floating -- window was not restored. - eq(1, funcs.winnr('$')) + eq(1, fn.winnr('$')) -- The command-line height should remain the same as it was. - eq(cmdheight, meths.get_option_value('cmdheight', {})) + eq(cmdheight, api.nvim_get_option_value('cmdheight', {})) os.remove(tmpfile) end) diff --git a/test/functional/ex_cmds/mkview_spec.lua b/test/functional/ex_cmds/mkview_spec.lua index f71b826210..de0a4fe0ea 100644 --- a/test/functional/ex_cmds/mkview_spec.lua +++ b/test/functional/ex_cmds/mkview_spec.lua @@ -4,7 +4,7 @@ local clear = helpers.clear local command = helpers.command local get_pathsep = helpers.get_pathsep local eq = helpers.eq -local funcs = helpers.funcs +local fn = helpers.fn local rmdir = helpers.rmdir local mkdir = helpers.mkdir @@ -28,9 +28,8 @@ describe(':mkview', function() end) it('viewoption curdir restores local current directory', function() - local cwd_dir = funcs.getcwd() - local set_view_dir_command = 'set viewdir=' .. cwd_dir .. - get_pathsep() .. view_dir + local cwd_dir = fn.getcwd() + local set_view_dir_command = 'set viewdir=' .. cwd_dir .. get_pathsep() .. view_dir -- By default the local current directory should save command(set_view_dir_command) @@ -56,12 +55,11 @@ describe(':mkview', function() command('edit ' .. tmp_file_base .. '2') command('loadview') -- The view's current directory should not have changed - eq(cwd_dir, funcs.getcwd()) + eq(cwd_dir, fn.getcwd()) -- Load the view with a saved local current directory command('edit ' .. tmp_file_base .. '1') command('loadview') -- The view's local directory should have been saved - eq(cwd_dir .. get_pathsep() .. local_dir, funcs.getcwd()) + eq(cwd_dir .. get_pathsep() .. local_dir, fn.getcwd()) end) - end) diff --git a/test/functional/ex_cmds/normal_spec.lua b/test/functional/ex_cmds/normal_spec.lua index 009f1d6516..723bfefcf4 100644 --- a/test/functional/ex_cmds/normal_spec.lua +++ b/test/functional/ex_cmds/normal_spec.lua @@ -1,7 +1,7 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local command = helpers.command -local funcs = helpers.funcs +local fn = helpers.fn local feed = helpers.feed local expect = helpers.expect local eq = helpers.eq @@ -29,10 +29,10 @@ describe(':normal!', function() it('can stop Visual mode without closing cmdwin vim-patch:9.0.0234', function() feed('q:') feed('v') - eq('v', funcs.mode(1)) - eq(':', funcs.getcmdwintype()) + eq('v', fn.mode(1)) + eq(':', fn.getcmdwintype()) command('normal! \027') - eq('n', funcs.mode(1)) - eq(':', funcs.getcmdwintype()) + eq('n', fn.mode(1)) + eq(':', fn.getcmdwintype()) end) end) diff --git a/test/functional/ex_cmds/oldfiles_spec.lua b/test/functional/ex_cmds/oldfiles_spec.lua index 19611429e0..8d1469f343 100644 --- a/test/functional/ex_cmds/oldfiles_spec.lua +++ b/test/functional/ex_cmds/oldfiles_spec.lua @@ -4,7 +4,7 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local command = helpers.command local expect_exit = helpers.expect_exit -local buf, eq, feed_command = helpers.curbufmeths, helpers.eq, helpers.feed_command +local api, eq, feed_command = helpers.api, helpers.eq, helpers.feed_command local feed, poke_eventloop = helpers.feed, helpers.poke_eventloop local ok = helpers.ok local eval = helpers.eval @@ -12,9 +12,15 @@ local eval = helpers.eval local shada_file = 'Xtest.shada' local function _clear() - clear{args={'-i', shada_file, -- Need shada for these tests. - '--cmd', 'set noswapfile undodir=. directory=. viewdir=. backupdir=. belloff= noshowcmd noruler'}, - args_rm={'-i', '--cmd'}} + clear { + args = { + '-i', + shada_file, -- Need shada for these tests. + '--cmd', + 'set noswapfile undodir=. directory=. viewdir=. backupdir=. belloff= noshowcmd noruler', + }, + args_rm = { '-i', '--cmd' }, + } end describe(':oldfiles', function() @@ -36,12 +42,12 @@ describe(':oldfiles', function() feed_command('edit testfile2') feed_command('wshada') feed_command('rshada!') - local oldfiles = helpers.meths.get_vvar('oldfiles') + local oldfiles = api.nvim_get_vvar('oldfiles') feed_command('oldfiles') screen:expect([[ | - 1: ]].. add_padding(oldfiles[1]) ..[[ | - 2: ]].. add_padding(oldfiles[2]) ..[[ | + 1: ]] .. add_padding(oldfiles[1]) .. [[ | + 2: ]] .. add_padding(oldfiles[2]) .. [[ | | Press ENTER or type command to continue^ | ]]) @@ -50,16 +56,16 @@ describe(':oldfiles', function() it('can be filtered with :filter', function() feed_command('edit file_one.txt') - local file1 = buf.get_name() + local file1 = api.nvim_buf_get_name(0) feed_command('edit file_two.txt') - local file2 = buf.get_name() + local file2 = api.nvim_buf_get_name(0) feed_command('edit another.txt') - local another = buf.get_name() + local another = api.nvim_buf_get_name(0) feed_command('wshada') feed_command('rshada!') local function get_oldfiles(cmd) - local t = eval([[split(execute(']]..cmd..[['), "\n")]]) + local t = eval([[split(execute(']] .. cmd .. [['), "\n")]]) for i, _ in ipairs(t) do t[i] = t[i]:gsub('^%d+:%s+', '') end @@ -68,16 +74,16 @@ describe(':oldfiles', function() end local oldfiles = get_oldfiles('oldfiles') - eq({another, file1, file2}, oldfiles) + eq({ another, file1, file2 }, oldfiles) oldfiles = get_oldfiles('filter file_ oldfiles') - eq({file1, file2}, oldfiles) + eq({ file1, file2 }, oldfiles) oldfiles = get_oldfiles('filter /another/ oldfiles') - eq({another}, oldfiles) + eq({ another }, oldfiles) oldfiles = get_oldfiles('filter! file_ oldfiles') - eq({another}, oldfiles) + eq({ another }, oldfiles) end) end) @@ -89,9 +95,9 @@ describe(':browse oldfiles', function() before_each(function() _clear() feed_command('edit testfile1') - filename = buf.get_name() + filename = api.nvim_buf_get_name(0) feed_command('edit testfile2') - filename2 = buf.get_name() + filename2 = api.nvim_buf_get_name(0) feed_command('wshada') poke_eventloop() _clear() @@ -102,7 +108,7 @@ describe(':browse oldfiles', function() -- Ensure v:oldfiles isn't busted. Since things happen so fast, -- the ordering of v:oldfiles is unstable (it uses qsort() under-the-hood). -- Let's verify the contents and the length of v:oldfiles before moving on. - oldfiles = helpers.meths.get_vvar('oldfiles') + oldfiles = helpers.api.nvim_get_vvar('oldfiles') eq(2, #oldfiles) ok(filename == oldfiles[1] or filename == oldfiles[2]) ok(filename2 == oldfiles[1] or filename2 == oldfiles[2]) @@ -117,16 +123,16 @@ describe(':browse oldfiles', function() it('provides a prompt and edits the chosen file', function() feed('2<cr>') - eq(oldfiles[2], buf.get_name()) + eq(oldfiles[2], api.nvim_buf_get_name(0)) end) it('provides a prompt and does nothing on <cr>', function() feed('<cr>') - eq('', buf.get_name()) + eq('', api.nvim_buf_get_name(0)) end) it('provides a prompt and does nothing if choice is out-of-bounds', function() feed('3<cr>') - eq('', buf.get_name()) + eq('', api.nvim_buf_get_name(0)) end) end) diff --git a/test/functional/ex_cmds/print_commands_spec.lua b/test/functional/ex_cmds/print_commands_spec.lua index 98c0f74635..ba5ec7d2d1 100644 --- a/test/functional/ex_cmds/print_commands_spec.lua +++ b/test/functional/ex_cmds/print_commands_spec.lua @@ -1,12 +1,11 @@ local helpers = require('test.functional.helpers')(after_each) -local clear, eq, command, funcs = - helpers.clear, helpers.eq, helpers.command, helpers.funcs +local clear, eq, command, fn = helpers.clear, helpers.eq, helpers.command, helpers.fn describe(':z^', function() before_each(clear) it('correctly sets the cursor after :z^', function() command('z^') - eq(1, funcs.line('.')) + eq(1, fn.line('.')) end) end) diff --git a/test/functional/ex_cmds/profile_spec.lua b/test/functional/ex_cmds/profile_spec.lua index 249373a9c4..f85dcc60ff 100644 --- a/test/functional/ex_cmds/profile_spec.lua +++ b/test/functional/ex_cmds/profile_spec.lua @@ -1,27 +1,27 @@ require('os') -local luv = require('luv') +local uv = vim.uv -local helpers = require('test.functional.helpers')(after_each) -local eval = helpers.eval -local command = helpers.command -local eq, neq = helpers.eq, helpers.neq +local helpers = require('test.functional.helpers')(after_each) +local eval = helpers.eval +local command = helpers.command +local eq, neq = helpers.eq, helpers.neq local tempfile = helpers.tmpname() -local source = helpers.source -local matches = helpers.matches +local source = helpers.source +local matches = helpers.matches local read_file = helpers.read_file -- tmpname() also creates the file on POSIX systems. Remove it again. -- We just need the name, ignoring any race conditions. -if luv.fs_stat(tempfile).uid then +if uv.fs_stat(tempfile).uid then os.remove(tempfile) end local function assert_file_exists(filepath) - neq(nil, luv.fs_stat(filepath).uid) + neq(nil, uv.fs_stat(filepath).uid) end local function assert_file_exists_not(filepath) - eq(nil, luv.fs_stat(filepath)) + eq(nil, uv.fs_stat(filepath)) end describe(':profile', function() @@ -29,7 +29,7 @@ describe(':profile', function() after_each(function() helpers.expect_exit(command, 'qall!') - if luv.fs_stat(tempfile).uid ~= nil then + if uv.fs_stat(tempfile).uid ~= nil then os.remove(tempfile) end end) diff --git a/test/functional/ex_cmds/quickfix_commands_spec.lua b/test/functional/ex_cmds/quickfix_commands_spec.lua index 4d9d8eeb90..5af0198ffe 100644 --- a/test/functional/ex_cmds/quickfix_commands_spec.lua +++ b/test/functional/ex_cmds/quickfix_commands_spec.lua @@ -4,31 +4,35 @@ local Screen = require('test.functional.ui.screen') local feed = helpers.feed local eq = helpers.eq local clear = helpers.clear -local funcs = helpers.funcs +local fn = helpers.fn local command = helpers.command local exc_exec = helpers.exc_exec local write_file = helpers.write_file -local curbufmeths = helpers.curbufmeths +local api = helpers.api local source = helpers.source local file_base = 'Xtest-functional-ex_cmds-quickfix_commands' before_each(clear) -for _, c in ipairs({'l', 'c'}) do +for _, c in ipairs({ 'l', 'c' }) do local file = ('%s.%s'):format(file_base, c) local filecmd = c .. 'file' local getfcmd = c .. 'getfile' local addfcmd = c .. 'addfile' - local getlist = (c == 'c') and funcs.getqflist or ( - function() return funcs.getloclist(0) end) + local getlist = (c == 'c') and fn.getqflist or function() + return fn.getloclist(0) + end describe((':%s*file commands'):format(c), function() before_each(function() - write_file(file, ([[ + write_file( + file, + ([[ %s-1.res:700:10:Line 700 %s-2.res:800:15:Line 800 - ]]):format(file, file)) + ]]):format(file, file) + ) end) after_each(function() os.remove(file) @@ -39,49 +43,114 @@ for _, c in ipairs({'l', 'c'}) do -- Second line of each entry (i.e. `nr=-1, …`) was obtained from actual -- results. First line (i.e. `{lnum=…`) was obtained from legacy test. local list = { - {lnum=700, end_lnum=0, col=10, end_col=0, text='Line 700', module='', - nr=-1, bufnr=2, valid=1, pattern='', vcol=0, ['type']=''}, - {lnum=800, end_lnum=0, col=15, end_col=0, text='Line 800', module='', - nr=-1, bufnr=3, valid=1, pattern='', vcol=0, ['type']=''}, + { + lnum = 700, + end_lnum = 0, + col = 10, + end_col = 0, + text = 'Line 700', + module = '', + nr = -1, + bufnr = 2, + valid = 1, + pattern = '', + vcol = 0, + ['type'] = '', + }, + { + lnum = 800, + end_lnum = 0, + col = 15, + end_col = 0, + text = 'Line 800', + module = '', + nr = -1, + bufnr = 3, + valid = 1, + pattern = '', + vcol = 0, + ['type'] = '', + }, } eq(list, getlist()) - eq(('%s-1.res'):format(file), funcs.bufname(list[1].bufnr)) - eq(('%s-2.res'):format(file), funcs.bufname(list[2].bufnr)) + eq(('%s-1.res'):format(file), fn.bufname(list[1].bufnr)) + eq(('%s-2.res'):format(file), fn.bufname(list[2].bufnr)) -- Run cfile/lfile from a modified buffer command('set nohidden') command('enew!') - curbufmeths.set_lines(1, 1, true, {'Quickfix'}) - eq(('Vim(%s):E37: No write since last change (add ! to override)'):format( - filecmd), - exc_exec(('%s %s'):format(filecmd, file))) + api.nvim_buf_set_lines(0, 1, 1, true, { 'Quickfix' }) + eq( + ('Vim(%s):E37: No write since last change (add ! to override)'):format(filecmd), + exc_exec(('%s %s'):format(filecmd, file)) + ) - write_file(file, ([[ + write_file( + file, + ([[ %s-3.res:900:30:Line 900 - ]]):format(file)) + ]]):format(file) + ) command(('%s %s'):format(addfcmd, file)) list[#list + 1] = { - lnum=900, end_lnum=0, col=30, end_col=0, text='Line 900', module='', - nr=-1, bufnr=5, valid=1, pattern='', vcol=0, ['type']='', + lnum = 900, + end_lnum = 0, + col = 30, + end_col = 0, + text = 'Line 900', + module = '', + nr = -1, + bufnr = 5, + valid = 1, + pattern = '', + vcol = 0, + ['type'] = '', } eq(list, getlist()) - eq(('%s-3.res'):format(file), funcs.bufname(list[3].bufnr)) + eq(('%s-3.res'):format(file), fn.bufname(list[3].bufnr)) - write_file(file, ([[ + write_file( + file, + ([[ %s-1.res:222:77:Line 222 %s-2.res:333:88:Line 333 - ]]):format(file, file)) + ]]):format(file, file) + ) command('enew!') command(('%s %s'):format(getfcmd, file)) list = { - {lnum=222, end_lnum=0, col=77, end_col=0, text='Line 222', module='', - nr=-1, bufnr=2, valid=1, pattern='', vcol=0, ['type']=''}, - {lnum=333, end_lnum=0, col=88, end_col=0, text='Line 333', module='', - nr=-1, bufnr=3, valid=1, pattern='', vcol=0, ['type']=''}, + { + lnum = 222, + end_lnum = 0, + col = 77, + end_col = 0, + text = 'Line 222', + module = '', + nr = -1, + bufnr = 2, + valid = 1, + pattern = '', + vcol = 0, + ['type'] = '', + }, + { + lnum = 333, + end_lnum = 0, + col = 88, + end_col = 0, + text = 'Line 333', + module = '', + nr = -1, + bufnr = 3, + valid = 1, + pattern = '', + vcol = 0, + ['type'] = '', + }, } eq(list, getlist()) - eq(('%s-1.res'):format(file), funcs.bufname(list[1].bufnr)) - eq(('%s-2.res'):format(file), funcs.bufname(list[2].bufnr)) + eq(('%s-1.res'):format(file), fn.bufname(list[1].bufnr)) + eq(('%s-2.res'):format(file), fn.bufname(list[2].bufnr)) end) end) end @@ -109,7 +178,7 @@ describe('quickfix', function() call append(0, ['New line 1', 'New line 2', 'New line 3']) silent ll ]]) - eq({0, 6, 1, 0, 1}, funcs.getcurpos()) + eq({ 0, 6, 1, 0, 1 }, fn.getcurpos()) end) it('BufAdd does not cause E16 when reusing quickfix buffer #18135', function() @@ -127,20 +196,20 @@ describe('quickfix', function() end) it(':vimgrep can specify Unicode pattern without delimiters', function() - eq('Vim(vimgrep):E480: No match: →', exc_exec('vimgrep → test/functional/fixtures/tty-test.c')) + eq( + 'Vim(vimgrep):E480: No match: →', + exc_exec('vimgrep → test/functional/fixtures/tty-test.c') + ) local screen = Screen.new(40, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {reverse = true}, -- IncSearch + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { reverse = true }, -- IncSearch }) screen:attach() feed('i→<Esc>:vimgrep →') screen:expect([[ {1:→} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 :vimgrep →^ | ]]) end) diff --git a/test/functional/ex_cmds/quit_spec.lua b/test/functional/ex_cmds/quit_spec.lua index 3680801dae..5a1759dab3 100644 --- a/test/functional/ex_cmds/quit_spec.lua +++ b/test/functional/ex_cmds/quit_spec.lua @@ -11,4 +11,3 @@ describe(':qa', function() -- errors end) end) - diff --git a/test/functional/ex_cmds/script_spec.lua b/test/functional/ex_cmds/script_spec.lua index 62249caa5e..4c963c5da7 100644 --- a/test/functional/ex_cmds/script_spec.lua +++ b/test/functional/ex_cmds/script_spec.lua @@ -5,7 +5,7 @@ local neq = helpers.neq local command = helpers.command local exec_capture = helpers.exec_capture local write_file = helpers.write_file -local meths = helpers.meths +local api = helpers.api local clear = helpers.clear local dedent = helpers.dedent local exc_exec = helpers.exc_exec @@ -17,7 +17,7 @@ before_each(clear) local function source(code) write_file(tmpfile, code) - command('source '..tmpfile) + command('source ' .. tmpfile) end describe('script_get-based command', function() @@ -30,29 +30,48 @@ describe('script_get-based command', function() local function test_garbage_exec(cmd, check_neq) describe(cmd, function() it('works correctly when skipping oneline variant', function() - eq(true, pcall(source, (dedent([[ + eq( + true, + pcall( + source, + (dedent([[ if 0 %s %s endif - ]])):format(cmd, garbage))) + ]])):format(cmd, garbage) + ) + ) eq('', exec_capture('messages')) if check_neq then - neq(0, exc_exec(dedent([[ + neq( + 0, + exc_exec(dedent([[ %s %s - ]])):format(cmd, garbage)) + ]])):format(cmd, garbage) + ) end end) it('works correctly when skipping HEREdoc variant', function() - eq(true, pcall(source, (dedent([[ + eq( + true, + pcall( + source, + (dedent([[ if 0 %s << EOF %s EOF endif - ]])):format(cmd, garbage))) + ]])):format(cmd, garbage) + ) + ) eq('', exec_capture('messages')) if check_neq then - eq(true, pcall(source, (dedent([[ + eq( + true, + pcall( + source, + (dedent([[ let g:exc = 0 try %s << EOF @@ -61,8 +80,10 @@ describe('script_get-based command', function() catch let g:exc = v:exception endtry - ]])):format(cmd, garbage))) - neq(0, meths.get_var('exc')) + ]])):format(cmd, garbage) + ) + ) + neq(0, api.nvim_get_var('exc')) end end) end) @@ -75,7 +96,7 @@ describe('script_get-based command', function() -- Provider-based scripts test_garbage_exec('ruby', not missing_provider('ruby')) - test_garbage_exec('python3', not missing_provider('python3')) + test_garbage_exec('python3', not missing_provider('python')) -- Missing scripts test_garbage_exec('python', false) diff --git a/test/functional/ex_cmds/sign_spec.lua b/test/functional/ex_cmds/sign_spec.lua index f280a45174..06de7f23a9 100644 --- a/test/functional/ex_cmds/sign_spec.lua +++ b/test/functional/ex_cmds/sign_spec.lua @@ -1,5 +1,7 @@ local helpers = require('test.functional.helpers')(after_each) -local clear, nvim, eq, assert_alive = helpers.clear, helpers.nvim, helpers.eq, helpers.assert_alive +local clear, eq, assert_alive = helpers.clear, helpers.eq, helpers.assert_alive +local command = helpers.command +local api = helpers.api describe('sign', function() before_each(clear) @@ -7,24 +9,24 @@ describe('sign', function() describe('without specifying buffer', function() it('deletes the sign from all buffers', function() -- place a sign with id 34 to first buffer - nvim('command', 'sign define Foo text=+ texthl=Delimiter linehl=Comment numhl=Number') - local buf1 = nvim('eval', 'bufnr("%")') - nvim('command', 'sign place 34 line=3 name=Foo buffer='..buf1) + command('sign define Foo text=+ texthl=Delimiter linehl=Comment numhl=Number') + local buf1 = api.nvim_eval('bufnr("%")') + command('sign place 34 line=3 name=Foo buffer=' .. buf1) -- create a second buffer and place the sign on it as well - nvim('command', 'new') - local buf2 = nvim('eval', 'bufnr("%")') - nvim('command', 'sign place 34 line=3 name=Foo buffer='..buf2) + command('new') + local buf2 = api.nvim_eval('bufnr("%")') + command('sign place 34 line=3 name=Foo buffer=' .. buf2) -- now unplace without specifying a buffer - nvim('command', 'sign unplace 34') - eq("--- Signs ---\n", nvim('exec', 'sign place buffer='..buf1, true)) - eq("--- Signs ---\n", nvim('exec', 'sign place buffer='..buf2, true)) + command('sign unplace 34') + eq('--- Signs ---\n', api.nvim_exec('sign place buffer=' .. buf1, true)) + eq('--- Signs ---\n', api.nvim_exec('sign place buffer=' .. buf2, true)) end) end) end) describe('define {id}', function() - it ('does not leak memory when specifying multiple times the same argument', function() - nvim('command', 'sign define Foo culhl=Normal culhl=Normal') + it('does not leak memory when specifying multiple times the same argument', function() + command('sign define Foo culhl=Normal culhl=Normal') assert_alive() end) end) diff --git a/test/functional/ex_cmds/source_spec.lua b/test/functional/ex_cmds/source_spec.lua index 24987354a4..5ce0e395bd 100644 --- a/test/functional/ex_cmds/source_spec.lua +++ b/test/functional/ex_cmds/source_spec.lua @@ -3,7 +3,7 @@ local command = helpers.command local insert = helpers.insert local eq = helpers.eq local clear = helpers.clear -local meths = helpers.meths +local api = helpers.api local feed = helpers.feed local feed_command = helpers.feed_command local write_file = helpers.write_file @@ -49,37 +49,43 @@ describe(':source', function() pending("'shellslash' only works on Windows") return end - meths.set_option_value('shellslash', false, {}) + api.nvim_set_option_value('shellslash', false, {}) mkdir('Xshellslash') - write_file([[Xshellslash/Xstack.vim]], [[ + write_file( + [[Xshellslash/Xstack.vim]], + [[ let g:stack1 = expand('<stack>') set shellslash let g:stack2 = expand('<stack>') set noshellslash let g:stack3 = expand('<stack>') - ]]) + ]] + ) for _ = 1, 2 do command([[source Xshellslash/Xstack.vim]]) - matches([[Xshellslash\Xstack%.vim]], meths.get_var('stack1')) - matches([[Xshellslash/Xstack%.vim]], meths.get_var('stack2')) - matches([[Xshellslash\Xstack%.vim]], meths.get_var('stack3')) + matches([[Xshellslash\Xstack%.vim]], api.nvim_get_var('stack1')) + matches([[Xshellslash/Xstack%.vim]], api.nvim_get_var('stack2')) + matches([[Xshellslash\Xstack%.vim]], api.nvim_get_var('stack3')) end - write_file([[Xshellslash/Xstack.lua]], [[ + write_file( + [[Xshellslash/Xstack.lua]], + [[ vim.g.stack1 = vim.fn.expand('<stack>') vim.o.shellslash = true vim.g.stack2 = vim.fn.expand('<stack>') vim.o.shellslash = false vim.g.stack3 = vim.fn.expand('<stack>') - ]]) + ]] + ) for _ = 1, 2 do command([[source Xshellslash/Xstack.lua]]) - matches([[Xshellslash\Xstack%.lua]], meths.get_var('stack1')) - matches([[Xshellslash/Xstack%.lua]], meths.get_var('stack2')) - matches([[Xshellslash\Xstack%.lua]], meths.get_var('stack3')) + matches([[Xshellslash\Xstack%.lua]], api.nvim_get_var('stack1')) + matches([[Xshellslash/Xstack%.lua]], api.nvim_get_var('stack2')) + matches([[Xshellslash\Xstack%.lua]], api.nvim_get_var('stack3')) end rmdir('Xshellslash') @@ -101,11 +107,11 @@ describe(':source', function() eq("{'k': 'v'}", exec_capture('echo b')) -- Script items are created only on script var access - eq("1", exec_capture('echo c')) - eq("0zBEEFCAFE", exec_capture('echo d')) + eq('1', exec_capture('echo c')) + eq('0zBEEFCAFE', exec_capture('echo d')) exec('set cpoptions+=C') - eq('Vim(let):E723: Missing end of Dictionary \'}\': ', exc_exec('source')) + eq("Vim(let):E723: Missing end of Dictionary '}': ", exc_exec('source')) end) it('selection in current buffer', function() @@ -132,14 +138,14 @@ describe(':source', function() feed_command(':source') eq('4', exec_capture('echo a')) eq("{'K': 'V'}", exec_capture('echo b')) - eq("<SNR>1_C()", exec_capture('echo D()')) + eq('<SNR>1_C()', exec_capture('echo D()')) -- Source last line only feed_command(':$source') eq('Vim(echo):E117: Unknown function: s:C', exc_exec('echo D()')) exec('set cpoptions+=C') - eq('Vim(let):E723: Missing end of Dictionary \'}\': ', exc_exec("'<,'>source")) + eq("Vim(let):E723: Missing end of Dictionary '}': ", exc_exec("'<,'>source")) end) it('does not break if current buffer is modified while sourced', function() @@ -163,19 +169,22 @@ describe(':source', function() it('can source lua files', function() local test_file = 'test.lua' - write_file(test_file, [[ + write_file( + test_file, + [[ vim.g.sourced_lua = 1 vim.g.sfile_value = vim.fn.expand('<sfile>') vim.g.stack_value = vim.fn.expand('<stack>') vim.g.script_value = vim.fn.expand('<script>') - ]]) + ]] + ) command('set shellslash') command('source ' .. test_file) eq(1, eval('g:sourced_lua')) - matches([[/test%.lua$]], meths.get_var('sfile_value')) - matches([[/test%.lua$]], meths.get_var('stack_value')) - matches([[/test%.lua$]], meths.get_var('script_value')) + matches([[/test%.lua$]], api.nvim_get_var('sfile_value')) + matches([[/test%.lua$]], api.nvim_get_var('stack_value')) + matches([[/test%.lua$]], api.nvim_get_var('script_value')) os.remove(test_file) end) @@ -220,9 +229,9 @@ describe(':source', function() eq(12, eval('g:c')) eq(' \\ 1\n "\\ 2', exec_lua('return _G.a')) - eq(':source (no file)', meths.get_var('sfile_value')) - eq(':source (no file)', meths.get_var('stack_value')) - eq(':source (no file)', meths.get_var('script_value')) + eq(':source (no file)', api.nvim_get_var('sfile_value')) + eq(':source (no file)', api.nvim_get_var('stack_value')) + eq(':source (no file)', api.nvim_get_var('script_value')) end) end @@ -245,22 +254,22 @@ describe(':source', function() local test_file = 'test.lua' -- Does throw E484 for unreadable files - local ok, result = pcall(exec_capture, ":source "..test_file ..'noexisting') + local ok, result = pcall(exec_capture, ':source ' .. test_file .. 'noexisting') eq(false, ok) - neq(nil, result:find("E484")) + neq(nil, result:find('E484')) -- Doesn't throw for parsing error - write_file (test_file, "vim.g.c = ") - ok, result = pcall(exec_capture, ":source "..test_file) + write_file(test_file, 'vim.g.c = ') + ok, result = pcall(exec_capture, ':source ' .. test_file) eq(false, ok) - eq(nil, result:find("E484")) + eq(nil, result:find('E484')) os.remove(test_file) -- Doesn't throw for runtime error - write_file (test_file, "error('Cause error anyway :D')") - ok, result = pcall(exec_capture, ":source "..test_file) + write_file(test_file, "error('Cause error anyway :D')") + ok, result = pcall(exec_capture, ':source ' .. test_file) eq(false, ok) - eq(nil, result:find("E484")) + eq(nil, result:find('E484')) os.remove(test_file) end) end) diff --git a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua index 436873b464..a6fdb919c5 100644 --- a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua +++ b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua @@ -1,19 +1,18 @@ local Screen = require('test.functional.ui.screen') local helpers = require('test.functional.helpers')(after_each) -local luv = require('luv') -local eq, eval, expect, exec = - helpers.eq, helpers.eval, helpers.expect, helpers.exec +local uv = vim.uv +local eq, eval, expect, exec = helpers.eq, helpers.eval, helpers.expect, helpers.exec local assert_alive = helpers.assert_alive local clear = helpers.clear local command = helpers.command local feed = helpers.feed -local funcs = helpers.funcs +local fn = helpers.fn local nvim_prog = helpers.nvim_prog local ok = helpers.ok local rmdir = helpers.rmdir local new_argv = helpers.new_argv local new_pipename = helpers.new_pipename -local pesc = helpers.pesc +local pesc = vim.pesc local os_kill = helpers.os_kill local set_session = helpers.set_session local spawn = helpers.spawn @@ -22,7 +21,7 @@ local expect_msg_seq = helpers.expect_msg_seq local pcall_err = helpers.pcall_err local mkdir = helpers.mkdir local poke_eventloop = helpers.poke_eventloop -local meths = helpers.meths +local api = helpers.api local retry = helpers.retry local write_file = helpers.write_file @@ -32,24 +31,24 @@ describe(':recover', function() it('fails if given a non-existent swapfile', function() local swapname = 'bogus_swapfile' local swapname2 = 'bogus_swapfile.swp' - eq('Vim(recover):E305: No swap file found for '..swapname, - pcall_err(command, 'recover '..swapname)) -- Should not segfault. #2117 + eq( + 'Vim(recover):E305: No swap file found for ' .. swapname, + pcall_err(command, 'recover ' .. swapname) + ) -- Should not segfault. #2117 -- Also check filename ending with ".swp". #9504 - eq('Vim(recover):E306: Cannot open '..swapname2, - pcall_err(command, 'recover '..swapname2)) -- Should not segfault. #2117 + eq('Vim(recover):E306: Cannot open ' .. swapname2, pcall_err(command, 'recover ' .. swapname2)) -- Should not segfault. #2117 assert_alive() end) - end) describe("preserve and (R)ecover with custom 'directory'", function() - local swapdir = luv.cwd()..'/Xtest_recover_dir' + local swapdir = uv.cwd() .. '/Xtest_recover_dir' local testfile = 'Xtest_recover_file1' -- Put swapdir at the start of the 'directory' list. #1836 -- Note: `set swapfile` *must* go after `set directory`: otherwise it may -- attempt to create a swapfile in different directory. local init = [[ - set directory^=]]..swapdir:gsub([[\]], [[\\]])..[[// + set directory^=]] .. swapdir:gsub([[\]], [[\\]]) .. [[// set swapfile fileformat=unix undolevels=-1 ]] @@ -67,7 +66,7 @@ describe("preserve and (R)ecover with custom 'directory'", function() local function setup_swapname() exec(init) - command('edit! '..testfile) + command('edit! ' .. testfile) feed('isometext<esc>') exec('redir => g:swapname | silent swapname | redir END') return eval('g:swapname') @@ -75,23 +74,23 @@ describe("preserve and (R)ecover with custom 'directory'", function() local function test_recover(swappath1) -- Start another Nvim instance. - local nvim2 = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed'}, true) + local nvim2 = spawn({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed' }, true) set_session(nvim2) exec(init) -- Use the "SwapExists" event to choose the (R)ecover choice at the dialog. command('autocmd SwapExists * let v:swapchoice = "r"') - command('silent edit! '..testfile) + command('silent edit! ' .. testfile) exec('redir => g:swapname | silent swapname | redir END') local swappath2 = eval('g:swapname') expect('sometext') -- swapfile from session 1 should end in .swp - eq(testfile..'.swp', string.match(swappath1, '[^%%]+$')) + eq(testfile .. '.swp', string.match(swappath1, '[^%%]+$')) -- swapfile from session 2 should end in .swo - eq(testfile..'.swo', string.match(swappath2, '[^%%]+$')) + eq(testfile .. '.swo', string.match(swappath2, '[^%%]+$')) -- Verify that :swapname was not truncated (:help 'shortmess'). ok(nil == string.find(swappath1, '%.%.%.')) ok(nil == string.find(swappath2, '%.%.%.')) @@ -115,27 +114,28 @@ describe("preserve and (R)ecover with custom 'directory'", function() local screen0 = Screen.new() screen0:attach() local child_server = new_pipename() - funcs.termopen({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--listen', child_server}) - screen0:expect({any = pesc('[No Name]')}) -- Wait for the child process to start. + fn.termopen({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--listen', child_server }, { + env = { VIMRUNTIME = os.getenv('VIMRUNTIME') }, + }) + screen0:expect({ any = pesc('[No Name]') }) -- Wait for the child process to start. local child_session = helpers.connect(child_server) set_session(child_session) local swappath1 = setup_swapname() set_session(nvim0) - command('call chanclose(&channel)') -- Kill the child process. - screen0:expect({any = pesc('[Process exited 1]')}) -- Wait for the child process to stop. + command('call chanclose(&channel)') -- Kill the child process. + screen0:expect({ any = pesc('[Process exited 1]') }) -- Wait for the child process to stop. test_recover(swappath1) end) - end) describe('swapfile detection', function() - local swapdir = luv.cwd()..'/Xtest_swapdialog_dir' + local swapdir = uv.cwd() .. '/Xtest_swapdialog_dir' local nvim0 -- Put swapdir at the start of the 'directory' list. #1836 -- Note: `set swapfile` *must* go after `set directory`: otherwise it may -- attempt to create a swapfile in different directory. local init = [[ - set directory^=]]..swapdir:gsub([[\]], [[\\]])..[[// + set directory^=]] .. swapdir:gsub([[\]], [[\\]]) .. [[// set swapfile fileformat=unix nomodified undolevels=-1 nohidden ]] before_each(function() @@ -153,67 +153,88 @@ describe('swapfile detection', function() it('always show swapfile dialog #8840 #9027', function() local testfile = 'Xtest_swapdialog_file1' - local expected_no_dialog = '^'..(' '):rep(256)..'|\n' - for _=1,37 do - expected_no_dialog = expected_no_dialog..'~'..(' '):rep(255)..'|\n' + local expected_no_dialog = '^' .. (' '):rep(256) .. '|\n' + for _ = 1, 37 do + expected_no_dialog = expected_no_dialog .. '~' .. (' '):rep(255) .. '|\n' end - expected_no_dialog = expected_no_dialog..testfile..(' '):rep(216)..'0,0-1 All|\n' - expected_no_dialog = expected_no_dialog..(' '):rep(256)..'|\n' + expected_no_dialog = expected_no_dialog .. testfile .. (' '):rep(216) .. '0,0-1 All|\n' + expected_no_dialog = expected_no_dialog .. (' '):rep(256) .. '|\n' exec(init) - command('edit! '..testfile) + command('edit! ' .. testfile) feed('isometext<esc>') command('preserve') -- Start another Nvim instance. - local nvim2 = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed'}, true, nil, true) + local nvim2 = spawn({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed' }, true, nil, true) set_session(nvim2) local screen2 = Screen.new(256, 40) screen2:attach() exec(init) - command('autocmd! nvim_swapfile') -- Delete the default handler (which skips the dialog). + command('autocmd! nvim_swapfile') -- Delete the default handler (which skips the dialog). -- With shortmess+=F command('set shortmess+=F') - feed(':edit '..testfile..'<CR>') - screen2:expect{any=[[E325: ATTENTION.*]]..'\n'..[[Found a swap file by the name ".*]] - ..[[Xtest_swapdialog_dir[/\].*]]..testfile..[[%.swp"]]} - feed('e') -- Chose "Edit" at the swap dialog. + feed(':edit ' .. testfile .. '<CR>') + screen2:expect { + any = [[E325: ATTENTION.*]] + .. '\n' + .. [[Found a swap file by the name ".*]] + .. [[Xtest_swapdialog_dir[/\].*]] + .. testfile + .. [[%.swp"]], + } + feed('e') -- Chose "Edit" at the swap dialog. screen2:expect(expected_no_dialog) -- With :silent and shortmess+=F feed(':silent edit %<CR>') - screen2:expect{any=[[Found a swap file by the name ".*]] - ..[[Xtest_swapdialog_dir[/\].*]]..testfile..[[%.swp"]]} - feed('e') -- Chose "Edit" at the swap dialog. + screen2:expect { + any = [[Found a swap file by the name ".*]] + .. [[Xtest_swapdialog_dir[/\].*]] + .. testfile + .. [[%.swp"]], + } + feed('e') -- Chose "Edit" at the swap dialog. screen2:expect(expected_no_dialog) -- With :silent! and shortmess+=F feed(':silent! edit %<CR>') - screen2:expect{any=[[Found a swap file by the name ".*]] - ..[[Xtest_swapdialog_dir[/\].*]]..testfile..[[%.swp"]]} - feed('e') -- Chose "Edit" at the swap dialog. + screen2:expect { + any = [[Found a swap file by the name ".*]] + .. [[Xtest_swapdialog_dir[/\].*]] + .. testfile + .. [[%.swp"]], + } + feed('e') -- Chose "Edit" at the swap dialog. screen2:expect(expected_no_dialog) -- With API (via eval/Vimscript) call and shortmess+=F feed(':call nvim_command("edit %")<CR>') - screen2:expect{any=[[Found a swap file by the name ".*]] - ..[[Xtest_swapdialog_dir[/\].*]]..testfile..[[%.swp"]]} - feed('e') -- Chose "Edit" at the swap dialog. + screen2:expect { + any = [[Found a swap file by the name ".*]] + .. [[Xtest_swapdialog_dir[/\].*]] + .. testfile + .. [[%.swp"]], + } + feed('e') -- Chose "Edit" at the swap dialog. feed('<c-c>') screen2:expect(expected_no_dialog) -- With API call and shortmess+=F - async_meths.command('edit %') - screen2:expect{any=[[Found a swap file by the name ".*]] - ..[[Xtest_swapdialog_dir[/\].*]]..testfile..[[%.swp"]]} - feed('e') -- Chose "Edit" at the swap dialog. + async_meths.nvim_command('edit %') + screen2:expect { + any = [[Found a swap file by the name ".*]] + .. [[Xtest_swapdialog_dir[/\].*]] + .. testfile + .. [[%.swp"]], + } + feed('e') -- Chose "Edit" at the swap dialog. expect_msg_seq({ - ignore={'redraw'}, - seqs={ - { {'notification', 'nvim_error_event', {0, 'Vim(edit):E325: ATTENTION'}}, - } - } + ignore = { 'redraw' }, + seqs = { + { { 'notification', 'nvim_error_event', { 0, 'Vim(edit):E325: ATTENTION' } } }, + }, }) feed('<cr>') @@ -224,8 +245,8 @@ describe('swapfile detection', function() exec(init) command('edit Xfile1') command("put ='some text...'") - command('preserve') -- Make sure the swap file exists. - local nvimpid = funcs.getpid() + command('preserve') -- Make sure the swap file exists. + local nvimpid = fn.getpid() local nvim1 = spawn(new_argv(), true, nil, true) set_session(nvim1) @@ -242,44 +263,29 @@ describe('swapfile detection', function() it('selecting "q" in the attention prompt', function() exec(init) command('edit Xfile1') - command('preserve') -- Make sure the swap file exists. + command('preserve') -- Make sure the swap file exists. local screen = Screen.new(75, 18) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { bold = true, foreground = Screen.colors.SeaGreen }, -- MoreMsg }) local nvim1 = spawn(new_argv(), true, nil, true) set_session(nvim1) screen:attach() exec(init) - command('autocmd! nvim_swapfile') -- Delete the default handler (which skips the dialog). + command('autocmd! nvim_swapfile') -- Delete the default handler (which skips the dialog). feed(':split Xfile1\n') -- The default SwapExists handler does _not_ skip this prompt. screen:expect({ - any = pesc('{1:[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: }^') + any = pesc('{1:[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: }^'), }) feed('q') feed(':<CR>') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*16 : | ]]) nvim1:close() @@ -288,35 +294,20 @@ describe('swapfile detection', function() set_session(nvim2) screen:attach() exec(init) - command('autocmd! nvim_swapfile') -- Delete the default handler (which skips the dialog). + command('autocmd! nvim_swapfile') -- Delete the default handler (which skips the dialog). command('set more') command('au bufadd * let foo_w = wincol()') feed(':e Xfile1<CR>') - screen:expect({any = pesc('{1:-- More --}^')}) + screen:expect({ any = pesc('{1:-- More --}^') }) feed('<Space>') screen:expect({ - any = pesc('{1:[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: }^') + any = pesc('{1:[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: }^'), }) feed('q') command([[echo 'hello']]) screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*16 hello | ]]) nvim2:close() @@ -327,15 +318,15 @@ describe('swapfile detection', function() local function test_swapfile_after_reboot(swapexists, on_swapfile_running) local screen = Screen.new(75, 30) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg - [2] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { bold = true, foreground = Screen.colors.SeaGreen }, -- MoreMsg + [2] = { background = Screen.colors.Red, foreground = Screen.colors.White }, -- ErrorMsg }) screen:attach() exec(init) if not swapexists then - command('autocmd! nvim_swapfile') -- Delete the default handler (which skips the dialog). + command('autocmd! nvim_swapfile') -- Delete the default handler (which skips the dialog). end command('set nohidden') @@ -361,7 +352,7 @@ describe('swapfile detection', function() edit Xswaptest call setline(1, ['a', 'b', 'c']) ]]) - local swname = funcs.CopySwapfile() + local swname = fn.CopySwapfile() -- Forget we edited this file exec([[ @@ -385,14 +376,16 @@ describe('swapfile detection', function() ]]) -- pretend that the swapfile was created before boot - local atime = os.time() - luv.uptime() - 10 - luv.fs_utime(swname, atime, atime) + local atime = os.time() - uv.uptime() - 10 + uv.fs_utime(swname, atime, atime) feed(':edit Xswaptest<CR>') - screen:expect({any = table.concat({ - pesc('{2:E325: ATTENTION}'), - pesc('{1:[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort: }^'), - }, '.*')}) + screen:expect({ + any = table.concat({ + pesc('{2:E325: ATTENTION}'), + pesc('{1:[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort: }^'), + }, '.*'), + }) feed('e') end @@ -400,12 +393,14 @@ describe('swapfile detection', function() -- oldtest: Test_nocatch_process_still_running() it('swapfile created before boot vim-patch:8.2.2586', function() test_swapfile_after_reboot(false, function(screen) - screen:expect({any = table.concat({ - pesc('{2:E325: ATTENTION}'), - 'file name: .*Xswaptest', - 'process ID: %d* %(STILL RUNNING%)', - pesc('{1:[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: }^'), - }, '.*')}) + screen:expect({ + any = table.concat({ + pesc('{2:E325: ATTENTION}'), + 'file name: .*Xswaptest', + 'process ID: %d* %(STILL RUNNING%)', + pesc('{1:[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: }^'), + }, '.*'), + }) end) end) @@ -414,34 +409,36 @@ describe('swapfile detection', function() screen:expect({ any = 'W325: Ignoring swapfile from Nvim process' }) end) end) - end) describe('quitting swapfile dialog on startup stops TUI properly', function() - local swapdir = luv.cwd()..'/Xtest_swapquit_dir' + local swapdir = uv.cwd() .. '/Xtest_swapquit_dir' local testfile = 'Xtest_swapquit_file1' local otherfile = 'Xtest_swapquit_file2' -- Put swapdir at the start of the 'directory' list. #1836 -- Note: `set swapfile` *must* go after `set directory`: otherwise it may -- attempt to create a swapfile in different directory. - local init_dir = [[set directory^=]]..swapdir:gsub([[\]], [[\\]])..[[//]] + local init_dir = [[set directory^=]] .. swapdir:gsub([[\]], [[\\]]) .. [[//]] local init_set = [[set swapfile fileformat=unix nomodified undolevels=-1 nohidden]] before_each(function() - clear({args = {'--cmd', init_dir, '--cmd', init_set}}) + clear({ args = { '--cmd', init_dir, '--cmd', init_set } }) rmdir(swapdir) mkdir(swapdir) - write_file(testfile, [[ + write_file( + testfile, + [[ first second third - ]]) - command('edit! '..testfile) + ]] + ) + command('edit! ' .. testfile) feed('Gisometext<esc>') poke_eventloop() - clear() -- Leaves a swap file behind - meths.ui_attach(80, 30, {}) + clear() -- Leaves a swap file behind + api.nvim_ui_attach(80, 30, {}) end) after_each(function() rmdir(swapdir) @@ -450,57 +447,100 @@ describe('quitting swapfile dialog on startup stops TUI properly', function() end) it('(Q)uit at first file argument', function() - local chan = funcs.termopen({nvim_prog, '-u', 'NONE', '-i', 'NONE', - '--cmd', init_dir, '--cmd', init_set, - testfile}) + local chan = fn.termopen( + { nvim_prog, '-u', 'NONE', '-i', 'NONE', '--cmd', init_dir, '--cmd', init_set, testfile }, + { + env = { VIMRUNTIME = os.getenv('VIMRUNTIME') }, + } + ) retry(nil, nil, function() - eq('[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:', - eval("getline('$')->trim(' ', 2)")) + eq( + '[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:', + eval("getline('$')->trim(' ', 2)") + ) end) - meths.chan_send(chan, 'q') + api.nvim_chan_send(chan, 'q') retry(nil, nil, function() - eq({'', '[Process exited 1]', ''}, - eval("[1, 2, '$']->map({_, lnum -> getline(lnum)->trim(' ', 2)})")) + eq( + { '', '[Process exited 1]', '' }, + eval("[1, 2, '$']->map({_, lnum -> getline(lnum)->trim(' ', 2)})") + ) end) end) it('(A)bort at second file argument with -p', function() - local chan = funcs.termopen({nvim_prog, '-u', 'NONE', '-i', 'NONE', - '--cmd', init_dir, '--cmd', init_set, - '-p', otherfile, testfile}) + local chan = fn.termopen({ + nvim_prog, + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + init_dir, + '--cmd', + init_set, + '-p', + otherfile, + testfile, + }, { + env = { VIMRUNTIME = os.getenv('VIMRUNTIME') }, + }) retry(nil, nil, function() - eq('[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:', - eval("getline('$')->trim(' ', 2)")) + eq( + '[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:', + eval("getline('$')->trim(' ', 2)") + ) end) - meths.chan_send(chan, 'a') + api.nvim_chan_send(chan, 'a') retry(nil, nil, function() - eq({'', '[Process exited 1]', ''}, - eval("[1, 2, '$']->map({_, lnum -> getline(lnum)->trim(' ', 2)})")) + eq( + { '', '[Process exited 1]', '' }, + eval("[1, 2, '$']->map({_, lnum -> getline(lnum)->trim(' ', 2)})") + ) end) end) it('(Q)uit at file opened by -t', function() - write_file(otherfile, ([[ + write_file( + otherfile, + ([[ !_TAG_FILE_ENCODING utf-8 // first %s /^ \zsfirst$/ second %s /^ \zssecond$/ - third %s /^ \zsthird$/]]):format(testfile, testfile, testfile)) - local chan = funcs.termopen({nvim_prog, '-u', 'NONE', '-i', 'NONE', - '--cmd', init_dir, '--cmd', init_set, - '--cmd', 'set tags='..otherfile, '-tsecond'}) + third %s /^ \zsthird$/]]):format(testfile, testfile, testfile) + ) + local chan = fn.termopen({ + nvim_prog, + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + init_dir, + '--cmd', + init_set, + '--cmd', + 'set tags=' .. otherfile, + '-tsecond', + }, { + env = { VIMRUNTIME = os.getenv('VIMRUNTIME') }, + }) retry(nil, nil, function() - eq('[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:', - eval("getline('$')->trim(' ', 2)")) + eq( + '[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:', + eval("getline('$')->trim(' ', 2)") + ) end) - meths.chan_send(chan, 'q') + api.nvim_chan_send(chan, 'q') retry(nil, nil, function() - eq('Press ENTER or type command to continue', - eval("getline('$')->trim(' ', 2)")) + eq('Press ENTER or type command to continue', eval("getline('$')->trim(' ', 2)")) end) - meths.chan_send(chan, '\r') + api.nvim_chan_send(chan, '\r') retry(nil, nil, function() - eq({'', '[Process exited 1]', ''}, - eval("[1, 2, '$']->map({_, lnum -> getline(lnum)->trim(' ', 2)})")) + eq( + { '', '[Process exited 1]', '' }, + eval("[1, 2, '$']->map({_, lnum -> getline(lnum)->trim(' ', 2)})") + ) end) end) end) diff --git a/test/functional/ex_cmds/syntax_spec.lua b/test/functional/ex_cmds/syntax_spec.lua index c9e96703de..ccdd604c55 100644 --- a/test/functional/ex_cmds/syntax_spec.lua +++ b/test/functional/ex_cmds/syntax_spec.lua @@ -8,10 +8,11 @@ describe(':syntax', function() before_each(clear) describe('keyword', function() - it('does not crash when group name contains unprintable characters', - function() - eq('Vim(syntax):E669: Unprintable character in group name', - exc_exec('syntax keyword \024 foo bar')) + it('does not crash when group name contains unprintable characters', function() + eq( + 'Vim(syntax):E669: Unprintable character in group name', + exc_exec('syntax keyword \024 foo bar') + ) end) end) end) diff --git a/test/functional/ex_cmds/trust_spec.lua b/test/functional/ex_cmds/trust_spec.lua index fe13bd7cd2..2997b504fa 100644 --- a/test/functional/ex_cmds/trust_spec.lua +++ b/test/functional/ex_cmds/trust_spec.lua @@ -7,7 +7,7 @@ local exec_capture = helpers.exec_capture local matches = helpers.matches local pathsep = helpers.get_pathsep() local is_os = helpers.is_os -local funcs = helpers.funcs +local fn = helpers.fn describe(':trust', function() local xstate = 'Xstate' @@ -22,7 +22,7 @@ describe(':trust', function() before_each(function() helpers.write_file('test_file', 'test') - clear{env={XDG_STATE_HOME=xstate}} + clear { env = { XDG_STATE_HOME = xstate } } end) after_each(function() @@ -30,50 +30,53 @@ describe(':trust', function() end) it('trust then deny then remove a file using current buffer', function() - local cwd = funcs.getcwd() - local hash = funcs.sha256(helpers.read_file('test_file')) + local cwd = fn.getcwd() + local hash = fn.sha256(helpers.read_file('test_file')) command('edit test_file') matches('^Allowed ".*test_file" in trust database%.$', exec_capture('trust')) - local trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + local trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(string.format('%s %s', hash, cwd .. pathsep .. 'test_file'), vim.trim(trust)) matches('^Denied ".*test_file" in trust database%.$', exec_capture('trust ++deny')) - trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(string.format('! %s', cwd .. pathsep .. 'test_file'), vim.trim(trust)) matches('^Removed ".*test_file" from trust database%.$', exec_capture('trust ++remove')) - trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(string.format(''), vim.trim(trust)) end) it('deny then trust then remove a file using current buffer', function() - local cwd = funcs.getcwd() - local hash = funcs.sha256(helpers.read_file('test_file')) + local cwd = fn.getcwd() + local hash = fn.sha256(helpers.read_file('test_file')) command('edit test_file') matches('^Denied ".*test_file" in trust database%.$', exec_capture('trust ++deny')) - local trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + local trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(string.format('! %s', cwd .. pathsep .. 'test_file'), vim.trim(trust)) matches('^Allowed ".*test_file" in trust database%.$', exec_capture('trust')) - trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(string.format('%s %s', hash, cwd .. pathsep .. 'test_file'), vim.trim(trust)) matches('^Removed ".*test_file" from trust database%.$', exec_capture('trust ++remove')) - trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(string.format(''), vim.trim(trust)) end) it('deny then remove a file using file path', function() - local cwd = funcs.getcwd() + local cwd = fn.getcwd() matches('^Denied ".*test_file" in trust database%.$', exec_capture('trust ++deny test_file')) - local trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + local trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(string.format('! %s', cwd .. pathsep .. 'test_file'), vim.trim(trust)) - matches('^Removed ".*test_file" from trust database%.$', exec_capture('trust ++remove test_file')) - trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + matches( + '^Removed ".*test_file" from trust database%.$', + exec_capture('trust ++remove test_file') + ) + trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(string.format(''), vim.trim(trust)) end) end) diff --git a/test/functional/ex_cmds/verbose_spec.lua b/test/functional/ex_cmds/verbose_spec.lua index 50077e9e0c..7ceb2460d3 100644 --- a/test/functional/ex_cmds/verbose_spec.lua +++ b/test/functional/ex_cmds/verbose_spec.lua @@ -5,19 +5,21 @@ local eq = helpers.eq local exec = helpers.exec local exec_capture = helpers.exec_capture local write_file = helpers.write_file -local call_viml_function = helpers.meths.call_function +local call_viml_function = helpers.api.nvim_call_function local function last_set_tests(cmd) local script_location, script_file -- All test cases below use the same nvim instance. setup(function() - clear{args={'-V1'}} + clear { args = { '-V1' } } script_file = 'test_verbose.lua' local current_dir = call_viml_function('getcwd', {}) - current_dir = call_viml_function('fnamemodify', {current_dir, ':~'}) - script_location = table.concat{current_dir, helpers.get_pathsep(), script_file} + current_dir = call_viml_function('fnamemodify', { current_dir, ':~' }) + script_location = table.concat { current_dir, helpers.get_pathsep(), script_file } - write_file(script_file, [[ + write_file( + script_file, + [[ vim.api.nvim_set_option_value('hlsearch', false, {}) vim.bo.expandtab = true vim.opt.number = true @@ -45,7 +47,8 @@ function! s:return80()\ endfunction\ let &tw = s:return80()\ ", true) -]]) +]] + ) exec(cmd .. ' ' .. script_file) end) @@ -55,54 +58,84 @@ let &tw = s:return80()\ it('"Last set" for option set by Lua', function() local result = exec_capture(':verbose set hlsearch?') - eq(string.format([[ + eq( + string.format( + [[ nohlsearch Last set from %s line 1]], - script_location), result) + script_location + ), + result + ) end) it('"Last set" for option set by vim.o', function() local result = exec_capture(':verbose set expandtab?') - eq(string.format([[ + eq( + string.format( + [[ expandtab Last set from %s line 2]], - script_location), result) + script_location + ), + result + ) end) it('"Last set" for option set by vim.opt', function() local result = exec_capture(':verbose set number?') - eq(string.format([[ + eq( + string.format( + [[ number Last set from %s line 3]], - script_location), result) + script_location + ), + result + ) end) it('"Last set" for mapping set by Lua', function() local result = exec_capture(':verbose map <leader>key1') - eq(string.format([[ + eq( + string.format( + [[ n \key1 * :echo "test"<CR> Last set from %s line 4]], - script_location), result) + script_location + ), + result + ) end) it('"Last set" for mapping set by vim.keymap', function() local result = exec_capture(':verbose map <leader>key2') - eq(string.format([[ + eq( + string.format( + [[ n \key2 * :echo "test"<CR> Last set from %s line 5]], - script_location), result) + script_location + ), + result + ) end) it('"Last set" for autocmd by vim.api.nvim_exec', function() local result = exec_capture(':verbose autocmd test_group Filetype c') - eq(string.format([[ + eq( + string.format( + [[ --- Autocommands --- test_group FileType c setl cindent Last set from %s line 7]], - script_location), result) + script_location + ), + result + ) end) it('"Last set" for command defined by nvim_command', function() @@ -110,38 +143,58 @@ test_group FileType pending('nvim_command does not set the script context') end local result = exec_capture(':verbose command Bdelete') - eq(string.format([[ + eq( + string.format( + [[ Name Args Address Complete Definition Bdelete 0 :bd Last set from %s line 13]], - script_location), result) + script_location + ), + result + ) end) it('"Last set" for command defined by nvim_create_user_command', function() local result = exec_capture(':verbose command TestCommand') - eq(string.format([[ + eq( + string.format( + [[ Name Args Address Complete Definition TestCommand 0 :echo 'Hello' Last set from %s line 14]], - script_location), result) + script_location + ), + result + ) end) it('"Last set" for function', function() local result = exec_capture(':verbose function Close_Window') - eq(string.format([[ + eq( + string.format( + [[ function Close_Window() abort Last set from %s line 16 1 wincmd - endfunction]], - script_location), result) + script_location + ), + result + ) end) it('"Last set" works with anonymous sid', function() local result = exec_capture(':verbose set tw?') - eq(string.format([[ + eq( + string.format( + [[ textwidth=80 Last set from %s line 22]], - script_location), result) + script_location + ), + result + ) end) end @@ -159,10 +212,13 @@ describe('lua verbose:', function() setup(function() clear() script_file = 'test_luafile.lua' - write_file(script_file, [[ + write_file( + script_file, + [[ vim.api.nvim_set_option_value('hlsearch', false, {}) - ]]) - exec(':source '..script_file) + ]] + ) + exec(':source ' .. script_file) end) teardown(function() @@ -171,9 +227,11 @@ describe('lua verbose:', function() it('is disabled when verbose = 0', function() local result = exec_capture(':verbose set hlsearch?') - eq([[ + eq( + [[ nohlsearch - Last set from Lua]], result) + Last set from Lua]], + result + ) end) end) - diff --git a/test/functional/ex_cmds/wincmd_spec.lua b/test/functional/ex_cmds/wincmd_spec.lua index b1f174f445..98c6358f45 100644 --- a/test/functional/ex_cmds/wincmd_spec.lua +++ b/test/functional/ex_cmds/wincmd_spec.lua @@ -1,13 +1,13 @@ -local helpers = require("test.functional.helpers")(after_each) +local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local eq = helpers.eq -local funcs = helpers.funcs +local fn = helpers.fn local command = helpers.command it(':wincmd accepts a count', function() clear() command('vsplit') - eq(1, funcs.winnr()) + eq(1, fn.winnr()) command('wincmd 2 w') - eq(2, funcs.winnr()) + eq(2, fn.winnr()) end) diff --git a/test/functional/ex_cmds/write_spec.lua b/test/functional/ex_cmds/write_spec.lua index 0b8ce93b09..f711731072 100644 --- a/test/functional/ex_cmds/write_spec.lua +++ b/test/functional/ex_cmds/write_spec.lua @@ -1,13 +1,11 @@ local helpers = require('test.functional.helpers')(after_each) -local luv = require('luv') local eq, eval, clear, write_file, source, insert = - helpers.eq, helpers.eval, helpers.clear, helpers.write_file, - helpers.source, helpers.insert + helpers.eq, helpers.eval, helpers.clear, helpers.write_file, helpers.source, helpers.insert local pcall_err = helpers.pcall_err local command = helpers.command local feed_command = helpers.feed_command -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local skip = helpers.skip local is_os = helpers.is_os local is_ci = helpers.is_ci @@ -40,9 +38,9 @@ describe(':write', function() command('set backupcopy=auto') write_file('test_bkc_file.txt', 'content0') if is_os('win') then - command("silent !mklink test_bkc_link.txt test_bkc_file.txt") + command('silent !mklink test_bkc_link.txt test_bkc_file.txt') else - command("silent !ln -s test_bkc_file.txt test_bkc_link.txt") + command('silent !ln -s test_bkc_file.txt test_bkc_link.txt') end if eval('v:shell_error') ~= 0 then pending('Cannot create symlink') @@ -61,9 +59,9 @@ describe(':write', function() command('set backupcopy=no') write_file('test_bkc_file.txt', 'content0') if is_os('win') then - command("silent !mklink test_bkc_link.txt test_bkc_file.txt") + command('silent !mklink test_bkc_link.txt test_bkc_file.txt') else - command("silent !ln -s test_bkc_file.txt test_bkc_link.txt") + command('silent !ln -s test_bkc_file.txt test_bkc_link.txt') end if eval('v:shell_error') ~= 0 then pending('Cannot create symlink') @@ -77,73 +75,80 @@ describe(':write', function() eq(eval("['content1']"), eval("readfile('test_bkc_link.txt')")) end) - it("appends FIFO file", function() + it('appends FIFO file', function() -- mkfifo creates read-only .lnk files on Windows if is_os('win') or eval("executable('mkfifo')") == 0 then pending('missing "mkfifo" command') end - local text = "some fifo text from write_spec" - assert(os.execute("mkfifo test_fifo")) + local text = 'some fifo text from write_spec' + assert(os.execute('mkfifo test_fifo')) insert(text) -- Blocks until a consumer reads the FIFO. - feed_command("write >> test_fifo") + feed_command('write >> test_fifo') -- Read the FIFO, this will unblock the :write above. - local fifo = assert(io.open("test_fifo")) - eq(text.."\n", fifo:read("*all")) + local fifo = assert(io.open('test_fifo')) + eq(text .. '\n', fifo:read('*all')) fifo:close() end) - it("++p creates missing parent directories", function() + it('++p creates missing parent directories', function() eq(0, eval("filereadable('p_opt.txt')")) - command("write ++p p_opt.txt") + command('write ++p p_opt.txt') eq(1, eval("filereadable('p_opt.txt')")) - os.remove("p_opt.txt") + os.remove('p_opt.txt') eq(0, eval("filereadable('p_opt.txt')")) - command("write ++p ./p_opt.txt") + command('write ++p ./p_opt.txt') eq(1, eval("filereadable('p_opt.txt')")) - os.remove("p_opt.txt") + os.remove('p_opt.txt') eq(0, eval("filereadable('test/write/p_opt.txt')")) - command("write ++p test/write/p_opt.txt") + command('write ++p test/write/p_opt.txt') eq(1, eval("filereadable('test/write/p_opt.txt')")) - eq(('Vim(write):E32: No file name'), pcall_err(command, 'write ++p test_write/')) + eq('Vim(write):E32: No file name', pcall_err(command, 'write ++p test_write/')) if not is_os('win') then - eq(('Vim(write):E17: "'..funcs.fnamemodify('.', ':p:h')..'" is a directory'), - pcall_err(command, 'write ++p .')) - eq(('Vim(write):E17: "'..funcs.fnamemodify('.', ':p:h')..'" is a directory'), - pcall_err(command, 'write ++p ./')) + eq( + ('Vim(write):E17: "' .. fn.fnamemodify('.', ':p:h') .. '" is a directory'), + pcall_err(command, 'write ++p .') + ) + eq( + ('Vim(write):E17: "' .. fn.fnamemodify('.', ':p:h') .. '" is a directory'), + pcall_err(command, 'write ++p ./') + ) end end) it('errors out correctly', function() skip(is_ci('cirrus')) command('let $HOME=""') - eq(funcs.fnamemodify('.', ':p:h'), funcs.fnamemodify('.', ':p:h:~')) + eq(fn.fnamemodify('.', ':p:h'), fn.fnamemodify('.', ':p:h:~')) -- Message from check_overwrite if not is_os('win') then - eq(('Vim(write):E17: "'..funcs.fnamemodify('.', ':p:h')..'" is a directory'), - pcall_err(command, 'write .')) + eq( + ('Vim(write):E17: "' .. fn.fnamemodify('.', ':p:h') .. '" is a directory'), + pcall_err(command, 'write .') + ) end - meths.set_option_value('writeany', true, {}) + api.nvim_set_option_value('writeany', true, {}) -- Message from buf_write - eq(('Vim(write):E502: "." is a directory'), pcall_err(command, 'write .')) - funcs.mkdir(fname_bak) - meths.set_option_value('backupdir', '.', {}) - meths.set_option_value('backup', true, {}) + eq('Vim(write):E502: "." is a directory', pcall_err(command, 'write .')) + fn.mkdir(fname_bak) + api.nvim_set_option_value('backupdir', '.', {}) + api.nvim_set_option_value('backup', true, {}) write_file(fname, 'content0') command('edit ' .. fname) - funcs.setline(1, 'TTY') - eq('Vim(write):E510: Can\'t make backup file (add ! to override)', - pcall_err(command, 'write')) - meths.set_option_value('backup', false, {}) - funcs.setfperm(fname, 'r--------') - eq('Vim(write):E505: "Xtest-functional-ex_cmds-write" is read-only (add ! to override)', - pcall_err(command, 'write')) + fn.setline(1, 'TTY') + eq("Vim(write):E510: Can't make backup file (add ! to override)", pcall_err(command, 'write')) + api.nvim_set_option_value('backup', false, {}) + fn.setfperm(fname, 'r--------') + eq( + 'Vim(write):E505: "Xtest-functional-ex_cmds-write" is read-only (add ! to override)', + pcall_err(command, 'write') + ) if is_os('win') then eq(0, os.execute('del /q/f ' .. fname)) eq(0, os.execute('rd /q/s ' .. fname_bak)) @@ -153,8 +158,7 @@ describe(':write', function() end write_file(fname_bak, 'TTYX') skip(is_os('win'), [[FIXME: exc_exec('write!') outputs 0 in Windows]]) - luv.fs_symlink(fname_bak .. ('/xxxxx'):rep(20), fname) - eq('Vim(write):E166: Can\'t open linked file for writing', - pcall_err(command, 'write!')) + vim.uv.fs_symlink(fname_bak .. ('/xxxxx'):rep(20), fname) + eq("Vim(write):E166: Can't open linked file for writing", pcall_err(command, 'write!')) end) end) diff --git a/test/functional/ex_cmds/wundo_spec.lua b/test/functional/ex_cmds/wundo_spec.lua index b6fcae0cf4..78081fa45f 100644 --- a/test/functional/ex_cmds/wundo_spec.lua +++ b/test/functional/ex_cmds/wundo_spec.lua @@ -2,9 +2,12 @@ local helpers = require('test.functional.helpers')(after_each) local command, clear, eval, spawn, nvim_prog, set_session = - helpers.command, helpers.clear, helpers.eval, helpers.spawn, - helpers.nvim_prog, helpers.set_session - + helpers.command, + helpers.clear, + helpers.eval, + helpers.spawn, + helpers.nvim_prog, + helpers.set_session describe(':wundo', function() before_each(clear) @@ -21,10 +24,18 @@ end) describe('u_* functions', function() it('safely fail on new, non-empty buffer', function() - local session = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed', - '-c', 'set undodir=. undofile'}) + local session = spawn({ + nvim_prog, + '-u', + 'NONE', + '-i', + 'NONE', + '--embed', + '-c', + 'set undodir=. undofile', + }) set_session(session) - command('echo "True"') -- Should not error out due to crashed Neovim + command('echo "True"') -- Should not error out due to crashed Neovim session:close() end) end) diff --git a/test/functional/ex_cmds/wviminfo_spec.lua b/test/functional/ex_cmds/wviminfo_spec.lua index 7525343891..23ae1440e6 100644 --- a/test/functional/ex_cmds/wviminfo_spec.lua +++ b/test/functional/ex_cmds/wviminfo_spec.lua @@ -1,8 +1,6 @@ local helpers = require('test.functional.helpers')(after_each) -local luv = require('luv') local clear = helpers.clear -local command, eq, neq, write_file = - helpers.command, helpers.eq, helpers.neq, helpers.write_file +local command, eq, neq, write_file = helpers.command, helpers.eq, helpers.neq, helpers.write_file local read_file = helpers.read_file local is_os = helpers.is_os @@ -10,21 +8,27 @@ describe(':wshada', function() local shada_file = 'wshada_test' before_each(function() - clear{args={'-i', is_os('win') and 'nul' or '/dev/null', - -- Need 'swapfile' for these tests. - '--cmd', 'set swapfile undodir=. directory=. viewdir=. backupdir=. belloff= noshowcmd noruler'}, - args_rm={'-n', '-i', '--cmd'}} + clear { + args = { + '-i', + is_os('win') and 'nul' or '/dev/null', + -- Need 'swapfile' for these tests. + '--cmd', + 'set swapfile undodir=. directory=. viewdir=. backupdir=. belloff= noshowcmd noruler', + }, + args_rm = { '-n', '-i', '--cmd' }, + } end) - after_each(function () + after_each(function() os.remove(shada_file) end) it('creates a shada file', function() -- file should _not_ exist - eq(nil, luv.fs_stat(shada_file)) - command('wsh! '..shada_file) + eq(nil, vim.uv.fs_stat(shada_file)) + command('wsh! ' .. shada_file) -- file _should_ exist - neq(nil, luv.fs_stat(shada_file)) + neq(nil, vim.uv.fs_stat(shada_file)) end) it('overwrites existing files', function() @@ -35,16 +39,15 @@ describe(':wshada', function() -- sanity check eq(text, read_file(shada_file)) - neq(nil, luv.fs_stat(shada_file)) + neq(nil, vim.uv.fs_stat(shada_file)) - command('wsh! '..shada_file) + command('wsh! ' .. shada_file) -- File should have been overwritten with a shada file. local fp = io.open(shada_file, 'r') local char1 = fp:read(1) fp:close() -- ShaDa file starts with a “header” entry - assert(char1:byte() == 0x01, - shada_file..' should be a shada file') + assert(char1:byte() == 0x01, shada_file .. ' should be a shada file') end) end) diff --git a/test/functional/example_spec.lua b/test/functional/example_spec.lua index f07f88b2b6..5fc55f4aab 100644 --- a/test/functional/example_spec.lua +++ b/test/functional/example_spec.lua @@ -12,12 +12,12 @@ describe('example', function() local screen before_each(function() clear() - screen = Screen.new(20,5) + screen = Screen.new(20, 5) screen:attach() - screen:set_default_attr_ids( { - [0] = {bold=true, foreground=Screen.colors.Blue}, - [1] = {bold=true, foreground=Screen.colors.Brown} - } ) + screen:set_default_attr_ids({ + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { bold = true, foreground = Screen.colors.Brown }, + }) end) it('screen test', function() @@ -47,7 +47,7 @@ describe('example', function() -- For this example, we enable `ext_tabline`: screen:detach() screen = Screen.new(25, 5) - screen:attach({rgb=true, ext_tabline=true}) + screen:attach({ rgb = true, ext_tabline = true }) -- From ":help ui" we find that `tabline_update` receives `curtab` and -- `tabs` objects. So we declare the UI handler like this: @@ -60,13 +60,14 @@ describe('example', function() command('tabedit foo') -- Use screen:expect{condition=…} to check the result. - screen:expect{condition=function() - eq({ id = 2 }, event_curtab) - eq({ - {tab = { id = 1 }, name = '[No Name]'}, - {tab = { id = 2 }, name = 'foo'}, - }, - event_tabs) - end} + screen:expect { + condition = function() + eq(2, event_curtab) + eq({ + { tab = 1, name = '[No Name]' }, + { tab = 2, name = 'foo' }, + }, event_tabs) + end, + } end) end) diff --git a/test/functional/fixtures/CMakeLists.txt b/test/functional/fixtures/CMakeLists.txt index 6e64b1e4dc..150407fe46 100644 --- a/test/functional/fixtures/CMakeLists.txt +++ b/test/functional/fixtures/CMakeLists.txt @@ -5,7 +5,7 @@ endif() if(WIN32) target_compile_definitions(test_lib INTERFACE MSWIN) endif() -target_link_libraries(test_lib INTERFACE nvim) +target_link_libraries(test_lib INTERFACE nvim_bin) add_executable(tty-test EXCLUDE_FROM_ALL tty-test.c) add_executable(shell-test EXCLUDE_FROM_ALL shell-test.c) diff --git a/test/functional/fixtures/fake-lsp-server.lua b/test/functional/fixtures/fake-lsp-server.lua index 0db9265a29..d9f44da0b4 100644 --- a/test/functional/fixtures/fake-lsp-server.lua +++ b/test/functional/fixtures/fake-lsp-server.lua @@ -1,19 +1,15 @@ local protocol = require 'vim.lsp.protocol' - -- Logs to $NVIM_LOG_FILE. -- -- TODO(justinmk): remove after https://github.com/neovim/neovim/pull/7062 local function log(loglevel, area, msg) - vim.fn.writefile( - {string.format('%s %s: %s', loglevel, area, msg)}, - vim.env.NVIM_LOG_FILE, - 'a') + vim.fn.writefile({ string.format('%s %s: %s', loglevel, area, msg) }, vim.env.NVIM_LOG_FILE, 'a') end local function message_parts(sep, ...) local parts = {} - for i = 1, select("#", ...) do + for i = 1, select('#', ...) do local arg = select(i, ...) if arg ~= nil then table.insert(parts, arg) @@ -26,26 +22,33 @@ end local function assert_eq(a, b, ...) if not vim.deep_equal(a, b) then - error(message_parts(": ", - ..., "assert_eq failed", - string.format("left == %q, right == %q", - table.concat(vim.split(vim.inspect(a), "\n"), ""), - table.concat(vim.split(vim.inspect(b), "\n"), "") + error( + message_parts( + ': ', + ..., + 'assert_eq failed', + string.format( + 'left == %q, right == %q', + table.concat(vim.split(vim.inspect(a), '\n'), ''), + table.concat(vim.split(vim.inspect(b), '\n'), '') + ) ) - )) + ) end end local function format_message_with_content_length(encoded_message) return table.concat { - 'Content-Length: '; tostring(#encoded_message); '\r\n\r\n'; - encoded_message; + 'Content-Length: ', + tostring(#encoded_message), + '\r\n\r\n', + encoded_message, } end local function read_message() - local line = io.read("*l") - local length = line:lower():match("content%-length:%s*(%d+)") + local line = io.read('*l') + local length = line:lower():match('content%-length:%s*(%d+)') return vim.json.decode(io.read(2 + length):sub(2)) end @@ -54,49 +57,51 @@ local function send(payload) end local function respond(id, err, result) - assert(type(id) == 'number', "id must be a number") - send { jsonrpc = "2.0"; id = id, error = err, result = result } + assert(type(id) == 'number', 'id must be a number') + send { jsonrpc = '2.0', id = id, error = err, result = result } end local function notify(method, params) - assert(type(method) == 'string', "method must be a string") + assert(type(method) == 'string', 'method must be a string') send { method = method, params = params or {} } end local function expect_notification(method, params, ...) local message = read_message() - assert_eq(method, message.method, - ..., "expect_notification", "method") + assert_eq(method, message.method, ..., 'expect_notification', 'method') if params then - assert_eq(params, message.params, - ..., "expect_notification", method, "params") - assert_eq({jsonrpc = "2.0"; method=method, params=params}, message, - ..., "expect_notification", "message") + assert_eq(params, message.params, ..., 'expect_notification', method, 'params') + assert_eq( + { jsonrpc = '2.0', method = method, params = params }, + message, + ..., + 'expect_notification', + 'message' + ) end end local function expect_request(method, handler, ...) local req = read_message() - assert_eq(method, req.method, - ..., "expect_request", "method") + assert_eq(method, req.method, ..., 'expect_request', 'method') local err, result = handler(req.params) respond(req.id, err, result) end -io.stderr:setvbuf("no") +io.stderr:setvbuf('no') local function skeleton(config) local on_init = assert(config.on_init) local body = assert(config.body) - expect_request("initialize", function(params) + expect_request('initialize', function(params) return nil, on_init(params) end) - expect_notification("initialized", {}) + expect_notification('initialized', {}) body() - expect_request("shutdown", function() + expect_request('shutdown', function() return nil, {} end) - expect_notification("exit", nil) + expect_notification('exit', nil) end -- The actual tests. @@ -108,13 +113,13 @@ function tests.basic_init() on_init = function(_) return { capabilities = { - textDocumentSync = protocol.TextDocumentSyncKind.None; - } + textDocumentSync = protocol.TextDocumentSyncKind.None, + }, } - end; + end, body = function() notify('test') - end; + end, } end @@ -135,89 +140,95 @@ function tests.check_workspace_configuration() skeleton { on_init = function(_params) return { capabilities = {} } - end; + end, body = function() notify('start') - notify('workspace/configuration', { items = { - { section = "testSetting1" }; - { section = "testSetting2" }; - { section = "test.Setting3" }; - { section = "test.Setting4" }; - } }) - expect_notification('workspace/configuration', { true; false; 'nested'; vim.NIL}) + notify('workspace/configuration', { + items = { + { section = 'testSetting1' }, + { section = 'testSetting2' }, + { section = 'test.Setting3' }, + { section = 'test.Setting4' }, + }, + }) + expect_notification('workspace/configuration', { true, false, 'nested', vim.NIL }) notify('shutdown') - end; + end, } end function tests.prepare_rename_nil() skeleton { on_init = function() - return { capabilities = { - renameProvider = { - prepareProvider = true - } - } + return { + capabilities = { + renameProvider = { + prepareProvider = true, + }, + }, } - end; + end, body = function() notify('start') expect_request('textDocument/prepareRename', function() return nil, nil end) notify('shutdown') - end; + end, } end function tests.prepare_rename_placeholder() skeleton { on_init = function() - return { capabilities = { - renameProvider = { - prepareProvider = true - } - } + return { + capabilities = { + renameProvider = { + prepareProvider = true, + }, + }, } - end; + end, body = function() notify('start') expect_request('textDocument/prepareRename', function() - return nil, {placeholder = 'placeholder'} + return nil, { placeholder = 'placeholder' } end) expect_request('textDocument/rename', function(params) assert_eq(params.newName, 'renameto') return nil, nil end) notify('shutdown') - end; + end, } end function tests.prepare_rename_range() skeleton { on_init = function() - return { capabilities = { - renameProvider = { - prepareProvider = true - } - } + return { + capabilities = { + renameProvider = { + prepareProvider = true, + }, + }, } - end; + end, body = function() notify('start') expect_request('textDocument/prepareRename', function() - return nil, { - start = { line = 1, character = 8 }, - ['end'] = { line = 1, character = 12 }, - } + return nil, + { + start = { line = 1, character = 8 }, + ['end'] = { line = 1, character = 12 }, + } end) expect_request('textDocument/rename', function(params) assert_eq(params.newName, 'renameto') return nil, nil end) notify('shutdown') - end; + end, } end @@ -227,18 +238,18 @@ function tests.prepare_rename_error() return { capabilities = { renameProvider = { - prepareProvider = true + prepareProvider = true, }, - } + }, } - end; + end, body = function() notify('start') expect_request('textDocument/prepareRename', function() return {}, nil end) notify('shutdown') - end; + end, } end @@ -249,13 +260,12 @@ function tests.basic_check_capabilities() assert_eq(params.capabilities, expected_capabilities) return { capabilities = { - textDocumentSync = protocol.TextDocumentSyncKind.Full; - codeLensProvider = false - } + textDocumentSync = protocol.TextDocumentSyncKind.Full, + codeLensProvider = false, + }, } - end; - body = function() - end; + end, + body = function() end, } end @@ -265,18 +275,18 @@ function tests.text_document_save_did_open() return { capabilities = { textDocumentSync = { - save = true - } - } + save = true, + }, + }, } - end; + end, body = function() notify('start') expect_notification('textDocument/didClose') expect_notification('textDocument/didOpen') expect_notification('textDocument/didSave') notify('shutdown') - end; + end, } end @@ -286,16 +296,16 @@ function tests.text_document_sync_save_bool() return { capabilities = { textDocumentSync = { - save = true - } - } + save = true, + }, + }, } - end; + end, body = function() notify('start') - expect_notification('textDocument/didSave', {textDocument = { uri = "file://" }}) + expect_notification('textDocument/didSave', { textDocument = { uri = 'file://' } }) notify('shutdown') - end; + end, } end @@ -306,22 +316,22 @@ function tests.text_document_sync_save_includeText() capabilities = { textDocumentSync = { save = { - includeText = true - } - } - } + includeText = true, + }, + }, + }, } - end; + end, body = function() notify('start') expect_notification('textDocument/didSave', { textDocument = { - uri = "file://" + uri = 'file://', }, - text = "help me\n" + text = 'help me\n', }) notify('shutdown') - end; + end, } end @@ -332,18 +342,17 @@ function tests.capabilities_for_client_supports_method() assert_eq(params.capabilities, expected_capabilities) return { capabilities = { - textDocumentSync = protocol.TextDocumentSyncKind.Full; - completionProvider = true; - hoverProvider = true; - renameProvider = false; - definitionProvider = false; - referencesProvider = false; - codeLensProvider = { resolveProvider = true; }; - } + textDocumentSync = protocol.TextDocumentSyncKind.Full, + completionProvider = true, + hoverProvider = true, + renameProvider = false, + definitionProvider = false, + referencesProvider = false, + codeLensProvider = { resolveProvider = true }, + }, } - end; - body = function() - end; + end, + body = function() end, } end @@ -351,13 +360,13 @@ function tests.check_forward_request_cancelled() skeleton { on_init = function(_) return { capabilities = {} } - end; + end, body = function() - expect_request("error_code_test", function() - return {code = -32800}, nil, {method = "error_code_test", client_id=1} + expect_request('error_code_test', function() + return { code = -32800 }, nil, { method = 'error_code_test', client_id = 1 } end) notify('finish') - end; + end, } end @@ -365,14 +374,14 @@ function tests.check_forward_content_modified() skeleton { on_init = function(_) return { capabilities = {} } - end; + end, body = function() - expect_request("error_code_test", function() - return {code = -32801}, nil, {method = "error_code_test", client_id=1} + expect_request('error_code_test', function() + return { code = -32801 }, nil, { method = 'error_code_test', client_id = 1 } end) expect_notification('finish') notify('finish') - end; + end, } end @@ -380,15 +389,15 @@ function tests.check_pending_request_tracked() skeleton { on_init = function(_) return { capabilities = {} } - end; + end, body = function() - local msg = read_message() - assert_eq('slow_request', msg.method) - expect_notification('release') - respond(msg.id, nil, {}) - expect_notification('finish') - notify('finish') - end; + local msg = read_message() + assert_eq('slow_request', msg.method) + expect_notification('release') + respond(msg.id, nil, {}) + expect_notification('finish') + notify('finish') + end, } end @@ -396,15 +405,15 @@ function tests.check_cancel_request_tracked() skeleton { on_init = function(_) return { capabilities = {} } - end; + end, body = function() - local msg = read_message() - assert_eq('slow_request', msg.method) - expect_notification('$/cancelRequest', {id=msg.id}) - expect_notification('release') - respond(msg.id, {code = -32800}, nil) - notify('finish') - end; + local msg = read_message() + assert_eq('slow_request', msg.method) + expect_notification('$/cancelRequest', { id = msg.id }) + expect_notification('release') + respond(msg.id, { code = -32800 }, nil) + notify('finish') + end, } end @@ -412,16 +421,16 @@ function tests.check_tracked_requests_cleared() skeleton { on_init = function(_) return { capabilities = {} } - end; + end, body = function() - local msg = read_message() - assert_eq('slow_request', msg.method) - expect_notification('$/cancelRequest', {id=msg.id}) - expect_notification('release') - respond(msg.id, nil, {}) - expect_notification('finish') - notify('finish') - end; + local msg = read_message() + assert_eq('slow_request', msg.method) + expect_notification('$/cancelRequest', { id = msg.id }) + expect_notification('release') + respond(msg.id, nil, {}) + expect_notification('finish') + notify('finish') + end, } end @@ -432,14 +441,14 @@ function tests.basic_finish() assert_eq(params.capabilities, expected_capabilities) return { capabilities = { - textDocumentSync = protocol.TextDocumentSyncKind.Full; - } + textDocumentSync = protocol.TextDocumentSyncKind.Full, + }, } - end; + end, body = function() - expect_notification("finish") + expect_notification('finish') notify('finish') - end; + end, } end @@ -450,23 +459,23 @@ function tests.basic_check_buffer_open() assert_eq(params.capabilities, expected_capabilities) return { capabilities = { - textDocumentSync = protocol.TextDocumentSyncKind.Full; - } + textDocumentSync = protocol.TextDocumentSyncKind.Full, + }, } - end; + end, body = function() notify('start') expect_notification('textDocument/didOpen', { textDocument = { - languageId = ""; - text = table.concat({"testing"; "123"}, "\n") .. '\n'; - uri = "file://"; - version = 0; - }; + languageId = '', + text = table.concat({ 'testing', '123' }, '\n') .. '\n', + uri = 'file://', + version = 0, + }, }) - expect_notification("finish") + expect_notification('finish') notify('finish') - end; + end, } end @@ -477,32 +486,32 @@ function tests.basic_check_buffer_open_and_change() assert_eq(params.capabilities, expected_capabilities) return { capabilities = { - textDocumentSync = protocol.TextDocumentSyncKind.Full; - } + textDocumentSync = protocol.TextDocumentSyncKind.Full, + }, } - end; + end, body = function() notify('start') expect_notification('textDocument/didOpen', { textDocument = { - languageId = ""; - text = table.concat({"testing"; "123"}, "\n") .. '\n'; - uri = "file://"; - version = 0; - }; + languageId = '', + text = table.concat({ 'testing', '123' }, '\n') .. '\n', + uri = 'file://', + version = 0, + }, }) expect_notification('textDocument/didChange', { textDocument = { - uri = "file://"; - version = 3; - }; + uri = 'file://', + version = 3, + }, contentChanges = { - { text = table.concat({"testing"; "boop"}, "\n") .. '\n'; }; - } + { text = table.concat({ 'testing', 'boop' }, '\n') .. '\n' }, + }, }) - expect_notification("finish") + expect_notification('finish') notify('finish') - end; + end, } end @@ -513,32 +522,32 @@ function tests.basic_check_buffer_open_and_change_noeol() assert_eq(params.capabilities, expected_capabilities) return { capabilities = { - textDocumentSync = protocol.TextDocumentSyncKind.Full; - } + textDocumentSync = protocol.TextDocumentSyncKind.Full, + }, } - end; + end, body = function() notify('start') expect_notification('textDocument/didOpen', { textDocument = { - languageId = ""; - text = table.concat({"testing"; "123"}, "\n"); - uri = "file://"; - version = 0; - }; + languageId = '', + text = table.concat({ 'testing', '123' }, '\n'), + uri = 'file://', + version = 0, + }, }) expect_notification('textDocument/didChange', { textDocument = { - uri = "file://"; - version = 3; - }; + uri = 'file://', + version = 3, + }, contentChanges = { - { text = table.concat({"testing"; "boop"}, "\n"); }; - } + { text = table.concat({ 'testing', 'boop' }, '\n') }, + }, }) - expect_notification("finish") + expect_notification('finish') notify('finish') - end; + end, } end function tests.basic_check_buffer_open_and_change_multi() @@ -548,41 +557,41 @@ function tests.basic_check_buffer_open_and_change_multi() assert_eq(params.capabilities, expected_capabilities) return { capabilities = { - textDocumentSync = protocol.TextDocumentSyncKind.Full; - } + textDocumentSync = protocol.TextDocumentSyncKind.Full, + }, } - end; + end, body = function() notify('start') expect_notification('textDocument/didOpen', { textDocument = { - languageId = ""; - text = table.concat({"testing"; "123"}, "\n") .. '\n'; - uri = "file://"; - version = 0; - }; + languageId = '', + text = table.concat({ 'testing', '123' }, '\n') .. '\n', + uri = 'file://', + version = 0, + }, }) expect_notification('textDocument/didChange', { textDocument = { - uri = "file://"; - version = 3; - }; + uri = 'file://', + version = 3, + }, contentChanges = { - { text = table.concat({"testing"; "321"}, "\n") .. '\n'; }; - } + { text = table.concat({ 'testing', '321' }, '\n') .. '\n' }, + }, }) expect_notification('textDocument/didChange', { textDocument = { - uri = "file://"; - version = 4; - }; + uri = 'file://', + version = 4, + }, contentChanges = { - { text = table.concat({"testing"; "boop"}, "\n") .. '\n'; }; - } + { text = table.concat({ 'testing', 'boop' }, '\n') .. '\n' }, + }, }) - expect_notification("finish") + expect_notification('finish') notify('finish') - end; + end, } end @@ -593,46 +602,46 @@ function tests.basic_check_buffer_open_and_change_multi_and_close() assert_eq(params.capabilities, expected_capabilities) return { capabilities = { - textDocumentSync = protocol.TextDocumentSyncKind.Full; - } + textDocumentSync = protocol.TextDocumentSyncKind.Full, + }, } - end; + end, body = function() notify('start') expect_notification('textDocument/didOpen', { textDocument = { - languageId = ""; - text = table.concat({"testing"; "123"}, "\n") .. '\n'; - uri = "file://"; - version = 0; - }; + languageId = '', + text = table.concat({ 'testing', '123' }, '\n') .. '\n', + uri = 'file://', + version = 0, + }, }) expect_notification('textDocument/didChange', { textDocument = { - uri = "file://"; - version = 3; - }; + uri = 'file://', + version = 3, + }, contentChanges = { - { text = table.concat({"testing"; "321"}, "\n") .. '\n'; }; - } + { text = table.concat({ 'testing', '321' }, '\n') .. '\n' }, + }, }) expect_notification('textDocument/didChange', { textDocument = { - uri = "file://"; - version = 4; - }; + uri = 'file://', + version = 4, + }, contentChanges = { - { text = table.concat({"testing"; "boop"}, "\n") .. '\n'; }; - } + { text = table.concat({ 'testing', 'boop' }, '\n') .. '\n' }, + }, }) expect_notification('textDocument/didClose', { textDocument = { - uri = "file://"; - }; + uri = 'file://', + }, }) - expect_notification("finish") + expect_notification('finish') notify('finish') - end; + end, } end @@ -650,40 +659,40 @@ function tests.basic_check_buffer_open_and_change_incremental() willSaveWaitUntil = true, save = { includeText = true, - } - } - } + }, + }, + }, } - end; + end, body = function() notify('start') expect_notification('textDocument/didOpen', { textDocument = { - languageId = ""; - text = table.concat({"testing"; "123"}, "\n") .. '\n'; - uri = "file://"; - version = 0; - }; + languageId = '', + text = table.concat({ 'testing', '123' }, '\n') .. '\n', + uri = 'file://', + version = 0, + }, }) expect_notification('textDocument/didChange', { textDocument = { - uri = "file://"; - version = 3; - }; + uri = 'file://', + version = 3, + }, contentChanges = { { range = { - start = { line = 1; character = 3; }; - ["end"] = { line = 1; character = 3; }; - }; - rangeLength = 0; - text = "boop"; - }; - } + start = { line = 1, character = 3 }, + ['end'] = { line = 1, character = 3 }, + }, + rangeLength = 0, + text = 'boop', + }, + }, }) - expect_notification("finish") + expect_notification('finish') notify('finish') - end; + end, } end @@ -694,89 +703,88 @@ function tests.basic_check_buffer_open_and_change_incremental_editing() assert_eq(params.capabilities, expected_capabilities) return { capabilities = { - textDocumentSync = protocol.TextDocumentSyncKind.Incremental; - } + textDocumentSync = protocol.TextDocumentSyncKind.Incremental, + }, } - end; + end, body = function() notify('start') expect_notification('textDocument/didOpen', { textDocument = { - languageId = ""; - text = table.concat({"testing"; "123"}, "\n"); - uri = "file://"; - version = 0; - }; + languageId = '', + text = table.concat({ 'testing', '123' }, '\n'), + uri = 'file://', + version = 0, + }, }) expect_notification('textDocument/didChange', { textDocument = { - uri = "file://"; - version = 3; - }; + uri = 'file://', + version = 3, + }, contentChanges = { { range = { - start = { line = 0; character = 0; }; - ["end"] = { line = 1; character = 0; }; - }; - rangeLength = 4; - text = "testing\n\n"; - }; - } + start = { line = 0, character = 0 }, + ['end'] = { line = 1, character = 0 }, + }, + rangeLength = 4, + text = 'testing\n\n', + }, + }, }) - expect_notification("finish") + expect_notification('finish') notify('finish') - end; + end, } end function tests.invalid_header() - io.stdout:write("Content-length: \r\n") + io.stdout:write('Content-length: \r\n') end function tests.decode_nil() skeleton { on_init = function(_) return { capabilities = {} } - end; + end, body = function() notify('start') - notify("workspace/executeCommand", { - arguments = { "EXTRACT_METHOD", {metadata = {field = vim.NIL}}, 3, 0, 6123, vim.NIL }, - command = "refactor.perform", - title = "EXTRACT_METHOD" + notify('workspace/executeCommand', { + arguments = { 'EXTRACT_METHOD', { metadata = { field = vim.NIL } }, 3, 0, 6123, vim.NIL }, + command = 'refactor.perform', + title = 'EXTRACT_METHOD', }) notify('finish') - end; + end, } end - function tests.code_action_with_resolve() skeleton { on_init = function() return { capabilities = { codeActionProvider = { - resolveProvider = true - } - } + resolveProvider = true, + }, + }, } - end; + end, body = function() notify('start') local cmd = { title = 'Command 1', - command = 'dummy1' + command = 'dummy1', } expect_request('textDocument/codeAction', function() - return nil, { cmd, } + return nil, { cmd } end) expect_request('codeAction/resolve', function() return nil, cmd end) notify('shutdown') - end; + end, } end @@ -789,7 +797,7 @@ function tests.code_action_server_side_command() resolveProvider = false, }, executeCommandProvider = { - commands = {"dummy1"} + commands = { 'dummy1' }, }, }, } @@ -811,23 +819,22 @@ function tests.code_action_server_side_command() }) end - function tests.code_action_filter() skeleton { on_init = function() return { capabilities = { codeActionProvider = { - resolveProvider = false - } - } + resolveProvider = false, + }, + }, } - end; + end, body = function() notify('start') local action = { title = 'Action 1', - command = 'command' + command = 'command', } local preferred_action = { title = 'Action 2', @@ -845,13 +852,13 @@ function tests.code_action_filter() command = 'type_annotate_foo_command', } expect_request('textDocument/codeAction', function() - return nil, { action, preferred_action, type_annotate_action, type_annotate_foo_action, } + return nil, { action, preferred_action, type_annotate_action, type_annotate_foo_action } end) expect_request('textDocument/codeAction', function() - return nil, { action, preferred_action, type_annotate_action, type_annotate_foo_action, } + return nil, { action, preferred_action, type_annotate_action, type_annotate_foo_action } end) notify('shutdown') - end; + end, } end @@ -859,13 +866,13 @@ function tests.clientside_commands() skeleton { on_init = function() return { - capabilities = {} + capabilities = {}, } - end; + end, body = function() notify('start') notify('shutdown') - end; + end, } end @@ -874,41 +881,41 @@ function tests.codelens_refresh_lock() on_init = function() return { capabilities = { - codeLensProvider = { resolveProvider = true; }; - } + codeLensProvider = { resolveProvider = true }, + }, } - end; + end, body = function() notify('start') - expect_request("textDocument/codeLens", function () - return {code = -32002, message = "ServerNotInitialized"}, nil + expect_request('textDocument/codeLens', function() + return { code = -32002, message = 'ServerNotInitialized' }, nil end) - expect_request("textDocument/codeLens", function () + expect_request('textDocument/codeLens', function() local lenses = { { range = { - start = { line = 0, character = 0, }, - ['end'] = { line = 0, character = 3 } + start = { line = 0, character = 0 }, + ['end'] = { line = 0, character = 3 }, }, - command = { title = 'Lens1', command = 'Dummy' } + command = { title = 'Lens1', command = 'Dummy' }, }, } return nil, lenses end) - expect_request("textDocument/codeLens", function () + expect_request('textDocument/codeLens', function() local lenses = { { range = { - start = { line = 0, character = 0, }, - ['end'] = { line = 0, character = 3 } + start = { line = 0, character = 0 }, + ['end'] = { line = 0, character = 3 }, }, - command = { title = 'Lens2', command = 'Dummy' } + command = { title = 'Lens2', command = 'Dummy' }, }, } return nil, lenses end) notify('shutdown') - end; + end, } end @@ -918,16 +925,16 @@ function tests.basic_formatting() return { capabilities = { documentFormattingProvider = true, - } + }, } - end; + end, body = function() notify('start') expect_request('textDocument/formatting', function() return nil, {} end) notify('shutdown') - end; + end, } end @@ -940,12 +947,12 @@ function tests.set_defaults_all_capabilities() completionProvider = true, documentRangeFormattingProvider = true, hoverProvider = true, - } + }, } - end; + end, body = function() notify('test') - end; + end, } end @@ -956,18 +963,18 @@ function tests.inlay_hint() assert_eq(params.capabilities, expected_capabilities) return { capabilities = { - inlayHintProvider = true; - } + inlayHintProvider = true, + }, } - end; + end, body = function() notify('start') expect_request('textDocument/inlayHint', function() return nil, {} end) - expect_notification("finish") + expect_notification('finish') notify('finish') - end; + end, } end @@ -981,11 +988,11 @@ kill_timer:start(timeout or 1e3, 0, function() kill_timer:stop() kill_timer:close() log('ERROR', 'LSP', 'TIMEOUT') - io.stderr:write("TIMEOUT") + io.stderr:write('TIMEOUT') os.exit(100) end) -local status, err = pcall(assert(tests[test_name], "Test not found")) +local status, err = pcall(assert(tests[test_name], 'Test not found')) kill_timer:stop() kill_timer:close() if not status then diff --git a/test/functional/fixtures/middle/filen.lua b/test/functional/fixtures/middle/filen.lua index fce50cc776..24ccb200de 100644 --- a/test/functional/fixtures/middle/filen.lua +++ b/test/functional/fixtures/middle/filen.lua @@ -1 +1 @@ -table.insert(_G.test_loadorder, "mittel") +table.insert(_G.test_loadorder, 'mittel') diff --git a/test/functional/fixtures/nvim/after/filen.lua b/test/functional/fixtures/nvim/after/filen.lua index 0128a0a16a..13f0cfc6b9 100644 --- a/test/functional/fixtures/nvim/after/filen.lua +++ b/test/functional/fixtures/nvim/after/filen.lua @@ -1 +1 @@ -table.insert(_G.test_loadorder, "ordinary after") +table.insert(_G.test_loadorder, 'ordinary after') diff --git a/test/functional/fixtures/nvim/filen.lua b/test/functional/fixtures/nvim/filen.lua index e2bd5e8f7f..914e551c96 100644 --- a/test/functional/fixtures/nvim/filen.lua +++ b/test/functional/fixtures/nvim/filen.lua @@ -1 +1 @@ -table.insert(_G.test_loadorder, "ordinary") +table.insert(_G.test_loadorder, 'ordinary') diff --git a/test/functional/fixtures/pack/foo/opt/bonus/lua/bonus.lua b/test/functional/fixtures/pack/foo/opt/bonus/lua/bonus.lua index 52cb0bc118..2ceec737fd 100644 --- a/test/functional/fixtures/pack/foo/opt/bonus/lua/bonus.lua +++ b/test/functional/fixtures/pack/foo/opt/bonus/lua/bonus.lua @@ -1 +1,5 @@ -return {launch=function() return "CPE 1704 TKS" end} +return { + launch = function() + return 'CPE 1704 TKS' + end, +} diff --git a/test/functional/fixtures/pack/foo/opt/funky/filen.lua b/test/functional/fixtures/pack/foo/opt/funky/filen.lua index a33b83c2a7..de0a754f6c 100644 --- a/test/functional/fixtures/pack/foo/opt/funky/filen.lua +++ b/test/functional/fixtures/pack/foo/opt/funky/filen.lua @@ -1,10 +1,10 @@ -table.insert(_G.test_loadorder, "funky!") +table.insert(_G.test_loadorder, 'funky!') if not _G.nesty then _G.nesty = true local save_order = _G.test_loadorder _G.test_loadorder = {} - _G.vim.o.pp = "" -- funky! + _G.vim.o.pp = '' -- funky! vim.cmd [[runtime! filen.lua ]] _G.nested_order = _G.test_loadorder _G.test_loadorder = save_order diff --git a/test/functional/fixtures/pack/foo/opt/superspecial/after/filen.lua b/test/functional/fixtures/pack/foo/opt/superspecial/after/filen.lua index 94bf6850b2..c906250fc9 100644 --- a/test/functional/fixtures/pack/foo/opt/superspecial/after/filen.lua +++ b/test/functional/fixtures/pack/foo/opt/superspecial/after/filen.lua @@ -1 +1 @@ -table.insert(_G.test_loadorder, "SuperSpecial after") +table.insert(_G.test_loadorder, 'SuperSpecial after') diff --git a/test/functional/fixtures/pack/foo/opt/superspecial/filen.lua b/test/functional/fixtures/pack/foo/opt/superspecial/filen.lua index cbaab1a45a..0dcd7f90d5 100644 --- a/test/functional/fixtures/pack/foo/opt/superspecial/filen.lua +++ b/test/functional/fixtures/pack/foo/opt/superspecial/filen.lua @@ -1 +1 @@ -table.insert(_G.test_loadorder, "SuperSpecial") +table.insert(_G.test_loadorder, 'SuperSpecial') diff --git a/test/functional/fixtures/pack/foo/start/bar/lua/bar.lua b/test/functional/fixtures/pack/foo/start/bar/lua/bar.lua index a7e9a61e35..1413376e02 100644 --- a/test/functional/fixtures/pack/foo/start/bar/lua/bar.lua +++ b/test/functional/fixtures/pack/foo/start/bar/lua/bar.lua @@ -1 +1,5 @@ -return {doit=function() return 9003 end} +return { + doit = function() + return 9003 + end, +} diff --git a/test/functional/fixtures/pack/foo/start/bar/lua/baz-quux.lua b/test/functional/fixtures/pack/foo/start/bar/lua/baz-quux.lua index c1c33d787e..c4677adcaf 100644 --- a/test/functional/fixtures/pack/foo/start/bar/lua/baz-quux.lua +++ b/test/functional/fixtures/pack/foo/start/bar/lua/baz-quux.lua @@ -1 +1,5 @@ -return {doit=function() return 9004 end} +return { + doit = function() + return 9004 + end, +} diff --git a/test/functional/fixtures/pack/foo/start/fancyplugin/after/filen.lua b/test/functional/fixtures/pack/foo/start/fancyplugin/after/filen.lua index 9beac762ee..bfd837d703 100644 --- a/test/functional/fixtures/pack/foo/start/fancyplugin/after/filen.lua +++ b/test/functional/fixtures/pack/foo/start/fancyplugin/after/filen.lua @@ -1 +1 @@ -table.insert(_G.test_loadorder, "FANCY after") +table.insert(_G.test_loadorder, 'FANCY after') diff --git a/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_y.lua b/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_y.lua index 7daa7733a0..a11d74597c 100644 --- a/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_y.lua +++ b/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_y.lua @@ -1 +1 @@ -return "I am fancy_y.lua" +return 'I am fancy_y.lua' diff --git a/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_z.lua b/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_z.lua index 6e81afdd70..f360731c79 100644 --- a/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_z.lua +++ b/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_z.lua @@ -1 +1 @@ -return "I am fancy_z.lua" +return 'I am fancy_z.lua' diff --git a/test/functional/fixtures/pack/foo/start/fancyplugin/filen.lua b/test/functional/fixtures/pack/foo/start/fancyplugin/filen.lua index 34e4b9c95e..b354c5d8cd 100644 --- a/test/functional/fixtures/pack/foo/start/fancyplugin/filen.lua +++ b/test/functional/fixtures/pack/foo/start/fancyplugin/filen.lua @@ -1 +1 @@ -table.insert(_G.test_loadorder, "FANCY") +table.insert(_G.test_loadorder, 'FANCY') diff --git a/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x.lua b/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x.lua index 1b897a96cc..d96270f01e 100644 --- a/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x.lua +++ b/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x.lua @@ -1 +1 @@ -return "I am fancy_x.lua" +return 'I am fancy_x.lua' diff --git a/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x/init.lua b/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x/init.lua index 8c27a43cab..83874e194c 100644 --- a/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x/init.lua +++ b/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x/init.lua @@ -1 +1 @@ -return "I am init.lua of fancy_x!" +return 'I am init.lua of fancy_x!' diff --git a/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_y/init.lua b/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_y/init.lua index b66cbee4f6..a2dd2a9df0 100644 --- a/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_y/init.lua +++ b/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_y/init.lua @@ -1,2 +1 @@ - -return "I am init.lua of fancy_y!" +return 'I am init.lua of fancy_y!' diff --git a/test/functional/fixtures/start/nvim-leftpad/lua/async_leftpad.lua b/test/functional/fixtures/start/nvim-leftpad/lua/async_leftpad.lua index ffbd8a4f83..ee116d761a 100644 --- a/test/functional/fixtures/start/nvim-leftpad/lua/async_leftpad.lua +++ b/test/functional/fixtures/start/nvim-leftpad/lua/async_leftpad.lua @@ -1,5 +1,8 @@ -return function (val, res) +return function(val, res) local handle - handle = vim.uv.new_async(function() _G[res] = require'leftpad'(val) handle:close() end) + handle = vim.uv.new_async(function() + _G[res] = require 'leftpad'(val) + handle:close() + end) handle:send() end diff --git a/test/functional/fixtures/start/nvim-leftpad/lua/leftpad.lua b/test/functional/fixtures/start/nvim-leftpad/lua/leftpad.lua index 866ed2fd30..5deb505624 100644 --- a/test/functional/fixtures/start/nvim-leftpad/lua/leftpad.lua +++ b/test/functional/fixtures/start/nvim-leftpad/lua/leftpad.lua @@ -1 +1,3 @@ -return function (str) return '\t' .. str end +return function(str) + return '\t' .. str +end diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index dcaaa664b9..d1d26919a0 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -1,4 +1,4 @@ -local luv = require('luv') +local uv = vim.uv local global_helpers = require('test.helpers') local Session = require('test.client.session') @@ -10,65 +10,76 @@ local check_cores = global_helpers.check_cores local check_logs = global_helpers.check_logs local dedent = global_helpers.dedent local eq = global_helpers.eq -local filter = global_helpers.tbl_filter local is_os = global_helpers.is_os -local map = global_helpers.tbl_map local ok = global_helpers.ok -local sleep = global_helpers.sleep -local tbl_contains = global_helpers.tbl_contains +local sleep = uv.sleep local fail = global_helpers.fail local module = {} -local start_dir = luv.cwd() local runtime_set = 'set runtimepath^=./build/lib/nvim/' -module.nvim_prog = ( - os.getenv('NVIM_PRG') - or global_helpers.test_build_dir .. '/bin/nvim' -) +module.nvim_prog = (os.getenv('NVIM_PRG') or global_helpers.paths.test_build_dir .. '/bin/nvim') -- Default settings for the test session. module.nvim_set = ( - 'set shortmess+=IS background=light noswapfile noautoindent startofline' - ..' laststatus=1 undodir=. directory=. viewdir=. backupdir=.' - ..' belloff= wildoptions-=pum joinspaces noshowcmd noruler nomore redrawdebug=invalid') + 'set shortmess+=IS background=light termguicolors noswapfile noautoindent startofline' + .. ' laststatus=1 undodir=. directory=. viewdir=. backupdir=.' + .. ' belloff= wildoptions-=pum joinspaces noshowcmd noruler nomore redrawdebug=invalid' +) module.nvim_argv = { - module.nvim_prog, '-u', 'NONE', '-i', 'NONE', + module.nvim_prog, + '-u', + 'NONE', + '-i', + 'NONE', -- XXX: find treesitter parsers. - '--cmd', runtime_set, - '--cmd', module.nvim_set, - '--cmd', 'mapclear', - '--cmd', 'mapclear!', - '--embed'} + '--cmd', + runtime_set, + '--cmd', + module.nvim_set, + -- Remove default mappings. + '--cmd', + 'mapclear | mapclear!', + -- Make screentest work after changing to the new default color scheme + -- Source 'vim' color scheme without side effects + -- TODO: rewrite tests + '--cmd', + 'lua dofile("runtime/colors/vim.lua")', + '--cmd', + 'unlet g:colors_name', + '--embed', +} -- Directory containing nvim. -module.nvim_dir = module.nvim_prog:gsub("[/\\][^/\\]+$", "") +module.nvim_dir = module.nvim_prog:gsub('[/\\][^/\\]+$', '') if module.nvim_dir == module.nvim_prog then - module.nvim_dir = "." + module.nvim_dir = '.' end -local prepend_argv +local prepend_argv --- @type string[]? if os.getenv('VALGRIND') then local log_file = os.getenv('VALGRIND_LOG') or 'valgrind-%p.log' - prepend_argv = {'valgrind', '-q', '--tool=memcheck', - '--leak-check=yes', '--track-origins=yes', - '--show-possibly-lost=no', - '--suppressions=src/.valgrind.supp', - '--log-file='..log_file} + prepend_argv = { + 'valgrind', + '-q', + '--tool=memcheck', + '--leak-check=yes', + '--track-origins=yes', + '--show-possibly-lost=no', + '--suppressions=src/.valgrind.supp', + '--log-file=' .. log_file, + } if os.getenv('GDB') then table.insert(prepend_argv, '--vgdb=yes') table.insert(prepend_argv, '--vgdb-error=0') end elseif os.getenv('GDB') then - local gdbserver_port = '7777' - if os.getenv('GDBSERVER_PORT') then - gdbserver_port = os.getenv('GDBSERVER_PORT') - end - prepend_argv = {'gdbserver', 'localhost:'..gdbserver_port} + local gdbserver_port = os.getenv('GDBSERVER_PORT') or '7777' + prepend_argv = { 'gdbserver', 'localhost:' .. gdbserver_port } end if prepend_argv then - local new_nvim_argv = {} + local new_nvim_argv = {} --- @type string[] local len = #prepend_argv for i = 1, len do new_nvim_argv[i] = prepend_argv[i] @@ -80,12 +91,15 @@ if prepend_argv then module.prepend_argv = prepend_argv end -local session, loop_running, last_error, method_error +local session --- @type test.Session? +local loop_running --- @type boolean? +local last_error --- @type string? +local method_error --- @type string? if not is_os('win') then - local sigpipe_handler = luv.new_signal() - luv.signal_start(sigpipe_handler, "sigpipe", function() - print("warning: got SIGPIPE signal. Likely related to a crash in nvim") + local sigpipe_handler = assert(uv.new_signal()) + uv.signal_start(sigpipe_handler, 'sigpipe', function() + print('warning: got SIGPIPE signal. Likely related to a crash in nvim') end) end @@ -97,10 +111,15 @@ function module.set_session(s) session = s end +--- @param method string +--- @param ... any +--- @return any function module.request(method, ...) + assert(session) local status, rv = session:request(method, ...) if not status then if loop_running then + --- @type string last_error = rv[2] session:stop() else @@ -110,12 +129,18 @@ function module.request(method, ...) return rv end +--- @param method string +--- @param ... any +--- @return any function module.request_lua(method, ...) return module.exec_lua([[return vim.api[...](select(2, ...))]], method, ...) end +--- @param timeout? integer +--- @return string? function module.next_msg(timeout) - return session:next_message(timeout and timeout or 10000) + assert(session) + return session:next_message(timeout or 10000) end function module.expect_twostreams(msgs1, msgs2) @@ -149,15 +174,16 @@ function module.expect_msg_seq(...) error('need at least 1 argument') end local arg1 = select(1, ...) - if (arg1['seqs'] and select('#', ...) > 1) or type(arg1) ~= 'table' then + if (arg1['seqs'] and select('#', ...) > 1) or type(arg1) ~= 'table' then error('invalid args') end local ignore = arg1['ignore'] and arg1['ignore'] or {} - local seqs = arg1['seqs'] and arg1['seqs'] or {...} + --- @type string[] + local seqs = arg1['seqs'] and arg1['seqs'] or { ... } if type(ignore) ~= 'table' then error("'ignore' arg must be a list of strings") end - table.sort(seqs, function(a, b) -- Sort ascending, by (shallow) length. + table.sort(seqs, function(a, b) -- Sort ascending, by (shallow) length. return #a < #b end) @@ -170,7 +196,7 @@ function module.expect_msg_seq(...) end return string.format('%s\n%s\n%s', err1, string.rep('=', 78), err2) end - local msg_timeout = module.load_adjust(10000) -- Big timeout for ASAN/valgrind. + local msg_timeout = module.load_adjust(10000) -- Big timeout for ASAN/valgrind. for anum = 1, #seqs do local expected_seq = seqs[anum] -- Collect enough messages to compare the next expected sequence. @@ -178,10 +204,18 @@ function module.expect_msg_seq(...) local msg = module.next_msg(msg_timeout) local msg_type = msg and msg[2] or nil if msg == nil then - error(cat_err(final_error, - string.format('got %d messages (ignored %d), expected %d', - #actual_seq, nr_ignored, #expected_seq))) - elseif tbl_contains(ignore, msg_type) then + error( + cat_err( + final_error, + string.format( + 'got %d messages (ignored %d), expected %d', + #actual_seq, + nr_ignored, + #expected_seq + ) + ) + ) + elseif vim.tbl_contains(ignore, msg_type) then nr_ignored = nr_ignored + 1 else table.insert(actual_seq, msg) @@ -192,8 +226,9 @@ function module.expect_msg_seq(...) return result end local message = result - if type(result) == "table" then + if type(result) == 'table' then -- 'eq' returns several things + --- @type string message = result.message end final_error = cat_err(final_error, message) @@ -202,7 +237,7 @@ function module.expect_msg_seq(...) end local function call_and_stop_on_error(lsession, ...) - local status, result = Session.safe_pcall(...) -- luacheck: ignore + local status, result = Session.safe_pcall(...) -- luacheck: ignore if not status then lsession:stop() last_error = result @@ -215,8 +250,16 @@ function module.set_method_error(err) method_error = err end +--- @param lsession test.Session +--- @param request_cb function? +--- @param notification_cb function? +--- @param setup_cb function? +--- @param timeout integer +--- @return {[1]: integer, [2]: string} function module.run_session(lsession, request_cb, notification_cb, setup_cb, timeout) - local on_request, on_notification, on_setup + local on_request --- @type function? + local on_notification --- @type function? + local on_setup --- @type function? if request_cb then function on_request(method, args) @@ -254,29 +297,24 @@ function module.run_session(lsession, request_cb, notification_cb, setup_cb, tim end function module.run(request_cb, notification_cb, setup_cb, timeout) + assert(session) return module.run_session(session, request_cb, notification_cb, setup_cb, timeout) end function module.stop() - session:stop() + assert(session):stop() end function module.nvim_prog_abs() -- system(['build/bin/nvim']) does not work for whatever reason. It must -- be executable searched in $PATH or something starting with / or ./. if module.nvim_prog:match('[/\\]') then - return module.request('nvim_call_function', 'fnamemodify', {module.nvim_prog, ':p'}) + return module.request('nvim_call_function', 'fnamemodify', { module.nvim_prog, ':p' }) else return module.nvim_prog end end --- Executes an ex-command. Vimscript errors manifest as client (lua) errors, but --- v:errmsg will not be updated. -function module.command(cmd) - module.request('nvim_command', cmd) -end - -- Use for commands which expect nvim to quit. -- The first argument can also be a timeout. function module.expect_exit(fn_or_timeout, ...) @@ -284,37 +322,33 @@ function module.expect_exit(fn_or_timeout, ...) if type(fn_or_timeout) == 'function' then eq(eof_err_msg, module.pcall_err(fn_or_timeout, ...)) else - eq(eof_err_msg, module.pcall_err(function(timeout, fn, ...) - fn(...) - while session:next_message(timeout) do - end - if session.eof_err then - error(session.eof_err[2]) - end - end, fn_or_timeout, ...)) + eq( + eof_err_msg, + module.pcall_err(function(timeout, fn, ...) + fn(...) + assert(session) + while session:next_message(timeout) do + end + if session.eof_err then + error(session.eof_err[2]) + end + end, fn_or_timeout, ...) + ) end end --- Evaluates a Vimscript expression. --- Fails on Vimscript error, but does not update v:errmsg. -function module.eval(expr) - return module.request('nvim_eval', expr) -end - --- Executes a Vimscript function via RPC. --- Fails on Vimscript error, but does not update v:errmsg. -function module.call(name, ...) - return module.request('nvim_call_function', name, {...}) -end - --- Executes a Vimscript function via Lua. --- Fails on Vimscript error, but does not update v:errmsg. +--- Executes a Vimscript function via Lua. +--- Fails on Vimscript error, but does not update v:errmsg. +--- @param name string +--- @param ... any +--- @return any function module.call_lua(name, ...) return module.exec_lua([[return vim.call(...)]], name, ...) end --- Sends user input to Nvim. --- Does not fail on Vimscript error, but v:errmsg will be updated. +--- Sends user input to Nvim. +--- Does not fail on Vimscript error, but v:errmsg will be updated. +--- @param input string local function nvim_feed(input) while #input > 0 do local written = module.request('nvim_input', input) @@ -326,22 +360,27 @@ local function nvim_feed(input) end end +--- @param ... string function module.feed(...) - for _, v in ipairs({...}) do + for _, v in ipairs({ ... }) do nvim_feed(dedent(v)) end end +--- @param ... string function module.rawfeed(...) - for _, v in ipairs({...}) do + for _, v in ipairs({ ... }) do nvim_feed(dedent(v)) end end +---@param ... string[]? +---@return string[] function module.merge_args(...) local i = 1 - local argv = {} - for anum = 1,select('#', ...) do + local argv = {} --- @type string[] + for anum = 1, select('#', ...) do + --- @type string[]? local args = select(anum, ...) if args then for _, arg in ipairs(args) do @@ -353,41 +392,44 @@ function module.merge_args(...) return argv end --- Removes Nvim startup args from `args` matching items in `args_rm`. --- --- - Special case: "-u", "-i", "--cmd" are treated specially: their "values" are also removed. --- - Special case: "runtimepath" will remove only { '--cmd', 'set runtimepath^=…', } --- --- Example: --- args={'--headless', '-u', 'NONE'} --- args_rm={'--cmd', '-u'} --- Result: --- {'--headless'} --- --- All matching cases are removed. --- --- Example: --- args={'--cmd', 'foo', '-N', '--cmd', 'bar'} --- args_rm={'--cmd', '-u'} --- Result: --- {'-N'} +--- Removes Nvim startup args from `args` matching items in `args_rm`. +--- +--- - Special case: "-u", "-i", "--cmd" are treated specially: their "values" are also removed. +--- - Special case: "runtimepath" will remove only { '--cmd', 'set runtimepath^=…', } +--- +--- Example: +--- args={'--headless', '-u', 'NONE'} +--- args_rm={'--cmd', '-u'} +--- Result: +--- {'--headless'} +--- +--- All matching cases are removed. +--- +--- Example: +--- args={'--cmd', 'foo', '-N', '--cmd', 'bar'} +--- args_rm={'--cmd', '-u'} +--- Result: +--- {'-N'} +--- @param args string[] +--- @param args_rm string[] +--- @return string[] local function remove_args(args, args_rm) - local new_args = {} - local skip_following = {'-u', '-i', '-c', '--cmd', '-s', '--listen'} + local new_args = {} --- @type string[] + local skip_following = { '-u', '-i', '-c', '--cmd', '-s', '--listen' } if not args_rm or #args_rm == 0 then - return {unpack(args)} + return { unpack(args) } end for _, v in ipairs(args_rm) do assert(type(v) == 'string') end local last = '' for _, arg in ipairs(args) do - if tbl_contains(skip_following, last) then + if vim.tbl_contains(skip_following, last) then last = '' - elseif tbl_contains(args_rm, arg) then + elseif vim.tbl_contains(args_rm, arg) then last = arg - elseif arg == runtime_set and tbl_contains(args_rm, 'runtimepath') then - table.remove(new_args) -- Remove the preceding "--cmd". + elseif arg == runtime_set and vim.tbl_contains(args_rm, 'runtimepath') then + table.remove(new_args) -- Remove the preceding "--cmd". last = '' else table.insert(new_args, arg) @@ -400,40 +442,48 @@ function module.check_close() if not session then return end - local start_time = luv.now() + local start_time = uv.now() session:close() - luv.update_time() -- Update cached value of luv.now() (libuv: uv_now()). - local end_time = luv.now() + uv.update_time() -- Update cached value of luv.now() (libuv: uv_now()). + local end_time = uv.now() local delta = end_time - start_time if delta > 500 then - print("nvim took " .. delta .. " milliseconds to exit after last test\n".. - "This indicates a likely problem with the test even if it passed!\n") + print( + 'nvim took ' + .. delta + .. ' milliseconds to exit after last test\n' + .. 'This indicates a likely problem with the test even if it passed!\n' + ) io.stdout:flush() end session = nil end ---- @param io_extra used for stdin_fd, see :help ui-option +--- @param argv string[] +--- @param merge boolean? +--- @param env string[]? +--- @param keep boolean +--- @param io_extra uv.uv_pipe_t? used for stdin_fd, see :help ui-option +--- @return test.Session function module.spawn(argv, merge, env, keep, io_extra) if not keep then module.check_close() end - local child_stream = ChildProcessStream.spawn( - merge and module.merge_args(prepend_argv, argv) or argv, - env, io_extra) + local child_stream = + ChildProcessStream.spawn(merge and module.merge_args(prepend_argv, argv) or argv, env, io_extra) return Session.new(child_stream) end -- Creates a new Session connected by domain socket (named pipe) or TCP. function module.connect(file_or_address) - local addr, port = string.match(file_or_address, "(.*):(%d+)") - local stream = (addr and port) and SocketStream.connect(addr, port) or - SocketStream.open(file_or_address) + local addr, port = string.match(file_or_address, '(.*):(%d+)') + local stream = (addr and port) and SocketStream.connect(addr, port) + or SocketStream.open(file_or_address) return Session.new(stream) end --- Starts a new global Nvim session. +-- Starts (and returns) a new global Nvim session. -- -- Parameters are interpreted as startup args, OR a map with these keys: -- args: List: Args appended to the default `nvim_argv` set. @@ -447,36 +497,49 @@ end -- clear{args={'-e'}, args_rm={'-i'}, env={TERM=term}} function module.clear(...) module.set_session(module.spawn_argv(false, ...)) + return module.get_session() end --- same params as clear, but does returns the session instead --- of replacing the default session +--- same params as clear, but does returns the session instead +--- of replacing the default session +--- @return test.Session function module.spawn_argv(keep, ...) local argv, env, io_extra = module.new_argv(...) return module.spawn(argv, nil, env, keep, io_extra) end --- Builds an argument list for use in clear(). --- ----@see clear() for parameters. +--- @class test.new_argv.Opts +--- @field args? string[] +--- @field args_rm? string[] +--- @field env? table<string,string> +--- @field io_extra? uv.uv_pipe_t + +--- Builds an argument list for use in clear(). +--- +--- @see clear() for parameters. +--- @param ... string +--- @return string[] +--- @return string[]? +--- @return uv.uv_pipe_t? function module.new_argv(...) - local args = {unpack(module.nvim_argv)} + local args = { unpack(module.nvim_argv) } table.insert(args, '--headless') if _G._nvim_test_id then -- Set the server name to the test-id for logging. #8519 table.insert(args, '--listen') table.insert(args, _G._nvim_test_id) end - local new_args - local io_extra - local env = nil + local new_args --- @type string[] + local io_extra --- @type uv.uv_pipe_t? + local env --- @type string[]? + --- @type test.new_argv.Opts|string local opts = select(1, ...) if type(opts) ~= 'table' then - new_args = {...} + new_args = { ... } else args = remove_args(args, opts.args_rm) if opts.env then - local env_opt = {} + local env_opt = {} --- @type table<string,string> for k, v in pairs(opts.env) do assert(type(k) == 'string') assert(type(v) == 'string') @@ -515,19 +578,21 @@ function module.new_argv(...) return args, env, io_extra end +--- @param ... string function module.insert(...) nvim_feed('i') - for _, v in ipairs({...}) do + for _, v in ipairs({ ... }) do local escaped = v:gsub('<', '<lt>') module.rawfeed(escaped) end nvim_feed('<ESC>') end --- Executes an ex-command by user input. Because nvim_input() is used, Vimscript --- errors will not manifest as client (lua) errors. Use command() for that. +--- Executes an ex-command by user input. Because nvim_input() is used, Vimscript +--- errors will not manifest as client (lua) errors. Use command() for that. +--- @param ... string function module.feed_command(...) - for _, v in ipairs({...}) do + for _, v in ipairs({ ... }) do if v:sub(1, 1) ~= '/' then -- not a search command, prefix with colon nvim_feed(':') @@ -543,7 +608,7 @@ function module.source(code) end function module.has_powershell() - return module.eval('executable("'..(is_os('win') and 'powershell' or 'pwsh')..'")') == 1 + return module.eval('executable("' .. (is_os('win') and 'powershell' or 'pwsh') .. '")') == 1 end --- Sets Nvim shell to powershell. @@ -557,102 +622,68 @@ function module.set_shell_powershell(fake) assert(found) end local shell = found and (is_os('win') and 'powershell' or 'pwsh') or module.testprg('pwsh-test') - local cmd = 'Remove-Item -Force '..table.concat(is_os('win') - and {'alias:cat', 'alias:echo', 'alias:sleep', 'alias:sort', 'alias:tee'} - or {'alias:echo'}, ',')..';' + local cmd = 'Remove-Item -Force ' + .. table.concat( + is_os('win') and { 'alias:cat', 'alias:echo', 'alias:sleep', 'alias:sort', 'alias:tee' } + or { 'alias:echo' }, + ',' + ) + .. ';' module.exec([[ - let &shell = ']]..shell..[[' + let &shell = ']] .. shell .. [[' set shellquote= shellxquote= let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command ' let &shellcmdflag .= '[Console]::InputEncoding=[Console]::OutputEncoding=[System.Text.UTF8Encoding]::new();' let &shellcmdflag .= '$PSDefaultParameterValues[''Out-File:Encoding'']=''utf8'';' - let &shellcmdflag .= ']]..cmd..[[' + let &shellcmdflag .= ']] .. cmd .. [[' let &shellredir = '2>&1 | %%{ "$_" } | Out-File %s; exit $LastExitCode' let &shellpipe = '2>&1 | %%{ "$_" } | tee %s; exit $LastExitCode' ]]) return found end +---@param func function +---@return table<string,function> function module.create_callindex(func) - local table = {} - setmetatable(table, { + return setmetatable({}, { + --- @param tbl table<any,function> + --- @param arg1 string + --- @return function __index = function(tbl, arg1) - local ret = function(...) return func(arg1, ...) end + local ret = function(...) + return func(arg1, ...) + end tbl[arg1] = ret return ret end, }) - return table end -local function ui(method, ...) - return module.request('nvim_ui_'..method, ...) +--- @param method string +--- @param ... any +function module.nvim_async(method, ...) + assert(session):notify(method, ...) end -function module.nvim_async(method, ...) - session:notify('nvim_'..method, ...) +--- Executes a Vimscript function via RPC. +--- Fails on Vimscript error, but does not update v:errmsg. +--- @param name string +--- @param ... any +--- @return any +function module.call(name, ...) + return module.request('nvim_call_function', name, { ... }) end module.async_meths = module.create_callindex(module.nvim_async) -module.uimeths = module.create_callindex(ui) - -local function create_api(request, call) - local m = {} - function m.nvim(method, ...) - return request('nvim_'..method, ...) - end - - function m.buffer(method, ...) - return request('nvim_buf_'..method, ...) - end - - function m.window(method, ...) - return request('nvim_win_'..method, ...) - end - - function m.tabpage(method, ...) - return request('nvim_tabpage_'..method, ...) - end - - function m.curbuf(method, ...) - if not method then - return m.nvim('get_current_buf') - end - return m.buffer(method, 0, ...) - end - - function m.curwin(method, ...) - if not method then - return m.nvim('get_current_win') - end - return m.window(method, 0, ...) - end - - function m.curtab(method, ...) - if not method then - return m.nvim('get_current_tabpage') - end - return m.tabpage(method, 0, ...) - end - - m.funcs = module.create_callindex(call) - m.meths = module.create_callindex(m.nvim) - m.bufmeths = module.create_callindex(m.buffer) - m.winmeths = module.create_callindex(m.window) - m.tabmeths = module.create_callindex(m.tabpage) - m.curbufmeths = module.create_callindex(m.curbuf) - m.curwinmeths = module.create_callindex(m.curwin) - m.curtabmeths = module.create_callindex(m.curtab) - - return m -end module.rpc = { - api = create_api(module.request, module.call), + fn = module.create_callindex(module.call), + api = module.create_callindex(module.request), } module.lua = { - api = create_api(module.request_lua, module.call_lua), + fn = module.create_callindex(module.call_lua), + api = module.create_callindex(module.request_lua), } module.describe_lua_and_rpc = function(describe) @@ -668,24 +699,37 @@ module.describe_lua_and_rpc = function(describe) end end -for name, fn in pairs(module.rpc.api) do - module[name] = fn +--- add for typing. The for loop after will overwrite this +module.api = vim.api +module.fn = vim.fn + +for name, fns in pairs(module.rpc) do + --- @diagnostic disable-next-line:no-unknown + module[name] = fns end +-- Executes an ex-command. Vimscript errors manifest as client (lua) errors, but +-- v:errmsg will not be updated. +module.command = module.api.nvim_command + +-- Evaluates a Vimscript expression. +-- Fails on Vimscript error, but does not update v:errmsg. +module.eval = module.api.nvim_eval + function module.poke_eventloop() -- Execute 'nvim_eval' (a deferred function) to -- force at least one main_loop iteration - session:request('nvim_eval', '1') + module.api.nvim_eval('1') end function module.buf_lines(bufnr) - return module.exec_lua("return vim.api.nvim_buf_get_lines((...), 0, -1, false)", bufnr) + return module.exec_lua('return vim.api.nvim_buf_get_lines((...), 0, -1, false)', bufnr) end ---@see buf_lines() function module.curbuf_contents() - module.poke_eventloop() -- Before inspecting the buffer, do whatever. - return table.concat(module.curbuf('get_lines', 0, -1, true), '\n') + module.poke_eventloop() -- Before inspecting the buffer, do whatever. + return table.concat(module.api.nvim_buf_get_lines(0, 0, -1, true), '\n') end function module.expect(contents) @@ -697,18 +741,21 @@ function module.expect_any(contents) return ok(nil ~= string.find(module.curbuf_contents(), contents, 1, true)) end +--- @param expected any[] +--- @param received any[] +--- @param kind string +--- @return any function module.expect_events(expected, received, kind) - local inspect = require'vim.inspect' if not pcall(eq, expected, received) then - local msg = 'unexpected '..kind..' received.\n\n' + local msg = 'unexpected ' .. kind .. ' received.\n\n' msg = msg .. 'received events:\n' for _, e in ipairs(received) do - msg = msg .. ' ' .. inspect(e) .. ';\n' + msg = msg .. ' ' .. vim.inspect(e) .. ';\n' end msg = msg .. '\nexpected events:\n' for _, e in ipairs(expected) do - msg = msg .. ' ' .. inspect(e) .. ';\n' + msg = msg .. ' ' .. vim.inspect(e) .. ';\n' end fail(msg) end @@ -723,18 +770,23 @@ end -- Asserts that buffer is loaded and visible in the current tabpage. function module.assert_visible(bufnr, visible) assert(type(visible) == 'boolean') - eq(visible, module.bufmeths.is_loaded(bufnr)) + eq(visible, module.api.nvim_buf_is_loaded(bufnr)) if visible then - assert(-1 ~= module.funcs.bufwinnr(bufnr), - 'expected buffer to be visible in current tabpage: '..tostring(bufnr)) + assert( + -1 ~= module.fn.bufwinnr(bufnr), + 'expected buffer to be visible in current tabpage: ' .. tostring(bufnr) + ) else - assert(-1 == module.funcs.bufwinnr(bufnr), - 'expected buffer NOT visible in current tabpage: '..tostring(bufnr)) + assert( + -1 == module.fn.bufwinnr(bufnr), + 'expected buffer NOT visible in current tabpage: ' .. tostring(bufnr) + ) end end +--- @param path string local function do_rmdir(path) - local stat = luv.fs_stat(path) + local stat = uv.fs_stat(path) if stat == nil then return end @@ -743,44 +795,45 @@ local function do_rmdir(path) end for file in vim.fs.dir(path) do if file ~= '.' and file ~= '..' then - local abspath = path..'/'..file + local abspath = path .. '/' .. file if global_helpers.isdir(abspath) then - do_rmdir(abspath) -- recurse + do_rmdir(abspath) -- recurse else local ret, err = os.remove(abspath) if not ret then if not session then - error('os.remove: '..err) + error('os.remove: ' .. err) else -- Try Nvim delete(): it handles `readonly` attribute on Windows, -- and avoids Lua cross-version/platform incompatibilities. if -1 == module.call('delete', abspath) then - local hint = (is_os('win') - and ' (hint: try :%bwipeout! before rmdir())' or '') - error('delete() failed'..hint..': '..abspath) + local hint = (is_os('win') and ' (hint: try :%bwipeout! before rmdir())' or '') + error('delete() failed' .. hint .. ': ' .. abspath) end end end end end end - local ret, err = luv.fs_rmdir(path) + local ret, err = uv.fs_rmdir(path) if not ret then - error('luv.fs_rmdir('..path..'): '..err) + error('luv.fs_rmdir(' .. path .. '): ' .. err) end end +local start_dir = uv.cwd() + function module.rmdir(path) local ret, _ = pcall(do_rmdir, path) if not ret and is_os('win') then -- Maybe "Permission denied"; try again after changing the nvim -- process to the top-level directory. - module.command([[exe 'cd '.fnameescape(']]..start_dir.."')") + module.command([[exe 'cd '.fnameescape(']] .. start_dir .. "')") ret, _ = pcall(do_rmdir, path) end -- During teardown, the nvim process may not exit quickly enough, then rmdir() -- will fail (on Windows). - if not ret then -- Try again. + if not ret then -- Try again. sleep(1000) do_rmdir(path) end @@ -799,44 +852,49 @@ function module.exc_exec(cmd) return ret end +--- @param cond boolean +--- @param reason string +--- @return boolean function module.skip(cond, reason) if cond then + --- @type fun(reason: string) local pending = getfenv(2).pending pending(reason or 'FIXME') return true - else - return false end + return false end -- Calls pending() and returns `true` if the system is too slow to -- run fragile or expensive tests. Else returns `false`. function module.skip_fragile(pending_fn, cond) - if pending_fn == nil or type(pending_fn) ~= type(function()end) then - error("invalid pending_fn") + if pending_fn == nil or type(pending_fn) ~= type(function() end) then + error('invalid pending_fn') end if cond then - pending_fn("skipped (test is fragile on this system)", function() end) + pending_fn('skipped (test is fragile on this system)', function() end) return true - elseif os.getenv("TEST_SKIP_FRAGILE") then - pending_fn("skipped (TEST_SKIP_FRAGILE)", function() end) + elseif os.getenv('TEST_SKIP_FRAGILE') then + pending_fn('skipped (TEST_SKIP_FRAGILE)', function() end) return true end return false end function module.exec(code) - module.meths.exec2(code, {}) + module.api.nvim_exec2(code, {}) end +--- @param code string +--- @return string function module.exec_capture(code) - return module.meths.exec2(code, { output = true }).output + return module.api.nvim_exec2(code, { output = true }).output end --- @param code string --- @return any function module.exec_lua(code, ...) - return module.meths.exec_lua(code, {...}) + return module.api.nvim_exec_lua(code, { ... }) end function module.get_pathsep() @@ -845,8 +903,8 @@ end --- Gets the filesystem root dir, namely "/" or "C:/". function module.pathroot() - local pathsep = package.config:sub(1,1) - return is_os('win') and (module.nvim_dir:sub(1,2)..pathsep) or '/' + local pathsep = package.config:sub(1, 1) + return is_os('win') and (module.nvim_dir:sub(1, 2) .. pathsep) or '/' end --- Gets the full `…/build/bin/{name}` path of a test program produced by @@ -868,26 +926,32 @@ end function module.new_pipename() -- HACK: Start a server temporarily, get the name, then stop it. local pipename = module.eval('serverstart()') - module.funcs.serverstop(pipename) + module.fn.serverstop(pipename) -- Remove the pipe so that trying to connect to it without a server listening -- will be an error instead of a hang. os.remove(pipename) return pipename end +--- @param provider string +--- @return string|boolean? function module.missing_provider(provider) - if provider == 'ruby' or provider == 'node' or provider == 'perl' then - local e = module.funcs['provider#'..provider..'#Detect']()[2] + if provider == 'ruby' or provider == 'perl' then + --- @type string? + local e = module.exec_lua("return {require('vim.provider." .. provider .. "').detect()}")[2] return e ~= '' and e or false - elseif provider == 'python' or provider == 'python3' then - local py_major_version = (provider == 'python3' and 3 or 2) - local e = module.funcs['provider#pythonx#Detect'](py_major_version)[2] + elseif provider == 'node' then + --- @type string? + local e = module.fn['provider#node#Detect']()[2] return e ~= '' and e or false - else - assert(false, 'Unknown provider: '..provider) + elseif provider == 'python' then + return module.exec_lua([[return {require('vim.provider.python').detect_by_module('neovim')}]])[2] end + assert(false, 'Unknown provider: ' .. provider) end +--- @param obj string|table +--- @return any function module.alter_slashes(obj) if not is_os('win') then return obj @@ -896,14 +960,14 @@ function module.alter_slashes(obj) local ret = obj:gsub('/', '\\') return ret elseif type(obj) == 'table' then - local ret = {} + --- @cast obj table<any,any> + local ret = {} --- @type table<any,any> for k, v in pairs(obj) do ret[k] = module.alter_slashes(v) end return ret - else - assert(false, 'expected string or table of strings, got '..type(obj)) end + assert(false, 'expected string or table of strings, got ' .. type(obj)) end local load_factor = 1 @@ -913,19 +977,26 @@ if global_helpers.is_ci() then module.request('nvim_command', 'source test/old/testdir/load.vim') load_factor = module.request('nvim_eval', 'g:test_load_factor') end + +--- @param num number +--- @return number function module.load_adjust(num) return math.ceil(num * load_factor) end +--- @param ctx table<string,any> +--- @return table function module.parse_context(ctx) - local parsed = {} - for _, item in ipairs({'regs', 'jumps', 'bufs', 'gvars'}) do - parsed[item] = filter(function(v) + local parsed = {} --- @type table<string,any> + for _, item in ipairs({ 'regs', 'jumps', 'bufs', 'gvars' }) do + --- @param v any + parsed[item] = vim.tbl_filter(function(v) return type(v) == 'table' end, module.call('msgpackparse', ctx[item])) end parsed['bufs'] = parsed['bufs'][1] - return map(function(v) + --- @param v any + return vim.tbl_map(function(v) if #v == 0 then return nil end @@ -935,25 +1006,30 @@ end function module.add_builddir_to_rtp() -- Add runtime from build dir for doc/tags (used with :help). - module.command(string.format([[set rtp+=%s/runtime]], module.test_build_dir)) + module.command(string.format([[set rtp+=%s/runtime]], module.paths.test_build_dir)) end --- Kill process with given pid +--- Kill (reap) a process by PID. +--- @param pid string +--- @return boolean? function module.os_kill(pid) - return os.execute((is_os('win') - and 'taskkill /f /t /pid '..pid..' > nul' - or 'kill -9 '..pid..' > /dev/null')) + return os.execute( + ( + is_os('win') and 'taskkill /f /t /pid ' .. pid .. ' > nul' + or 'kill -9 ' .. pid .. ' > /dev/null' + ) + ) end --- Create folder with non existing parents +--- Create folder with non existing parents +--- @param path string +--- @return boolean? function module.mkdir_p(path) - return os.execute((is_os('win') - and 'mkdir '..path - or 'mkdir -p '..path)) + return os.execute((is_os('win') and 'mkdir ' .. path or 'mkdir -p ' .. path)) end --- @class test.functional.helpers: test.helpers -module = global_helpers.tbl_extend('error', module, global_helpers) +module = vim.tbl_extend('error', module, global_helpers) --- @return test.functional.helpers return function(after_each) @@ -964,7 +1040,7 @@ return function(after_each) if session then local msg = session:next_message(0) if msg then - if msg[1] == "notification" and msg[2] == "nvim_error_event" then + if msg[1] == 'notification' and msg[2] == 'nvim_error_event' then error(msg[3][2]) end end diff --git a/test/functional/legacy/008_autocommands_spec.lua b/test/functional/legacy/008_autocommands_spec.lua index 4088cd1644..16f0216bc0 100644 --- a/test/functional/legacy/008_autocommands_spec.lua +++ b/test/functional/legacy/008_autocommands_spec.lua @@ -3,7 +3,8 @@ local helpers = require('test.functional.helpers')(after_each) local source = helpers.source -local clear, command, expect, eq, eval = helpers.clear, helpers.command, helpers.expect, helpers.eq, helpers.eval +local clear, command, expect, eq, eval = + helpers.clear, helpers.command, helpers.expect, helpers.eq, helpers.eval local write_file, dedent = helpers.write_file, helpers.dedent local read_file = helpers.read_file local expect_exit = helpers.expect_exit @@ -16,8 +17,8 @@ describe('autocommands that delete and unload buffers:', function() end of Xxx]]) local text2 = text1:gsub('1', '2') setup(function() - write_file('Xxx1', text1..'\n') - write_file('Xxx2', text2..'\n') + write_file('Xxx1', text1 .. '\n') + write_file('Xxx2', text2 .. '\n') end) teardown(function() os.remove(test_file) @@ -36,8 +37,7 @@ describe('autocommands that delete and unload buffers:', function() -- The legacy test file did not check the error message. command('let v:errmsg = "no error"') command('silent! write') - eq('E203: Autocommands deleted or unloaded buffer to be written', - eval('v:errmsg')) + eq('E203: Autocommands deleted or unloaded buffer to be written', eval('v:errmsg')) eq('Xxx2', eval('bufname("%")')) expect(text2) -- Start editing Xxx2. @@ -46,8 +46,7 @@ describe('autocommands that delete and unload buffers:', function() command('let v:errmsg = "no error"') -- Write Xxx2, will delete the buffer and give an error msg. command('silent! write') - eq('E203: Autocommands deleted or unloaded buffer to be written', - eval('v:errmsg')) + eq('E203: Autocommands deleted or unloaded buffer to be written', eval('v:errmsg')) eq('Xxx1', eval('bufname("%")')) expect(text1) end) @@ -63,7 +62,7 @@ describe('autocommands that delete and unload buffers:', function() endwhile endfunc func WriteToOut() - edit! ]]..test_file..[[ + edit! ]] .. test_file .. [[ $put ='VimLeave done' write @@ -80,7 +79,6 @@ describe('autocommands that delete and unload buffers:', function() command('silent! edit Makefile') -- an existing file command('silent! split new2') expect_exit(command, 'silent! quit') - eq('VimLeave done', - string.match(read_file(test_file), "^%s*(.-)%s*$")) + eq('VimLeave done', string.match(read_file(test_file), '^%s*(.-)%s*$')) end) end) diff --git a/test/functional/legacy/011_autocommands_spec.lua b/test/functional/legacy/011_autocommands_spec.lua index 5b6d030567..eba878b99a 100644 --- a/test/functional/legacy/011_autocommands_spec.lua +++ b/test/functional/legacy/011_autocommands_spec.lua @@ -12,11 +12,16 @@ -- Use a FileChangedShell autocommand to avoid a prompt for "Xtestfile.gz" -- being modified outside of Vim (noticed on Solaris). -local helpers= require('test.functional.helpers')(after_each) -local luv = require('luv') +local helpers = require('test.functional.helpers')(after_each) local clear, feed_command, expect, eq, neq, dedent, write_file, feed = - helpers.clear, helpers.feed_command, helpers.expect, helpers.eq, helpers.neq, - helpers.dedent, helpers.write_file, helpers.feed + helpers.clear, + helpers.feed_command, + helpers.expect, + helpers.eq, + helpers.neq, + helpers.dedent, + helpers.write_file, + helpers.feed local command = helpers.command local read_file = helpers.read_file local is_os = helpers.is_os @@ -27,12 +32,12 @@ local function has_gzip() end local function prepare_gz_file(name, text) - write_file(name, text..'\n') + write_file(name, text .. '\n') -- Compress the file with gzip. - command([[call system(['gzip', '--force', ']]..name..[['])]]) + command([[call system(['gzip', '--force', ']] .. name .. [['])]]) -- This should create the .gz file and delete the original. - neq(nil, luv.fs_stat(name..'.gz')) - eq(nil, luv.fs_stat(name)) + neq(nil, vim.uv.fs_stat(name .. '.gz')) + eq(nil, vim.uv.fs_stat(name)) end describe('file reading, writing and bufnew and filter autocommands', function() @@ -49,14 +54,17 @@ describe('file reading, writing and bufnew and filter autocommands', function() line 10 Abcdefghijklmnopqrstuvwxyz end of testfile]]) setup(function() - write_file('Xtest.c', [[ + write_file( + 'Xtest.c', + [[ /* * Here is a new .c file */ - ]]) + ]] + ) end) - before_each(function () - clear({env={GZIP=nil}}) + before_each(function() + clear({ env = { GZIP = nil } }) end) teardown(function() os.remove('Xtestfile.gz') @@ -67,7 +75,6 @@ describe('file reading, writing and bufnew and filter autocommands', function() if not has_gzip() then pending('skipped (missing `gzip` utility)', function() end) else - it('FileReadPost (using gzip)', function() prepare_gz_file('Xtestfile', text1) --execute('au FileChangedShell * echo "caught FileChangedShell"') @@ -75,7 +82,7 @@ describe('file reading, writing and bufnew and filter autocommands', function() feed_command("au FileReadPost *.gz '[,']!gzip -d") -- Read and decompress the testfile. feed_command('$r Xtestfile.gz') - expect('\n'..text1) + expect('\n' .. text1) end) it('BufReadPre, BufReadPost (using gzip)', function() @@ -100,7 +107,9 @@ describe('file reading, writing and bufnew and filter autocommands', function() -- luacheck: ignore 611 (Line contains only whitespaces) it('FileReadPre, FileReadPost', function() prepare_gz_file('Xtestfile', text1) - feed_command('au! FileReadPre *.gz exe "silent !gzip -d " . shellescape(expand("<afile>"))') + feed_command( + 'au! FileReadPre *.gz exe "silent !gzip -d " . shellescape(expand("<afile>"))' + ) feed_command('au FileReadPre *.gz call rename(expand("<afile>:r"), expand("<afile>"))') feed_command("au! FileReadPost *.gz '[,']s/l/L/") -- Read compressed file. @@ -121,7 +130,6 @@ describe('file reading, writing and bufnew and filter autocommands', function() Line 10 Abcdefghijklmnopqrstuvwxyz end of testfiLe]]) end) - end it('FileAppendPre, FileAppendPost', function() @@ -169,9 +177,15 @@ describe('file reading, writing and bufnew and filter autocommands', function() */]])) -- Need temp files here. feed_command('set shelltemp') - feed_command('au FilterReadPre *.out call rename(expand("<afile>"), expand("<afile>") . ".t")') - feed_command('au FilterReadPre *.out exe "silent !sed s/e/E/ " . shellescape(expand("<afile>")) . ".t >" . shellescape(expand("<afile>"))') - feed_command('au FilterReadPre *.out exe "silent !rm " . shellescape(expand("<afile>")) . ".t"') + feed_command( + 'au FilterReadPre *.out call rename(expand("<afile>"), expand("<afile>") . ".t")' + ) + feed_command( + 'au FilterReadPre *.out exe "silent !sed s/e/E/ " . shellescape(expand("<afile>")) . ".t >" . shellescape(expand("<afile>"))' + ) + feed_command( + 'au FilterReadPre *.out exe "silent !rm " . shellescape(expand("<afile>")) . ".t"' + ) feed_command("au FilterReadPost *.out '[,']s/x/X/g") -- Edit the output file. feed_command('e! test.out') diff --git a/test/functional/legacy/012_directory_spec.lua b/test/functional/legacy/012_directory_spec.lua index 25d0dcb81e..b428318e3f 100644 --- a/test/functional/legacy/012_directory_spec.lua +++ b/test/functional/legacy/012_directory_spec.lua @@ -4,13 +4,12 @@ -- - "dir", in directory relative to current dir local helpers = require('test.functional.helpers')(after_each) -local luv = require('luv') local eq = helpers.eq local neq = helpers.neq local poke_eventloop = helpers.poke_eventloop -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local clear = helpers.clear local insert = helpers.insert local command = helpers.command @@ -21,7 +20,7 @@ local mkdir = helpers.mkdir local function ls_dir_sorted(dirname) local files = {} for f in vim.fs.dir(dirname) do - if f ~= "." and f~= ".." then + if f ~= '.' and f ~= '..' then table.insert(files, f) end end @@ -57,36 +56,36 @@ describe("'directory' option", function() line 3 Abcdefghij end of testfile]]) - meths.set_option_value('swapfile', true, {}) - meths.set_option_value('swapfile', true, {}) - meths.set_option_value('directory', '.', {}) + api.nvim_set_option_value('swapfile', true, {}) + api.nvim_set_option_value('swapfile', true, {}) + api.nvim_set_option_value('directory', '.', {}) -- sanity check: files should not exist yet. - eq(nil, luv.fs_stat('.Xtest1.swp')) + eq(nil, vim.uv.fs_stat('.Xtest1.swp')) command('edit! Xtest1') poke_eventloop() - eq('Xtest1', funcs.buffer_name('%')) + eq('Xtest1', fn.buffer_name('%')) -- Verify that the swapfile exists. In the legacy test this was done by -- reading the output from :!ls. - neq(nil, luv.fs_stat('.Xtest1.swp')) + neq(nil, vim.uv.fs_stat('.Xtest1.swp')) - meths.set_option_value('directory', './Xtest2,.', {}) + api.nvim_set_option_value('directory', './Xtest2,.', {}) command('edit Xtest1') poke_eventloop() -- swapfile should no longer exist in CWD. - eq(nil, luv.fs_stat('.Xtest1.swp')) + eq(nil, vim.uv.fs_stat('.Xtest1.swp')) - eq({ "Xtest1.swp", "Xtest3" }, ls_dir_sorted("Xtest2")) + eq({ 'Xtest1.swp', 'Xtest3' }, ls_dir_sorted('Xtest2')) - meths.set_option_value('directory', 'Xtest.je', {}) + api.nvim_set_option_value('directory', 'Xtest.je', {}) command('bdelete') command('edit Xtest2/Xtest3') - eq(true, meths.get_option_value('swapfile', {})) + eq(true, api.nvim_get_option_value('swapfile', {})) poke_eventloop() - eq({ "Xtest3" }, ls_dir_sorted("Xtest2")) - eq({ "Xtest3.swp" }, ls_dir_sorted("Xtest.je")) + eq({ 'Xtest3' }, ls_dir_sorted('Xtest2')) + eq({ 'Xtest3.swp' }, ls_dir_sorted('Xtest.je')) end) end) diff --git a/test/functional/legacy/023_edit_arguments_spec.lua b/test/functional/legacy/023_edit_arguments_spec.lua index f59d192c1e..64b2f6fa95 100644 --- a/test/functional/legacy/023_edit_arguments_spec.lua +++ b/test/functional/legacy/023_edit_arguments_spec.lua @@ -28,7 +28,7 @@ describe(':edit', function() -- Open Xfile2 using '|' range command('edit Xfile2|1') - command("s/\\//SLASH/") + command('s/\\//SLASH/') command('yank A') command('w! Xfile2') diff --git a/test/functional/legacy/025_jump_tag_hidden_spec.lua b/test/functional/legacy/025_jump_tag_hidden_spec.lua index 15bd56a601..33bab05404 100644 --- a/test/functional/legacy/025_jump_tag_hidden_spec.lua +++ b/test/functional/legacy/025_jump_tag_hidden_spec.lua @@ -56,6 +56,6 @@ describe('jump to a tag with hidden set', function() feed_command('$d') -- Assert buffer contents. - expect("#efine SECTION_OFF 3") + expect('#efine SECTION_OFF 3') end) end) diff --git a/test/functional/legacy/029_join_spec.lua b/test/functional/legacy/029_join_spec.lua index b28f276a7c..c808a21afc 100644 --- a/test/functional/legacy/029_join_spec.lua +++ b/test/functional/legacy/029_join_spec.lua @@ -313,7 +313,9 @@ describe('joining lines', function() feed('j') feed_command('.,+5join') feed('j6J<cr>') - feed('oSome code!<cr>// Make sure backspacing does not remove this comment leader.<esc>0i<bs><esc>') + feed( + 'oSome code!<cr>// Make sure backspacing does not remove this comment leader.<esc>0i<bs><esc>' + ) expect([[ { diff --git a/test/functional/legacy/031_close_commands_spec.lua b/test/functional/legacy/031_close_commands_spec.lua index d02b1a2049..173ebf1cf4 100644 --- a/test/functional/legacy/031_close_commands_spec.lua +++ b/test/functional/legacy/031_close_commands_spec.lua @@ -119,9 +119,12 @@ describe('Commands that close windows and/or buffers', function() feed_command('q!') feed('<CR>') expect('testtext 1') - expect_exit(source, [[ + expect_exit( + source, + [[ q! " Now nvim should have exited - throw "Oh, Not finished yet."]]) + throw "Oh, Not finished yet."]] + ) end) end) diff --git a/test/functional/legacy/034_user_function_spec.lua b/test/functional/legacy/034_user_function_spec.lua index 0b7dfc4f0e..c30c7275f2 100644 --- a/test/functional/legacy/034_user_function_spec.lua +++ b/test/functional/legacy/034_user_function_spec.lua @@ -7,13 +7,15 @@ local helpers = require('test.functional.helpers')(after_each) local feed, insert, source = helpers.feed, helpers.insert, helpers.source local clear, feed_command, expect = helpers.clear, helpers.feed_command, helpers.expect -describe('user functions, expr-mappings, overwrite protected builtin functions and regression on calling expressions', function() - setup(clear) +describe( + 'user functions, expr-mappings, overwrite protected builtin functions and regression on calling expressions', + function() + setup(clear) - it('are working', function() - insert('here') + it('are working', function() + insert('here') - source([[ + source([[ function Table(title, ...) let ret = a:title let idx = 1 @@ -59,35 +61,35 @@ describe('user functions, expr-mappings, overwrite protected builtin functions a let retval = "nop" /^here ]]) - feed('C<C-R>=Table("xxx", 4, "asdf")<cr>') - -- Using a actual space will not work as feed() calls dedent on the input. - feed('<space><C-R>=Compute(45, 0, "retval")<cr>') - feed('<space><C-R>=retval<cr>') - feed('<space><C-R>=Compute(45, 5, "retval")<cr>') - feed('<space><C-R>=retval<cr>') - feed('<space><C-R>=g:FuncRef(333)<cr>') - feed('<cr>') - feed('XX+-XX<cr>') - feed('---*---<cr>') - feed('(one<cr>') - feed('(two<cr>') - feed('[(one again<esc>') - feed_command('call append(line("$"), max([1, 2, 3]))') - feed_command('call extend(g:, {"max": function("min")})') - feed_command('call append(line("$"), max([1, 2, 3]))') - feed_command('try') - -- Regression: the first line below used to throw "E110: Missing ')'" - -- Second is here just to prove that this line is correct when not - -- skipping rhs of &&. - feed_command([[ $put =(0&&(function('tr'))(1, 2, 3))]]) - feed_command([[ $put =(1&&(function('tr'))(1, 2, 3))]]) - feed_command('catch') - feed_command([[ $put ='!!! Unexpected exception:']]) - feed_command(' $put =v:exception') - feed_command('endtry') + feed('C<C-R>=Table("xxx", 4, "asdf")<cr>') + -- Using a actual space will not work as feed() calls dedent on the input. + feed('<space><C-R>=Compute(45, 0, "retval")<cr>') + feed('<space><C-R>=retval<cr>') + feed('<space><C-R>=Compute(45, 5, "retval")<cr>') + feed('<space><C-R>=retval<cr>') + feed('<space><C-R>=g:FuncRef(333)<cr>') + feed('<cr>') + feed('XX+-XX<cr>') + feed('---*---<cr>') + feed('(one<cr>') + feed('(two<cr>') + feed('[(one again<esc>') + feed_command('call append(line("$"), max([1, 2, 3]))') + feed_command('call extend(g:, {"max": function("min")})') + feed_command('call append(line("$"), max([1, 2, 3]))') + feed_command('try') + -- Regression: the first line below used to throw "E110: Missing ')'" + -- Second is here just to prove that this line is correct when not + -- skipping rhs of &&. + feed_command([[ $put =(0&&(function('tr'))(1, 2, 3))]]) + feed_command([[ $put =(1&&(function('tr'))(1, 2, 3))]]) + feed_command('catch') + feed_command([[ $put ='!!! Unexpected exception:']]) + feed_command(' $put =v:exception') + feed_command('endtry') - -- Assert buffer contents. - expect([[ + -- Assert buffer contents. + expect([[ xxx4asdf fail nop ok 9 333 XX111-XX ---222--- @@ -98,5 +100,6 @@ describe('user functions, expr-mappings, overwrite protected builtin functions a 3 0 1]]) - end) -end) + end) + end +) diff --git a/test/functional/legacy/036_regexp_character_classes_spec.lua b/test/functional/legacy/036_regexp_character_classes_spec.lua index 6f66efcb67..ed35b2b245 100644 --- a/test/functional/legacy/036_regexp_character_classes_spec.lua +++ b/test/functional/legacy/036_regexp_character_classes_spec.lua @@ -5,16 +5,16 @@ local clear, command, expect = helpers.clear, helpers.command, helpers.expect local source, write_file = helpers.source, helpers.write_file local function sixlines(text) - local result = '' - for _ = 1, 6 do - result = result .. text .. '\n' - end - return result + local result = '' + for _ = 1, 6 do + result = result .. text .. '\n' + end + return result end local function diff(text, nodedent) local fname = helpers.tmpname() - command('w! '..fname) + command('w! ' .. fname) helpers.poke_eventloop() local data = io.open(fname):read('*all') if nodedent then @@ -40,7 +40,16 @@ describe('character classes in regexp', function() -- The original test32.in file was not in utf-8 encoding and did also -- contain some control characters. We use lua escape sequences to write -- them to the test file. - local line = ctrl1..punct1..digits..punct2..upper..punct3..lower..punct4..ctrl2..iso_text + local line = ctrl1 + .. punct1 + .. digits + .. punct2 + .. upper + .. punct3 + .. lower + .. punct4 + .. ctrl2 + .. iso_text write_file('test36.in', sixlines(line)) end) before_each(function() @@ -59,8 +68,9 @@ describe('character classes in regexp', function() 4 s/\%#=0[0-9]//g 5 s/\%#=1[0-9]//g 6 s/\%#=2[0-9]//g]]) - diff(sixlines(ctrl1..punct1..punct2..upper..punct3..lower..punct4.. - ctrl2..iso_text)) + diff( + sixlines(ctrl1 .. punct1 .. punct2 .. upper .. punct3 .. lower .. punct4 .. ctrl2 .. iso_text) + ) end) it('is working', function() source([[ @@ -86,8 +96,11 @@ describe('character classes in regexp', function() 4 s/\%#=0[0-7]//g 5 s/\%#=1[0-7]//g 6 s/\%#=2[0-7]//g]]) - diff(sixlines(ctrl1..punct1..'89'..punct2..upper..punct3..lower..punct4..ctrl2.. - iso_text)) + diff( + sixlines( + ctrl1 .. punct1 .. '89' .. punct2 .. upper .. punct3 .. lower .. punct4 .. ctrl2 .. iso_text + ) + ) end) it('is working', function() source([[ @@ -113,7 +126,11 @@ describe('character classes in regexp', function() 4 s/\%#=0[0-9A-Fa-f]//g 5 s/\%#=1[0-9A-Fa-f]//g 6 s/\%#=2[0-9A-Fa-f]//g]]) - diff(sixlines(ctrl1..punct1..punct2..'GHIXYZ'..punct3..'ghiwxyz'..punct4..ctrl2..iso_text)) + diff( + sixlines( + ctrl1 .. punct1 .. punct2 .. 'GHIXYZ' .. punct3 .. 'ghiwxyz' .. punct4 .. ctrl2 .. iso_text + ) + ) end) it('is working', function() source([[ @@ -139,7 +156,7 @@ describe('character classes in regexp', function() 4 s/\%#=0[0-9A-Za-z_]//g 5 s/\%#=1[0-9A-Za-z_]//g 6 s/\%#=2[0-9A-Za-z_]//g]]) - diff(sixlines(ctrl1..punct1..punct2..'[\\]^`'..punct4..ctrl2..iso_text)) + diff(sixlines(ctrl1 .. punct1 .. punct2 .. '[\\]^`' .. punct4 .. ctrl2 .. iso_text)) end) it('is working', function() source([[ @@ -165,8 +182,7 @@ describe('character classes in regexp', function() 4 s/\%#=0[A-Za-z_]//g 5 s/\%#=1[A-Za-z_]//g 6 s/\%#=2[A-Za-z_]//g]]) - diff(sixlines(ctrl1..punct1..digits..punct2..'[\\]^`'..punct4..ctrl2.. - iso_text)) + diff(sixlines(ctrl1 .. punct1 .. digits .. punct2 .. '[\\]^`' .. punct4 .. ctrl2 .. iso_text)) end) it('is working', function() source([[ @@ -192,7 +208,7 @@ describe('character classes in regexp', function() 4 s/\%#=0[A-Za-z]//g 5 s/\%#=1[A-Za-z]//g 6 s/\%#=2[A-Za-z]//g]]) - diff(sixlines(ctrl1..punct1..digits..punct2..punct3..punct4..ctrl2..iso_text)) + diff(sixlines(ctrl1 .. punct1 .. digits .. punct2 .. punct3 .. punct4 .. ctrl2 .. iso_text)) end) it('is working', function() source([[ @@ -218,8 +234,11 @@ describe('character classes in regexp', function() 4 s/\%#=0[a-z]//g 5 s/\%#=1[a-z]//g 6 s/\%#=2[a-z]//g]]) - diff(sixlines(ctrl1..punct1..digits..punct2..upper..punct3..punct4.. - ctrl2..iso_text)) + diff( + sixlines( + ctrl1 .. punct1 .. digits .. punct2 .. upper .. punct3 .. punct4 .. ctrl2 .. iso_text + ) + ) end) it('is working', function() source([[ @@ -245,8 +264,11 @@ describe('character classes in regexp', function() 4 s/\%#=0[A-Z]//g 5 s/\%#=1[A-Z]//g 6 s/\%#=2[A-Z]//g]]) - diff(sixlines(ctrl1..punct1..digits..punct2..punct3..lower..punct4.. - ctrl2..iso_text)) + diff( + sixlines( + ctrl1 .. punct1 .. digits .. punct2 .. punct3 .. lower .. punct4 .. ctrl2 .. iso_text + ) + ) end) it('is working', function() source([[ @@ -272,8 +294,19 @@ describe('character classes in regexp', function() 4 s/\%#=0\%4l^\t...//g 5 s/\%#=1\%5l^\t...//g 6 s/\%#=2\%6l^\t...//g]]) - diff(sixlines(string.sub(punct1, 1)..digits..punct2..upper..punct3.. - lower..punct4..ctrl2..iso_text)) + diff( + sixlines( + string.sub(punct1, 1) + .. digits + .. punct2 + .. upper + .. punct3 + .. lower + .. punct4 + .. ctrl2 + .. iso_text + ) + ) end) it('does not convert character class ranges to an incorrect class', function() source([[ @@ -284,7 +317,9 @@ describe('character classes in regexp', function() 5 s/\%#=1[^0-z]//g 6 s/\%#=2[^0-z]//g ]]) - diff(string.rep(ctrl1..punct1..punct4..ctrl2..iso_text..'\n', 3) - ..string.rep(digits..punct2..upper..punct3..lower..'\n', 3)) + diff( + string.rep(ctrl1 .. punct1 .. punct4 .. ctrl2 .. iso_text .. '\n', 3) + .. string.rep(digits .. punct2 .. upper .. punct3 .. lower .. '\n', 3) + ) end) end) diff --git a/test/functional/legacy/038_virtual_replace_spec.lua b/test/functional/legacy/038_virtual_replace_spec.lua index 8dd7bdda6e..2f85e7d5a3 100644 --- a/test/functional/legacy/038_virtual_replace_spec.lua +++ b/test/functional/legacy/038_virtual_replace_spec.lua @@ -38,7 +38,9 @@ describe('Virtual replace mode', function() feed('BCDEFGHIJ<cr>') feed('<tab>KL<cr>') feed('MNO<cr>') - feed('PQR<C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><esc>:$<cr>') + feed( + 'PQR<C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><esc>:$<cr>' + ) feed('iab<tab>cdefghi<tab>jkl<esc>0gRAB......CDEFGHI.J<esc>o<esc>:<cr>') feed('iabcdefghijklmnopqrst<esc>0gRAB<tab>IJKLMNO<tab>QR<esc>') diff --git a/test/functional/legacy/039_visual_block_mode_commands_spec.lua b/test/functional/legacy/039_visual_block_mode_commands_spec.lua index 135058c579..bc3fea765c 100644 --- a/test/functional/legacy/039_visual_block_mode_commands_spec.lua +++ b/test/functional/legacy/039_visual_block_mode_commands_spec.lua @@ -2,13 +2,12 @@ -- And test "U" in Visual mode, also on German sharp S. local helpers = require('test.functional.helpers')(after_each) -local nvim, eq = helpers.meths, helpers.eq +local nvim, eq = helpers.api, helpers.eq local insert, feed = helpers.insert, helpers.feed local clear, expect = helpers.clear, helpers.expect local feed_command = helpers.feed_command describe('Visual block mode', function() - before_each(function() clear() @@ -135,7 +134,7 @@ describe('Visual block mode', function() end) it('should make a selected part uppercase', function() - -- GUe must uppercase a whole word, also when ß changes to SS. + -- GUe must uppercase a whole word, also when ß changes to ẞ. feed('Gothe youtußeuu end<ESC>Ypk0wgUe<CR>') -- GUfx must uppercase until x, inclusive. feed('O- youßtußexu -<ESC>0fogUfx<CR>') @@ -151,13 +150,13 @@ describe('Visual block mode', function() expect([[ - the YOUTUSSEUU end - - yOUSSTUSSEXu - - THE YOUTUSSEUU END - 111THE YOUTUSSEUU END + the YOUTUẞEUU end + - yOUẞTUẞEXu - + THE YOUTUẞEUU END + 111THE YOUTUẞEUU END BLAH DI DOH DUT - 222the yoUTUSSEUU END + 222the yoUTUẞEUU END 333THE YOUTUßeuu end]]) end) @@ -205,14 +204,14 @@ describe('Visual block mode', function() feed('G2l') feed('2k<C-v>$gj<ESC>') feed_command([[let cpos=getpos("'>")]]) - local cpos = nvim.get_var('cpos') + local cpos = nvim.nvim_get_var('cpos') local expected = { col = 4, - off = 0 + off = 0, } local actual = { col = cpos[3], - off = cpos[4] + off = cpos[4], } eq(expected, actual) diff --git a/test/functional/legacy/055_list_and_dict_types_spec.lua b/test/functional/legacy/055_list_and_dict_types_spec.lua index 75294b3786..e8ae60e350 100644 --- a/test/functional/legacy/055_list_and_dict_types_spec.lua +++ b/test/functional/legacy/055_list_and_dict_types_spec.lua @@ -547,7 +547,8 @@ describe('list and dictionary types', function() $put =string(sort(copy(l), 1)) $put =string(sort(copy(l), 'i')) $put =string(sort(copy(l)))]=]) - expect([=[ + expect( + [=[ ['-0', 'A11', 2, 'xaaa', 4, 'foo', 'foo6', 'foo', [0, 1, 2], 'x8', [0, 1, 2], 1.5] [1.5, [0, 1, 2], 'x8', [0, 1, 2], 'foo', 'foo6', 'foo', 4, 'xaaa', 2, 2, 'A11', '-0'] @@ -559,7 +560,8 @@ describe('list and dictionary types', function() [-1, 'one', 'two', 'three', 'four', 1.0e-15, 0.22, 7, 9, 12, 18, 22, 255] ['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}] ['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}] - ['BAR', 'Bar', 'FOO', 'FOOBAR', 'Foo', 'bar', 'foo', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}]]=]) + ['BAR', 'Bar', 'FOO', 'FOOBAR', 'Foo', 'bar', 'foo', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}]]=] + ) end) it('splitting a string to a list', function() diff --git a/test/functional/legacy/057_sort_spec.lua b/test/functional/legacy/057_sort_spec.lua index 328d6f6fa0..9b4746591f 100644 --- a/test/functional/legacy/057_sort_spec.lua +++ b/test/functional/legacy/057_sort_spec.lua @@ -2,8 +2,8 @@ local helpers = require('test.functional.helpers')(after_each) -local insert, command, clear, expect, eq, poke_eventloop = helpers.insert, - helpers.command, helpers.clear, helpers.expect, helpers.eq, helpers.poke_eventloop +local insert, command, clear, expect, eq, poke_eventloop = + helpers.insert, helpers.command, helpers.clear, helpers.expect, helpers.eq, helpers.poke_eventloop local exc_exec = helpers.exc_exec describe(':sort', function() diff --git a/test/functional/legacy/060_exists_and_has_functions_spec.lua b/test/functional/legacy/060_exists_and_has_functions_spec.lua index 1794f23b3a..82fece3e84 100644 --- a/test/functional/legacy/060_exists_and_has_functions_spec.lua +++ b/test/functional/legacy/060_exists_and_has_functions_spec.lua @@ -9,7 +9,9 @@ describe('exists() and has() functions', function() setup(function() clear() -- Create a temporary script needed for the test. - write_file('test60.vim', [[ + write_file( + 'test60.vim', + [[ " Vim script for exists() function test " Script-local variables are checked here @@ -107,7 +109,8 @@ describe('exists() and has() functions', function() echo "FAILED" endif unlet str - ]]) + ]] + ) end) teardown(function() os.remove('test.out') @@ -115,7 +118,6 @@ describe('exists() and has() functions', function() end) it('is working', function() - source([=[ " Add the special directory with test scripts to &rtp set rtp+=test/functional/fixtures @@ -850,6 +852,5 @@ describe('exists() and has() functions', function() g:footest#x = 1 footest#F() 0 UndefFun() 0]]) - end) end) diff --git a/test/functional/legacy/063_match_and_matchadd_spec.lua b/test/functional/legacy/063_match_and_matchadd_spec.lua index 235a826640..0c2b59932b 100644 --- a/test/functional/legacy/063_match_and_matchadd_spec.lua +++ b/test/functional/legacy/063_match_and_matchadd_spec.lua @@ -13,35 +13,30 @@ describe('063: Test for ":match", "matchadd()" and related functions', function( local screen = Screen.new(40, 5) screen:attach() screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, - [1] = {background = Screen.colors.Red}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { background = Screen.colors.Red }, }) - command("highlight MyGroup1 term=bold ctermbg=red guibg=red") - command("highlight MyGroup2 term=italic ctermbg=green guibg=green") - command("highlight MyGroup3 term=underline ctermbg=blue guibg=blue") + command('highlight MyGroup1 term=bold ctermbg=red guibg=red') + command('highlight MyGroup2 term=italic ctermbg=green guibg=green') + command('highlight MyGroup3 term=underline ctermbg=blue guibg=blue') -- Check that "matchaddpos()" positions matches correctly insert('abcdefghijklmnopq') command("call matchaddpos('MyGroup1', [[1, 5], [1, 8, 3]], 10, 3)") screen:expect([[ abcd{1:e}fg{1:hij}klmnop^q | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) - command("call clearmatches()") + command('call clearmatches()') command("call setline(1, 'abcdΣabcdef')") command("call matchaddpos('MyGroup1', [[1, 4, 2], [1, 9, 2]])") screen:expect([[ abc{1:dΣ}ab{1:cd}e^f | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) end) end) - diff --git a/test/functional/legacy/069_multibyte_formatting_spec.lua b/test/functional/legacy/069_multibyte_formatting_spec.lua index 9c248e3aa8..05e6aa1435 100644 --- a/test/functional/legacy/069_multibyte_formatting_spec.lua +++ b/test/functional/legacy/069_multibyte_formatting_spec.lua @@ -4,8 +4,13 @@ -- Also test byteidx() and byteidxcomp() local helpers = require('test.functional.helpers')(after_each) -local feed, insert, eq, eval, clear, feed_command, expect = helpers.feed, - helpers.insert, helpers.eq, helpers.eval, helpers.clear, helpers.feed_command, +local feed, insert, eq, eval, clear, feed_command, expect = + helpers.feed, + helpers.insert, + helpers.eq, + helpers.eval, + helpers.clear, + helpers.feed_command, helpers.expect describe('multibyte text', function() diff --git a/test/functional/legacy/074_global_var_in_viminfo_spec.lua b/test/functional/legacy/074_global_var_in_viminfo_spec.lua index 06d8b276d7..0a9ad330c2 100644 --- a/test/functional/legacy/074_global_var_in_viminfo_spec.lua +++ b/test/functional/legacy/074_global_var_in_viminfo_spec.lua @@ -1,10 +1,8 @@ -- Tests for storing global variables in the .shada file local helpers = require('test.functional.helpers')(after_each) -local luv = require('luv') local clear, command, eq, neq, eval, poke_eventloop = - helpers.clear, helpers.command, helpers.eq, helpers.neq, helpers.eval, - helpers.poke_eventloop + helpers.clear, helpers.command, helpers.eq, helpers.neq, helpers.eval, helpers.poke_eventloop describe('storing global variables in ShaDa files', function() local tempname = 'Xtest-functional-legacy-074' @@ -14,19 +12,115 @@ describe('storing global variables in ShaDa files', function() end) it('is working', function() - clear{args_rm={'-i'}, args={'-i', 'Xviminfo'}} + clear { args_rm = { '-i' }, args = { '-i', 'Xviminfo' } } - local test_dict = {foo = 1, bar = 0, longvarible = 1000} - local test_list = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100} + local test_dict = { foo = 1, bar = 0, longvarible = 1000 } + local test_list = { + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + } command('set visualbell') command('set shada+=!') - command('let MY_GLOBAL_DICT={\'foo\': 1, \'bar\': 0, \'longvarible\': 1000}') + command("let MY_GLOBAL_DICT={'foo': 1, 'bar': 0, 'longvarible': 1000}") -- Store a really long list. Initially this was testing line wrapping in -- viminfo, but shada files has no line wrapping, no matter how long the -- list is. @@ -39,7 +133,7 @@ describe('storing global variables in ShaDa files', function() poke_eventloop() -- Assert that the shada file exists. - neq(nil, luv.fs_stat(tempname)) + neq(nil, vim.uv.fs_stat(tempname)) command('unlet MY_GLOBAL_DICT') command('unlet MY_GLOBAL_LIST') -- Assert that the variables where deleted. diff --git a/test/functional/legacy/078_swapfile_recover_spec.lua b/test/functional/legacy/078_swapfile_recover_spec.lua index 45f0aed37a..dc5b1a8540 100644 --- a/test/functional/legacy/078_swapfile_recover_spec.lua +++ b/test/functional/legacy/078_swapfile_recover_spec.lua @@ -9,8 +9,8 @@ local clear, expect, source = helpers.clear, helpers.expect, helpers.source describe('78', function() setup(clear) teardown(function() - os.remove(".Xtest.swp") - os.remove(".Xtest.swo") + os.remove('.Xtest.swp') + os.remove('.Xtest.swo') end) it('is working', function() diff --git a/test/functional/legacy/083_tag_search_with_file_encoding_spec.lua b/test/functional/legacy/083_tag_search_with_file_encoding_spec.lua index 54620c7104..5e9c131c64 100644 --- a/test/functional/legacy/083_tag_search_with_file_encoding_spec.lua +++ b/test/functional/legacy/083_tag_search_with_file_encoding_spec.lua @@ -1,11 +1,11 @@ -- Tests for tag search with !_TAG_FILE_ENCODING. local helpers = require('test.functional.helpers')(after_each) -local insert, source, clear, expect, write_file = helpers.insert, - helpers.source, helpers.clear, helpers.expect, helpers.write_file +local insert, source, clear, expect, write_file = + helpers.insert, helpers.source, helpers.clear, helpers.expect, helpers.write_file local function has_iconv() - clear() -- ensures session + clear() -- ensures session return 1 == helpers.eval('has("iconv")') end @@ -18,14 +18,17 @@ describe('tag search with !_TAG_FILE_ENCODING', function() write_file('Xtags1.txt', 'text for tags1\nabcdefghijklmnopqrs\n') write_file('Xtags2.txt', 'text for tags2\nABC\n') write_file('Xtags3.txt', 'text for tags3\nABC\n') - write_file('Xtags1', [[ + write_file( + 'Xtags1', + [[ !_TAG_FILE_ENCODING utf-8 // abcdefghijklmnopqrs Xtags1.txt /abcdefghijklmnopqrs - ]]) - write_file('test83-tags2', - '!_TAG_FILE_ENCODING cp932 //\n' .. - '\130`\130a\130b Xtags2.txt /\130`\130a\130b\n' - ) + ]] + ) + write_file( + 'test83-tags2', + '!_TAG_FILE_ENCODING cp932 //\n' .. '\130`\130a\130b Xtags2.txt /\130`\130a\130b\n' + ) -- The last file is very long but repetitive and can be generated on the -- fly. local text = helpers.dedent([[ @@ -51,7 +54,6 @@ describe('tag search with !_TAG_FILE_ENCODING', function() pending('skipped (missing iconv)', function() end) else it('is working', function() - insert('Results of test83') -- Case1: diff --git a/test/functional/legacy/090_sha256_spec.lua b/test/functional/legacy/090_sha256_spec.lua index e364af9400..701b777df1 100644 --- a/test/functional/legacy/090_sha256_spec.lua +++ b/test/functional/legacy/090_sha256_spec.lua @@ -8,7 +8,7 @@ describe('sha256()', function() setup(clear) it('is working', function() - insert("start:") + insert('start:') source([[ let testcase='test for empty string: ' diff --git a/test/functional/legacy/091_context_variables_spec.lua b/test/functional/legacy/091_context_variables_spec.lua index c08a58e14b..3b9fdf740f 100644 --- a/test/functional/legacy/091_context_variables_spec.lua +++ b/test/functional/legacy/091_context_variables_spec.lua @@ -8,7 +8,7 @@ describe('context variables', function() setup(clear) it('is working', function() - insert("start:") + insert('start:') -- Test for getbufvar(). -- Use strings to test for memory leaks. diff --git a/test/functional/legacy/096_location_list_spec.lua b/test/functional/legacy/096_location_list_spec.lua index b21a2085f6..2817d5d240 100644 --- a/test/functional/legacy/096_location_list_spec.lua +++ b/test/functional/legacy/096_location_list_spec.lua @@ -45,20 +45,18 @@ describe('location list', function() setl readonly exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '') endfunction - ]] .. - - -- Register the above buffer setup function to be executed before - -- starting to edit a new "test protocol" buffer. - [[ + ]] + -- Register the above buffer setup function to be executed before + -- starting to edit a new "test protocol" buffer. + .. [[ augroup testgroup au! autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>")) augroup END - ]] .. - - -- Populate the location list of the current window with some test - -- protocol file locations such as "test://foo.txt". - [[ + ]] + -- Populate the location list of the current window with some test + -- protocol file locations such as "test://foo.txt". + .. [[ let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ] let qflist = [] for word in words @@ -68,11 +66,12 @@ describe('location list', function() " valid. call setloclist(0, qflist, ' ') endfor - ]]) + ]] + ) -- Set up the result buffer. command('enew') - command('w! '..test_file) + command('w! ' .. test_file) command('b 1') -- Test A. @@ -99,14 +98,16 @@ describe('location list', function() command([[let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')]]) command('wincmd n') command('wincmd K') - command('b '..test_file) + command('b ' .. test_file) -- Prepare test output and write it to the result buffer. command([[let fileName = substitute(fileName, '\\', '/', 'g')]]) command([[let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')]]) command([[call append(line('$'), "Test A:")]]) command([[call append(line('$'), " - file name displayed: " . fileName)]]) - command([[call append(line('$'), " - quickfix claims that the file name displayed is: " . locationListFileName)]]) + command( + [[call append(line('$'), " - quickfix claims that the file name displayed is: " . locationListFileName)]] + ) command('w') -- Clean slate for the next test. @@ -132,7 +133,7 @@ describe('location list', function() command('let numberOfWindowsOpen = winnr("$")') command('wincmd n') command('wincmd K') - command('b '..test_file) + command('b ' .. test_file) -- Prepare test output and write it to the result buffer. command('call append(line("$"), "Test B:")') @@ -170,12 +171,14 @@ describe('location list', function() command('let bufferName = expand("%")') command('wincmd n') command('wincmd K') - command('b '..test_file) + command('b ' .. test_file) -- Prepare test output and write it to the result buffer. command([[let bufferName = substitute(bufferName, '\\', '/', 'g')]]) command([[call append(line("$"), "Test C:")]]) - command([[call append(line('$'), " - 'buftype' of the location list window: " . locationListWindowBufType)]]) + command( + [[call append(line('$'), " - 'buftype' of the location list window: " . locationListWindowBufType)]] + ) command([[call append(line('$'), " - buffer displayed in the 2nd window: " . bufferName)]]) command('w') command('wincmd o') diff --git a/test/functional/legacy/097_glob_path_spec.lua b/test/functional/legacy/097_glob_path_spec.lua index a62dc4d4c8..b335b3bf41 100644 --- a/test/functional/legacy/097_glob_path_spec.lua +++ b/test/functional/legacy/097_glob_path_spec.lua @@ -11,13 +11,13 @@ describe('glob() and globpath()', function() setup(function() if helpers.is_os('win') then - os.execute("md sautest\\autoload") - os.execute(".>sautest\\autoload\\Test104.vim 2>nul") - os.execute(".>sautest\\autoload\\footest.vim 2>nul") + os.execute('md sautest\\autoload') + os.execute('.>sautest\\autoload\\Test104.vim 2>nul') + os.execute('.>sautest\\autoload\\footest.vim 2>nul') else - os.execute("mkdir -p sautest/autoload") - os.execute("touch sautest/autoload/Test104.vim") - os.execute("touch sautest/autoload/footest.vim") + os.execute('mkdir -p sautest/autoload') + os.execute('touch sautest/autoload/Test104.vim') + os.execute('touch sautest/autoload/footest.vim') end end) @@ -76,7 +76,7 @@ describe('glob() and globpath()', function() os.execute('del /q/f Xxx{ Xxx$') os.execute('rd /q /s sautest') else - os.execute("rm -rf sautest Xxx{ Xxx$") + os.execute('rm -rf sautest Xxx{ Xxx$') end end) end) diff --git a/test/functional/legacy/102_fnameescape_spec.lua b/test/functional/legacy/102_fnameescape_spec.lua index c8ee423ff3..11bdbd7c9c 100644 --- a/test/functional/legacy/102_fnameescape_spec.lua +++ b/test/functional/legacy/102_fnameescape_spec.lua @@ -20,7 +20,7 @@ describe('fnameescape', function() end) teardown(function() - os.remove("Xspa ce") - os.remove("Xemark!") + os.remove('Xspa ce') + os.remove('Xemark!') end) end) diff --git a/test/functional/legacy/106_errorformat_spec.lua b/test/functional/legacy/106_errorformat_spec.lua index 3f017a704f..2a83d48c07 100644 --- a/test/functional/legacy/106_errorformat_spec.lua +++ b/test/functional/legacy/106_errorformat_spec.lua @@ -8,7 +8,7 @@ describe('errorformat', function() setup(clear) it('is working', function() - command("set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#") + command('set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#') command("cgetexpr ['WWWW', 'EEEE', 'CCCC']") command("$put =strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))") command("cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']") diff --git a/test/functional/legacy/107_adjust_window_and_contents_spec.lua b/test/functional/legacy/107_adjust_window_and_contents_spec.lua index 841eeef0af..5a8fdda32d 100644 --- a/test/functional/legacy/107_adjust_window_and_contents_spec.lua +++ b/test/functional/legacy/107_adjust_window_and_contents_spec.lua @@ -50,15 +50,7 @@ describe('107', function() [1, '1 '] | [50, '50 '] | ^[59, '59 '] | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*9 3 more lines | ]]) end) diff --git a/test/functional/legacy/108_backtrace_debug_commands_spec.lua b/test/functional/legacy/108_backtrace_debug_commands_spec.lua index 1c1a2095d5..ccdd0cd2be 100644 --- a/test/functional/legacy/108_backtrace_debug_commands_spec.lua +++ b/test/functional/legacy/108_backtrace_debug_commands_spec.lua @@ -9,7 +9,7 @@ describe('108', function() before_each(clear) it('is working', function() - command("set shortmess-=F") + command('set shortmess-=F') feed_command('lang mess C') feed_command('function! Foo()') feed_command(' let var1 = 1') diff --git a/test/functional/legacy/arglist_spec.lua b/test/functional/legacy/arglist_spec.lua index a15809907b..3e78d7ca5f 100644 --- a/test/functional/legacy/arglist_spec.lua +++ b/test/functional/legacy/arglist_spec.lua @@ -33,10 +33,7 @@ describe('argument list commands', function() feed('N') screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | + ~ |*4 | ]]) feed(':confirm quit\n') diff --git a/test/functional/legacy/assert_spec.lua b/test/functional/legacy/assert_spec.lua index d49d7d665a..04c90281a7 100644 --- a/test/functional/legacy/assert_spec.lua +++ b/test/functional/legacy/assert_spec.lua @@ -1,20 +1,19 @@ local helpers = require('test.functional.helpers')(after_each) -local nvim, call = helpers.meths, helpers.call +local nvim, call = helpers.api, helpers.call local clear, eq = helpers.clear, helpers.eq local source, command = helpers.source, helpers.command local exc_exec = helpers.exc_exec local eval = helpers.eval local function expected_errors(errors) - eq(errors, nvim.get_vvar('errors')) + eq(errors, nvim.nvim_get_vvar('errors')) end local function expected_empty() - eq({}, nvim.get_vvar('errors')) + eq({}, nvim.nvim_get_vvar('errors')) end describe('assert function:', function() - before_each(function() clear() end) @@ -39,24 +38,24 @@ describe('assert function:', function() end) it('should change v:errors when expected is not equal to actual', function() - eq(1, call('assert_equal', 0, {0})) - expected_errors({'Expected 0 but got [0]'}) + eq(1, call('assert_equal', 0, { 0 })) + expected_errors({ 'Expected 0 but got [0]' }) end) it('should change v:errors when expected is not equal to actual', function() - eq(1, call('assert_equal', 0, "0")) - expected_errors({"Expected 0 but got '0'"}) + eq(1, call('assert_equal', 0, '0')) + expected_errors({ "Expected 0 but got '0'" }) end) it('should change v:errors when expected is not equal to actual', function() -- Lua does not tell integer from float. command('call assert_equal(1, 1.0)') - expected_errors({'Expected 1 but got 1.0'}) + expected_errors({ 'Expected 1 but got 1.0' }) end) it('should change v:errors when expected is not equal to actual', function() call('assert_equal', 'true', 'false') - expected_errors({"Expected 'true' but got 'false'"}) + expected_errors({ "Expected 'true' but got 'false'" }) end) it('should change v:errors when expected is not equal to actual', function() @@ -69,8 +68,10 @@ describe('assert function:', function() call assert_equal(s:w, '') endfunction ]]) - eq('Vim(call):E724: unable to correctly dump variable with self-referencing container', - exc_exec('call CheckAssert()')) + eq( + 'Vim(call):E724: unable to correctly dump variable with self-referencing container', + exc_exec('call CheckAssert()') + ) end) end) @@ -84,12 +85,12 @@ describe('assert function:', function() it('should change v:errors when actual is not false', function() eq(1, call('assert_false', 1)) - expected_errors({'Expected False but got 1'}) + expected_errors({ 'Expected False but got 1' }) end) it('should change v:errors when actual is not false', function() call('assert_false', {}) - expected_errors({'Expected False but got []'}) + expected_errors({ 'Expected False but got []' }) end) end) @@ -97,14 +98,14 @@ describe('assert function:', function() describe('assert_true', function() it('should not change v:errors when actual is true', function() eq(0, call('assert_true', 1)) - eq(0, call('assert_true', -1)) -- In Vim script, non-zero Numbers are TRUE. + eq(0, call('assert_true', -1)) -- In Vim script, non-zero Numbers are TRUE. eq(0, call('assert_true', true)) expected_empty() end) it('should change v:errors when actual is not true', function() eq(1, call('assert_true', 1.5)) - expected_errors({'Expected True but got 1.5'}) + expected_errors({ 'Expected True but got 1.5' }) end) end) @@ -145,7 +146,7 @@ describe('assert function:', function() call assert_true('', 'file two') ]]) expected_errors({ - "nvim_exec2(): equal assertion failed: Expected 1 but got 100", + 'nvim_exec2(): equal assertion failed: Expected 1 but got 100', "nvim_exec2(): true assertion failed: Expected False but got 'true'", "nvim_exec2(): false assertion failed: Expected True but got 'false'", "nvim_exec2(): file two: Expected True but got ''", @@ -162,7 +163,7 @@ describe('assert function:', function() it('should change v:errors when cmd succeeds', function() eq(1, eval([[assert_fails('call empty("")', '')]])) - expected_errors({'command did not fail: call empty("")'}) + expected_errors({ 'command did not fail: call empty("")' }) end) end) end) diff --git a/test/functional/legacy/autochdir_spec.lua b/test/functional/legacy/autochdir_spec.lua index 5da54b4850..e5980f5942 100644 --- a/test/functional/legacy/autochdir_spec.lua +++ b/test/functional/legacy/autochdir_spec.lua @@ -1,11 +1,11 @@ local helpers = require('test.functional.helpers')(after_each) local clear, eq, matches = helpers.clear, helpers.eq, helpers.matches -local eval, command, call, meths = helpers.eval, helpers.command, helpers.call, helpers.meths +local eval, command, call, api = helpers.eval, helpers.command, helpers.call, helpers.api local source, exec_capture = helpers.source, helpers.exec_capture local mkdir = helpers.mkdir local function expected_empty() - eq({}, meths.get_vvar('errors')) + eq({}, api.nvim_get_vvar('errors')) end describe('autochdir behavior', function() @@ -25,13 +25,13 @@ describe('autochdir behavior', function() it('sets filename', function() command('set acd') command('new') - command('w '..dir..'/Xtest') + command('w ' .. dir .. '/Xtest') eq('Xtest', eval("expand('%')")) eq(dir, eval([[substitute(getcwd(), '.*/\(\k*\)', '\1', '')]])) end) it(':file in win_execute() does not cause wrong directory', function() - command('cd '..dir) + command('cd ' .. dir) source([[ func Test_set_filename_other_window() let cwd = getcwd() @@ -64,53 +64,53 @@ describe('autochdir behavior', function() it('win_execute() does not change directory', function() local subdir = 'Xfile' - command('cd '..dir) + command('cd ' .. dir) command('set acd') call('mkdir', subdir) local winid = eval('win_getid()') - command('new '..subdir..'/file') - matches(dir..'/'..subdir..'$', eval('getcwd()')) + command('new ' .. subdir .. '/file') + matches(dir .. '/' .. subdir .. '$', eval('getcwd()')) command('cd ..') - matches(dir..'$', eval('getcwd()')) + matches(dir .. '$', eval('getcwd()')) call('win_execute', winid, 'echo') - matches(dir..'$', eval('getcwd()')) + matches(dir .. '$', eval('getcwd()')) end) it(':verbose pwd shows whether autochdir is used', function() local subdir = 'Xautodir' - command('cd '..dir) + command('cd ' .. dir) local cwd = eval('getcwd()') command('edit global.txt') - matches('%[global%].*'..dir..'$', exec_capture('verbose pwd')) + matches('%[global%].*' .. dir .. '$', exec_capture('verbose pwd')) call('mkdir', subdir) - command('split '..subdir..'/local.txt') - command('lcd '..subdir) - matches('%[window%].*'..dir..'/'..subdir..'$', exec_capture('verbose pwd')) + command('split ' .. subdir .. '/local.txt') + command('lcd ' .. subdir) + matches('%[window%].*' .. dir .. '/' .. subdir .. '$', exec_capture('verbose pwd')) command('set acd') command('wincmd w') - matches('%[autochdir%].*'..dir..'$', exec_capture('verbose pwd')) - command('tcd '..cwd) - matches('%[tabpage%].*'..dir..'$', exec_capture('verbose pwd')) - command('cd '..cwd) - matches('%[global%].*'..dir..'$', exec_capture('verbose pwd')) - command('lcd '..cwd) - matches('%[window%].*'..dir..'$', exec_capture('verbose pwd')) + matches('%[autochdir%].*' .. dir .. '$', exec_capture('verbose pwd')) + command('tcd ' .. cwd) + matches('%[tabpage%].*' .. dir .. '$', exec_capture('verbose pwd')) + command('cd ' .. cwd) + matches('%[global%].*' .. dir .. '$', exec_capture('verbose pwd')) + command('lcd ' .. cwd) + matches('%[window%].*' .. dir .. '$', exec_capture('verbose pwd')) command('edit') - matches('%[autochdir%].*'..dir..'$', exec_capture('verbose pwd')) + matches('%[autochdir%].*' .. dir .. '$', exec_capture('verbose pwd')) command('enew') command('wincmd w') - matches('%[autochdir%].*'..dir..'/'..subdir..'$', exec_capture('verbose pwd')) + matches('%[autochdir%].*' .. dir .. '/' .. subdir .. '$', exec_capture('verbose pwd')) command('wincmd w') - matches('%[window%].*'..dir..'$', exec_capture('verbose pwd')) + matches('%[window%].*' .. dir .. '$', exec_capture('verbose pwd')) command('wincmd w') - matches('%[autochdir%].*'..dir..'/'..subdir..'$', exec_capture('verbose pwd')) + matches('%[autochdir%].*' .. dir .. '/' .. subdir .. '$', exec_capture('verbose pwd')) command('set noacd') - matches('%[autochdir%].*'..dir..'/'..subdir..'$', exec_capture('verbose pwd')) + matches('%[autochdir%].*' .. dir .. '/' .. subdir .. '$', exec_capture('verbose pwd')) command('wincmd w') - matches('%[window%].*'..dir..'$', exec_capture('verbose pwd')) - command('cd '..cwd) - matches('%[global%].*'..dir..'$', exec_capture('verbose pwd')) + matches('%[window%].*' .. dir .. '$', exec_capture('verbose pwd')) + command('cd ' .. cwd) + matches('%[global%].*' .. dir .. '$', exec_capture('verbose pwd')) command('wincmd w') - matches('%[window%].*'..dir..'/'..subdir..'$', exec_capture('verbose pwd')) + matches('%[window%].*' .. dir .. '/' .. subdir .. '$', exec_capture('verbose pwd')) end) end) diff --git a/test/functional/legacy/autocmd_option_spec.lua b/test/functional/legacy/autocmd_option_spec.lua index 6034d13e2a..9966df263b 100644 --- a/test/functional/legacy/autocmd_option_spec.lua +++ b/test/functional/legacy/autocmd_option_spec.lua @@ -1,8 +1,9 @@ local helpers = require('test.functional.helpers')(after_each) -local nvim = helpers.meths +local nvim = helpers.api local clear, eq, neq, eval = helpers.clear, helpers.eq, helpers.neq, helpers.eval -local curbuf, buf = helpers.curbuf, helpers.bufmeths -local curwin = helpers.curwin +local api = helpers.api +local curbuf = helpers.api.nvim_get_current_buf +local curwin = helpers.api.nvim_get_current_win local exec_capture = helpers.exec_capture local source, command = helpers.source, helpers.command @@ -29,9 +30,7 @@ end local function set_hook(pattern) command( - 'au OptionSet ' - .. pattern .. - ' :call AutoCommand(expand("<amatch>"), bufnr("%"), winnr())' + 'au OptionSet ' .. pattern .. ' :call AutoCommand(expand("<amatch>"), bufnr("%"), winnr())' ) end @@ -40,26 +39,26 @@ local function init_var() end local function get_result() - local ret = nvim.get_var('ret') + local ret = nvim.nvim_get_var('ret') init_var() return ret end local function expected_table(option, oldval, oldval_l, oldval_g, newval, scope, cmd, attr) return { - option = option, - oldval = oldval, + option = option, + oldval = oldval, oldval_l = oldval_l, oldval_g = oldval_g, - newval = newval, - scope = scope, - cmd = cmd, - attr = attr, + newval = newval, + scope = scope, + cmd = cmd, + attr = attr, } end local function expected_combination(...) - local args = {...} + local args = { ... } local ret = get_result() if not (#args == #ret) then @@ -119,7 +118,6 @@ end describe('au OptionSet', function() describe('with any option (*)', function() - before_each(function() clear() declare_hook_function() @@ -129,44 +127,44 @@ describe('au OptionSet', function() it('should be called in setting number option', function() command('set nu') - expected_combination({'number', false, false, false, true, 'global', 'set'}) + expected_combination({ 'number', false, false, false, true, 'global', 'set' }) command('setlocal nonu') - expected_combination({'number', true, true, '', false, 'local', 'setlocal'}) + expected_combination({ 'number', true, true, '', false, 'local', 'setlocal' }) command('setglobal nonu') - expected_combination({'number', true, '', true, false, 'global', 'setglobal'}) + expected_combination({ 'number', true, '', true, false, 'global', 'setglobal' }) end) - it('should be called in setting autoindent option',function() + it('should be called in setting autoindent option', function() command('setlocal ai') - expected_combination({'autoindent', false, false, '', true, 'local', 'setlocal'}) + expected_combination({ 'autoindent', false, false, '', true, 'local', 'setlocal' }) command('setglobal ai') - expected_combination({'autoindent', false, '', false, true, 'global', 'setglobal'}) + expected_combination({ 'autoindent', false, '', false, true, 'global', 'setglobal' }) command('set noai') - expected_combination({'autoindent', true, true, true, false, 'global', 'set'}) + expected_combination({ 'autoindent', true, true, true, false, 'global', 'set' }) end) - it('should be called in inverting global autoindent option',function() + it('should be called in inverting global autoindent option', function() command('set ai!') - expected_combination({'autoindent', false, false, false, true, 'global', 'set'}) + expected_combination({ 'autoindent', false, false, false, true, 'global', 'set' }) end) - it('should be called in being unset local autoindent option',function() + it('should be called in being unset local autoindent option', function() command('setlocal ai') - expected_combination({'autoindent', false, false, '', true, 'local', 'setlocal'}) + expected_combination({ 'autoindent', false, false, '', true, 'local', 'setlocal' }) command('setlocal ai<') - expected_combination({'autoindent', true, true, '', false, 'local', 'setlocal'}) + expected_combination({ 'autoindent', true, true, '', false, 'local', 'setlocal' }) end) - it('should be called in setting global list and number option at the same time',function() + it('should be called in setting global list and number option at the same time', function() command('set list nu') expected_combination( - {'list', false, false, false, true, 'global', 'set'}, - {'number', false, false, false, true, 'global', 'set'} + { 'list', false, false, false, true, 'global', 'set' }, + { 'number', false, false, false, true, 'global', 'set' } ) end) @@ -177,27 +175,27 @@ describe('au OptionSet', function() it('should be called in setting local acd', function() command('setlocal acd') - expected_combination({'autochdir', false, false, '', true, 'local', 'setlocal'}) + expected_combination({ 'autochdir', false, false, '', true, 'local', 'setlocal' }) end) it('should be called in setting autoread', function() command('set noar') - expected_combination({'autoread', true, true, true, false, 'global', 'set'}) + expected_combination({ 'autoread', true, true, true, false, 'global', 'set' }) command('setlocal ar') - expected_combination({'autoread', false, false, '', true, 'local', 'setlocal'}) + expected_combination({ 'autoread', false, false, '', true, 'local', 'setlocal' }) end) it('should be called in inverting global autoread', function() command('setglobal invar') - expected_combination({'autoread', true, '', true, false, 'global', 'setglobal'}) + expected_combination({ 'autoread', true, '', true, false, 'global', 'setglobal' }) end) it('should be called in setting backspace option through :let', function() local oldval = eval('&backspace') command('let &bs=""') - expected_combination({'backspace', oldval, oldval, oldval, '', 'global', 'set'}) + expected_combination({ 'backspace', oldval, oldval, oldval, '', 'global', 'set' }) end) describe('being set by setbufvar()', function() @@ -208,15 +206,24 @@ describe('au OptionSet', function() it('should trigger using correct option name', function() command('call setbufvar(1, "&backup", 1)') - expected_combination({'backup', false, false, '', true, 'local', 'setlocal'}) + expected_combination({ 'backup', false, false, '', true, 'local', 'setlocal' }) end) it('should trigger if the current buffer is different from the targeted buffer', function() local new_buffer = make_buffer() - local new_bufnr = buf.get_number(new_buffer) + local new_bufnr = api.nvim_buf_get_number(new_buffer) command('call setbufvar(' .. new_bufnr .. ', "&buftype", "nofile")') - expected_combination({'buftype', '', '', '', 'nofile', 'local', 'setlocal', {bufnr = new_bufnr}}) + expected_combination({ + 'buftype', + '', + '', + '', + 'nofile', + 'local', + 'setlocal', + { bufnr = new_bufnr }, + }) end) end) @@ -224,24 +231,30 @@ describe('au OptionSet', function() local oldval = eval('&backupext') command('set backupext=foo') - expected_combination({'backupext', oldval, oldval, oldval, 'foo', 'global', 'set'}) + expected_combination({ 'backupext', oldval, oldval, oldval, 'foo', 'global', 'set' }) command('set backupext&') - expected_combination({'backupext', 'foo', 'foo', 'foo', oldval, 'global', 'set'}) + expected_combination({ 'backupext', 'foo', 'foo', 'foo', oldval, 'global', 'set' }) command('setglobal backupext=bar') - expected_combination({'backupext', oldval, '', oldval, 'bar', 'global', 'setglobal'}) + expected_combination({ 'backupext', oldval, '', oldval, 'bar', 'global', 'setglobal' }) command('noa set backupext&') -- As this is a global option this sets the global value even though :setlocal is used! command('setlocal backupext=baz') - expected_combination({'backupext', oldval, oldval, '', 'baz', 'local', 'setlocal'}) + expected_combination({ 'backupext', oldval, oldval, '', 'baz', 'local', 'setlocal' }) command('noa setglobal backupext=ext_global') command('noa setlocal backupext=ext_local') -- Sets the global(!) value command('set backupext=foo') expected_combination({ - 'backupext', 'ext_local', 'ext_local', 'ext_local', 'foo', 'global', 'set' + 'backupext', + 'ext_local', + 'ext_local', + 'ext_local', + 'foo', + 'global', + 'set', }) end) @@ -249,16 +262,16 @@ describe('au OptionSet', function() local oldval = eval('&tags') command('set tags=tagpath') - expected_combination({'tags', oldval, oldval, oldval, 'tagpath', 'global', 'set'}) + expected_combination({ 'tags', oldval, oldval, oldval, 'tagpath', 'global', 'set' }) command('set tags&') - expected_combination({'tags', 'tagpath', 'tagpath', 'tagpath', oldval, 'global', 'set'}) + expected_combination({ 'tags', 'tagpath', 'tagpath', 'tagpath', oldval, 'global', 'set' }) command('setglobal tags=tagpath1') - expected_combination({'tags', oldval, '', oldval, 'tagpath1', 'global', 'setglobal'}) + expected_combination({ 'tags', oldval, '', oldval, 'tagpath1', 'global', 'setglobal' }) command('setlocal tags=tagpath2') - expected_combination({'tags', 'tagpath1', 'tagpath1', '', 'tagpath2', 'local', 'setlocal'}) + expected_combination({ 'tags', 'tagpath1', 'tagpath1', '', 'tagpath2', 'local', 'setlocal' }) -- Note: v:option_old is the old global value for global-local options. -- but the old local value for all other kinds of options. @@ -266,7 +279,13 @@ describe('au OptionSet', function() command('noa setlocal tags=tag_local') command('set tags=tagpath') expected_combination({ - 'tags', 'tag_global', 'tag_local', 'tag_global', 'tagpath', 'global', 'set' + 'tags', + 'tag_global', + 'tag_local', + 'tag_global', + 'tagpath', + 'global', + 'set', }) -- Note: v:option_old is the old global value for global-local options. @@ -274,26 +293,48 @@ describe('au OptionSet', function() command('noa set tags=tag_global') command('noa setlocal tags=') command('set tags=tagpath') - expected_combination({'tags', 'tag_global', 'tag_global', 'tag_global', 'tagpath', 'global', 'set'}) + expected_combination({ + 'tags', + 'tag_global', + 'tag_global', + 'tag_global', + 'tagpath', + 'global', + 'set', + }) end) it('with string local (to buffer) option', function() local oldval = eval('&spelllang') command('set spelllang=elvish,klingon') - expected_combination({'spelllang', oldval, oldval, oldval, 'elvish,klingon', 'global', 'set'}) + expected_combination({ + 'spelllang', + oldval, + oldval, + oldval, + 'elvish,klingon', + 'global', + 'set', + }) command('set spelllang&') expected_combination({ - 'spelllang', 'elvish,klingon', 'elvish,klingon', 'elvish,klingon', oldval, 'global', 'set' + 'spelllang', + 'elvish,klingon', + 'elvish,klingon', + 'elvish,klingon', + oldval, + 'global', + 'set', }) command('setglobal spelllang=elvish') - expected_combination({'spelllang', oldval, '', oldval, 'elvish', 'global', 'setglobal'}) + expected_combination({ 'spelllang', oldval, '', oldval, 'elvish', 'global', 'setglobal' }) command('noa set spelllang&') command('setlocal spelllang=klingon') - expected_combination({'spelllang', oldval, oldval, '', 'klingon', 'local', 'setlocal'}) + expected_combination({ 'spelllang', oldval, oldval, '', 'klingon', 'local', 'setlocal' }) -- Note: v:option_old is the old global value for global-local options. -- but the old local value for all other kinds of options. @@ -301,7 +342,13 @@ describe('au OptionSet', function() command('noa setlocal spelllang=spelllocal') command('set spelllang=foo') expected_combination({ - 'spelllang', 'spelllocal', 'spelllocal', 'spellglobal', 'foo', 'global', 'set' + 'spelllang', + 'spelllocal', + 'spelllocal', + 'spellglobal', + 'foo', + 'global', + 'set', }) end) @@ -309,259 +356,257 @@ describe('au OptionSet', function() local oldval = eval('&statusline') command('set statusline=foo') - expected_combination({'statusline', oldval, oldval, '', 'foo', 'global', 'set'}) + expected_combination({ 'statusline', oldval, oldval, '', 'foo', 'global', 'set' }) -- Note: v:option_old is the old global value for global-local options. -- but the old local value for all other kinds of options. command('set statusline&') - expected_combination({'statusline', 'foo', 'foo', 'foo', oldval, 'global', 'set'}) + expected_combination({ 'statusline', 'foo', 'foo', 'foo', oldval, 'global', 'set' }) command('setglobal statusline=bar') - expected_combination({'statusline', oldval, '', oldval, 'bar', 'global', 'setglobal'}) + expected_combination({ 'statusline', oldval, '', oldval, 'bar', 'global', 'setglobal' }) command('noa set statusline&') command('setlocal statusline=baz') - expected_combination({'statusline', oldval, oldval, '', 'baz', 'local', 'setlocal'}) + expected_combination({ 'statusline', oldval, oldval, '', 'baz', 'local', 'setlocal' }) -- Note: v:option_old is the old global value for global-local options. -- but the old local value for all other kinds of options. command('noa setglobal statusline=bar') command('noa setlocal statusline=baz') command('set statusline=foo') - expected_combination({'statusline', 'bar', 'baz', 'bar', 'foo', 'global', 'set'}) + expected_combination({ 'statusline', 'bar', 'baz', 'bar', 'foo', 'global', 'set' }) end) it('with string local (to window) option', function() local oldval = eval('&foldignore') command('set foldignore=fo') - expected_combination({'foldignore', oldval, oldval, oldval, 'fo', 'global', 'set'}) + expected_combination({ 'foldignore', oldval, oldval, oldval, 'fo', 'global', 'set' }) command('set foldignore&') - expected_combination({'foldignore', 'fo', 'fo', 'fo', oldval, 'global', 'set'}) + expected_combination({ 'foldignore', 'fo', 'fo', 'fo', oldval, 'global', 'set' }) command('setglobal foldignore=bar') - expected_combination({'foldignore', oldval, '', oldval, 'bar', 'global', 'setglobal'}) + expected_combination({ 'foldignore', oldval, '', oldval, 'bar', 'global', 'setglobal' }) command('noa set foldignore&') command('setlocal foldignore=baz') - expected_combination({'foldignore', oldval, oldval, '', 'baz', 'local', 'setlocal'}) + expected_combination({ 'foldignore', oldval, oldval, '', 'baz', 'local', 'setlocal' }) command('noa setglobal foldignore=glob') command('noa setlocal foldignore=loc') command('set foldignore=fo') - expected_combination({'foldignore', 'loc', 'loc', 'glob', 'fo', 'global', 'set'}) + expected_combination({ 'foldignore', 'loc', 'loc', 'glob', 'fo', 'global', 'set' }) end) it('with number global option', function() command('noa setglobal cmdheight=8') command('noa setlocal cmdheight=1') -- Sets the global(!) value command('setglobal cmdheight=2') - expected_combination({'cmdheight', 1, '', 1, 2, 'global', 'setglobal'}) + expected_combination({ 'cmdheight', 1, '', 1, 2, 'global', 'setglobal' }) command('noa setglobal cmdheight=8') command('noa setlocal cmdheight=1') -- Sets the global(!) value command('setlocal cmdheight=2') - expected_combination({'cmdheight', 1, 1, '', 2, 'local', 'setlocal'}) + expected_combination({ 'cmdheight', 1, 1, '', 2, 'local', 'setlocal' }) -- Note: v:option_old is the old global value for global-local options. -- but the old local value for all other kinds of options. command('noa setglobal cmdheight=8') command('noa setlocal cmdheight=1') -- Sets the global(!) value command('set cmdheight=2') - expected_combination({'cmdheight', 1, 1, 1, 2, 'global', 'set'}) + expected_combination({ 'cmdheight', 1, 1, 1, 2, 'global', 'set' }) -- Note: v:option_old is the old global value for global-local options. -- but the old local value for all other kinds of options. command('noa set cmdheight=8') command('set cmdheight=2') - expected_combination({'cmdheight', 8, 8, 8, 2, 'global', 'set'}) + expected_combination({ 'cmdheight', 8, 8, 8, 2, 'global', 'set' }) end) it('with number global-local (to buffer) option', function() command('noa setglobal undolevels=8') command('noa setlocal undolevels=1') command('setglobal undolevels=2') - expected_combination({'undolevels', 8, '', 8, 2, 'global', 'setglobal'}) + expected_combination({ 'undolevels', 8, '', 8, 2, 'global', 'setglobal' }) command('noa setglobal undolevels=8') command('noa setlocal undolevels=1') command('setlocal undolevels=2') - expected_combination({'undolevels', 1, 1, '', 2, 'local', 'setlocal'}) + expected_combination({ 'undolevels', 1, 1, '', 2, 'local', 'setlocal' }) -- Note: v:option_old is the old global value for global-local options. -- but the old local value for all other kinds of options. command('noa setglobal undolevels=8') command('noa setlocal undolevels=1') command('set undolevels=2') - expected_combination({'undolevels', 8, 1, 8, 2, 'global', 'set'}) + expected_combination({ 'undolevels', 8, 1, 8, 2, 'global', 'set' }) -- Note: v:option_old is the old global value for global-local options. -- but the old local value for all other kinds of options. command('noa set undolevels=8') command('set undolevels=2') - expected_combination({'undolevels', 8, 8, 8, 2, 'global', 'set'}) + expected_combination({ 'undolevels', 8, 8, 8, 2, 'global', 'set' }) end) it('with number local (to buffer) option', function() command('noa setglobal wrapmargin=8') command('noa setlocal wrapmargin=1') command('setglobal wrapmargin=2') - expected_combination({'wrapmargin', 8, '', 8, 2, 'global', 'setglobal'}) + expected_combination({ 'wrapmargin', 8, '', 8, 2, 'global', 'setglobal' }) command('noa setglobal wrapmargin=8') command('noa setlocal wrapmargin=1') command('setlocal wrapmargin=2') - expected_combination({'wrapmargin', 1, 1, '', 2, 'local', 'setlocal'}) + expected_combination({ 'wrapmargin', 1, 1, '', 2, 'local', 'setlocal' }) command('noa setglobal wrapmargin=8') command('noa setlocal wrapmargin=1') command('set wrapmargin=2') - expected_combination({'wrapmargin', 1, 1, 8, 2, 'global', 'set'}) + expected_combination({ 'wrapmargin', 1, 1, 8, 2, 'global', 'set' }) command('noa set wrapmargin=8') command('set wrapmargin=2') - expected_combination({'wrapmargin', 8, 8, 8, 2, 'global', 'set'}) + expected_combination({ 'wrapmargin', 8, 8, 8, 2, 'global', 'set' }) end) it('with number global-local (to window) option', function() command('noa setglobal scrolloff=8') command('noa setlocal scrolloff=1') command('setglobal scrolloff=2') - expected_combination({'scrolloff', 8, '', 8, 2, 'global', 'setglobal'}) + expected_combination({ 'scrolloff', 8, '', 8, 2, 'global', 'setglobal' }) command('noa setglobal scrolloff=8') command('noa setlocal scrolloff=1') command('setlocal scrolloff=2') - expected_combination({'scrolloff', 1, 1, '', 2, 'local', 'setlocal'}) + expected_combination({ 'scrolloff', 1, 1, '', 2, 'local', 'setlocal' }) -- Note: v:option_old is the old global value for global-local options. -- but the old local value for all other kinds of options. command('noa setglobal scrolloff=8') command('noa setlocal scrolloff=1') command('set scrolloff=2') - expected_combination({'scrolloff', 8, 1, 8, 2, 'global', 'set'}) + expected_combination({ 'scrolloff', 8, 1, 8, 2, 'global', 'set' }) -- Note: v:option_old is the old global value for global-local options. -- but the old local value for all other kinds of options. command('noa set scrolloff=8') command('set scrolloff=2') - expected_combination({'scrolloff', 8, 8, 8, 2, 'global', 'set'}) + expected_combination({ 'scrolloff', 8, 8, 8, 2, 'global', 'set' }) end) it('with number local (to window) option', function() command('noa setglobal foldcolumn=8') command('noa setlocal foldcolumn=1') command('setglobal foldcolumn=2') - expected_combination({'foldcolumn', '8', '', '8', '2', 'global', 'setglobal'}) + expected_combination({ 'foldcolumn', '8', '', '8', '2', 'global', 'setglobal' }) command('noa setglobal foldcolumn=8') command('noa setlocal foldcolumn=1') command('setlocal foldcolumn=2') - expected_combination({'foldcolumn', '1', '1', '', '2', 'local', 'setlocal'}) + expected_combination({ 'foldcolumn', '1', '1', '', '2', 'local', 'setlocal' }) command('noa setglobal foldcolumn=8') command('noa setlocal foldcolumn=1') command('set foldcolumn=2') - expected_combination({'foldcolumn', '1', '1', '8', '2', 'global', 'set'}) + expected_combination({ 'foldcolumn', '1', '1', '8', '2', 'global', 'set' }) command('noa set foldcolumn=8') command('set foldcolumn=2') - expected_combination({'foldcolumn', '8', '8', '8', '2', 'global', 'set'}) + expected_combination({ 'foldcolumn', '8', '8', '8', '2', 'global', 'set' }) end) it('with boolean global option', function() command('noa setglobal nowrapscan') command('noa setlocal wrapscan') -- Sets the global(!) value command('setglobal nowrapscan') - expected_combination({'wrapscan', true, '', true, false, 'global', 'setglobal'}) + expected_combination({ 'wrapscan', true, '', true, false, 'global', 'setglobal' }) command('noa setglobal nowrapscan') command('noa setlocal wrapscan') -- Sets the global(!) value command('setlocal nowrapscan') - expected_combination({'wrapscan', true, true, '', false, 'local', 'setlocal'}) + expected_combination({ 'wrapscan', true, true, '', false, 'local', 'setlocal' }) command('noa setglobal nowrapscan') command('noa setlocal wrapscan') -- Sets the global(!) value command('set nowrapscan') - expected_combination({'wrapscan', true, true, true, false, 'global', 'set'}) + expected_combination({ 'wrapscan', true, true, true, false, 'global', 'set' }) command('noa set nowrapscan') command('set wrapscan') - expected_combination({'wrapscan', false, false, false, true, 'global', 'set'}) + expected_combination({ 'wrapscan', false, false, false, true, 'global', 'set' }) end) it('with boolean global-local (to buffer) option', function() command('noa setglobal noautoread') command('noa setlocal autoread') command('setglobal autoread') - expected_combination({'autoread', false, '', false, true, 'global', 'setglobal'}) + expected_combination({ 'autoread', false, '', false, true, 'global', 'setglobal' }) command('noa setglobal noautoread') command('noa setlocal autoread') command('setlocal noautoread') - expected_combination({'autoread', true, true, '', false, 'local', 'setlocal'}) + expected_combination({ 'autoread', true, true, '', false, 'local', 'setlocal' }) -- Note: v:option_old is the old global value for global-local options. -- but the old local value for all other kinds of options. command('noa setglobal noautoread') command('noa setlocal autoread') command('set autoread') - expected_combination({'autoread', false, true, false, true, 'global', 'set'}) + expected_combination({ 'autoread', false, true, false, true, 'global', 'set' }) -- Note: v:option_old is the old global value for global-local options. -- but the old local value for all other kinds of options. command('noa set noautoread') command('set autoread') - expected_combination({'autoread', false, false, false, true, 'global', 'set'}) + expected_combination({ 'autoread', false, false, false, true, 'global', 'set' }) end) it('with boolean local (to buffer) option', function() command('noa setglobal nocindent') command('noa setlocal cindent') command('setglobal cindent') - expected_combination({'cindent', false, '', false, true, 'global', 'setglobal'}) + expected_combination({ 'cindent', false, '', false, true, 'global', 'setglobal' }) command('noa setglobal nocindent') command('noa setlocal cindent') command('setlocal nocindent') - expected_combination({'cindent', true, true, '', false, 'local', 'setlocal'}) + expected_combination({ 'cindent', true, true, '', false, 'local', 'setlocal' }) command('noa setglobal nocindent') command('noa setlocal cindent') command('set cindent') - expected_combination({'cindent', true, true, false, true, 'global', 'set'}) + expected_combination({ 'cindent', true, true, false, true, 'global', 'set' }) command('noa set nocindent') command('set cindent') - expected_combination({'cindent', false, false, false, true, 'global', 'set'}) + expected_combination({ 'cindent', false, false, false, true, 'global', 'set' }) end) it('with boolean local (to window) option', function() command('noa setglobal nocursorcolumn') command('noa setlocal cursorcolumn') command('setglobal cursorcolumn') - expected_combination({'cursorcolumn', false, '', false, true, 'global', 'setglobal'}) + expected_combination({ 'cursorcolumn', false, '', false, true, 'global', 'setglobal' }) command('noa setglobal nocursorcolumn') command('noa setlocal cursorcolumn') command('setlocal nocursorcolumn') - expected_combination({'cursorcolumn', true, true, '', false, 'local', 'setlocal'}) + expected_combination({ 'cursorcolumn', true, true, '', false, 'local', 'setlocal' }) command('noa setglobal nocursorcolumn') command('noa setlocal cursorcolumn') command('set cursorcolumn') - expected_combination({'cursorcolumn', true, true, false, true, 'global', 'set'}) + expected_combination({ 'cursorcolumn', true, true, false, true, 'global', 'set' }) command('noa set nocursorcolumn') command('set cursorcolumn') - expected_combination({'cursorcolumn', false, false, false, true, 'global', 'set'}) + expected_combination({ 'cursorcolumn', false, false, false, true, 'global', 'set' }) end) - end) describe('with specific option', function() - before_each(function() clear() declare_hook_function() @@ -575,13 +620,13 @@ describe('au OptionSet', function() expected_empty() command('setlocal ro') - expected_combination({'readonly', false, false, '', true, 'local', 'setlocal'}) + expected_combination({ 'readonly', false, false, '', true, 'local', 'setlocal' }) command('setglobal ro') - expected_combination({'readonly', false, '', false, true, 'global', 'setglobal'}) + expected_combination({ 'readonly', false, '', false, true, 'global', 'setglobal' }) command('set noro') - expected_combination({'readonly', true, true, true, false, 'global', 'set'}) + expected_combination({ 'readonly', true, true, true, false, 'global', 'set' }) end) describe('being set by setbufvar()', function() @@ -596,18 +641,26 @@ describe('au OptionSet', function() set_hook('backup') command('call setbufvar(1, "&backup", 1)') - expected_combination({'backup', false, false, '', true, 'local', 'setlocal'}) + expected_combination({ 'backup', false, false, '', true, 'local', 'setlocal' }) end) it('should trigger if the current buffer is different from the targeted buffer', function() set_hook('buftype') local new_buffer = make_buffer() - local new_bufnr = buf.get_number(new_buffer) + local new_bufnr = api.nvim_buf_get_number(new_buffer) command('call setbufvar(' .. new_bufnr .. ', "&buftype", "nofile")') - expected_combination({ 'buftype', '', '', '', 'nofile', 'local', 'setlocal', - { bufnr = new_bufnr } }) + expected_combination({ + 'buftype', + '', + '', + '', + 'nofile', + 'local', + 'setlocal', + { bufnr = new_bufnr }, + }) end) end) @@ -623,43 +676,54 @@ describe('au OptionSet', function() set_hook('backup') command('call setwinvar(1, "&backup", 1)') - expected_combination({'backup', false, false, '', true, 'local', 'setlocal'}) + expected_combination({ 'backup', false, false, '', true, 'local', 'setlocal' }) end) - it('should not trigger if the current window is different from the targeted window', function() - set_hook('cursorcolumn') + it( + 'should not trigger if the current window is different from the targeted window', + function() + set_hook('cursorcolumn') - local new_winnr = get_new_window_number() + local new_winnr = get_new_window_number() - command('call setwinvar(' .. new_winnr .. ', "&cursorcolumn", 1)') - -- expected_combination({'cursorcolumn', false, true, 'local', {winnr = new_winnr}}) - expected_empty() - end) + command('call setwinvar(' .. new_winnr .. ', "&cursorcolumn", 1)') + -- expected_combination({'cursorcolumn', false, true, 'local', {winnr = new_winnr}}) + expected_empty() + end + ) end) describe('being set by neovim api', function() it('should trigger if a boolean option be set globally', function() set_hook('autochdir') - nvim.set_option_value('autochdir', true, {scope='global'}) - eq(true, nvim.get_option_value('autochdir', {scope='global'})) - expected_combination({'autochdir', false, '', false, true, 'global', 'setglobal'}) + nvim.nvim_set_option_value('autochdir', true, { scope = 'global' }) + eq(true, nvim.nvim_get_option_value('autochdir', { scope = 'global' })) + expected_combination({ 'autochdir', false, '', false, true, 'global', 'setglobal' }) end) it('should trigger if a number option be set globally', function() set_hook('cmdheight') - nvim.set_option_value('cmdheight', 5, {scope='global'}) - eq(5, nvim.get_option_value('cmdheight', {scope='global'})) - expected_combination({'cmdheight', 1, '', 1, 5, 'global', 'setglobal'}) + nvim.nvim_set_option_value('cmdheight', 5, { scope = 'global' }) + eq(5, nvim.nvim_get_option_value('cmdheight', { scope = 'global' })) + expected_combination({ 'cmdheight', 1, '', 1, 5, 'global', 'setglobal' }) end) it('should trigger if a string option be set globally', function() set_hook('ambiwidth') - nvim.set_option_value('ambiwidth', 'double', {scope='global'}) - eq('double', nvim.get_option_value('ambiwidth', {scope='global'})) - expected_combination({'ambiwidth', 'single', '', 'single', 'double', 'global', 'setglobal'}) + nvim.nvim_set_option_value('ambiwidth', 'double', { scope = 'global' }) + eq('double', nvim.nvim_get_option_value('ambiwidth', { scope = 'global' })) + expected_combination({ + 'ambiwidth', + 'single', + '', + 'single', + 'double', + 'global', + 'setglobal', + }) end) end) end) diff --git a/test/functional/legacy/autocmd_spec.lua b/test/functional/legacy/autocmd_spec.lua new file mode 100644 index 0000000000..97051f3d3f --- /dev/null +++ b/test/functional/legacy/autocmd_spec.lua @@ -0,0 +1,40 @@ +local helpers = require('test.functional.helpers')(after_each) +local clear = helpers.clear +local write_file = helpers.write_file +local command = helpers.command +local feed = helpers.feed +local api = helpers.api +local eq = helpers.eq + +before_each(clear) + +-- oldtest: Test_autocmd_invalidates_undo_on_textchanged() +it('no E440 in quickfix window when autocommand invalidates undo', function() + write_file( + 'XTest_autocmd_invalidates_undo_on_textchanged', + [[ + set hidden + " create quickfix list (at least 2 lines to move line) + vimgrep /u/j % + + " enter quickfix window + cwindow + + " set modifiable + setlocal modifiable + + " set autocmd to clear quickfix list + + autocmd! TextChanged <buffer> call setqflist([]) + " move line + move+1 + ]] + ) + finally(function() + os.remove('XTest_autocmd_invalidates_undo_on_textchanged') + end) + command('edit XTest_autocmd_invalidates_undo_on_textchanged') + command('so %') + feed('G') + eq('', api.nvim_get_vvar('errmsg')) +end) diff --git a/test/functional/legacy/breakindent_spec.lua b/test/functional/legacy/breakindent_spec.lua index 3913ba935a..cf0065f394 100644 --- a/test/functional/legacy/breakindent_spec.lua +++ b/test/functional/legacy/breakindent_spec.lua @@ -12,9 +12,9 @@ describe('breakindent', function() it('cursor shown at correct position with showbreak', function() local screen = Screen.new(75, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {background = Screen.colors.Grey, foreground = Screen.colors.DarkBlue}, -- SignColumn - [2] = {bold = true}, -- ModeMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { background = Screen.colors.Grey, foreground = Screen.colors.DarkBlue }, -- SignColumn + [2] = { bold = true }, -- ModeMsg }) screen:attach() exec([[ @@ -26,13 +26,12 @@ describe('breakindent', function() eval repeat('x', &columns - leftcol - 1)->setline(1) eval 'second line'->setline(2) ]]) + feed('AX') screen:expect([[ {1: }xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxX| {1: }^second line | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {2:-- INSERT --} | ]]) -- No line wraps, so changing 'showbreak' should lead to the same screen. @@ -43,22 +42,75 @@ describe('breakindent', function() screen:expect_unchanged() -- The first line now wraps because of "eol" in 'listchars'. command('setlocal list') - screen:expect{grid=[[ + screen:expect([[ {1: }xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxX| {1: } {0:+^$} | {1: }second line{0:$} | - {0:~ }| - {0:~ }| + {0:~ }|*2 {2:-- INSERT --} | - ]]} + ]]) command('setlocal nobreakindent') - screen:expect{grid=[[ + screen:expect([[ {1: }xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxX| {1: }{0:+^$} | {1: }second line{0:$} | + {0:~ }|*2 + {2:-- INSERT --} | + ]]) + end) + + -- oldtest: Test_visual_starts_before_skipcol() + it('Visual selection that starts before skipcol shows correctly', function() + local screen = Screen.new(75, 6) + exec([[ + 1new + setlocal breakindent + call setline(1, "\t" .. join(range(100))) + ]]) + screen:set_default_attr_ids({ + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { background = Screen.colors.LightGrey, foreground = Screen.colors.Black }, -- Visual + [2] = { bold = true, reverse = true }, -- StatusLine + [3] = { reverse = true }, -- StatusLineNC + [4] = { bold = true }, -- ModeMsg + }) + screen:attach() + + feed('v$') + screen:expect([[ + {0:<<<} {1: 93 94 95 96 97 98 99}^ | + {2:[No Name] [+] }| + | {0:~ }| + {3:[No Name] }| + {4:-- VISUAL --} | + ]]) + command('setlocal showbreak=+++') + screen:expect([[ + {0:+++}{1: 90 91 92 93 94 95 96 97 98 99}^ | + {2:[No Name] [+] }| + | {0:~ }| - {2:-- INSERT --} | - ]]} + {3:[No Name] }| + {4:-- VISUAL --} | + ]]) + command('setlocal breakindentopt+=sbr') + screen:expect([[ + {0:+++} {1: 93 94 95 96 97 98 99}^ | + {2:[No Name] [+] }| + | + {0:~ }| + {3:[No Name] }| + {4:-- VISUAL --} | + ]]) + command('setlocal nobreakindent') + screen:expect([[ + {0:+++}{1: 98 99}^ | + {2:[No Name] [+] }| + | + {0:~ }| + {3:[No Name] }| + {4:-- VISUAL --} | + ]]) end) end) diff --git a/test/functional/legacy/buffer_spec.lua b/test/functional/legacy/buffer_spec.lua index 1e8909f0d0..b3964540f0 100644 --- a/test/functional/legacy/buffer_spec.lua +++ b/test/functional/legacy/buffer_spec.lua @@ -1,16 +1,16 @@ local helpers = require('test.functional.helpers')(after_each) local clear, source = helpers.clear, helpers.source -local call, eq, meths = helpers.call, helpers.eq, helpers.meths +local call, eq, api = helpers.call, helpers.eq, helpers.api local function expected_empty() - eq({}, meths.get_vvar('errors')) + eq({}, api.nvim_get_vvar('errors')) end describe('buffer', function() before_each(function() clear() - meths.ui_attach(80, 24, {}) - meths.set_option_value('hidden', false, {}) + api.nvim_ui_attach(80, 24, {}) + api.nvim_set_option_value('hidden', false, {}) end) it('deleting a modified buffer with :confirm', function() diff --git a/test/functional/legacy/changelist_spec.lua b/test/functional/legacy/changelist_spec.lua index 72c9872163..b673e74128 100644 --- a/test/functional/legacy/changelist_spec.lua +++ b/test/functional/legacy/changelist_spec.lua @@ -9,7 +9,7 @@ describe('changelist', function() setup(clear) it('is working', function() - insert("1\n2") + insert('1\n2') feed('Gkylp') feed_command('set ul=100') diff --git a/test/functional/legacy/close_count_spec.lua b/test/functional/legacy/close_count_spec.lua index 60ae155fbf..930dae668a 100644 --- a/test/functional/legacy/close_count_spec.lua +++ b/test/functional/legacy/close_count_spec.lua @@ -19,20 +19,20 @@ describe('close_count', function() command('close!') command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({6, 5, 4, 2, 1}, eval('buffers')) + eq({ 6, 5, 4, 2, 1 }, eval('buffers')) command('1close!') command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({5, 4, 2, 1}, eval('buffers')) + eq({ 5, 4, 2, 1 }, eval('buffers')) command('$close!') command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({5, 4, 2}, eval('buffers')) + eq({ 5, 4, 2 }, eval('buffers')) command('1wincmd w') command('2close!') command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({5, 2}, eval('buffers')) + eq({ 5, 2 }, eval('buffers')) command('1wincmd w') command('new') command('new') @@ -40,37 +40,37 @@ describe('close_count', function() command('-1close!') command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({7, 5, 2}, eval('buffers')) + eq({ 7, 5, 2 }, eval('buffers')) command('2wincmd w') command('+1close!') command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({7, 5}, eval('buffers')) + eq({ 7, 5 }, eval('buffers')) command('only!') command('b1') command('let tests = []') command('for i in range(5)|new|endfor') command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({13, 12, 11, 10, 9, 1}, eval('buffers')) + eq({ 13, 12, 11, 10, 9, 1 }, eval('buffers')) command('4wincmd w') command('.hide') command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({13, 12, 11, 9, 1}, eval('buffers')) + eq({ 13, 12, 11, 9, 1 }, eval('buffers')) command('1hide') command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({12, 11, 9, 1}, eval('buffers')) + eq({ 12, 11, 9, 1 }, eval('buffers')) command('$hide') command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({12, 11, 9}, eval('buffers')) + eq({ 12, 11, 9 }, eval('buffers')) command('1wincmd w') command('2hide') command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({12, 9}, eval('buffers')) + eq({ 12, 9 }, eval('buffers')) command('1wincmd w') command('new') command('new') @@ -78,12 +78,12 @@ describe('close_count', function() command('-hide') command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({15, 12, 9}, eval('buffers')) + eq({ 15, 12, 9 }, eval('buffers')) command('2wincmd w') command('+hide') command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({15, 12}, eval('buffers')) + eq({ 15, 12 }, eval('buffers')) command('only!') command('b1') command('let tests = []') @@ -93,16 +93,16 @@ describe('close_count', function() command('$ hide') command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({20, 19, 18, 17, 16}, eval('buffers')) + eq({ 20, 19, 18, 17, 16 }, eval('buffers')) command('$-1 close!') command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({20, 19, 18, 16}, eval('buffers')) + eq({ 20, 19, 18, 16 }, eval('buffers')) command('1wincmd w') command('.+close!') command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({20, 18, 16}, eval('buffers')) + eq({ 20, 18, 16 }, eval('buffers')) command('only!') command('b1') command('let tests = []') @@ -113,22 +113,22 @@ describe('close_count', function() poke_eventloop() command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({25, 24, 23, 21, 1}, eval('buffers')) + eq({ 25, 24, 23, 21, 1 }, eval('buffers')) feed('1<C-W>c<cr>') poke_eventloop() command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({24, 23, 21, 1}, eval('buffers')) + eq({ 24, 23, 21, 1 }, eval('buffers')) feed('9<C-W>c<cr>') poke_eventloop() command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({24, 23, 21}, eval('buffers')) + eq({ 24, 23, 21 }, eval('buffers')) command('1wincmd w') feed('2<C-W>c<cr>') poke_eventloop() command('let buffers = []') command('windo call add(buffers, bufnr("%"))') - eq({24, 21}, eval('buffers')) + eq({ 24, 21 }, eval('buffers')) end) end) diff --git a/test/functional/legacy/cmdline_spec.lua b/test/functional/legacy/cmdline_spec.lua index 3cbff2a01b..8c94451f9a 100644 --- a/test/functional/legacy/cmdline_spec.lua +++ b/test/functional/legacy/cmdline_spec.lua @@ -5,8 +5,8 @@ local command = helpers.command local feed = helpers.feed local feed_command = helpers.feed_command local exec = helpers.exec -local meths = helpers.meths -local pesc = helpers.pesc +local api = helpers.api +local pesc = vim.pesc describe('cmdline', function() before_each(clear) @@ -16,10 +16,10 @@ describe('cmdline', function() local screen = Screen.new(30, 10) screen:attach() screen:set_default_attr_ids { - [1] = {underline = true, background = Screen.colors.LightGrey}; - [2] = {bold = true}; - [3] = {reverse = true}; - [4] = {bold = true, foreground = Screen.colors.Blue1}; + [1] = { underline = true, background = Screen.colors.LightGrey }, + [2] = { bold = true }, + [3] = { reverse = true }, + [4] = { bold = true, foreground = Screen.colors.Blue1 }, } feed_command([[call setline(1, range(30))]]) @@ -37,35 +37,28 @@ describe('cmdline', function() ]]) feed [[:tabnew<cr>]] - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: + [No Name] }{2: [No Name] }{3: }{1:X}| ^ | - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*7 :tabnew | - ]]} + ]], + } feed [[<C-w>-<C-w>-]] - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: + [No Name] }{2: [No Name] }{3: }{1:X}| ^ | - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| - | - | - | - ]]} + {4:~ }|*5 + |*3 + ]], + } feed [[gt]] - screen:expect{grid=[[ + screen:expect { + grid = [[ {2: + [No Name] }{1: [No Name] }{3: }{1:X}| ^0 | 1 | @@ -76,20 +69,15 @@ describe('cmdline', function() 6 | 7 | | - ]]} + ]], + } feed [[gt]] screen:expect([[ {1: + [No Name] }{2: [No Name] }{3: }{1:X}| ^ | - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| - | - | - | + {4:~ }|*5 + |*3 ]]) end) @@ -105,8 +93,7 @@ describe('cmdline', function() feed_command('DoSomething') screen:expect([[ | - ~ | - ~ | + ~ |*2 | Executing: DoSomething | Executing: echo 'hello' |set ts=4 |let v = '123' |echo v | @@ -123,8 +110,8 @@ describe('cmdline', function() it('tabline is redrawn on entering cmdline', function() local screen = Screen.new(30, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {reverse = true}, -- TabLineFill + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { reverse = true }, -- TabLineFill }) screen:attach() exec([[ @@ -135,9 +122,7 @@ describe('cmdline', function() screen:expect([[ {1:foo }| | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 :^ | ]]) end) @@ -146,7 +131,7 @@ describe('cmdline', function() it('cmdline cursor position is correct after :redraw with cmdheight=2', function() local screen = Screen.new(30, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText }) screen:attach() exec([[ @@ -156,9 +141,7 @@ describe('cmdline', function() feed(':for i in range(3)<CR>') screen:expect([[ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 :for i in range(3) | : ^ | ]]) @@ -166,9 +149,7 @@ describe('cmdline', function() -- Note: this may still be considered broken, ref #18140 screen:expect([[ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 : :let i =^ | | ]]) @@ -177,8 +158,8 @@ describe('cmdline', function() it("setting 'cmdheight' works after outputting two messages vim-patch:9.0.0665", function() local screen = Screen.new(60, 8) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {bold = true, reverse = true}, -- StatusLine + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { bold = true, reverse = true }, -- StatusLine }) screen:attach() exec([[ @@ -194,22 +175,14 @@ describe('cmdline', function() feed(':call EchoTwo()') screen:expect([[ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {1:[No Name] }| :call EchoTwo()^ | ]]) feed('<CR>') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {1:[No Name] }| | ]]) @@ -219,22 +192,19 @@ describe('cmdline', function() it("changing 'cmdheight' when there is a tabline", function() local screen = Screen.new(60, 8) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {bold = true, reverse = true}, -- StatusLine - [2] = {bold = true}, -- TabLineSel - [3] = {reverse = true}, -- TabLineFill + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { bold = true, reverse = true }, -- StatusLine + [2] = { bold = true }, -- TabLineSel + [3] = { reverse = true }, -- TabLineFill }) screen:attach() - meths.set_option_value('laststatus', 2, {}) - meths.set_option_value('showtabline', 2, {}) - meths.set_option_value('cmdheight', 1, {}) + api.nvim_set_option_value('laststatus', 2, {}) + api.nvim_set_option_value('showtabline', 2, {}) + api.nvim_set_option_value('cmdheight', 1, {}) screen:expect([[ {2: [No Name] }{3: }| ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {1:[No Name] }| | ]]) @@ -244,13 +214,13 @@ describe('cmdline', function() it("ruler has correct position with 'rulerformat' set", function() local screen = Screen.new(20, 3) screen:set_default_attr_ids { - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText } screen:attach() - meths.set_option_value('ruler', true, {}) - meths.set_option_value('rulerformat', 'longish', {}) - meths.set_option_value('laststatus', 0, {}) - meths.set_option_value('winwidth', 1, {}) + api.nvim_set_option_value('ruler', true, {}) + api.nvim_set_option_value('rulerformat', 'longish', {}) + api.nvim_set_option_value('laststatus', 0, {}) + api.nvim_set_option_value('winwidth', 1, {}) feed [[<C-W>v<C-W>|<C-W>p]] screen:expect [[ │^ | @@ -267,72 +237,41 @@ describe('cmdwin', function() it('still uses a new buffer when interrupting more prompt on open', function() local screen = Screen.new(30, 16) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {bold = true, reverse = true}, -- StatusLine - [2] = {reverse = true}, -- StatusLineNC - [3] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg - [4] = {bold = true}, -- ModeMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { bold = true, reverse = true }, -- StatusLine + [2] = { reverse = true }, -- StatusLineNC + [3] = { bold = true, foreground = Screen.colors.SeaGreen }, -- MoreMsg + [4] = { bold = true }, -- ModeMsg }) screen:attach() command('set more') command('autocmd WinNew * highlight') feed('q:') - screen:expect({any = pesc('{3:-- More --}^')}) + screen:expect({ any = pesc('{3:-- More --}^') }) feed('q') screen:expect([[ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {2:[No Name] }| {0::}^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 {1:[Command Line] }| | ]]) feed([[aecho 'done']]) screen:expect([[ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {2:[No Name] }| {0::}echo 'done'^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 {1:[Command Line] }| {4:-- INSERT --} | ]]) feed('<CR>') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*14 done | ]]) end) diff --git a/test/functional/legacy/conceal_spec.lua b/test/functional/legacy/conceal_spec.lua index 6aaa93f886..9a23d16c5b 100644 --- a/test/functional/legacy/conceal_spec.lua +++ b/test/functional/legacy/conceal_spec.lua @@ -6,7 +6,7 @@ local exec = helpers.exec local feed = helpers.feed local expect_pos = function(row, col) - return helpers.eq({row, col}, helpers.eval('[screenrow(), screencol()]')) + return helpers.eq({ row, col }, helpers.eval('[screenrow(), screencol()]')) end describe('Conceal', function() @@ -19,10 +19,10 @@ describe('Conceal', function() it('works', function() local screen = Screen.new(75, 12) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {bold = true, reverse = true}, -- StatusLine - [2] = {reverse = true}, -- StatusLineNC, IncSearch - [3] = {bold = true}, -- ModeMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { bold = true, reverse = true }, -- StatusLine + [2] = { reverse = true }, -- StatusLineNC, IncSearch + [3] = { bold = true }, -- ModeMsg }) screen:attach() exec([[ @@ -386,9 +386,9 @@ describe('Conceal', function() it('CursorColumn and ColorColumn on wrapped line', function() local screen = Screen.new(40, 10) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {background = Screen.colors.Grey90}, -- CursorColumn - [2] = {background = Screen.colors.LightRed}, -- ColorColumn + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { background = Screen.colors.Grey90 }, -- CursorColumn + [2] = { background = Screen.colors.LightRed }, -- ColorColumn }) screen:attach() -- Check that cursorcolumn and colorcolumn don't get broken in presence of @@ -416,10 +416,7 @@ describe('Conceal', function() two two two two |hidden| ^here two two | three three three three {1:t}hree | {0: >>> }thre{2:e} three three three | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 /here | ]]) @@ -431,10 +428,7 @@ describe('Conceal', function() two two two two |hidden| here two tw^o | three three three three three | {0: >>> }thre{2:e} three three three | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 /here | ]]) end) @@ -443,8 +437,8 @@ describe('Conceal', function() it('resize editor', function() local screen = Screen.new(75, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {foreground = Screen.colors.Blue}, -- Comment + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { foreground = Screen.colors.Blue }, -- Comment }) screen:attach() exec([[ @@ -455,21 +449,14 @@ describe('Conceal', function() ]]) screen:expect([[ one two three four five, the ^backticks should be concealed | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) screen:try_resize(75, 7) screen:expect([[ one two three four five, the ^backticks should be concealed | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) end) @@ -478,7 +465,7 @@ describe('Conceal', function() it('with linebreak', function() local screen = Screen.new(75, 8) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText }) screen:attach() exec([[ @@ -501,8 +488,7 @@ describe('Conceal', function() aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | {0:+ }bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb | {0:+ }cccccc | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end) diff --git a/test/functional/legacy/cpoptions_spec.lua b/test/functional/legacy/cpoptions_spec.lua index d2f382ec12..288146199a 100644 --- a/test/functional/legacy/cpoptions_spec.lua +++ b/test/functional/legacy/cpoptions_spec.lua @@ -15,19 +15,13 @@ describe('cpoptions', function() feed('c2w') screen:expect([[ ^one tw$ three | - ~ | - ~ | - ~ | - ~ | + ~ |*4 -- INSERT -- | ]]) feed('vim<Esc>') screen:expect([[ vi^m three | - ~ | - ~ | - ~ | - ~ | + ~ |*4 | ]]) end) diff --git a/test/functional/legacy/crash_spec.lua b/test/functional/legacy/crash_spec.lua index 5094f81847..094bea253e 100644 --- a/test/functional/legacy/crash_spec.lua +++ b/test/functional/legacy/crash_spec.lua @@ -6,7 +6,6 @@ local feed = helpers.feed before_each(clear) --- oldtest: Test_crash1() it('no crash when ending Visual mode while editing buffer closes window', function() command('new') command('autocmd ModeChanged v:n ++once close') @@ -14,3 +13,21 @@ it('no crash when ending Visual mode while editing buffer closes window', functi command('enew') assert_alive() end) + +it('no crash when ending Visual mode close the window to switch to', function() + command('new') + command('autocmd ModeChanged v:n ++once only') + feed('v') + command('wincmd p') + assert_alive() +end) + +it('no crash when truncating overlong message', function() + pcall(command, 'source test/old/testdir/crash/vim_msg_trunc_poc') + assert_alive() +end) + +it('no crash with very long option error message', function() + pcall(command, 'source test/old/testdir/crash/poc_did_set_langmap') + assert_alive() +end) diff --git a/test/functional/legacy/debugger_spec.lua b/test/functional/legacy/debugger_spec.lua index e6fb81719f..7ed5e84da6 100644 --- a/test/functional/legacy/debugger_spec.lua +++ b/test/functional/legacy/debugger_spec.lua @@ -13,8 +13,8 @@ describe('debugger', function() before_each(function() screen = Screen.new(999, 10) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}; - [1] = {reverse = true, bold = true}; + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { reverse = true, bold = true }, }) screen:attach() end) @@ -30,20 +30,16 @@ describe('debugger', function() command(':let g:Xtest_var = 10') command(':breakadd expr g:Xtest_var') feed(':source %<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^let g:Xtest_var += 1{MATCH: *}| - {0:~{MATCH: *}}| - {0:~{MATCH: *}}| - {0:~{MATCH: *}}| - {0:~{MATCH: *}}| - {0:~{MATCH: *}}| - {0:~{MATCH: *}}| - {0:~{MATCH: *}}| - {0:~{MATCH: *}}| + {0:~{MATCH: *}}|*8 :source %{MATCH: *}| - ]]} + ]], + } feed(':source %<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ let g:Xtest_var += 1{MATCH: *}| {0:~{MATCH: *}}| {1:{MATCH: *}}| @@ -54,22 +50,19 @@ describe('debugger', function() {MATCH:.*}XdebugBreakExpr.vim{MATCH: *}| line 1: let g:Xtest_var += 1{MATCH: *}| >^{MATCH: *}| - ]]} + ]], + } feed('cont<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^let g:Xtest_var += 1{MATCH: *}| - {0:~{MATCH: *}}| - {0:~{MATCH: *}}| - {0:~{MATCH: *}}| - {0:~{MATCH: *}}| - {0:~{MATCH: *}}| - {0:~{MATCH: *}}| - {0:~{MATCH: *}}| - {0:~{MATCH: *}}| + {0:~{MATCH: *}}|*8 {MATCH: *}| - ]]} + ]], + } feed(':source %<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ let g:Xtest_var += 1{MATCH: *}| {0:~{MATCH: *}}| {1:{MATCH: *}}| @@ -80,6 +73,7 @@ describe('debugger', function() {MATCH:.*}XdebugBreakExpr.vim{MATCH: *}| line 1: let g:Xtest_var += 1{MATCH: *}| >^{MATCH: *}| - ]]} + ]], + } end) end) diff --git a/test/functional/legacy/delete_spec.lua b/test/functional/legacy/delete_spec.lua index 1b9ec9af62..1227065af2 100644 --- a/test/functional/legacy/delete_spec.lua +++ b/test/functional/legacy/delete_spec.lua @@ -49,9 +49,9 @@ describe('Test for delete()', function() it('symlink directory delete', function() command("call mkdir('Xdir1')") if helpers.is_os('win') then - command("silent !mklink /j Xlink Xdir1") + command('silent !mklink /j Xlink Xdir1') else - command("silent !ln -s Xdir1 Xlink") + command('silent !ln -s Xdir1 Xlink') end eq(1, eval("isdirectory('Xdir1')")) eq(1, eval("isdirectory('Xlink')")) diff --git a/test/functional/legacy/digraph_spec.lua b/test/functional/legacy/digraph_spec.lua index 7eeb83eb5f..015f144b74 100644 --- a/test/functional/legacy/digraph_spec.lua +++ b/test/functional/legacy/digraph_spec.lua @@ -10,36 +10,27 @@ describe('digraph', function() it('characters displayed on the screen', function() local screen = Screen.new(10, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {foreground = Screen.colors.Blue}, -- SpecialKey - [2] = {bold = true}, -- ModeMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { foreground = Screen.colors.Blue }, -- SpecialKey + [2] = { bold = true }, -- ModeMsg }) screen:attach() feed('i<C-K>') screen:expect([[ {1:^?} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {2:-- INSERT --}| ]]) feed('1') screen:expect([[ {1:^1} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {2:-- INSERT --}| ]]) feed('2') screen:expect([[ ½^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {2:-- INSERT --}| ]]) end) diff --git a/test/functional/legacy/display_spec.lua b/test/functional/legacy/display_spec.lua index 9c6f521882..153fad2e22 100644 --- a/test/functional/legacy/display_spec.lua +++ b/test/functional/legacy/display_spec.lua @@ -14,7 +14,7 @@ describe('display', function() local screen = Screen.new(20, 4) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true}, + [1] = { bold = true }, }) command([[call setline(1, repeat('a', 21))]]) @@ -32,9 +32,9 @@ describe('display', function() local screen = Screen.new(60, 8) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true}, -- ModeMsg - [2] = {background = Screen.colors.LightGrey}, -- Visual - [3] = {background = Screen.colors.Grey, foreground = Screen.colors.DarkBlue}, -- SignColumn + [1] = { bold = true }, -- ModeMsg + [2] = { background = Screen.colors.LightGrey, foreground = Screen.colors.Black }, -- Visual + [3] = { background = Screen.colors.Grey, foreground = Screen.colors.DarkBlue }, -- SignColumn }) exec([[ @@ -48,12 +48,7 @@ describe('display', function() feed('VG7kk') screen:expect([[ {3: }^f{2:oo} | - {3: }foo | - {3: }foo | - {3: }foo | - {3: }foo | - {3: }foo | - {3: }foo | + {3: }foo |*6 {1:-- VISUAL LINE --} | ]]) end) @@ -61,9 +56,9 @@ describe('display', function() local function run_test_display_lastline(euro) local screen = Screen.new(75, 10) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [2] = {bold = true, reverse = true}, -- StatusLine - [3] = {reverse = true}, -- StatusLineNC + [1] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [2] = { bold = true, reverse = true }, -- StatusLine + [3] = { reverse = true }, -- StatusLineNC }) screen:attach() exec([[ @@ -80,12 +75,9 @@ describe('display', function() end screen:expect((([[ ^a│aaa | - a│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - a│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| + a│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|*2 b│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb | - b│{1:~ }| - b│{1:~ }| - b│{1:~ }| + b│{1:~ }|*3 {1:@}│{1:~ }| {2:< }{3:[No Name] [+] }| | @@ -97,12 +89,9 @@ describe('display', function() command('100wincmd >') screen:expect((([[ ^aaa │a| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│a| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│a| + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│a|*2 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb │b| - {1:~ }│b| - {1:~ }│b| - {1:~ }│b| + {1:~ }│b|*3 {1:~ }│{1:@}| {2:[No Name] [+] }{3:<}| | @@ -119,8 +108,7 @@ describe('display', function() {1:@@@ }| {2:[No Name] [+] }| aaa | - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|*2 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb | {3:[No Name] [+] }| | @@ -133,9 +121,7 @@ describe('display', function() a │bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| bb│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| bb│bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb | - bb│{1:~ }| - bb│{1:~ }| - bb│{1:~ }| + bb│{1:~ }|*3 {1:@@}│{1:~ }| {2:< }{3:[No Name] [+] }| | @@ -164,17 +150,7 @@ describe('display', function() feed('736|') screen:expect([[ <<<aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|*11 ^aaaaaaaaaaaaaaa | | ]]) @@ -182,16 +158,7 @@ describe('display', function() feed('D') screen:expect([[ <<<aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|*10 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa^a| bbbbb bbbbb bbbbb bbbbb bbbbb bb@@@| | @@ -205,29 +172,14 @@ describe('display', function() bbbbb ccccc ccccc ccccc ccccc cccc| c ccccc ccccc ddddd ddddd ddddd ddd| dd ddddd ddddd ddddd | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*8 | ]]) -- "w_skipcol" is reset to bring the entire topline into view because -- the line length is now smaller than the current skipcol + marker. feed('x') screen:expect([[ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|*9 aa^a | bbbbb bbbbb bbbbb bbbbb bbbbb bbbbb| bbbbb ccccc ccccc ccccc ccccc cccc| @@ -246,11 +198,7 @@ describe('display', function() ]]) screen:expect([[ <<<bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|*5 b^b | | ]]) @@ -260,12 +208,7 @@ describe('display', function() feed('$0') screen:expect([[ <<<b^bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|*6 | ]]) -- Going to the start of the line with "b" did not set w_skipcol correctly with 'smoothscroll'. @@ -273,24 +216,14 @@ describe('display', function() feed('$b') screen:expect([[ 2 b ^bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|*6 | ]]) -- Same for "ge". feed('$ge') screen:expect([[ 2 ^b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|*6 | ]]) end) diff --git a/test/functional/legacy/edit_spec.lua b/test/functional/legacy/edit_spec.lua index 939999e21b..0762e5e671 100644 --- a/test/functional/legacy/edit_spec.lua +++ b/test/functional/legacy/edit_spec.lua @@ -4,7 +4,7 @@ local clear = helpers.clear local command = helpers.command local expect = helpers.expect local feed = helpers.feed -local sleep = helpers.sleep +local sleep = vim.uv.sleep before_each(clear) @@ -31,27 +31,21 @@ describe('edit', function() it('inserting a register using CTRL-R', function() local screen = Screen.new(10, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {foreground = Screen.colors.Blue}, -- SpecialKey - [2] = {bold = true}, -- ModeMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { foreground = Screen.colors.Blue }, -- SpecialKey + [2] = { bold = true }, -- ModeMsg }) screen:attach() feed('a<C-R>') screen:expect([[ {1:^"} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {2:-- INSERT --}| ]]) feed('=') screen:expect([[ {1:"} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 =^ | ]]) end) @@ -60,32 +54,26 @@ describe('edit', function() it('positioning cursor after CTRL-R expression failed', function() local screen = Screen.new(60, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {foreground = Screen.colors.Blue}, -- SpecialKey - [2] = {foreground = Screen.colors.SlateBlue}, - [3] = {bold = true}, -- ModeMsg - [4] = {reverse = true, bold = true}, -- MsgSeparator - [5] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg - [6] = {foreground = Screen.colors.SeaGreen, bold = true}, -- MoreMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { foreground = Screen.colors.Blue }, -- SpecialKey + [2] = { foreground = Screen.colors.SlateBlue }, + [3] = { bold = true }, -- ModeMsg + [4] = { reverse = true, bold = true }, -- MsgSeparator + [5] = { background = Screen.colors.Red, foreground = Screen.colors.White }, -- ErrorMsg + [6] = { foreground = Screen.colors.SeaGreen, bold = true }, -- MoreMsg }) screen:attach() feed('i<C-R>') screen:expect([[ {1:^"} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- INSERT --} | ]]) feed('={}') screen:expect([[ {1:"} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ={2:{}}^ | ]]) -- trying to insert a dictionary produces an error @@ -102,20 +90,14 @@ describe('edit', function() feed(':') screen:expect([[ :^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- INSERT --} | ]]) -- ending Insert mode should put the cursor back on the ':' feed('<Esc>') screen:expect([[ ^: | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) end) diff --git a/test/functional/legacy/erasebackword_spec.lua b/test/functional/legacy/erasebackword_spec.lua index 8ca64df328..46057fe599 100644 --- a/test/functional/legacy/erasebackword_spec.lua +++ b/test/functional/legacy/erasebackword_spec.lua @@ -8,7 +8,6 @@ describe('CTRL-W in Insert mode', function() -- luacheck: ignore 611 (Line contains only whitespaces) it('works for multi-byte characters', function() - for i = 1, 6 do feed('o wwwこんにちわ世界ワールドvim ' .. string.rep('<C-w>', i) .. '<esc>') end diff --git a/test/functional/legacy/eval_spec.lua b/test/functional/legacy/eval_spec.lua index c531c59fd1..21d0ce118d 100644 --- a/test/functional/legacy/eval_spec.lua +++ b/test/functional/legacy/eval_spec.lua @@ -11,7 +11,9 @@ local dedent = helpers.dedent describe('eval', function() setup(function() - write_file('test_eval_setup.vim', [[ + write_file( + 'test_eval_setup.vim', + [[ set noswapfile lang C @@ -33,7 +35,8 @@ describe('eval', function() execute "silent normal! Go==\n==\e\"".a:1."P" endif endfun - ]]) + ]] + ) end) before_each(clear) teardown(function() @@ -53,8 +56,8 @@ describe('eval', function() expect([[ ": type v; value: abc (['abc']), expr: abc (['abc']) - ": type V; value: abc]].."\000 (['abc']), expr: abc\000"..[[ (['abc']) - ": type V; value: abc]].."\r\000 (['abc\r']), expr: abc\r\000 (['abc\r"..[[']) + ": type V; value: abc]] .. "\000 (['abc']), expr: abc\000" .. [[ (['abc']) + ": type V; value: abc]] .. "\r\000 (['abc\r']), expr: abc\r\000 (['abc\r" .. [[']) =: type v; value: abc (['abc']), expr: "abc" (['"abc"'])]]) end) @@ -97,29 +100,29 @@ describe('eval', function() == =abcB= {{{2 setreg('c', 'abcC', 'l') - c: type V; value: abcC]].."\000 (['abcC']), expr: abcC\000"..[[ (['abcC']) + c: type V; value: abcC]] .. "\000 (['abcC']), expr: abcC\000" .. [[ (['abcC']) == abcC == {{{2 setreg('d', 'abcD', 'V') - d: type V; value: abcD]].."\000 (['abcD']), expr: abcD\000"..[[ (['abcD']) + d: type V; value: abcD]] .. "\000 (['abcD']), expr: abcD\000" .. [[ (['abcD']) == abcD == {{{2 setreg('e', 'abcE', 'b') - e: type ]]..'\022'..[[4; value: abcE (['abcE']), expr: abcE (['abcE']) + e: type ]] .. '\022' .. [[4; value: abcE (['abcE']), expr: abcE (['abcE']) == =abcE= - {{{2 setreg('f', 'abcF', ']]..'\022'..[[') - f: type ]]..'\022'..[[4; value: abcF (['abcF']), expr: abcF (['abcF']) + {{{2 setreg('f', 'abcF', ']] .. '\022' .. [[') + f: type ]] .. '\022' .. [[4; value: abcF (['abcF']), expr: abcF (['abcF']) == =abcF= {{{2 setreg('g', 'abcG', 'b10') - g: type ]]..'\022'..[[10; value: abcG (['abcG']), expr: abcG (['abcG']) + g: type ]] .. '\022' .. [[10; value: abcG (['abcG']), expr: abcG (['abcG']) == =abcG = - {{{2 setreg('h', 'abcH', ']]..'\022'..[[10') - h: type ]]..'\022'..[[10; value: abcH (['abcH']), expr: abcH (['abcH']) + {{{2 setreg('h', 'abcH', ']] .. '\022' .. [[10') + h: type ]] .. '\022' .. [[10; value: abcH (['abcH']), expr: abcH (['abcH']) == =abcH = {{{2 setreg('I', 'abcI') @@ -132,12 +135,12 @@ describe('eval', function() == =abcAabcAc= {{{2 setreg('A', 'abcAl', 'l') - A: type V; value: abcAabcAcabcAl]].."\000 (['abcAabcAcabcAl']), expr: abcAabcAcabcAl\000"..[[ (['abcAabcAcabcAl']) + A: type V; value: abcAabcAcabcAl]] .. "\000 (['abcAabcAcabcAl']), expr: abcAabcAcabcAl\000" .. [[ (['abcAabcAcabcAl']) == abcAabcAcabcAl == {{{2 setreg('A', 'abcAc2', 'c') - A: type v; value: abcAabcAcabcAl]].."\000abcAc2 (['abcAabcAcabcAl', 'abcAc2']), expr: abcAabcAcabcAl\000"..[[abcAc2 (['abcAabcAcabcAl', 'abcAc2']) + A: type v; value: abcAabcAcabcAl]] .. "\000abcAc2 (['abcAabcAcabcAl', 'abcAc2']), expr: abcAabcAcabcAl\000" .. [[abcAc2 (['abcAabcAcabcAl', 'abcAc2']) == =abcAabcAcabcAl abcAc2= @@ -146,50 +149,50 @@ describe('eval', function() == =abcBabcBc= {{{2 setreg('b', 'abcBb', 'ba') - b: type ]]..'\022'..[[5; value: abcBabcBcabcBb (['abcBabcBcabcBb']), expr: abcBabcBcabcBb (['abcBabcBcabcBb']) + b: type ]] .. '\022' .. [[5; value: abcBabcBcabcBb (['abcBabcBcabcBb']), expr: abcBabcBcabcBb (['abcBabcBcabcBb']) == =abcBabcBcabcBb= {{{2 setreg('b', 'abcBc2', 'ca') - b: type v; value: abcBabcBcabcBb]].."\000abcBc2 (['abcBabcBcabcBb', 'abcBc2']), expr: abcBabcBcabcBb\000"..[[abcBc2 (['abcBabcBcabcBb', 'abcBc2']) + b: type v; value: abcBabcBcabcBb]] .. "\000abcBc2 (['abcBabcBcabcBb', 'abcBc2']), expr: abcBabcBcabcBb\000" .. [[abcBc2 (['abcBabcBcabcBb', 'abcBc2']) == =abcBabcBcabcBb abcBc2= {{{2 setreg('b', 'abcBb2', 'b50a') - b: type ]].."\02250; value: abcBabcBcabcBb\000abcBc2abcBb2 (['abcBabcBcabcBb', 'abcBc2abcBb2']), expr: abcBabcBcabcBb\000"..[[abcBc2abcBb2 (['abcBabcBcabcBb', 'abcBc2abcBb2']) + b: type ]] .. "\02250; value: abcBabcBcabcBb\000abcBc2abcBb2 (['abcBabcBcabcBb', 'abcBc2abcBb2']), expr: abcBabcBcabcBb\000" .. [[abcBc2abcBb2 (['abcBabcBcabcBb', 'abcBc2abcBb2']) == =abcBabcBcabcBb = abcBc2abcBb2 {{{2 setreg('C', 'abcCl', 'l') - C: type V; value: abcC]].."\000abcCl\000 (['abcC', 'abcCl']), expr: abcC\000abcCl\000"..[[ (['abcC', 'abcCl']) + C: type V; value: abcC]] .. "\000abcCl\000 (['abcC', 'abcCl']), expr: abcC\000abcCl\000" .. [[ (['abcC', 'abcCl']) == abcC abcCl == {{{2 setreg('C', 'abcCc', 'c') - C: type v; value: abcC]].."\000abcCl\000abcCc (['abcC', 'abcCl', 'abcCc']), expr: abcC\000abcCl\000"..[[abcCc (['abcC', 'abcCl', 'abcCc']) + C: type v; value: abcC]] .. "\000abcCl\000abcCc (['abcC', 'abcCl', 'abcCc']), expr: abcC\000abcCl\000" .. [[abcCc (['abcC', 'abcCl', 'abcCc']) == =abcC abcCl abcCc= {{{2 setreg('D', 'abcDb', 'b') - D: type ]].."\0225; value: abcD\000abcDb (['abcD', 'abcDb']), expr: abcD\000"..[[abcDb (['abcD', 'abcDb']) + D: type ]] .. "\0225; value: abcD\000abcDb (['abcD', 'abcDb']), expr: abcD\000" .. [[abcDb (['abcD', 'abcDb']) == =abcD = abcDb {{{2 setreg('E', 'abcEb', 'b') - E: type ]].."\0225; value: abcE\000abcEb (['abcE', 'abcEb']), expr: abcE\000"..[[abcEb (['abcE', 'abcEb']) + E: type ]] .. "\0225; value: abcE\000abcEb (['abcE', 'abcEb']), expr: abcE\000" .. [[abcEb (['abcE', 'abcEb']) == =abcE = abcEb {{{2 setreg('E', 'abcEl', 'l') - E: type V; value: abcE]].."\000abcEb\000abcEl\000 (['abcE', 'abcEb', 'abcEl']), expr: abcE\000abcEb\000abcEl\000"..[[ (['abcE', 'abcEb', 'abcEl']) + E: type V; value: abcE]] .. "\000abcEb\000abcEl\000 (['abcE', 'abcEb', 'abcEl']), expr: abcE\000abcEb\000abcEl\000" .. [[ (['abcE', 'abcEb', 'abcEl']) == abcE abcEb abcEl == {{{2 setreg('F', 'abcFc', 'c') - F: type v; value: abcF]].."\000abcFc (['abcF', 'abcFc']), expr: abcF\000"..[[abcFc (['abcF', 'abcFc']) + F: type v; value: abcF]] .. "\000abcFc (['abcF', 'abcFc']), expr: abcF\000" .. [[abcFc (['abcF', 'abcFc']) == =abcF abcFc=]]) @@ -219,36 +222,36 @@ describe('eval', function() command([[call SetReg('F', "\n", 'b')]]) expect([[ - {{{2 setreg('A', ']]..'\000'..[[') - A: type V; value: abcA2]].."\000 (['abcA2']), expr: abcA2\000"..[[ (['abcA2']) + {{{2 setreg('A', ']] .. '\000' .. [[') + A: type V; value: abcA2]] .. "\000 (['abcA2']), expr: abcA2\000" .. [[ (['abcA2']) == abcA2 == - {{{2 setreg('B', ']]..'\000'..[[', 'c') - B: type v; value: abcB2]].."\000 (['abcB2', '']), expr: abcB2\000"..[[ (['abcB2', '']) + {{{2 setreg('B', ']] .. '\000' .. [[', 'c') + B: type v; value: abcB2]] .. "\000 (['abcB2', '']), expr: abcB2\000" .. [[ (['abcB2', '']) == =abcB2 = - {{{2 setreg('C', ']]..'\000'..[[') - C: type V; value: abcC2]].."\000\000 (['abcC2', '']), expr: abcC2\000\000"..[[ (['abcC2', '']) + {{{2 setreg('C', ']] .. '\000' .. [[') + C: type V; value: abcC2]] .. "\000\000 (['abcC2', '']), expr: abcC2\000\000" .. [[ (['abcC2', '']) == abcC2 == - {{{2 setreg('D', ']]..'\000'..[[', 'l') - D: type V; value: abcD2]].."\000\000 (['abcD2', '']), expr: abcD2\000\000"..[[ (['abcD2', '']) + {{{2 setreg('D', ']] .. '\000' .. [[', 'l') + D: type V; value: abcD2]] .. "\000\000 (['abcD2', '']), expr: abcD2\000\000" .. [[ (['abcD2', '']) == abcD2 == - {{{2 setreg('E', ']]..'\000'..[[') - E: type V; value: abcE2]].."\000\000 (['abcE2', '']), expr: abcE2\000\000"..[[ (['abcE2', '']) + {{{2 setreg('E', ']] .. '\000' .. [[') + E: type V; value: abcE2]] .. "\000\000 (['abcE2', '']), expr: abcE2\000\000" .. [[ (['abcE2', '']) == abcE2 == - {{{2 setreg('F', ']]..'\000'..[[', 'b') - F: type ]].."\0220; value: abcF2\000 (['abcF2', '']), expr: abcF2\000"..[[ (['abcF2', '']) + {{{2 setreg('F', ']] .. '\000' .. [[', 'b') + F: type ]] .. "\0220; value: abcF2\000 (['abcF2', '']), expr: abcF2\000" .. [[ (['abcF2', '']) == =abcF2= ]]) @@ -282,21 +285,21 @@ describe('eval', function() == =abcA3= {{{2 setreg('b', ['abcB3'], 'l') - b: type V; value: abcB3]].."\000 (['abcB3']), expr: abcB3\000"..[[ (['abcB3']) + b: type V; value: abcB3]] .. "\000 (['abcB3']), expr: abcB3\000" .. [[ (['abcB3']) == abcB3 == {{{2 setreg('c', ['abcC3'], 'b') - c: type ]]..'\022'..[[5; value: abcC3 (['abcC3']), expr: abcC3 (['abcC3']) + c: type ]] .. '\022' .. [[5; value: abcC3 (['abcC3']), expr: abcC3 (['abcC3']) == =abcC3= {{{2 setreg('d', ['abcD3']) - d: type V; value: abcD3]].."\000 (['abcD3']), expr: abcD3\000"..[[ (['abcD3']) + d: type V; value: abcD3]] .. "\000 (['abcD3']), expr: abcD3\000" .. [[ (['abcD3']) == abcD3 == {{{2 setreg('e', [1, 2, 'abc', 3]) - e: type V; value: 1]].."\0002\000abc\0003\000 (['1', '2', 'abc', '3']), expr: 1\0002\000abc\0003\000"..[[ (['1', '2', 'abc', '3']) + e: type V; value: 1]] .. "\0002\000abc\0003\000 (['1', '2', 'abc', '3']), expr: 1\0002\000abc\0003\000" .. [[ (['1', '2', 'abc', '3']) == 1 2 @@ -304,7 +307,7 @@ describe('eval', function() 3 == {{{2 setreg('f', [1, 2, 3]) - f: type V; value: 1]].."\0002\0003\000 (['1', '2', '3']), expr: 1\0002\0003\000"..[[ (['1', '2', '3']) + f: type V; value: 1]] .. "\0002\0003\000 (['1', '2', '3']), expr: 1\0002\0003\000" .. [[ (['1', '2', '3']) == 1 2 @@ -312,49 +315,49 @@ describe('eval', function() == {{{1 Appending lists with setreg() {{{2 setreg('A', ['abcA3c'], 'c') - A: type v; value: abcA3]].."\000abcA3c (['abcA3', 'abcA3c']), expr: abcA3\000"..[[abcA3c (['abcA3', 'abcA3c']) + A: type v; value: abcA3]] .. "\000abcA3c (['abcA3', 'abcA3c']), expr: abcA3\000" .. [[abcA3c (['abcA3', 'abcA3c']) == =abcA3 abcA3c= {{{2 setreg('b', ['abcB3l'], 'la') - b: type V; value: abcB3]].."\000abcB3l\000 (['abcB3', 'abcB3l']), expr: abcB3\000abcB3l\000"..[[ (['abcB3', 'abcB3l']) + b: type V; value: abcB3]] .. "\000abcB3l\000 (['abcB3', 'abcB3l']), expr: abcB3\000abcB3l\000" .. [[ (['abcB3', 'abcB3l']) == abcB3 abcB3l == {{{2 setreg('C', ['abcC3b'], 'lb') - C: type ]].."\0226; value: abcC3\000abcC3b (['abcC3', 'abcC3b']), expr: abcC3\000"..[[abcC3b (['abcC3', 'abcC3b']) + C: type ]] .. "\0226; value: abcC3\000abcC3b (['abcC3', 'abcC3b']), expr: abcC3\000" .. [[abcC3b (['abcC3', 'abcC3b']) == =abcC3 = abcC3b {{{2 setreg('D', ['abcD32']) - D: type V; value: abcD3]].."\000abcD32\000 (['abcD3', 'abcD32']), expr: abcD3\000abcD32\000"..[[ (['abcD3', 'abcD32']) + D: type V; value: abcD3]] .. "\000abcD32\000 (['abcD3', 'abcD32']), expr: abcD3\000abcD32\000" .. [[ (['abcD3', 'abcD32']) == abcD3 abcD32 == {{{2 setreg('A', ['abcA32']) - A: type V; value: abcA3]].."\000abcA3c\000abcA32\000 (['abcA3', 'abcA3c', 'abcA32']), expr: abcA3\000abcA3c\000abcA32\000"..[[ (['abcA3', 'abcA3c', 'abcA32']) + A: type V; value: abcA3]] .. "\000abcA3c\000abcA32\000 (['abcA3', 'abcA3c', 'abcA32']), expr: abcA3\000abcA3c\000abcA32\000" .. [[ (['abcA3', 'abcA3c', 'abcA32']) == abcA3 abcA3c abcA32 == {{{2 setreg('B', ['abcB3c'], 'c') - B: type v; value: abcB3]].."\000abcB3l\000abcB3c (['abcB3', 'abcB3l', 'abcB3c']), expr: abcB3\000abcB3l\000"..[[abcB3c (['abcB3', 'abcB3l', 'abcB3c']) + B: type v; value: abcB3]] .. "\000abcB3l\000abcB3c (['abcB3', 'abcB3l', 'abcB3c']), expr: abcB3\000abcB3l\000" .. [[abcB3c (['abcB3', 'abcB3l', 'abcB3c']) == =abcB3 abcB3l abcB3c= {{{2 setreg('C', ['abcC3l'], 'l') - C: type V; value: abcC3]].."\000abcC3b\000abcC3l\000 (['abcC3', 'abcC3b', 'abcC3l']), expr: abcC3\000abcC3b\000abcC3l\000"..[[ (['abcC3', 'abcC3b', 'abcC3l']) + C: type V; value: abcC3]] .. "\000abcC3b\000abcC3l\000 (['abcC3', 'abcC3b', 'abcC3l']), expr: abcC3\000abcC3b\000abcC3l\000" .. [[ (['abcC3', 'abcC3b', 'abcC3l']) == abcC3 abcC3b abcC3l == {{{2 setreg('D', ['abcD3b'], 'b') - D: type ]].."\0226; value: abcD3\000abcD32\000abcD3b (['abcD3', 'abcD32', 'abcD3b']), expr: abcD3\000abcD32\000"..[[abcD3b (['abcD3', 'abcD32', 'abcD3b']) + D: type ]] .. "\0226; value: abcD3\000abcD32\000abcD3b (['abcD3', 'abcD32', 'abcD3b']), expr: abcD3\000abcD32\000" .. [[abcD3b (['abcD3', 'abcD32', 'abcD3b']) == =abcD3 = abcD32 @@ -368,53 +371,57 @@ describe('eval', function() command([[$put ='{{{1 Appending lists with NL with setreg()']]) command([=[call SetReg('A', ["\n", 'abcA3l2'], 'l')]=]) expect( - '\n'.. - '{{{1 Appending lists with NL with setreg()\n'.. - "{{{2 setreg('A', ['\000', 'abcA3l2'], 'l')\n".. - "A: type V; value: abcA3\000abcA3c\000abcA32\000\000\000abcA3l2\000 (['abcA3', 'abcA3c', 'abcA32', '\000', 'abcA3l2']), expr: abcA3\000abcA3c\000abcA32\000\000\000abcA3l2\000 (['abcA3', 'abcA3c', 'abcA32', '\000', 'abcA3l2'])\n".. - '==\n'.. - 'abcA3\n'.. - 'abcA3c\n'.. - 'abcA32\n'.. - '\000\n'.. - 'abcA3l2\n'.. - '==') + '\n' + .. '{{{1 Appending lists with NL with setreg()\n' + .. "{{{2 setreg('A', ['\000', 'abcA3l2'], 'l')\n" + .. "A: type V; value: abcA3\000abcA3c\000abcA32\000\000\000abcA3l2\000 (['abcA3', 'abcA3c', 'abcA32', '\000', 'abcA3l2']), expr: abcA3\000abcA3c\000abcA32\000\000\000abcA3l2\000 (['abcA3', 'abcA3c', 'abcA32', '\000', 'abcA3l2'])\n" + .. '==\n' + .. 'abcA3\n' + .. 'abcA3c\n' + .. 'abcA32\n' + .. '\000\n' + .. 'abcA3l2\n' + .. '==' + ) command('%delete') command([=[call SetReg('B', ["\n", 'abcB3c2'], 'c')]=]) expect( - '\n'.. - "{{{2 setreg('B', ['\000', 'abcB3c2'], 'c')\n".. - "B: type v; value: abcB3\000abcB3l\000abcB3c\000\000\000abcB3c2 (['abcB3', 'abcB3l', 'abcB3c', '\000', 'abcB3c2']), expr: abcB3\000abcB3l\000abcB3c\000\000\000abcB3c2 (['abcB3', 'abcB3l', 'abcB3c', '\000', 'abcB3c2'])\n".. - '==\n'.. - '=abcB3\n'.. - 'abcB3l\n'.. - 'abcB3c\n'.. - '\000\n'.. - 'abcB3c2=') + '\n' + .. "{{{2 setreg('B', ['\000', 'abcB3c2'], 'c')\n" + .. "B: type v; value: abcB3\000abcB3l\000abcB3c\000\000\000abcB3c2 (['abcB3', 'abcB3l', 'abcB3c', '\000', 'abcB3c2']), expr: abcB3\000abcB3l\000abcB3c\000\000\000abcB3c2 (['abcB3', 'abcB3l', 'abcB3c', '\000', 'abcB3c2'])\n" + .. '==\n' + .. '=abcB3\n' + .. 'abcB3l\n' + .. 'abcB3c\n' + .. '\000\n' + .. 'abcB3c2=' + ) command('%delete') command([=[call SetReg('C', ["\n", 'abcC3b2'], 'b')]=]) expect( - '\n'.. - "{{{2 setreg('C', ['\000', 'abcC3b2'], 'b')\n".. - "C: type \0227; value: abcC3\000abcC3b\000abcC3l\000\000\000abcC3b2 (['abcC3', 'abcC3b', 'abcC3l', '\000', 'abcC3b2']), expr: abcC3\000abcC3b\000abcC3l\000\000\000abcC3b2 (['abcC3', 'abcC3b', 'abcC3l', '\000', 'abcC3b2'])\n".. - '==\n'.. - '=abcC3 =\n'.. - ' abcC3b\n'.. - ' abcC3l\n'.. - ' \000\n'.. - ' abcC3b2') + '\n' + .. "{{{2 setreg('C', ['\000', 'abcC3b2'], 'b')\n" + .. "C: type \0227; value: abcC3\000abcC3b\000abcC3l\000\000\000abcC3b2 (['abcC3', 'abcC3b', 'abcC3l', '\000', 'abcC3b2']), expr: abcC3\000abcC3b\000abcC3l\000\000\000abcC3b2 (['abcC3', 'abcC3b', 'abcC3l', '\000', 'abcC3b2'])\n" + .. '==\n' + .. '=abcC3 =\n' + .. ' abcC3b\n' + .. ' abcC3l\n' + .. ' \000\n' + .. ' abcC3b2' + ) command('%delete') command([=[call SetReg('D', ["\n", 'abcD3b50'],'b50')]=]) expect( - '\n'.. - "{{{2 setreg('D', ['\000', 'abcD3b50'], 'b50')\n".. - "D: type \02250; value: abcD3\000abcD32\000abcD3b\000\000\000abcD3b50 (['abcD3', 'abcD32', 'abcD3b', '\000', 'abcD3b50']), expr: abcD3\000abcD32\000abcD3b\000\000\000abcD3b50 (['abcD3', 'abcD32', 'abcD3b', '\000', 'abcD3b50'])\n".. - '==\n'.. - '=abcD3 =\n'.. - ' abcD32\n'.. - ' abcD3b\n'.. - ' \000\n'.. - ' abcD3b50') + '\n' + .. "{{{2 setreg('D', ['\000', 'abcD3b50'], 'b50')\n" + .. "D: type \02250; value: abcD3\000abcD32\000abcD3b\000\000\000abcD3b50 (['abcD3', 'abcD32', 'abcD3b', '\000', 'abcD3b50']), expr: abcD3\000abcD32\000abcD3b\000\000\000abcD3b50 (['abcD3', 'abcD32', 'abcD3b', '\000', 'abcD3b50'])\n" + .. '==\n' + .. '=abcD3 =\n' + .. ' abcD32\n' + .. ' abcD3b\n' + .. ' \000\n' + .. ' abcD3b50' + ) end) -- The tests for setting lists with NLs are split into separate it() blocks @@ -422,77 +429,92 @@ describe('eval', function() -- make trouble on a line on its own. it('setting lists with NLs with setreg(), part 1', function() command('so test_eval_setup.vim') - command([=[call SetReg('a', ['abcA4-0', "\n", "abcA4-2\n", "\nabcA4-3", "abcA4-4\nabcA4-4-2"])]=]) + command( + [=[call SetReg('a', ['abcA4-0', "\n", "abcA4-2\n", "\nabcA4-3", "abcA4-4\nabcA4-4-2"])]=] + ) expect( - '\n'.. - "{{{2 setreg('a', ['abcA4-0', '\000', 'abcA4-2\000', '\000abcA4-3', 'abcA4-4\000abcA4-4-2'])\n".. - "a: type V; value: abcA4-0\000\000\000abcA4-2\000\000\000abcA4-3\000abcA4-4\000abcA4-4-2\000 (['abcA4-0', '\000', 'abcA4-2\000', '\000abcA4-3', 'abcA4-4\000abcA4-4-2']), expr: abcA4-0\000\000\000abcA4-2\000\000\000abcA4-3\000abcA4-4\000abcA4-4-2\000 (['abcA4-0', '\000', 'abcA4-2\000', '\000abcA4-3', 'abcA4-4\000abcA4-4-2'])\n".. - '==\n'.. - 'abcA4-0\n'.. - '\000\n'.. - 'abcA4-2\000\n'.. - '\000abcA4-3\n'.. - 'abcA4-4\000abcA4-4-2\n'.. - '==') + '\n' + .. "{{{2 setreg('a', ['abcA4-0', '\000', 'abcA4-2\000', '\000abcA4-3', 'abcA4-4\000abcA4-4-2'])\n" + .. "a: type V; value: abcA4-0\000\000\000abcA4-2\000\000\000abcA4-3\000abcA4-4\000abcA4-4-2\000 (['abcA4-0', '\000', 'abcA4-2\000', '\000abcA4-3', 'abcA4-4\000abcA4-4-2']), expr: abcA4-0\000\000\000abcA4-2\000\000\000abcA4-3\000abcA4-4\000abcA4-4-2\000 (['abcA4-0', '\000', 'abcA4-2\000', '\000abcA4-3', 'abcA4-4\000abcA4-4-2'])\n" + .. '==\n' + .. 'abcA4-0\n' + .. '\000\n' + .. 'abcA4-2\000\n' + .. '\000abcA4-3\n' + .. 'abcA4-4\000abcA4-4-2\n' + .. '==' + ) end) it('setting lists with NLs with setreg(), part 2', function() command('so test_eval_setup.vim') - command([=[call SetReg('b', ['abcB4c-0', "\n", "abcB4c-2\n", "\nabcB4c-3", "abcB4c-4\nabcB4c-4-2"], 'c')]=]) + command( + [=[call SetReg('b', ['abcB4c-0', "\n", "abcB4c-2\n", "\nabcB4c-3", "abcB4c-4\nabcB4c-4-2"], 'c')]=] + ) expect( - '\n'.. - "{{{2 setreg('b', ['abcB4c-0', '\000', 'abcB4c-2\000', '\000abcB4c-3', 'abcB4c-4\000abcB4c-4-2'], 'c')\n".. - "b: type v; value: abcB4c-0\000\000\000abcB4c-2\000\000\000abcB4c-3\000abcB4c-4\000abcB4c-4-2 (['abcB4c-0', '\000', 'abcB4c-2\000', '\000abcB4c-3', 'abcB4c-4\000abcB4c-4-2']), expr: abcB4c-0\000\000\000abcB4c-2\000\000\000abcB4c-3\000abcB4c-4\000abcB4c-4-2 (['abcB4c-0', '\000', 'abcB4c-2\000', '\000abcB4c-3', 'abcB4c-4\000abcB4c-4-2'])\n".. - '==\n'.. - '=abcB4c-0\n'.. - '\000\n'.. - 'abcB4c-2\000\n'.. - '\000abcB4c-3\n'.. - 'abcB4c-4\000abcB4c-4-2=') + '\n' + .. "{{{2 setreg('b', ['abcB4c-0', '\000', 'abcB4c-2\000', '\000abcB4c-3', 'abcB4c-4\000abcB4c-4-2'], 'c')\n" + .. "b: type v; value: abcB4c-0\000\000\000abcB4c-2\000\000\000abcB4c-3\000abcB4c-4\000abcB4c-4-2 (['abcB4c-0', '\000', 'abcB4c-2\000', '\000abcB4c-3', 'abcB4c-4\000abcB4c-4-2']), expr: abcB4c-0\000\000\000abcB4c-2\000\000\000abcB4c-3\000abcB4c-4\000abcB4c-4-2 (['abcB4c-0', '\000', 'abcB4c-2\000', '\000abcB4c-3', 'abcB4c-4\000abcB4c-4-2'])\n" + .. '==\n' + .. '=abcB4c-0\n' + .. '\000\n' + .. 'abcB4c-2\000\n' + .. '\000abcB4c-3\n' + .. 'abcB4c-4\000abcB4c-4-2=' + ) end) it('setting lists with NLs with setreg(), part 3', function() command('so test_eval_setup.vim') - command([=[call SetReg('c', ['abcC4l-0', "\n", "abcC4l-2\n", "\nabcC4l-3", "abcC4l-4\nabcC4l-4-2"], 'l')]=]) + command( + [=[call SetReg('c', ['abcC4l-0', "\n", "abcC4l-2\n", "\nabcC4l-3", "abcC4l-4\nabcC4l-4-2"], 'l')]=] + ) expect( - '\n'.. - "{{{2 setreg('c', ['abcC4l-0', '\000', 'abcC4l-2\000', '\000abcC4l-3', 'abcC4l-4\000abcC4l-4-2'], 'l')\n".. - "c: type V; value: abcC4l-0\000\000\000abcC4l-2\000\000\000abcC4l-3\000abcC4l-4\000abcC4l-4-2\000 (['abcC4l-0', '\000', 'abcC4l-2\000', '\000abcC4l-3', 'abcC4l-4\000abcC4l-4-2']), expr: abcC4l-0\000\000\000abcC4l-2\000\000\000abcC4l-3\000abcC4l-4\000abcC4l-4-2\000 (['abcC4l-0', '\000', 'abcC4l-2\000', '\000abcC4l-3', 'abcC4l-4\000abcC4l-4-2'])\n".. - '==\n'.. - 'abcC4l-0\n'.. - '\000\n'.. - 'abcC4l-2\000\n'.. - '\000abcC4l-3\n'.. - 'abcC4l-4\000abcC4l-4-2\n'.. - '==') + '\n' + .. "{{{2 setreg('c', ['abcC4l-0', '\000', 'abcC4l-2\000', '\000abcC4l-3', 'abcC4l-4\000abcC4l-4-2'], 'l')\n" + .. "c: type V; value: abcC4l-0\000\000\000abcC4l-2\000\000\000abcC4l-3\000abcC4l-4\000abcC4l-4-2\000 (['abcC4l-0', '\000', 'abcC4l-2\000', '\000abcC4l-3', 'abcC4l-4\000abcC4l-4-2']), expr: abcC4l-0\000\000\000abcC4l-2\000\000\000abcC4l-3\000abcC4l-4\000abcC4l-4-2\000 (['abcC4l-0', '\000', 'abcC4l-2\000', '\000abcC4l-3', 'abcC4l-4\000abcC4l-4-2'])\n" + .. '==\n' + .. 'abcC4l-0\n' + .. '\000\n' + .. 'abcC4l-2\000\n' + .. '\000abcC4l-3\n' + .. 'abcC4l-4\000abcC4l-4-2\n' + .. '==' + ) end) it('setting lists with NLs with setreg(), part 4', function() command('so test_eval_setup.vim') - command([=[call SetReg('d', ['abcD4b-0', "\n", "abcD4b-2\n", "\nabcD4b-3", "abcD4b-4\nabcD4b-4-2"], 'b')]=]) + command( + [=[call SetReg('d', ['abcD4b-0', "\n", "abcD4b-2\n", "\nabcD4b-3", "abcD4b-4\nabcD4b-4-2"], 'b')]=] + ) expect( - '\n'.. - "{{{2 setreg('d', ['abcD4b-0', '\000', 'abcD4b-2\000', '\000abcD4b-3', 'abcD4b-4\000abcD4b-4-2'], 'b')\n".. - "d: type \02219; value: abcD4b-0\000\000\000abcD4b-2\000\000\000abcD4b-3\000abcD4b-4\000abcD4b-4-2 (['abcD4b-0', '\000', 'abcD4b-2\000', '\000abcD4b-3', 'abcD4b-4\000abcD4b-4-2']), expr: abcD4b-0\000\000\000abcD4b-2\000\000\000abcD4b-3\000abcD4b-4\000abcD4b-4-2 (['abcD4b-0', '\000', 'abcD4b-2\000', '\000abcD4b-3', 'abcD4b-4\000abcD4b-4-2'])\n".. - '==\n'.. - '=abcD4b-0 =\n'.. - ' \000\n'.. - ' abcD4b-2\000\n'.. - ' \000abcD4b-3\n'.. - ' abcD4b-4\000abcD4b-4-2') + '\n' + .. "{{{2 setreg('d', ['abcD4b-0', '\000', 'abcD4b-2\000', '\000abcD4b-3', 'abcD4b-4\000abcD4b-4-2'], 'b')\n" + .. "d: type \02219; value: abcD4b-0\000\000\000abcD4b-2\000\000\000abcD4b-3\000abcD4b-4\000abcD4b-4-2 (['abcD4b-0', '\000', 'abcD4b-2\000', '\000abcD4b-3', 'abcD4b-4\000abcD4b-4-2']), expr: abcD4b-0\000\000\000abcD4b-2\000\000\000abcD4b-3\000abcD4b-4\000abcD4b-4-2 (['abcD4b-0', '\000', 'abcD4b-2\000', '\000abcD4b-3', 'abcD4b-4\000abcD4b-4-2'])\n" + .. '==\n' + .. '=abcD4b-0 =\n' + .. ' \000\n' + .. ' abcD4b-2\000\n' + .. ' \000abcD4b-3\n' + .. ' abcD4b-4\000abcD4b-4-2' + ) end) it('setting lists with NLs with setreg(), part 5', function() command('so test_eval_setup.vim') - command([=[call SetReg('e', ['abcE4b10-0', "\n", "abcE4b10-2\n", "\nabcE4b10-3", "abcE4b10-4\nabcE4b10-4-2"], 'b10')]=]) + command( + [=[call SetReg('e', ['abcE4b10-0', "\n", "abcE4b10-2\n", "\nabcE4b10-3", "abcE4b10-4\nabcE4b10-4-2"], 'b10')]=] + ) expect( - '\n'.. - "{{{2 setreg('e', ['abcE4b10-0', '\000', 'abcE4b10-2\000', '\000abcE4b10-3', 'abcE4b10-4\000abcE4b10-4-2'], 'b10')\n".. - "e: type \02210; value: abcE4b10-0\000\000\000abcE4b10-2\000\000\000abcE4b10-3\000abcE4b10-4\000abcE4b10-4-2 (['abcE4b10-0', '\000', 'abcE4b10-2\000', '\000abcE4b10-3', 'abcE4b10-4\000abcE4b10-4-2']), expr: abcE4b10-0\000\000\000abcE4b10-2\000\000\000abcE4b10-3\000abcE4b10-4\000abcE4b10-4-2 (['abcE4b10-0', '\000', 'abcE4b10-2\000', '\000abcE4b10-3', 'abcE4b10-4\000abcE4b10-4-2'])\n".. - '==\n'.. - '=abcE4b10-0=\n'.. - ' \000\n'.. - ' abcE4b10-2\000\n'.. - ' \000abcE4b10-3\n'.. - ' abcE4b10-4\000abcE4b10-4-2') + '\n' + .. "{{{2 setreg('e', ['abcE4b10-0', '\000', 'abcE4b10-2\000', '\000abcE4b10-3', 'abcE4b10-4\000abcE4b10-4-2'], 'b10')\n" + .. "e: type \02210; value: abcE4b10-0\000\000\000abcE4b10-2\000\000\000abcE4b10-3\000abcE4b10-4\000abcE4b10-4-2 (['abcE4b10-0', '\000', 'abcE4b10-2\000', '\000abcE4b10-3', 'abcE4b10-4\000abcE4b10-4-2']), expr: abcE4b10-0\000\000\000abcE4b10-2\000\000\000abcE4b10-3\000abcE4b10-4\000abcE4b10-4-2 (['abcE4b10-0', '\000', 'abcE4b10-2\000', '\000abcE4b10-3', 'abcE4b10-4\000abcE4b10-4-2'])\n" + .. '==\n' + .. '=abcE4b10-0=\n' + .. ' \000\n' + .. ' abcE4b10-2\000\n' + .. ' \000abcE4b10-3\n' + .. ' abcE4b10-4\000abcE4b10-4-2' + ) end) it('getreg("a",1,1) returns a valid list when "a is unset', function() @@ -511,19 +533,19 @@ describe('eval', function() eq({}, eval("getreg('0',1,1)")) -- x is a mutable list - command("let y = x") - eq({}, eval("y")) + command('let y = x') + eq({}, eval('y')) command("call add(x, 'item')") - eq({'item'}, eval("y")) + eq({ 'item' }, eval('y')) end) it('sets the unnamed register when the "u" option is passed to setreg', function() command("call setreg('a','a reg', 'cu')") - eq("a reg", eval('@"')) + eq('a reg', eval('@"')) command("call setreg('b','b reg', 'cu')") - eq("b reg", eval('@"')) + eq('b reg', eval('@"')) command("call setreg('c','c reg', 'c')") - eq("b reg", eval('@"')) + eq('b reg', eval('@"')) end) it('search and expressions', function() @@ -532,20 +554,36 @@ describe('eval', function() command([=[call SetReg('/', ["abc/\n"])]=]) command([=[call SetReg('=', ['"abc/"'])]=]) command([=[call SetReg('=', ["\"abc/\n\""])]=]) - expect([[ + expect( + [[ {{{2 setreg('/', ['abc/']) /: type v; value: abc/ (['abc/']), expr: abc/ (['abc/']) == =abc/= - {{{2 setreg('/', ['abc/]]..'\000'..[[']) - /: type v; value: abc/]].."\000 (['abc/\000']), expr: abc/\000 (['abc/\000"..[[']) - == - =abc/]]..'\000'..[[= + {{{2 setreg('/', ['abc/]] + .. '\000' + .. [[']) + /: type v; value: abc/]] + .. "\000 (['abc/\000']), expr: abc/\000 (['abc/\000" + .. [[']) + == + =abc/]] + .. '\000' + .. [[= {{{2 setreg('=', ['"abc/"']) =: type v; value: abc/ (['abc/']), expr: "abc/" (['"abc/"']) - {{{2 setreg('=', ['"abc/]]..'\000'..[["']) - =: type v; value: abc/]].."\000 (['abc/\000"..[[']), expr: "abc/]]..'\000'..[[" (['"abc/]]..'\000'..[["'])]]) + {{{2 setreg('=', ['"abc/]] + .. '\000' + .. [["']) + =: type v; value: abc/]] + .. "\000 (['abc/\000" + .. [[']), expr: "abc/]] + .. '\000' + .. [[" (['"abc/]] + .. '\000' + .. [["'])]] + ) end) describe('system clipboard', function() @@ -574,15 +612,25 @@ describe('eval', function() command('AR *') command('let &cb=_clipopt') command("call call('setreg', _clipreg)") - expect([[ + expect( + [[ Some first line (this text was at the top of the old test_eval.in). Note: system clipboard is saved, changed and restored. clipboard contents something else - *: type V; value: clipboard contents]]..'\00'..[[ (['clipboard contents']), expr: clipboard contents]]..'\00'..[[ (['clipboard contents']) - *: type V; value: something else]]..'\00'..[[ (['something else']), expr: something else]]..'\00'..[[ (['something else'])]]) + *: type V; value: clipboard contents]] + .. '\00' + .. [[ (['clipboard contents']), expr: clipboard contents]] + .. '\00' + .. [[ (['clipboard contents']) + *: type V; value: something else]] + .. '\00' + .. [[ (['something else']), expr: something else]] + .. '\00' + .. [[ (['something else'])]] + ) end) end) @@ -625,24 +673,30 @@ describe('eval', function() end) it('function name not starting with a capital', function() - eq('Vim(function):E128: Function name must start with a capital or "s:": g:test()\\nendfunction', - exc_exec(dedent([[ + eq( + 'Vim(function):E128: Function name must start with a capital or "s:": g:test()\\nendfunction', + exc_exec(dedent([[ function! g:test() - endfunction]]))) + endfunction]])) + ) end) it('Function name followed by #', function() - eq('Vim(function):E128: Function name must start with a capital or "s:": test2() "#\\nendfunction', - exc_exec(dedent([[ + eq( + 'Vim(function):E128: Function name must start with a capital or "s:": test2() "#\\nendfunction', + exc_exec(dedent([[ function! test2() "# - endfunction]]))) + endfunction]])) + ) end) it('function name includes a colon', function() - eq('Vim(function):E884: Function name cannot contain a colon: b:test()\\nendfunction', - exc_exec(dedent([[ + eq( + 'Vim(function):E884: Function name cannot contain a colon: b:test()\\nendfunction', + exc_exec(dedent([[ function! b:test() - endfunction]]))) + endfunction]])) + ) end) it('function name starting with/without "g:", buffer-local funcref', function() @@ -686,8 +740,10 @@ describe('eval', function() end) it("using $ instead of '$' must give an error", function() - eq('Vim(call):E116: Invalid arguments for function append', - exc_exec('call append($, "foobar")')) + eq( + 'Vim(call):E116: Invalid arguments for function append', + exc_exec('call append($, "foobar")') + ) end) it('getcurpos/setpos', function() diff --git a/test/functional/legacy/ex_mode_spec.lua b/test/functional/legacy/ex_mode_spec.lua index f21c47e175..ae4c4309d1 100644 --- a/test/functional/legacy/ex_mode_spec.lua +++ b/test/functional/legacy/ex_mode_spec.lua @@ -5,7 +5,7 @@ local command = helpers.command local eq = helpers.eq local eval = helpers.eval local feed = helpers.feed -local meths = helpers.meths +local api = helpers.api local poke_eventloop = helpers.poke_eventloop before_each(clear) @@ -14,9 +14,9 @@ describe('Ex mode', function() it('supports command line editing', function() local function test_ex_edit(expected, cmd) feed('gQ' .. cmd .. '<C-b>"<CR>') - local ret = eval('@:[1:]') -- Remove leading quote. + local ret = eval('@:[1:]') -- Remove leading quote. feed('visual<CR>') - eq(meths.replace_termcodes(expected, true, true, true), ret) + eq(api.nvim_replace_termcodes(expected, true, true, true), ret) end command('set sw=2') test_ex_edit('bar', 'foo bar<C-u>bar') @@ -46,9 +46,9 @@ describe('Ex mode', function() command('set noincsearch nohlsearch inccommand=') local screen = Screen.new(60, 6) screen:set_default_attr_ids({ - [0] = {bold = true, reverse = true}, -- MsgSeparator - [1] = {foreground = Screen.colors.Brown}, -- LineNr - [2] = {bold = true, foreground = Screen.colors.Blue}, -- NonText + [0] = { bold = true, reverse = true }, -- MsgSeparator + [1] = { foreground = Screen.colors.Brown }, -- LineNr + [2] = { bold = true, foreground = Screen.colors.Blue }, -- NonText }) screen:attach() command([[call setline(1, ['foo foo', 'foo foo', 'foo foo'])]]) @@ -118,8 +118,7 @@ describe('Ex mode', function() {1: 1 }foo bar | {1: 2 }foo foo | {1: 3 }^foo foo | - {2:~ }| - {2:~ }| + {2:~ }|*2 | ]]) end) @@ -127,8 +126,8 @@ describe('Ex mode', function() it('pressing Ctrl-C in :append inside a loop in Ex mode does not hang', function() local screen = Screen.new(60, 6) screen:set_default_attr_ids({ - [0] = {bold = true, reverse = true}, -- MsgSeparator - [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText + [0] = { bold = true, reverse = true }, -- MsgSeparator + [1] = { bold = true, foreground = Screen.colors.Blue }, -- NonText }) screen:attach() feed('gQ') @@ -143,7 +142,7 @@ describe('Ex mode', function() ^ | ]]) feed('<C-C>') - poke_eventloop() -- Wait for input to be flushed + poke_eventloop() -- Wait for input to be flushed feed('foo<CR>') screen:expect([[ Entering Ex mode. Type "visual" to go to Normal mode. | @@ -166,10 +165,7 @@ describe('Ex mode', function() feed('vi<CR>') screen:expect([[ ^foo | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]) end) diff --git a/test/functional/legacy/excmd_spec.lua b/test/functional/legacy/excmd_spec.lua index eb480a6689..41f14c4645 100644 --- a/test/functional/legacy/excmd_spec.lua +++ b/test/functional/legacy/excmd_spec.lua @@ -6,8 +6,8 @@ local exec = helpers.exec local exec_lua = helpers.exec_lua local expect_exit = helpers.expect_exit local feed = helpers.feed -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local read_file = helpers.read_file local source = helpers.source local eq = helpers.eq @@ -23,7 +23,9 @@ end describe('Ex command', function() before_each(clear) - after_each(function() eq({}, meths.get_vvar('errors')) end) + after_each(function() + eq({}, api.nvim_get_vvar('errors')) + end) it('checks for address line overflow', function() if sizeoflong() < 8 then @@ -47,10 +49,10 @@ describe(':confirm command dialog', function() clear() screen = Screen.new(75, 20) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {bold = true, reverse = true}, -- StatusLine, MsgSeparator - [2] = {reverse = true}, -- StatusLineNC - [3] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { bold = true, reverse = true }, -- StatusLine, MsgSeparator + [2] = { reverse = true }, -- StatusLineNC + [3] = { bold = true, foreground = Screen.colors.SeaGreen }, -- MoreMsg }) screen:attach() end @@ -74,21 +76,13 @@ describe(':confirm command dialog', function() feed(':confirm qall\n') screen:expect([[ bar2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {2:Xbar [+] }| foo2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {2:Xfoo [+] }| | - {0:~ }| - {0:~ }| + {0:~ }|*2 {1: }| :confirm qall | {3:Save changes to "Xbar"?} | @@ -112,21 +106,13 @@ describe(':confirm command dialog', function() feed(':confirm qall\n') screen:expect([[ bar3 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {2:Xbar [+] }| foo3 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {2:Xfoo [+] }| | - {0:~ }| - {0:~ }| + {0:~ }|*2 {1: }| :confirm qall | {3:Save changes to "Xbar"?} | @@ -150,21 +136,13 @@ describe(':confirm command dialog', function() feed(':confirm qall\n') screen:expect([[ bar4 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {2:Xbar [+] }| foo4 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {2:Xfoo [+] }| | - {0:~ }| - {0:~ }| + {0:~ }|*2 {1: }| :confirm qall | {3:Save changes to "Xbar"?} | @@ -173,17 +151,10 @@ describe(':confirm command dialog', function() feed('N') screen:expect([[ bar4 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {2:Xbar [+] }| foo4 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {2:Xfoo [+] }| | {1: }| @@ -215,9 +186,7 @@ describe(':confirm command dialog', function() feed(':confirm close\n') screen:expect([[ abc | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {1:[No Name] [+] }| | {1: }| @@ -228,22 +197,17 @@ describe(':confirm command dialog', function() feed('C') screen:expect([[ ^abc | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {1:[No Name] [+] }| | - {0:~ }| - {0:~ }| + {0:~ }|*2 {2:[No Name] }| | ]]) feed(':confirm close\n') screen:expect([[ abc | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {1:[No Name] [+] }| | {1: }| @@ -254,14 +218,7 @@ describe(':confirm command dialog', function() feed('N') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*8 | ]]) end) @@ -280,9 +237,7 @@ describe(':confirm command dialog', function() feed(':confirm q\n') screen:expect([[ foo | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {1: }| :confirm q | {3:Save changes to "Untitled"?} | @@ -291,12 +246,7 @@ describe(':confirm command dialog', function() feed('C') screen:expect([[ ^abc | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 | ]]) @@ -304,9 +254,7 @@ describe(':confirm command dialog', function() feed(':confirm wq\n') screen:expect([[ foo | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {1: }| "Xfoo" [noeol] 1L, 3B written | {3:Save changes to "Untitled"?} | @@ -315,12 +263,7 @@ describe(':confirm command dialog', function() feed('C') screen:expect([[ ^abc | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 "Xfoo" [noeol] 1L, 3B written | ]]) @@ -343,8 +286,7 @@ describe(':confirm command dialog', function() feed(':set ro | confirm w\n') screen:expect([[ foobar | - {0:~ }| - {0:~ }| + {0:~ }|*2 {1: }| :set ro | confirm w | {3:'readonly' option is set for "Xconfirm_write_ro".} | @@ -354,11 +296,7 @@ describe(':confirm command dialog', function() feed('N') screen:expect([[ fooba^r | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | 1,6 All | ]]) @@ -367,8 +305,7 @@ describe(':confirm command dialog', function() feed(':confirm w\n') screen:expect([[ foobar | - {0:~ }| - {0:~ }| + {0:~ }|*2 {1: }| :confirm w | {3:'readonly' option is set for "Xconfirm_write_ro".} | @@ -400,10 +337,10 @@ describe(':confirm command dialog', function() ]]) end eq('foobar\n', read_file('Xconfirm_write_ro')) - feed('<CR>') -- suppress hit-enter prompt + feed('<CR>') -- suppress hit-enter prompt -- Try to write with read-only file permissions. - funcs.setfperm('Xconfirm_write_ro', 'r--r--r--') + fn.setfperm('Xconfirm_write_ro', 'r--r--r--') feed(':set noro | silent undo | confirm w\n') screen:expect([[ foobar | @@ -440,7 +377,7 @@ describe(':confirm command dialog', function() ]]) end eq('foo\n', read_file('Xconfirm_write_ro')) - feed('<CR>') -- suppress hit-enter prompt + feed('<CR>') -- suppress hit-enter prompt os.remove('Xconfirm_write_ro') end) @@ -473,8 +410,7 @@ describe(':confirm command dialog', function() b | c | d | - {0:~ }| - {0:~ }| + {0:~ }|*2 | 1,1 All | ]]) diff --git a/test/functional/legacy/filechanged_spec.lua b/test/functional/legacy/filechanged_spec.lua index c8e772f597..46ecfdcd63 100644 --- a/test/functional/legacy/filechanged_spec.lua +++ b/test/functional/legacy/filechanged_spec.lua @@ -1,19 +1,19 @@ local helpers = require('test.functional.helpers')(after_each) local clear, source = helpers.clear, helpers.source -local call, eq, meths = helpers.call, helpers.eq, helpers.meths +local call, eq, api = helpers.call, helpers.eq, helpers.api local is_os = helpers.is_os local skip = helpers.skip local function expected_empty() - eq({}, meths.get_vvar('errors')) + eq({}, api.nvim_get_vvar('errors')) end describe('file changed dialog', function() before_each(function() clear() - meths.ui_attach(80, 24, {}) - meths.set_option_value('autoread', false, {}) - meths.set_option_value('fsync', true, {}) + api.nvim_ui_attach(80, 24, {}) + api.nvim_set_option_value('autoread', false, {}) + api.nvim_set_option_value('fsync', true, {}) end) it('works', function() diff --git a/test/functional/legacy/fixeol_spec.lua b/test/functional/legacy/fixeol_spec.lua index 3cc9d54e2b..01b87ac9a0 100644 --- a/test/functional/legacy/fixeol_spec.lua +++ b/test/functional/legacy/fixeol_spec.lua @@ -6,11 +6,11 @@ local clear, feed_command, expect = helpers.clear, helpers.feed_command, helpers describe('fixeol', function() local function rmtestfiles() - os.remove("test.out") - os.remove("XXEol") - os.remove("XXNoEol") - os.remove("XXTestEol") - os.remove("XXTestNoEol") + os.remove('test.out') + os.remove('XXEol') + os.remove('XXNoEol') + os.remove('XXTestEol') + os.remove('XXTestNoEol') end setup(function() clear() diff --git a/test/functional/legacy/fnamemodify_spec.lua b/test/functional/legacy/fnamemodify_spec.lua index 6262db3a2f..570b523d92 100644 --- a/test/functional/legacy/fnamemodify_spec.lua +++ b/test/functional/legacy/fnamemodify_spec.lua @@ -2,10 +2,10 @@ local helpers = require('test.functional.helpers')(after_each) local clear, source = helpers.clear, helpers.source -local call, eq, nvim = helpers.call, helpers.eq, helpers.meths +local call, eq, nvim = helpers.call, helpers.eq, helpers.api local function expected_empty() - eq({}, nvim.get_vvar('errors')) + eq({}, nvim.nvim_get_vvar('errors')) end describe('filename modifiers', function() diff --git a/test/functional/legacy/fold_spec.lua b/test/functional/legacy/fold_spec.lua index 83513a3f94..c39aae87d2 100644 --- a/test/functional/legacy/fold_spec.lua +++ b/test/functional/legacy/fold_spec.lua @@ -15,10 +15,10 @@ describe('folding', function() screen = Screen.new(45, 8) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [2] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey}, -- Folded - [3] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.Grey}, -- FoldColumn - [4] = {foreground = Screen.colors.Brown}, -- LineNr + [1] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [2] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey }, -- Folded + [3] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.Grey }, -- FoldColumn + [4] = { foreground = Screen.colors.Brown }, -- LineNr }) screen:attach() end) @@ -50,7 +50,7 @@ describe('folding', function() 1 aa]]) end) - it("foldmethod=marker", function() + it('foldmethod=marker', function() screen:try_resize(20, 10) insert([[ dd {{{ @@ -72,18 +72,15 @@ describe('folding', function() dd {{{ | ee {{{ }}} | {{{ | - ff }}} | - ff }}} | + ff }}} |*2 ^ | line 2 foldlevel=2 | - 1 | - 1 | + 1 |*2 | ]]) - end) - it("foldmethod=indent", function() + it('foldmethod=indent', function() screen:try_resize(20, 8) feed_command('set fdm=indent sw=2') insert([[ @@ -109,7 +106,7 @@ describe('folding', function() ]]) end) - it("foldmethod=syntax", function() + it('foldmethod=syntax', function() screen:try_resize(35, 15) insert([[ 1 aa @@ -148,7 +145,7 @@ describe('folding', function() a jj]]) end) - it("foldmethod=expression", function() + it('foldmethod=expression', function() insert([[ 1 aa 2 bb @@ -227,22 +224,14 @@ describe('folding', function() screen:expect([[ {3:+ }{4: 0 }{2:^+-- 2 lines: ·························}| {3:+ }{4: 1 }{2:+-- 2 lines: ·························}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | ]]) - feed("j") + feed('j') screen:expect([[ {3:+ }{4: 1 }{2:+-- 2 lines: ·························}| {3:+ }{4: 0 }{2:^+-- 2 lines: ·························}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | ]]) end) @@ -259,10 +248,7 @@ describe('folding', function() ^one | {2:+-- 2 lines: two····························}| four | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]) feed('2G') @@ -271,9 +257,7 @@ describe('folding', function() ^two | three | four | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]) feed('4G') @@ -281,10 +265,7 @@ describe('folding', function() one | {2:+-- 2 lines: two····························}| ^four | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]) feed('3G') @@ -293,9 +274,7 @@ describe('folding', function() two | ^three | four | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]) feed('1G') @@ -303,10 +282,7 @@ describe('folding', function() ^one | {2:+-- 2 lines: two····························}| four | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]) feed('2G') @@ -315,9 +291,7 @@ describe('folding', function() ^two | three | four | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]) feed('k') @@ -325,10 +299,7 @@ describe('folding', function() ^one | {2:+-- 2 lines: two····························}| four | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]) end) diff --git a/test/functional/legacy/function_sort_spec.lua b/test/functional/legacy/function_sort_spec.lua index 414953aacc..36128bb0a2 100644 --- a/test/functional/legacy/function_sort_spec.lua +++ b/test/functional/legacy/function_sort_spec.lua @@ -11,24 +11,24 @@ describe('sort', function() before_each(clear) it('numbers compared as strings', function() - eq({1, 2, 3}, eval('sort([3, 2, 1])')) - eq({13, 28, 3}, eval('sort([3, 28, 13])')) + eq({ 1, 2, 3 }, eval('sort([3, 2, 1])')) + eq({ 13, 28, 3 }, eval('sort([3, 28, 13])')) end) it('numbers compared as numeric', function() - eq({1, 2, 3}, eval("sort([3, 2, 1], 'n')")) - eq({3, 13, 28}, eval("sort([3, 28, 13], 'n')")) + eq({ 1, 2, 3 }, eval("sort([3, 2, 1], 'n')")) + eq({ 3, 13, 28 }, eval("sort([3, 28, 13], 'n')")) -- Strings are not sorted. - eq({'13', '28', '3'}, eval("sort(['13', '28', '3'], 'n')")) + eq({ '13', '28', '3' }, eval("sort(['13', '28', '3'], 'n')")) end) it('numbers compared as numbers', function() - eq({3, 13, 28}, eval("sort([13, 28, 3], 'N')")) - eq({'3', '13', '28'}, eval("sort(['13', '28', '3'], 'N')")) + eq({ 3, 13, 28 }, eval("sort([13, 28, 3], 'N')")) + eq({ '3', '13', '28' }, eval("sort(['13', '28', '3'], 'N')")) end) it('numbers compared as float', function() - eq({0.28, 3, 13.5}, eval("sort([13.5, 0.28, 3], 'f')")) + eq({ 0.28, 3, 13.5 }, eval("sort([13.5, 0.28, 3], 'f')")) end) it('ability to call sort() from a compare function', function() @@ -43,15 +43,15 @@ describe('sort', function() endfunc ]]) - eq({1, 3, 5}, eval("sort([3, 1, 5], 'Compare1')")) + eq({ 1, 3, 5 }, eval("sort([3, 1, 5], 'Compare1')")) end) it('default sort', function() -- docs say omitted, empty or zero argument sorts on string representation - eq({'2', 'A', 'AA', 'a', 1, 3.3}, eval('sort([3.3, 1, "2", "A", "a", "AA"])')) - eq({'2', 'A', 'AA', 'a', 1, 3.3}, eval([[sort([3.3, 1, "2", "A", "a", "AA"], '')]])) - eq({'2', 'A', 'AA', 'a', 1, 3.3}, eval('sort([3.3, 1, "2", "A", "a", "AA"], 0)')) - eq({'2', 'A', 'a', 'AA', 1, 3.3}, eval('sort([3.3, 1, "2", "A", "a", "AA"], 1)')) + eq({ '2', 'A', 'AA', 'a', 1, 3.3 }, eval('sort([3.3, 1, "2", "A", "a", "AA"])')) + eq({ '2', 'A', 'AA', 'a', 1, 3.3 }, eval([[sort([3.3, 1, "2", "A", "a", "AA"], '')]])) + eq({ '2', 'A', 'AA', 'a', 1, 3.3 }, eval('sort([3.3, 1, "2", "A", "a", "AA"], 0)')) + eq({ '2', 'A', 'a', 'AA', 1, 3.3 }, eval('sort([3.3, 1, "2", "A", "a", "AA"], 1)')) neq(nil, exc_exec('call sort([3.3, 1, "2"], 3)'):find('E474:')) end) end) diff --git a/test/functional/legacy/gf_spec.lua b/test/functional/legacy/gf_spec.lua index 9f725446be..b51f671bee 100644 --- a/test/functional/legacy/gf_spec.lua +++ b/test/functional/legacy/gf_spec.lua @@ -10,7 +10,9 @@ describe('gf', function() it('is not allowed when buffer is locked', function() command('au OptionSet diff norm! gf') command([[call setline(1, ['Xfile1', 'line2', 'line3', 'line4'])]]) - eq('OptionSet Autocommands for "diff": Vim(normal):E788: Not allowed to edit another buffer now', - pcall_err(command, 'diffthis')) + eq( + 'OptionSet Autocommands for "diff": Vim(normal):E788: Not allowed to edit another buffer now', + pcall_err(command, 'diffthis') + ) end) end) diff --git a/test/functional/legacy/global_spec.lua b/test/functional/legacy/global_spec.lua index ff02c41e6c..2c92b7814a 100644 --- a/test/functional/legacy/global_spec.lua +++ b/test/functional/legacy/global_spec.lua @@ -12,8 +12,8 @@ describe(':global', function() it('can be interrupted using Ctrl-C in cmdline mode vim-patch:9.0.0082', function() local screen = Screen.new(75, 6) screen:set_default_attr_ids({ - [0] = {bold = true, reverse = true}, -- MsgSeparator - [1] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg + [0] = { bold = true, reverse = true }, -- MsgSeparator + [1] = { background = Screen.colors.Red, foreground = Screen.colors.White }, -- ErrorMsg }) screen:attach() @@ -24,20 +24,17 @@ describe(':global', function() ]]) feed(':g/foo/norm :<C-V>;<CR>') - poke_eventloop() -- Wait for :sleep to start + poke_eventloop() -- Wait for :sleep to start feed('<C-C>') screen:expect([[ ^foo | - foo | - foo | - foo | - foo | + foo |*4 {1:Interrupted} | ]]) -- Also test in Ex mode feed('gQg/foo/norm :<C-V>;<CR>') - poke_eventloop() -- Wait for :sleep to start + poke_eventloop() -- Wait for :sleep to start feed('<C-C>') screen:expect([[ {0: }| diff --git a/test/functional/legacy/highlight_spec.lua b/test/functional/legacy/highlight_spec.lua index 0a130f1607..3d06bf3978 100644 --- a/test/functional/legacy/highlight_spec.lua +++ b/test/functional/legacy/highlight_spec.lua @@ -39,7 +39,9 @@ describe(':highlight', function() -- Test setting colors. -- Test clearing one color and all doesn't generate error or warning - feed_command('hi NewGroup cterm=italic ctermfg=DarkBlue ctermbg=Grey gui=NONE guifg=#00ff00 guibg=Cyan') + feed_command( + 'hi NewGroup cterm=italic ctermfg=DarkBlue ctermbg=Grey gui=NONE guifg=#00ff00 guibg=Cyan' + ) feed_command('hi Group2 cterm=NONE') feed_command('hi Group3 cterm=bold') feed_command('redir! @a') @@ -54,8 +56,7 @@ describe(':highlight', function() feed_command('hi clear') feed_command('hi Group3') feed('<cr>') - eq('Vim(highlight):E475: Invalid argument: cterm=\'asdf', - exc_exec([[hi Crash cterm='asdf]])) + eq("Vim(highlight):E475: Invalid argument: cterm='asdf", exc_exec([[hi Crash cterm='asdf]])) feed_command('redir END') -- Filter ctermfg and ctermbg, the numbers depend on the terminal @@ -99,9 +100,9 @@ describe('Visual selection highlight', function() it("when 'showbreak' is set", function() local screen = Screen.new(60, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {background = Screen.colors.LightGrey}, -- Visual - [2] = {bold = true}, -- ModeMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { background = Screen.colors.LightGrey, foreground = Screen.colors.Black }, -- Visual + [2] = { bold = true }, -- ModeMsg }) screen:attach() exec([[ @@ -112,10 +113,7 @@ describe('Visual selection highlight', function() feed('v$') screen:expect([[ {0:>}{1:n, no sea takimata sanctus est Lorem ipsum dolor sit amet.}^ | - | - | - | - | + |*4 {2:-- VISUAL --} | ]]) end) diff --git a/test/functional/legacy/increment_spec.lua b/test/functional/legacy/increment_spec.lua index d35f4bdae6..a81044114c 100644 --- a/test/functional/legacy/increment_spec.lua +++ b/test/functional/legacy/increment_spec.lua @@ -3,10 +3,9 @@ local helpers = require('test.functional.helpers')(after_each) local source, command = helpers.source, helpers.command local call, clear = helpers.call, helpers.clear -local eq, nvim = helpers.eq, helpers.meths +local eq, nvim = helpers.eq, helpers.api describe('Ctrl-A/Ctrl-X on visual selections', function() - before_each(function() clear() source([=[ @@ -744,18 +743,18 @@ describe('Ctrl-A/Ctrl-X on visual selections', function() it('works on Test ' .. id, function() command('set nrformats&vi') -- &vi makes Vim compatible call('Test_visual_increment_' .. id) - eq({}, nvim.get_vvar('errors')) + eq({}, nvim.nvim_get_vvar('errors')) end) end it('does not drop leading zeroes', function() command('set nrformats&vi') -- &vi makes Vim compatible call('Test_normal_increment_01') - eq({}, nvim.get_vvar('errors')) + eq({}, nvim.nvim_get_vvar('errors')) end) it('maintains correct column after CTRL-A', function() call('Test_normal_increment_02') - eq({}, nvim.get_vvar('errors')) + eq({}, nvim.nvim_get_vvar('errors')) end) end) diff --git a/test/functional/legacy/lispwords_spec.lua b/test/functional/legacy/lispwords_spec.lua index 57d8d51377..efac8775d3 100644 --- a/test/functional/legacy/lispwords_spec.lua +++ b/test/functional/legacy/lispwords_spec.lua @@ -8,7 +8,7 @@ local source = helpers.source describe('lispwords', function() before_each(clear) - it('should be set global-local',function() + it('should be set global-local', function() source([[ setglobal lispwords=foo,bar,baz setlocal lispwords-=foo diff --git a/test/functional/legacy/listchars_spec.lua b/test/functional/legacy/listchars_spec.lua index a9aa238d4e..746e0550a6 100644 --- a/test/functional/legacy/listchars_spec.lua +++ b/test/functional/legacy/listchars_spec.lua @@ -103,10 +103,10 @@ describe("'listchars'", function() it('"exceeds" character does not appear in foldcolumn vim-patch:8.2.3121', function() local screen = Screen.new(60, 10) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [2] = {bold = true, reverse = true}, -- StatusLine - [3] = {reverse = true}, -- StatusLineNC - [4] = {background = Screen.colors.Grey, foreground = Screen.colors.DarkBlue}, -- FoldColumn, SignColumn + [1] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [2] = { bold = true, reverse = true }, -- StatusLine + [3] = { reverse = true }, -- StatusLineNC + [4] = { background = Screen.colors.Grey, foreground = Screen.colors.DarkBlue }, -- FoldColumn, SignColumn }) screen:attach() exec([[ @@ -121,10 +121,7 @@ describe("'listchars'", function() {4: } │{4: } │{4: } | {4: }a │{4: }a │{4: }a | {4: }aaaaaa │{4: }a{1:>}│{4: }aaaaaa | - {1:~ }│{1:~ }│{1:~ }| - {1:~ }│{1:~ }│{1:~ }| - {1:~ }│{1:~ }│{1:~ }| - {1:~ }│{1:~ }│{1:~ }| + {1:~ }│{1:~ }│{1:~ }|*4 {3:[No Name] [+] <[+] }{2:[No Name] [+] }| | ]]) @@ -134,10 +131,7 @@ describe("'listchars'", function() {4: } │{4: } │{4: } | {4: }a │{4: }a│{4: }a | {4: }aaaaaa │{4: }{1:>}│{4: }aaaaaa | - {1:~ }│{1:~ }│{1:~ }| - {1:~ }│{1:~ }│{1:~ }| - {1:~ }│{1:~ }│{1:~ }| - {1:~ }│{1:~ }│{1:~ }| + {1:~ }│{1:~ }│{1:~ }|*4 {3:[No Name] [+] <+] }{2:[No Name] [+] }| | ]]) @@ -147,10 +141,7 @@ describe("'listchars'", function() {4: } │{4: }│{4: } | {4: }a │{4: }│{4: }a | {4: }aaaaaa │{4: }│{4: }aaaaaa | - {1:~ }│{1:~ }│{1:~ }| - {1:~ }│{1:~ }│{1:~ }| - {1:~ }│{1:~ }│{1:~ }| - {1:~ }│{1:~ }│{1:~ }| + {1:~ }│{1:~ }│{1:~ }|*4 {3:[No Name] [+] <] }{2:[No Name] [+] }| | ]]) @@ -160,10 +151,7 @@ describe("'listchars'", function() {4: } │{4: }│{4: } | {4: }a │{4: }│{4: }a | {4: }aaaaaa │{4: }│{4: }aaaaaa | - {1:~ }│{1:~ }│{1:~ }| - {1:~ }│{1:~ }│{1:~ }| - {1:~ }│{1:~ }│{1:~ }| - {1:~ }│{1:~ }│{1:~ }| + {1:~ }│{1:~ }│{1:~ }|*4 {3:[No Name] [+] < }{2:[No Name] [+] }| | ]]) @@ -173,10 +161,7 @@ describe("'listchars'", function() {4: } │{4: }│{4: } | {4: }a │{4: }│{4: }a | {4: }aaaaaa │{4: }│{4: }aaaaaa | - {1:~ }│{1:~}│{1:~ }| - {1:~ }│{1:~}│{1:~ }| - {1:~ }│{1:~}│{1:~ }| - {1:~ }│{1:~}│{1:~ }| + {1:~ }│{1:~}│{1:~ }|*4 {3:[No Name] [+] < }{2:[No Name] [+] }| | ]]) @@ -187,10 +172,7 @@ describe("'listchars'", function() {4: } │{4: } │{4: } | {4: }a │{4: }a │{4: }a | {4: }aaaaaa │{4: }aaaaaa │{4: }aaaaaa | - {1:~ }│{1:~ }│{1:~ }| - {1:~ }│{1:~ }│{1:~ }| - {1:~ }│{1:~ }│{1:~ }| - {1:~ }│{1:~ }│{1:~ }| + {1:~ }│{1:~ }│{1:~ }|*4 {3:[No Name] [+] }{2:[No Name] [+] }{3:[No Name] [+] }| :set nowrap foldcolumn=4 | ]]) @@ -200,10 +182,7 @@ describe("'listchars'", function() {4: } │{4: }│{4: } | {4: }a │{4: }│{4: }a | {4: }aaaaaa │{4: ^ }│{4: }aaaaaa | - {1:~ }│{1:~ }│{1:~ }| - {1:~ }│{1:~ }│{1:~ }| - {1:~ }│{1:~ }│{1:~ }| - {1:~ }│{1:~ }│{1:~ }| + {1:~ }│{1:~ }│{1:~ }|*4 {3:[No Name] [+] }{2:<[+] }{3:[No Name] [+] }| :set nowrap foldcolumn=4 | ]]) @@ -213,10 +192,7 @@ describe("'listchars'", function() {4: } │{4: }│{4: } | {4: }a │{4: }│{4: }a | {4: }aaaaaa │{4:^ }│{4: }aaaaaa | - {1:~ }│{1:~}│{1:~ }| - {1:~ }│{1:~}│{1:~ }| - {1:~ }│{1:~}│{1:~ }| - {1:~ }│{1:~}│{1:~ }| + {1:~ }│{1:~}│{1:~ }|*4 {3:[No Name] [+] }{2:< }{3:[No Name] [+] }| :set nowrap foldcolumn=4 | ]]) diff --git a/test/functional/legacy/listlbr_spec.lua b/test/functional/legacy/listlbr_spec.lua index d4f11a61c2..50628e5ef9 100644 --- a/test/functional/legacy/listlbr_spec.lua +++ b/test/functional/legacy/listlbr_spec.lua @@ -57,7 +57,9 @@ describe('listlbr', function() feed_command('let line=ScreenChar(winwidth(0))') feed_command('call DoRecordScreen()') - feed_command('let g:test ="Test 4: set linebreak with tab and 1 line as long as screen: should break!"') + feed_command( + 'let g:test ="Test 4: set linebreak with tab and 1 line as long as screen: should break!"' + ) feed_command('set nolist linebreak ts=8') feed_command([[let line="1\t".repeat('a', winwidth(0)-2)]]) feed_command('$put =line') @@ -71,7 +73,9 @@ describe('listlbr', function() feed_command('$') feed_command('norm! zt') - feed_command('let g:test ="Test 5: set linebreak with conceal and set list and tab displayed by different char (line may not be truncated)"') + feed_command( + 'let g:test ="Test 5: set linebreak with conceal and set list and tab displayed by different char (line may not be truncated)"' + ) feed_command('set cpo&vim list linebreak conceallevel=2 concealcursor=nv listchars=tab:ab') feed_command('syn match ConcealVar contained /_/ conceal') feed_command('syn match All /.*/ contains=ConcealVar') @@ -201,9 +205,9 @@ describe('listlbr', function() it('cursor position is drawn correctly after operator', function() local screen = Screen.new(60, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {background = Screen.colors.LightGrey}, -- Visual - [2] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { background = Screen.colors.LightGrey, foreground = Screen.colors.Black }, -- Visual + [2] = { background = Screen.colors.Red, foreground = Screen.colors.White }, -- ErrorMsg }) screen:attach() @@ -217,18 +221,14 @@ describe('listlbr', function() screen:expect([[ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | bbbbbbbbbb {1:c}^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 2 | ]]) feed('zo') screen:expect([[ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | bbbbbbbbbb ^c | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {2:E490: No fold found} | ]]) @@ -236,18 +236,14 @@ describe('listlbr', function() screen:expect([[ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | bbbbbbbbbb {1:c}^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {2:E490: No fold found} 2 | ]]) feed('gq') screen:expect([[ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | bbbbbbbbbb ^c | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {2:E490: No fold found} | ]]) @@ -255,18 +251,14 @@ describe('listlbr', function() screen:expect([[ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | bbbbbbbbbb {1:c}^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {2:E490: No fold found} 1x2 | ]]) feed('I') screen:expect([[ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | bbbbbbbbbb ^c | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {2:E490: No fold found} | ]]) @@ -274,18 +266,14 @@ describe('listlbr', function() screen:expect([[ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | bbbbbbbbbb {1:c}^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {2:E490: No fold found} 2 | ]]) feed('s') screen:expect([[ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | bbbbbbbbbb ^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {2:E490: No fold found} | ]]) end) diff --git a/test/functional/legacy/listlbr_utf8_spec.lua b/test/functional/legacy/listlbr_utf8_spec.lua index d7f4c71af2..8e5d9b88bc 100644 --- a/test/functional/legacy/listlbr_utf8_spec.lua +++ b/test/functional/legacy/listlbr_utf8_spec.lua @@ -1,12 +1,14 @@ -- Test for linebreak and list option in utf-8 mode local helpers = require('test.functional.helpers')(after_each) +local Screen = require('test.functional.ui.screen') local source = helpers.source local feed = helpers.feed +local exec = helpers.exec local clear, expect = helpers.clear, helpers.expect describe('linebreak', function() - setup(clear) + before_each(clear) -- luacheck: ignore 621 (Indentation) -- luacheck: ignore 613 (Trailing whitespaces in a string) @@ -208,4 +210,29 @@ describe('linebreak', function() a b c¶ Screen attributes are the same!]]) end) + + -- oldtest: Test_visual_ends_before_showbreak() + it("Visual area is correct when it ends before multibyte 'showbreak'", function() + local screen = Screen.new(60, 8) + screen:set_default_attr_ids({ + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { background = Screen.colors.LightGrey, foreground = Screen.colors.Black }, -- Visual + [2] = { bold = true }, -- ModeMsg + }) + screen:attach() + exec([[ + let &wrap = v:true + let &linebreak = v:true + let &showbreak = '↪ ' + eval ['xxxxx ' .. 'y'->repeat(&columns - 6) .. ' zzzz']->setline(1) + normal! wvel + ]]) + screen:expect([[ + xxxxx | + {0:↪ }{1:yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy}^ {1: }| + {0:↪ }zzzz | + {0:~ }|*4 + {2:-- VISUAL --} | + ]]) + end) end) diff --git a/test/functional/legacy/mapping_spec.lua b/test/functional/legacy/mapping_spec.lua index c1f23ab0a6..9eddec40f7 100644 --- a/test/functional/legacy/mapping_spec.lua +++ b/test/functional/legacy/mapping_spec.lua @@ -3,8 +3,8 @@ local helpers = require('test.functional.helpers')(after_each) local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert local expect, poke_eventloop = helpers.expect, helpers.poke_eventloop -local command, eq, eval, meths = helpers.command, helpers.eq, helpers.eval, helpers.meths -local sleep = helpers.sleep +local command, eq, eval, api = helpers.command, helpers.eq, helpers.eval, helpers.api +local sleep = vim.uv.sleep describe('mapping', function() before_each(clear) @@ -110,7 +110,9 @@ describe('mapping', function() command('imapclear') command('set whichwrap=<,>,[,]') feed('G3o<esc>2k') - command([[:exe ":norm! iTest3: text with a (parenthesis here\<C-G>U\<Right>new line here\<esc>\<up>\<up>."]]) + command( + [[:exe ":norm! iTest3: text with a (parenthesis here\<C-G>U\<Right>new line here\<esc>\<up>\<up>."]] + ) expect([[ @@ -132,9 +134,9 @@ describe('mapping', function() command('nnoremap <LeftDrag> <LeftDrag><Cmd><CR>') poke_eventloop() - meths.input_mouse('left', 'press', '', 0, 0, 0) + api.nvim_input_mouse('left', 'press', '', 0, 0, 0) poke_eventloop() - meths.input_mouse('left', 'drag', '', 0, 0, 1) + api.nvim_input_mouse('left', 'drag', '', 0, 0, 1) poke_eventloop() eq('s', eval('mode()')) end) @@ -145,9 +147,9 @@ describe('mapping', function() command('inoremap <LeftDrag> <LeftDrag><Cmd>let g:dragged = 1<CR>') feed('i') poke_eventloop() - meths.input_mouse('left', 'press', '', 0, 0, 0) + api.nvim_input_mouse('left', 'press', '', 0, 0, 0) poke_eventloop() - meths.input_mouse('left', 'drag', '', 0, 0, 1) + api.nvim_input_mouse('left', 'drag', '', 0, 0, 1) poke_eventloop() eq(1, eval('g:dragged')) eq('v', eval('mode()')) @@ -156,9 +158,9 @@ describe('mapping', function() command([[inoremap <LeftDrag> <LeftDrag><C-\><C-N>]]) feed('i') poke_eventloop() - meths.input_mouse('left', 'press', '', 0, 0, 0) + api.nvim_input_mouse('left', 'press', '', 0, 0, 0) poke_eventloop() - meths.input_mouse('left', 'drag', '', 0, 0, 1) + api.nvim_input_mouse('left', 'drag', '', 0, 0, 1) poke_eventloop() eq('n', eval('mode()')) end) diff --git a/test/functional/legacy/match_spec.lua b/test/functional/legacy/match_spec.lua index b6e45c396c..ab791f03e5 100644 --- a/test/functional/legacy/match_spec.lua +++ b/test/functional/legacy/match_spec.lua @@ -11,8 +11,8 @@ describe('matchaddpos()', function() it('can add more than 8 match positions vim-patch:9.0.0620', function() local screen = Screen.new(60, 14) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {background = Screen.colors.Yellow}, -- Search + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { background = Screen.colors.Yellow }, -- Search }) screen:attach() exec([[ @@ -43,8 +43,8 @@ describe('match highlighting', function() it('does not continue in linebreak vim-patch:8.2.3698', function() local screen = Screen.new(75, 10) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { background = Screen.colors.Red, foreground = Screen.colors.White }, -- ErrorMsg }) screen:attach() exec([=[ @@ -55,13 +55,7 @@ describe('match highlighting', function() screen:expect([[ ^xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx{1:]} | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*7 | ]]) end) @@ -69,9 +63,9 @@ describe('match highlighting', function() it('is shown with incsearch vim-patch:8.2.3940', function() local screen = Screen.new(75, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {background = Screen.colors.Yellow}, -- Search - [2] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { background = Screen.colors.Yellow }, -- Search + [2] = { background = Screen.colors.Red, foreground = Screen.colors.White }, -- ErrorMsg }) screen:attach() exec([[ @@ -101,8 +95,8 @@ describe('match highlighting', function() it('on a Tab vim-patch:8.2.4062', function() local screen = Screen.new(75, 10) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { background = Screen.colors.Red, foreground = Screen.colors.White }, -- ErrorMsg }) screen:attach() exec([[ @@ -112,14 +106,7 @@ describe('match highlighting', function() ]]) screen:expect([[ {1: ^ }ix | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*8 | ]]) end) diff --git a/test/functional/legacy/matchparen_spec.lua b/test/functional/legacy/matchparen_spec.lua index 22d9247698..b03107deb0 100644 --- a/test/functional/legacy/matchparen_spec.lua +++ b/test/functional/legacy/matchparen_spec.lua @@ -13,8 +13,8 @@ describe('matchparen', function() local screen = Screen.new(30, 7) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true}, - [2] = {background = Screen.colors.LightGrey}, + [1] = { bold = true }, + [2] = { background = Screen.colors.LightGrey, foreground = Screen.colors.Black }, }) exec([[ @@ -40,23 +40,19 @@ describe('matchparen', function() it('matchparen highlight is cleared when switching buffer', function() local screen = Screen.new(20, 5) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, - [1] = {background = Screen.colors.Cyan}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { background = Screen.colors.Cyan }, }) screen:attach() local screen1 = [[ {1:^()} | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]] local screen2 = [[ ^aa | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]] @@ -86,11 +82,11 @@ describe('matchparen', function() local screen = Screen.new(30, 9) screen:attach() screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}; - [1] = {background = Screen.colors.Plum1}; - [2] = {background = Screen.colors.Grey}; - [3] = {bold = true}; - [4] = {bold = true, foreground = Screen.colors.SeaGreen}; + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { background = Screen.colors.Plum1 }, + [2] = { background = Screen.colors.Grey }, + [3] = { bold = true }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen }, }) exec([[ @@ -101,7 +97,8 @@ describe('matchparen', function() ]]) feed('i<C-X><C-N><C-N>') - screen:expect{grid=[[ + screen:expect { + grid = [[ aa | aaa | aaaa | @@ -111,6 +108,7 @@ describe('matchparen', function() {1: aaaa }{0: }| {0:~ }| {3:-- }{4:match 2 of 3} | - ]]} + ]], + } end) end) diff --git a/test/functional/legacy/memory_usage_spec.lua b/test/functional/legacy/memory_usage_spec.lua index 5f722e5190..a05e9fdf57 100644 --- a/test/functional/legacy/memory_usage_spec.lua +++ b/test/functional/legacy/memory_usage_spec.lua @@ -19,7 +19,10 @@ if is_asan() then return elseif is_os('win') then if is_ci('github') then - pending('Windows runners in Github Actions do not have a stable environment to estimate memory usage', function() end) + pending( + 'Windows runners in Github Actions do not have a stable environment to estimate memory usage', + function() end + ) return elseif eval("executable('wmic')") == 0 then pending('missing "wmic" command', function() end) @@ -34,9 +37,9 @@ local monitor_memory_usage = { memory_usage = function(self) local handle if is_os('win') then - handle = io.popen('wmic process where processid=' ..self.pid..' get WorkingSetSize') + handle = io.popen('wmic process where processid=' .. self.pid .. ' get WorkingSetSize') else - handle = io.popen('ps -o rss= -p '..self.pid) + handle = io.popen('ps -o rss= -p ' .. self.pid) end return tonumber(handle:read('*a'):match('%d+')) end, @@ -49,7 +52,7 @@ local monitor_memory_usage = { table.insert(self.hist, val) ok(#self.hist > 20) local result = {} - for key,value in ipairs(self.hist) do + for key, value in ipairs(self.hist) do if value ~= self.hist[key + 1] then table.insert(result, value) end @@ -60,7 +63,7 @@ local monitor_memory_usage = { end) end, dump = function(self) - return 'max: '..self.max ..', last: '..self.last + return 'max: ' .. self.max .. ', last: ' .. self.last end, monitor_memory_usage = function(self, pid) local obj = { @@ -72,12 +75,13 @@ local monitor_memory_usage = { setmetatable(obj, { __index = self }) obj:op() return obj - end + end, } -setmetatable(monitor_memory_usage, -{__call = function(self, pid) - return monitor_memory_usage.monitor_memory_usage(self, pid) -end}) +setmetatable(monitor_memory_usage, { + __call = function(self, pid) + return monitor_memory_usage.monitor_memory_usage(self, pid) + end, +}) describe('memory usage', function() local tmpfile = 'X_memory_usage' @@ -101,46 +105,51 @@ describe('memory usage', function() --[[ Case: if a local variable captures a:000, funccall object will be free just after it finishes. - ]]-- + ]] + -- it('function capture vargs', function() local pid = eval('getpid()') local before = monitor_memory_usage(pid) - write_file(tmpfile, [[ + write_file( + tmpfile, + [[ func s:f(...) let x = a:000 endfunc for _ in range(10000) call s:f(0) endfor - ]]) + ]] + ) -- TODO: check_result fails if command() is used here. Why? #16064 - feed_command('source '..tmpfile) + feed_command('source ' .. tmpfile) poke_eventloop() local after = monitor_memory_usage(pid) -- Estimate the limit of max usage as 2x initial usage. -- The lower limit can fluctuate a bit, use 97%. - check_result({before=before, after=after}, - pcall(ok, before.last * 97 / 100 < after.max)) - check_result({before=before, after=after}, - pcall(ok, before.last * 2 > after.max)) + check_result({ before = before, after = after }, pcall(ok, before.last * 97 / 100 < after.max)) + check_result({ before = before, after = after }, pcall(ok, before.last * 2 > after.max)) -- In this case, garbage collecting is not needed. -- The value might fluctuate a bit, allow for 3% tolerance below and 5% above. -- Based on various test runs. local lower = after.last * 97 / 100 local upper = after.last * 105 / 100 - check_result({before=before, after=after}, pcall(ok, lower < after.max)) - check_result({before=before, after=after}, pcall(ok, after.max < upper)) + check_result({ before = before, after = after }, pcall(ok, lower < after.max)) + check_result({ before = before, after = after }, pcall(ok, after.max < upper)) end) --[[ Case: if a local variable captures l: dict, funccall object will not be free until garbage collector runs, but after that memory usage doesn't increase so much even when rerun Xtest.vim since system memory caches. - ]]-- + ]] + -- it('function capture lvars', function() local pid = eval('getpid()') local before = monitor_memory_usage(pid) - write_file(tmpfile, [[ + write_file( + tmpfile, + [[ if !exists('s:defined_func') func s:f() let x = l: @@ -150,13 +159,14 @@ describe('memory usage', function() for _ in range(10000) call s:f() endfor - ]]) - feed_command('source '..tmpfile) + ]] + ) + feed_command('source ' .. tmpfile) poke_eventloop() local after = monitor_memory_usage(pid) for _ = 1, 3 do -- TODO: check_result fails if command() is used here. Why? #16064 - feed_command('source '..tmpfile) + feed_command('source ' .. tmpfile) poke_eventloop() end local last = monitor_memory_usage(pid) @@ -167,10 +177,8 @@ describe('memory usage', function() local upper_multiplier = is_os('freebsd') and 19 or 12 local lower = before.last * 8 / 10 local upper = load_adjust((after.max + (after.last - before.last)) * upper_multiplier / 10) - check_result({before=before, after=after, last=last}, - pcall(ok, lower < last.last)) - check_result({before=before, after=after, last=last}, - pcall(ok, last.last < upper)) + check_result({ before = before, after = after, last = last }, pcall(ok, lower < last.last)) + check_result({ before = before, after = after, last = last }, pcall(ok, last.last < upper)) end) it('releases memory when closing windows when folds exist', function() @@ -205,6 +213,6 @@ describe('memory usage', function() -- but is small enough that if memory were not released (prior to PR #14884), the test -- would fail. local upper = before.last * 1.10 - check_result({before=before, after=after}, pcall(ok, after.last <= upper)) + check_result({ before = before, after = after }, pcall(ok, after.last <= upper)) end) end) diff --git a/test/functional/legacy/messages_spec.lua b/test/functional/legacy/messages_spec.lua index e0cc1dc79c..a87398b158 100644 --- a/test/functional/legacy/messages_spec.lua +++ b/test/functional/legacy/messages_spec.lua @@ -4,7 +4,7 @@ local clear = helpers.clear local command = helpers.command local exec = helpers.exec local feed = helpers.feed -local meths = helpers.meths +local api = helpers.api local nvim_dir = helpers.nvim_dir local assert_alive = helpers.assert_alive @@ -17,10 +17,10 @@ describe('messages', function() it('a warning causes scrolling if and only if it has a stacktrace', function() screen = Screen.new(75, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg - [2] = {bold = true, reverse = true}, -- MsgSeparator - [3] = {foreground = Screen.colors.Red}, -- WarningMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { bold = true, foreground = Screen.colors.SeaGreen }, -- MoreMsg + [2] = { bold = true, reverse = true }, -- MsgSeparator + [3] = { foreground = Screen.colors.Red }, -- WarningMsg }) screen:attach() @@ -32,20 +32,17 @@ describe('messages', function() command('enew') command('set readonly') feed('u') - screen:expect({grid = [[ + screen:expect({ + grid = [[ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:W10: Warning: Changing a readonly file}^ | - ]], timeout = 500}) + ]], + timeout = 500, + }) screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 Already at oldest change | ]]) end) @@ -54,8 +51,8 @@ describe('messages', function() it('clearing mode does not remove message', function() screen = Screen.new(60, 10) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { background = Screen.colors.Red, foreground = Screen.colors.White }, -- ErrorMsg }) screen:attach() exec([[ @@ -74,12 +71,7 @@ describe('messages', function() ^one | NoSuchFile | three | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 from DebugSilent normal | ]]) @@ -89,12 +81,7 @@ describe('messages', function() ^one | NoSuchFile | three | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 from DebugSilent visual | ]]) @@ -105,11 +92,7 @@ describe('messages', function() one | NoSuchFil^e | three | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 from DebugSilent visual | {1:E447: Can't find file "NoSuchFile" in path} | ]]) @@ -124,8 +107,8 @@ describe('messages', function() it('works', function() screen = Screen.new(75, 6) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg - [2] = {foreground = Screen.colors.Brown}, -- LineNr + [1] = { bold = true, foreground = Screen.colors.SeaGreen }, -- MoreMsg + [2] = { foreground = Screen.colors.Brown }, -- LineNr }) screen:attach() @@ -421,15 +404,15 @@ describe('messages', function() it('verbose message before echo command', function() screen = Screen.new(60, 10) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { bold = true, foreground = Screen.colors.SeaGreen }, -- MoreMsg }) screen:attach() - command('cd '..nvim_dir) - meths.set_option_value('shell', './shell-test', {}) - meths.set_option_value('shellcmdflag', 'REP 20', {}) - meths.set_option_value('shellxquote', '', {}) -- win: avoid extra quotes + command('cd ' .. nvim_dir) + api.nvim_set_option_value('shell', './shell-test', {}) + api.nvim_set_option_value('shellcmdflag', 'REP 20', {}) + api.nvim_set_option_value('shellxquote', '', {}) -- win: avoid extra quotes -- display a page and go back, results in exactly the same view feed([[:4 verbose echo system('foo')<CR>]]) @@ -475,18 +458,10 @@ describe('messages', function() -- do the same with 'cmdheight' set to 2 feed('q') command('set ch=2') - command('mode') -- FIXME: bottom is invalid after scrolling screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - | - | + {0:~ }|*7 + |*2 ]]) feed([[:4 verbose echo system('foo')<CR>]]) screen:expect([[ @@ -533,9 +508,9 @@ describe('messages', function() it('with control characters can be quit vim-patch:8.2.1844', function() screen = Screen.new(40, 10) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg - [2] = {foreground = Screen.colors.Blue}, -- SpecialKey + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { bold = true, foreground = Screen.colors.SeaGreen }, -- MoreMsg + [2] = { foreground = Screen.colors.Blue }, -- SpecialKey }) screen:attach() @@ -555,14 +530,7 @@ describe('messages', function() feed('q') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*8 | ]]) end) @@ -572,9 +540,9 @@ describe('messages', function() before_each(function() screen = Screen.new(40, 6) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [2] = {bold = true}, -- ModeMsg - [3] = {bold = true, reverse=true}, -- StatusLine + [1] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [2] = { bold = true }, -- ModeMsg + [3] = { bold = true, reverse = true }, -- StatusLine }) screen:attach() end) @@ -591,18 +559,14 @@ describe('messages', function() feed('i') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {3: }| {2:-- INSERT --} | ]]) feed('<C-C>') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {3: }| | ]]) @@ -617,18 +581,14 @@ describe('messages', function() feed('i') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {3:[No Name] }| {2:-- INSERT --} | ]]) feed('<Esc>') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {3:[No Name] }| | ]]) @@ -639,19 +599,13 @@ describe('messages', function() feed('i<C-O>') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {2:-- (insert) --} | ]]) feed('<C-C>') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]) end) @@ -661,9 +615,9 @@ describe('messages', function() it('y/n prompt works', function() screen = Screen.new(75, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg - [2] = {bold = true, reverse = true}, -- MsgSeparator + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { bold = true, foreground = Screen.colors.SeaGreen }, -- MoreMsg + [2] = { bold = true, reverse = true }, -- MsgSeparator }) screen:attach() command('set noincsearch nohlsearch inccommand=') @@ -673,18 +627,14 @@ describe('messages', function() screen:expect([[ 1 | 2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {1:Backwards range given, OK to swap (y/n)?}^ | ]]) feed('n') screen:expect([[ ^1 | 2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {1:Backwards range given, OK to swap (y/n)?}n | ]]) @@ -692,18 +642,14 @@ describe('messages', function() screen:expect([[ 1 | 2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {1:Backwards range given, OK to swap (y/n)?}^ | ]]) feed('<Esc>') screen:expect([[ ^1 | 2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {1:Backwards range given, OK to swap (y/n)?}n | ]]) @@ -711,18 +657,14 @@ describe('messages', function() screen:expect([[ 1 | 2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {1:Backwards range given, OK to swap (y/n)?}^ | ]]) feed('y') screen:expect([[ y1 | ^y2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {1:Backwards range given, OK to swap (y/n)?}y | ]]) end) @@ -731,10 +673,10 @@ describe('messages', function() it("fileinfo works when 'cmdheight' has just decreased", function() screen = Screen.new(40, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}; -- NonText - [1] = {bold = true}; -- TabLineSel - [2] = {underline = true, background = Screen.colors.LightGrey}; -- TabLine - [3] = {reverse = true}; -- TabLineFill + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { bold = true }, -- TabLineSel + [2] = { underline = true, background = Screen.colors.LightGrey }, -- TabLine + [3] = { reverse = true }, -- TabLineFill }) screen:attach() @@ -745,23 +687,18 @@ describe('messages', function() tabnew set cmdheight=2 ]]) - command('mode') -- FIXME: bottom is invalid after scrolling screen:expect([[ {2: [No Name] }{1: [No Name] }{3: }{2:X}| ^ | - {0:~ }| - {0:~ }| - | - | + {0:~ }|*2 + |*2 ]]) feed(':tabprev | edit Xfileinfo.txt<CR>') screen:expect([[ {1: Xfileinfo.txt }{2: [No Name] }{3: }{2:X}| ^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 "Xfileinfo.txt" [New] | ]]) assert_alive() @@ -771,7 +708,7 @@ describe('messages', function() it('fileinfo does not overwrite echo message vim-patch:8.2.4156', function() screen = Screen.new(40, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText }) screen:attach() @@ -793,17 +730,9 @@ describe('messages', function() feed('0$') screen:expect([[ ^hi | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 'b' written | ]]) os.remove('b.txt') end) - - it('no crash when truncating overlong message', function() - pcall(command, 'source test/old/testdir/crash/vim_msg_trunc_poc') - assert_alive() - end) end) diff --git a/test/functional/legacy/mksession_spec.lua b/test/functional/legacy/mksession_spec.lua index bca9cd833c..689d918cd9 100644 --- a/test/functional/legacy/mksession_spec.lua +++ b/test/functional/legacy/mksession_spec.lua @@ -1,7 +1,7 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local command = helpers.command -local funcs = helpers.funcs +local fn = helpers.fn local eq = helpers.eq describe('mksession', function() @@ -18,7 +18,7 @@ describe('mksession', function() command('mksession! Xtest_mks.out') local found_rtp = 0 local found_pp = 0 - for _, line in pairs(funcs.readfile('Xtest_mks.out', 'b')) do + for _, line in pairs(fn.readfile('Xtest_mks.out', 'b')) do if line:find('set runtimepath') then found_rtp = found_rtp + 1 end @@ -32,7 +32,7 @@ describe('mksession', function() command('set sessionoptions+=skiprtp') command('mksession! Xtest_mks.out') local found_rtp_or_pp = 0 - for _, line in pairs(funcs.readfile('Xtest_mks.out', 'b')) do + for _, line in pairs(fn.readfile('Xtest_mks.out', 'b')) do if line:find('set runtimepath') or line:find('set packpath') then found_rtp_or_pp = found_rtp_or_pp + 1 end diff --git a/test/functional/legacy/move_spec.lua b/test/functional/legacy/move_spec.lua index 855996da8f..1500d48ad9 100644 --- a/test/functional/legacy/move_spec.lua +++ b/test/functional/legacy/move_spec.lua @@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local clear = helpers.clear local feed = helpers.feed -local funcs = helpers.funcs +local fn = helpers.fn before_each(clear) @@ -11,22 +11,18 @@ describe(':move', function() it('redraws correctly when undone', function() local screen = Screen.new(60, 10) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText }) screen:attach() - funcs.setline(1, {'First', 'Second', 'Third', 'Fourth'}) + fn.setline(1, { 'First', 'Second', 'Third', 'Fourth' }) feed('gg:move +1<CR>') screen:expect([[ Second | ^First | Third | Fourth | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 :move +1 | ]]) @@ -38,11 +34,7 @@ describe(':move', function() Second | Third | Fourth | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) end) diff --git a/test/functional/legacy/normal_spec.lua b/test/functional/legacy/normal_spec.lua index ba875460f5..1dddeed033 100644 --- a/test/functional/legacy/normal_spec.lua +++ b/test/functional/legacy/normal_spec.lua @@ -7,35 +7,29 @@ before_each(clear) describe('normal', function() -- oldtest: Test_normal_j_below_botline() - it([["j" does not skip lines when scrolling below botline and 'foldmethod' is not "manual"]], function() - local screen = Screen.new(40, 19) - screen:attach() - screen:set_default_attr_ids({{foreground = Screen.colors.Brown}}) - exec([[ + it( + [["j" does not skip lines when scrolling below botline and 'foldmethod' is not "manual"]], + function() + local screen = Screen.new(40, 19) + screen:attach() + screen:set_default_attr_ids({ { foreground = Screen.colors.Brown } }) + exec([[ set number foldmethod=diff scrolloff=0 call setline(1, map(range(1, 9), 'repeat(v:val, 200)')) norm Lj ]]) - screen:expect([[ + screen:expect([[ {1: 2 }222222222222222222222222222222222222| - {1: }222222222222222222222222222222222222| - {1: }222222222222222222222222222222222222| - {1: }222222222222222222222222222222222222| - {1: }222222222222222222222222222222222222| + {1: }222222222222222222222222222222222222|*4 {1: }22222222222222222222 | {1: 3 }333333333333333333333333333333333333| - {1: }333333333333333333333333333333333333| - {1: }333333333333333333333333333333333333| - {1: }333333333333333333333333333333333333| - {1: }333333333333333333333333333333333333| + {1: }333333333333333333333333333333333333|*4 {1: }33333333333333333333 | {1: 4 }^444444444444444444444444444444444444| - {1: }444444444444444444444444444444444444| - {1: }444444444444444444444444444444444444| - {1: }444444444444444444444444444444444444| - {1: }444444444444444444444444444444444444| + {1: }444444444444444444444444444444444444|*4 {1: }44444444444444444444 | | ]]) - end) + end + ) end) diff --git a/test/functional/legacy/number_spec.lua b/test/functional/legacy/number_spec.lua new file mode 100644 index 0000000000..c112532eed --- /dev/null +++ b/test/functional/legacy/number_spec.lua @@ -0,0 +1,306 @@ +local helpers = require('test.functional.helpers')(after_each) +local Screen = require('test.functional.ui.screen') +local clear = helpers.clear +local command = helpers.command +local exec = helpers.exec +local feed = helpers.feed + +describe("'number' and 'relativenumber'", function() + before_each(clear) + + -- oldtest: Test_relativenumber_colors() + it('LineNr, LineNrAbove and LineNrBelow', function() + local screen = Screen.new(50, 10) + screen:set_default_attr_ids({ + [1] = { foreground = Screen.colors.Red }, + [2] = { foreground = Screen.colors.Blue }, + [3] = { foreground = Screen.colors.Green }, + }) + screen:attach() + exec([[ + call setline(1, range(200)) + 111 + set number relativenumber + hi LineNr guifg=red + ]]) + screen:expect([[ + {1: 4 }106 | + {1: 3 }107 | + {1: 2 }108 | + {1: 1 }109 | + {1:111 }^110 | + {1: 1 }111 | + {1: 2 }112 | + {1: 3 }113 | + {1: 4 }114 | + | + ]]) + command('hi LineNrAbove guifg=blue') + screen:expect([[ + {2: 4 }106 | + {2: 3 }107 | + {2: 2 }108 | + {2: 1 }109 | + {1:111 }^110 | + {1: 1 }111 | + {1: 2 }112 | + {1: 3 }113 | + {1: 4 }114 | + | + ]]) + command('hi LineNrBelow guifg=green') + screen:expect([[ + {2: 4 }106 | + {2: 3 }107 | + {2: 2 }108 | + {2: 1 }109 | + {1:111 }^110 | + {3: 1 }111 | + {3: 2 }112 | + {3: 3 }113 | + {3: 4 }114 | + | + ]]) + command('hi clear LineNrAbove') + screen:expect([[ + {1: 4 }106 | + {1: 3 }107 | + {1: 2 }108 | + {1: 1 }109 | + {1:111 }^110 | + {3: 1 }111 | + {3: 2 }112 | + {3: 3 }113 | + {3: 4 }114 | + | + ]]) + end) + + -- oldtest: Test_relativenumber_colors_wrapped() + it('LineNr, LineNrAbove and LineNrBelow with wrapped lines', function() + local screen = Screen.new(50, 20) + screen:set_default_attr_ids({ + [1] = { background = Screen.colors.Red, foreground = Screen.colors.Black }, + [2] = { background = Screen.colors.Blue, foreground = Screen.colors.Black }, + [3] = { background = Screen.colors.Green, foreground = Screen.colors.Black }, + [4] = { bold = true, foreground = Screen.colors.Blue }, + }) + screen:attach() + exec([[ + set display=lastline scrolloff=0 + call setline(1, range(200)->map('v:val->string()->repeat(40)')) + 111 + set number relativenumber + hi LineNr guibg=red guifg=black + hi LineNrAbove guibg=blue guifg=black + hi LineNrBelow guibg=green guifg=black + ]]) + screen:expect([[ + {2: 2 }1081081081081081081081081081081081081081081081| + {2: }0810810810810810810810810810810810810810810810| + {2: }8108108108108108108108108108 | + {2: 1 }1091091091091091091091091091091091091091091091| + {2: }0910910910910910910910910910910910910910910910| + {2: }9109109109109109109109109109 | + {1:111 }^1101101101101101101101101101101101101101101101| + {1: }1011011011011011011011011011011011011011011011| + {1: }0110110110110110110110110110 | + {3: 1 }1111111111111111111111111111111111111111111111| + {3: }1111111111111111111111111111111111111111111111| + {3: }1111111111111111111111111111 | + {3: 2 }1121121121121121121121121121121121121121121121| + {3: }1211211211211211211211211211211211211211211211| + {3: }2112112112112112112112112112 | + {3: 3 }1131131131131131131131131131131131131131131131| + {3: }1311311311311311311311311311311311311311311311| + {3: }3113113113113113113113113113 | + {3: 4 }1141141141141141141141141141141141141141141{4:@@@}| + | + ]]) + feed('k') + screen:expect([[ + {2: 1 }1081081081081081081081081081081081081081081081| + {2: }0810810810810810810810810810810810810810810810| + {2: }8108108108108108108108108108 | + {1:110 }^1091091091091091091091091091091091091091091091| + {1: }0910910910910910910910910910910910910910910910| + {1: }9109109109109109109109109109 | + {3: 1 }1101101101101101101101101101101101101101101101| + {3: }1011011011011011011011011011011011011011011011| + {3: }0110110110110110110110110110 | + {3: 2 }1111111111111111111111111111111111111111111111| + {3: }1111111111111111111111111111111111111111111111| + {3: }1111111111111111111111111111 | + {3: 3 }1121121121121121121121121121121121121121121121| + {3: }1211211211211211211211211211211211211211211211| + {3: }2112112112112112112112112112 | + {3: 4 }1131131131131131131131131131131131131131131131| + {3: }1311311311311311311311311311311311311311311311| + {3: }3113113113113113113113113113 | + {3: 5 }1141141141141141141141141141141141141141141{4:@@@}| + | + ]]) + feed('2j') + screen:expect([[ + {2: 3 }1081081081081081081081081081081081081081081081| + {2: }0810810810810810810810810810810810810810810810| + {2: }8108108108108108108108108108 | + {2: 2 }1091091091091091091091091091091091091091091091| + {2: }0910910910910910910910910910910910910910910910| + {2: }9109109109109109109109109109 | + {2: 1 }1101101101101101101101101101101101101101101101| + {2: }1011011011011011011011011011011011011011011011| + {2: }0110110110110110110110110110 | + {1:112 }^1111111111111111111111111111111111111111111111| + {1: }1111111111111111111111111111111111111111111111| + {1: }1111111111111111111111111111 | + {3: 1 }1121121121121121121121121121121121121121121121| + {3: }1211211211211211211211211211211211211211211211| + {3: }2112112112112112112112112112 | + {3: 2 }1131131131131131131131131131131131131131131131| + {3: }1311311311311311311311311311311311311311311311| + {3: }3113113113113113113113113113 | + {3: 3 }1141141141141141141141141141141141141141141{4:@@@}| + | + ]]) + feed('2j') + screen:expect([[ + {2: 5 }1081081081081081081081081081081081081081081081| + {2: }0810810810810810810810810810810810810810810810| + {2: }8108108108108108108108108108 | + {2: 4 }1091091091091091091091091091091091091091091091| + {2: }0910910910910910910910910910910910910910910910| + {2: }9109109109109109109109109109 | + {2: 3 }1101101101101101101101101101101101101101101101| + {2: }1011011011011011011011011011011011011011011011| + {2: }0110110110110110110110110110 | + {2: 2 }1111111111111111111111111111111111111111111111| + {2: }1111111111111111111111111111111111111111111111| + {2: }1111111111111111111111111111 | + {2: 1 }1121121121121121121121121121121121121121121121| + {2: }1211211211211211211211211211211211211211211211| + {2: }2112112112112112112112112112 | + {1:114 }^1131131131131131131131131131131131131131131131| + {1: }1311311311311311311311311311311311311311311311| + {1: }3113113113113113113113113113 | + {3: 1 }1141141141141141141141141141141141141141141{4:@@@}| + | + ]]) + feed('k') + screen:expect([[ + {2: 4 }1081081081081081081081081081081081081081081081| + {2: }0810810810810810810810810810810810810810810810| + {2: }8108108108108108108108108108 | + {2: 3 }1091091091091091091091091091091091091091091091| + {2: }0910910910910910910910910910910910910910910910| + {2: }9109109109109109109109109109 | + {2: 2 }1101101101101101101101101101101101101101101101| + {2: }1011011011011011011011011011011011011011011011| + {2: }0110110110110110110110110110 | + {2: 1 }1111111111111111111111111111111111111111111111| + {2: }1111111111111111111111111111111111111111111111| + {2: }1111111111111111111111111111 | + {1:113 }^1121121121121121121121121121121121121121121121| + {1: }1211211211211211211211211211211211211211211211| + {1: }2112112112112112112112112112 | + {3: 1 }1131131131131131131131131131131131131131131131| + {3: }1311311311311311311311311311311311311311311311| + {3: }3113113113113113113113113113 | + {3: 2 }1141141141141141141141141141141141141141141{4:@@@}| + | + ]]) + end) + + -- oldtest: Test_relativenumber_callback() + it('relative line numbers are updated if cursor is moved from timer', function() + local screen = Screen.new(50, 8) + screen:set_default_attr_ids({ + [1] = { foreground = Screen.colors.Brown }, -- LineNr + [2] = { bold = true, foreground = Screen.colors.Blue1 }, -- NonText + }) + screen:attach() + exec([[ + call setline(1, ['aaaaa', 'bbbbb', 'ccccc', 'ddddd']) + set relativenumber + call cursor(4, 1) + + func Func(timer) + call cursor(1, 1) + endfunc + + call timer_start(300, 'Func') + ]]) + screen:expect({ + grid = [[ + {1: 3 }aaaaa | + {1: 2 }bbbbb | + {1: 1 }ccccc | + {1: 0 }^ddddd | + {2:~ }|*3 + | + ]], + timeout = 100, + }) + screen:expect({ + grid = [[ + {1: 0 }^aaaaa | + {1: 1 }bbbbb | + {1: 2 }ccccc | + {1: 3 }ddddd | + {2:~ }|*3 + | + ]], + }) + end) + + -- oldtest: Test_number_insert_delete_lines() + it('line numbers are updated when deleting/inserting lines', function() + local screen = Screen.new(50, 8) + screen:set_default_attr_ids({ + [1] = { foreground = Screen.colors.Brown }, -- LineNr + [2] = { bold = true, foreground = Screen.colors.Blue1 }, -- NonText + }) + screen:attach() + exec([[ + call setline(1, range(1, 7)) + set number + call cursor(2, 1) + ]]) + local snapshot1 = [[ + {1: 1 }1 | + {1: 2 }^2 | + {1: 3 }3 | + {1: 4 }4 | + {1: 5 }5 | + {1: 6 }6 | + {1: 7 }7 | + | + ]] + screen:expect(snapshot1) + feed('dd') + screen:expect([[ + {1: 1 }1 | + {1: 2 }^3 | + {1: 3 }4 | + {1: 4 }5 | + {1: 5 }6 | + {1: 6 }7 | + {2:~ }| + | + ]]) + feed('P') + screen:expect(snapshot1) + feed('2dd') + screen:expect([[ + {1: 1 }1 | + {1: 2 }^4 | + {1: 3 }5 | + {1: 4 }6 | + {1: 5 }7 | + {2:~ }|*2 + | + ]]) + feed('P') + screen:expect(snapshot1) + end) +end) diff --git a/test/functional/legacy/options_spec.lua b/test/functional/legacy/options_spec.lua index ce46ea013d..2f20b6bd51 100644 --- a/test/functional/legacy/options_spec.lua +++ b/test/functional/legacy/options_spec.lua @@ -2,8 +2,8 @@ local helpers = require('test.functional.helpers')(after_each) local command, clear = helpers.command, helpers.clear local source, expect = helpers.source, helpers.expect -local exc_exec = helpers.exc_exec; -local matches = helpers.matches; +local exc_exec = helpers.exc_exec +local matches = helpers.matches local Screen = require('test.functional.ui.screen') describe('options', function() @@ -66,17 +66,7 @@ describe('set', function() command('verbose set scroll?') screen:expect([[ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*11 | scroll=7 | Last set from changed window size | diff --git a/test/functional/legacy/prompt_buffer_spec.lua b/test/functional/legacy/prompt_buffer_spec.lua index 5c3f8a6f8c..e4810feedb 100644 --- a/test/functional/legacy/prompt_buffer_spec.lua +++ b/test/functional/legacy/prompt_buffer_spec.lua @@ -4,8 +4,9 @@ local feed = helpers.feed local source = helpers.source local clear = helpers.clear local command = helpers.command +local expect = helpers.expect local poke_eventloop = helpers.poke_eventloop -local meths = helpers.meths +local api = helpers.api local eq = helpers.eq local neq = helpers.neq @@ -57,14 +58,10 @@ describe('prompt buffer', function() ]]) screen:expect([[ cmd: ^ | - ~ | - ~ | - ~ | + ~ |*3 [Prompt] [+] | other buffer | - ~ | - ~ | - ~ | + ~ |*3 -- INSERT -- | ]]) end @@ -76,7 +73,7 @@ describe('prompt buffer', function() -- oldtest: Test_prompt_basic() it('works', function() source_script() - feed("hello\n") + feed('hello\n') screen:expect([[ cmd: hello | Command: "hello" | @@ -84,22 +81,13 @@ describe('prompt buffer', function() cmd: ^ | [Prompt] | other buffer | - ~ | - ~ | - ~ | + ~ |*3 -- INSERT -- | ]]) - feed("exit\n") + feed('exit\n') screen:expect([[ ^other buffer | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*8 | ]]) end) @@ -107,69 +95,46 @@ describe('prompt buffer', function() -- oldtest: Test_prompt_editing() it('editing', function() source_script() - feed("hello<BS><BS>") + feed('hello<BS><BS>') screen:expect([[ cmd: hel^ | - ~ | - ~ | - ~ | + ~ |*3 [Prompt] [+] | other buffer | - ~ | - ~ | - ~ | + ~ |*3 -- INSERT -- | ]]) - feed("<Left><Left><Left><BS>-") + feed('<Left><Left><Left><BS>-') screen:expect([[ cmd: -^hel | - ~ | - ~ | - ~ | + ~ |*3 [Prompt] [+] | other buffer | - ~ | - ~ | - ~ | + ~ |*3 -- INSERT -- | ]]) - feed("<C-O>lz") + feed('<C-O>lz') screen:expect([[ cmd: -hz^el | - ~ | - ~ | - ~ | + ~ |*3 [Prompt] [+] | other buffer | - ~ | - ~ | - ~ | + ~ |*3 -- INSERT -- | ]]) - feed("<End>x") + feed('<End>x') screen:expect([[ cmd: -hzelx^ | - ~ | - ~ | - ~ | + ~ |*3 [Prompt] [+] | other buffer | - ~ | - ~ | - ~ | + ~ |*3 -- INSERT -- | ]]) - feed("<C-U>exit\n") + feed('<C-U>exit\n') screen:expect([[ ^other buffer | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*8 | ]]) end) @@ -177,43 +142,33 @@ describe('prompt buffer', function() -- oldtest: Test_prompt_switch_windows() it('switch windows', function() source_script() - feed("<C-O>:call SwitchWindows()<CR>") - screen:expect{grid=[[ + feed('<C-O>:call SwitchWindows()<CR>') + screen:expect { + grid = [[ cmd: | - ~ | - ~ | - ~ | + ~ |*3 [Prompt] [+] | ^other buffer | - ~ | - ~ | - ~ | + ~ |*3 | - ]]} - feed("<C-O>:call SwitchWindows()<CR>") + ]], + } + feed('<C-O>:call SwitchWindows()<CR>') screen:expect([[ cmd: ^ | - ~ | - ~ | - ~ | + ~ |*3 [Prompt] [+] | other buffer | - ~ | - ~ | - ~ | + ~ |*3 -- INSERT -- | ]]) - feed("<Esc>") + feed('<Esc>') screen:expect([[ cmd:^ | - ~ | - ~ | - ~ | + ~ |*3 [Prompt] [+] | other buffer | - ~ | - ~ | - ~ | + ~ |*3 | ]]) end) @@ -226,12 +181,12 @@ describe('prompt buffer', function() call timer_start(0, {-> nvim_buf_set_lines(s:buf, -1, -1, 0, ['walrus'])}) ]] poke_eventloop() - eq({ mode = 'i', blocking = false }, meths.get_mode()) + eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) end) -- oldtest: Test_prompt_appending_while_hidden() it('accessing hidden prompt buffer does not start insert mode', function() - local prev_win = meths.get_current_win() + local prev_win = api.nvim_get_current_win() source([[ new prompt set buftype=prompt @@ -251,16 +206,48 @@ describe('prompt buffer', function() endfunc ]]) feed('asomething<CR>') - eq('something', meths.get_var('entered')) - neq(prev_win, meths.get_current_win()) + eq('something', api.nvim_get_var('entered')) + neq(prev_win, api.nvim_get_current_win()) feed('exit<CR>') - eq(prev_win, meths.get_current_win()) - eq({ mode = 'n', blocking = false }, meths.get_mode()) + eq(prev_win, api.nvim_get_current_win()) + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) command('call DoAppend()') - eq({ mode = 'n', blocking = false }, meths.get_mode()) + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) feed('i') - eq({ mode = 'i', blocking = false }, meths.get_mode()) + eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) command('call DoAppend()') - eq({ mode = 'i', blocking = false }, meths.get_mode()) + eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) + end) + + -- oldtest: Test_prompt_leave_modify_hidden() + it('modifying hidden buffer does not prevent prompt buffer mode change', function() + source([[ + file hidden + set bufhidden=hide + enew + new prompt + set buftype=prompt + + inoremap <buffer> w <Cmd>wincmd w<CR> + inoremap <buffer> q <Cmd>bwipe!<CR> + autocmd BufLeave prompt call appendbufline('hidden', '$', 'Leave') + autocmd BufEnter prompt call appendbufline('hidden', '$', 'Enter') + autocmd BufWinLeave prompt call appendbufline('hidden', '$', 'Close') + ]]) + feed('a') + eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) + feed('w') + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) + feed('<C-W>w') + eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) + feed('q') + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) + command('bwipe!') + expect([[ + + Leave + Enter + Leave + Close]]) end) end) diff --git a/test/functional/legacy/put_spec.lua b/test/functional/legacy/put_spec.lua index 4a42a1c8a3..c78946d690 100644 --- a/test/functional/legacy/put_spec.lua +++ b/test/functional/legacy/put_spec.lua @@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local clear = helpers.clear local exec_lua = helpers.exec_lua -local meths = helpers.meths +local api = helpers.api local source = helpers.source local eq = helpers.eq @@ -15,7 +15,9 @@ end describe('put', function() before_each(clear) - after_each(function() eq({}, meths.get_vvar('errors')) end) + after_each(function() + eq({}, api.nvim_get_vvar('errors')) + end) it('very large count 64-bit', function() if sizeoflong() < 8 then @@ -64,8 +66,7 @@ describe('put', function() three more text │ three more text | ^four more text │ four more text | │ | - ~ │~ | - ~ │~ | + ~ │~ |*2 [No Name] [+] [No Name] [+] | | ]]) diff --git a/test/functional/legacy/scroll_opt_spec.lua b/test/functional/legacy/scroll_opt_spec.lua index 8ac1141c2b..8d22c299d6 100644 --- a/test/functional/legacy/scroll_opt_spec.lua +++ b/test/functional/legacy/scroll_opt_spec.lua @@ -23,9 +23,9 @@ describe('smoothscroll', function() set number ]]) feed('<C-Y>') - screen:expect({any = " 1 ^one"}) + screen:expect({ any = ' 1 ^one' }) feed('<C-E><C-E><C-E>') - screen:expect({any = " 2 ^two"}) + screen:expect({ any = ' 2 ^two' }) end) -- oldtest: Test_smoothscroll_CtrlE_CtrlY() @@ -36,17 +36,14 @@ describe('smoothscroll', function() :5 ]]) local s1 = [[ - word word word word word word word word | - word word word word word word word word | + word word word word word word word word |*2 word word word word | line three | long word long word long word long word | long word long word long word | ^line | - line | - line | - ~ | - ~ | + line |*2 + ~ |*2 | ]] local s2 = [[ @@ -56,11 +53,8 @@ describe('smoothscroll', function() long word long word long word long word | long word long word long word | ^line | - line | - line | - ~ | - ~ | - ~ | + line |*2 + ~ |*3 | ]] local s3 = [[ @@ -69,26 +63,17 @@ describe('smoothscroll', function() long word long word long word long word | long word long word long word | ^line | - line | - line | - ~ | - ~ | - ~ | - ~ | + line |*2 + ~ |*4 | ]] local s4 = [[ line three | long word long word long word long word | long word long word long word | - line | - line | + line |*2 ^line | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*5 | ]] local s5 = [[ @@ -96,13 +81,9 @@ describe('smoothscroll', function() line three | long word long word long word long word | long word long word long word | - line | - line | + line |*2 ^line | - ~ | - ~ | - ~ | - ~ | + ~ |*4 | ]] local s6 = [[ @@ -111,38 +92,30 @@ describe('smoothscroll', function() line three | long word long word long word long word | long word long word long word | - line | - line | + line |*2 ^line | - ~ | - ~ | - ~ | + ~ |*3 | ]] local s7 = [[ - word word word word word word word word | - word word word word word word word word | + word word word word word word word word |*2 word word word word | line three | long word long word long word long word | long word long word long word | - line | - line | + line |*2 ^line | - ~ | - ~ | + ~ |*2 | ]] local s8 = [[ line one | - word word word word word word word word | - word word word word word word word word | + word word word word word word word word |*2 word word word word | line three | long word long word long word long word | long word long word long word | - line | - line | + line |*2 ^line | ~ | | @@ -187,8 +160,7 @@ describe('smoothscroll', function() ϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛϛ^ϛϛϛϛϛ| ϛϛϛϛϛ | 222222222222222222222222222222222222 | - ~ | - ~ | + ~ |*2 | ]]) end) @@ -217,9 +189,7 @@ describe('smoothscroll', function() 3 ^line | 4 line | 5 line | - ~ | - ~ | - ~ | + ~ |*3 | ]]) feed('<C-E>') @@ -231,10 +201,7 @@ describe('smoothscroll', function() 3 ^line | 4 line | 5 line | - ~ | - ~ | - ~ | - ~ | + ~ |*4 | ]]) feed('<C-E>') @@ -245,11 +212,7 @@ describe('smoothscroll', function() 3 ^line | 4 line | 5 line | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*5 | ]]) exec('set cpo-=n') @@ -261,10 +224,7 @@ describe('smoothscroll', function() 3 ^line | 4 line | 5 line | - ~ | - ~ | - ~ | - ~ | + ~ |*4 | ]]) feed('<C-Y>') @@ -277,9 +237,7 @@ describe('smoothscroll', function() 3 ^line | 4 line | 5 line | - ~ | - ~ | - ~ | + ~ |*3 | ]]) feed('<C-Y>') @@ -293,8 +251,7 @@ describe('smoothscroll', function() 3 ^line | 4 line | 5 line | - ~ | - ~ | + ~ |*2 | ]]) exec('botright split') @@ -351,18 +308,13 @@ describe('smoothscroll', function() y long text very long text very long| text very long text very long text | 1 three | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*6 --No lines in buffer-- | ]]) end) -- oldtest: Test_smoothscroll_list() - it("works with list mode", function() + it('works with list mode', function() screen:try_resize(40, 8) exec([[ set smoothscroll scrolloff=0 @@ -376,8 +328,7 @@ describe('smoothscroll', function() very long text very long text very long | text very long text- | three | - ~ | - ~ | + ~ |*2 | ]]) exec('set listchars+=precedes:#') @@ -387,14 +338,13 @@ describe('smoothscroll', function() very long text very long text very long | text very long text- | three | - ~ | - ~ | + ~ |*2 | ]]) end) -- oldtest: Test_smoothscroll_diff_mode() - it("works with diff mode", function() + it('works with diff mode', function() screen:try_resize(40, 8) exec([[ let text = 'just some text here' @@ -408,8 +358,7 @@ describe('smoothscroll', function() ]]) screen:expect([[ - ^just some text here | - ~ | - ~ | + ~ |*2 [No Name] [+] | - just some text here | ~ | @@ -476,7 +425,7 @@ describe('smoothscroll', function() end) -- oldtest: Test_smoothscroll_wrap_long_line() - it("adjusts the cursor position in a long line", function() + it('adjusts the cursor position in a long line', function() screen:try_resize(40, 6) exec([[ call setline(1, ['one', 'two', 'Line' .. (' with lots of text'->repeat(30)) .. ' end', 'four']) @@ -580,10 +529,7 @@ describe('smoothscroll', function() feed('zt') screen:expect([[ ^four | - ~ | - ~ | - ~ | - ~ | + ~ |*4 | ]]) feed('zz') @@ -591,8 +537,7 @@ describe('smoothscroll', function() <<<of text with lots of text with lots o| f text with lots of text end | ^four | - ~ | - ~ | + ~ |*2 | ]]) feed('zb') @@ -608,7 +553,9 @@ describe('smoothscroll', function() -- This time, use a shorter long line that is barely long enough to span more -- than one window. Note that the cursor is at the bottom this time because -- Vim prefers to do so if we are scrolling a few lines only. - exec("call setline(1, ['one', 'two', 'Line' .. (' with lots of text'->repeat(10)) .. ' end', 'four'])") + exec( + "call setline(1, ['one', 'two', 'Line' .. (' with lots of text'->repeat(10)) .. ' end', 'four'])" + ) -- Currently visible lines were replaced, test that the lines and cursor -- are correctly displayed. screen:expect_unchanged() @@ -630,7 +577,7 @@ describe('smoothscroll', function() end) -- oldtest: Test_smoothscroll_one_long_line() - it("scrolls correctly when moving the cursor", function() + it('scrolls correctly when moving the cursor', function() screen:try_resize(40, 6) exec([[ call setline(1, 'with lots of text '->repeat(7)) @@ -650,8 +597,7 @@ describe('smoothscroll', function() <<<ts of text with lots of text with lot| ^s of text with lots of text with lots of| text | - ~ | - ~ | + ~ |*2 | ]]) feed('0') @@ -659,7 +605,7 @@ describe('smoothscroll', function() end) -- oldtest: Test_smoothscroll_long_line_showbreak() - it("cursor is not one screen line too far down", function() + it('cursor is not one screen line too far down', function() screen:try_resize(40, 6) -- a line that spans four screen lines exec("call setline(1, 'with lots of text in one line '->repeat(6))") @@ -696,28 +642,23 @@ describe('smoothscroll', function() screen:expect([[ ^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 口口口口口口口口口口 | - ~ | - ~ | - ~ | + ~ |*3 | ]]) feed('<C-E>') screen:expect([[ <<< 口口口口口口口^口 | - ~ | - ~ | - ~ | - ~ | + ~ |*4 | ]]) end) -- oldtest: Test_smoothscroll_zero_width() - it("does not divide by zero with a narrow window", function() + it('does not divide by zero with a narrow window', function() screen:try_resize(12, 2) screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.Brown}, - [2] = {foreground = Screen.colors.Blue1, bold = true}, + [1] = { foreground = Screen.colors.Brown }, + [2] = { foreground = Screen.colors.Blue1, bold = true }, }) exec([[ call setline(1, ['a'->repeat(100)]) @@ -739,7 +680,7 @@ describe('smoothscroll', function() end) -- oldtest: Test_smoothscroll_ins_lines() - it("does not unnecessarily insert lines", function() + it('does not unnecessarily insert lines', function() screen:try_resize(40, 6) exec([=[ set wrap smoothscroll scrolloff=0 conceallevel=2 concealcursor=nc @@ -763,7 +704,7 @@ describe('smoothscroll', function() end) -- oldtest: Test_smoothscroll_cursormoved_line() - it("does not place the cursor in the command line", function() + it('does not place the cursor in the command line', function() screen:try_resize(40, 6) exec([=[ set smoothscroll @@ -786,7 +727,7 @@ describe('smoothscroll', function() end) -- oldtest: Test_smoothscroll_eob() - it("does not scroll halfway at end of buffer", function() + it('does not scroll halfway at end of buffer', function() screen:try_resize(40, 10) exec([[ set smoothscroll @@ -795,14 +736,7 @@ describe('smoothscroll', function() ]]) -- does not scroll halfway when scrolling to end of buffer screen:expect([[ - | - | - | - | - | - | - | - | + |*8 ^ | | ]]) @@ -811,26 +745,20 @@ describe('smoothscroll', function() -- cursor is not placed below window screen:expect([[ <<<aaaaaaaaaaaaaaaaa | - | - | - | - | - | - | - | + |*7 ^ | | ]]) end) -- oldtest: Test_smoothscroll_incsearch() - it("does not reset skipcol when doing incremental search on the same word", function() + it('does not reset skipcol when doing incremental search on the same word', function() screen:try_resize(40, 8) screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.Brown}, - [2] = {foreground = Screen.colors.Blue1, bold = true}, - [3] = {background = Screen.colors.Yellow1}, - [4] = {reverse = true}, + [1] = { foreground = Screen.colors.Brown }, + [2] = { foreground = Screen.colors.Blue1, bold = true }, + [3] = { background = Screen.colors.Yellow1 }, + [4] = { reverse = true }, }) exec([[ set smoothscroll number scrolloff=0 incsearch @@ -888,8 +816,8 @@ describe('smoothscroll', function() it('scrolling multiple lines and stopping at non-zero skipcol', function() screen:try_resize(40, 10) screen:set_default_attr_ids({ - [0] = {foreground = Screen.colors.Blue, bold = true}, - [1] = {background = Screen.colors.Grey90}, + [0] = { foreground = Screen.colors.Blue, bold = true }, + [1] = { background = Screen.colors.Grey90 }, }) exec([[ setlocal cursorline scrolloff=0 smoothscroll @@ -907,8 +835,7 @@ describe('smoothscroll', function() aaaaaaaaaa | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| aaaaaaaaaa | - | - | + |*2 bbb | | ]]) @@ -917,25 +844,19 @@ describe('smoothscroll', function() {0:<<<}{1:aaaaaa^a }| aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| aaaaaaaaaa | - | - | + |*2 bbb | ccc | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) feed('2<C-E>') screen:expect([[ {0:<<<}{1:aaaaaa^a }| - | - | + |*2 bbb | ccc | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) end) @@ -944,10 +865,10 @@ describe('smoothscroll', function() it('does not divide by zero in zero-width window', function() screen:try_resize(40, 19) screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.Brown}; -- LineNr - [2] = {bold = true, foreground = Screen.colors.Blue}; -- NonText - [3] = {bold = true, reverse = true}; -- StatusLine - [4] = {reverse = true}; -- StatusLineNC + [1] = { foreground = Screen.colors.Brown }, -- LineNr + [2] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [3] = { bold = true, reverse = true }, -- StatusLine + [4] = { reverse = true }, -- StatusLineNC }) exec([[ silent normal yy @@ -962,21 +883,7 @@ describe('smoothscroll', function() ]]) screen:expect([[ {1: }│ | - {2:@}│ | - {2:@}│ | - {2:@}│ | - {2:@}│ | - {2:@}│ | - {2:@}│ | - {2:@}│ | - {2:@}│ | - {2:@}│ | - {2:@}│ | - {2:@}│ | - {2:@}│ | - {2:@}│ | - {2:@}│ | - {2:@}│ | + {2:@}│ |*15 {2:^@}│ | {3:< }{4:[No Name] [+] }| | @@ -1001,8 +908,7 @@ describe('smoothscroll', function() line3line3line3line3line3line3line3line3| line3line3line3line3 | line4 | - ~ | - ~ | + ~ |*2 [No Name] [+] | | ]]) @@ -1023,7 +929,7 @@ describe('smoothscroll', function() assert_alive() end) - it("works with virt_lines above and below", function() + it('works with virt_lines above and below', function() screen:try_resize(55, 7) exec([=[ call setline(1, ['Line' .. (' with some text'->repeat(7))]->repeat(3)) @@ -1096,6 +1002,22 @@ describe('smoothscroll', function() ]]) end) + it('works in Insert mode at bottom of window', function() + screen:try_resize(40, 9) + exec([[ + call setline(1, repeat([repeat('A very long line ...', 10)], 5)) + set wrap smoothscroll scrolloff=0 + ]]) + feed('Go123456789<CR>') + screen:expect([[ + <<<ery long line ...A very long line ...| + A very long line ...A very long line ...|*5 + 123456789 | + ^ | + -- INSERT -- | + ]]) + end) + it('<<< marker shows with tabline, winbar and splits', function() screen:try_resize(40, 12) exec([[ @@ -1153,8 +1075,8 @@ describe('smoothscroll', function() it('works with very long line', function() screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.Brown}, - [2] = {foreground = Screen.colors.Blue1, bold = true}, + [1] = { foreground = Screen.colors.Brown }, + [2] = { foreground = Screen.colors.Blue1, bold = true }, }) exec([[ edit test/functional/fixtures/bigfile_oneline.txt diff --git a/test/functional/legacy/search_spec.lua b/test/functional/legacy/search_spec.lua index 25620f5262..2fda341123 100644 --- a/test/functional/legacy/search_spec.lua +++ b/test/functional/legacy/search_spec.lua @@ -5,7 +5,7 @@ local command = helpers.command local eq = helpers.eq local eval = helpers.eval local feed = helpers.feed -local funcs = helpers.funcs +local fn = helpers.fn local poke_eventloop = helpers.poke_eventloop local exec = helpers.exec @@ -18,7 +18,7 @@ describe('search cmdline', function() screen = Screen.new(20, 3) screen:attach() screen:set_default_attr_ids({ - inc = {reverse = true}, + inc = { reverse = true }, err = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, more = { bold = true, foreground = Screen.colors.SeaGreen4 }, tilde = { bold = true, foreground = Screen.colors.Blue1 }, @@ -27,9 +27,17 @@ describe('search cmdline', function() end) local function tenlines() - funcs.setline(1, { - ' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there', - ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar' + fn.setline(1, { + ' 1', + ' 2 these', + ' 3 the', + ' 4 their', + ' 5 there', + ' 6 their', + ' 7 the', + ' 8 them', + ' 9 these', + ' 10 foobar', }) command('1') end @@ -47,7 +55,7 @@ describe('search cmdline', function() describe('can traverse matches', function() before_each(tenlines) local function forwarditer(wrapscan) - command('set incsearch '..wrapscan) + command('set incsearch ' .. wrapscan) feed('/the') screen:expect([[ 1 | @@ -60,7 +68,7 @@ describe('search cmdline', function() 3 {inc:the} | /the^ | ]]) - eq({0, 0, 0, 0}, funcs.getpos('"')) + eq({ 0, 0, 0, 0 }, fn.getpos('"')) feed('<C-G>') screen:expect([[ 3 the | @@ -106,20 +114,23 @@ describe('search cmdline', function() /the^ | ]]) else - screen:expect{grid=[[ + screen:expect { + grid = [[ 8 them | 9 {inc:the}se | /the^ | - ]], condition=function() - eq(true, screen.bell) - end} + ]], + condition = function() + eq(true, screen.bell) + end, + } feed('<CR>') - eq({0, 0, 0, 0}, funcs.getpos('"')) + eq({ 0, 0, 0, 0 }, fn.getpos('"')) end end local function backiter(wrapscan) - command('set incsearch '..wrapscan) + command('set incsearch ' .. wrapscan) command('$') feed('?the') @@ -144,13 +155,16 @@ describe('search cmdline', function() ]]) else feed('<C-G>') - screen:expect{grid=[[ + screen:expect { + grid = [[ 9 {inc:the}se | 10 foobar | ?the^ | - ]], condition=function() - eq(true, screen.bell) - end} + ]], + condition = function() + eq(true, screen.bell) + end, + } feed('<CR>') screen:expect([[ 9 ^these | @@ -193,13 +207,16 @@ describe('search cmdline', function() ?the^ | ]]) else - screen:expect{grid=[[ + screen:expect { + grid = [[ 2 {inc:the}se | 3 the | ?the^ | - ]], condition=function() - eq(true, screen.bell) - end} + ]], + condition = function() + eq(true, screen.bell) + end, + } end end @@ -351,7 +368,7 @@ describe('search cmdline', function() end) it('can traverse matches in the same line with <C-G>/<C-T>', function() - funcs.setline(1, { ' 1', ' 2 these', ' 3 the theother' }) + fn.setline(1, { ' 1', ' 2 these', ' 3 the theother' }) command('1') command('set incsearch') @@ -439,9 +456,16 @@ describe('search cmdline', function() 10 ^foobar | /fo | ]]) - eq({lnum = 10, leftcol = 0, col = 4, topfill = 0, topline = 6, - coladd = 0, skipcol = 0, curswant = 4}, - funcs.winsaveview()) + eq({ + lnum = 10, + leftcol = 0, + col = 4, + topfill = 0, + topline = 6, + coladd = 0, + skipcol = 0, + curswant = 4, + }, fn.winsaveview()) end) it('restores original view after failed search', function() @@ -467,16 +491,23 @@ describe('search cmdline', function() {more:Press ENTER or type command to continue}^ | ]]) feed('<CR>') - eq({lnum = 1, leftcol = 0, col = 0, topfill = 0, topline = 1, - coladd = 0, skipcol = 0, curswant = 0}, - funcs.winsaveview()) + eq({ + lnum = 1, + leftcol = 0, + col = 0, + topfill = 0, + topline = 1, + coladd = 0, + skipcol = 0, + curswant = 0, + }, fn.winsaveview()) end) -- oldtest: Test_search_cmdline4(). it("CTRL-G with 'incsearch' and ? goes in the right direction", function() screen:try_resize(40, 4) command('enew!') - funcs.setline(1, {' 1 the first', ' 2 the second', ' 3 the third'}) + fn.setline(1, { ' 1 the first', ' 2 the second', ' 3 the third' }) command('set laststatus=0 shortmess+=s') command('set incsearch') command('$') @@ -577,7 +608,7 @@ describe('search cmdline', function() it('incsearch works with :sort', function() screen:try_resize(20, 4) command('set incsearch hlsearch scrolloff=0') - funcs.setline(1, {'another one 2', 'that one 3', 'the one 1'}) + fn.setline(1, { 'another one 2', 'that one 3', 'the one 1' }) feed(':sort ni u /on') screen:expect([[ @@ -593,7 +624,7 @@ describe('search cmdline', function() it('incsearch works with :vimgrep family', function() screen:try_resize(30, 4) command('set incsearch hlsearch scrolloff=0') - funcs.setline(1, {'another one 2', 'that one 3', 'the one 1'}) + fn.setline(1, { 'another one 2', 'that one 3', 'the one 1' }) feed(':vimgrep on') screen:expect([[ @@ -688,27 +719,18 @@ describe('search cmdline', function() local s = [[ {tilde:<<<} 18 19 20 21 22 2| ^3 24 | - | - | - | - | + |*4 ]] screen:expect(s) feed('/xx') screen:expect([[ - | - | - | - | + |*4 {inc:xx}x | /xx^ | ]]) feed('x') screen:expect([[ - | - | - | - | + |*4 {inc:xxx} | /xxx^ | ]]) @@ -724,9 +746,9 @@ describe('Search highlight', function() it('beyond line end vim-patch:8.2.2542', function() local screen = Screen.new(50, 6) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [2] = {background = Screen.colors.Yellow}, -- Search - [3] = {background = Screen.colors.Grey90}, -- CursorLine + [1] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [2] = { background = Screen.colors.Yellow }, -- Search + [3] = { background = Screen.colors.Grey90 }, -- CursorLine }) screen:attach() exec([[ @@ -737,11 +759,9 @@ describe('Search highlight', function() ]]) feed([[/\_.*<CR>]]) screen:expect([[ - {2:xxx } | - {2:xxx } | + {2:xxx } |*2 {2:^xxx }{3: }| - {1:~ }| - {1:~ }| + {1:~ }|*2 /\_.* | ]]) end) @@ -750,11 +770,11 @@ describe('Search highlight', function() it('is combined with Visual highlight vim-patch:8.2.2797', function() local screen = Screen.new(40, 6) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [2] = {bold = true}, -- ModeMsg, Search - [3] = {background = Screen.colors.LightGrey}, -- Visual - [4] = {background = Screen.colors.Yellow, bold = true}, -- Search - [5] = {background = Screen.colors.LightGrey, bold = true}, -- Visual + Search + [1] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [2] = { bold = true }, -- ModeMsg, Search + [3] = { background = Screen.colors.LightGrey, foreground = Screen.colors.Black }, -- Visual + [4] = { background = Screen.colors.Yellow, bold = true }, -- Search + [5] = { background = Screen.colors.LightGrey, bold = true, foreground = Screen.colors.Black }, }) screen:attach() exec([[ @@ -769,8 +789,7 @@ describe('Search highlight', function() xxx {4:y}{5:yy}{3: zzz} | {3:xxx }{5:yyy}{3: zzz} | {3:xxx }{5:y}{4:^yy} zzz | - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:-- VISUAL --} | ]]) end) diff --git a/test/functional/legacy/search_stat_spec.lua b/test/functional/legacy/search_stat_spec.lua index bd5ab68e5c..378060d316 100644 --- a/test/functional/legacy/search_stat_spec.lua +++ b/test/functional/legacy/search_stat_spec.lua @@ -8,11 +8,11 @@ describe('search stat', function() clear() screen = Screen.new(30, 10) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [2] = {background = Screen.colors.Yellow}, -- Search - [3] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey}, -- Folded - [4] = {reverse = true}, -- IncSearch, TabLineFill - [5] = {foreground = Screen.colors.Red}, -- WarningMsg + [1] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [2] = { background = Screen.colors.Yellow }, -- Search + [3] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey }, -- Folded + [4] = { reverse = true }, -- IncSearch, TabLineFill + [5] = { foreground = Screen.colors.Red }, -- WarningMsg }) screen:attach() end) @@ -35,8 +35,7 @@ describe('search stat', function() {2:^find this} | fooooobar | foba | - foobar | - foobar | + foobar |*2 foo | fooooobar | foba | @@ -49,8 +48,7 @@ describe('search stat', function() {2:^find this} | fooooobar | foba | - foobar | - foobar | + foobar |*2 foo | fooooobar | foba | @@ -73,11 +71,7 @@ describe('search stat', function() {3:^+-- 2 lines: foo·············}| endif | | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 /foo [1/2] | ]]) -- Note: there is an intermediate state where the search stat disappears. @@ -99,12 +93,7 @@ describe('search stat', function() int cat; | int {2:^dog}; | cat = {2:dog}; | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 /dog [1/2] | ]]) feed('G0gD') @@ -112,12 +101,7 @@ describe('search stat', function() int {2:^cat}; | int dog; | {2:cat} = dog; | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | ]]) end) @@ -148,11 +132,7 @@ describe('search stat', function() {2:abc}--c | --------{4:abc} | --{2:abc} | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 /abc^ | ]]) @@ -162,11 +142,7 @@ describe('search stat', function() {2:abc}--c | --------{2:abc} | --{4:abc} | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 /abc^ | ]]) @@ -176,11 +152,7 @@ describe('search stat', function() {4:abc}--c | --------{2:abc} | --{2:abc} | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 /abc^ | ]]) end) @@ -197,13 +169,7 @@ describe('search stat', function() screen:expect([[ {2:^test} | | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*7 /\<test\> [1/1] | ]]) @@ -211,13 +177,7 @@ describe('search stat', function() screen:expect([[ {2:^test} | | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*7 ?\<test\> [1/1] | ]]) @@ -227,13 +187,7 @@ describe('search stat', function() screen:expect([[ {2:^test} | | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*7 {5:search hit TOP, continuing at BOTTOM} | ]]) end) diff --git a/test/functional/legacy/source_spec.lua b/test/functional/legacy/source_spec.lua index f31521607d..7a19541a77 100644 --- a/test/functional/legacy/source_spec.lua +++ b/test/functional/legacy/source_spec.lua @@ -9,22 +9,22 @@ before_each(clear) describe(':source!', function() -- oldtest: Test_nested_script() it('gives E22 when scripts nested too deep', function() - write_file('Xscript.vim', [[ + write_file( + 'Xscript.vim', + [[ :source! Xscript.vim - ]]) + ]] + ) local screen = Screen.new(75, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { background = Screen.colors.Red, foreground = Screen.colors.White }, -- ErrorMsg }) screen:attach() feed(':source! Xscript.vim\n') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {1:E22: Scripts nested too deep} | ]]) os.remove('Xscript.vim') diff --git a/test/functional/legacy/statusline_spec.lua b/test/functional/legacy/statusline_spec.lua index c5b17f8749..567e829879 100644 --- a/test/functional/legacy/statusline_spec.lua +++ b/test/functional/legacy/statusline_spec.lua @@ -16,9 +16,9 @@ describe('statusline', function() it('is updated in cmdline mode when using window-local statusline vim-patch:8.2.2737', function() screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [2] = {bold = true, reverse = true}, -- StatusLine - [3] = {reverse = true}, -- StatusLineNC + [1] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [2] = { bold = true, reverse = true }, -- StatusLine + [3] = { reverse = true }, -- StatusLineNC }) exec([[ setlocal statusline=-%{mode()}- @@ -48,9 +48,9 @@ describe('statusline', function() it('truncated item does not cause off-by-one highlight vim-patch:8.2.4929', function() screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [2] = {foreground = Screen.colors.Blue}, -- User1 - [3] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- User2 + [1] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [2] = { foreground = Screen.colors.Blue }, -- User1 + [3] = { background = Screen.colors.Red, foreground = Screen.colors.White }, -- User2 }) exec([[ set laststatus=2 @@ -60,10 +60,7 @@ describe('statusline', function() ]]) screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {3:<F}{2:GHI }| | ]]) @@ -72,11 +69,11 @@ describe('statusline', function() -- oldtest: Test_statusline_showcmd() it('showcmdloc=statusline works', function() screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {background = Screen.colors.LightGrey}, -- Visual - [2] = {bold = true}, -- MoreMsg - [3] = {bold = true, reverse = true}, -- StatusLine - [5] = {background = Screen.colors.LightGrey, foreground = Screen.colors.DarkBlue}, -- Folded + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { background = Screen.colors.LightGrey, foreground = Screen.colors.Black }, -- Visual + [2] = { bold = true }, -- MoreMsg + [3] = { bold = true, reverse = true }, -- StatusLine + [5] = { background = Screen.colors.LightGrey, foreground = Screen.colors.DarkBlue }, -- Folded }) exec([[ func MyStatusLine() @@ -97,9 +94,7 @@ describe('statusline', function() screen:expect([[ {5:+-- 2 lines: a···································}| ^c | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:g }| | ]]) @@ -110,8 +105,7 @@ describe('statusline', function() ^a | b | c | - {0:~ }| - {0:~ }| + {0:~ }|*2 {3: }| | ]]) @@ -121,8 +115,7 @@ describe('statusline', function() {1:a} | {1:b} | {1:c}^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:3x2 }| {2:-- VISUAL BLOCK --} | ]]) @@ -132,8 +125,7 @@ describe('statusline', function() a | b | ^c | - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:1234 }| | ]]) @@ -145,8 +137,7 @@ describe('statusline', function() a | b | ^c | - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:[No Name] [+] 1234 }| : | ]]) diff --git a/test/functional/legacy/substitute_spec.lua b/test/functional/legacy/substitute_spec.lua index f3ce343680..b462c10202 100644 --- a/test/functional/legacy/substitute_spec.lua +++ b/test/functional/legacy/substitute_spec.lua @@ -20,9 +20,14 @@ describe('substitute()', function() local function test_1_and_2() eq('AA', eval("substitute('A', 'A', '&&', '')")) eq('&', eval([[substitute('B', 'B', '\&', '')]])) - eq('C123456789987654321', eval([[substitute('C123456789', ]] .. - [['C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', ]] .. - [['\0\9\8\7\6\5\4\3\2\1', '')]])) + eq( + 'C123456789987654321', + eval( + [[substitute('C123456789', ]] + .. [['C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', ]] + .. [['\0\9\8\7\6\5\4\3\2\1', '')]] + ) + ) eq('d', eval("substitute('D', 'D', 'd', '')")) eq('~', eval("substitute('E', 'E', '~', '')")) eq('~', eval([[substitute('F', 'F', '\~', '')]])) @@ -61,10 +66,9 @@ describe('substitute()', function() feed_command('set magic&') eq('a\\a', eval([[substitute('aAa', 'A', '\="\\"', '')]])) eq('b\\\\b', eval([[substitute('bBb', 'B', '\="\\\\"', '')]])) - eq('c\rc', eval([[substitute('cCc', 'C', '\="]]..'\r'..[["', '')]])) - eq('d\\\rd', eval([[substitute('dDd', 'D', '\="\\]]..'\r'..[["', '')]])) - eq('e\\\\\re', - eval([[substitute('eEe', 'E', '\="\\\\]]..'\r'..[["', '')]])) + eq('c\rc', eval([[substitute('cCc', 'C', '\="]] .. '\r' .. [["', '')]])) + eq('d\\\rd', eval([[substitute('dDd', 'D', '\="\\]] .. '\r' .. [["', '')]])) + eq('e\\\\\re', eval([[substitute('eEe', 'E', '\="\\\\]] .. '\r' .. [["', '')]])) eq('f\\rf', eval([[substitute('fFf', 'F', '\="\\r"', '')]])) eq('j\\nj', eval([[substitute('jJj', 'J', '\="\\n"', '')]])) eq('k\rk', eval([[substitute('kKk', 'K', '\="\r"', '')]])) @@ -73,39 +77,81 @@ describe('substitute()', function() it('with submatch() (TEST_4)', function() feed_command('set magic&') - eq('a\\a', eval([[substitute('aAa', 'A', ]] .. - [['\=substitute(submatch(0), ".", "\\", "")', '')]])) - eq('b\\b', eval([[substitute('bBb', 'B', ]] .. - [['\=substitute(submatch(0), ".", "\\\\", "")', '')]])) - eq('c\rc', eval([[substitute('cCc', 'C', ]] .. - [['\=substitute(submatch(0), ".", "]]..'\r'..[[", "")', '')]])) - eq('d\rd', eval([[substitute('dDd', 'D', ]] .. - [['\=substitute(submatch(0), ".", "\\]]..'\r'..[[", "")', '')]])) - eq('e\\\re', eval([[substitute('eEe', 'E', ]] .. - [['\=substitute(submatch(0), ".", "\\\\]]..'\r'..[[", "")', '')]])) - eq('f\rf', eval([[substitute('fFf', 'F', ]] .. - [['\=substitute(submatch(0), ".", "\\r", "")', '')]])) - eq('j\nj', eval([[substitute('jJj', 'J', ]] .. - [['\=substitute(submatch(0), ".", "\\n", "")', '')]])) - eq('k\rk', eval([[substitute('kKk', 'K', ]] .. - [['\=substitute(submatch(0), ".", "\r", "")', '')]])) - eq('l\nl', eval([[substitute('lLl', 'L', ]] .. - [['\=substitute(submatch(0), ".", "\n", "")', '')]])) + eq( + 'a\\a', + eval([[substitute('aAa', 'A', ]] .. [['\=substitute(submatch(0), ".", "\\", "")', '')]]) + ) + eq( + 'b\\b', + eval([[substitute('bBb', 'B', ]] .. [['\=substitute(submatch(0), ".", "\\\\", "")', '')]]) + ) + eq( + 'c\rc', + eval( + [[substitute('cCc', 'C', ]] + .. [['\=substitute(submatch(0), ".", "]] + .. '\r' + .. [[", "")', '')]] + ) + ) + eq( + 'd\rd', + eval( + [[substitute('dDd', 'D', ]] + .. [['\=substitute(submatch(0), ".", "\\]] + .. '\r' + .. [[", "")', '')]] + ) + ) + eq( + 'e\\\re', + eval( + [[substitute('eEe', 'E', ]] + .. [['\=substitute(submatch(0), ".", "\\\\]] + .. '\r' + .. [[", "")', '')]] + ) + ) + eq( + 'f\rf', + eval([[substitute('fFf', 'F', ]] .. [['\=substitute(submatch(0), ".", "\\r", "")', '')]]) + ) + eq( + 'j\nj', + eval([[substitute('jJj', 'J', ]] .. [['\=substitute(submatch(0), ".", "\\n", "")', '')]]) + ) + eq( + 'k\rk', + eval([[substitute('kKk', 'K', ]] .. [['\=substitute(submatch(0), ".", "\r", "")', '')]]) + ) + eq( + 'l\nl', + eval([[substitute('lLl', 'L', ]] .. [['\=substitute(submatch(0), ".", "\n", "")', '')]]) + ) end) it('with submatch() (TEST_5)', function() feed_command('set magic&') - eq('A123456789987654321', eval([[substitute('A123456789', ]] .. - [['A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', ]] .. - [['\=submatch(0) . submatch(9) . submatch(8) . submatch(7) . ]] .. - [[submatch(6) . submatch(5) . submatch(4) . submatch(3) . ]] .. - [[submatch(2) . submatch(1)', '')]])) - eq("[['A123456789'], ['9'], ['8'], ['7'], ['6'], ['5'], ['4'], ['3'], " .. - "['2'], ['1']]", eval([[substitute('A123456789', ]] .. - [['A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', ]] .. - [['\=string([submatch(0, 1), submatch(9, 1), submatch(8, 1), ]] .. - [[submatch(7, 1), submatch(6, 1), submatch(5, 1), submatch(4, 1), ]] .. - [[submatch(3, 1), submatch(2, 1), submatch(1, 1)])', '')]])) + eq( + 'A123456789987654321', + eval( + [[substitute('A123456789', ]] + .. [['A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', ]] + .. [['\=submatch(0) . submatch(9) . submatch(8) . submatch(7) . ]] + .. [[submatch(6) . submatch(5) . submatch(4) . submatch(3) . ]] + .. [[submatch(2) . submatch(1)', '')]] + ) + ) + eq( + "[['A123456789'], ['9'], ['8'], ['7'], ['6'], ['5'], ['4'], ['3'], " .. "['2'], ['1']]", + eval( + [[substitute('A123456789', ]] + .. [['A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', ]] + .. [['\=string([submatch(0, 1), submatch(9, 1), submatch(8, 1), ]] + .. [[submatch(7, 1), submatch(6, 1), submatch(5, 1), submatch(4, 1), ]] + .. [[submatch(3, 1), submatch(2, 1), submatch(1, 1)])', '')]] + ) + ) end) -- TEST_6 was about the 'cpoptions' flag / which was removed in pull request @@ -115,8 +161,7 @@ describe('substitute()', function() feed_command('set magic&') eq('A\rA', eval("substitute('A\rA', 'A.', '\\=submatch(0)', '')")) eq('B\nB', eval([[substitute("B\nB", 'B.', '\=submatch(0)', '')]])) - eq("['B\n']B", - eval([[substitute("B\nB", 'B.', '\=string(submatch(0, 1))', '')]])) + eq("['B\n']B", eval([[substitute("B\nB", 'B.', '\=string(submatch(0, 1))', '')]])) eq('-abab', eval([[substitute('-bb', '\zeb', 'a', 'g')]])) eq('c-cbcbc', eval([[substitute('-bb', '\ze', 'c', 'g')]])) end) @@ -145,9 +190,9 @@ describe(':substitute', function() feed_command('set magic&') feed_command([[1s/\(^\|,\)\ze\(,\|X\)/\1N/g]]) feed_command([[2s/\(^\|,\)\ze\(,\|Y\)/\1N/gc]]) - feed('a') -- For the dialog of the previous :s command. + feed('a') -- For the dialog of the previous :s command. feed_command([[3s/\(^\|,\)\ze\(,\|Z\)/\1N/gc]]) - feed('yy') -- For the dialog of the previous :s command. + feed('yy') -- For the dialog of the previous :s command. expect([[ N,,NX N,,NY @@ -158,16 +203,16 @@ describe(':substitute', function() insert('xxx') feed_command('set magic&') feed_command('s/x/X/gc') - feed('yyq') -- For the dialog of the previous :s command. + feed('yyq') -- For the dialog of the previous :s command. expect('XXx') end) it('first char is highlighted with confirmation dialog and empty match', function() local screen = Screen.new(60, 8) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {reverse = true}, -- IncSearch - [2] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { reverse = true }, -- IncSearch + [2] = { bold = true, foreground = Screen.colors.SeaGreen }, -- MoreMsg }) screen:attach() exec([[ @@ -179,10 +224,7 @@ describe(':substitute', function() {1:o}ne | two | three | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {2:replace with (y/n/a/q/l/^E/^Y)?}^ | ]]) end) diff --git a/test/functional/legacy/syn_attr_spec.lua b/test/functional/legacy/syn_attr_spec.lua index e6573da5d3..ec47bdf9af 100644 --- a/test/functional/legacy/syn_attr_spec.lua +++ b/test/functional/legacy/syn_attr_spec.lua @@ -37,12 +37,12 @@ describe('synIDattr()', function() end) end - for _, mode in ipairs({'cterm', 'gui'}) do + for _, mode in ipairs({ 'cterm', 'gui' }) do describe(('"%s"'):format(mode), function() for _, attr in ipairs(bool_attrs) do none_test(attr, mode) end - for _, attr in ipairs({'inverse', 'bg', 'fg', 'sp'}) do + for _, attr in ipairs({ 'inverse', 'bg', 'fg', 'sp' }) do none_test(attr, mode) end end) diff --git a/test/functional/legacy/tabline_spec.lua b/test/functional/legacy/tabline_spec.lua index 6b368d1857..683c7d9bd7 100644 --- a/test/functional/legacy/tabline_spec.lua +++ b/test/functional/legacy/tabline_spec.lua @@ -17,12 +17,12 @@ describe('tabline', function() -- oldtest: Test_tabline_showcmd() it('showcmdloc=tabline works', function() screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {background = Screen.colors.LightGrey}, -- Visual - [2] = {bold = true}, -- MoreMsg, TabLineSel - [3] = {reverse = true}, -- TabLineFill - [4] = {background = Screen.colors.LightGrey, underline = true}, -- TabLine - [5] = {background = Screen.colors.LightGrey, foreground = Screen.colors.DarkBlue}, -- Folded + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { background = Screen.colors.LightGrey, foreground = Screen.colors.Black }, -- Visual + [2] = { bold = true }, -- MoreMsg, TabLineSel + [3] = { reverse = true }, -- TabLineFill + [4] = { background = Screen.colors.LightGrey, underline = true }, -- TabLine + [5] = { background = Screen.colors.LightGrey, foreground = Screen.colors.DarkBlue }, -- Folded }) exec([[ func MyTabLine() @@ -44,9 +44,7 @@ describe('tabline', function() {3:g }| {5:+-- 2 lines: a···································}| ^c | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) @@ -57,8 +55,7 @@ describe('tabline', function() ^a | b | c | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) @@ -68,8 +65,7 @@ describe('tabline', function() {1:a} | {1:b} | {1:c}^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {2:-- VISUAL BLOCK --} | ]]) @@ -79,8 +75,7 @@ describe('tabline', function() a | b | ^c | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) @@ -92,8 +87,7 @@ describe('tabline', function() a | b | ^c | - {0:~ }| - {0:~ }| + {0:~ }|*2 : | ]]) end) diff --git a/test/functional/legacy/tagcase_spec.lua b/test/functional/legacy/tagcase_spec.lua index 9ca0e0009f..f84fc673cf 100644 --- a/test/functional/legacy/tagcase_spec.lua +++ b/test/functional/legacy/tagcase_spec.lua @@ -10,10 +10,13 @@ local write_file = helpers.write_file describe("'tagcase' option", function() setup(function() - write_file('Xtags', [[ + write_file( + 'Xtags', + [[ Bar Xtext 3 Foo Xtext 2 - foo Xtext 4]]) + foo Xtext 4]] + ) end) before_each(function() diff --git a/test/functional/legacy/undolevels_spec.lua b/test/functional/legacy/undolevels_spec.lua index 1dfc4c17ba..e8badc6864 100644 --- a/test/functional/legacy/undolevels_spec.lua +++ b/test/functional/legacy/undolevels_spec.lua @@ -1,6 +1,6 @@ local helpers = require('test.functional.helpers')(after_each) local source, clear = helpers.source, helpers.clear -local eq, nvim = helpers.eq, helpers.meths +local eq, nvim = helpers.eq, helpers.api describe('undolevel', function() setup(clear) @@ -57,6 +57,6 @@ describe('undolevel', function() call Test_global_local_undolevels() ]]) - eq({}, nvim.get_vvar('errors')) + eq({}, nvim.nvim_get_vvar('errors')) end) end) diff --git a/test/functional/legacy/vimscript_spec.lua b/test/functional/legacy/vimscript_spec.lua index 16a1080396..8b0a920a3e 100644 --- a/test/functional/legacy/vimscript_spec.lua +++ b/test/functional/legacy/vimscript_spec.lua @@ -3,16 +3,16 @@ local Screen = require('test.functional.ui.screen') local clear = helpers.clear local exec = helpers.exec local feed = helpers.feed -local meths = helpers.meths +local api = helpers.api before_each(clear) describe('Vim script', function() -- oldtest: Test_deep_nest() - it('Error when if/for/while/try/function is nested too deep',function() + it('Error when if/for/while/try/function is nested too deep', function() local screen = Screen.new(80, 24) screen:attach() - meths.set_option_value('laststatus', 2, {}) + api.nvim_set_option_value('laststatus', 2, {}) exec([[ " Deep nesting of if ... endif func Test1() @@ -59,25 +59,25 @@ describe('Vim script', function() let @a = '' endfunc ]]) - screen:expect({any = '%[No Name%]'}) + screen:expect({ any = '%[No Name%]' }) feed(':call Test1()<CR>') - screen:expect({any = 'E579: '}) + screen:expect({ any = 'E579: ' }) feed('<C-C>') - screen:expect({any = '%[No Name%]'}) + screen:expect({ any = '%[No Name%]' }) feed(':call Test2()<CR>') - screen:expect({any = 'E585: '}) + screen:expect({ any = 'E585: ' }) feed('<C-C>') - screen:expect({any = '%[No Name%]'}) + screen:expect({ any = '%[No Name%]' }) feed(':call Test3()<CR>') - screen:expect({any = 'E585: '}) + screen:expect({ any = 'E585: ' }) feed('<C-C>') - screen:expect({any = '%[No Name%]'}) + screen:expect({ any = '%[No Name%]' }) feed(':call Test4()<CR>') - screen:expect({any = 'E601: '}) + screen:expect({ any = 'E601: ' }) feed('<C-C>') - screen:expect({any = '%[No Name%]'}) + screen:expect({ any = '%[No Name%]' }) feed(':call Test5()<CR>') - screen:expect({any = 'E1058: '}) + screen:expect({ any = 'E1058: ' }) end) -- oldtest: Test_typed_script_var() @@ -85,6 +85,6 @@ describe('Vim script', function() local screen = Screen.new(80, 24) screen:attach() feed(":echo get(s:, 'foo', 'x')\n") - screen:expect({any = 'E116: '}) + screen:expect({ any = 'E116: ' }) end) end) diff --git a/test/functional/legacy/visual_spec.lua b/test/functional/legacy/visual_spec.lua index 629fab5eb5..151e5874e1 100644 --- a/test/functional/legacy/visual_spec.lua +++ b/test/functional/legacy/visual_spec.lua @@ -13,9 +13,9 @@ describe('Visual highlight', function() before_each(function() screen = Screen.new(50, 6) screen:set_default_attr_ids({ - [0] = {foreground = Screen.colors.Blue, bold = true}, -- NonText - [1] = {bold = true}, -- ModeMsg - [2] = {background = Screen.colors.LightGrey}, -- Visual + [0] = { foreground = Screen.colors.Blue, bold = true }, -- NonText + [1] = { bold = true }, -- ModeMsg + [2] = { background = Screen.colors.LightGrey, foreground = Screen.colors.Black }, -- Visual }) screen:attach() end) @@ -33,8 +33,7 @@ describe('Visual highlight', function() {2:aaaaaa}^ | {2:bbbb } | {2:cc } | - {0:~ }| - {0:~ }| + {0:~ }|*2 {1:-- VISUAL BLOCK --} | ]]) @@ -43,8 +42,7 @@ describe('Visual highlight', function() {2:aaaaaa } | {2:bbbb } | {2:cc}^ {2: } | - {0:~ }| - {0:~ }| + {0:~ }|*2 {1:-- VISUAL BLOCK --} | ]]) end) @@ -60,9 +58,7 @@ describe('Visual highlight', function() screen:expect([[ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa^a| {0:+}{2:aaaa}aaaaaa | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {1:-- VISUAL --} | ]]) end) diff --git a/test/functional/legacy/window_cmd_spec.lua b/test/functional/legacy/window_cmd_spec.lua index 979b46ae47..7fe4ec8eb6 100644 --- a/test/functional/legacy/window_cmd_spec.lua +++ b/test/functional/legacy/window_cmd_spec.lua @@ -11,7 +11,7 @@ it('scrolling with laststatus=0 and :botright split', function() clear('--cmd', 'set ruler') local screen = Screen.new(40, 10) screen:set_default_attr_ids({ - [1] = {reverse = true}, -- StatusLineNC + [1] = { reverse = true }, -- StatusLineNC }) screen:attach() exec([[ @@ -296,10 +296,7 @@ describe('splitkeep', function() a | b | c | - ~ | - ~ | - ~ | - ~ | + ~ |*4 [No Name] | ^a | b | @@ -328,8 +325,7 @@ describe('splitkeep', function() <<<e line with lots of text in one line | ^with lots of text in one line with lots | of text in one line | - ~ | - ~ | + ~ |*2 [No Name] [+] | | ]]) diff --git a/test/functional/legacy/wordcount_spec.lua b/test/functional/legacy/wordcount_spec.lua index 21f96628c0..82021dd98d 100644 --- a/test/functional/legacy/wordcount_spec.lua +++ b/test/functional/legacy/wordcount_spec.lua @@ -50,75 +50,83 @@ describe('wordcount', function() ]=]) -- Test 1: empty window - eq(eval([=[ + eq( + eval([=[ [[''], {'chars': 0, 'cursor_chars': 0, 'words': 0, 'cursor_words': 0, 'bytes': 0, 'cursor_bytes': 0}] ]=]), - eval('DoRecordWin()') - ) + eval('DoRecordWin()') + ) -- Test 2: some words, cursor at start command([[call PutInWindow('one two three')]]) - eq(eval([=[ + eq( + eval([=[ [['', 'one two three'], {'chars': 15, 'cursor_chars': 1, 'words': 3, 'cursor_words': 0, 'bytes': 15, 'cursor_bytes': 1}] ]=]), - eval('DoRecordWin([1, 1, 0])') - ) + eval('DoRecordWin([1, 1, 0])') + ) -- Test 3: some words, cursor at end command([[call PutInWindow('one two three')]]) - eq(eval([=[ + eq( + eval([=[ [['', 'one two three'], {'chars': 15, 'cursor_chars': 14, 'words': 3, 'cursor_words': 3, 'bytes': 15, 'cursor_bytes': 14}] ]=]), - eval('DoRecordWin([2, 99, 0])') - ) + eval('DoRecordWin([2, 99, 0])') + ) -- Test 4: some words, cursor at end, ve=all command('set ve=all') command([[call PutInWindow('one two three')]]) - eq(eval([=[ + eq( + eval([=[ [['', 'one two three'], {'chars': 15, 'cursor_chars': 15, 'words': 3, 'cursor_words': 3, 'bytes': 15, 'cursor_bytes': 15}] ]=]), - eval('DoRecordWin([2,99,0])') - ) + eval('DoRecordWin([2,99,0])') + ) command('set ve=') -- Test 5: several lines with words command([=[call PutInWindow(['one two three', 'one two three', 'one two three'])]=]) - eq(eval([=[ + eq( + eval([=[ [['', 'one two three', 'one two three', 'one two three'], {'chars': 43, 'cursor_chars': 42, 'words': 9, 'cursor_words': 9, 'bytes': 43, 'cursor_bytes': 42}] ]=]), - eval('DoRecordWin([4,99,0])') - ) + eval('DoRecordWin([4,99,0])') + ) -- Test 6: one line with BOM set command([[call PutInWindow('one two three')]]) command('wincmd k') command('set bomb') command('wincmd j') - eq(eval([=[ + eq( + eval([=[ [['', 'one two three'], {'chars': 15, 'cursor_chars': 14, 'words': 3, 'cursor_words': 3, 'bytes': 18, 'cursor_bytes': 14}] ]=]), - eval('DoRecordWin([2,99,0])') - ) + eval('DoRecordWin([2,99,0])') + ) command('wincmd k') command('set nobomb') command('wincmd j') -- Test 7: one line with multibyte words command([=[call PutInWindow(['Äne M¤ne Müh'])]=]) - eq(eval([=[ + eq( + eval([=[ [['', 'Äne M¤ne Müh'], {'chars': 14, 'cursor_chars': 13, 'words': 3, 'cursor_words': 3, 'bytes': 17, 'cursor_bytes': 16}] ]=]), - eval('DoRecordWin([2,99,0])') - ) + eval('DoRecordWin([2,99,0])') + ) -- Test 8: several lines with multibyte words command([=[call PutInWindow(['Äne M¤ne Müh', 'und raus bist dü!'])]=]) - eq(eval([=[ + eq( + eval([=[ [['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'cursor_chars': 31, 'words': 7, 'cursor_words': 7, 'bytes': 36, 'cursor_bytes': 35}] ]=]), - eval('DoRecordWin([3,99,0])') - ) + eval('DoRecordWin([3,99,0])') + ) -- Test 9: visual mode, complete buffer command([=[call PutInWindow(['Äne M¤ne Müh', 'und raus bist dü!'])]=]) @@ -131,11 +139,12 @@ describe('wordcount', function() command('set stl= ls=1') command('let log=DoRecordWin([3,99,0])') command('let log[1]=g:visual_stat') - eq(eval([=[ + eq( + eval([=[ [['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 32, 'visual_words': 7, 'visual_bytes': 36}] ]=]), - eval('log') - ) + eval('log') + ) -- Test 10: visual mode (empty) command([=[call PutInWindow(['Äne M¤ne Müh', 'und raus bist dü!'])]=]) @@ -148,11 +157,12 @@ describe('wordcount', function() command('set stl= ls=1') command('let log=DoRecordWin([3,99,0])') command('let log[1]=g:visual_stat') - eq(eval([=[ + eq( + eval([=[ [['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 1, 'visual_words': 0, 'visual_bytes': 1}] ]=]), - eval('log') - ) + eval('log') + ) -- Test 11: visual mode, single line command([=[call PutInWindow(['Äne M¤ne Müh', 'und raus bist dü!'])]=]) @@ -165,10 +175,11 @@ describe('wordcount', function() command('set stl= ls=1') command('let log=DoRecordWin([3,99,0])') command('let log[1]=g:visual_stat') - eq(eval([=[ + eq( + eval([=[ [['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 13, 'visual_words': 3, 'visual_bytes': 16}] ]=]), - eval('log') - ) + eval('log') + ) end) end) diff --git a/test/functional/lua/api_spec.lua b/test/functional/lua/api_spec.lua index d808693a9e..acd56a0ddb 100644 --- a/test/functional/lua/api_spec.lua +++ b/test/functional/lua/api_spec.lua @@ -3,10 +3,10 @@ local helpers = require('test.functional.helpers')(after_each) local exc_exec = helpers.exc_exec local remove_trace = helpers.remove_trace -local funcs = helpers.funcs +local fn = helpers.fn local clear = helpers.clear local eval = helpers.eval -local NIL = helpers.NIL +local NIL = vim.NIL local eq = helpers.eq local exec_lua = helpers.exec_lua local pcall_err = helpers.pcall_err @@ -17,64 +17,77 @@ describe('luaeval(vim.api.…)', function() describe('with channel_id and buffer handle', function() describe('nvim_buf_get_lines', function() it('works', function() - funcs.setline(1, {"abc", "def", "a\nb", "ttt"}) - eq({'a\000b'}, - funcs.luaeval('vim.api.nvim_buf_get_lines(1, 2, 3, false)')) + fn.setline(1, { 'abc', 'def', 'a\nb', 'ttt' }) + eq({ 'a\000b' }, fn.luaeval('vim.api.nvim_buf_get_lines(1, 2, 3, false)')) end) end) describe('nvim_buf_set_lines', function() it('works', function() - funcs.setline(1, {"abc", "def", "a\nb", "ttt"}) - eq(NIL, funcs.luaeval('vim.api.nvim_buf_set_lines(1, 1, 2, false, {"b\\0a"})')) - eq({'abc', 'b\000a', 'a\000b', 'ttt'}, - funcs.luaeval('vim.api.nvim_buf_get_lines(1, 0, 4, false)')) + fn.setline(1, { 'abc', 'def', 'a\nb', 'ttt' }) + eq(NIL, fn.luaeval('vim.api.nvim_buf_set_lines(1, 1, 2, false, {"b\\0a"})')) + eq( + { 'abc', 'b\000a', 'a\000b', 'ttt' }, + fn.luaeval('vim.api.nvim_buf_get_lines(1, 0, 4, false)') + ) end) end) end) describe('with errors', function() it('transforms API error from nvim_buf_set_lines into lua error', function() - funcs.setline(1, {"abc", "def", "a\nb", "ttt"}) - eq({false, "'replacement string' item contains newlines"}, - funcs.luaeval('{pcall(vim.api.nvim_buf_set_lines, 1, 1, 2, false, {"b\\na"})}')) + fn.setline(1, { 'abc', 'def', 'a\nb', 'ttt' }) + eq( + { false, "'replacement string' item contains newlines" }, + fn.luaeval('{pcall(vim.api.nvim_buf_set_lines, 1, 1, 2, false, {"b\\na"})}') + ) end) it('transforms API error from nvim_win_set_cursor into lua error', function() - eq({false, 'Argument "pos" must be a [row, col] array'}, - funcs.luaeval('{pcall(vim.api.nvim_win_set_cursor, 0, {1, 2, 3})}')) + eq( + { false, 'Argument "pos" must be a [row, col] array' }, + fn.luaeval('{pcall(vim.api.nvim_win_set_cursor, 0, {1, 2, 3})}') + ) -- Used to produce a memory leak due to a bug in nvim_win_set_cursor - eq({false, 'Invalid window id: -1'}, - funcs.luaeval('{pcall(vim.api.nvim_win_set_cursor, -1, {1, 2, 3})}')) + eq( + { false, 'Invalid window id: -1' }, + fn.luaeval('{pcall(vim.api.nvim_win_set_cursor, -1, {1, 2, 3})}') + ) end) - it('transforms API error from nvim_win_set_cursor + same array as in first test into lua error', - function() - eq({false, 'Argument "pos" must be a [row, col] array'}, - funcs.luaeval('{pcall(vim.api.nvim_win_set_cursor, 0, {"b\\na"})}')) - end) + it( + 'transforms API error from nvim_win_set_cursor + same array as in first test into lua error', + function() + eq( + { false, 'Argument "pos" must be a [row, col] array' }, + fn.luaeval('{pcall(vim.api.nvim_win_set_cursor, 0, {"b\\na"})}') + ) + end + ) end) it('correctly evaluates API code which calls luaeval', function() - local str = (([===[vim.api.nvim_eval([==[ + local str = ( + ([===[vim.api.nvim_eval([==[ luaeval('vim.api.nvim_eval([=[ luaeval("vim.api.nvim_eval([[ luaeval(1) ]])") ]=])') - ]==])]===]):gsub('\n', ' ')) - eq(1, funcs.luaeval(str)) + ]==])]===]):gsub('\n', ' ') + ) + eq(1, fn.luaeval(str)) end) it('correctly converts from API objects', function() - eq(1, funcs.luaeval('vim.api.nvim_eval("1")')) - eq('1', funcs.luaeval([[vim.api.nvim_eval('"1"')]])) - eq('Blobby', funcs.luaeval('vim.api.nvim_eval("0z426c6f626279")')) - eq({}, funcs.luaeval('vim.api.nvim_eval("[]")')) - eq({}, funcs.luaeval('vim.api.nvim_eval("{}")')) - eq(1, funcs.luaeval('vim.api.nvim_eval("1.0")')) - eq('\000', funcs.luaeval('vim.api.nvim_eval("0z00")')) - eq(true, funcs.luaeval('vim.api.nvim_eval("v:true")')) - eq(false, funcs.luaeval('vim.api.nvim_eval("v:false")')) - eq(NIL, funcs.luaeval('vim.api.nvim_eval("v:null")')) + eq(1, fn.luaeval('vim.api.nvim_eval("1")')) + eq('1', fn.luaeval([[vim.api.nvim_eval('"1"')]])) + eq('Blobby', fn.luaeval('vim.api.nvim_eval("0z426c6f626279")')) + eq({}, fn.luaeval('vim.api.nvim_eval("[]")')) + eq({}, fn.luaeval('vim.api.nvim_eval("{}")')) + eq(1, fn.luaeval('vim.api.nvim_eval("1.0")')) + eq('\000', fn.luaeval('vim.api.nvim_eval("0z00")')) + eq(true, fn.luaeval('vim.api.nvim_eval("v:true")')) + eq(false, fn.luaeval('vim.api.nvim_eval("v:false")')) + eq(NIL, fn.luaeval('vim.api.nvim_eval("v:null")')) eq(0, eval([[type(luaeval('vim.api.nvim_eval("1")'))]])) eq(1, eval([[type(luaeval('vim.api.nvim_eval("''1''")'))]])) @@ -86,28 +99,32 @@ describe('luaeval(vim.api.…)', function() eq(6, eval([[type(luaeval('vim.api.nvim_eval("v:false")'))]])) eq(7, eval([[type(luaeval('vim.api.nvim_eval("v:null")'))]])) - eq({foo=42}, funcs.luaeval([[vim.api.nvim_eval('{"foo": 42}')]])) - eq({42}, funcs.luaeval([[vim.api.nvim_eval('[42]')]])) + eq({ foo = 42 }, fn.luaeval([[vim.api.nvim_eval('{"foo": 42}')]])) + eq({ 42 }, fn.luaeval([[vim.api.nvim_eval('[42]')]])) - eq({foo={bar=42}, baz=50}, funcs.luaeval([[vim.api.nvim_eval('{"foo": {"bar": 42}, "baz": 50}')]])) - eq({{42}, {}}, funcs.luaeval([=[vim.api.nvim_eval('[[42], []]')]=])) + eq( + { foo = { bar = 42 }, baz = 50 }, + fn.luaeval([[vim.api.nvim_eval('{"foo": {"bar": 42}, "baz": 50}')]]) + ) + eq({ { 42 }, {} }, fn.luaeval([=[vim.api.nvim_eval('[[42], []]')]=])) end) it('correctly converts to API objects', function() - eq(1, funcs.luaeval('vim.api.nvim__id(1)')) - eq('1', funcs.luaeval('vim.api.nvim__id("1")')) - eq({1}, funcs.luaeval('vim.api.nvim__id({1})')) - eq({foo=1}, funcs.luaeval('vim.api.nvim__id({foo=1})')) - eq(1.5, funcs.luaeval('vim.api.nvim__id(1.5)')) - eq(true, funcs.luaeval('vim.api.nvim__id(true)')) - eq(false, funcs.luaeval('vim.api.nvim__id(false)')) - eq(NIL, funcs.luaeval('vim.api.nvim__id(nil)')) + eq(1, fn.luaeval('vim.api.nvim__id(1)')) + eq('1', fn.luaeval('vim.api.nvim__id("1")')) + eq({ 1 }, fn.luaeval('vim.api.nvim__id({1})')) + eq({ foo = 1 }, fn.luaeval('vim.api.nvim__id({foo=1})')) + eq(1.5, fn.luaeval('vim.api.nvim__id(1.5)')) + eq(true, fn.luaeval('vim.api.nvim__id(true)')) + eq(false, fn.luaeval('vim.api.nvim__id(false)')) + eq(NIL, fn.luaeval('vim.api.nvim__id(nil)')) -- API strings from Blobs can work as NUL-terminated C strings - eq('Vim(call):E5555: API call: Vim:E15: Invalid expression: ""', - exc_exec('call nvim_eval(v:_null_blob)')) - eq('Vim(call):E5555: API call: Vim:E15: Invalid expression: ""', - exc_exec('call nvim_eval(0z)')) + eq( + 'Vim(call):E5555: API call: Vim:E15: Invalid expression: ""', + exc_exec('call nvim_eval(v:_null_blob)') + ) + eq('Vim(call):E5555: API call: Vim:E15: Invalid expression: ""', exc_exec('call nvim_eval(0z)')) eq(1, eval('nvim_eval(0z31)')) eq(0, eval([[type(luaeval('vim.api.nvim__id(1)'))]])) @@ -119,68 +136,152 @@ describe('luaeval(vim.api.…)', function() eq(6, eval([[type(luaeval('vim.api.nvim__id(false)'))]])) eq(7, eval([[type(luaeval('vim.api.nvim__id(nil)'))]])) - eq({foo=1, bar={42, {{baz=true}, 5}}}, funcs.luaeval('vim.api.nvim__id({foo=1, bar={42, {{baz=true}, 5}}})')) + eq( + { foo = 1, bar = { 42, { { baz = true }, 5 } } }, + fn.luaeval('vim.api.nvim__id({foo=1, bar={42, {{baz=true}, 5}}})') + ) - eq(true, funcs.luaeval('vim.api.nvim__id(vim.api.nvim__id)(true)')) - eq(42, exec_lua [[ + eq(true, fn.luaeval('vim.api.nvim__id(vim.api.nvim__id)(true)')) + eq( + 42, + exec_lua [[ local f = vim.api.nvim__id({42, vim.api.nvim__id}) return f[2](f[1]) - ]]) + ]] + ) end) it('correctly converts container objects with type_idx to API objects', function() - eq(5, eval('type(luaeval("vim.api.nvim__id({[vim.type_idx]=vim.types.float, [vim.val_idx]=0})"))')) + eq( + 5, + eval('type(luaeval("vim.api.nvim__id({[vim.type_idx]=vim.types.float, [vim.val_idx]=0})"))') + ) eq(4, eval([[type(luaeval('vim.api.nvim__id({[vim.type_idx]=vim.types.dictionary})'))]])) eq(3, eval([[type(luaeval('vim.api.nvim__id({[vim.type_idx]=vim.types.array})'))]])) - eq({}, funcs.luaeval('vim.api.nvim__id({[vim.type_idx]=vim.types.array})')) + eq({}, fn.luaeval('vim.api.nvim__id({[vim.type_idx]=vim.types.array})')) -- Presence of type_idx makes Vim ignore some keys - eq({42}, funcs.luaeval('vim.api.nvim__id({[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})')) - eq({foo=2}, funcs.luaeval('vim.api.nvim__id({[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})')) - eq(10, funcs.luaeval('vim.api.nvim__id({[vim.type_idx]=vim.types.float, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})')) - eq({}, funcs.luaeval('vim.api.nvim__id({[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2})')) + eq( + { 42 }, + fn.luaeval( + 'vim.api.nvim__id({[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})' + ) + ) + eq( + { foo = 2 }, + fn.luaeval( + 'vim.api.nvim__id({[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})' + ) + ) + eq( + 10, + fn.luaeval( + 'vim.api.nvim__id({[vim.type_idx]=vim.types.float, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})' + ) + ) + eq( + {}, + fn.luaeval( + 'vim.api.nvim__id({[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2})' + ) + ) end) it('correctly converts arrays with type_idx to API objects', function() eq(3, eval([[type(luaeval('vim.api.nvim__id_array({[vim.type_idx]=vim.types.array})'))]])) - eq({}, funcs.luaeval('vim.api.nvim__id_array({[vim.type_idx]=vim.types.array})')) - - eq({42}, funcs.luaeval('vim.api.nvim__id_array({[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})')) - eq({{foo=2}}, funcs.luaeval('vim.api.nvim__id_array({{[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})')) - eq({10}, funcs.luaeval('vim.api.nvim__id_array({{[vim.type_idx]=vim.types.float, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})')) - eq({}, funcs.luaeval('vim.api.nvim__id_array({[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2})')) - - eq({}, funcs.luaeval('vim.api.nvim__id_array({})')) + eq({}, fn.luaeval('vim.api.nvim__id_array({[vim.type_idx]=vim.types.array})')) + + eq( + { 42 }, + fn.luaeval( + 'vim.api.nvim__id_array({[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})' + ) + ) + eq( + { { foo = 2 } }, + fn.luaeval( + 'vim.api.nvim__id_array({{[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})' + ) + ) + eq( + { 10 }, + fn.luaeval( + 'vim.api.nvim__id_array({{[vim.type_idx]=vim.types.float, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})' + ) + ) + eq( + {}, + fn.luaeval( + 'vim.api.nvim__id_array({[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2})' + ) + ) + + eq({}, fn.luaeval('vim.api.nvim__id_array({})')) eq(3, eval([[type(luaeval('vim.api.nvim__id_array({})'))]])) end) it('correctly converts dictionaries with type_idx to API objects', function() - eq(4, eval([[type(luaeval('vim.api.nvim__id_dictionary({[vim.type_idx]=vim.types.dictionary})'))]])) - - eq({}, funcs.luaeval('vim.api.nvim__id_dictionary({[vim.type_idx]=vim.types.dictionary})')) - - eq({v={42}}, funcs.luaeval('vim.api.nvim__id_dictionary({v={[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})')) - eq({foo=2}, funcs.luaeval('vim.api.nvim__id_dictionary({[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})')) - eq({v=10}, funcs.luaeval('vim.api.nvim__id_dictionary({v={[vim.type_idx]=vim.types.float, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})')) - eq({v={}}, funcs.luaeval('vim.api.nvim__id_dictionary({v={[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2}})')) + eq( + 4, + eval([[type(luaeval('vim.api.nvim__id_dictionary({[vim.type_idx]=vim.types.dictionary})'))]]) + ) + + eq({}, fn.luaeval('vim.api.nvim__id_dictionary({[vim.type_idx]=vim.types.dictionary})')) + + eq( + { v = { 42 } }, + fn.luaeval( + 'vim.api.nvim__id_dictionary({v={[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})' + ) + ) + eq( + { foo = 2 }, + fn.luaeval( + 'vim.api.nvim__id_dictionary({[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})' + ) + ) + eq( + { v = 10 }, + fn.luaeval( + 'vim.api.nvim__id_dictionary({v={[vim.type_idx]=vim.types.float, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})' + ) + ) + eq( + { v = {} }, + fn.luaeval( + 'vim.api.nvim__id_dictionary({v={[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2}})' + ) + ) -- If API requests dictionary, then empty table will be the one. This is not -- the case normally because empty table is an empty array. - eq({}, funcs.luaeval('vim.api.nvim__id_dictionary({})')) + eq({}, fn.luaeval('vim.api.nvim__id_dictionary({})')) eq(4, eval([[type(luaeval('vim.api.nvim__id_dictionary({})'))]])) end) it('converts booleans in positional args', function() - eq({''}, exec_lua [[ return vim.api.nvim_buf_get_lines(0, 0, 10, false) ]]) - eq({''}, exec_lua [[ return vim.api.nvim_buf_get_lines(0, 0, 10, nil) ]]) - eq('Index out of bounds', pcall_err(exec_lua, [[ return vim.api.nvim_buf_get_lines(0, 0, 10, true) ]])) - eq('Index out of bounds', pcall_err(exec_lua, [[ return vim.api.nvim_buf_get_lines(0, 0, 10, 1) ]])) + eq({ '' }, exec_lua [[ return vim.api.nvim_buf_get_lines(0, 0, 10, false) ]]) + eq({ '' }, exec_lua [[ return vim.api.nvim_buf_get_lines(0, 0, 10, nil) ]]) + eq( + 'Index out of bounds', + pcall_err(exec_lua, [[ return vim.api.nvim_buf_get_lines(0, 0, 10, true) ]]) + ) + eq( + 'Index out of bounds', + pcall_err(exec_lua, [[ return vim.api.nvim_buf_get_lines(0, 0, 10, 1) ]]) + ) -- this follows lua conventions for bools (not api convention for Boolean) - eq('Index out of bounds', pcall_err(exec_lua, [[ return vim.api.nvim_buf_get_lines(0, 0, 10, 0) ]])) - eq('Index out of bounds', pcall_err(exec_lua, [[ return vim.api.nvim_buf_get_lines(0, 0, 10, {}) ]])) + eq( + 'Index out of bounds', + pcall_err(exec_lua, [[ return vim.api.nvim_buf_get_lines(0, 0, 10, 0) ]]) + ) + eq( + 'Index out of bounds', + pcall_err(exec_lua, [[ return vim.api.nvim_buf_get_lines(0, 0, 10, {}) ]]) + ) end) it('converts booleans in optional args', function() @@ -190,50 +291,92 @@ describe('luaeval(vim.api.…)', function() -- API conventions (not lua conventions): zero is falsy eq({}, exec_lua [[ return vim.api.nvim_exec2("echo 'foobar'", {output=0}) ]]) - eq({output='foobar'}, exec_lua [[ return vim.api.nvim_exec2("echo 'foobar'", {output=true}) ]]) - eq({output='foobar'}, exec_lua [[ return vim.api.nvim_exec2("echo 'foobar'", {output=1}) ]]) - eq([[Invalid 'output': not a boolean]], pcall_err(exec_lua, [[ return vim.api.nvim_exec2("echo 'foobar'", {output={}}) ]])) + eq( + { output = 'foobar' }, + exec_lua [[ return vim.api.nvim_exec2("echo 'foobar'", {output=true}) ]] + ) + eq({ output = 'foobar' }, exec_lua [[ return vim.api.nvim_exec2("echo 'foobar'", {output=1}) ]]) + eq( + [[Invalid 'output': not a boolean]], + pcall_err(exec_lua, [[ return vim.api.nvim_exec2("echo 'foobar'", {output={}}) ]]) + ) end) it('errors out correctly when working with API', function() -- Conversion errors - eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'obj': Cannot convert given Lua table]], - remove_trace(exc_exec([[call luaeval("vim.api.nvim__id({1, foo=42})")]]))) + eq( + [[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'obj': Cannot convert given Lua table]], + remove_trace(exc_exec([[call luaeval("vim.api.nvim__id({1, foo=42})")]])) + ) -- Errors in number of arguments - eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected 1 argument', - remove_trace(exc_exec([[call luaeval("vim.api.nvim__id()")]]))) - eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected 1 argument', - remove_trace(exc_exec([[call luaeval("vim.api.nvim__id(1, 2)")]]))) - eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected 2 arguments', - remove_trace(exc_exec([[call luaeval("vim.api.nvim_set_var(1, 2, 3)")]]))) + eq( + 'Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected 1 argument', + remove_trace(exc_exec([[call luaeval("vim.api.nvim__id()")]])) + ) + eq( + 'Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected 1 argument', + remove_trace(exc_exec([[call luaeval("vim.api.nvim__id(1, 2)")]])) + ) + eq( + 'Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected 2 arguments', + remove_trace(exc_exec([[call luaeval("vim.api.nvim_set_var(1, 2, 3)")]])) + ) -- Error in argument types - eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'name': Expected Lua string]], - remove_trace(exc_exec([[call luaeval("vim.api.nvim_set_var(1, 2)")]]))) - - eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'start': Expected Lua number]], - remove_trace(exc_exec([[call luaeval("vim.api.nvim_buf_get_lines(0, 'test', 1, false)")]]))) - eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'start': Number is not integral]], - remove_trace(exc_exec([[call luaeval("vim.api.nvim_buf_get_lines(0, 1.5, 1, false)")]]))) - eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'window': Expected Lua number]], - remove_trace(exc_exec([[call luaeval("vim.api.nvim_win_is_valid(nil)")]]))) - - eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'flt': Expected Lua number]], - remove_trace(exc_exec([[call luaeval("vim.api.nvim__id_float('test')")]]))) - eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'flt': Expected Float-like Lua table]], - remove_trace(exc_exec([[call luaeval("vim.api.nvim__id_float({[vim.type_idx]=vim.types.dictionary})")]]))) - - eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'arr': Expected Lua table]], - remove_trace(exc_exec([[call luaeval("vim.api.nvim__id_array(1)")]]))) - eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'arr': Expected Array-like Lua table]], - remove_trace(exc_exec([[call luaeval("vim.api.nvim__id_array({[vim.type_idx]=vim.types.dictionary})")]]))) - - eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'dct': Expected Lua table]], - remove_trace(exc_exec([[call luaeval("vim.api.nvim__id_dictionary(1)")]]))) - eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'dct': Expected Dict-like Lua table]], - remove_trace(exc_exec([[call luaeval("vim.api.nvim__id_dictionary({[vim.type_idx]=vim.types.array})")]]))) - - eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected Lua table]], - remove_trace(exc_exec([[call luaeval("vim.api.nvim_set_keymap('', '', '', '')")]]))) + eq( + [[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'name': Expected Lua string]], + remove_trace(exc_exec([[call luaeval("vim.api.nvim_set_var(1, 2)")]])) + ) + + eq( + [[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'start': Expected Lua number]], + remove_trace(exc_exec([[call luaeval("vim.api.nvim_buf_get_lines(0, 'test', 1, false)")]])) + ) + eq( + [[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'start': Number is not integral]], + remove_trace(exc_exec([[call luaeval("vim.api.nvim_buf_get_lines(0, 1.5, 1, false)")]])) + ) + eq( + [[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'window': Expected Lua number]], + remove_trace(exc_exec([[call luaeval("vim.api.nvim_win_is_valid(nil)")]])) + ) + + eq( + [[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'flt': Expected Lua number]], + remove_trace(exc_exec([[call luaeval("vim.api.nvim__id_float('test')")]])) + ) + eq( + [[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'flt': Expected Float-like Lua table]], + remove_trace( + exc_exec([[call luaeval("vim.api.nvim__id_float({[vim.type_idx]=vim.types.dictionary})")]]) + ) + ) + + eq( + [[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'arr': Expected Lua table]], + remove_trace(exc_exec([[call luaeval("vim.api.nvim__id_array(1)")]])) + ) + eq( + [[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'arr': Expected Array-like Lua table]], + remove_trace( + exc_exec([[call luaeval("vim.api.nvim__id_array({[vim.type_idx]=vim.types.dictionary})")]]) + ) + ) + + eq( + [[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'dct': Expected Lua table]], + remove_trace(exc_exec([[call luaeval("vim.api.nvim__id_dictionary(1)")]])) + ) + eq( + [[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'dct': Expected Dict-like Lua table]], + remove_trace( + exc_exec([[call luaeval("vim.api.nvim__id_dictionary({[vim.type_idx]=vim.types.array})")]]) + ) + ) + + eq( + [[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected Lua table]], + remove_trace(exc_exec([[call luaeval("vim.api.nvim_set_keymap('', '', '', '')")]])) + ) -- TODO: check for errors with Tabpage argument -- TODO: check for errors with Window argument @@ -241,8 +384,15 @@ describe('luaeval(vim.api.…)', function() end) it('accepts any value as API Boolean', function() - eq('', funcs.luaeval('vim.api.nvim_replace_termcodes("", vim, false, nil)')) - eq('', funcs.luaeval('vim.api.nvim_replace_termcodes("", 0, 1.5, "test")')) - eq('', funcs.luaeval('vim.api.nvim_replace_termcodes("", true, {}, {[vim.type_idx]=vim.types.array})')) + eq('', fn.luaeval('vim.api.nvim_replace_termcodes("", vim, false, nil)')) + eq('', fn.luaeval('vim.api.nvim_replace_termcodes("", 0, 1.5, "test")')) + eq( + '', + fn.luaeval('vim.api.nvim_replace_termcodes("", true, {}, {[vim.type_idx]=vim.types.array})') + ) + end) + + it('serializes sparse arrays in Lua', function() + eq({ [1] = vim.NIL, [2] = 2 }, exec_lua [[ return { [2] = 2 } ]]) end) end) diff --git a/test/functional/lua/base64_spec.lua b/test/functional/lua/base64_spec.lua index f0d112c23e..21fd536a98 100644 --- a/test/functional/lua/base64_spec.lua +++ b/test/functional/lua/base64_spec.lua @@ -49,12 +49,15 @@ describe('vim.base64', function() end -- Explicitly check encoded output - eq('VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZwo=', encode('The quick brown fox jumps over the lazy dog\n')) + eq( + 'VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZwo=', + encode('The quick brown fox jumps over the lazy dog\n') + ) -- Test vectors from rfc4648 local rfc4648 = { { '', '' }, - { 'f', 'Zg==', }, + { 'f', 'Zg==' }, { 'fo', 'Zm8=' }, { 'foo', 'Zm9v' }, { 'foob', 'Zm9vYg==' }, diff --git a/test/functional/lua/buffer_updates_spec.lua b/test/functional/lua/buffer_updates_spec.lua index 51e4548edb..714e1b951f 100644 --- a/test/functional/lua/buffer_updates_spec.lua +++ b/test/functional/lua/buffer_updates_spec.lua @@ -1,10 +1,9 @@ -- Test suite for testing interactions with API bindings local helpers = require('test.functional.helpers')(after_each) -local luv = require('luv') local command = helpers.command -local meths = helpers.meths -local funcs = helpers.funcs +local api = helpers.api +local fn = helpers.fn local clear = helpers.clear local eq = helpers.eq local fail = helpers.fail @@ -14,15 +13,17 @@ local expect_events = helpers.expect_events local write_file = helpers.write_file local dedent = helpers.dedent -local origlines = {"original line 1", - "original line 2", - "original line 3", - "original line 4", - "original line 5", - "original line 6", - " indented line"} - -before_each(function () +local origlines = { + 'original line 1', + 'original line 2', + 'original line 3', + 'original line 4', + 'original line 5', + 'original line 6', + ' indented line', +} + +before_each(function() clear() exec_lua [[ local evname = ... @@ -53,15 +54,15 @@ end) describe('lua buffer event callbacks: on_lines', function() local function setup_eventcheck(verify, utf_sizes, lines) local lastsize - meths.buf_set_lines(0, 0, -1, true, lines) + api.nvim_buf_set_lines(0, 0, -1, true, lines) if verify then - lastsize = meths.buf_get_offset(0, meths.buf_line_count(0)) + lastsize = api.nvim_buf_get_offset(0, api.nvim_buf_line_count(0)) end - exec_lua("return test_register(...)", 0, "on_lines", "test1",false,utf_sizes) - local verify_name = "test1" + exec_lua('return test_register(...)', 0, 'on_lines', 'test1', false, utf_sizes) + local verify_name = 'test1' local function check_events(expected) - local events = exec_lua("return get_events(...)" ) + local events = exec_lua('return get_events(...)') if utf_sizes then -- this test case uses ASCII only, so sizes should be the same. -- Unicode is tested below. @@ -70,13 +71,14 @@ describe('lua buffer event callbacks: on_lines', function() event[10] = event[10] or event[9] end end - expect_events(expected, events, "line updates") + expect_events(expected, events, 'line updates') if verify then for _, event in ipairs(events) do - if event[1] == verify_name and event[2] == "lines" then + if event[1] == verify_name and event[2] == 'lines' then local startline, endline = event[5], event[7] - local newrange = meths.buf_get_offset(0, endline) - meths.buf_get_offset(0, startline) - local newsize = meths.buf_get_offset(0, meths.buf_line_count(0)) + local newrange = api.nvim_buf_get_offset(0, endline) + - api.nvim_buf_get_offset(0, startline) + local newsize = api.nvim_buf_get_offset(0, api.nvim_buf_line_count(0)) local oldrange = newrange + lastsize - newsize eq(oldrange, event[8]) lastsize = newsize @@ -84,101 +86,102 @@ describe('lua buffer event callbacks: on_lines', function() end end end - return check_events, function(new) verify_name = new end + return check_events, function(new) + verify_name = new + end end - -- verifying the sizes with nvim_buf_get_offset is nice (checks we cannot -- assert the wrong thing), but masks errors with unflushed lines (as -- nvim_buf_get_offset forces a flush of the memline). To be safe run the -- test both ways. - local function check(verify,utf_sizes) + local function check(verify, utf_sizes) local check_events, verify_name = setup_eventcheck(verify, utf_sizes, origlines) - local tick = meths.buf_get_changedtick(0) + local tick = api.nvim_buf_get_changedtick(0) command('set autoindent') command('normal! GyyggP') tick = tick + 1 - check_events {{ "test1", "lines", 1, tick, 0, 0, 1, 0}} + check_events { { 'test1', 'lines', 1, tick, 0, 0, 1, 0 } } - meths.buf_set_lines(0, 3, 5, true, {"changed line"}) + api.nvim_buf_set_lines(0, 3, 5, true, { 'changed line' }) tick = tick + 1 - check_events {{ "test1", "lines", 1, tick, 3, 5, 4, 32 }} + check_events { { 'test1', 'lines', 1, tick, 3, 5, 4, 32 } } - exec_lua("return test_register(...)", 0, "on_lines", "test2", true, utf_sizes) + exec_lua('return test_register(...)', 0, 'on_lines', 'test2', true, utf_sizes) tick = tick + 1 command('undo') -- plugins can opt in to receive changedtick events, or choose -- to only receive actual changes. check_events { - { "test1", "lines", 1, tick, 3, 4, 5, 13 }; - { "test2", "lines", 1, tick, 3, 4, 5, 13 }; - { "test2", "changedtick", 1, tick+1 }; + { 'test1', 'lines', 1, tick, 3, 4, 5, 13 }, + { 'test2', 'lines', 1, tick, 3, 4, 5, 13 }, + { 'test2', 'changedtick', 1, tick + 1 }, } tick = tick + 1 tick = tick + 1 command('redo') check_events { - { "test1", "lines", 1, tick, 3, 5, 4, 32 }; - { "test2", "lines", 1, tick, 3, 5, 4, 32 }; - { "test2", "changedtick", 1, tick+1 }; + { 'test1', 'lines', 1, tick, 3, 5, 4, 32 }, + { 'test2', 'lines', 1, tick, 3, 5, 4, 32 }, + { 'test2', 'changedtick', 1, tick + 1 }, } tick = tick + 1 tick = tick + 1 command('undo!') check_events { - { "test1", "lines", 1, tick, 3, 4, 5, 13 }; - { "test2", "lines", 1, tick, 3, 4, 5, 13 }; - { "test2", "changedtick", 1, tick+1 }; + { 'test1', 'lines', 1, tick, 3, 4, 5, 13 }, + { 'test2', 'lines', 1, tick, 3, 4, 5, 13 }, + { 'test2', 'changedtick', 1, tick + 1 }, } tick = tick + 1 -- simulate next callback returning true exec_lua("test_unreg = 'test1'") - meths.buf_set_lines(0, 6, 7, true, {"x1","x2","x3"}) + api.nvim_buf_set_lines(0, 6, 7, true, { 'x1', 'x2', 'x3' }) tick = tick + 1 -- plugins can opt in to receive changedtick events, or choose -- to only receive actual changes. check_events { - { "test1", "lines", 1, tick, 6, 7, 9, 16 }; - { "test2", "lines", 1, tick, 6, 7, 9, 16 }; + { 'test1', 'lines', 1, tick, 6, 7, 9, 16 }, + { 'test2', 'lines', 1, tick, 6, 7, 9, 16 }, } - verify_name "test2" + verify_name 'test2' - meths.buf_set_lines(0, 1, 1, true, {"added"}) + api.nvim_buf_set_lines(0, 1, 1, true, { 'added' }) tick = tick + 1 - check_events {{ "test2", "lines", 1, tick, 1, 1, 2, 0 }} + check_events { { 'test2', 'lines', 1, tick, 1, 1, 2, 0 } } feed('wix') tick = tick + 1 - check_events {{ "test2", "lines", 1, tick, 4, 5, 5, 16 }} + check_events { { 'test2', 'lines', 1, tick, 4, 5, 5, 16 } } -- check hot path for multiple insert feed('yz') tick = tick + 1 - check_events {{ "test2", "lines", 1, tick, 4, 5, 5, 17 }} + check_events { { 'test2', 'lines', 1, tick, 4, 5, 5, 17 } } feed('<bs>') tick = tick + 1 - check_events {{ "test2", "lines", 1, tick, 4, 5, 5, 19 }} + check_events { { 'test2', 'lines', 1, tick, 4, 5, 5, 19 } } feed('<esc>Go') tick = tick + 1 - check_events {{ "test2", "lines", 1, tick, 11, 11, 12, 0 }} + check_events { { 'test2', 'lines', 1, tick, 11, 11, 12, 0 } } feed('x') tick = tick + 1 - check_events {{ "test2", "lines", 1, tick, 11, 12, 12, 5 }} + check_events { { 'test2', 'lines', 1, tick, 11, 12, 12, 5 } } command('bwipe!') - check_events {{ "test2", "detach", 1 }} - end + check_events { { 'test2', 'detach', 1 } } + end it('works', function() check(false) @@ -189,54 +192,56 @@ describe('lua buffer event callbacks: on_lines', function() end) it('works with utf_sizes and ASCII text', function() - check(false,true) + check(false, true) end) local function check_unicode(verify) - local unicode_text = {"ascii text", - "latin text åäö", - "BMP text ɧ αλφά", - "BMP text 汉语 ↥↧", - "SMP 🤦 🦄🦃", - "combining å بِيَّة"} + local unicode_text = { + 'ascii text', + 'latin text åäö', + 'BMP text ɧ αλφά', + 'BMP text 汉语 ↥↧', + 'SMP 🤦 🦄🦃', + 'combining å بِيَّة', + } local check_events, verify_name = setup_eventcheck(verify, true, unicode_text) - local tick = meths.buf_get_changedtick(0) + local tick = api.nvim_buf_get_changedtick(0) feed('ggdd') tick = tick + 1 - check_events {{ "test1", "lines", 1, tick, 0, 1, 0, 11, 11, 11 }} + check_events { { 'test1', 'lines', 1, tick, 0, 1, 0, 11, 11, 11 } } feed('A<bs>') tick = tick + 1 - check_events {{ "test1", "lines", 1, tick, 0, 1, 1, 18, 15, 15 }} + check_events { { 'test1', 'lines', 1, tick, 0, 1, 1, 18, 15, 15 } } feed('<esc>jylp') tick = tick + 1 - check_events {{ "test1", "lines", 1, tick, 1, 2, 2, 21, 16, 16 }} + check_events { { 'test1', 'lines', 1, tick, 1, 2, 2, 21, 16, 16 } } feed('+eea<cr>') tick = tick + 1 - check_events {{ "test1", "lines", 1, tick, 2, 3, 4, 23, 15, 15 }} + check_events { { 'test1', 'lines', 1, tick, 2, 3, 4, 23, 15, 15 } } feed('<esc>jdw') tick = tick + 1 -- non-BMP chars count as 2 UTF-2 codeunits - check_events {{ "test1", "lines", 1, tick, 4, 5, 5, 18, 9, 12 }} + check_events { { 'test1', 'lines', 1, tick, 4, 5, 5, 18, 9, 12 } } feed('+rx') tick = tick + 1 -- count the individual codepoints of a composed character. - check_events {{ "test1", "lines", 1, tick, 5, 6, 6, 27, 20, 20 }} + check_events { { 'test1', 'lines', 1, tick, 5, 6, 6, 27, 20, 20 } } feed('kJ') tick = tick + 1 -- verification fails with multiple line updates, sorry about that - verify_name "" + verify_name '' -- NB: this is inefficient (but not really wrong). check_events { - { "test1", "lines", 1, tick, 4, 5, 5, 14, 5, 8 }; - { "test1", "lines", 1, tick+1, 5, 6, 5, 27, 20, 20 }; + { 'test1', 'lines', 1, tick, 4, 5, 5, 14, 5, 8 }, + { 'test1', 'lines', 1, tick + 1, 5, 6, 5, 27, 20, 20 }, } end @@ -248,9 +253,8 @@ describe('lua buffer event callbacks: on_lines', function() check_unicode(true) end) - it('has valid cursor position while shifting', function() - meths.buf_set_lines(0, 0, -1, true, {'line1'}) + api.nvim_buf_set_lines(0, 0, -1, true, { 'line1' }) exec_lua([[ vim.api.nvim_buf_attach(0, false, { on_lines = function() @@ -259,15 +263,15 @@ describe('lua buffer event callbacks: on_lines', function() }) ]]) feed('>>') - eq(1, meths.get_var('listener_cursor_line')) + eq(1, api.nvim_get_var('listener_cursor_line')) end) it('has valid cursor position while deleting lines', function() - meths.buf_set_lines(0, 0, -1, true, { "line_1", "line_2", "line_3", "line_4"}) - meths.win_set_cursor(0, {2, 0}) - eq(2, meths.win_get_cursor(0)[1]) - meths.buf_set_lines(0, 0, -1, true, { "line_1", "line_2", "line_3"}) - eq(2, meths.win_get_cursor(0)[1]) + api.nvim_buf_set_lines(0, 0, -1, true, { 'line_1', 'line_2', 'line_3', 'line_4' }) + api.nvim_win_set_cursor(0, { 2, 0 }) + eq(2, api.nvim_win_get_cursor(0)[1]) + api.nvim_buf_set_lines(0, 0, -1, true, { 'line_1', 'line_2', 'line_3' }) + eq(2, api.nvim_win_get_cursor(0)[1]) end) it('does not SEGFAULT when accessing window buffer info in on_detach #14998', function() @@ -286,16 +290,16 @@ describe('lua buffer event callbacks: on_lines', function() ]] exec_lua(code) - command("q!") + command('q!') helpers.assert_alive() exec_lua(code) - command("bd!") + command('bd!') helpers.assert_alive() end) it('#12718 lnume', function() - meths.buf_set_lines(0, 0, -1, true, {'1', '2', '3'}) + api.nvim_buf_set_lines(0, 0, -1, true, { '1', '2', '3' }) exec_lua([[ vim.api.nvim_buf_attach(0, false, { on_lines = function(...) @@ -308,28 +312,31 @@ describe('lua buffer event callbacks: on_lines', function() feed('G0') feed('p') -- Is the last arg old_byte_size correct? Doesn't matter for this PR - eq(meths.get_var('linesev'), { "lines", 1, 4, 2, 3, 5, 4 }) + eq(api.nvim_get_var('linesev'), { 'lines', 1, 4, 2, 3, 5, 4 }) feed('2G0') feed('p') - eq(meths.get_var('linesev'), { "lines", 1, 5, 1, 4, 4, 8 }) + eq(api.nvim_get_var('linesev'), { 'lines', 1, 5, 1, 4, 4, 8 }) feed('1G0') feed('P') - eq(meths.get_var('linesev'), { "lines", 1, 6, 0, 3, 3, 9 }) + eq(api.nvim_get_var('linesev'), { 'lines', 1, 6, 0, 3, 3, 9 }) end) - it('calling nvim_buf_call() from callback does not cause Normal mode CTRL-A to misbehave #16729', function() - exec_lua([[ + it( + 'calling nvim_buf_call() from callback does not cause Normal mode CTRL-A to misbehave #16729', + function() + exec_lua([[ vim.api.nvim_buf_attach(0, false, { on_lines = function(...) vim.api.nvim_buf_call(0, function() end) end, }) ]]) - feed('itest123<Esc><C-A>') - eq('test124', meths.get_current_line()) - end) + feed('itest123<Esc><C-A>') + eq('test124', api.nvim_get_current_line()) + end + ) end) describe('lua: nvim_buf_attach on_bytes', function() @@ -339,24 +346,24 @@ describe('lua: nvim_buf_attach on_bytes', function() -- test both ways. local function setup_eventcheck(verify, start_txt) if start_txt then - meths.buf_set_lines(0, 0, -1, true, start_txt) + api.nvim_buf_set_lines(0, 0, -1, true, start_txt) else - start_txt = meths.buf_get_lines(0, 0, -1, true) + start_txt = api.nvim_buf_get_lines(0, 0, -1, true) end local shadowbytes = table.concat(start_txt, '\n') .. '\n' -- TODO: while we are brewing the real strong coffee, -- verify should check buf_get_offset after every check_events if verify then - local len = meths.buf_get_offset(0, meths.buf_line_count(0)) + local len = api.nvim_buf_get_offset(0, api.nvim_buf_line_count(0)) eq(len == -1 and 1 or len, string.len(shadowbytes)) end - exec_lua("return test_register(...)", 0, "on_bytes", "test1", false, false, true) - meths.buf_get_changedtick(0) + exec_lua('return test_register(...)', 0, 'on_bytes', 'test1', false, false, true) + api.nvim_buf_get_changedtick(0) - local verify_name = "test1" + local verify_name = 'test1' local function check_events(expected) - local events = exec_lua("return get_events(...)" ) - expect_events(expected, events, "byte updates") + local events = exec_lua('return get_events(...)') + expect_events(expected, events, 'byte updates') if not verify then return @@ -364,12 +371,12 @@ describe('lua: nvim_buf_attach on_bytes', function() for _, event in ipairs(events) do for _, elem in ipairs(event) do - if type(elem) == "number" and elem < 0 then - fail(string.format("Received event has negative values")) + if type(elem) == 'number' and elem < 0 then + fail(string.format('Received event has negative values')) end end - if event[1] == verify_name and event[2] == "bytes" then + if event[1] == verify_name and event[2] == 'bytes' then local _, _, _, _, _, _, start_byte, _, _, old_byte, _, _, new_byte = unpack(event) local before = string.sub(shadowbytes, 1, start_byte) -- no text in the tests will contain 0xff bytes (invalid UTF-8) @@ -377,15 +384,19 @@ describe('lua: nvim_buf_attach on_bytes', function() local unknown = string.rep('\255', new_byte) local after = string.sub(shadowbytes, start_byte + old_byte + 1) shadowbytes = before .. unknown .. after - elseif event[1] == verify_name and event[2] == "reload" then - shadowbytes = table.concat(meths.buf_get_lines(0, 0, -1, true), '\n') .. '\n' + elseif event[1] == verify_name and event[2] == 'reload' then + shadowbytes = table.concat(api.nvim_buf_get_lines(0, 0, -1, true), '\n') .. '\n' end end - local text = meths.buf_get_lines(0, 0, -1, true) + local text = api.nvim_buf_get_lines(0, 0, -1, true) local bytes = table.concat(text, '\n') .. '\n' - eq(string.len(bytes), string.len(shadowbytes), '\non_bytes: total bytecount of buffer is wrong') + eq( + string.len(bytes), + string.len(shadowbytes), + '\non_bytes: total bytecount of buffer is wrong' + ) for i = 1, string.len(shadowbytes) do local shadowbyte = string.sub(shadowbytes, i, i) if shadowbyte ~= '\255' then @@ -400,89 +411,89 @@ describe('lua: nvim_buf_attach on_bytes', function() -- Yes, we can do both local function do_both(verify) it('single and multiple join', function() - local check_events = setup_eventcheck(verify, origlines) - feed 'ggJ' - check_events { - {'test1', 'bytes', 1, 3, 0, 15, 15, 1, 0, 1, 0, 1, 1}; - } + local check_events = setup_eventcheck(verify, origlines) + feed 'ggJ' + check_events { + { 'test1', 'bytes', 1, 3, 0, 15, 15, 1, 0, 1, 0, 1, 1 }, + } - feed '3J' - check_events { - {'test1', 'bytes', 1, 5, 0, 31, 31, 1, 0, 1, 0, 1, 1}; - {'test1', 'bytes', 1, 5, 0, 47, 47, 1, 0, 1, 0, 1, 1}; - } + feed '3J' + check_events { + { 'test1', 'bytes', 1, 5, 0, 31, 31, 1, 0, 1, 0, 1, 1 }, + { 'test1', 'bytes', 1, 5, 0, 47, 47, 1, 0, 1, 0, 1, 1 }, + } end) it('opening lines', function() - local check_events = setup_eventcheck(verify, origlines) - -- meths.set_option_value('autoindent', true, {}) - feed 'Go' - check_events { - { "test1", "bytes", 1, 4, 7, 0, 114, 0, 0, 0, 1, 0, 1 }; - } - feed '<cr>' - check_events { - { "test1", "bytes", 1, 5, 7, 0, 114, 0, 0, 0, 1, 0, 1 }; - } + local check_events = setup_eventcheck(verify, origlines) + -- api.nvim_set_option_value('autoindent', true, {}) + feed 'Go' + check_events { + { 'test1', 'bytes', 1, 3, 7, 0, 114, 0, 0, 0, 1, 0, 1 }, + } + feed '<cr>' + check_events { + { 'test1', 'bytes', 1, 5, 7, 0, 114, 0, 0, 0, 1, 0, 1 }, + } end) it('opening lines with autoindent', function() - local check_events = setup_eventcheck(verify, origlines) - meths.set_option_value('autoindent', true, {}) - feed 'Go' - check_events { - { "test1", "bytes", 1, 4, 7, 0, 114, 0, 0, 0, 1, 0, 5 }; - } - feed '<cr>' - check_events { - { "test1", "bytes", 1, 4, 7, 0, 114, 0, 4, 4, 0, 0, 0 }; - { "test1", "bytes", 1, 5, 7, 0, 114, 0, 0, 0, 1, 4, 5 }; - } + local check_events = setup_eventcheck(verify, origlines) + api.nvim_set_option_value('autoindent', true, {}) + feed 'Go' + check_events { + { 'test1', 'bytes', 1, 3, 7, 0, 114, 0, 0, 0, 1, 0, 5 }, + } + feed '<cr>' + check_events { + { 'test1', 'bytes', 1, 4, 7, 0, 114, 0, 4, 4, 0, 0, 0 }, + { 'test1', 'bytes', 1, 5, 7, 0, 114, 0, 0, 0, 1, 4, 5 }, + } end) it('setline(num, line)', function() local check_events = setup_eventcheck(verify, origlines) - funcs.setline(2, "babla") + fn.setline(2, 'babla') check_events { - { "test1", "bytes", 1, 3, 1, 0, 16, 0, 15, 15, 0, 5, 5 }; + { 'test1', 'bytes', 1, 3, 1, 0, 16, 0, 15, 15, 0, 5, 5 }, } - funcs.setline(2, {"foo", "bar"}) + fn.setline(2, { 'foo', 'bar' }) check_events { - { "test1", "bytes", 1, 4, 1, 0, 16, 0, 5, 5, 0, 3, 3 }; - { "test1", "bytes", 1, 5, 2, 0, 20, 0, 15, 15, 0, 3, 3 }; + { 'test1', 'bytes', 1, 4, 1, 0, 16, 0, 5, 5, 0, 3, 3 }, + { 'test1', 'bytes', 1, 5, 2, 0, 20, 0, 15, 15, 0, 3, 3 }, } - local buf_len = meths.buf_line_count(0) - funcs.setline(buf_len + 1, "baz") + local buf_len = api.nvim_buf_line_count(0) + fn.setline(buf_len + 1, 'baz') check_events { - { "test1", "bytes", 1, 6, 7, 0, 90, 0, 0, 0, 1, 0, 4 }; + { 'test1', 'bytes', 1, 6, 7, 0, 90, 0, 0, 0, 1, 0, 4 }, } end) it('continuing comments with fo=or', function() - local check_events = setup_eventcheck(verify, {'// Comment'}) - meths.set_option_value('formatoptions', 'ro', {}) - meths.set_option_value('filetype', 'c', {}) + local check_events = setup_eventcheck(verify, { '// Comment' }) + api.nvim_set_option_value('formatoptions', 'ro', {}) + api.nvim_set_option_value('filetype', 'c', {}) feed 'A<CR>' check_events { - { "test1", "bytes", 1, 4, 0, 10, 10, 0, 0, 0, 1, 3, 4 }; + { 'test1', 'bytes', 1, 4, 0, 10, 10, 0, 0, 0, 1, 3, 4 }, } feed '<ESC>' check_events { - { "test1", "bytes", 1, 4, 1, 2, 13, 0, 1, 1, 0, 0, 0 }; + { 'test1', 'bytes', 1, 4, 1, 2, 13, 0, 1, 1, 0, 0, 0 }, } feed 'ggo' -- goto first line to continue testing check_events { - { "test1", "bytes", 1, 6, 1, 0, 11, 0, 0, 0, 1, 0, 4 }; + { 'test1', 'bytes', 1, 5, 1, 0, 11, 0, 0, 0, 1, 0, 4 }, } feed '<CR>' check_events { - { "test1", "bytes", 1, 6, 1, 2, 13, 0, 1, 1, 0, 0, 0 }; - { "test1", "bytes", 1, 7, 1, 2, 13, 0, 0, 0, 1, 3, 4 }; + { 'test1', 'bytes', 1, 6, 1, 2, 13, 0, 1, 1, 0, 0, 0 }, + { 'test1', 'bytes', 1, 7, 1, 2, 13, 0, 0, 0, 1, 3, 4 }, } end) @@ -491,757 +502,775 @@ describe('lua: nvim_buf_attach on_bytes', function() feed 'ia' check_events { - { "test1", "bytes", 1, 3, 0, 0, 0, 0, 0, 0, 0, 1, 1 }; + { 'test1', 'bytes', 1, 3, 0, 0, 0, 0, 0, 0, 0, 1, 1 }, } end) - it("deleting lines", function() + it('deleting lines', function() local check_events = setup_eventcheck(verify, origlines) - feed("dd") + feed('dd') check_events { - { "test1", "bytes", 1, 3, 0, 0, 0, 1, 0, 16, 0, 0, 0 }; + { 'test1', 'bytes', 1, 3, 0, 0, 0, 1, 0, 16, 0, 0, 0 }, } - feed("d2j") + feed('d2j') check_events { - { "test1", "bytes", 1, 4, 0, 0, 0, 3, 0, 48, 0, 0, 0 }; + { 'test1', 'bytes', 1, 4, 0, 0, 0, 3, 0, 48, 0, 0, 0 }, } - feed("ld<c-v>2j") + feed('ld<c-v>2j') check_events { - { "test1", "bytes", 1, 5, 0, 1, 1, 0, 1, 1, 0, 0, 0 }; - { "test1", "bytes", 1, 5, 1, 1, 16, 0, 1, 1, 0, 0, 0 }; - { "test1", "bytes", 1, 5, 2, 1, 31, 0, 1, 1, 0, 0, 0 }; + { 'test1', 'bytes', 1, 5, 0, 1, 1, 0, 1, 1, 0, 0, 0 }, + { 'test1', 'bytes', 1, 5, 1, 1, 16, 0, 1, 1, 0, 0, 0 }, + { 'test1', 'bytes', 1, 5, 2, 1, 31, 0, 1, 1, 0, 0, 0 }, } - feed("vjwd") + feed('vjwd') check_events { - { "test1", "bytes", 1, 10, 0, 1, 1, 1, 9, 23, 0, 0, 0 }; + { 'test1', 'bytes', 1, 10, 0, 1, 1, 1, 9, 23, 0, 0, 0 }, } end) - it("changing lines", function() + it('changing lines', function() local check_events = setup_eventcheck(verify, origlines) - feed "cc" + feed 'cc' check_events { - { "test1", "bytes", 1, 4, 0, 0, 0, 0, 15, 15, 0, 0, 0 }; + { 'test1', 'bytes', 1, 4, 0, 0, 0, 0, 15, 15, 0, 0, 0 }, } - feed "<ESC>" + feed '<ESC>' check_events {} - feed "c3j" + feed 'c3j' check_events { - { "test1", "bytes", 1, 4, 1, 0, 1, 3, 0, 48, 0, 0, 0 }; + { 'test1', 'bytes', 1, 4, 1, 0, 1, 3, 0, 48, 0, 0, 0 }, } end) - it("visual charwise paste", function() - local check_events = setup_eventcheck(verify, {'1234567890'}) - funcs.setreg('a', '___') + it('visual charwise paste', function() + local check_events = setup_eventcheck(verify, { '1234567890' }) + fn.setreg('a', '___') feed '1G1|vll' check_events {} feed '"ap' check_events { - { "test1", "bytes", 1, 3, 0, 0, 0, 0, 3, 3, 0, 0, 0 }; - { "test1", "bytes", 1, 5, 0, 0, 0, 0, 0, 0, 0, 3, 3 }; + { 'test1', 'bytes', 1, 3, 0, 0, 0, 0, 3, 3, 0, 0, 0 }, + { 'test1', 'bytes', 1, 5, 0, 0, 0, 0, 0, 0, 0, 3, 3 }, } end) it('blockwise paste', function() - local check_events = setup_eventcheck(verify, {'1', '2', '3'}) + local check_events = setup_eventcheck(verify, { '1', '2', '3' }) feed('1G0') feed('y<C-v>2j') feed('G0') feed('p') check_events { - { "test1", "bytes", 1, 3, 2, 1, 5, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 3, 3, 0, 7, 0, 0, 0, 0, 3, 3 }; - { "test1", "bytes", 1, 3, 4, 0, 10, 0, 0, 0, 0, 3, 3 }; + { 'test1', 'bytes', 1, 3, 2, 1, 5, 0, 0, 0, 0, 1, 1 }, + { 'test1', 'bytes', 1, 3, 3, 0, 7, 0, 0, 0, 0, 3, 3 }, + { 'test1', 'bytes', 1, 3, 4, 0, 10, 0, 0, 0, 0, 3, 3 }, } feed('2G0') feed('p') check_events { - { "test1", "bytes", 1, 4, 1, 1, 3, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 4, 2, 1, 6, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 4, 3, 1, 10, 0, 0, 0, 0, 1, 1 }; + { 'test1', 'bytes', 1, 4, 1, 1, 3, 0, 0, 0, 0, 1, 1 }, + { 'test1', 'bytes', 1, 4, 2, 1, 6, 0, 0, 0, 0, 1, 1 }, + { 'test1', 'bytes', 1, 4, 3, 1, 10, 0, 0, 0, 0, 1, 1 }, } feed('1G0') feed('P') check_events { - { "test1", "bytes", 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 5, 1, 0, 3, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 5, 2, 0, 7, 0, 0, 0, 0, 1, 1 }; + { 'test1', 'bytes', 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 1 }, + { 'test1', 'bytes', 1, 5, 1, 0, 3, 0, 0, 0, 0, 1, 1 }, + { 'test1', 'bytes', 1, 5, 2, 0, 7, 0, 0, 0, 0, 1, 1 }, } - end) - it("linewise paste", function() + it('linewise paste', function() local check_events = setup_eventcheck(verify, origlines) - feed'yyp' + feed 'yyp' check_events { - { "test1", "bytes", 1, 3, 1, 0, 16, 0, 0, 0, 1, 0, 16 }; + { 'test1', 'bytes', 1, 3, 1, 0, 16, 0, 0, 0, 1, 0, 16 }, } - feed'Gyyp' + feed 'Gyyp' check_events { - { "test1", "bytes", 1, 4, 8, 0, 130, 0, 0, 0, 1, 0, 18 }; + { 'test1', 'bytes', 1, 4, 8, 0, 130, 0, 0, 0, 1, 0, 18 }, } end) it('inccomand=nosplit and substitute', function() - local check_events = setup_eventcheck(verify, - {"abcde", "12345"}) - meths.set_option_value('inccommand', 'nosplit', {}) + local check_events = setup_eventcheck(verify, { 'abcde', '12345' }) + api.nvim_set_option_value('inccommand', 'nosplit', {}) -- linewise substitute feed(':%s/bcd/') check_events { - { "test1", "bytes", 1, 3, 0, 1, 1, 0, 3, 3, 0, 0, 0 }; - { "test1", "bytes", 1, 5, 0, 1, 1, 0, 0, 0, 0, 3, 3 }; + { 'test1', 'bytes', 1, 3, 0, 1, 1, 0, 3, 3, 0, 0, 0 }, + { 'test1', 'bytes', 1, 5, 0, 1, 1, 0, 0, 0, 0, 3, 3 }, } feed('a') check_events { - { "test1", "bytes", 1, 3, 0, 1, 1, 0, 3, 3, 0, 1, 1 }; - { "test1", "bytes", 1, 5, 0, 1, 1, 0, 1, 1, 0, 3, 3 }; + { 'test1', 'bytes', 1, 3, 0, 1, 1, 0, 3, 3, 0, 1, 1 }, + { 'test1', 'bytes', 1, 5, 0, 1, 1, 0, 1, 1, 0, 3, 3 }, } - feed("<esc>") + feed('<esc>') -- splitting lines feed([[:%s/abc/\r]]) check_events { - { "test1", "bytes", 1, 3, 0, 0, 0, 0, 3, 3, 1, 0, 1 }; - { "test1", "bytes", 1, 6, 0, 0, 0, 1, 0, 1, 0, 3, 3 }; + { 'test1', 'bytes', 1, 3, 0, 0, 0, 0, 3, 3, 1, 0, 1 }, + { 'test1', 'bytes', 1, 6, 0, 0, 0, 1, 0, 1, 0, 3, 3 }, } - feed("<esc>") + feed('<esc>') -- multi-line regex feed([[:%s/de\n123/a]]) check_events { - { "test1", "bytes", 1, 3, 0, 3, 3, 1, 3, 6, 0, 1, 1 }; - { "test1", "bytes", 1, 6, 0, 3, 3, 0, 1, 1, 1, 3, 6 }; + { 'test1', 'bytes', 1, 3, 0, 3, 3, 1, 3, 6, 0, 1, 1 }, + { 'test1', 'bytes', 1, 6, 0, 3, 3, 0, 1, 1, 1, 3, 6 }, } - feed("<esc>") + feed('<esc>') -- replacing with unicode - feed(":%s/b/→") + feed(':%s/b/→') check_events { - { "test1", "bytes", 1, 3, 0, 1, 1, 0, 1, 1, 0, 3, 3 }; - { "test1", "bytes", 1, 5, 0, 1, 1, 0, 3, 3, 0, 1, 1 }; + { 'test1', 'bytes', 1, 3, 0, 1, 1, 0, 1, 1, 0, 3, 3 }, + { 'test1', 'bytes', 1, 5, 0, 1, 1, 0, 3, 3, 0, 1, 1 }, } - feed("<esc>") + feed('<esc>') -- replacing with expression register feed([[:%s/b/\=5+5]]) check_events { - { "test1", "bytes", 1, 3, 0, 1, 1, 0, 1, 1, 0, 2, 2 }; - { "test1", "bytes", 1, 5, 0, 1, 1, 0, 2, 2, 0, 1, 1 }; + { 'test1', 'bytes', 1, 3, 0, 1, 1, 0, 1, 1, 0, 2, 2 }, + { 'test1', 'bytes', 1, 5, 0, 1, 1, 0, 2, 2, 0, 1, 1 }, } - feed("<esc>") + feed('<esc>') -- replacing with backslash feed([[:%s/b/\\]]) check_events { - { "test1", "bytes", 1, 3, 0, 1, 1, 0, 1, 1, 0, 1, 1 }; - { "test1", "bytes", 1, 5, 0, 1, 1, 0, 1, 1, 0, 1, 1 }; + { 'test1', 'bytes', 1, 3, 0, 1, 1, 0, 1, 1, 0, 1, 1 }, + { 'test1', 'bytes', 1, 5, 0, 1, 1, 0, 1, 1, 0, 1, 1 }, } - feed("<esc>") + feed('<esc>') -- replacing with backslash from expression register feed([[:%s/b/\='\']]) check_events { - { "test1", "bytes", 1, 3, 0, 1, 1, 0, 1, 1, 0, 1, 1 }; - { "test1", "bytes", 1, 5, 0, 1, 1, 0, 1, 1, 0, 1, 1 }; + { 'test1', 'bytes', 1, 3, 0, 1, 1, 0, 1, 1, 0, 1, 1 }, + { 'test1', 'bytes', 1, 5, 0, 1, 1, 0, 1, 1, 0, 1, 1 }, } - feed("<esc>") + feed('<esc>') -- replacing with backslash followed by another character feed([[:%s/b/\\!]]) check_events { - { "test1", "bytes", 1, 3, 0, 1, 1, 0, 1, 1, 0, 2, 2 }; - { "test1", "bytes", 1, 5, 0, 1, 1, 0, 2, 2, 0, 1, 1 }; + { 'test1', 'bytes', 1, 3, 0, 1, 1, 0, 1, 1, 0, 2, 2 }, + { 'test1', 'bytes', 1, 5, 0, 1, 1, 0, 2, 2, 0, 1, 1 }, } - feed("<esc>") + feed('<esc>') -- replacing with backslash followed by another character from expression register feed([[:%s/b/\='\!']]) check_events { - { "test1", "bytes", 1, 3, 0, 1, 1, 0, 1, 1, 0, 2, 2 }; - { "test1", "bytes", 1, 5, 0, 1, 1, 0, 2, 2, 0, 1, 1 }; + { 'test1', 'bytes', 1, 3, 0, 1, 1, 0, 1, 1, 0, 2, 2 }, + { 'test1', 'bytes', 1, 5, 0, 1, 1, 0, 2, 2, 0, 1, 1 }, } end) it('nvim_buf_set_text insert', function() - local check_events = setup_eventcheck(verify, {"bastext"}) - meths.buf_set_text(0, 0, 3, 0, 3, {"fiol","kontra"}) + local check_events = setup_eventcheck(verify, { 'bastext' }) + api.nvim_buf_set_text(0, 0, 3, 0, 3, { 'fiol', 'kontra' }) check_events { - { "test1", "bytes", 1, 3, 0, 3, 3, 0, 0, 0, 1, 6, 11 }; + { 'test1', 'bytes', 1, 3, 0, 3, 3, 0, 0, 0, 1, 6, 11 }, } - meths.buf_set_text(0, 1, 6, 1, 6, {"punkt","syntgitarr","övnings"}) + api.nvim_buf_set_text(0, 1, 6, 1, 6, { 'punkt', 'syntgitarr', 'övnings' }) check_events { - { "test1", "bytes", 1, 4, 1, 6, 14, 0, 0, 0, 2, 8, 25 }; + { 'test1', 'bytes', 1, 4, 1, 6, 14, 0, 0, 0, 2, 8, 25 }, } - eq({ "basfiol", "kontrapunkt", "syntgitarr", "övningstext" }, - meths.buf_get_lines(0, 0, -1, true)) + eq( + { 'basfiol', 'kontrapunkt', 'syntgitarr', 'övningstext' }, + api.nvim_buf_get_lines(0, 0, -1, true) + ) end) it('nvim_buf_set_text replace', function() local check_events = setup_eventcheck(verify, origlines) - meths.buf_set_text(0, 2, 3, 2, 8, {"very text"}) + api.nvim_buf_set_text(0, 2, 3, 2, 8, { 'very text' }) check_events { - { "test1", "bytes", 1, 3, 2, 3, 35, 0, 5, 5, 0, 9, 9 }; + { 'test1', 'bytes', 1, 3, 2, 3, 35, 0, 5, 5, 0, 9, 9 }, } - meths.buf_set_text(0, 3, 5, 3, 7, {" splitty","line "}) + api.nvim_buf_set_text(0, 3, 5, 3, 7, { ' splitty', 'line ' }) check_events { - { "test1", "bytes", 1, 4, 3, 5, 57, 0, 2, 2, 1, 5, 14 }; + { 'test1', 'bytes', 1, 4, 3, 5, 57, 0, 2, 2, 1, 5, 14 }, } - meths.buf_set_text(0, 0, 8, 1, 2, {"JOINY"}) + api.nvim_buf_set_text(0, 0, 8, 1, 2, { 'JOINY' }) check_events { - { "test1", "bytes", 1, 5, 0, 8, 8, 1, 2, 10, 0, 5, 5 }; + { 'test1', 'bytes', 1, 5, 0, 8, 8, 1, 2, 10, 0, 5, 5 }, } - meths.buf_set_text(0, 4, 0, 6, 0, {"was 5,6",""}) + api.nvim_buf_set_text(0, 4, 0, 6, 0, { 'was 5,6', '' }) check_events { - { "test1", "bytes", 1, 6, 4, 0, 75, 2, 0, 32, 1, 0, 8 }; + { 'test1', 'bytes', 1, 6, 4, 0, 75, 2, 0, 32, 1, 0, 8 }, } - eq({ "originalJOINYiginal line 2", "orivery text line 3", "origi splitty", - "line l line 4", "was 5,6", " indented line" }, - meths.buf_get_lines(0, 0, -1, true)) - + eq({ + 'originalJOINYiginal line 2', + 'orivery text line 3', + 'origi splitty', + 'line l line 4', + 'was 5,6', + ' indented line', + }, api.nvim_buf_get_lines(0, 0, -1, true)) end) it('nvim_buf_set_text delete', function() local check_events = setup_eventcheck(verify, origlines) -- really {""} but accepts {} as a shorthand - meths.buf_set_text(0, 0, 0, 1, 0, {}) + api.nvim_buf_set_text(0, 0, 0, 1, 0, {}) check_events { - { "test1", "bytes", 1, 3, 0, 0, 0, 1, 0, 16, 0, 0, 0 }; + { 'test1', 'bytes', 1, 3, 0, 0, 0, 1, 0, 16, 0, 0, 0 }, } -- TODO(bfredl): this works but is not as convenient as set_lines - meths.buf_set_text(0, 4, 15, 5, 17, {""}) + api.nvim_buf_set_text(0, 4, 15, 5, 17, { '' }) check_events { - { "test1", "bytes", 1, 4, 4, 15, 79, 1, 17, 18, 0, 0, 0 }; + { 'test1', 'bytes', 1, 4, 4, 15, 79, 1, 17, 18, 0, 0, 0 }, } - eq({ "original line 2", "original line 3", "original line 4", - "original line 5", "original line 6" }, - meths.buf_get_lines(0, 0, -1, true)) + eq({ + 'original line 2', + 'original line 3', + 'original line 4', + 'original line 5', + 'original line 6', + }, api.nvim_buf_get_lines(0, 0, -1, true)) end) it('checktime autoread', function() - write_file("Xtest-reload", dedent [[ + write_file( + 'Xtest-reload', + dedent [[ old line 1 - old line 2]]) + old line 2]] + ) local atime = os.time() - 10 - luv.fs_utime("Xtest-reload", atime, atime) - command "e Xtest-reload" - command "set autoread" + vim.uv.fs_utime('Xtest-reload', atime, atime) + command 'e Xtest-reload' + command 'set autoread' local check_events = setup_eventcheck(verify, nil) - write_file("Xtest-reload", dedent [[ + write_file( + 'Xtest-reload', + dedent [[ new line 1 new line 2 - new line 3]]) + new line 3]] + ) - command "checktime" + command 'checktime' check_events { - { "test1", "reload", 1 }; + { 'test1', 'reload', 1 }, } feed 'ggJ' check_events { - { "test1", "bytes", 1, 5, 0, 10, 10, 1, 0, 1, 0, 1, 1 }; + { 'test1', 'bytes', 1, 5, 0, 10, 10, 1, 0, 1, 0, 1, 1 }, } - eq({'new line 1 new line 2', 'new line 3'}, meths.buf_get_lines(0, 0, -1, true)) + eq({ 'new line 1 new line 2', 'new line 3' }, api.nvim_buf_get_lines(0, 0, -1, true)) -- check we can undo and redo a reload event. feed 'u' check_events { - { "test1", "bytes", 1, 8, 0, 10, 10, 0, 1, 1, 1, 0, 1 }; + { 'test1', 'bytes', 1, 8, 0, 10, 10, 0, 1, 1, 1, 0, 1 }, } feed 'u' check_events { - { "test1", "reload", 1 }; + { 'test1', 'reload', 1 }, } feed '<c-r>' check_events { - { "test1", "reload", 1 }; + { 'test1', 'reload', 1 }, } feed '<c-r>' check_events { - { "test1", "bytes", 1, 14, 0, 10, 10, 1, 0, 1, 0, 1, 1 }; + { 'test1', 'bytes', 1, 14, 0, 10, 10, 1, 0, 1, 0, 1, 1 }, } end) - it("tab with noexpandtab and softtabstop", function() - command("set noet") - command("set ts=4") - command("set sw=2") - command("set sts=4") + it('tab with noexpandtab and softtabstop', function() + command('set noet') + command('set ts=4') + command('set sw=2') + command('set sts=4') - local check_events = setup_eventcheck(verify, {'asdfasdf'}) + local check_events = setup_eventcheck(verify, { 'asdfasdf' }) - feed("gg0i<tab>") + feed('gg0i<tab>') check_events { - { "test1", "bytes", 1, 3, 0, 0, 0, 0, 0, 0, 0, 1, 1 }, - { "test1", "bytes", 1, 4, 0, 1, 1, 0, 0, 0, 0, 1, 1 }, + { 'test1', 'bytes', 1, 3, 0, 0, 0, 0, 0, 0, 0, 1, 1 }, + { 'test1', 'bytes', 1, 4, 0, 1, 1, 0, 0, 0, 0, 1, 1 }, } - feed("<tab>") + feed('<tab>') -- when spaces are merged into a tabstop check_events { - { "test1", "bytes", 1, 5, 0, 2, 2, 0, 0, 0, 0, 1, 1 }, - { "test1", "bytes", 1, 6, 0, 3, 3, 0, 0, 0, 0, 1, 1 }, - { "test1", "bytes", 1, 7, 0, 0, 0, 0, 4, 4, 0, 1, 1 }, + { 'test1', 'bytes', 1, 5, 0, 2, 2, 0, 0, 0, 0, 1, 1 }, + { 'test1', 'bytes', 1, 6, 0, 3, 3, 0, 0, 0, 0, 1, 1 }, + { 'test1', 'bytes', 1, 7, 0, 0, 0, 0, 4, 4, 0, 1, 1 }, } - - feed("<esc>u") + feed('<esc>u') check_events { - { "test1", "bytes", 1, 9, 0, 0, 0, 0, 1, 1, 0, 4, 4 }, - { "test1", "bytes", 1, 9, 0, 0, 0, 0, 4, 4, 0, 0, 0 } + { 'test1', 'bytes', 1, 9, 0, 0, 0, 0, 1, 1, 0, 4, 4 }, + { 'test1', 'bytes', 1, 9, 0, 0, 0, 0, 4, 4, 0, 0, 0 }, } -- in REPLACE mode - feed("R<tab><tab>") + feed('R<tab><tab>') check_events { - { "test1", "bytes", 1, 10, 0, 0, 0, 0, 1, 1, 0, 1, 1 }, - { "test1", "bytes", 1, 11, 0, 1, 1, 0, 0, 0, 0, 1, 1 }, - { "test1", "bytes", 1, 12, 0, 2, 2, 0, 1, 1, 0, 1, 1 }, - { "test1", "bytes", 1, 13, 0, 3, 3, 0, 0, 0, 0, 1, 1 }, - { "test1", "bytes", 1, 14, 0, 0, 0, 0, 4, 4, 0, 1, 1 }, + { 'test1', 'bytes', 1, 10, 0, 0, 0, 0, 1, 1, 0, 1, 1 }, + { 'test1', 'bytes', 1, 11, 0, 1, 1, 0, 0, 0, 0, 1, 1 }, + { 'test1', 'bytes', 1, 12, 0, 2, 2, 0, 1, 1, 0, 1, 1 }, + { 'test1', 'bytes', 1, 13, 0, 3, 3, 0, 0, 0, 0, 1, 1 }, + { 'test1', 'bytes', 1, 14, 0, 0, 0, 0, 4, 4, 0, 1, 1 }, } - feed("<esc>u") + feed('<esc>u') check_events { - { "test1", "bytes", 1, 16, 0, 0, 0, 0, 1, 1, 0, 4, 4 }, - { "test1", "bytes", 1, 16, 0, 2, 2, 0, 2, 2, 0, 1, 1 }, - { "test1", "bytes", 1, 16, 0, 0, 0, 0, 2, 2, 0, 1, 1 } + { 'test1', 'bytes', 1, 16, 0, 0, 0, 0, 1, 1, 0, 4, 4 }, + { 'test1', 'bytes', 1, 16, 0, 2, 2, 0, 2, 2, 0, 1, 1 }, + { 'test1', 'bytes', 1, 16, 0, 0, 0, 0, 2, 2, 0, 1, 1 }, } -- in VISUALREPLACE mode - feed("gR<tab><tab>") - check_events { - { "test1", "bytes", 1, 17, 0, 0, 0, 0, 1, 1, 0, 1, 1 }; - { "test1", "bytes", 1, 18, 0, 1, 1, 0, 1, 1, 0, 1, 1 }; - { "test1", "bytes", 1, 19, 0, 2, 2, 0, 1, 1, 0, 1, 1 }; - { "test1", "bytes", 1, 20, 0, 3, 3, 0, 1, 1, 0, 1, 1 }; - { "test1", "bytes", 1, 21, 0, 3, 3, 0, 1, 1, 0, 0, 0 }; - { "test1", "bytes", 1, 22, 0, 3, 3, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 24, 0, 2, 2, 0, 1, 1, 0, 0, 0 }; - { "test1", "bytes", 1, 25, 0, 2, 2, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 27, 0, 1, 1, 0, 1, 1, 0, 0, 0 }; - { "test1", "bytes", 1, 28, 0, 1, 1, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 30, 0, 0, 0, 0, 1, 1, 0, 0, 0 }; - { "test1", "bytes", 1, 31, 0, 0, 0, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 33, 0, 0, 0, 0, 4, 4, 0, 1, 1 }; + feed('gR<tab><tab>') + check_events { + { 'test1', 'bytes', 1, 17, 0, 0, 0, 0, 1, 1, 0, 1, 1 }, + { 'test1', 'bytes', 1, 18, 0, 1, 1, 0, 1, 1, 0, 1, 1 }, + { 'test1', 'bytes', 1, 19, 0, 2, 2, 0, 1, 1, 0, 1, 1 }, + { 'test1', 'bytes', 1, 20, 0, 3, 3, 0, 1, 1, 0, 1, 1 }, + { 'test1', 'bytes', 1, 21, 0, 3, 3, 0, 1, 1, 0, 0, 0 }, + { 'test1', 'bytes', 1, 22, 0, 3, 3, 0, 0, 0, 0, 1, 1 }, + { 'test1', 'bytes', 1, 24, 0, 2, 2, 0, 1, 1, 0, 0, 0 }, + { 'test1', 'bytes', 1, 25, 0, 2, 2, 0, 0, 0, 0, 1, 1 }, + { 'test1', 'bytes', 1, 27, 0, 1, 1, 0, 1, 1, 0, 0, 0 }, + { 'test1', 'bytes', 1, 28, 0, 1, 1, 0, 0, 0, 0, 1, 1 }, + { 'test1', 'bytes', 1, 30, 0, 0, 0, 0, 1, 1, 0, 0, 0 }, + { 'test1', 'bytes', 1, 31, 0, 0, 0, 0, 0, 0, 0, 1, 1 }, + { 'test1', 'bytes', 1, 33, 0, 0, 0, 0, 4, 4, 0, 1, 1 }, } -- inserting tab after other tabs - command("set sw=4") - feed("<esc>0a<tab>") + command('set sw=4') + feed('<esc>0a<tab>') check_events { - { "test1", "bytes", 1, 34, 0, 1, 1, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 35, 0, 2, 2, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 36, 0, 3, 3, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 37, 0, 4, 4, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 38, 0, 1, 1, 0, 4, 4, 0, 1, 1 }; + { 'test1', 'bytes', 1, 34, 0, 1, 1, 0, 0, 0, 0, 1, 1 }, + { 'test1', 'bytes', 1, 35, 0, 2, 2, 0, 0, 0, 0, 1, 1 }, + { 'test1', 'bytes', 1, 36, 0, 3, 3, 0, 0, 0, 0, 1, 1 }, + { 'test1', 'bytes', 1, 37, 0, 4, 4, 0, 0, 0, 0, 1, 1 }, + { 'test1', 'bytes', 1, 38, 0, 1, 1, 0, 4, 4, 0, 1, 1 }, } end) - it("retab", function() - command("set noet") - command("set ts=4") + it('retab', function() + command('set noet') + command('set ts=4') - local check_events = setup_eventcheck(verify, {" asdf"}) - command("retab 8") + local check_events = setup_eventcheck(verify, { ' asdf' }) + command('retab 8') check_events { - { "test1", "bytes", 1, 3, 0, 0, 0, 0, 7, 7, 0, 9, 9 }; + { 'test1', 'bytes', 1, 3, 0, 0, 0, 0, 7, 7, 0, 9, 9 }, } end) - it("sends events when undoing with undofile", function() - write_file("Xtest-undofile", dedent([[ + it('sends events when undoing with undofile', function() + write_file( + 'Xtest-undofile', + dedent([[ 12345 hello world - ]])) + ]]) + ) - command("e! Xtest-undofile") - command("set undodir=. | set undofile") + command('e! Xtest-undofile') + command('set undodir=. | set undofile') - local ns = helpers.request('nvim_create_namespace', "ns1") - meths.buf_set_extmark(0, ns, 0, 0, {}) + local ns = helpers.request('nvim_create_namespace', 'ns1') + api.nvim_buf_set_extmark(0, ns, 0, 0, {}) - eq({"12345", "hello world"}, meths.buf_get_lines(0, 0, -1, true)) + eq({ '12345', 'hello world' }, api.nvim_buf_get_lines(0, 0, -1, true)) -- splice - feed("gg0d2l") + feed('gg0d2l') - eq({"345", "hello world"}, meths.buf_get_lines(0, 0, -1, true)) + eq({ '345', 'hello world' }, api.nvim_buf_get_lines(0, 0, -1, true)) -- move - command(".m+1") + command('.m+1') - eq({"hello world", "345"}, meths.buf_get_lines(0, 0, -1, true)) + eq({ 'hello world', '345' }, api.nvim_buf_get_lines(0, 0, -1, true)) -- reload undofile and undo changes - command("w") - command("set noundofile") - command("bw!") - command("e! Xtest-undofile") + command('w') + command('set noundofile') + command('bw!') + command('e! Xtest-undofile') - command("set undofile") + command('set undofile') local check_events = setup_eventcheck(verify, nil) - feed("u") - eq({"345", "hello world"}, meths.buf_get_lines(0, 0, -1, true)) + feed('u') + eq({ '345', 'hello world' }, api.nvim_buf_get_lines(0, 0, -1, true)) check_events { - { "test1", "bytes", 2, 6, 1, 0, 12, 1, 0, 4, 0, 0, 0 }, - { "test1", "bytes", 2, 6, 0, 0, 0, 0, 0, 0, 1, 0, 4 } + { 'test1', 'bytes', 2, 6, 1, 0, 12, 1, 0, 4, 0, 0, 0 }, + { 'test1', 'bytes', 2, 6, 0, 0, 0, 0, 0, 0, 1, 0, 4 }, } - feed("u") - eq({"12345", "hello world"}, meths.buf_get_lines(0, 0, -1, true)) + feed('u') + eq({ '12345', 'hello world' }, api.nvim_buf_get_lines(0, 0, -1, true)) check_events { - { "test1", "bytes", 2, 8, 0, 0, 0, 0, 0, 0, 0, 2, 2 } + { 'test1', 'bytes', 2, 8, 0, 0, 0, 0, 0, 0, 0, 2, 2 }, } - command("bw!") + command('bw!') end) - it("blockwise paste with uneven line lengths", function() - local check_events = setup_eventcheck(verify, {'aaaa', 'aaa', 'aaa'}) + it('blockwise paste with uneven line lengths', function() + local check_events = setup_eventcheck(verify, { 'aaaa', 'aaa', 'aaa' }) - -- eq({}, meths.buf_get_lines(0, 0, -1, true)) - feed("gg0<c-v>jj$d") + -- eq({}, api.nvim_buf_get_lines(0, 0, -1, true)) + feed('gg0<c-v>jj$d') check_events { - { "test1", "bytes", 1, 3, 0, 0, 0, 0, 4, 4, 0, 0, 0 }, - { "test1", "bytes", 1, 3, 1, 0, 1, 0, 3, 3, 0, 0, 0 }, - { "test1", "bytes", 1, 3, 2, 0, 2, 0, 3, 3, 0, 0, 0 }, + { 'test1', 'bytes', 1, 3, 0, 0, 0, 0, 4, 4, 0, 0, 0 }, + { 'test1', 'bytes', 1, 3, 1, 0, 1, 0, 3, 3, 0, 0, 0 }, + { 'test1', 'bytes', 1, 3, 2, 0, 2, 0, 3, 3, 0, 0, 0 }, } - feed("p") + feed('p') check_events { - { "test1", "bytes", 1, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4 }, - { "test1", "bytes", 1, 4, 1, 0, 5, 0, 0, 0, 0, 3, 3 }, - { "test1", "bytes", 1, 4, 2, 0, 9, 0, 0, 0, 0, 3, 3 }, + { 'test1', 'bytes', 1, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4 }, + { 'test1', 'bytes', 1, 4, 1, 0, 5, 0, 0, 0, 0, 3, 3 }, + { 'test1', 'bytes', 1, 4, 2, 0, 9, 0, 0, 0, 0, 3, 3 }, } - end) - it(":luado", function() - local check_events = setup_eventcheck(verify, {"abc", "12345"}) + it(':luado', function() + local check_events = setup_eventcheck(verify, { 'abc', '12345' }) command(".luado return 'a'") check_events { - { "test1", "bytes", 1, 3, 0, 0, 0, 0, 3, 3, 0, 1, 1 }; + { 'test1', 'bytes', 1, 3, 0, 0, 0, 0, 3, 3, 0, 1, 1 }, } - command("luado return 10") + command('luado return 10') check_events { - { "test1", "bytes", 1, 4, 0, 0, 0, 0, 1, 1, 0, 2, 2 }; - { "test1", "bytes", 1, 5, 1, 0, 3, 0, 5, 5, 0, 2, 2 }; + { 'test1', 'bytes', 1, 4, 0, 0, 0, 0, 1, 1, 0, 2, 2 }, + { 'test1', 'bytes', 1, 5, 1, 0, 3, 0, 5, 5, 0, 2, 2 }, } - end) - it("flushes deleted bytes on move", function() - local check_events = setup_eventcheck(verify, {"AAA", "BBB", "CCC", "DDD"}) + it('flushes deleted bytes on move', function() + local check_events = setup_eventcheck(verify, { 'AAA', 'BBB', 'CCC', 'DDD' }) - feed(":.move+1<cr>") + feed(':.move+1<cr>') check_events { - { "test1", "bytes", 1, 5, 0, 0, 0, 1, 0, 4, 0, 0, 0 }; - { "test1", "bytes", 1, 5, 1, 0, 4, 0, 0, 0, 1, 0, 4 }; + { 'test1', 'bytes', 1, 5, 0, 0, 0, 1, 0, 4, 0, 0, 0 }, + { 'test1', 'bytes', 1, 5, 1, 0, 4, 0, 0, 0, 1, 0, 4 }, } - feed("jd2j") + feed('jd2j') check_events { - { "test1", "bytes", 1, 6, 2, 0, 8, 2, 0, 8, 0, 0, 0 }; + { 'test1', 'bytes', 1, 6, 2, 0, 8, 2, 0, 8, 0, 0, 0 }, } end) - it("virtual edit", function () - local check_events = setup_eventcheck(verify, { "", " " }) + it('virtual edit', function() + local check_events = setup_eventcheck(verify, { '', ' ' }) - meths.set_option_value('virtualedit', "all", {}) + api.nvim_set_option_value('virtualedit', 'all', {}) feed [[<Right><Right>iab<ESC>]] check_events { - { "test1", "bytes", 1, 3, 0, 0, 0, 0, 0, 0, 0, 2, 2 }; - { "test1", "bytes", 1, 4, 0, 2, 2, 0, 0, 0, 0, 2, 2 }; + { 'test1', 'bytes', 1, 3, 0, 0, 0, 0, 0, 0, 0, 2, 2 }, + { 'test1', 'bytes', 1, 4, 0, 2, 2, 0, 0, 0, 0, 2, 2 }, } feed [[j<Right><Right>iab<ESC>]] check_events { - { "test1", "bytes", 1, 5, 1, 0, 5, 0, 1, 1, 0, 8, 8 }; - { "test1", "bytes", 1, 6, 1, 5, 10, 0, 0, 0, 0, 2, 2 }; + { 'test1', 'bytes', 1, 5, 1, 0, 5, 0, 1, 1, 0, 8, 8 }, + { 'test1', 'bytes', 1, 6, 1, 5, 10, 0, 0, 0, 0, 2, 2 }, } end) - it("block visual paste", function() - local check_events = setup_eventcheck(verify, {"AAA", - "BBB", - "CCC", - "DDD", - "EEE", - "FFF"}) - funcs.setreg("a", "___") + it('block visual paste', function() + local check_events = setup_eventcheck(verify, { 'AAA', 'BBB', 'CCC', 'DDD', 'EEE', 'FFF' }) + fn.setreg('a', '___') feed([[gg0l<c-v>3jl"ap]]) check_events { - { "test1", "bytes", 1, 3, 0, 1, 1, 0, 2, 2, 0, 0, 0 }; - { "test1", "bytes", 1, 3, 1, 1, 3, 0, 2, 2, 0, 0, 0 }; - { "test1", "bytes", 1, 3, 2, 1, 5, 0, 2, 2, 0, 0, 0 }; - { "test1", "bytes", 1, 3, 3, 1, 7, 0, 2, 2, 0, 0, 0 }; - { "test1", "bytes", 1, 5, 0, 1, 1, 0, 0, 0, 0, 3, 3 }; - { "test1", "bytes", 1, 6, 1, 1, 6, 0, 0, 0, 0, 3, 3 }; - { "test1", "bytes", 1, 7, 2, 1, 11, 0, 0, 0, 0, 3, 3 }; - { "test1", "bytes", 1, 8, 3, 1, 16, 0, 0, 0, 0, 3, 3 }; + { 'test1', 'bytes', 1, 3, 0, 1, 1, 0, 2, 2, 0, 0, 0 }, + { 'test1', 'bytes', 1, 3, 1, 1, 3, 0, 2, 2, 0, 0, 0 }, + { 'test1', 'bytes', 1, 3, 2, 1, 5, 0, 2, 2, 0, 0, 0 }, + { 'test1', 'bytes', 1, 3, 3, 1, 7, 0, 2, 2, 0, 0, 0 }, + { 'test1', 'bytes', 1, 5, 0, 1, 1, 0, 0, 0, 0, 3, 3 }, + { 'test1', 'bytes', 1, 6, 1, 1, 6, 0, 0, 0, 0, 3, 3 }, + { 'test1', 'bytes', 1, 7, 2, 1, 11, 0, 0, 0, 0, 3, 3 }, + { 'test1', 'bytes', 1, 8, 3, 1, 16, 0, 0, 0, 0, 3, 3 }, } end) - it("visual paste", function() - local check_events= setup_eventcheck(verify, { "aaa {", "b", "}" }) + it('visual paste', function() + local check_events = setup_eventcheck(verify, { 'aaa {', 'b', '}' }) -- Setting up - feed[[jdd]] + feed [[jdd]] check_events { - { "test1", "bytes", 1, 3, 1, 0, 6, 1, 0, 2, 0, 0, 0 }; + { 'test1', 'bytes', 1, 3, 1, 0, 6, 1, 0, 2, 0, 0, 0 }, } -- Actually testing - feed[[v%p]] + feed [[v%p]] + check_events { + { 'test1', 'bytes', 1, 8, 0, 4, 4, 1, 1, 3, 0, 0, 0 }, + { 'test1', 'bytes', 1, 8, 0, 4, 4, 0, 0, 0, 2, 0, 3 }, + } + end) + + it('visual paste 2: splitting an empty line', function() + local check_events = setup_eventcheck(verify, { 'abc', '{', 'def', '}' }) + feed('ggyyjjvi{p') check_events { - { "test1", "bytes", 1, 8, 0, 4, 4, 1, 1, 3, 0, 0, 0 }; - { "test1", "bytes", 1, 8, 0, 4, 4, 0, 0, 0, 2, 0, 3 }; + { 'test1', 'bytes', 1, 6, 2, 0, 6, 1, 0, 4, 0, 0, 0 }, + { 'test1', 'bytes', 1, 6, 2, 0, 6, 0, 0, 0, 2, 0, 5 }, } end) - it("nvim_buf_set_lines", function() - local check_events = setup_eventcheck(verify, {"AAA", "BBB"}) + it('nvim_buf_set_lines', function() + local check_events = setup_eventcheck(verify, { 'AAA', 'BBB' }) -- delete - meths.buf_set_lines(0, 0, 1, true, {}) + api.nvim_buf_set_lines(0, 0, 1, true, {}) check_events { - { "test1", "bytes", 1, 3, 0, 0, 0, 1, 0, 4, 0, 0, 0 }; + { 'test1', 'bytes', 1, 3, 0, 0, 0, 1, 0, 4, 0, 0, 0 }, } -- add - meths.buf_set_lines(0, 0, 0, true, {'asdf'}) + api.nvim_buf_set_lines(0, 0, 0, true, { 'asdf' }) check_events { - { "test1", "bytes", 1, 4, 0, 0, 0, 0, 0, 0, 1, 0, 5 }; + { 'test1', 'bytes', 1, 4, 0, 0, 0, 0, 0, 0, 1, 0, 5 }, } -- replace - meths.buf_set_lines(0, 0, 1, true, {'asdf', 'fdsa'}) + api.nvim_buf_set_lines(0, 0, 1, true, { 'asdf', 'fdsa' }) check_events { - { "test1", "bytes", 1, 5, 0, 0, 0, 1, 0, 5, 2, 0, 10 }; + { 'test1', 'bytes', 1, 5, 0, 0, 0, 1, 0, 5, 2, 0, 10 }, } end) - it("flushes delbytes on substitute", function() - local check_events = setup_eventcheck(verify, {"AAA", "BBB", "CCC"}) + it('flushes delbytes on substitute', function() + local check_events = setup_eventcheck(verify, { 'AAA', 'BBB', 'CCC' }) - feed("gg0") - command("s/AAA/GGG/") + feed('gg0') + command('s/AAA/GGG/') check_events { - { "test1", "bytes", 1, 3, 0, 0, 0, 0, 3, 3, 0, 3, 3 }; + { 'test1', 'bytes', 1, 3, 0, 0, 0, 0, 3, 3, 0, 3, 3 }, } -- check that byte updates for :delete (which uses curbuf->deleted_bytes2) -- are correct - command("delete") + command('delete') check_events { - { "test1", "bytes", 1, 4, 0, 0, 0, 1, 0, 4, 0, 0, 0 }; + { 'test1', 'bytes', 1, 4, 0, 0, 0, 1, 0, 4, 0, 0, 0 }, } end) - it("flushes delbytes on join", function() - local check_events = setup_eventcheck(verify, {"AAA", "BBB", "CCC"}) + it('flushes delbytes on join', function() + local check_events = setup_eventcheck(verify, { 'AAA', 'BBB', 'CCC' }) - feed("gg0J") + feed('gg0J') check_events { - { "test1", "bytes", 1, 3, 0, 3, 3, 1, 0, 1, 0, 1, 1 }; + { 'test1', 'bytes', 1, 3, 0, 3, 3, 1, 0, 1, 0, 1, 1 }, } - command("delete") + command('delete') check_events { - { "test1", "bytes", 1, 5, 0, 0, 0, 1, 0, 8, 0, 0, 0 }; + { 'test1', 'bytes', 1, 5, 0, 0, 0, 1, 0, 8, 0, 0, 0 }, } end) - it("sends updates on U", function() - feed("ggiAAA<cr>BBB") - feed("<esc>gg$a CCC") + it('sends updates on U', function() + feed('ggiAAA<cr>BBB') + feed('<esc>gg$a CCC') local check_events = setup_eventcheck(verify, nil) - feed("ggU") + feed('ggU') check_events { - { "test1", "bytes", 1, 6, 0, 7, 7, 0, 0, 0, 0, 3, 3 }; + { 'test1', 'bytes', 1, 6, 0, 7, 7, 0, 0, 0, 0, 3, 3 }, } end) - it("delete in completely empty buffer", function() + it('delete in completely empty buffer', function() local check_events = setup_eventcheck(verify, nil) - command "delete" - check_events { } + command 'delete' + check_events {} end) - it("delete the only line of a buffer", function() - local check_events = setup_eventcheck(verify, {"AAA"}) + it('delete the only line of a buffer', function() + local check_events = setup_eventcheck(verify, { 'AAA' }) - command "delete" + command 'delete' check_events { - { "test1", "bytes", 1, 3, 0, 0, 0, 1, 0, 4, 1, 0, 1 }; + { 'test1', 'bytes', 1, 3, 0, 0, 0, 1, 0, 4, 1, 0, 1 }, } end) - it("delete the last line of a buffer with two lines", function() - local check_events = setup_eventcheck(verify, {"AAA", "BBB"}) + it('delete the last line of a buffer with two lines', function() + local check_events = setup_eventcheck(verify, { 'AAA', 'BBB' }) - command "2delete" + command '2delete' check_events { - { "test1", "bytes", 1, 3, 1, 0, 4, 1, 0, 4, 0, 0, 0 }; + { 'test1', 'bytes', 1, 3, 1, 0, 4, 1, 0, 4, 0, 0, 0 }, } end) - it(":sort lines", function() - local check_events = setup_eventcheck(verify, {"CCC", "BBB", "AAA"}) + it(':sort lines', function() + local check_events = setup_eventcheck(verify, { 'CCC', 'BBB', 'AAA' }) - command "%sort" + command '%sort' check_events { - { "test1", "bytes", 1, 3, 0, 0, 0, 3, 0, 12, 3, 0, 12 }; + { 'test1', 'bytes', 1, 3, 0, 0, 0, 3, 0, 12, 3, 0, 12 }, } end) - it("handles already sorted lines", function() - local check_events = setup_eventcheck(verify, {"AAA", "BBB", "CCC"}) + it('handles already sorted lines', function() + local check_events = setup_eventcheck(verify, { 'AAA', 'BBB', 'CCC' }) - command "%sort" - check_events { } + command '%sort' + check_events {} end) - it("works with accepting spell suggestions", function() - local check_events = setup_eventcheck(verify, {"hallo world", "hallo world"}) + it('works with accepting spell suggestions', function() + local check_events = setup_eventcheck(verify, { 'hallo world', 'hallo world' }) - feed("gg0z=4<cr><cr>") -- accepts 'Hello' + feed('gg0z=4<cr><cr>') -- accepts 'Hello' check_events { - { "test1", "bytes", 1, 3, 0, 0, 0, 0, 2, 2, 0, 2, 2 }; + { 'test1', 'bytes', 1, 3, 0, 0, 0, 0, 2, 2, 0, 2, 2 }, } - command("spellrepall") -- replaces whole words + command('spellrepall') -- replaces whole words check_events { - { "test1", "bytes", 1, 4, 1, 0, 12, 0, 5, 5, 0, 5, 5 }; + { 'test1', 'bytes', 1, 4, 1, 0, 12, 0, 5, 5, 0, 5, 5 }, } end) it('works with :diffput and :diffget', function() - local check_events = setup_eventcheck(verify, {"AAA"}) + local check_events = setup_eventcheck(verify, { 'AAA' }) command('diffthis') command('new') command('diffthis') - meths.buf_set_lines(0, 0, -1, true, {"AAA", "BBB"}) + api.nvim_buf_set_lines(0, 0, -1, true, { 'AAA', 'BBB' }) feed('G') command('diffput') check_events { - { "test1", "bytes", 1, 3, 1, 0, 4, 0, 0, 0, 1, 0, 4 }; + { 'test1', 'bytes', 1, 3, 1, 0, 4, 0, 0, 0, 1, 0, 4 }, } - meths.buf_set_lines(0, 0, -1, true, {"AAA", "CCC"}) + api.nvim_buf_set_lines(0, 0, -1, true, { 'AAA', 'CCC' }) feed('<C-w>pG') command('diffget') check_events { - { "test1", "bytes", 1, 4, 1, 0, 4, 1, 0, 4, 1, 0, 4 }; + { 'test1', 'bytes', 1, 4, 1, 0, 4, 1, 0, 4, 1, 0, 4 }, } end) local function test_lockmarks(mode) - local description = (mode ~= "") and mode or "(baseline)" - it("test_lockmarks " .. description .. " %delete _", function() - local check_events = setup_eventcheck(verify, {"AAA", "BBB", "CCC"}) + local description = (mode ~= '') and mode or '(baseline)' + it('test_lockmarks ' .. description .. ' %delete _', function() + local check_events = setup_eventcheck(verify, { 'AAA', 'BBB', 'CCC' }) - command(mode .. " %delete _") + command(mode .. ' %delete _') check_events { - { "test1", "bytes", 1, 3, 0, 0, 0, 3, 0, 12, 1, 0, 1 }; + { 'test1', 'bytes', 1, 3, 0, 0, 0, 3, 0, 12, 1, 0, 1 }, } end) - it("test_lockmarks " .. description .. " append()", function() + it('test_lockmarks ' .. description .. ' append()', function() local check_events = setup_eventcheck(verify) command(mode .. " call append(0, 'CCC')") check_events { - { "test1", "bytes", 1, 2, 0, 0, 0, 0, 0, 0, 1, 0, 4 }; + { 'test1', 'bytes', 1, 2, 0, 0, 0, 0, 0, 0, 1, 0, 4 }, } command(mode .. " call append(1, 'BBBB')") check_events { - { "test1", "bytes", 1, 3, 1, 0, 4, 0, 0, 0, 1, 0, 5 }; + { 'test1', 'bytes', 1, 3, 1, 0, 4, 0, 0, 0, 1, 0, 5 }, } command(mode .. " call append(2, '')") check_events { - { "test1", "bytes", 1, 4, 2, 0, 9, 0, 0, 0, 1, 0, 1 }; + { 'test1', 'bytes', 1, 4, 2, 0, 9, 0, 0, 0, 1, 0, 1 }, } - command(mode .. " $delete _") + command(mode .. ' $delete _') check_events { - { "test1", "bytes", 1, 5, 3, 0, 10, 1, 0, 1, 0, 0, 0 }; + { 'test1', 'bytes', 1, 5, 3, 0, 10, 1, 0, 1, 0, 0, 0 }, } - eq("CCC|BBBB|", table.concat(meths.buf_get_lines(0, 0, -1, true), "|")) + eq('CCC|BBBB|', table.concat(api.nvim_buf_get_lines(0, 0, -1, true), '|')) end) end -- check that behavior is identical with and without "lockmarks" - test_lockmarks "" - test_lockmarks "lockmarks" + test_lockmarks '' + test_lockmarks 'lockmarks' teardown(function() - os.remove "Xtest-reload" - os.remove "Xtest-undofile" - os.remove ".Xtest-undofile.un~" + os.remove 'Xtest-reload' + os.remove 'Xtest-undofile' + os.remove '.Xtest-undofile.un~' end) end @@ -1253,4 +1282,3 @@ describe('lua: nvim_buf_attach on_bytes', function() do_both(false) end) end) - diff --git a/test/functional/lua/command_line_completion_spec.lua b/test/functional/lua/command_line_completion_spec.lua index 177e077f4a..b88a38082f 100644 --- a/test/functional/lua/command_line_completion_spec.lua +++ b/test/functional/lua/command_line_completion_spec.lua @@ -5,34 +5,33 @@ local eq = helpers.eq local exec_lua = helpers.exec_lua local get_completions = function(input, env) - return exec_lua("return {vim._expand_pat(...)}", input, env) + return exec_lua('return {vim._expand_pat(...)}', input, env) end local get_compl_parts = function(parts) - return exec_lua("return {vim._expand_pat_get_parts(...)}", parts) + return exec_lua('return {vim._expand_pat_get_parts(...)}', parts) end before_each(clear) describe('nlua_expand_pat', function() it('should complete exact matches', function() - eq({{'exact'}, 0}, get_completions('exact', { exact = true })) + eq({ { 'exact' }, 0 }, get_completions('exact', { exact = true })) end) it('should return empty table when nothing matches', function() - eq({{}, 0}, get_completions('foo', { bar = true })) + eq({ {}, 0 }, get_completions('foo', { bar = true })) end) it('should return nice completions with function call prefix', function() - eq({{'FOO'}, 6}, get_completions('print(F', { FOO = true, bawr = true })) + eq({ { 'FOO' }, 6 }, get_completions('print(F', { FOO = true, bawr = true })) end) it('should return keys for nested dictionaries', function() eq( - {{ + { { 'nvim_buf_set_lines', - }, 8 - }, + }, 8 }, get_completions('vim.api.nvim_buf_', { vim = { api = { @@ -40,34 +39,32 @@ describe('nlua_expand_pat', function() nvim_win_doesnt_match = true, }, other_key = true, - } + }, }) ) end) it('it should work with colons', function() eq( - {{ + { { 'bawr', 'baz', - }, 8 - }, + }, 8 }, get_completions('MyClass:b', { MyClass = { baz = true, bawr = true, foo = false, - } + }, }) ) end) it('should return keys for string reffed dictionaries', function() eq( - {{ + { { 'nvim_buf_set_lines', - }, 11 - }, + }, 11 }, get_completions('vim["api"].nvim_buf_', { vim = { api = { @@ -75,17 +72,16 @@ describe('nlua_expand_pat', function() nvim_win_doesnt_match = true, }, other_key = true, - } + }, }) ) end) it('should return keys for string reffed dictionaries', function() eq( - {{ + { { 'nvim_buf_set_lines', - }, 21 - }, + }, 21 }, get_completions('vim["nested"]["api"].nvim_buf_', { vim = { nested = { @@ -95,80 +91,76 @@ describe('nlua_expand_pat', function() }, }, other_key = true, - } + }, }) ) end) it('should work with lazy submodules of "vim" global', function() - eq({{ 'inspect', 'inspect_pos' }, 4 }, - get_completions('vim.inspec')) + eq({ { 'inspect', 'inspect_pos' }, 4 }, get_completions('vim.inspec')) - eq({{ 'treesitter' }, 4 }, - get_completions('vim.treesi')) + eq({ { 'treesitter' }, 4 }, get_completions('vim.treesi')) - eq({{ 'set' }, 11 }, - get_completions('vim.keymap.se')) + eq({ { 'set' }, 11 }, get_completions('vim.keymap.se')) end) it('should be able to interpolate globals', function() eq( - {{ + { { 'nvim_buf_set_lines', - }, 12 - }, + }, 12 }, get_completions('vim[MY_VAR].nvim_buf_', { - MY_VAR = "api", + MY_VAR = 'api', vim = { api = { nvim_buf_set_lines = true, nvim_win_doesnt_match = true, }, other_key = true, - } + }, }) ) end) it('should return everything if the input is of length 0', function() - eq({{"other", "vim"}, 0}, get_completions('', { vim = true, other = true })) + eq({ { 'other', 'vim' }, 0 }, get_completions('', { vim = true, other = true })) end) describe('get_parts', function() it('should return an empty list for no separators', function() - eq({{}, 1}, get_compl_parts("vim")) + eq({ {}, 1 }, get_compl_parts('vim')) end) it('just the first item before a period', function() - eq({{"vim"}, 5}, get_compl_parts("vim.ap")) + eq({ { 'vim' }, 5 }, get_compl_parts('vim.ap')) end) it('should return multiple parts just for period', function() - eq({{"vim", "api"}, 9}, get_compl_parts("vim.api.nvim_buf")) + eq({ { 'vim', 'api' }, 9 }, get_compl_parts('vim.api.nvim_buf')) end) it('should be OK with colons', function() - eq({{"vim", "api"}, 9}, get_compl_parts("vim:api.nvim_buf")) + eq({ { 'vim', 'api' }, 9 }, get_compl_parts('vim:api.nvim_buf')) end) it('should work for just one string ref', function() - eq({{"vim", "api"}, 12}, get_compl_parts("vim['api'].nvim_buf")) + eq({ { 'vim', 'api' }, 12 }, get_compl_parts("vim['api'].nvim_buf")) end) it('should work for just one string ref, with double quote', function() - eq({{"vim", "api"}, 12}, get_compl_parts('vim["api"].nvim_buf')) + eq({ { 'vim', 'api' }, 12 }, get_compl_parts('vim["api"].nvim_buf')) end) it('should allows back-to-back string ref', function() - eq({{"vim", "nested", "api"}, 22}, get_compl_parts('vim["nested"]["api"].nvim_buf')) + eq({ { 'vim', 'nested', 'api' }, 22 }, get_compl_parts('vim["nested"]["api"].nvim_buf')) end) it('should allows back-to-back string ref with spaces before and after', function() - eq({{"vim", "nested", "api"}, 25}, get_compl_parts('vim[ "nested" ]["api"].nvim_buf')) + eq({ { 'vim', 'nested', 'api' }, 25 }, get_compl_parts('vim[ "nested" ]["api"].nvim_buf')) end) it('should allow VAR style loolup', function() - eq({{"vim", {"NESTED"}, "api"}, 20}, get_compl_parts('vim[NESTED]["api"].nvim_buf')) + eq({ { 'vim', { 'NESTED' }, 'api' }, 20 }, get_compl_parts('vim[NESTED]["api"].nvim_buf')) end) end) end) diff --git a/test/functional/lua/commands_spec.lua b/test/functional/lua/commands_spec.lua index fca619348d..b8d0638ce5 100644 --- a/test/functional/lua/commands_spec.lua +++ b/test/functional/lua/commands_spec.lua @@ -3,106 +3,124 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local eq = helpers.eq -local NIL = helpers.NIL +local NIL = vim.NIL local eval = helpers.eval local feed = helpers.feed local clear = helpers.clear local matches = helpers.matches -local meths = helpers.meths +local api = helpers.api local exec_lua = helpers.exec_lua local exec_capture = helpers.exec_capture -local funcs = helpers.funcs +local fn = helpers.fn local source = helpers.source local dedent = helpers.dedent local command = helpers.command local exc_exec = helpers.exc_exec local pcall_err = helpers.pcall_err local write_file = helpers.write_file -local curbufmeths = helpers.curbufmeths local remove_trace = helpers.remove_trace before_each(clear) -describe(':lua command', function() +describe(':lua', function() it('works', function() - eq('', exec_capture( - 'lua vim.api.nvim_buf_set_lines(1, 1, 2, false, {"TEST"})')) - eq({'', 'TEST'}, curbufmeths.get_lines(0, 100, false)) + eq('', exec_capture('lua vim.api.nvim_buf_set_lines(1, 1, 2, false, {"TEST"})')) + eq({ '', 'TEST' }, api.nvim_buf_get_lines(0, 0, 100, false)) source([[ lua << EOF vim.api.nvim_buf_set_lines(1, 1, 2, false, {"TSET"}) EOF]]) - eq({'', 'TSET'}, curbufmeths.get_lines(0, 100, false)) + eq({ '', 'TSET' }, api.nvim_buf_get_lines(0, 0, 100, false)) source([[ lua << EOF vim.api.nvim_buf_set_lines(1, 1, 2, false, {"SETT"})]]) - eq({'', 'SETT'}, curbufmeths.get_lines(0, 100, false)) + eq({ '', 'SETT' }, api.nvim_buf_get_lines(0, 0, 100, false)) source([[ lua << EOF vim.api.nvim_buf_set_lines(1, 1, 2, false, {"ETTS"}) vim.api.nvim_buf_set_lines(1, 2, 3, false, {"TTSE"}) vim.api.nvim_buf_set_lines(1, 3, 4, false, {"STTE"}) EOF]]) - eq({'', 'ETTS', 'TTSE', 'STTE'}, curbufmeths.get_lines(0, 100, false)) - matches('.*Vim%(lua%):E15: Invalid expression: .*', pcall_err(source, [[ + eq({ '', 'ETTS', 'TTSE', 'STTE' }, api.nvim_buf_get_lines(0, 0, 100, false)) + matches( + '.*Vim%(lua%):E15: Invalid expression: .*', + pcall_err( + source, + [[ lua << eval EOF {} EOF - ]])) + ]] + ) + ) end) + it('throws catchable errors', function() - eq([[Vim(lua):E5107: Error loading lua [string ":lua"]:0: unexpected symbol near ')']], - pcall_err(command, 'lua ()')) - eq([[Vim(lua):E5108: Error executing lua [string ":lua"]:1: TEST]], - remove_trace(exc_exec('lua error("TEST")'))) - eq([[Vim(lua):E5108: Error executing lua [string ":lua"]:1: Invalid buffer id: -10]], - remove_trace(exc_exec('lua vim.api.nvim_buf_set_lines(-10, 1, 1, false, {"TEST"})'))) - eq({''}, curbufmeths.get_lines(0, 100, false)) + eq('Vim(lua):E471: Argument required', pcall_err(command, 'lua')) + eq( + [[Vim(lua):E5107: Error loading lua [string ":lua"]:0: unexpected symbol near ')']], + pcall_err(command, 'lua ()') + ) + eq( + [[Vim(lua):E5108: Error executing lua [string ":lua"]:1: TEST]], + remove_trace(exc_exec('lua error("TEST")')) + ) + eq( + [[Vim(lua):E5108: Error executing lua [string ":lua"]:1: Invalid buffer id: -10]], + remove_trace(exc_exec('lua vim.api.nvim_buf_set_lines(-10, 1, 1, false, {"TEST"})')) + ) + eq({ '' }, api.nvim_buf_get_lines(0, 0, 100, false)) end) + it('works with NULL errors', function() - eq([=[Vim(lua):E5108: Error executing lua [NULL]]=], - exc_exec('lua error(nil)')) + eq([=[Vim(lua):E5108: Error executing lua [NULL]]=], exc_exec('lua error(nil)')) end) + it('accepts embedded NLs without heredoc', function() -- Such code is usually used for `:execute 'lua' {generated_string}`: -- heredocs do not work in this case. - meths.command([[ + command([[ lua vim.api.nvim_buf_set_lines(1, 1, 2, false, {"ETTS"}) vim.api.nvim_buf_set_lines(1, 2, 3, false, {"TTSE"}) vim.api.nvim_buf_set_lines(1, 3, 4, false, {"STTE"}) ]]) - eq({'', 'ETTS', 'TTSE', 'STTE'}, curbufmeths.get_lines(0, 100, false)) + eq({ '', 'ETTS', 'TTSE', 'STTE' }, api.nvim_buf_get_lines(0, 0, 100, false)) end) + it('preserves global and not preserves local variables', function() eq('', exec_capture('lua gvar = 42')) eq('', exec_capture('lua local lvar = 100500')) - eq(NIL, funcs.luaeval('lvar')) - eq(42, funcs.luaeval('gvar')) + eq(NIL, fn.luaeval('lvar')) + eq(42, fn.luaeval('gvar')) end) + it('works with long strings', function() local s = ('x'):rep(100500) - eq('Vim(lua):E5107: Error loading lua [string ":lua"]:0: unfinished string near \'<eof>\'', - pcall_err(command, ('lua vim.api.nvim_buf_set_lines(1, 1, 2, false, {"%s})'):format(s))) - eq({''}, curbufmeths.get_lines(0, -1, false)) + eq( + 'Vim(lua):E5107: Error loading lua [string ":lua"]:0: unfinished string near \'<eof>\'', + pcall_err(command, ('lua vim.api.nvim_buf_set_lines(1, 1, 2, false, {"%s})'):format(s)) + ) + eq({ '' }, api.nvim_buf_get_lines(0, 0, -1, false)) eq('', exec_capture(('lua vim.api.nvim_buf_set_lines(1, 1, 2, false, {"%s"})'):format(s))) - eq({'', s}, curbufmeths.get_lines(0, -1, false)) + eq({ '', s }, api.nvim_buf_get_lines(0, 0, -1, false)) end) it('can show multiline error messages', function() - local screen = Screen.new(40,10) + local screen = Screen.new(40, 10) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {bold = true, reverse = true}, - [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [4] = {bold = true, foreground = Screen.colors.SeaGreen4}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { bold = true, reverse = true }, + [3] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen4 }, }) feed(':lua error("fail\\nmuch error\\nsuch details")<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2: }| {3:E5108: Error executing lua [string ":lua}| {3:"]:1: fail} | @@ -113,29 +131,30 @@ describe(':lua command', function() {3: [string ":lua"]:1: in main chunk}| | {4:Press ENTER or type command to continue}^ | - ]]} + ]], + } feed('<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 | - ]]} - eq('E5108: Error executing lua [string ":lua"]:1: fail\nmuch error\nsuch details', remove_trace(eval('v:errmsg'))) + ]], + } + eq( + 'E5108: Error executing lua [string ":lua"]:1: fail\nmuch error\nsuch details', + remove_trace(eval('v:errmsg')) + ) - local status, err = pcall(command,'lua error("some error\\nin a\\nAPI command")') - local expected = 'Vim(lua):E5108: Error executing lua [string ":lua"]:1: some error\nin a\nAPI command' + local status, err = pcall(command, 'lua error("some error\\nin a\\nAPI command")') + local expected = + 'Vim(lua):E5108: Error executing lua [string ":lua"]:1: some error\nin a\nAPI command' eq(false, status) eq(expected, string.sub(remove_trace(err), -string.len(expected))) feed(':messages<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2: }| {3:E5108: Error executing lua [string ":lua}| {3:"]:1: fail} | @@ -146,17 +165,18 @@ describe(':lua command', function() {3: [string ":lua"]:1: in main chunk}| | {4:Press ENTER or type command to continue}^ | - ]]} + ]], + } end) it('prints result of =expr', function() - exec_lua("x = 5") - eq("5", exec_capture(':lua =x')) - eq("5", exec_capture('=x')) + exec_lua('x = 5') + eq('5', exec_capture(':lua =x')) + eq('5', exec_capture('=x')) exec_lua("function x() return 'hello' end") eq('hello', exec_capture(':lua = x()')) - exec_lua("x = {a = 1, b = 2}") - eq("{\n a = 1,\n b = 2\n}", exec_capture(':lua =x')) + exec_lua('x = {a = 1, b = 2}') + eq('{\n a = 1,\n b = 2\n}', exec_capture(':lua =x')) exec_lua([[function x(success) if success then return true, "Return value" @@ -164,69 +184,127 @@ describe(':lua command', function() return false, nil, "Error message" end end]]) - eq(dedent[[ + eq( + dedent [[ true Return value]], - exec_capture(':lua =x(true)')) - eq(dedent[[ + exec_capture(':lua =x(true)') + ) + eq( + dedent [[ false nil Error message]], - exec_capture('=x(false)')) + exec_capture('=x(false)') + ) + end) + + it('with range', function() + local screen = Screen.new(40, 10) + screen:attach() + api.nvim_buf_set_lines(0, 0, 0, 0, { 'nonsense', 'function x() print "hello" end', 'x()' }) + + -- ":{range}lua" fails on invalid Lua code. + eq( + [[:{range}lua: Vim(lua):E5107: Error loading lua [string ":{range}lua"]:0: '=' expected near '<eof>']], + pcall_err(command, '1lua') + ) + + -- ":{range}lua" executes valid Lua code. + feed(':2,3lua<CR>') + screen:expect { + grid = [[ + nonsense | + function x() print "hello" end | + x() | + ^ | + {1:~ }|*5 + hello | + ]], + attr_ids = { + [1] = { foreground = Screen.colors.Blue, bold = true }, + }, + } + + -- ":{range}lua {code}" executes {code}, ignoring {range} + eq('', exec_capture('1lua gvar = 42')) + eq(42, fn.luaeval('gvar')) end) end) describe(':luado command', function() it('works', function() - curbufmeths.set_lines(0, 1, false, {"ABC", "def", "gHi"}) + api.nvim_buf_set_lines(0, 0, 1, false, { 'ABC', 'def', 'gHi' }) eq('', exec_capture('luado lines = (lines or {}) lines[#lines + 1] = {linenr, line}')) - eq({'ABC', 'def', 'gHi'}, curbufmeths.get_lines(0, -1, false)) - eq({{1, 'ABC'}, {2, 'def'}, {3, 'gHi'}}, funcs.luaeval('lines')) + eq({ 'ABC', 'def', 'gHi' }, api.nvim_buf_get_lines(0, 0, -1, false)) + eq({ { 1, 'ABC' }, { 2, 'def' }, { 3, 'gHi' } }, fn.luaeval('lines')) -- Automatic transformation of numbers eq('', exec_capture('luado return linenr')) - eq({'1', '2', '3'}, curbufmeths.get_lines(0, -1, false)) + eq({ '1', '2', '3' }, api.nvim_buf_get_lines(0, 0, -1, false)) eq('', exec_capture('luado return ("<%02x>"):format(line:byte())')) - eq({'<31>', '<32>', '<33>'}, curbufmeths.get_lines(0, -1, false)) + eq({ '<31>', '<32>', '<33>' }, api.nvim_buf_get_lines(0, 0, -1, false)) end) + it('stops processing lines when suddenly out of lines', function() - curbufmeths.set_lines(0, 1, false, {"ABC", "def", "gHi"}) + api.nvim_buf_set_lines(0, 0, 1, false, { 'ABC', 'def', 'gHi' }) eq('', exec_capture('2,$luado runs = ((runs or 0) + 1) vim.api.nvim_command("%d")')) - eq({''}, curbufmeths.get_lines(0, -1, false)) - eq(1, funcs.luaeval('runs')) - end) - it('works correctly when changing lines out of range', function() - curbufmeths.set_lines(0, 1, false, {"ABC", "def", "gHi"}) - eq('Vim(luado):E322: Line number out of range: 1 past the end', - pcall_err(command, '2,$luado vim.api.nvim_command("%d") return linenr')) - eq({''}, curbufmeths.get_lines(0, -1, false)) + eq({ '' }, api.nvim_buf_get_lines(0, 0, -1, false)) + eq(1, fn.luaeval('runs')) + + api.nvim_buf_set_lines(0, 0, -1, false, { 'one', 'two', 'three' }) + eq('', exec_capture('luado vim.api.nvim_command("%d")')) + eq({ '' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + api.nvim_buf_set_lines(0, 0, -1, false, { 'one', 'two', 'three' }) + eq('', exec_capture('luado vim.api.nvim_command("1,2d")')) + eq({ 'three' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + api.nvim_buf_set_lines(0, 0, -1, false, { 'one', 'two', 'three' }) + eq('', exec_capture('luado vim.api.nvim_command("2,3d"); return "REPLACED"')) + eq({ 'REPLACED' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + api.nvim_buf_set_lines(0, 0, -1, false, { 'one', 'two', 'three' }) + eq('', exec_capture('2,3luado vim.api.nvim_command("1,2d"); return "REPLACED"')) + eq({ 'three' }, api.nvim_buf_get_lines(0, 0, -1, false)) end) + it('fails on errors', function() - eq([[Vim(luado):E5109: Error loading lua: [string ":luado"]:0: unexpected symbol near ')']], - pcall_err(command, 'luado ()')) - eq([[Vim(luado):E5111: Error calling lua: [string ":luado"]:0: attempt to perform arithmetic on global 'liness' (a nil value)]], - pcall_err(command, 'luado return liness + 1')) + eq( + [[Vim(luado):E5109: Error loading lua: [string ":luado"]:0: unexpected symbol near ')']], + pcall_err(command, 'luado ()') + ) + eq( + [[Vim(luado):E5111: Error calling lua: [string ":luado"]:0: attempt to perform arithmetic on global 'liness' (a nil value)]], + pcall_err(command, 'luado return liness + 1') + ) end) + it('works with NULL errors', function() - eq([=[Vim(luado):E5111: Error calling lua: [NULL]]=], - exc_exec('luado error(nil)')) + eq([=[Vim(luado):E5111: Error calling lua: [NULL]]=], exc_exec('luado error(nil)')) end) + it('fails in sandbox when needed', function() - curbufmeths.set_lines(0, 1, false, {"ABC", "def", "gHi"}) - eq('Vim(luado):E48: Not allowed in sandbox: sandbox luado runs = (runs or 0) + 1', - pcall_err(command, 'sandbox luado runs = (runs or 0) + 1')) - eq(NIL, funcs.luaeval('runs')) + api.nvim_buf_set_lines(0, 0, 1, false, { 'ABC', 'def', 'gHi' }) + eq( + 'Vim(luado):E48: Not allowed in sandbox: sandbox luado runs = (runs or 0) + 1', + pcall_err(command, 'sandbox luado runs = (runs or 0) + 1') + ) + eq(NIL, fn.luaeval('runs')) end) + it('works with long strings', function() local s = ('x'):rep(100500) - eq('Vim(luado):E5109: Error loading lua: [string ":luado"]:0: unfinished string near \'<eof>\'', - pcall_err(command, ('luado return "%s'):format(s))) - eq({''}, curbufmeths.get_lines(0, -1, false)) + eq( + 'Vim(luado):E5109: Error loading lua: [string ":luado"]:0: unfinished string near \'<eof>\'', + pcall_err(command, ('luado return "%s'):format(s)) + ) + eq({ '' }, api.nvim_buf_get_lines(0, 0, -1, false)) eq('', exec_capture(('luado return "%s"'):format(s))) - eq({s}, curbufmeths.get_lines(0, -1, false)) + eq({ s }, api.nvim_buf_get_lines(0, 0, -1, false)) end) end) @@ -238,26 +316,40 @@ describe(':luafile', function() end) it('works', function() - write_file(fname, [[ + write_file( + fname, + [[ vim.api.nvim_buf_set_lines(1, 1, 2, false, {"ETTS"}) vim.api.nvim_buf_set_lines(1, 2, 3, false, {"TTSE"}) vim.api.nvim_buf_set_lines(1, 3, 4, false, {"STTE"}) - ]]) + ]] + ) eq('', exec_capture('luafile ' .. fname)) - eq({'', 'ETTS', 'TTSE', 'STTE'}, curbufmeths.get_lines(0, 100, false)) + eq({ '', 'ETTS', 'TTSE', 'STTE' }, api.nvim_buf_get_lines(0, 0, 100, false)) end) it('correctly errors out', function() write_file(fname, '()') - eq(("Vim(luafile):E5112: Error while creating lua chunk: %s:1: unexpected symbol near ')'"):format(fname), - exc_exec('luafile ' .. fname)) + eq( + ("Vim(luafile):E5112: Error while creating lua chunk: %s:1: unexpected symbol near ')'"):format( + fname + ), + exc_exec('luafile ' .. fname) + ) write_file(fname, 'vimm.api.nvim_buf_set_lines(1, 1, 2, false, {"ETTS"})') - eq(("Vim(luafile):E5113: Error while calling lua chunk: %s:1: attempt to index global 'vimm' (a nil value)"):format(fname), - remove_trace(exc_exec('luafile ' .. fname))) + eq( + ("Vim(luafile):E5113: Error while calling lua chunk: %s:1: attempt to index global 'vimm' (a nil value)"):format( + fname + ), + remove_trace(exc_exec('luafile ' .. fname)) + ) end) + it('works with NULL errors', function() write_file(fname, 'error(nil)') - eq([=[Vim(luafile):E5113: Error while calling lua chunk: [NULL]]=], - exc_exec('luafile ' .. fname)) + eq( + [=[Vim(luafile):E5113: Error while calling lua chunk: [NULL]]=], + exc_exec('luafile ' .. fname) + ) end) end) diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua index f061fac50a..5802925339 100644 --- a/test/functional/lua/diagnostic_spec.lua +++ b/test/functional/lua/diagnostic_spec.lua @@ -1,12 +1,12 @@ local helpers = require('test.functional.helpers')(after_each) -local NIL = helpers.NIL +local NIL = vim.NIL local command = helpers.command local clear = helpers.clear local exec_lua = helpers.exec_lua local eq = helpers.eq -local nvim = helpers.nvim local matches = helpers.matches +local api = helpers.api local pcall_err = helpers.pcall_err describe('vim.diagnostic', function() @@ -128,12 +128,20 @@ describe('vim.diagnostic', function() return vim.diagnostic.get() ]] eq(3, #result) - eq(2, exec_lua([[return #vim.tbl_filter(function(d) return d.bufnr == diagnostic_bufnr end, ...)]], result)) + eq( + 2, + exec_lua( + [[return #vim.tbl_filter(function(d) return d.bufnr == diagnostic_bufnr end, ...)]], + result + ) + ) eq('Diagnostic #1', result[1].message) end) it('removes diagnostics from the cache when a buffer is removed', function() - eq(2, exec_lua [[ + eq( + 2, + exec_lua [[ vim.api.nvim_win_set_buf(0, diagnostic_bufnr) local other_bufnr = vim.fn.bufadd('test | test') local lines = vim.api.nvim_buf_get_lines(diagnostic_bufnr, 0, -1, true) @@ -151,16 +159,23 @@ describe('vim.diagnostic', function() vim.opt_local.buflisted = true vim.cmd('bwipeout!') return #vim.diagnostic.get() - ]]) - eq(2, exec_lua [[ + ]] + ) + eq( + 2, + exec_lua [[ vim.api.nvim_set_current_buf(diagnostic_bufnr) vim.opt_local.buflisted = false return #vim.diagnostic.get() - ]]) - eq(0, exec_lua [[ + ]] + ) + eq( + 0, + exec_lua [[ vim.cmd('bwipeout!') return #vim.diagnostic.get() - ]]) + ]] + ) end) it('removes diagnostic from stale cache on reset', function() @@ -194,37 +209,48 @@ describe('vim.diagnostic', function() end) it('resolves buffer number 0 to the current buffer', function() - eq(2, exec_lua [[ + eq( + 2, + exec_lua [[ vim.api.nvim_set_current_buf(diagnostic_bufnr) vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic #1', 1, 1, 1, 1), make_error('Diagnostic #2', 2, 1, 2, 1), }) return #vim.diagnostic.get(0) - ]]) + ]] + ) end) it('saves and count a single error', function() - eq(1, exec_lua [[ + eq( + 1, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic #1', 1, 1, 1, 1), }) return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns) - ]]) + ]] + ) end) it('saves and count multiple errors', function() - eq(2, exec_lua [[ + eq( + 2, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic #1', 1, 1, 1, 1), make_error('Diagnostic #2', 2, 1, 2, 1), }) return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns) - ]]) + ]] + ) end) it('saves and count from multiple namespaces', function() - eq({1, 1, 2}, exec_lua [[ + eq( + { 1, 1, 2 }, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic From Server 1', 1, 1, 1, 1), }) @@ -239,11 +265,14 @@ describe('vim.diagnostic', function() -- All namespaces count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR), } - ]]) + ]] + ) end) it('saves and count from multiple namespaces with respect to severity', function() - eq({3, 0, 3}, exec_lua [[ + eq( + { 3, 0, 3 }, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic From Server 1:1', 1, 1, 1, 1), make_error('Diagnostic From Server 1:2', 2, 2, 2, 2), @@ -260,7 +289,8 @@ describe('vim.diagnostic', function() -- All namespaces count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR), } - ]]) + ]] + ) end) it('handles one namespace clearing highlights while the other still has highlights', function() @@ -269,8 +299,10 @@ describe('vim.diagnostic', function() -- 1 Warning (2) + 1 Warning (1) -- 2 highlights and 2 underlines (since error) -- 1 highlight + 1 underline - local all_highlights = {1, 1, 2, 4, 2} - eq(all_highlights, exec_lua [[ + local all_highlights = { 1, 1, 2, 4, 2 } + eq( + all_highlights, + exec_lua [[ local ns_1_diags = { make_error("Error 1", 1, 1, 1, 5), make_warning("Warning on Server 1", 2, 1, 2, 3), @@ -289,10 +321,13 @@ describe('vim.diagnostic', function() count_extmarks(diagnostic_bufnr, diagnostic_ns), count_extmarks(diagnostic_bufnr, other_ns), } - ]]) + ]] + ) -- Clear diagnostics from namespace 1, and make sure we have the right amount of stuff for namespace 2 - eq({1, 1, 2, 0, 2}, exec_lua [[ + eq( + { 1, 1, 2, 0, 2 }, + exec_lua [[ vim.diagnostic.disable(diagnostic_bufnr, diagnostic_ns) return { count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns), @@ -301,10 +336,13 @@ describe('vim.diagnostic', function() count_extmarks(diagnostic_bufnr, diagnostic_ns), count_extmarks(diagnostic_bufnr, other_ns), } - ]]) + ]] + ) -- Show diagnostics from namespace 1 again - eq(all_highlights, exec_lua([[ + eq( + all_highlights, + exec_lua([[ vim.diagnostic.enable(diagnostic_bufnr, diagnostic_ns) return { count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns), @@ -313,11 +351,14 @@ describe('vim.diagnostic', function() count_extmarks(diagnostic_bufnr, diagnostic_ns), count_extmarks(diagnostic_bufnr, other_ns), } - ]])) + ]]) + ) end) it('does not display diagnostics when disabled', function() - eq({0, 2}, exec_lua [[ + eq( + { 0, 2 }, + exec_lua [[ local ns_1_diags = { make_error("Error 1", 1, 1, 1, 5), make_warning("Warning on Server 1", 2, 1, 2, 3), @@ -335,9 +376,12 @@ describe('vim.diagnostic', function() count_extmarks(diagnostic_bufnr, diagnostic_ns), count_extmarks(diagnostic_bufnr, other_ns), } - ]]) + ]] + ) - eq({4, 0}, exec_lua [[ + eq( + { 4, 0 }, + exec_lua [[ vim.diagnostic.enable(diagnostic_bufnr, diagnostic_ns) vim.diagnostic.disable(diagnostic_bufnr, other_ns) @@ -345,7 +389,8 @@ describe('vim.diagnostic', function() count_extmarks(diagnostic_bufnr, diagnostic_ns), count_extmarks(diagnostic_bufnr, other_ns), } - ]]) + ]] + ) end) describe('show() and hide()', function() @@ -660,8 +705,10 @@ describe('vim.diagnostic', function() -- 1 Warning (2) + 1 Warning (1) -- 2 highlights and 2 underlines (since error) -- 1 highlight + 1 underline - local all_highlights = {1, 1, 2, 4, 2} - eq(all_highlights, exec_lua [[ + local all_highlights = { 1, 1, 2, 4, 2 } + eq( + all_highlights, + exec_lua [[ local ns_1_diags = { make_error("Error 1", 1, 1, 1, 5), make_warning("Warning on Server 1", 2, 1, 2, 3), @@ -680,13 +727,16 @@ describe('vim.diagnostic', function() count_extmarks(diagnostic_bufnr, diagnostic_ns), count_extmarks(diagnostic_bufnr, other_ns), } - ]]) + ]] + ) -- Reset diagnostics from namespace 1 exec_lua([[ vim.diagnostic.reset(diagnostic_ns) ]]) -- Make sure we have the right diagnostic count - eq({0, 1, 1, 0, 2} , exec_lua [[ + eq( + { 0, 1, 1, 0, 2 }, + exec_lua [[ local diagnostic_count = {} vim.wait(100, function () diagnostic_count = { count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns), @@ -696,13 +746,16 @@ describe('vim.diagnostic', function() count_extmarks(diagnostic_bufnr, other_ns), } end ) return diagnostic_count - ]]) + ]] + ) -- Reset diagnostics from namespace 2 exec_lua([[ vim.diagnostic.reset(other_ns) ]]) -- Make sure we have the right diagnostic count - eq({0, 0, 0, 0, 0}, exec_lua [[ + eq( + { 0, 0, 0, 0, 0 }, + exec_lua [[ local diagnostic_count = {} vim.wait(100, function () diagnostic_count = { count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns), @@ -712,8 +765,8 @@ describe('vim.diagnostic', function() count_extmarks(diagnostic_bufnr, other_ns), } end ) return diagnostic_count - ]]) - + ]] + ) end) it("doesn't error after bwipeout called on buffer", function() @@ -728,17 +781,22 @@ describe('vim.diagnostic', function() describe('get_next_pos()', function() it('can find the next pos with only one namespace', function() - eq({1, 1}, exec_lua [[ + eq( + { 1, 1 }, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic #1', 1, 1, 1, 1), }) vim.api.nvim_win_set_buf(0, diagnostic_bufnr) return vim.diagnostic.get_next_pos() - ]]) + ]] + ) end) it('can find next pos with two errors', function() - eq({4, 4}, exec_lua [[ + eq( + { 4, 4 }, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic #1', 1, 1, 1, 1), make_error('Diagnostic #2', 4, 4, 4, 4), @@ -746,44 +804,56 @@ describe('vim.diagnostic', function() vim.api.nvim_win_set_buf(0, diagnostic_bufnr) vim.api.nvim_win_set_cursor(0, {3, 1}) return vim.diagnostic.get_next_pos { namespace = diagnostic_ns } - ]]) + ]] + ) end) it('can cycle when position is past error', function() - eq({1, 1}, exec_lua [[ + eq( + { 1, 1 }, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic #1', 1, 1, 1, 1), }) vim.api.nvim_win_set_buf(0, diagnostic_bufnr) vim.api.nvim_win_set_cursor(0, {3, 1}) return vim.diagnostic.get_next_pos { namespace = diagnostic_ns } - ]]) + ]] + ) end) it('will not cycle when wrap is off', function() - eq(false, exec_lua [[ + eq( + false, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic #1', 1, 1, 1, 1), }) vim.api.nvim_win_set_buf(0, diagnostic_bufnr) vim.api.nvim_win_set_cursor(0, {3, 1}) return vim.diagnostic.get_next_pos { namespace = diagnostic_ns, wrap = false } - ]]) + ]] + ) end) it('can cycle even from the last line', function() - eq({4, 4}, exec_lua [[ + eq( + { 4, 4 }, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic #2', 4, 4, 4, 4), }) vim.api.nvim_win_set_buf(0, diagnostic_bufnr) vim.api.nvim_win_set_cursor(0, {vim.api.nvim_buf_line_count(0), 1}) return vim.diagnostic.get_prev_pos { namespace = diagnostic_ns } - ]]) + ]] + ) end) it('works with diagnostics past the end of the line #16349', function() - eq({4, 0}, exec_lua [[ + eq( + { 4, 0 }, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic #1', 3, 9001, 3, 9001), make_error('Diagnostic #2', 4, 0, 4, 0), @@ -792,11 +862,14 @@ describe('vim.diagnostic', function() vim.api.nvim_win_set_cursor(0, {1, 1}) vim.diagnostic.goto_next { float = false } return vim.diagnostic.get_next_pos { namespace = diagnostic_ns } - ]]) + ]] + ) end) it('works with diagnostics before the start of the line', function() - eq({4, 0}, exec_lua [[ + eq( + { 4, 0 }, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic #1', 3, 9001, 3, 9001), make_error('Diagnostic #2', 4, -1, 4, -1), @@ -805,24 +878,30 @@ describe('vim.diagnostic', function() vim.api.nvim_win_set_cursor(0, {1, 1}) vim.diagnostic.goto_next { float = false } return vim.diagnostic.get_next_pos { namespace = diagnostic_ns } - ]]) -end) + ]] + ) + end) end) describe('get_prev_pos()', function() it('can find the prev pos with only one namespace', function() - eq({1, 1}, exec_lua [[ + eq( + { 1, 1 }, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic #1', 1, 1, 1, 1), }) vim.api.nvim_win_set_buf(0, diagnostic_bufnr) vim.api.nvim_win_set_cursor(0, {3, 1}) return vim.diagnostic.get_prev_pos() - ]]) + ]] + ) end) it('can find prev pos with two errors', function() - eq({1, 1}, exec_lua [[ + eq( + { 1, 1 }, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic #1', 1, 1, 1, 1), make_error('Diagnostic #2', 4, 4, 4, 4), @@ -830,29 +909,36 @@ end) vim.api.nvim_win_set_buf(0, diagnostic_bufnr) vim.api.nvim_win_set_cursor(0, {3, 1}) return vim.diagnostic.get_prev_pos { namespace = diagnostic_ns } - ]]) + ]] + ) end) it('can cycle when position is past error', function() - eq({4, 4}, exec_lua [[ + eq( + { 4, 4 }, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic #2', 4, 4, 4, 4), }) vim.api.nvim_win_set_buf(0, diagnostic_bufnr) vim.api.nvim_win_set_cursor(0, {3, 1}) return vim.diagnostic.get_prev_pos { namespace = diagnostic_ns } - ]]) + ]] + ) end) it('respects wrap parameter', function() - eq(false, exec_lua [[ + eq( + false, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic #2', 4, 4, 4, 4), }) vim.api.nvim_win_set_buf(0, diagnostic_bufnr) vim.api.nvim_win_set_cursor(0, {3, 1}) return vim.diagnostic.get_prev_pos { namespace = diagnostic_ns, wrap = false} - ]]) + ]] + ) end) end) @@ -862,18 +948,23 @@ end) end) it('returns all diagnostics when no severity is supplied', function() - eq(2, exec_lua [[ + eq( + 2, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error("Error 1", 1, 1, 1, 5), make_warning("Warning on Server 1", 1, 1, 2, 3), }) return #vim.diagnostic.get(diagnostic_bufnr) - ]]) + ]] + ) end) it('returns only requested diagnostics when severity range is supplied', function() - eq({2, 3, 2}, exec_lua [[ + eq( + { 2, 3, 2 }, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error("Error 1", 1, 1, 1, 5), make_warning("Warning on Server 1", 1, 1, 2, 3), @@ -891,11 +982,14 @@ end) } }), } - ]]) + ]] + ) end) it('returns only requested diagnostics when severities are supplied', function() - eq({1, 1, 2}, exec_lua [[ + eq( + { 1, 1, 2 }, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error("Error 1", 1, 1, 1, 5), make_warning("Warning on Server 1", 1, 1, 2, 3), @@ -913,11 +1007,14 @@ end) } }), } - ]]) + ]] + ) end) it('allows filtering by line', function() - eq(1, exec_lua [[ + eq( + 1, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error("Error 1", 1, 1, 1, 5), make_warning("Warning on Server 1", 1, 1, 2, 3), @@ -926,13 +1023,132 @@ end) }) return #vim.diagnostic.get(diagnostic_bufnr, {lnum = 2}) - ]]) + ]] + ) + end) + end) + + describe('count', function() + it('returns actually present severity counts', function() + eq( + exec_lua [[return { + [vim.diagnostic.severity.ERROR] = 4, + [vim.diagnostic.severity.WARN] = 3, + [vim.diagnostic.severity.INFO] = 2, + [vim.diagnostic.severity.HINT] = 1, + }]], + exec_lua [[ + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error("Error 1", 1, 1, 1, 2), + make_error("Error 2", 1, 3, 1, 4), + make_error("Error 3", 1, 5, 1, 6), + make_error("Error 4", 1, 7, 1, 8), + make_warning("Warning 1", 2, 1, 2, 2), + make_warning("Warning 2", 2, 3, 2, 4), + make_warning("Warning 3", 2, 5, 2, 6), + make_info("Info 1", 3, 1, 3, 2), + make_info("Info 2", 3, 3, 3, 4), + make_hint("Hint 1", 4, 1, 4, 2), + }) + return vim.diagnostic.count(diagnostic_bufnr) + ]] + ) + eq( + exec_lua [[return { + [vim.diagnostic.severity.ERROR] = 2, + [vim.diagnostic.severity.INFO] = 1, + }]], + exec_lua [[ + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error("Error 1", 1, 1, 1, 2), + make_error("Error 2", 1, 3, 1, 4), + make_info("Info 1", 3, 1, 3, 2), + }) + return vim.diagnostic.count(diagnostic_bufnr) + ]] + ) + end) + + it('returns only requested diagnostics count when severity range is supplied', function() + eq( + exec_lua [[return { + { [vim.diagnostic.severity.ERROR] = 1, [vim.diagnostic.severity.WARN] = 1 }, + { [vim.diagnostic.severity.WARN] = 1, [vim.diagnostic.severity.INFO] = 1, [vim.diagnostic.severity.HINT] = 1 }, + { [vim.diagnostic.severity.WARN] = 1, [vim.diagnostic.severity.INFO] = 1 }, + }]], + exec_lua [[ + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error("Error 1", 1, 1, 1, 5), + make_warning("Warning on Server 1", 1, 1, 2, 3), + make_info("Ignored information", 1, 1, 2, 3), + make_hint("Here's a hint", 1, 1, 2, 3), + }) + + return { + vim.diagnostic.count(diagnostic_bufnr, { severity = {min=vim.diagnostic.severity.WARN} }), + vim.diagnostic.count(diagnostic_bufnr, { severity = {max=vim.diagnostic.severity.WARN} }), + vim.diagnostic.count(diagnostic_bufnr, { + severity = { + min=vim.diagnostic.severity.INFO, + max=vim.diagnostic.severity.WARN, + } + }), + } + ]] + ) + end) + + it('returns only requested diagnostics when severities are supplied', function() + eq( + exec_lua [[return { + { [vim.diagnostic.severity.WARN] = 1 }, + { [vim.diagnostic.severity.ERROR] = 1 }, + { [vim.diagnostic.severity.WARN] = 1, [vim.diagnostic.severity.INFO] = 1 }, + }]], + exec_lua [[ + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error("Error 1", 1, 1, 1, 5), + make_warning("Warning on Server 1", 1, 1, 2, 3), + make_info("Ignored information", 1, 1, 2, 3), + make_hint("Here's a hint", 1, 1, 2, 3), + }) + + return { + vim.diagnostic.count(diagnostic_bufnr, { severity = {vim.diagnostic.severity.WARN} }), + vim.diagnostic.count(diagnostic_bufnr, { severity = {vim.diagnostic.severity.ERROR} }), + vim.diagnostic.count(diagnostic_bufnr, { + severity = { + vim.diagnostic.severity.INFO, + vim.diagnostic.severity.WARN, + } + }), + } + ]] + ) + end) + + it('allows filtering by line', function() + eq( + exec_lua [[return { [vim.diagnostic.severity.ERROR] = 1 }]], + exec_lua [[ + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error("Error 1", 1, 1, 1, 5), + make_warning("Warning on Server 1", 1, 1, 2, 3), + make_info("Ignored information", 1, 1, 2, 3), + make_error("Error On Other Line", 2, 1, 1, 5), + }) + + return vim.diagnostic.count(diagnostic_bufnr, {lnum = 2}) + ]] + ) end) end) describe('config()', function() it('works with global, namespace, and ephemeral options', function() - eq(1, exec_lua [[ + eq( + 1, + exec_lua [[ vim.diagnostic.config({ virtual_text = false, }) @@ -947,9 +1163,12 @@ end) }) return count_extmarks(diagnostic_bufnr, diagnostic_ns) - ]]) + ]] + ) - eq(1, exec_lua [[ + eq( + 1, + exec_lua [[ vim.diagnostic.config({ virtual_text = false, }) @@ -964,9 +1183,12 @@ end) }, {virtual_text = true}) return count_extmarks(diagnostic_bufnr, diagnostic_ns) - ]]) + ]] + ) - eq(0, exec_lua [[ + eq( + 0, + exec_lua [[ vim.diagnostic.config({ virtual_text = false, }) @@ -981,9 +1203,12 @@ end) }, {virtual_text = true}) return count_extmarks(diagnostic_bufnr, diagnostic_ns) - ]]) + ]] + ) - eq(1, exec_lua [[ + eq( + 1, + exec_lua [[ vim.diagnostic.config({ virtual_text = false, }) @@ -1000,7 +1225,8 @@ end) }) return count_extmarks(diagnostic_bufnr, diagnostic_ns) - ]]) + ]] + ) end) it('can use functions for config values', function() @@ -1013,7 +1239,10 @@ end) }) ]] - eq(1, exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]]) + eq( + 1, + exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]] + ) eq(2, exec_lua [[return count_extmarks(diagnostic_bufnr, diagnostic_ns)]]) -- Now, don't enable virtual text. @@ -1024,13 +1253,17 @@ end) }, diagnostic_ns) ]] - eq(1, exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]]) + eq( + 1, + exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]] + ) eq(1, exec_lua [[return count_extmarks(diagnostic_bufnr, diagnostic_ns)]]) end) it('allows filtering by severity', function() local get_extmark_count_with_severity = function(min_severity) - return exec_lua([[ + return exec_lua( + [[ vim.diagnostic.config({ underline = false, virtual_text = { @@ -1043,15 +1276,17 @@ end) }) return count_extmarks(diagnostic_bufnr, diagnostic_ns) - ]], min_severity) + ]], + min_severity + ) end -- No messages with Error or higher - eq(0, get_extmark_count_with_severity("ERROR")) + eq(0, get_extmark_count_with_severity('ERROR')) -- But now we don't filter it - eq(1, get_extmark_count_with_severity("WARN")) - eq(1, get_extmark_count_with_severity("HINT")) + eq(1, get_extmark_count_with_severity('WARN')) + eq(1, get_extmark_count_with_severity('HINT')) end) it('allows sorting by severity', function() @@ -1080,9 +1315,19 @@ end) table.insert(virt_texts, (string.gsub(virt_text[i][2], "DiagnosticVirtualText", ""))) end + local ns = vim.diagnostic.get_namespace(diagnostic_ns) + local sign_ns = ns.user_data.sign_ns local signs = {} - for _, v in ipairs(vim.fn.sign_getplaced(diagnostic_bufnr, {group = "*"})[1].signs) do - table.insert(signs, (string.gsub(v.name, "DiagnosticSign", ""))) + local all_signs = vim.api.nvim_buf_get_extmarks(diagnostic_bufnr, sign_ns, 0, -1, {type = 'sign', details = true}) + table.sort(all_signs, function(a, b) + return a[1] > b[1] + end) + + for _, v in ipairs(all_signs) do + local s = v[4].sign_hl_group:gsub('DiagnosticSign', "") + if not vim.tbl_contains(signs, s) then + signs[#signs + 1] = s + end end return {virt_texts, signs} @@ -1093,16 +1338,16 @@ end) -- Virt texts are defined lowest priority to highest, signs from -- highest to lowest - eq({'Warn', 'Error', 'Info'}, result[1]) - eq({'Info', 'Error', 'Warn'}, result[2]) + eq({ 'Warn', 'Error', 'Info' }, result[1]) + eq({ 'Info', 'Error', 'Warn' }, result[2]) result = exec_lua [[return get_virt_text_and_signs(true)]] - eq({'Info', 'Warn', 'Error'}, result[1]) - eq({'Error', 'Warn', 'Info'}, result[2]) + eq({ 'Info', 'Warn', 'Error' }, result[1]) + eq({ 'Error', 'Warn', 'Info' }, result[2]) result = exec_lua [[return get_virt_text_and_signs({ reverse = true })]] - eq({'Error', 'Warn', 'Info'}, result[1]) - eq({'Info', 'Warn', 'Error'}, result[2]) + eq({ 'Error', 'Warn', 'Info' }, result[1]) + eq({ 'Info', 'Warn', 'Error' }, result[2]) end) it('can show diagnostic sources in virtual text', function() @@ -1185,8 +1430,8 @@ end) local extmarks = get_virt_text_extmarks(diagnostic_ns) return {extmarks[1][4].virt_text, extmarks[2][4].virt_text} ]] - eq(" 👀 Warning", result[1][3][1]) - eq(" 🔥 Error", result[2][3][1]) + eq(' 👀 Warning', result[1][3][1]) + eq(' 🔥 Error', result[2][3][1]) end) it('includes source for formatted diagnostics', function() @@ -1213,12 +1458,14 @@ end) local extmarks = get_virt_text_extmarks(diagnostic_ns) return {extmarks[1][4].virt_text, extmarks[2][4].virt_text} ]] - eq(" some_linter: 👀 Warning", result[1][3][1]) - eq(" another_linter: 🔥 Error", result[2][3][1]) + eq(' some_linter: 👀 Warning', result[1][3][1]) + eq(' another_linter: 🔥 Error', result[2][3][1]) end) it('can add a prefix to virtual text', function() - eq('E Some error', exec_lua [[ + eq( + 'E Some error', + exec_lua [[ local diagnostics = { make_error('Some error', 0, 0, 0, 0), } @@ -1235,9 +1482,12 @@ end) local prefix = extmarks[1][4].virt_text[2][1] local message = extmarks[1][4].virt_text[3][1] return prefix .. message - ]]) + ]] + ) - eq('[(1/1) err-code] Some error', exec_lua [[ + eq( + '[(1/1) err-code] Some error', + exec_lua [[ local diagnostics = { make_error('Some error', 0, 0, 0, 0, nil, 'err-code'), } @@ -1254,11 +1504,14 @@ end) local prefix = extmarks[1][4].virt_text[2][1] local message = extmarks[1][4].virt_text[3][1] return prefix .. message - ]]) + ]] + ) end) it('can add a suffix to virtual text', function() - eq(' Some error ✘', exec_lua [[ + eq( + ' Some error ✘', + exec_lua [[ local diagnostics = { make_error('Some error', 0, 0, 0, 0), } @@ -1274,9 +1527,12 @@ end) local extmarks = get_virt_text_extmarks(diagnostic_ns) local virt_text = extmarks[1][4].virt_text[3][1] return virt_text - ]]) + ]] + ) - eq(' Some error [err-code]', exec_lua [[ + eq( + ' Some error [err-code]', + exec_lua [[ local diagnostics = { make_error('Some error', 0, 0, 0, 0, nil, 'err-code'), } @@ -1292,20 +1548,23 @@ end) local extmarks = get_virt_text_extmarks(diagnostic_ns) local virt_text = extmarks[1][4].virt_text[3][1] return virt_text - ]]) + ]] + ) end) end) describe('set()', function() it('validates its arguments', function() - matches("expected a list of diagnostics", - pcall_err(exec_lua, [[vim.diagnostic.set(1, 0, {lnum = 1, col = 2})]])) + matches( + 'expected a list of diagnostics', + pcall_err(exec_lua, [[vim.diagnostic.set(1, 0, {lnum = 1, col = 2})]]) + ) end) it('can perform updates after insert_leave', function() exec_lua [[vim.api.nvim_set_current_buf(diagnostic_bufnr)]] - nvim("input", "o") - eq({mode='i', blocking=false}, nvim("get_mode")) + api.nvim_input('o') + eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) -- Save the diagnostics exec_lua [[ @@ -1318,21 +1577,27 @@ end) ]] -- No diagnostics displayed yet. - eq({mode='i', blocking=false}, nvim("get_mode")) - eq(1, exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]]) + eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) + eq( + 1, + exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]] + ) eq(0, exec_lua [[return count_extmarks(diagnostic_bufnr, diagnostic_ns)]]) - nvim("input", "<esc>") - eq({mode='n', blocking=false}, nvim("get_mode")) + api.nvim_input('<esc>') + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) - eq(1, exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]]) + eq( + 1, + exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]] + ) eq(2, exec_lua [[return count_extmarks(diagnostic_bufnr, diagnostic_ns)]]) end) it('does not perform updates when not needed', function() exec_lua [[vim.api.nvim_set_current_buf(diagnostic_bufnr)]] - nvim("input", "o") - eq({mode='i', blocking=false}, nvim("get_mode")) + api.nvim_input('o') + eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) -- Save the diagnostics exec_lua [[ @@ -1354,24 +1619,30 @@ end) ]] -- No diagnostics displayed yet. - eq({mode='i', blocking=false}, nvim("get_mode")) - eq(1, exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]]) + eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) + eq( + 1, + exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]] + ) eq(0, exec_lua [[return count_extmarks(diagnostic_bufnr, diagnostic_ns)]]) eq(0, exec_lua [[return DisplayCount]]) - nvim("input", "<esc>") - eq({mode='n', blocking=false}, nvim("get_mode")) + api.nvim_input('<esc>') + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) - eq(1, exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]]) + eq( + 1, + exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]] + ) eq(2, exec_lua [[return count_extmarks(diagnostic_bufnr, diagnostic_ns)]]) eq(1, exec_lua [[return DisplayCount]]) -- Go in and out of insert mode one more time. - nvim("input", "o") - eq({mode='i', blocking=false}, nvim("get_mode")) + api.nvim_input('o') + eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) - nvim("input", "<esc>") - eq({mode='n', blocking=false}, nvim("get_mode")) + api.nvim_input('<esc>') + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) -- Should not have set the virtual text again. eq(1, exec_lua [[return DisplayCount]]) @@ -1379,8 +1650,8 @@ end) it('never sets virtual text, in combination with insert leave', function() exec_lua [[vim.api.nvim_set_current_buf(diagnostic_bufnr)]] - nvim("input", "o") - eq({mode='i', blocking=false}, nvim("get_mode")) + api.nvim_input('o') + eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) -- Save the diagnostics exec_lua [[ @@ -1403,24 +1674,30 @@ end) ]] -- No diagnostics displayed yet. - eq({mode='i', blocking=false}, nvim("get_mode")) - eq(1, exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]]) + eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) + eq( + 1, + exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]] + ) eq(0, exec_lua [[return count_extmarks(diagnostic_bufnr, diagnostic_ns)]]) eq(0, exec_lua [[return DisplayCount]]) - nvim("input", "<esc>") - eq({mode='n', blocking=false}, nvim("get_mode")) + api.nvim_input('<esc>') + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) - eq(1, exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]]) + eq( + 1, + exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]] + ) eq(1, exec_lua [[return count_extmarks(diagnostic_bufnr, diagnostic_ns)]]) eq(0, exec_lua [[return DisplayCount]]) -- Go in and out of insert mode one more time. - nvim("input", "o") - eq({mode='i', blocking=false}, nvim("get_mode")) + api.nvim_input('o') + eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) - nvim("input", "<esc>") - eq({mode='n', blocking=false}, nvim("get_mode")) + api.nvim_input('<esc>') + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) -- Should not have set the virtual text still. eq(0, exec_lua [[return DisplayCount]]) @@ -1428,8 +1705,8 @@ end) it('can perform updates while in insert mode, if desired', function() exec_lua [[vim.api.nvim_set_current_buf(diagnostic_bufnr)]] - nvim("input", "o") - eq({mode='i', blocking=false}, nvim("get_mode")) + api.nvim_input('o') + eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) -- Save the diagnostics exec_lua [[ @@ -1443,49 +1720,126 @@ end) ]] -- Diagnostics are displayed, because the user wanted them that way! - eq({mode='i', blocking=false}, nvim("get_mode")) - eq(1, exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]]) + eq({ mode = 'i', blocking = false }, api.nvim_get_mode()) + eq( + 1, + exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]] + ) eq(2, exec_lua [[return count_extmarks(diagnostic_bufnr, diagnostic_ns)]]) - nvim("input", "<esc>") - eq({mode='n', blocking=false}, nvim("get_mode")) + api.nvim_input('<esc>') + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) - eq(1, exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]]) + eq( + 1, + exec_lua [[return count_diagnostics(diagnostic_bufnr, vim.diagnostic.severity.ERROR, diagnostic_ns)]] + ) eq(2, exec_lua [[return count_extmarks(diagnostic_bufnr, diagnostic_ns)]]) end) it('can set diagnostics without displaying them', function() - eq(0, exec_lua [[ + eq( + 0, + exec_lua [[ vim.diagnostic.disable(diagnostic_bufnr, diagnostic_ns) vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic From Server 1:1', 1, 1, 1, 1), }) return count_extmarks(diagnostic_bufnr, diagnostic_ns) - ]]) + ]] + ) - eq(2, exec_lua [[ + eq( + 2, + exec_lua [[ vim.diagnostic.enable(diagnostic_bufnr, diagnostic_ns) return count_extmarks(diagnostic_bufnr, diagnostic_ns) - ]]) + ]] + ) end) it('can set display options', function() - eq(0, exec_lua [[ + eq( + 0, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic From Server 1:1', 1, 1, 1, 1), }, { virtual_text = false, underline = false }) return count_extmarks(diagnostic_bufnr, diagnostic_ns) - ]]) + ]] + ) - eq(1, exec_lua [[ + eq( + 1, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic From Server 1:1', 1, 1, 1, 1), }, { virtual_text = true, underline = false }) return count_extmarks(diagnostic_bufnr, diagnostic_ns) - ]]) + ]] + ) end) - it('sets signs', function() + it('sets and clears signs #26193 #26555', function() + do + local result = exec_lua [[ + vim.diagnostic.config({ + signs = true, + }) + + local diagnostics = { + make_error('Error', 1, 1, 1, 2), + make_warning('Warning', 3, 3, 3, 3), + } + + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics) + + local ns = vim.diagnostic.get_namespace(diagnostic_ns) + local sign_ns = ns.user_data.sign_ns + + local signs = vim.api.nvim_buf_get_extmarks(diagnostic_bufnr, sign_ns, 0, -1, {type ='sign', details = true}) + local result = {} + for _, s in ipairs(signs) do + result[#result + 1] = { lnum = s[2] + 1, name = s[4].sign_hl_group } + end + return result + ]] + + eq({ 2, 'DiagnosticSignError' }, { result[1].lnum, result[1].name }) + eq({ 4, 'DiagnosticSignWarn' }, { result[2].lnum, result[2].name }) + end + + do + local result = exec_lua [[ + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {}) + + local ns = vim.diagnostic.get_namespace(diagnostic_ns) + local sign_ns = ns.user_data.sign_ns + + return vim.api.nvim_buf_get_extmarks(diagnostic_bufnr, sign_ns, 0, -1, {type ='sign', details = true}) + ]] + + eq({}, result) + end + end) + + it('respects legacy signs placed with :sign define or sign_define #26618', function() + -- Legacy signs for diagnostics were deprecated in 0.10 and will be removed in 0.12 + eq(0, helpers.fn.has('nvim-0.12')) + + helpers.command( + 'sign define DiagnosticSignError text= texthl= linehl=ErrorMsg numhl=ErrorMsg' + ) + helpers.command( + 'sign define DiagnosticSignWarn text= texthl= linehl=WarningMsg numhl=WarningMsg' + ) + helpers.command( + 'sign define DiagnosticSignInfo text= texthl= linehl=Underlined numhl=Underlined' + ) + helpers.command( + 'sign define DiagnosticSignHint text= texthl= linehl=Underlined numhl=Underlined' + ) + local result = exec_lua [[ vim.diagnostic.config({ signs = true, @@ -1498,17 +1852,46 @@ end) vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics) - return vim.fn.sign_getplaced(diagnostic_bufnr, {group = '*'})[1].signs + local ns = vim.diagnostic.get_namespace(diagnostic_ns) + local sign_ns = ns.user_data.sign_ns + + local signs = vim.api.nvim_buf_get_extmarks(diagnostic_bufnr, sign_ns, 0, -1, {type ='sign', details = true}) + local result = {} + for _, s in ipairs(signs) do + result[#result + 1] = { + lnum = s[2] + 1, + name = s[4].sign_hl_group, + text = s[4].sign_text or '', + numhl = s[4].number_hl_group, + linehl = s[4].line_hl_group, + } + end + return result ]] - eq({2, 'DiagnosticSignError'}, {result[1].lnum, result[1].name}) - eq({4, 'DiagnosticSignWarn'}, {result[2].lnum, result[2].name}) + eq({ + lnum = 2, + name = 'DiagnosticSignError', + text = '', + numhl = 'ErrorMsg', + linehl = 'ErrorMsg', + }, result[1]) + + eq({ + lnum = 4, + name = 'DiagnosticSignWarn', + text = '', + numhl = 'WarningMsg', + linehl = 'WarningMsg', + }, result[2]) end) end) describe('open_float()', function() it('can display a header', function() - eq({'Diagnostics:', '1. Syntax error'}, exec_lua [[ + eq( + { 'Diagnostics:', '1. Syntax error' }, + exec_lua [[ local diagnostics = { make_error("Syntax error", 0, 1, 0, 3), } @@ -1518,9 +1901,12 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) - eq({"We're no strangers to love...", '1. Syntax error'}, exec_lua [[ + eq( + { "We're no strangers to love...", '1. Syntax error' }, + exec_lua [[ local diagnostics = { make_error("Syntax error", 0, 1, 0, 3), } @@ -1530,9 +1916,12 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) - eq({'You know the rules', '1. Syntax error'}, exec_lua [[ + eq( + { 'You know the rules', '1. Syntax error' }, + exec_lua [[ local diagnostics = { make_error("Syntax error", 0, 1, 0, 3), } @@ -1542,11 +1931,14 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) end) it('can show diagnostics from the whole buffer', function() - eq({'1. Syntax error', '2. Some warning'}, exec_lua [[ + eq( + { '1. Syntax error', '2. Some warning' }, + exec_lua [[ local diagnostics = { make_error("Syntax error", 0, 1, 0, 3), make_warning("Some warning", 1, 1, 1, 3), @@ -1557,12 +1949,15 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) end) it('can show diagnostics from a single line', function() -- Using cursor position - eq({'1. Some warning'}, exec_lua [[ + eq( + { '1. Some warning' }, + exec_lua [[ local diagnostics = { make_error("Syntax error", 0, 1, 0, 3), make_warning("Some warning", 1, 1, 1, 3), @@ -1574,10 +1969,13 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) -- With specified position - eq({'1. Some warning'}, exec_lua [[ + eq( + { '1. Some warning' }, + exec_lua [[ local diagnostics = { make_error("Syntax error", 0, 1, 0, 3), make_warning("Some warning", 1, 1, 1, 3), @@ -1589,12 +1987,15 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) end) it('can show diagnostics from a specific position', function() -- Using cursor position - eq({'Syntax error'}, exec_lua [[ + eq( + { 'Syntax error' }, + exec_lua [[ local diagnostics = { make_error("Syntax error", 1, 1, 1, 2), make_warning("Some warning", 1, 3, 1, 4), @@ -1606,10 +2007,13 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) -- With specified position - eq({'Some warning'}, exec_lua [[ + eq( + { 'Some warning' }, + exec_lua [[ local diagnostics = { make_error("Syntax error", 1, 1, 1, 2), make_warning("Some warning", 1, 3, 1, 4), @@ -1621,10 +2025,13 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) -- With column position past the end of the line. #16062 - eq({'Syntax error'}, exec_lua [[ + eq( + { 'Syntax error' }, + exec_lua [[ local first_line_len = #vim.api.nvim_buf_get_lines(diagnostic_bufnr, 0, 1, true)[1] local diagnostics = { make_error("Syntax error", 0, first_line_len + 1, 1, 0), @@ -1636,14 +2043,19 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) - end) - - it('creates floating window and returns float bufnr and winnr if current line contains diagnostics', function() - -- Two lines: - -- Diagnostic: - -- 1. <msg> - eq(2, exec_lua [[ + ]] + ) + end) + + it( + 'creates floating window and returns float bufnr and winnr if current line contains diagnostics', + function() + -- Two lines: + -- Diagnostic: + -- 1. <msg> + eq( + 2, + exec_lua [[ local diagnostics = { make_error("Syntax error", 0, 1, 0, 3), } @@ -1653,11 +2065,15 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return #lines - ]]) - end) + ]] + ) + end + ) it('only reports diagnostics from the current buffer when bufnr is omitted #15710', function() - eq(2, exec_lua [[ + eq( + 2, + exec_lua [[ local other_bufnr = vim.api.nvim_create_buf(true, false) local buf_1_diagnostics = { make_error("Syntax error", 0, 1, 0, 3), @@ -1672,11 +2088,14 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return #lines - ]]) + ]] + ) end) it('allows filtering by namespace', function() - eq(2, exec_lua [[ + eq( + 2, + exec_lua [[ local ns_1_diagnostics = { make_error("Syntax error", 0, 1, 0, 3), } @@ -1690,13 +2109,18 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return #lines - ]]) + ]] + ) end) - it('creates floating window and returns float bufnr and winnr without header, if requested', function() - -- One line (since no header): - -- 1. <msg> - eq(1, exec_lua [[ + it( + 'creates floating window and returns float bufnr and winnr without header, if requested', + function() + -- One line (since no header): + -- 1. <msg> + eq( + 1, + exec_lua [[ local diagnostics = { make_error("Syntax error", 0, 1, 0, 3), } @@ -1706,11 +2130,15 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return #lines - ]]) - end) + ]] + ) + end + ) it('clamps diagnostic line numbers within the valid range', function() - eq(1, exec_lua [[ + eq( + 1, + exec_lua [[ local diagnostics = { make_error("Syntax error", 6, 0, 6, 0), } @@ -1720,13 +2148,16 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return #lines - ]]) + ]] + ) end) it('can show diagnostic source', function() exec_lua [[vim.api.nvim_win_set_buf(0, diagnostic_bufnr)]] - eq({"1. Syntax error"}, exec_lua [[ + eq( + { '1. Syntax error' }, + exec_lua [[ local diagnostics = { make_error("Syntax error", 0, 1, 0, 3, "source x"), } @@ -1738,9 +2169,12 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) - eq({"1. source x: Syntax error"}, exec_lua [[ + eq( + { '1. source x: Syntax error' }, + exec_lua [[ local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, { header = false, source = "always", @@ -1748,9 +2182,12 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) - eq({"1. source x: Syntax error", "2. source y: Another error"}, exec_lua [[ + eq( + { '1. source x: Syntax error', '2. source y: Another error' }, + exec_lua [[ local diagnostics = { make_error("Syntax error", 0, 1, 0, 3, "source x"), make_error("Another error", 0, 1, 0, 3, "source y"), @@ -1763,13 +2200,16 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) end) it('respects severity_sort', function() exec_lua [[vim.api.nvim_win_set_buf(0, diagnostic_bufnr)]] - eq({"1. Syntax error", "2. Info", "3. Error", "4. Warning"}, exec_lua [[ + eq( + { '1. Syntax error', '2. Info', '3. Error', '4. Warning' }, + exec_lua [[ local diagnostics = { make_error("Syntax error", 0, 1, 0, 3), make_info('Info', 0, 3, 0, 4), @@ -1785,28 +2225,36 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) - eq({"1. Syntax error", "2. Error", "3. Warning", "4. Info"}, exec_lua [[ + eq( + { '1. Syntax error', '2. Error', '3. Warning', '4. Info' }, + exec_lua [[ vim.diagnostic.config({severity_sort = true}) local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, { header = false }) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) - eq({"1. Info", "2. Warning", "3. Error", "4. Syntax error"}, exec_lua [[ + eq( + { '1. Info', '2. Warning', '3. Error', '4. Syntax error' }, + exec_lua [[ vim.diagnostic.config({severity_sort = { reverse = true } }) local float_bufnr, winnr = vim.diagnostic.open_float(diagnostic_bufnr, { header = false }) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) end) it('can filter by severity', function() local count_diagnostics_with_severity = function(min_severity, max_severity) - return exec_lua([[ + return exec_lua( + [[ local min_severity, max_severity = ... vim.diagnostic.config({ float = { @@ -1829,19 +2277,24 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return #lines - ]], min_severity, max_severity) + ]], + min_severity, + max_severity + ) end - eq(2, count_diagnostics_with_severity("ERROR")) - eq(3, count_diagnostics_with_severity("WARN")) - eq(1, count_diagnostics_with_severity("WARN", "WARN")) - eq(4, count_diagnostics_with_severity("HINT")) - eq(0, count_diagnostics_with_severity("HINT", "HINT")) + eq(2, count_diagnostics_with_severity('ERROR')) + eq(3, count_diagnostics_with_severity('WARN')) + eq(1, count_diagnostics_with_severity('WARN', 'WARN')) + eq(4, count_diagnostics_with_severity('HINT')) + eq(0, count_diagnostics_with_severity('HINT', 'HINT')) end) it('can add a prefix to diagnostics', function() -- Default is to add a number - eq({'1. Syntax error', '2. Some warning'}, exec_lua [[ + eq( + { '1. Syntax error', '2. Some warning' }, + exec_lua [[ local diagnostics = { make_error("Syntax error", 0, 1, 0, 3), make_warning("Some warning", 1, 1, 1, 3), @@ -1852,9 +2305,12 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) - eq({'Syntax error', 'Some warning'}, exec_lua [[ + eq( + { 'Syntax error', 'Some warning' }, + exec_lua [[ local diagnostics = { make_error("Syntax error", 0, 1, 0, 3), make_warning("Some warning", 1, 1, 1, 3), @@ -1865,9 +2321,12 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) - eq({'1. Syntax error', '2. Some warning'}, exec_lua [[ + eq( + { '1. Syntax error', '2. Some warning' }, + exec_lua [[ local diagnostics = { make_error("Syntax error", 0, 1, 0, 3), make_warning("Some warning", 0, 1, 0, 3), @@ -1887,9 +2346,12 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) - eq({'Syntax error'}, exec_lua [[ + eq( + { 'Syntax error' }, + exec_lua [[ local diagnostics = { make_error("Syntax error", 0, 1, 0, 3), } @@ -1908,15 +2370,20 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) - eq(".../diagnostic.lua:0: prefix: expected string|table|function, got number", - pcall_err(exec_lua, [[ vim.diagnostic.open_float({ prefix = 42 }) ]])) + eq( + '.../diagnostic.lua:0: prefix: expected string|table|function, got number', + pcall_err(exec_lua, [[ vim.diagnostic.open_float({ prefix = 42 }) ]]) + ) end) it('can add a suffix to diagnostics', function() -- Default is to render the diagnostic error code - eq({'1. Syntax error [code-x]', '2. Some warning [code-y]'}, exec_lua [[ + eq( + { '1. Syntax error [code-x]', '2. Some warning [code-y]' }, + exec_lua [[ local diagnostics = { make_error("Syntax error", 0, 1, 0, 3, nil, "code-x"), make_warning("Some warning", 1, 1, 1, 3, nil, "code-y"), @@ -1927,9 +2394,12 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) - eq({'1. Syntax error', '2. Some warning'}, exec_lua [[ + eq( + { '1. Syntax error', '2. Some warning' }, + exec_lua [[ local diagnostics = { make_error("Syntax error", 0, 1, 0, 3, nil, "code-x"), make_warning("Some warning", 1, 1, 1, 3, nil, "code-y"), @@ -1940,10 +2410,13 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) -- Suffix is rendered on the last line of a multiline diagnostic - eq({'1. Syntax error', ' More context [code-x]'}, exec_lua [[ + eq( + { '1. Syntax error', ' More context [code-x]' }, + exec_lua [[ local diagnostics = { make_error("Syntax error\nMore context", 0, 1, 0, 3, nil, "code-x"), } @@ -1953,14 +2426,19 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) - eq(".../diagnostic.lua:0: suffix: expected string|table|function, got number", - pcall_err(exec_lua, [[ vim.diagnostic.open_float({ suffix = 42 }) ]])) + eq( + '.../diagnostic.lua:0: suffix: expected string|table|function, got number', + pcall_err(exec_lua, [[ vim.diagnostic.open_float({ suffix = 42 }) ]]) + ) end) it('works with the old signature', function() - eq({'1. Syntax error'}, exec_lua [[ + eq( + { '1. Syntax error' }, + exec_lua [[ local diagnostics = { make_error("Syntax error", 0, 1, 0, 3), } @@ -1970,7 +2448,8 @@ end) local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false) vim.api.nvim_win_close(winnr, true) return lines - ]]) + ]] + ) end) end) @@ -2015,55 +2494,76 @@ end) describe('match()', function() it('matches a string', function() - local msg = "ERROR: george.txt:19:84:Two plus two equals five" + local msg = 'ERROR: george.txt:19:84:Two plus two equals five' local diagnostic = { severity = exec_lua [[return vim.diagnostic.severity.ERROR]], lnum = 18, col = 83, end_lnum = 18, end_col = 83, - message = "Two plus two equals five", + message = 'Two plus two equals five', } - eq(diagnostic, exec_lua([[ + eq( + diagnostic, + exec_lua( + [[ return vim.diagnostic.match(..., "^(%w+): [^:]+:(%d+):(%d+):(.+)$", {"severity", "lnum", "col", "message"}) - ]], msg)) + ]], + msg + ) + ) end) it('returns nil if the pattern fails to match', function() - eq(NIL, exec_lua [[ + eq( + NIL, + exec_lua [[ local msg = "The answer to life, the universe, and everything is" return vim.diagnostic.match(msg, "This definitely will not match", {}) - ]]) + ]] + ) end) it('respects default values', function() - local msg = "anna.txt:1:Happy families are all alike" + local msg = 'anna.txt:1:Happy families are all alike' local diagnostic = { severity = exec_lua [[return vim.diagnostic.severity.INFO]], lnum = 0, col = 0, end_lnum = 0, end_col = 0, - message = "Happy families are all alike", + message = 'Happy families are all alike', } - eq(diagnostic, exec_lua([[ + eq( + diagnostic, + exec_lua( + [[ return vim.diagnostic.match(..., "^[^:]+:(%d+):(.+)$", {"lnum", "message"}, nil, {severity = vim.diagnostic.severity.INFO}) - ]], msg)) + ]], + msg + ) + ) end) it('accepts a severity map', function() - local msg = "46:FATAL:Et tu, Brute?" + local msg = '46:FATAL:Et tu, Brute?' local diagnostic = { severity = exec_lua [[return vim.diagnostic.severity.ERROR]], lnum = 45, col = 0, end_lnum = 45, end_col = 0, - message = "Et tu, Brute?", + message = 'Et tu, Brute?', } - eq(diagnostic, exec_lua([[ + eq( + diagnostic, + exec_lua( + [[ return vim.diagnostic.match(..., "^(%d+):(%w+):(.+)$", {"lnum", "severity", "message"}, {FATAL = vim.diagnostic.severity.ERROR}) - ]], msg)) + ]], + msg + ) + ) end) end) @@ -2095,12 +2595,20 @@ end) describe('handlers', function() it('checks that a new handler is a table', function() - matches([[.*handler: expected table, got string.*]], pcall_err(exec_lua, [[ vim.diagnostic.handlers.foo = "bar" ]])) - matches([[.*handler: expected table, got function.*]], pcall_err(exec_lua, [[ vim.diagnostic.handlers.foo = function() end ]])) + matches( + [[.*handler: expected table, got string.*]], + pcall_err(exec_lua, [[ vim.diagnostic.handlers.foo = "bar" ]]) + ) + matches( + [[.*handler: expected table, got function.*]], + pcall_err(exec_lua, [[ vim.diagnostic.handlers.foo = function() end ]]) + ) end) it('can add new handlers', function() - eq(true, exec_lua [[ + eq( + true, + exec_lua [[ local handler_called = false vim.diagnostic.handlers.test = { show = function(namespace, bufnr, diagnostics, opts) @@ -2117,11 +2625,14 @@ end) make_warning("Warning", 0, 0, 0, 0), }) return handler_called - ]]) + ]] + ) end) it('can disable handlers by setting the corresponding option to false', function() - eq(false, exec_lua [[ + eq( + false, + exec_lua [[ local handler_called = false vim.diagnostic.handlers.test = { show = function(namespace, bufnr, diagnostics, opts) @@ -2134,11 +2645,14 @@ end) make_warning("Warning", 0, 0, 0, 0), }) return handler_called - ]]) + ]] + ) end) - it('always calls a handler\'s hide function if defined', function() - eq({false, true}, exec_lua [[ + it("always calls a handler's hide function if defined", function() + eq( + { false, true }, + exec_lua [[ local hide_called = false local show_called = false vim.diagnostic.handlers.test = { @@ -2158,11 +2672,14 @@ end) }) vim.diagnostic.hide(diagnostic_ns, diagnostic_bufnr) return {show_called, hide_called} - ]]) + ]] + ) end) it('triggers the autocommand when diagnostics are set', function() - eq({true, true}, exec_lua [[ + eq( + { true, true }, + exec_lua [[ -- Set a different buffer as current to test that <abuf> is being set properly in -- DiagnosticChanged callbacks local tmp = vim.api.nvim_create_buf(false, true) @@ -2182,11 +2699,14 @@ end) triggered[1] == diagnostic_bufnr, triggered[2] == 1, } - ]]) - end) + ]] + ) + end) it('triggers the autocommand when diagnostics are cleared', function() - eq(true, exec_lua [[ + eq( + true, + exec_lua [[ local tmp = vim.api.nvim_create_buf(false, true) vim.api.nvim_set_current_buf(tmp) vim.g.diagnostic_autocmd_triggered = 0 @@ -2194,11 +2714,14 @@ end) vim.api.nvim_buf_set_name(diagnostic_bufnr, "test | test") vim.diagnostic.reset(diagnostic_ns, diagnostic_bufnr) return vim.g.diagnostic_autocmd_triggered == diagnostic_bufnr - ]]) - end) + ]] + ) + end) - it("checks if diagnostics are disabled in a buffer", function() - eq({true, true, true , true}, exec_lua [[ + it('checks if diagnostics are disabled in a buffer', function() + eq( + { true, true, true, true }, + exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic #1', 1, 1, 1, 1), }) @@ -2210,9 +2733,12 @@ end) vim.diagnostic.is_disabled(diagnostic_bufnr, diagnostic_ns), vim.diagnostic.is_disabled(_, diagnostic_ns), } - ]]) + ]] + ) - eq({false, false, false , false}, exec_lua [[ + eq( + { false, false, false, false }, + exec_lua [[ vim.diagnostic.enable() return { vim.diagnostic.is_disabled(), @@ -2220,7 +2746,8 @@ end) vim.diagnostic.is_disabled(diagnostic_bufnr, diagnostic_ns), vim.diagnostic.is_disabled(_, diagnostic_ns), } - ]]) + ]] + ) end) end) end) diff --git a/test/functional/lua/ffi_spec.lua b/test/functional/lua/ffi_spec.lua index 3a37b18cd1..c9e8e9d4ca 100644 --- a/test/functional/lua/ffi_spec.lua +++ b/test/functional/lua/ffi_spec.lua @@ -11,7 +11,9 @@ describe('ffi.cdef', function() pending('missing LuaJIT FFI') end - eq(12, exec_lua[[ + eq( + 12, + exec_lua [[ local ffi = require('ffi') ffi.cdef('int curwin_col_off(void);') @@ -19,9 +21,12 @@ describe('ffi.cdef', function() vim.cmd('set number numberwidth=4 signcolumn=yes:4') return ffi.C.curwin_col_off() - ]]) + ]] + ) - eq(20, exec_lua[=[ + eq( + 20, + exec_lua [=[ local ffi = require('ffi') ffi.cdef[[ @@ -38,7 +43,7 @@ describe('ffi.cdef', function() char *out, size_t outlen, char *fmt, - char *opt_name, + int opt_idx, int opt_scope, int fillchar, int maxwidth, @@ -53,7 +58,7 @@ describe('ffi.cdef', function() ffi.new('char[1024]'), 1024, ffi.cast('char*', 'StatusLineOfLength20'), - nil, + -1, 0, 0, 0, @@ -61,15 +66,19 @@ describe('ffi.cdef', function() nil, nil ) - ]=]) + ]=] + ) -- Check that extern symbols are exported and accessible - eq(true, exec_lua[[ + eq( + true, + exec_lua [[ local ffi = require('ffi') ffi.cdef('uint64_t display_tick;') return ffi.C.display_tick >= 0 - ]]) + ]] + ) end) end) diff --git a/test/functional/lua/filetype_spec.lua b/test/functional/lua/filetype_spec.lua index b3d95e1c7f..8b0e0a8beb 100644 --- a/test/functional/lua/filetype_spec.lua +++ b/test/functional/lua/filetype_spec.lua @@ -1,7 +1,7 @@ local helpers = require('test.functional.helpers')(after_each) local exec_lua = helpers.exec_lua local eq = helpers.eq -local meths = helpers.meths +local api = helpers.api local clear = helpers.clear local pathroot = helpers.pathroot local command = helpers.command @@ -19,18 +19,23 @@ describe('vim.filetype', function() end) it('works with extensions', function() - eq('radicalscript', exec_lua [[ + eq( + 'radicalscript', + exec_lua [[ vim.filetype.add({ extension = { rs = 'radicalscript', }, }) return vim.filetype.match({ filename = 'main.rs' }) - ]]) + ]] + ) end) it('prioritizes filenames over extensions', function() - eq('somethingelse', exec_lua [[ + eq( + 'somethingelse', + exec_lua [[ vim.filetype.add({ extension = { rs = 'radicalscript', @@ -40,20 +45,27 @@ describe('vim.filetype', function() }, }) return vim.filetype.match({ filename = 'main.rs' }) - ]]) + ]] + ) end) it('works with filenames', function() - eq('nim', exec_lua [[ + eq( + 'nim', + exec_lua [[ vim.filetype.add({ filename = { ['s_O_m_e_F_i_l_e'] = 'nim', }, }) return vim.filetype.match({ filename = 's_O_m_e_F_i_l_e' }) - ]]) + ]] + ) - eq('dosini', exec_lua([[ + eq( + 'dosini', + exec_lua( + [[ local root = ... vim.filetype.add({ filename = { @@ -62,11 +74,17 @@ describe('vim.filetype', function() }, }) return vim.filetype.match({ filename = root .. '/.config/fun/config' }) - ]], root)) + ]], + root + ) + ) end) it('works with patterns', function() - eq('markdown', exec_lua([[ + eq( + 'markdown', + exec_lua( + [[ local root = ... vim.env.HOME = '/a-funky+home%dir' vim.filetype.add({ @@ -75,13 +93,18 @@ describe('vim.filetype', function() } }) return vim.filetype.match({ filename = '~/blog/why_neovim_is_awesome.txt' }) - ]], root)) + ]], + root + ) + ) end) it('works with functions', function() command('new') command('file relevant_to_me') - eq('foss', exec_lua [[ + eq( + 'foss', + exec_lua [[ vim.filetype.add({ pattern = { ["relevant_to_(%a+)"] = function(path, bufnr, capture) @@ -92,26 +115,33 @@ describe('vim.filetype', function() } }) return vim.filetype.match({ buf = 0 }) - ]]) + ]] + ) end) it('works with contents #22180', function() - eq('sh', exec_lua [[ + eq( + 'sh', + exec_lua [[ -- Needs to be set so detect#sh doesn't fail vim.g.ft_ignore_pat = '\\.\\(Z\\|gz\\|bz2\\|zip\\|tgz\\)$' return vim.filetype.match({ contents = { '#!/usr/bin/env bash' } }) - ]]) + ]] + ) end) it('considers extension mappings when matching from hashbang', function() - eq('fooscript', exec_lua [[ + eq( + 'fooscript', + exec_lua [[ vim.filetype.add({ extension = { foo = 'fooscript', } }) return vim.filetype.match({ contents = { '#!/usr/bin/env foo' } }) - ]]) + ]] + ) end) it('can get default option values for filetypes via vim.filetype.get_option()', function() @@ -120,20 +150,21 @@ describe('vim.filetype', function() for ft, opts in pairs { lua = { commentstring = '-- %s' }, vim = { commentstring = '"%s' }, - man = { tagfunc = 'v:lua.require\'man\'.goto_tag' }, - xml = { formatexpr = 'xmlformat#Format()' } + man = { tagfunc = "v:lua.require'man'.goto_tag" }, + xml = { formatexpr = 'xmlformat#Format()' }, } do for option, value in pairs(opts) do eq(value, exec_lua([[ return vim.filetype.get_option(...) ]], ft, option)) end end - end) end) describe('filetype.lua', function() it('does not override user autocommands that set filetype #20333', function() - clear({args={'--clean', '--cmd', 'autocmd BufRead *.md set filetype=notmarkdown', 'README.md'}}) - eq('notmarkdown', meths.get_option_value('filetype', {})) + clear({ + args = { '--clean', '--cmd', 'autocmd BufRead *.md set filetype=notmarkdown', 'README.md' }, + }) + eq('notmarkdown', api.nvim_get_option_value('filetype', {})) end) end) diff --git a/test/functional/lua/fs_spec.lua b/test/functional/lua/fs_spec.lua index 6bdb9ed79d..6821fe3c5e 100644 --- a/test/functional/lua/fs_spec.lua +++ b/test/functional/lua/fs_spec.lua @@ -1,5 +1,4 @@ local helpers = require('test.functional.helpers')(after_each) -local uv = require('luv') local clear = helpers.clear local exec_lua = helpers.exec_lua @@ -7,8 +6,8 @@ local eq = helpers.eq local mkdir_p = helpers.mkdir_p local rmdir = helpers.rmdir local nvim_dir = helpers.nvim_dir -local test_build_dir = helpers.test_build_dir -local test_source_path = helpers.test_source_path +local test_build_dir = helpers.paths.test_build_dir +local test_source_path = helpers.paths.test_source_path local nvim_prog = helpers.nvim_prog local is_os = helpers.is_os local mkdir = helpers.mkdir @@ -55,40 +54,33 @@ describe('vim.fs', function() it('works', function() local test_dir = nvim_dir .. '/test' mkdir_p(test_dir) - local dirs = exec_lua([[ - local test_dir, test_build_dir = ... - local dirs = {} - for dir in vim.fs.parents(test_dir .. "/foo.txt") do - dirs[#dirs + 1] = dir - if dir == test_build_dir then - break - end + local dirs = {} + for dir in vim.fs.parents(test_dir .. '/foo.txt') do + dirs[#dirs + 1] = dir + if dir == test_build_dir then + break end - return dirs - ]], test_dir, test_build_dir) - eq({test_dir, nvim_dir, test_build_dir}, dirs) + end + eq({ test_dir, nvim_dir, test_build_dir }, dirs) rmdir(test_dir) end) end) describe('dirname()', function() it('works', function() - eq(test_build_dir, exec_lua([[ - local nvim_dir = ... - return vim.fs.dirname(nvim_dir) - ]], nvim_dir)) + eq(test_build_dir, vim.fs.dirname(nvim_dir)) local function test_paths(paths) for _, path in ipairs(paths) do eq( - exec_lua([[ + exec_lua( + [[ local path = ... return vim.fn.fnamemodify(path,':h'):gsub('\\', '/') - ]], path), - exec_lua([[ - local path = ... - return vim.fs.dirname(path) - ]], path), + ]], + path + ), + vim.fs.dirname(path), path ) end @@ -103,23 +95,19 @@ describe('vim.fs', function() describe('basename()', function() it('works', function() - - eq(nvim_prog_basename, exec_lua([[ - local nvim_prog = ... - return vim.fs.basename(nvim_prog) - ]], nvim_prog)) + eq(nvim_prog_basename, vim.fs.basename(nvim_prog)) local function test_paths(paths) for _, path in ipairs(paths) do eq( - exec_lua([[ + exec_lua( + [[ local path = ... return vim.fn.fnamemodify(path,':t'):gsub('\\', '/') - ]], path), - exec_lua([[ - local path = ... - return vim.fs.basename(path) - ]], path), + ]], + path + ), + vim.fs.basename(path), path ) end @@ -145,7 +133,10 @@ describe('vim.fs', function() end) it('works', function() - eq(true, exec_lua([[ + eq( + true, + exec_lua( + [[ local dir, nvim = ... for name, type in vim.fs.dir(dir) do if name == nvim and type == 'file' then @@ -153,7 +144,11 @@ describe('vim.fs', function() end end return false - ]], nvim_dir, nvim_prog_basename)) + ]], + nvim_dir, + nvim_prog_basename + ) + ) end) it('works with opts.depth and opts.skip', function() @@ -171,7 +166,8 @@ describe('vim.fs', function() io.open('testd/a/b/c/c4', 'w'):close() local function run(dir, depth, skip) - local r = exec_lua([[ + local r = exec_lua( + [[ local dir, depth, skip = ... local r = {} local skip_f @@ -186,7 +182,11 @@ describe('vim.fs', function() r[name] = type_ end return r - ]], dir, depth, skip) + ]], + dir, + depth, + skip + ) return r end @@ -212,7 +212,7 @@ describe('vim.fs', function() exp['a/b/c'] = 'directory' eq(exp, run('testd', 3)) - eq(exp, run('testd', 999, {'a/b/c'})) + eq(exp, run('testd', 999, { 'a/b/c' })) exp['a/b/c/a4'] = 'file' exp['a/b/c/b4'] = 'file' @@ -224,88 +224,92 @@ describe('vim.fs', function() describe('find()', function() it('works', function() - eq({test_build_dir .. "/build"}, exec_lua([[ - local dir = ... - return vim.fs.find('build', { path = dir, upward = true, type = 'directory' }) - ]], nvim_dir)) - eq({nvim_prog}, exec_lua([[ - local dir, nvim = ... - return vim.fs.find(nvim, { path = dir, type = 'file' }) - ]], test_build_dir, nvim_prog_basename)) - eq({nvim_dir}, exec_lua([[ - local dir = ... - local parent, name = dir:match('^(.*/)([^/]+)$') - return vim.fs.find(name, { path = parent, upward = true, type = 'directory' }) - ]], nvim_dir)) + eq( + { test_build_dir .. '/build' }, + vim.fs.find('build', { path = nvim_dir, upward = true, type = 'directory' }) + ) + eq({ nvim_prog }, vim.fs.find(nvim_prog_basename, { path = test_build_dir, type = 'file' })) + + local parent, name = nvim_dir:match('^(.*/)([^/]+)$') + eq({ nvim_dir }, vim.fs.find(name, { path = parent, upward = true, type = 'directory' })) end) it('accepts predicate as names', function() - eq({test_build_dir .. "/build"}, exec_lua([[ - local dir = ... - local opts = { path = dir, upward = true, type = 'directory' } - return vim.fs.find(function(x) return x == 'build' end, opts) - ]], nvim_dir)) - eq({nvim_prog}, exec_lua([[ - local dir, nvim = ... - return vim.fs.find(function(x) return x == nvim end, { path = dir, type = 'file' }) - ]], test_build_dir, nvim_prog_basename)) - eq({}, exec_lua([[ - local dir = ... - local opts = { path = dir, upward = true, type = 'directory' } - return vim.fs.find(function(x) return x == 'no-match' end, opts) - ]], nvim_dir)) + local opts = { path = nvim_dir, upward = true, type = 'directory' } + eq( + { test_build_dir .. '/build' }, + vim.fs.find(function(x) + return x == 'build' + end, opts) + ) + eq( + { nvim_prog }, + vim.fs.find(function(x) + return x == nvim_prog_basename + end, { path = test_build_dir, type = 'file' }) + ) + eq( + {}, + vim.fs.find(function(x) + return x == 'no-match' + end, opts) + ) + + opts = { path = test_source_path .. '/contrib', limit = math.huge } eq( - exec_lua([[ + exec_lua( + [[ local dir = ... return vim.tbl_map(vim.fs.basename, vim.fn.glob(dir..'/contrib/*', false, true)) - ]], test_source_path), - exec_lua([[ - local dir = ... - local opts = { path = dir .. "/contrib", limit = math.huge } - return vim.tbl_map(vim.fs.basename, vim.fs.find(function(_, d) return d:match('[\\/]contrib$') end, opts)) - ]], test_source_path)) + ]], + test_source_path + ), + vim.tbl_map( + vim.fs.basename, + vim.fs.find(function(_, d) + return d:match('[\\/]contrib$') + end, opts) + ) + ) end) end) describe('joinpath()', function() it('works', function() - eq('foo/bar/baz', exec_lua([[ - return vim.fs.joinpath('foo', 'bar', 'baz') - ]], nvim_dir)) - eq('foo/bar/baz', exec_lua([[ - return vim.fs.joinpath('foo', '/bar/', '/baz') - ]], nvim_dir)) + eq('foo/bar/baz', vim.fs.joinpath('foo', 'bar', 'baz')) + eq('foo/bar/baz', vim.fs.joinpath('foo', '/bar/', '/baz')) end) end) describe('normalize()', function() it('works with backward slashes', function() - eq('C:/Users/jdoe', exec_lua [[ return vim.fs.normalize('C:\\Users\\jdoe') ]]) + eq('C:/Users/jdoe', vim.fs.normalize('C:\\Users\\jdoe')) end) it('removes trailing /', function() - eq('/home/user', exec_lua [[ return vim.fs.normalize('/home/user/') ]]) + eq('/home/user', vim.fs.normalize('/home/user/')) end) it('works with /', function() - eq('/', exec_lua [[ return vim.fs.normalize('/') ]]) + eq('/', vim.fs.normalize('/')) end) it('works with ~', function() - eq( - exec_lua([[ - local home = ... - return home .. '/src/foo' - ]], vim.fs.normalize(uv.os_homedir())), - exec_lua [[ return vim.fs.normalize('~/src/foo') ]]) + eq(vim.fs.normalize(vim.uv.os_homedir()) .. '/src/foo', vim.fs.normalize('~/src/foo')) end) it('works with environment variables', function() local xdg_config_home = test_build_dir .. '/.config' - eq(xdg_config_home .. '/nvim', exec_lua([[ + eq( + xdg_config_home .. '/nvim', + exec_lua( + [[ vim.env.XDG_CONFIG_HOME = ... return vim.fs.normalize('$XDG_CONFIG_HOME/nvim') - ]], xdg_config_home)) + ]], + xdg_config_home + ) + ) end) if is_os('win') then it('Last slash is not truncated from root drive', function() - eq('C:/', exec_lua [[ return vim.fs.normalize('C:/') ]]) + eq('C:/', vim.fs.normalize('C:/')) end) end end) diff --git a/test/functional/plugin/lsp/watchfiles_spec.lua b/test/functional/lua/glob_spec.lua index a8260e0c98..1eac037575 100644 --- a/test/functional/plugin/lsp/watchfiles_spec.lua +++ b/test/functional/lua/glob_spec.lua @@ -1,14 +1,20 @@ local helpers = require('test.functional.helpers')(after_each) - local eq = helpers.eq local exec_lua = helpers.exec_lua -describe('vim.lsp._watchfiles', function() +describe('glob', function() before_each(helpers.clear) after_each(helpers.clear) local match = function(...) - return exec_lua('return require("vim.lsp._watchfiles")._match(...)', ...) + return exec_lua( + [[ + local pattern = select(1, ...) + local str = select(2, ...) + return require("vim.glob").to_lpeg(pattern):match(str) ~= nil + ]], + ... + ) end describe('glob matching', function() @@ -61,18 +67,16 @@ describe('vim.lsp._watchfiles', function() eq(true, match('dir/*/file.txt', 'dir/subdir/file.txt')) eq(false, match('dir/*/file.txt', 'dir/subdir/subdir/file.txt')) - -- TODO: The spec does not describe this, but VSCode only interprets ** when it's by + -- The spec does not describe this, but VSCode only interprets ** when it's by -- itself in a path segment, and otherwise interprets ** as consecutive * directives. - -- The following tests show how this behavior should work, but is not yet fully implemented. - -- Currently, "a**" parses incorrectly as "a" "**" and "**a" parses correctly as "*" "*" "a". -- see: https://github.com/microsoft/vscode/blob/eef30e7165e19b33daa1e15e92fa34ff4a5df0d3/src/vs/base/common/glob.ts#L112 eq(true, match('a**', 'abc')) -- '**' should parse as two '*'s when not by itself in a path segment eq(true, match('**c', 'abc')) - -- eq(false, match('a**', 'ab')) -- each '*' should still represent at least one character + eq(false, match('a**', 'ab')) -- each '*' should still represent at least one character eq(false, match('**c', 'bc')) eq(true, match('a**', 'abcd')) eq(true, match('**d', 'abcd')) - -- eq(false, match('a**', 'abc/d')) + eq(false, match('a**', 'abc/d')) eq(false, match('**d', 'abc/d')) end) diff --git a/test/functional/lua/help_spec.lua b/test/functional/lua/help_spec.lua deleted file mode 100644 index ef1b8ebf3f..0000000000 --- a/test/functional/lua/help_spec.lua +++ /dev/null @@ -1,53 +0,0 @@ --- Tests for gen_help_html.lua. Validates :help tags/links and HTML doc generation. --- --- TODO: extract parts of gen_help_html.lua into Nvim stdlib? - -local helpers = require('test.functional.helpers')(after_each) -local clear = helpers.clear -local exec_lua = helpers.exec_lua -local eq = helpers.eq -local ok = helpers.ok - -if helpers.skip(helpers.is_ci('cirrus'), 'No need to run this on Cirrus') then return end - -describe(':help docs', function() - before_each(clear) - it('validate', function() - -- If this test fails, try these steps (in order): - -- 1. Fix/cleanup the :help docs. - -- 2. Fix the parser: https://github.com/neovim/tree-sitter-vimdoc - -- 3. File a parser bug, and adjust the tolerance of this test in the meantime. - - local rv = exec_lua([[return require('scripts.gen_help_html').validate('./build/runtime/doc')]]) - -- Check that we actually found helpfiles. - ok(rv.helpfiles > 100, '>100 :help files', rv.helpfiles) - - eq({}, rv.parse_errors, 'no parse errors') - eq(0, rv.err_count, 'no parse errors') - eq({}, rv.invalid_links, 'invalid tags in :help docs') - eq({}, rv.invalid_urls, 'invalid URLs in :help docs') - eq({}, rv.invalid_spelling, 'invalid spelling in :help docs (see spell_dict in scripts/gen_help_html.lua)') - end) - - it('gen_help_html.lua generates HTML', function() - -- 1. Test that gen_help_html.lua actually works. - -- 2. Test that parse errors did not increase wildly. Because we explicitly test only a few - -- :help files, we can be precise about the tolerances here. - - local tmpdir = exec_lua('return vim.fs.dirname(vim.fn.tempname())') - -- Because gen() is slow (~30s), this test is limited to a few files. - local rv = exec_lua([[ - local to_dir = ... - return require('scripts.gen_help_html').gen( - './build/runtime/doc', - to_dir, - { 'pi_health.txt', 'help.txt', 'index.txt', 'nvim.txt', } - ) - ]], - tmpdir - ) - eq(4, #rv.helpfiles) - eq(0, rv.err_count, 'parse errors in :help docs') - eq({}, rv.invalid_links, 'invalid tags in :help docs') - end) -end) diff --git a/test/functional/lua/highlight_spec.lua b/test/functional/lua/highlight_spec.lua index 8e499f1e79..197f3139f3 100644 --- a/test/functional/lua/highlight_spec.lua +++ b/test/functional/lua/highlight_spec.lua @@ -1,9 +1,11 @@ local helpers = require('test.functional.helpers')(after_each) local exec_lua = helpers.exec_lua local eq = helpers.eq +local neq = helpers.neq local eval = helpers.eval local command = helpers.command local clear = helpers.clear +local api = helpers.api describe('vim.highlight.on_yank', function() before_each(function() @@ -16,7 +18,7 @@ describe('vim.highlight.on_yank', function() vim.highlight.on_yank({timeout = 10, on_macro = true, event = {operator = "y", regtype = "v"}}) vim.cmd('bwipeout!') ]]) - helpers.sleep(10) + vim.uv.sleep(10) helpers.feed('<cr>') -- avoid hang if error message exists eq('', eval('v:errmsg')) end) @@ -31,4 +33,34 @@ describe('vim.highlight.on_yank', function() ]]) eq('', eval('v:errmsg')) end) + + it('does not show in another window', function() + command('vsplit') + exec_lua([[ + vim.api.nvim_buf_set_mark(0,"[",1,1,{}) + vim.api.nvim_buf_set_mark(0,"]",1,1,{}) + vim.highlight.on_yank({timeout = math.huge, on_macro = true, event = {operator = "y"}}) + ]]) + neq({}, api.nvim_win_get_ns(0)) + command('wincmd w') + eq({}, api.nvim_win_get_ns(0)) + end) + + it('removes old highlight if new one is created before old one times out', function() + command('vnew') + exec_lua([[ + vim.api.nvim_buf_set_mark(0,"[",1,1,{}) + vim.api.nvim_buf_set_mark(0,"]",1,1,{}) + vim.highlight.on_yank({timeout = math.huge, on_macro = true, event = {operator = "y"}}) + ]]) + neq({}, api.nvim_win_get_ns(0)) + command('wincmd w') + exec_lua([[ + vim.api.nvim_buf_set_mark(0,"[",1,1,{}) + vim.api.nvim_buf_set_mark(0,"]",1,1,{}) + vim.highlight.on_yank({timeout = math.huge, on_macro = true, event = {operator = "y"}}) + ]]) + command('wincmd w') + eq({}, api.nvim_win_get_ns(0)) + end) end) diff --git a/test/functional/lua/inspector_spec.lua b/test/functional/lua/inspector_spec.lua index c369956e56..ad8b5a45a8 100644 --- a/test/functional/lua/inspector_spec.lua +++ b/test/functional/lua/inspector_spec.lua @@ -46,9 +46,9 @@ describe('vim.inspect_pos', function() hl_group_link = 'Normal', ns_id = 1, priority = 4096, - right_gravity = true + right_gravity = true, }, - row = 0 + row = 0, }, { col = 10, @@ -63,10 +63,10 @@ describe('vim.inspect_pos', function() hl_group_link = 'Normal', ns_id = 2, priority = 4096, - right_gravity = true + right_gravity = true, }, - row = 0 - } + row = 0, + }, }, treesitter = {}, semantic_tokens = {}, diff --git a/test/functional/lua/iter_spec.lua b/test/functional/lua/iter_spec.lua index ffa28e7b11..8d6cf1264b 100644 --- a/test/functional/lua/iter_spec.lua +++ b/test/functional/lua/iter_spec.lua @@ -6,11 +6,11 @@ local pcall_err = helpers.pcall_err describe('vim.iter', function() it('new() on iterable class instance', function() local rb = vim.ringbuf(3) - rb:push("a") - rb:push("b") + rb:push('a') + rb:push('b') local it = vim.iter(rb) - eq({"a", "b"}, it:totable()) + eq({ 'a', 'b' }, it:totable()) end) it('filter()', function() @@ -20,18 +20,43 @@ describe('vim.iter', function() local t = { 1, 2, 3, 4, 5 } eq({ 1, 3, 5 }, vim.iter(t):filter(odd):totable()) - eq({ 2, 4 }, vim.iter(t):filter(function(v) return not odd(v) end):totable()) - eq({}, vim.iter(t):filter(function(v) return v > 5 end):totable()) + eq( + { 2, 4 }, + vim + .iter(t) + :filter(function(v) + return not odd(v) + end) + :totable() + ) + eq( + {}, + vim + .iter(t) + :filter(function(v) + return v > 5 + end) + :totable() + ) do local it = vim.iter(ipairs(t)) - it:filter(function(i, v) return i > 1 and v < 5 end) - it:map(function(_, v) return v * 2 end) + it:filter(function(i, v) + return i > 1 and v < 5 + end) + it:map(function(_, v) + return v * 2 + end) eq({ 4, 6, 8 }, it:totable()) end local it = vim.iter(string.gmatch('the quick brown fox', '%w+')) - eq({'the', 'fox'}, it:filter(function(s) return #s <= 3 end):totable()) + eq( + { 'the', 'fox' }, + it:filter(function(s) + return #s <= 3 + end):totable() + ) end) it('map()', function() @@ -39,11 +64,11 @@ describe('vim.iter', function() eq( { 2, 4, 6, 8, 10 }, vim - .iter(t) - :map(function(v) - return 2 * v - end) - :totable() + .iter(t) + :map(function(v) + return 2 * v + end) + :totable() ) local it = vim.gsplit( @@ -59,21 +84,25 @@ describe('vim.iter', function() eq( { 'Lion 2', 'Lion 4' }, vim - .iter(it) - :map(function(s) - local lnum = s:match('(%d+)') - if lnum and tonumber(lnum) % 2 == 0 then - return vim.trim(s:gsub('Line', 'Lion')) - end - end) - :totable() + .iter(it) + :map(function(s) + local lnum = s:match('(%d+)') + if lnum and tonumber(lnum) % 2 == 0 then + return vim.trim(s:gsub('Line', 'Lion')) + end + end) + :totable() ) end) it('for loops', function() - local t = {1, 2, 3, 4, 5} + local t = { 1, 2, 3, 4, 5 } local acc = 0 - for v in vim.iter(t):map(function(v) return v * 3 end) do + for v in + vim.iter(t):map(function(v) + return v * 3 + end) + do acc = acc + v end eq(45, acc) @@ -81,18 +110,27 @@ describe('vim.iter', function() it('totable()', function() do - local it = vim.iter({1, 2, 3}):map(function(v) return v, v*v end) - eq({{1, 1}, {2, 4}, {3, 9}}, it:totable()) + local it = vim.iter({ 1, 2, 3 }):map(function(v) + return v, v * v + end) + eq({ { 1, 1 }, { 2, 4 }, { 3, 9 } }, it:totable()) end do local it = vim.iter(string.gmatch('1,4,lol,17,blah,2,9,3', '%d+')):map(tonumber) - eq({1, 4, 17, 2, 9, 3}, it:totable()) + eq({ 1, 4, 17, 2, 9, 3 }, it:totable()) end end) + it('join()', function() + eq('1, 2, 3', vim.iter({ 1, 2, 3 }):join(', ')) + eq('a|b|c|d', vim.iter(vim.gsplit('a|b|c|d', '|')):join('|')) + end) + it('next()', function() - local it = vim.iter({1, 2, 3}):map(function(v) return 2 * v end) + local it = vim.iter({ 1, 2, 3 }):map(function(v) + return 2 * v + end) eq(2, it:next()) eq(4, it:next()) eq(6, it:next()) @@ -100,19 +138,19 @@ describe('vim.iter', function() end) it('rev()', function() - eq({3, 2, 1}, vim.iter({1, 2, 3}):rev():totable()) + eq({ 3, 2, 1 }, vim.iter({ 1, 2, 3 }):rev():totable()) - local it = vim.iter(string.gmatch("abc", "%w")) + local it = vim.iter(string.gmatch('abc', '%w')) matches('rev%(%) requires a list%-like table', pcall_err(it.rev, it)) end) it('skip()', function() do - local t = {4, 3, 2, 1} + local t = { 4, 3, 2, 1 } eq(t, vim.iter(t):skip(0):totable()) - eq({3, 2, 1}, vim.iter(t):skip(1):totable()) - eq({2, 1}, vim.iter(t):skip(2):totable()) - eq({1}, vim.iter(t):skip(#t - 1):totable()) + eq({ 3, 2, 1 }, vim.iter(t):skip(1):totable()) + eq({ 2, 1 }, vim.iter(t):skip(2):totable()) + eq({ 1 }, vim.iter(t):skip(#t - 1):totable()) eq({}, vim.iter(t):skip(#t):totable()) eq({}, vim.iter(t):skip(#t + 1):totable()) end @@ -121,10 +159,10 @@ describe('vim.iter', function() local function skip(n) return vim.iter(vim.gsplit('a|b|c|d', '|')):skip(n):totable() end - eq({'a', 'b', 'c', 'd'}, skip(0)) - eq({'b', 'c', 'd'}, skip(1)) - eq({'c', 'd'}, skip(2)) - eq({'d'}, skip(3)) + eq({ 'a', 'b', 'c', 'd' }, skip(0)) + eq({ 'b', 'c', 'd' }, skip(1)) + eq({ 'c', 'd' }, skip(2)) + eq({ 'd' }, skip(3)) eq({}, skip(4)) eq({}, skip(5)) end @@ -132,11 +170,11 @@ describe('vim.iter', function() it('skipback()', function() do - local t = {4, 3, 2, 1} + local t = { 4, 3, 2, 1 } eq(t, vim.iter(t):skipback(0):totable()) - eq({4, 3, 2}, vim.iter(t):skipback(1):totable()) - eq({4, 3}, vim.iter(t):skipback(2):totable()) - eq({4}, vim.iter(t):skipback(#t - 1):totable()) + eq({ 4, 3, 2 }, vim.iter(t):skipback(1):totable()) + eq({ 4, 3 }, vim.iter(t):skipback(2):totable()) + eq({ 4 }, vim.iter(t):skipback(#t - 1):totable()) eq({}, vim.iter(t):skipback(#t):totable()) eq({}, vim.iter(t):skipback(#t + 1):totable()) end @@ -146,14 +184,14 @@ describe('vim.iter', function() end) it('slice()', function() - local t = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} - eq({3, 4, 5, 6, 7}, vim.iter(t):slice(3, 7):totable()) + local t = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } + eq({ 3, 4, 5, 6, 7 }, vim.iter(t):slice(3, 7):totable()) eq({}, vim.iter(t):slice(6, 5):totable()) eq({}, vim.iter(t):slice(0, 0):totable()) - eq({1}, vim.iter(t):slice(1, 1):totable()) - eq({1, 2}, vim.iter(t):slice(1, 2):totable()) - eq({10}, vim.iter(t):slice(10, 10):totable()) - eq({8, 9, 10}, vim.iter(t):slice(8, 11):totable()) + eq({ 1 }, vim.iter(t):slice(1, 1):totable()) + eq({ 1, 2 }, vim.iter(t):slice(1, 2):totable()) + eq({ 10 }, vim.iter(t):slice(10, 10):totable()) + eq({ 8, 9, 10 }, vim.iter(t):slice(8, 11):totable()) local it = vim.iter(vim.gsplit('a|b|c|d', '|')) matches('slice%(%) requires a list%-like table', pcall_err(it.slice, it, 1, 3)) @@ -161,7 +199,7 @@ describe('vim.iter', function() it('nth()', function() do - local t = {4, 3, 2, 1} + local t = { 4, 3, 2, 1 } eq(nil, vim.iter(t):nth(0)) eq(4, vim.iter(t):nth(1)) eq(3, vim.iter(t):nth(2)) @@ -185,7 +223,7 @@ describe('vim.iter', function() it('nthback()', function() do - local t = {4, 3, 2, 1} + local t = { 4, 3, 2, 1 } eq(nil, vim.iter(t):nthback(0)) eq(1, vim.iter(t):nthback(1)) eq(2, vim.iter(t):nthback(2)) @@ -198,6 +236,33 @@ describe('vim.iter', function() matches('skipback%(%) requires a list%-like table', pcall_err(it.nthback, it, 1)) end) + it('take()', function() + do + local t = { 4, 3, 2, 1 } + eq({}, vim.iter(t):take(0):totable()) + eq({ 4 }, vim.iter(t):take(1):totable()) + eq({ 4, 3 }, vim.iter(t):take(2):totable()) + eq({ 4, 3, 2 }, vim.iter(t):take(3):totable()) + eq({ 4, 3, 2, 1 }, vim.iter(t):take(4):totable()) + eq({ 4, 3, 2, 1 }, vim.iter(t):take(5):totable()) + end + + do + local t = { 4, 3, 2, 1 } + local it = vim.iter(t) + eq({ 4, 3 }, it:take(2):totable()) + -- tail is already set from the previous take() + eq({ 4, 3 }, it:take(3):totable()) + end + + do + local it = vim.iter(vim.gsplit('a|b|c|d', '|')) + eq({ 'a', 'b' }, it:take(2):totable()) + -- non-array iterators are consumed by take() + eq({}, it:take(2):totable()) + end + end) + it('any()', function() local function odd(v) return v % 2 ~= 0 @@ -214,8 +279,18 @@ describe('vim.iter', function() end do - eq(true, vim.iter(vim.gsplit('a|b|c|d', '|')):any(function(s) return s == 'd' end)) - eq(false, vim.iter(vim.gsplit('a|b|c|d', '|')):any(function(s) return s == 'e' end)) + eq( + true, + vim.iter(vim.gsplit('a|b|c|d', '|')):any(function(s) + return s == 'd' + end) + ) + eq( + false, + vim.iter(vim.gsplit('a|b|c|d', '|')):any(function(s) + return s == 'e' + end) + ) end end) @@ -235,8 +310,18 @@ describe('vim.iter', function() end do - eq(true, vim.iter(vim.gsplit('a|a|a|a', '|')):all(function(s) return s == 'a' end)) - eq(false, vim.iter(vim.gsplit('a|a|a|b', '|')):all(function(s) return s == 'a' end)) + eq( + true, + vim.iter(vim.gsplit('a|a|a|a', '|')):all(function(s) + return s == 'a' + end) + ) + eq( + false, + vim.iter(vim.gsplit('a|a|a|b', '|')):all(function(s) + return s == 'a' + end) + ) end end) @@ -248,10 +333,10 @@ describe('vim.iter', function() it('enumerate()', function() local it = vim.iter(vim.gsplit('abc', '')):enumerate() - eq({1, 'a'}, {it:next()}) - eq({2, 'b'}, {it:next()}) - eq({3, 'c'}, {it:next()}) - eq({}, {it:next()}) + eq({ 1, 'a' }, { it:next() }) + eq({ 2, 'b' }, { it:next() }) + eq({ 3, 'c' }, { it:next() }) + eq({}, { it:next() }) end) it('peek()', function() @@ -269,14 +354,21 @@ describe('vim.iter', function() end) it('find()', function() - local t = {3, 6, 9, 12} + local t = { 3, 6, 9, 12 } eq(12, vim.iter(t):find(12)) eq(nil, vim.iter(t):find(15)) - eq(12, vim.iter(t):find(function(v) return v % 4 == 0 end)) + eq( + 12, + vim.iter(t):find(function(v) + return v % 4 == 0 + end) + ) do local it = vim.iter(t) - local pred = function(v) return v % 3 == 0 end + local pred = function(v) + return v % 3 == 0 + end eq(3, it:find(pred)) eq(6, it:find(pred)) eq(9, it:find(pred)) @@ -286,7 +378,9 @@ describe('vim.iter', function() do local it = vim.iter(vim.gsplit('AbCdE', '')) - local pred = function(s) return s:match('[A-Z]') end + local pred = function(s) + return s:match('[A-Z]') + end eq('A', it:find(pred)) eq('C', it:find(pred)) eq('E', it:find(pred)) @@ -295,7 +389,7 @@ describe('vim.iter', function() end) it('rfind()', function() - local t = {1, 2, 3, 2, 1} + local t = { 1, 2, 3, 2, 1 } do local it = vim.iter(t) eq(1, it:rfind(1)) @@ -305,10 +399,12 @@ describe('vim.iter', function() do local it = vim.iter(t):enumerate() - local pred = function(i) return i % 2 ~= 0 end - eq({5, 1}, {it:rfind(pred)}) - eq({3, 3}, {it:rfind(pred)}) - eq({1, 1}, {it:rfind(pred)}) + local pred = function(i) + return i % 2 ~= 0 + end + eq({ 5, 1 }, { it:rfind(pred) }) + eq({ 3, 3 }, { it:rfind(pred) }) + eq({ 1, 1 }, { it:rfind(pred) }) eq(nil, it:rfind(pred)) end @@ -350,12 +446,52 @@ describe('vim.iter', function() end) it('fold()', function() - local t = {1, 2, 3, 4, 5} - eq(115, vim.iter(t):fold(100, function(acc, v) return acc + v end)) - eq({5, 4, 3, 2, 1}, vim.iter(t):fold({}, function(acc, v) - table.insert(acc, 1, v) - return acc - end)) + local t = { 1, 2, 3, 4, 5 } + eq( + 115, + vim.iter(t):fold(100, function(acc, v) + return acc + v + end) + ) + eq( + { 5, 4, 3, 2, 1 }, + vim.iter(t):fold({}, function(acc, v) + table.insert(acc, 1, v) + return acc + end) + ) + end) + + it('flatten()', function() + local t = { { 1, { 2 } }, { { { { 3 } } }, { 4 } }, { 5 } } + + eq(t, vim.iter(t):flatten(-1):totable()) + eq(t, vim.iter(t):flatten(0):totable()) + eq({ 1, { 2 }, { { { 3 } } }, { 4 }, 5 }, vim.iter(t):flatten():totable()) + eq({ 1, 2, { { 3 } }, 4, 5 }, vim.iter(t):flatten(2):totable()) + eq({ 1, 2, { 3 }, 4, 5 }, vim.iter(t):flatten(3):totable()) + eq({ 1, 2, 3, 4, 5 }, vim.iter(t):flatten(4):totable()) + + local m = { a = 1, b = { 2, 3 }, d = { 4 } } + local it = vim.iter(m) + + local flat_err = 'flatten%(%) requires a list%-like table' + matches(flat_err, pcall_err(it.flatten, it)) + + -- cases from the documentation + local simple_example = { 1, { 2 }, { { 3 } } } + eq({ 1, 2, { 3 } }, vim.iter(simple_example):flatten():totable()) + + local not_list_like = vim.iter({ [2] = 2 }) + matches(flat_err, pcall_err(not_list_like.flatten, not_list_like)) + + local also_not_list_like = vim.iter({ nil, 2 }) + matches(flat_err, pcall_err(not_list_like.flatten, also_not_list_like)) + + local nested_non_lists = vim.iter({ 1, { { a = 2 } }, { { nil } }, { 3 } }) + eq({ 1, { a = 2 }, { nil }, 3 }, nested_non_lists:flatten():totable()) + -- only error if we're going deep enough to flatten a dict-like table + matches(flat_err, pcall_err(nested_non_lists.flatten, nested_non_lists, math.huge)) end) it('handles map-like tables', function() @@ -385,9 +521,12 @@ describe('vim.iter', function() }, } - local output = vim.iter(map):map(function(key, value) - return { [key] = value.file } - end):totable() + local output = vim + .iter(map) + :map(function(key, value) + return { [key] = value.file } + end) + :totable() table.sort(output, function(a, b) return next(a) < next(b) diff --git a/test/functional/lua/json_spec.lua b/test/functional/lua/json_spec.lua index 25fdb48eea..d348e2de3c 100644 --- a/test/functional/lua/json_spec.lua +++ b/test/functional/lua/json_spec.lua @@ -16,40 +16,44 @@ describe('vim.json.decode()', function() end) it('validation', function() - eq('Expected object key string but found invalid token at character 2', - pcall_err(exec_lua, [[return vim.json.decode('{a:"b"}')]])) + eq( + 'Expected object key string but found invalid token at character 2', + pcall_err(exec_lua, [[return vim.json.decode('{a:"b"}')]]) + ) end) it('options', function() local jsonstr = '{"arr":[1,2,null],"bar":[3,7],"foo":{"a":"b"},"baz":null}' eq({ - arr = { 1, 2, vim.NIL }, - bar = { 3, 7 }, - baz = vim.NIL, - foo = { a = 'b' }, - }, - exec_lua([[return vim.json.decode(..., {})]], jsonstr)) - eq({ - arr = { 1, 2, vim.NIL }, - bar = { 3, 7 }, - -- baz = nil, - foo = { a = 'b' }, - }, - exec_lua([[return vim.json.decode(..., { luanil = { object = true } })]], jsonstr)) + arr = { 1, 2, vim.NIL }, + bar = { 3, 7 }, + baz = vim.NIL, + foo = { a = 'b' }, + }, exec_lua([[return vim.json.decode(..., {})]], jsonstr)) eq({ - arr = { 1, 2 }, - bar = { 3, 7 }, - baz = vim.NIL, - foo = { a = 'b' }, - }, - exec_lua([[return vim.json.decode(..., { luanil = { array = true } })]], jsonstr)) + arr = { 1, 2, vim.NIL }, + bar = { 3, 7 }, + -- baz = nil, + foo = { a = 'b' }, + }, exec_lua([[return vim.json.decode(..., { luanil = { object = true } })]], jsonstr)) eq({ + arr = { 1, 2 }, + bar = { 3, 7 }, + baz = vim.NIL, + foo = { a = 'b' }, + }, exec_lua([[return vim.json.decode(..., { luanil = { array = true } })]], jsonstr)) + eq( + { arr = { 1, 2 }, bar = { 3, 7 }, -- baz = nil, foo = { a = 'b' }, }, - exec_lua([[return vim.json.decode(..., { luanil = { array = true, object = true } })]], jsonstr)) + exec_lua( + [[return vim.json.decode(..., { luanil = { array = true, object = true } })]], + jsonstr + ) + ) end) it('parses integer numbers', function() @@ -96,11 +100,15 @@ describe('vim.json.decode()', function() end) it('parses containers', function() - eq({1}, exec_lua([[return vim.json.decode('[1]')]])) - eq({vim.NIL, 1}, exec_lua([[return vim.json.decode('[null, 1]')]])) - eq({['1']=2}, exec_lua([[return vim.json.decode('{"1": 2}')]])) - eq({['1']=2, ['3']={{['4']={['5']={{}, 1}}}}}, - exec_lua([[return vim.json.decode('{"1": 2, "3": [{"4": {"5": [ [], 1]}}]}')]])) + eq({ 1 }, exec_lua([[return vim.json.decode('[1]')]])) + eq({ vim.NIL, 1 }, exec_lua([[return vim.json.decode('[null, 1]')]])) + eq({ ['1'] = 2 }, exec_lua([[return vim.json.decode('{"1": 2}')]])) + eq( + { ['1'] = 2, ['3'] = { { ['4'] = { ['5'] = { {}, 1 } } } } }, + exec_lua([[return vim.json.decode('{"1": 2, "3": [{"4": {"5": [ [], 1]}}]}')]]) + ) + -- Empty string is a valid key. #20757 + eq({ [''] = 42 }, exec_lua([[return vim.json.decode('{"": 42}')]])) end) it('parses strings properly', function() @@ -109,8 +117,8 @@ describe('vim.json.decode()', function() eq('\\/"\t\b\n\r\f', exec_lua([=[return vim.json.decode([["\\\/\"\t\b\n\r\f"]])]=])) eq('/a', exec_lua([=[return vim.json.decode([["\/a"]])]=])) -- Unicode characters: 2-byte, 3-byte - eq('«',exec_lua([=[return vim.json.decode([["«"]])]=])) - eq('ફ',exec_lua([=[return vim.json.decode([["ફ"]])]=])) + eq('«', exec_lua([=[return vim.json.decode([["«"]])]=])) + eq('ફ', exec_lua([=[return vim.json.decode([["ફ"]])]=])) end) it('parses surrogate pairs properly', function() @@ -118,11 +126,11 @@ describe('vim.json.decode()', function() end) it('accepts all spaces in every position where space may be put', function() - local s = ' \t\n\r \t\r\n \n\t\r \n\r\t \r\t\n \r\n\t\t \n\r\t \r\n\t\n \r\t\n\r \t\r \n\t\r\n \n \t\r\n \r\t\n\t \r\n\t\r \n\r \t\n\r\t \r \t\n\r \n\t\r\t \n\r\t\n \r\n \t\r\n\t' + local s = + ' \t\n\r \t\r\n \n\t\r \n\r\t \r\t\n \r\n\t\t \n\r\t \r\n\t\n \r\t\n\r \t\r \n\t\r\n \n \t\r\n \r\t\n\t \r\n\t\r \n\r \t\n\r\t \r \t\n\r \n\t\r\t \n\r\t\n \r\n \t\r\n\t' local str = ('%s{%s"key"%s:%s[%s"val"%s,%s"val2"%s]%s,%s"key2"%s:%s1%s}%s'):gsub('%%s', s) - eq({key={'val', 'val2'}, key2=1}, exec_lua([[return vim.json.decode(...)]], str)) + eq({ key = { 'val', 'val2' }, key2 = 1 }, exec_lua([[return vim.json.decode(...)]], str)) end) - end) describe('vim.json.encode()', function() @@ -161,10 +169,11 @@ describe('vim.json.encode()', function() it('dumps dictionaries', function() eq('{}', exec_lua([[return vim.json.encode(vim.empty_dict())]])) eq('{"d":[]}', exec_lua([[return vim.json.encode({d={}})]])) + -- Empty string is a valid key. #20757 + eq('{"":42}', exec_lua([[return vim.json.encode({['']=42})]])) end) it('dumps vim.NIL', function() eq('null', exec_lua([[return vim.json.encode(vim.NIL)]])) end) - end) diff --git a/test/functional/lua/loader_spec.lua b/test/functional/lua/loader_spec.lua index 34c36b04ef..4e42a18405 100644 --- a/test/functional/lua/loader_spec.lua +++ b/test/functional/lua/loader_spec.lua @@ -3,43 +3,77 @@ local helpers = require('test.functional.helpers')(after_each) local exec_lua = helpers.exec_lua local command = helpers.command +local clear = helpers.clear local eq = helpers.eq describe('vim.loader', function() - before_each(helpers.clear) + before_each(clear) + + it('can work in compatibility with --luamod-dev #27413', function() + clear({ args = { '--luamod-dev' } }) + exec_lua [[ + vim.loader.enable() + + require("vim.fs") + + -- try to load other vim submodules as well (Nvim Lua stdlib) + for key, _ in pairs(vim._submodules) do + local modname = 'vim.' .. key -- e.g. "vim.fs" + + local lhs = vim[key] + local rhs = require(modname) + assert( + lhs == rhs, + ('%s != require("%s"), %s != %s'):format(modname, modname, tostring(lhs), tostring(rhs)) + ) + end + ]] + end) it('handles changing files (#23027)', function() - exec_lua[[ + exec_lua [[ vim.loader.enable() ]] local tmp = helpers.tmpname() command('edit ' .. tmp) - eq(1, exec_lua([[ + eq( + 1, + exec_lua( + [[ vim.api.nvim_buf_set_lines(0, 0, -1, true, {'_G.TEST=1'}) vim.cmd.write() loadfile(...)() return _G.TEST - ]], tmp)) + ]], + tmp + ) + ) -- fs latency - helpers.sleep(10) + vim.uv.sleep(10) - eq(2, exec_lua([[ + eq( + 2, + exec_lua( + [[ vim.api.nvim_buf_set_lines(0, 0, -1, true, {'_G.TEST=2'}) vim.cmd.write() loadfile(...)() return _G.TEST - ]], tmp)) + ]], + tmp + ) + ) end) it('handles % signs in modpath (#24491)', function() - exec_lua[[ + exec_lua [[ vim.loader.enable() ]] - local tmp1, tmp2 = (function (t) + local tmp1, tmp2 = (function(t) assert(os.remove(t)) assert(helpers.mkdir(t)) assert(helpers.mkdir(t .. '/%')) diff --git a/test/functional/lua/loop_spec.lua b/test/functional/lua/loop_spec.lua index c0924fa0c0..71eaf29009 100644 --- a/test/functional/lua/loop_spec.lua +++ b/test/functional/lua/loop_spec.lua @@ -1,10 +1,10 @@ -- Test suite for testing interactions with API bindings local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local clear = helpers.clear -local sleep = helpers.sleep +local sleep = vim.uv.sleep local feed = helpers.feed local eq = helpers.eq local eval = helpers.eval @@ -15,23 +15,20 @@ local retry = helpers.retry before_each(clear) describe('vim.uv', function() - it('version', function() - assert(funcs.luaeval('vim.uv.version()')>=72961, "libuv version too old") - matches("(%d+)%.(%d+)%.(%d+)", funcs.luaeval('vim.uv.version_string()')) + assert(fn.luaeval('vim.uv.version()') >= 72961, 'libuv version too old') + matches('(%d+)%.(%d+)%.(%d+)', fn.luaeval('vim.uv.version_string()')) end) it('timer', function() exec_lua('vim.api.nvim_set_var("coroutine_cnt", 0)', {}) - local code=[[ - local uv = vim.uv - + local code = [[ local touch = 0 local function wait(ms) local this = coroutine.running() assert(this) - local timer = uv.new_timer() + local timer = vim.uv.new_timer() timer:start(ms, 0, vim.schedule_wrap(function () timer:close() touch = touch + 1 @@ -51,24 +48,24 @@ describe('vim.uv', function() end)() ]] - eq(0, meths.get_var('coroutine_cnt')) + eq(0, api.nvim_get_var('coroutine_cnt')) exec_lua(code) retry(2, nil, function() sleep(50) - eq(2, meths.get_var('coroutine_cnt')) + eq(2, api.nvim_get_var('coroutine_cnt')) end) - eq(3, meths.get_var('coroutine_cnt_1')) + eq(3, api.nvim_get_var('coroutine_cnt_1')) end) it('is API safe', function() - local screen = Screen.new(50,10) + local screen = Screen.new(50, 10) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {bold = true, reverse = true}, - [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [4] = {bold = true, foreground = Screen.colors.SeaGreen4}, - [5] = {bold = true}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { bold = true, reverse = true }, + [3] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [5] = { bold = true }, }) -- deferred API functions are disabled, as their safety can't be guaranteed @@ -96,7 +93,7 @@ describe('vim.uv', function() ]]) feed('<cr>') eq(false, eval("get(g:, 'valid', v:false)")) - eq(true, exec_lua("return _G.is_fast")) + eq(true, exec_lua('return _G.is_fast')) -- callbacks can be scheduled to be executed in the main event loop -- where the entire API is available @@ -112,18 +109,11 @@ describe('vim.uv', function() screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 howdy | ]]) eq(true, eval("get(g:, 'valid', v:false)")) - eq(false, exec_lua("return _G.is_fast")) + eq(false, exec_lua('return _G.is_fast')) -- fast (not deferred) API functions are allowed to be called directly exec_lua([[ @@ -137,17 +127,10 @@ describe('vim.uv', function() ]]) screen:expect([[ sneaky^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 {5:-- INSERT --} | ]]) - eq({blocking=false, mode='n'}, exec_lua("return _G.mode")) + eq({ blocking = false, mode = 'n' }, exec_lua('return _G.mode')) end) it("is equal to require('luv')", function() diff --git a/test/functional/lua/luaeval_spec.lua b/test/functional/lua/luaeval_spec.lua index dfbd2fb18b..b28cfa4dd2 100644 --- a/test/functional/lua/luaeval_spec.lua +++ b/test/functional/lua/luaeval_spec.lua @@ -7,12 +7,12 @@ local exc_exec = helpers.exc_exec local remove_trace = helpers.remove_trace local exec_lua = helpers.exec_lua local command = helpers.command -local meths = helpers.meths -local funcs = helpers.funcs +local api = helpers.api +local fn = helpers.fn local clear = helpers.clear local eval = helpers.eval local feed = helpers.feed -local NIL = helpers.NIL +local NIL = vim.NIL local eq = helpers.eq before_each(clear) @@ -39,7 +39,7 @@ describe('luaeval()', function() describe('second argument', function() it('is successfully received', function() local t = {t=true, f=false, --[[n=NIL,]] d={l={'string', 42, 0.42}}} - eq(t, funcs.luaeval("_A", t)) + eq(t, fn.luaeval("_A", t)) -- Not tested: nil, funcrefs, returned object identity: behaviour will -- most likely change. end) @@ -47,39 +47,37 @@ describe('luaeval()', function() describe('lua values', function() it('are successfully transformed', function() eq({n=1, f=1.5, s='string', l={4, 2}}, - funcs.luaeval('{n=1, f=1.5, s="string", l={4, 2}}')) + fn.luaeval('{n=1, f=1.5, s="string", l={4, 2}}')) -- Not tested: nil inside containers: behaviour will most likely change. - eq(NIL, funcs.luaeval('nil')) - eq({['']=1}, funcs.luaeval('{[""]=1}')) + eq(NIL, fn.luaeval('nil')) + eq({['']=1}, fn.luaeval('{[""]=1}')) end) end) describe('recursive lua values', function() it('are successfully transformed', function() command('lua rawset(_G, "d", {})') command('lua rawset(d, "d", d)') - eq('\n{\'d\': {...@0}}', funcs.execute('echo luaeval("d")')) + eq('\n{\'d\': {...@0}}', fn.execute('echo luaeval("d")')) command('lua rawset(_G, "l", {})') command('lua table.insert(l, l)') - eq('\n[[...@0]]', funcs.execute('echo luaeval("l")')) + eq('\n[[...@0]]', fn.execute('echo luaeval("l")')) end) end) describe('strings with NULs', function() it('are successfully converted to blobs', function() command([[let s = luaeval('"\0"')]]) - eq('\000', meths.get_var('s')) + eq('\000', api.nvim_get_var('s')) end) - it('are successfully converted to special dictionaries in table keys', - function() + it('are successfully converted to special dictionaries in table keys', function() command([[let d = luaeval('{["\0"]=1}')]]) - eq({_TYPE={}, _VAL={{{_TYPE={}, _VAL={'\n'}}, 1}}}, meths.get_var('d')) - eq(1, funcs.eval('d._TYPE is v:msgpack_types.map')) - eq(1, funcs.eval('d._VAL[0][0]._TYPE is v:msgpack_types.string')) + eq({_TYPE={}, _VAL={{{_TYPE={}, _VAL={'\n'}}, 1}}}, api.nvim_get_var('d')) + eq(1, fn.eval('d._TYPE is v:msgpack_types.map')) + eq(1, fn.eval('d._VAL[0][0]._TYPE is v:msgpack_types.string')) end) - it('are successfully converted to blobs from a list', - function() + it('are successfully converted to blobs from a list', function() command([[let l = luaeval('{"abc", "a\0b", "c\0d", "def"}')]]) - eq({'abc', 'a\000b', 'c\000d', 'def'}, meths.get_var('l')) + eq({'abc', 'a\000b', 'c\000d', 'def'}, api.nvim_get_var('l')) end) end) @@ -88,62 +86,68 @@ describe('luaeval()', function() it('correctly evaluates scalars', function() -- Also test method call (->) syntax - eq(1, funcs.luaeval('1')) + eq(1, fn.luaeval('1')) eq(0, eval('"1"->luaeval()->type()')) - eq(1.5, funcs.luaeval('1.5')) + eq(1.5, fn.luaeval('1.5')) eq(5, eval('"1.5"->luaeval()->type()')) - eq("test", funcs.luaeval('"test"')) + eq("test", fn.luaeval('"test"')) eq(1, eval('"\'test\'"->luaeval()->type()')) - eq('', funcs.luaeval('""')) - eq('\000', funcs.luaeval([['\0']])) - eq('\000\n\000', funcs.luaeval([['\0\n\0']])) + eq('', fn.luaeval('""')) + eq('\000', fn.luaeval([['\0']])) + eq('\000\n\000', fn.luaeval([['\0\n\0']])) eq(10, eval([[type(luaeval("'\\0\\n\\0'"))]])) - eq(true, funcs.luaeval('true')) - eq(false, funcs.luaeval('false')) - eq(NIL, funcs.luaeval('nil')) + eq(true, fn.luaeval('true')) + eq(false, fn.luaeval('false')) + eq(NIL, fn.luaeval('nil')) end) it('correctly evaluates containers', function() - eq({}, funcs.luaeval('{}')) + eq({}, fn.luaeval('{}')) eq(3, eval('type(luaeval("{}"))')) - eq({test=1, foo=2}, funcs.luaeval('{test=1, foo=2}')) + eq({test=1, foo=2}, fn.luaeval('{test=1, foo=2}')) eq(4, eval('type(luaeval("{test=1, foo=2}"))')) - eq({4, 2}, funcs.luaeval('{4, 2}')) + eq({4, 2}, fn.luaeval('{4, 2}')) eq(3, eval('type(luaeval("{4, 2}"))')) + eq({NIL, 20}, fn.luaeval('{[2] = 20}')) + eq(3, eval('type(luaeval("{[2] = 20}"))')) + + eq({10, NIL, 30}, fn.luaeval('{[1] = 10, [3] = 30}')) + eq(3, eval('type(luaeval("{[1] = 10, [3] = 30}"))')) + local level = 30 - eq(nested_by_level[level].o, funcs.luaeval(nested_by_level[level].s)) + eq(nested_by_level[level].o, fn.luaeval(nested_by_level[level].s)) eq({_TYPE={}, _VAL={{{_TYPE={}, _VAL={'\n', '\n'}}, '\000\n\000\000'}}}, - funcs.luaeval([[{['\0\n\0']='\0\n\0\0'}]])) + fn.luaeval([[{['\0\n\0']='\0\n\0\0'}]])) eq(1, eval([[luaeval('{["\0\n\0"]="\0\n\0\0"}')._TYPE is v:msgpack_types.map]])) eq(1, eval([[luaeval('{["\0\n\0"]="\0\n\0\0"}')._VAL[0][0]._TYPE is v:msgpack_types.string]])) eq({nested={{_TYPE={}, _VAL={{{_TYPE={}, _VAL={'\n', '\n'}}, '\000\n\000\000'}}}}}, - funcs.luaeval([[{nested={{['\0\n\0']='\0\n\0\0'}}}]])) + fn.luaeval([[{nested={{['\0\n\0']='\0\n\0\0'}}}]])) end) it('correctly passes scalars as argument', function() - eq(1, funcs.luaeval('_A', 1)) - eq(1.5, funcs.luaeval('_A', 1.5)) - eq('', funcs.luaeval('_A', '')) - eq('test', funcs.luaeval('_A', 'test')) - eq(NIL, funcs.luaeval('_A', NIL)) - eq(true, funcs.luaeval('_A', true)) - eq(false, funcs.luaeval('_A', false)) + eq(1, fn.luaeval('_A', 1)) + eq(1.5, fn.luaeval('_A', 1.5)) + eq('', fn.luaeval('_A', '')) + eq('test', fn.luaeval('_A', 'test')) + eq(NIL, fn.luaeval('_A', NIL)) + eq(true, fn.luaeval('_A', true)) + eq(false, fn.luaeval('_A', false)) end) it('correctly passes containers as argument', function() - eq({}, funcs.luaeval('_A', {})) - eq({test=1}, funcs.luaeval('_A', {test=1})) - eq({4, 2}, funcs.luaeval('_A', {4, 2})) + eq({}, fn.luaeval('_A', {})) + eq({test=1}, fn.luaeval('_A', {test=1})) + eq({4, 2}, fn.luaeval('_A', {4, 2})) local level = 28 - eq(nested_by_level[level].o, funcs.luaeval('_A', nested_by_level[level].o)) + eq(nested_by_level[level].o, fn.luaeval('_A', nested_by_level[level].o)) end) local function sp(typ, val) @@ -158,7 +162,7 @@ describe('luaeval()', function() return sp('map', '[' .. val .. ']') end local function luaevalarg(argexpr, expr) - return eval(([=[ + return eval((([=[ [ extend(g:, {'_ret': luaeval(%s, %s)})._ret, type(g:_ret)==type({})&&has_key(g:_ret, '_TYPE') @@ -168,7 +172,7 @@ describe('luaeval()', function() get(g:_ret, '_VAL', g:_ret) ] : [0, g:_ret]][1] - ]=]):format(expr or '"_A"', argexpr):gsub('\n', '')) + ]=]):format(expr or '"_A"', argexpr):gsub('\n', ''))) end it('correctly passes special dictionaries', function() @@ -182,7 +186,7 @@ describe('luaeval()', function() end) it('issues an error in some cases', function() - eq("Vim(call):E5100: Cannot convert given lua table: table should either have a sequence of positive integer keys or contain only string keys", + eq("Vim(call):E5100: Cannot convert given lua table: table should contain either only integer keys or only string keys", exc_exec('call luaeval("{1, foo=2}")')) startswith("Vim(call):E5107: Error loading lua [string \"luaeval()\"]:", @@ -395,26 +399,26 @@ describe('luaeval()', function() eq(4, eval([[type(luaeval('{[vim.type_idx]=vim.types.dictionary}'))]])) eq(3, eval([[type(luaeval('{[vim.type_idx]=vim.types.array}'))]])) - eq({}, funcs.luaeval('{[vim.type_idx]=vim.types.array}')) + eq({}, fn.luaeval('{[vim.type_idx]=vim.types.array}')) -- Presence of type_idx makes Vim ignore some keys - eq({42}, funcs.luaeval('{[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}')) - eq({foo=2}, funcs.luaeval('{[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}')) - eq(10, funcs.luaeval('{[vim.type_idx]=vim.types.float, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}')) + eq({42}, fn.luaeval('{[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}')) + eq({foo=2}, fn.luaeval('{[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}')) + eq(10, fn.luaeval('{[vim.type_idx]=vim.types.float, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}')) -- The following should not crash - eq({}, funcs.luaeval('{[vim.type_idx]=vim.types.dictionary}')) + eq({}, fn.luaeval('{[vim.type_idx]=vim.types.dictionary}')) end) it('correctly converts self-containing containers', function() - meths.set_var('l', {}) + api.nvim_set_var('l', {}) eval('add(l, l)') eq(true, eval('luaeval("_A == _A[1]", l)')) eq(true, eval('luaeval("_A[1] == _A[1][1]", [l])')) eq(true, eval('luaeval("_A.d == _A.d[1]", {"d": l})')) eq(true, eval('luaeval("_A ~= _A[1]", [l])')) - meths.set_var('d', {foo=42}) + api.nvim_set_var('d', {foo=42}) eval('extend(d, {"d": d})') eq(true, eval('luaeval("_A == _A.d", d)')) eq(true, eval('luaeval("_A[1] == _A[1].d", [d])')) @@ -437,7 +441,7 @@ describe('luaeval()', function() local s = ('x'):rep(65536) eq('Vim(call):E5107: Error loading lua [string "luaeval()"]:1: unexpected symbol near \')\'', exc_exec([[call luaeval("(']] .. s ..[[' + )")]])) - eq(s, funcs.luaeval('"' .. s .. '"')) + eq(s, fn.luaeval('"' .. s .. '"')) end) end) @@ -474,7 +478,7 @@ describe('v:lua', function() eq(7, eval('v:lua.foo(3,4,v:null)')) eq(true, exec_lua([[return _G.val == vim.NIL]])) eq(NIL, eval('v:lua.mymod.noisy("eval")')) - eq("hey eval", meths.get_current_line()) + eq("hey eval", api.nvim_get_current_line()) eq("string: abc", eval('v:lua.mymod.whatis(0z616263)')) eq("string: ", eval('v:lua.mymod.whatis(v:_null_blob)')) @@ -490,7 +494,7 @@ describe('v:lua', function() eq("boop", exec_lua([[return _G.val]])) eq(NIL, eval('"there"->v:lua.mymod.noisy()')) - eq("hey there", meths.get_current_line()) + eq("hey there", api.nvim_get_current_line()) eq({5, 10, 15, 20}, eval('[[1], [2, 3], [4]]->v:lua.vim.tbl_flatten()->map({_, v -> v * 5})')) eq("Vim:E5108: Error executing lua [string \"<nvim>\"]:0: attempt to call global 'nonexistent' (a nil value)", @@ -499,7 +503,7 @@ describe('v:lua', function() it('works in :call', function() command(":call v:lua.mymod.noisy('command')") - eq("hey command", meths.get_current_line()) + eq("hey command", api.nvim_get_current_line()) eq("Vim(call):E5108: Error executing lua [string \"<nvim>\"]:0: attempt to call global 'nonexistent' (a nil value)", pcall_err(command, 'call v:lua.mymod.crashy()')) end) @@ -514,21 +518,19 @@ describe('v:lua', function() [5] = {bold = true, foreground = Screen.colors.SeaGreen4}, }) screen:attach() - meths.set_option_value('omnifunc', 'v:lua.mymod.omni', {}) + api.nvim_set_option_value('omnifunc', 'v:lua.mymod.omni', {}) feed('isome st<c-x><c-o>') screen:expect{grid=[[ some stuff^ | {1:~ }{2: stuff }{1: }| {1:~ }{3: steam }{1: }| {1:~ }{3: strange things }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {4:-- Omni completion (^O^N^P) }{5:match 1 of 3} | ]]} - meths.set_option_value('operatorfunc', 'v:lua.mymod.noisy', {}) + api.nvim_set_option_value('operatorfunc', 'v:lua.mymod.noisy', {}) feed('<Esc>g@g@') - eq("hey line", meths.get_current_line()) + eq("hey line", api.nvim_get_current_line()) end) it('supports packages', function() @@ -536,6 +538,8 @@ describe('v:lua', function() eq('\tbadval', eval("v:lua.require'leftpad'('badval')")) eq(9003, eval("v:lua.require'bar'.doit()")) eq(9004, eval("v:lua.require'baz-quux'.doit()")) + eq(9003, eval("1 ? v:lua.require'bar'.doit() : v:lua.require'baz-quux'.doit()")) + eq(9004, eval("0 ? v:lua.require'bar'.doit() : v:lua.require'baz-quux'.doit()")) end) it('throw errors for invalid use', function() diff --git a/test/functional/lua/mpack_spec.lua b/test/functional/lua/mpack_spec.lua index cc788ed8bb..0b6a6d60bd 100644 --- a/test/functional/lua/mpack_spec.lua +++ b/test/functional/lua/mpack_spec.lua @@ -8,16 +8,22 @@ local exec_lua = helpers.exec_lua describe('lua vim.mpack', function() before_each(clear) it('encodes vim.NIL', function() - eq({true, true, true, true}, exec_lua [[ + eq( + { true, true, true, true }, + exec_lua [[ local var = vim.mpack.decode(vim.mpack.encode({33, vim.NIL, 77})) return {var[1]==33, var[2]==vim.NIL, var[3]==77, var[4]==nil} - ]]) + ]] + ) end) it('encodes vim.empty_dict()', function() - eq({{{}, "foo", {}}, true, false}, exec_lua [[ + eq( + { { {}, 'foo', {} }, true, false }, + exec_lua [[ local var = vim.mpack.decode(vim.mpack.encode({{}, "foo", vim.empty_dict()})) return {var, vim.tbl_islist(var[1]), vim.tbl_islist(var[3])} - ]]) + ]] + ) end) end) diff --git a/test/functional/lua/overrides_spec.lua b/test/functional/lua/overrides_spec.lua index c08f3d06a9..ecbdde3bfd 100644 --- a/test/functional/lua/overrides_spec.lua +++ b/test/functional/lua/overrides_spec.lua @@ -3,11 +3,11 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local eq = helpers.eq -local NIL = helpers.NIL +local NIL = vim.NIL local feed = helpers.feed local clear = helpers.clear -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local command = helpers.command local write_file = helpers.write_file local exec_capture = helpers.exec_capture @@ -25,15 +25,15 @@ end) describe('print', function() it('returns nothing', function() - eq(NIL, funcs.luaeval('print("abc")')) - eq(0, funcs.luaeval('select("#", print("abc"))')) + eq(NIL, fn.luaeval('print("abc")')) + eq(0, fn.luaeval('select("#", print("abc"))')) end) it('allows catching printed text with :execute', function() - eq('\nabc', funcs.execute('lua print("abc")')) - eq('\nabc', funcs.execute('luado print("abc")')) - eq('\nabc', funcs.execute('call luaeval("print(\'abc\')")')) + eq('\nabc', fn.execute('lua print("abc")')) + eq('\nabc', fn.execute('luado print("abc")')) + eq('\nabc', fn.execute('call luaeval("print(\'abc\')")')) write_file(fname, 'print("abc")') - eq('\nabc', funcs.execute('luafile ' .. fname)) + eq('\nabc', fn.execute('luafile ' .. fname)) eq('abc', exec_capture('lua print("abc")')) eq('abc', exec_capture('luado print("abc")')) @@ -42,25 +42,36 @@ describe('print', function() eq('abc', exec_capture('luafile ' .. fname)) end) it('handles errors in __tostring', function() - write_file(fname, [[ + write_file( + fname, + [[ local meta_nilerr = { __tostring = function() error(nil) end } local meta_abcerr = { __tostring = function() error("abc") end } local meta_tblout = { __tostring = function() return {"TEST"} end } v_nilerr = setmetatable({}, meta_nilerr) v_abcerr = setmetatable({}, meta_abcerr) v_tblout = setmetatable({}, meta_tblout) - ]]) + ]] + ) eq('', exec_capture('luafile ' .. fname)) -- TODO(bfredl): these look weird, print() should not use "E5114:" style errors.. - eq('Vim(lua):E5108: Error executing lua E5114: Error while converting print argument #2: [NULL]', - pcall_err(command, 'lua print("foo", v_nilerr, "bar")')) - eq('Vim(lua):E5108: Error executing lua E5114: Error while converting print argument #2: Xtest-functional-lua-overrides-luafile:2: abc', - pcall_err(command, 'lua print("foo", v_abcerr, "bar")')) - eq('Vim(lua):E5108: Error executing lua E5114: Error while converting print argument #2: <Unknown error: lua_tolstring returned NULL for tostring result>', - pcall_err(command, 'lua print("foo", v_tblout, "bar")')) + eq( + 'Vim(lua):E5108: Error executing lua E5114: Error while converting print argument #2: [NULL]', + pcall_err(command, 'lua print("foo", v_nilerr, "bar")') + ) + eq( + 'Vim(lua):E5108: Error executing lua E5114: Error while converting print argument #2: Xtest-functional-lua-overrides-luafile:2: abc', + pcall_err(command, 'lua print("foo", v_abcerr, "bar")') + ) + eq( + 'Vim(lua):E5108: Error executing lua E5114: Error while converting print argument #2: <Unknown error: lua_tolstring returned NULL for tostring result>', + pcall_err(command, 'lua print("foo", v_tblout, "bar")') + ) end) it('coerces error values into strings', function() - write_file(fname, [[ + write_file( + fname, + [[ function string_error() error("my mistake") end function number_error() error(1234) end function nil_error() error(nil) end @@ -82,27 +93,35 @@ describe('print', function() }) error(err) end - ]]) + ]] + ) eq('', exec_capture('luafile ' .. fname)) - eq('Vim(lua):E5108: Error executing lua Xtest-functional-lua-overrides-luafile:1: my mistake', - pcall_err(command, 'lua string_error()')) - eq('Vim(lua):E5108: Error executing lua Xtest-functional-lua-overrides-luafile:2: 1234', - pcall_err(command, 'lua number_error()')) - eq('Vim(lua):E5108: Error executing lua [NULL]', - pcall_err(command, 'lua nil_error()')) - eq('Vim(lua):E5108: Error executing lua [NULL]', - pcall_err(command, 'lua table_error()')) - eq('Vim(lua):E5108: Error executing lua Internal Error [11234] my mistake', - pcall_err(command, 'lua custom_error()')) - eq('Vim(lua):E5108: Error executing lua [NULL]', - pcall_err(command, 'lua bad_custom_error()')) + eq( + 'Vim(lua):E5108: Error executing lua Xtest-functional-lua-overrides-luafile:1: my mistake', + pcall_err(command, 'lua string_error()') + ) + eq( + 'Vim(lua):E5108: Error executing lua Xtest-functional-lua-overrides-luafile:2: 1234', + pcall_err(command, 'lua number_error()') + ) + eq('Vim(lua):E5108: Error executing lua [NULL]', pcall_err(command, 'lua nil_error()')) + eq('Vim(lua):E5108: Error executing lua [NULL]', pcall_err(command, 'lua table_error()')) + eq( + 'Vim(lua):E5108: Error executing lua Internal Error [11234] my mistake', + pcall_err(command, 'lua custom_error()') + ) + eq('Vim(lua):E5108: Error executing lua [NULL]', pcall_err(command, 'lua bad_custom_error()')) end) it('prints strings with NULs and NLs correctly', function() - meths.set_option_value('more', true, {}) - eq('abc ^@ def\nghi^@^@^@jkl\nTEST\n\n\nT\n', - exec_capture([[lua print("abc \0 def\nghi\0\0\0jkl\nTEST\n\n\nT\n")]])) - eq('abc ^@ def\nghi^@^@^@jkl\nTEST\n\n\nT^@', - exec_capture([[lua print("abc \0 def\nghi\0\0\0jkl\nTEST\n\n\nT\0")]])) + api.nvim_set_option_value('more', true, {}) + eq( + 'abc ^@ def\nghi^@^@^@jkl\nTEST\n\n\nT\n', + exec_capture([[lua print("abc \0 def\nghi\0\0\0jkl\nTEST\n\n\nT\n")]]) + ) + eq( + 'abc ^@ def\nghi^@^@^@jkl\nTEST\n\n\nT^@', + exec_capture([[lua print("abc \0 def\nghi\0\0\0jkl\nTEST\n\n\nT\0")]]) + ) eq('T^@', exec_capture([[lua print("T\0")]])) eq('T\n', exec_capture([[lua print("T\n")]])) end) @@ -114,7 +133,8 @@ describe('print', function() eq('abc def', exec_capture('lua print("abc", "", "def")')) end) it('defers printing in luv event handlers', function() - exec_lua([[ + exec_lua( + [[ local cmd = ... function test() local timer = vim.uv.new_timer() @@ -133,7 +153,9 @@ describe('print', function() print("very slow") vim.api.nvim_command("sleep 1m") -- force deferred event processing end - ]], (is_os('win') and "timeout 1") or "sleep 0.1") + ]], + (is_os('win') and 'timeout 1') or 'sleep 0.1' + ) eq('very slow\nvery fast', exec_capture('lua test()')) end) @@ -141,33 +163,34 @@ describe('print', function() local screen = Screen.new(40, 8) screen:attach() screen:set_default_attr_ids({ - [0] = {bold = true, foreground=Screen.colors.Blue}, - [1] = {bold = true, foreground = Screen.colors.SeaGreen}, - [2] = {bold = true, reverse = true}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { bold = true, foreground = Screen.colors.SeaGreen }, + [2] = { bold = true, reverse = true }, }) feed([[:lua print('\na')<CR>]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {2: }| | a | {1:Press ENTER or type command to continue}^ | - ]]} + ]], + } feed('<CR>') feed([[:lua print('b\n\nc')<CR>]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {2: }| b | | c | {1:Press ENTER or type command to continue}^ | - ]]} + ]], + } end) end) @@ -178,10 +201,10 @@ describe('debug.debug', function() screen = Screen.new() screen:attach() screen:set_default_attr_ids { - [0] = {bold=true, foreground=255}; - [1] = {bold = true, reverse = true}; - E = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}; - cr = {bold = true, foreground = Screen.colors.SeaGreen4}; + [0] = { bold = true, foreground = 255 }, + [1] = { bold = true, reverse = true }, + E = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + cr = { bold = true, foreground = Screen.colors.SeaGreen4 }, } end) @@ -194,33 +217,19 @@ describe('debug.debug', function() end ]]) feed(':lua Test()\n') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*10 {1: }| nil | lua_debug> ^ | - ]]} + ]], + } feed('print("TEST")\n') screen:expect([[ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*8 {1: }| nil | lua_debug> print("TEST") | @@ -228,10 +237,10 @@ describe('debug.debug', function() lua_debug> ^ | ]]) feed('<C-c>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {1: }| nil | lua_debug> print("TEST") | @@ -243,31 +252,21 @@ describe('debug.debug', function() {E: [string ":lua"]:5: in function 'Test'} | {E: [string ":lua"]:1: in main chunk} | Interrupt: {cr:Press ENTER or type command to continue}^ | - ]]} + ]], + } feed('<C-l>:lua Test()\n') screen:expect([[ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*10 {1: }| nil | lua_debug> ^ | ]]) feed('\n') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {1: }| nil | lua_debug> | @@ -277,56 +276,39 @@ describe('debug.debug', function() {E: [string ":lua"]:5: in function 'Test'} | {E: [string ":lua"]:1: in main chunk} | {cr:Press ENTER or type command to continue}^ | - ]]} + ]], + } end) it("can be safely exited with 'cont'", function() feed('<cr>') feed(':lua debug.debug() print("x")<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*12 lua_debug> ^ | - ]]} + ]], + } - feed("conttt<cr>") -- misspelled cont; invalid syntax - screen:expect{grid=[[ + feed('conttt<cr>') -- misspelled cont; invalid syntax + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*8 {1: }| lua_debug> conttt | {E:E5115: Error while loading debug string: (debug comma}| {E:nd):1: '=' expected near '<eof>'} | lua_debug> ^ | - ]]} + ]], + } - feed("cont<cr>") -- exactly "cont", exit now - screen:expect{grid=[[ + feed('cont<cr>') -- exactly "cont", exit now + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 {1: }| lua_debug> conttt | {E:E5115: Error while loading debug string: (debug comma}| @@ -334,41 +316,33 @@ describe('debug.debug', function() lua_debug> cont | x | {cr:Press ENTER or type command to continue}^ | - ]]} + ]], + } feed('<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*12 | - ]]} + ]], + } end) end) describe('os.getenv', function() it('returns nothing for undefined env var', function() - eq(NIL, funcs.luaeval('os.getenv("XTEST_1")')) + eq(NIL, fn.luaeval('os.getenv("XTEST_1")')) end) it('returns env var set by the parent process', function() local value = 'foo' - clear({env = {['XTEST_1']=value}}) - eq(value, funcs.luaeval('os.getenv("XTEST_1")')) + clear({ env = { ['XTEST_1'] = value } }) + eq(value, fn.luaeval('os.getenv("XTEST_1")')) end) it('returns env var set by let', function() local value = 'foo' - meths.command('let $XTEST_1 = "'..value..'"') - eq(value, funcs.luaeval('os.getenv("XTEST_1")')) + command('let $XTEST_1 = "' .. value .. '"') + eq(value, fn.luaeval('os.getenv("XTEST_1")')) end) end) @@ -376,6 +350,6 @@ end) -- luajit or PUC lua 5.1. describe('bit module', function() it('works', function() - eq (9, exec_lua [[ return require'bit'.band(11,13) ]]) + eq(9, exec_lua [[ return require'bit'.band(11,13) ]]) end) end) diff --git a/test/functional/lua/runtime_spec.lua b/test/functional/lua/runtime_spec.lua index 0b8b2234db..6f36ccfb9e 100644 --- a/test/functional/lua/runtime_spec.lua +++ b/test/functional/lua/runtime_spec.lua @@ -4,7 +4,7 @@ local clear = helpers.clear local eq = helpers.eq local eval = helpers.eval local exec = helpers.exec -local funcs = helpers.funcs +local fn = helpers.fn local mkdir_p = helpers.mkdir_p local rmdir = helpers.rmdir local write_file = helpers.write_file @@ -15,8 +15,8 @@ describe('runtime:', function() local init = 'dummy_init.lua' setup(function() - io.open(init, 'w'):close() -- touch init file - clear{args = {'-u', init}} + io.open(init, 'w'):close() -- touch init file + clear { args = { '-u', init } } exec('set rtp+=' .. plug_dir) exec([[ set shell=doesnotexist @@ -45,11 +45,11 @@ describe('runtime:', function() end) it('lua colorschemes work and are included in cmdline completion', function() - local colorscheme_file = table.concat({colorscheme_folder, 'new_colorscheme.lua'}, sep) + local colorscheme_file = table.concat({ colorscheme_folder, 'new_colorscheme.lua' }, sep) write_file(colorscheme_file, [[vim.g.lua_colorscheme = 1]]) - eq({'new_colorscheme'}, funcs.getcompletion('new_c', 'color')) - eq({'colors/new_colorscheme.lua'}, funcs.getcompletion('colors/new_c', 'runtime')) + eq({ 'new_colorscheme' }, fn.getcompletion('new_c', 'color')) + eq({ 'colors/new_colorscheme.lua' }, fn.getcompletion('colors/new_c', 'runtime')) exec('colorscheme new_colorscheme') @@ -64,48 +64,60 @@ describe('runtime:', function() end) exec('set pp+=' .. pack_dir) - local pack_opt_dir = table.concat({pack_dir, 'pack', 'some_name', 'opt'}, sep) - local colors_opt_dir = table.concat({pack_opt_dir, 'some_pack', 'colors'}, sep) + local pack_opt_dir = table.concat({ pack_dir, 'pack', 'some_name', 'opt' }, sep) + local colors_opt_dir = table.concat({ pack_opt_dir, 'some_pack', 'colors' }, sep) mkdir_p(colors_opt_dir) - local after_colorscheme_folder = table.concat({plug_dir, 'after', 'colors'}, sep) + local after_colorscheme_folder = table.concat({ plug_dir, 'after', 'colors' }, sep) mkdir_p(after_colorscheme_folder) exec('set rtp+=' .. plug_dir .. '/after') - write_file(table.concat({colors_opt_dir, 'new_colorscheme.lua'}, sep), - [[vim.g.colorscheme = 'lua_pp']]) + write_file( + table.concat({ colors_opt_dir, 'new_colorscheme.lua' }, sep), + [[vim.g.colorscheme = 'lua_pp']] + ) exec('colorscheme new_colorscheme') eq('lua_pp', eval('g:colorscheme')) - write_file(table.concat({colors_opt_dir, 'new_colorscheme.vim'}, sep), - [[let g:colorscheme = 'vim_pp']]) + write_file( + table.concat({ colors_opt_dir, 'new_colorscheme.vim' }, sep), + [[let g:colorscheme = 'vim_pp']] + ) exec('colorscheme new_colorscheme') eq('vim_pp', eval('g:colorscheme')) - write_file(table.concat({after_colorscheme_folder, 'new_colorscheme.lua'}, sep), - [[vim.g.colorscheme = 'lua_rtp_after']]) + write_file( + table.concat({ after_colorscheme_folder, 'new_colorscheme.lua' }, sep), + [[vim.g.colorscheme = 'lua_rtp_after']] + ) exec('colorscheme new_colorscheme') eq('lua_rtp_after', eval('g:colorscheme')) - write_file(table.concat({after_colorscheme_folder, 'new_colorscheme.vim'}, sep), - [[let g:colorscheme = 'vim_rtp_after']]) + write_file( + table.concat({ after_colorscheme_folder, 'new_colorscheme.vim' }, sep), + [[let g:colorscheme = 'vim_rtp_after']] + ) exec('colorscheme new_colorscheme') eq('vim_rtp_after', eval('g:colorscheme')) - write_file(table.concat({colorscheme_folder, 'new_colorscheme.lua'}, sep), - [[vim.g.colorscheme = 'lua_rtp']]) + write_file( + table.concat({ colorscheme_folder, 'new_colorscheme.lua' }, sep), + [[vim.g.colorscheme = 'lua_rtp']] + ) exec('colorscheme new_colorscheme') eq('lua_rtp', eval('g:colorscheme')) - write_file(table.concat({colorscheme_folder, 'new_colorscheme.vim'}, sep), - [[let g:colorscheme = 'vim_rtp']]) + write_file( + table.concat({ colorscheme_folder, 'new_colorscheme.vim' }, sep), + [[let g:colorscheme = 'vim_rtp']] + ) exec('colorscheme new_colorscheme') eq('vim_rtp', eval('g:colorscheme')) end) end) describe('compiler', function() - local compiler_folder = table.concat({plug_dir, 'compiler'}, sep) + local compiler_folder = table.concat({ plug_dir, 'compiler' }, sep) before_each(function() mkdir_p(compiler_folder) end) @@ -114,8 +126,8 @@ describe('runtime:', function() local compiler_file = compiler_folder .. sep .. 'new_compiler.lua' write_file(compiler_file, [[vim.b.lua_compiler = 1]]) - eq({'new_compiler'}, funcs.getcompletion('new_c', 'compiler')) - eq({'compiler/new_compiler.lua'}, funcs.getcompletion('compiler/new_c', 'runtime')) + eq({ 'new_compiler' }, fn.getcompletion('new_c', 'compiler')) + eq({ 'compiler/new_compiler.lua' }, fn.getcompletion('compiler/new_c', 'runtime')) exec('compiler new_compiler') @@ -123,126 +135,189 @@ describe('runtime:', function() end) it("'rtp' order is respected", function() - local after_compiler_folder = table.concat({plug_dir, 'after', 'compiler'}, sep) - mkdir_p(table.concat({compiler_folder, 'new_compiler'}, sep)) - mkdir_p(table.concat({after_compiler_folder, 'new_compiler'}, sep)) + local after_compiler_folder = table.concat({ plug_dir, 'after', 'compiler' }, sep) + mkdir_p(table.concat({ compiler_folder, 'new_compiler' }, sep)) + mkdir_p(table.concat({ after_compiler_folder, 'new_compiler' }, sep)) exec('set rtp+=' .. plug_dir .. '/after') exec('let g:seq = ""') -- A .lua file is loaded after a .vim file if they only differ in extension. -- All files in after/compiler/ are loaded after all files in compiler/. - write_file(table.concat({compiler_folder, 'new_compiler.vim'}, sep), [[let g:seq ..= 'A']]) - write_file(table.concat({compiler_folder, 'new_compiler.lua'}, sep), [[vim.g.seq = vim.g.seq .. 'B']]) - write_file(table.concat({after_compiler_folder, 'new_compiler.vim'}, sep), [[let g:seq ..= 'a']]) - write_file(table.concat({after_compiler_folder, 'new_compiler.lua'}, sep), [[vim.g.seq = vim.g.seq .. 'b']]) + write_file(table.concat({ compiler_folder, 'new_compiler.vim' }, sep), [[let g:seq ..= 'A']]) + write_file( + table.concat({ compiler_folder, 'new_compiler.lua' }, sep), + [[vim.g.seq = vim.g.seq .. 'B']] + ) + write_file( + table.concat({ after_compiler_folder, 'new_compiler.vim' }, sep), + [[let g:seq ..= 'a']] + ) + write_file( + table.concat({ after_compiler_folder, 'new_compiler.lua' }, sep), + [[vim.g.seq = vim.g.seq .. 'b']] + ) exec('compiler new_compiler') eq('ABab', eval('g:seq')) end) end) describe('ftplugin', function() - local ftplugin_folder = table.concat({plug_dir, 'ftplugin'}, sep) + local ftplugin_folder = table.concat({ plug_dir, 'ftplugin' }, sep) it('lua ftplugins work and are included in cmdline completion', function() mkdir_p(ftplugin_folder) - local ftplugin_file = table.concat({ftplugin_folder , 'new-ft.lua'}, sep) - write_file(ftplugin_file , [[vim.b.lua_ftplugin = 1]]) + local ftplugin_file = table.concat({ ftplugin_folder, 'new-ft.lua' }, sep) + write_file(ftplugin_file, [[vim.b.lua_ftplugin = 1]]) - eq({'new-ft'}, funcs.getcompletion('new-f', 'filetype')) - eq({'ftplugin/new-ft.lua'}, funcs.getcompletion('ftplugin/new-f', 'runtime')) + eq({ 'new-ft' }, fn.getcompletion('new-f', 'filetype')) + eq({ 'ftplugin/new-ft.lua' }, fn.getcompletion('ftplugin/new-f', 'runtime')) exec [[set filetype=new-ft]] eq(1, eval('b:lua_ftplugin')) end) it("'rtp' order is respected", function() - local after_ftplugin_folder = table.concat({plug_dir, 'after', 'ftplugin'}, sep) - mkdir_p(table.concat({ftplugin_folder, 'new-ft'}, sep)) - mkdir_p(table.concat({after_ftplugin_folder, 'new-ft'}, sep)) + local after_ftplugin_folder = table.concat({ plug_dir, 'after', 'ftplugin' }, sep) + mkdir_p(table.concat({ ftplugin_folder, 'new-ft' }, sep)) + mkdir_p(table.concat({ after_ftplugin_folder, 'new-ft' }, sep)) exec('set rtp+=' .. plug_dir .. '/after') exec('let g:seq = ""') -- A .lua file is loaded after a .vim file if they only differ in extension. -- All files in after/ftplugin/ are loaded after all files in ftplugin/. - write_file(table.concat({ftplugin_folder, 'new-ft.vim'}, sep), [[let g:seq ..= 'A']]) - write_file(table.concat({ftplugin_folder, 'new-ft.lua'}, sep), [[vim.g.seq = vim.g.seq .. 'B']]) - write_file(table.concat({ftplugin_folder, 'new-ft_a.vim'}, sep), [[let g:seq ..= 'C']]) - write_file(table.concat({ftplugin_folder, 'new-ft_a.lua'}, sep), [[vim.g.seq = vim.g.seq .. 'D']]) - write_file(table.concat({ftplugin_folder, 'new-ft', 'a.vim'}, sep), [[let g:seq ..= 'E']]) - write_file(table.concat({ftplugin_folder, 'new-ft', 'a.lua'}, sep), [[vim.g.seq = vim.g.seq .. 'F']]) - write_file(table.concat({after_ftplugin_folder, 'new-ft.vim'}, sep), [[let g:seq ..= 'a']]) - write_file(table.concat({after_ftplugin_folder, 'new-ft.lua'}, sep), [[vim.g.seq = vim.g.seq .. 'b']]) - write_file(table.concat({after_ftplugin_folder, 'new-ft_a.vim'}, sep), [[let g:seq ..= 'c']]) - write_file(table.concat({after_ftplugin_folder, 'new-ft_a.lua'}, sep), [[vim.g.seq = vim.g.seq .. 'd']]) - write_file(table.concat({after_ftplugin_folder, 'new-ft', 'a.vim'}, sep), [[let g:seq ..= 'e']]) - write_file(table.concat({after_ftplugin_folder, 'new-ft', 'a.lua'}, sep), [[vim.g.seq = vim.g.seq .. 'f']]) + write_file(table.concat({ ftplugin_folder, 'new-ft.vim' }, sep), [[let g:seq ..= 'A']]) + write_file( + table.concat({ ftplugin_folder, 'new-ft.lua' }, sep), + [[vim.g.seq = vim.g.seq .. 'B']] + ) + write_file(table.concat({ ftplugin_folder, 'new-ft_a.vim' }, sep), [[let g:seq ..= 'C']]) + write_file( + table.concat({ ftplugin_folder, 'new-ft_a.lua' }, sep), + [[vim.g.seq = vim.g.seq .. 'D']] + ) + write_file(table.concat({ ftplugin_folder, 'new-ft', 'a.vim' }, sep), [[let g:seq ..= 'E']]) + write_file( + table.concat({ ftplugin_folder, 'new-ft', 'a.lua' }, sep), + [[vim.g.seq = vim.g.seq .. 'F']] + ) + write_file(table.concat({ after_ftplugin_folder, 'new-ft.vim' }, sep), [[let g:seq ..= 'a']]) + write_file( + table.concat({ after_ftplugin_folder, 'new-ft.lua' }, sep), + [[vim.g.seq = vim.g.seq .. 'b']] + ) + write_file( + table.concat({ after_ftplugin_folder, 'new-ft_a.vim' }, sep), + [[let g:seq ..= 'c']] + ) + write_file( + table.concat({ after_ftplugin_folder, 'new-ft_a.lua' }, sep), + [[vim.g.seq = vim.g.seq .. 'd']] + ) + write_file( + table.concat({ after_ftplugin_folder, 'new-ft', 'a.vim' }, sep), + [[let g:seq ..= 'e']] + ) + write_file( + table.concat({ after_ftplugin_folder, 'new-ft', 'a.lua' }, sep), + [[vim.g.seq = vim.g.seq .. 'f']] + ) exec('setfiletype new-ft') eq('ABCDEFabcdef', eval('g:seq')) end) it("'rtp' order is respected with 'fileignorecase'", function() exec('set fileignorecase') - local after_ftplugin_folder = table.concat({plug_dir, 'after', 'ftplugin'}, sep) - mkdir_p(table.concat({ftplugin_folder, 'new-ft'}, sep)) - mkdir_p(table.concat({after_ftplugin_folder, 'new-ft'}, sep)) + local after_ftplugin_folder = table.concat({ plug_dir, 'after', 'ftplugin' }, sep) + mkdir_p(table.concat({ ftplugin_folder, 'new-ft' }, sep)) + mkdir_p(table.concat({ after_ftplugin_folder, 'new-ft' }, sep)) exec('set rtp+=' .. plug_dir .. '/after') exec('let g:seq = ""') -- A .lua file is loaded after a .vim file if they only differ in extension. -- All files in after/ftplugin/ are loaded after all files in ftplugin/. - write_file(table.concat({ftplugin_folder, 'new-ft.VIM'}, sep), [[let g:seq ..= 'A']]) - write_file(table.concat({ftplugin_folder, 'new-ft.LUA'}, sep), [[vim.g.seq = vim.g.seq .. 'B']]) - write_file(table.concat({ftplugin_folder, 'new-ft_a.vim'}, sep), [[let g:seq ..= 'C']]) - write_file(table.concat({ftplugin_folder, 'new-ft_a.lua'}, sep), [[vim.g.seq = vim.g.seq .. 'D']]) - write_file(table.concat({ftplugin_folder, 'new-ft', 'a.VIM'}, sep), [[let g:seq ..= 'E']]) - write_file(table.concat({ftplugin_folder, 'new-ft', 'a.LUA'}, sep), [[vim.g.seq = vim.g.seq .. 'F']]) - write_file(table.concat({after_ftplugin_folder, 'new-ft.vim'}, sep), [[let g:seq ..= 'a']]) - write_file(table.concat({after_ftplugin_folder, 'new-ft.lua'}, sep), [[vim.g.seq = vim.g.seq .. 'b']]) - write_file(table.concat({after_ftplugin_folder, 'new-ft_a.VIM'}, sep), [[let g:seq ..= 'c']]) - write_file(table.concat({after_ftplugin_folder, 'new-ft_a.LUA'}, sep), [[vim.g.seq = vim.g.seq .. 'd']]) - write_file(table.concat({after_ftplugin_folder, 'new-ft', 'a.vim'}, sep), [[let g:seq ..= 'e']]) - write_file(table.concat({after_ftplugin_folder, 'new-ft', 'a.lua'}, sep), [[vim.g.seq = vim.g.seq .. 'f']]) + write_file(table.concat({ ftplugin_folder, 'new-ft.VIM' }, sep), [[let g:seq ..= 'A']]) + write_file( + table.concat({ ftplugin_folder, 'new-ft.LUA' }, sep), + [[vim.g.seq = vim.g.seq .. 'B']] + ) + write_file(table.concat({ ftplugin_folder, 'new-ft_a.vim' }, sep), [[let g:seq ..= 'C']]) + write_file( + table.concat({ ftplugin_folder, 'new-ft_a.lua' }, sep), + [[vim.g.seq = vim.g.seq .. 'D']] + ) + write_file(table.concat({ ftplugin_folder, 'new-ft', 'a.VIM' }, sep), [[let g:seq ..= 'E']]) + write_file( + table.concat({ ftplugin_folder, 'new-ft', 'a.LUA' }, sep), + [[vim.g.seq = vim.g.seq .. 'F']] + ) + write_file(table.concat({ after_ftplugin_folder, 'new-ft.vim' }, sep), [[let g:seq ..= 'a']]) + write_file( + table.concat({ after_ftplugin_folder, 'new-ft.lua' }, sep), + [[vim.g.seq = vim.g.seq .. 'b']] + ) + write_file( + table.concat({ after_ftplugin_folder, 'new-ft_a.VIM' }, sep), + [[let g:seq ..= 'c']] + ) + write_file( + table.concat({ after_ftplugin_folder, 'new-ft_a.LUA' }, sep), + [[vim.g.seq = vim.g.seq .. 'd']] + ) + write_file( + table.concat({ after_ftplugin_folder, 'new-ft', 'a.vim' }, sep), + [[let g:seq ..= 'e']] + ) + write_file( + table.concat({ after_ftplugin_folder, 'new-ft', 'a.lua' }, sep), + [[vim.g.seq = vim.g.seq .. 'f']] + ) exec('setfiletype new-ft') eq('ABCDEFabcdef', eval('g:seq')) end) end) describe('indent', function() - local indent_folder = table.concat({plug_dir, 'indent'}, sep) + local indent_folder = table.concat({ plug_dir, 'indent' }, sep) it('lua indents work and are included in cmdline completion', function() mkdir_p(indent_folder) - local indent_file = table.concat({indent_folder , 'new-ft.lua'}, sep) - write_file(indent_file , [[vim.b.lua_indent = 1]]) + local indent_file = table.concat({ indent_folder, 'new-ft.lua' }, sep) + write_file(indent_file, [[vim.b.lua_indent = 1]]) - eq({'new-ft'}, funcs.getcompletion('new-f', 'filetype')) - eq({'indent/new-ft.lua'}, funcs.getcompletion('indent/new-f', 'runtime')) + eq({ 'new-ft' }, fn.getcompletion('new-f', 'filetype')) + eq({ 'indent/new-ft.lua' }, fn.getcompletion('indent/new-f', 'runtime')) exec [[set filetype=new-ft]] eq(1, eval('b:lua_indent')) end) it("'rtp' order is respected", function() - local after_indent_folder = table.concat({plug_dir, 'after', 'indent'}, sep) - mkdir_p(table.concat({indent_folder, 'new-ft'}, sep)) - mkdir_p(table.concat({after_indent_folder, 'new-ft'}, sep)) + local after_indent_folder = table.concat({ plug_dir, 'after', 'indent' }, sep) + mkdir_p(table.concat({ indent_folder, 'new-ft' }, sep)) + mkdir_p(table.concat({ after_indent_folder, 'new-ft' }, sep)) exec('set rtp+=' .. plug_dir .. '/after') exec('let g:seq = ""') -- A .lua file is loaded after a .vim file if they only differ in extension. -- All files in after/indent/ are loaded after all files in indent/. - write_file(table.concat({indent_folder, 'new-ft.vim'}, sep), [[let g:seq ..= 'A']]) - write_file(table.concat({indent_folder, 'new-ft.lua'}, sep), [[vim.g.seq = vim.g.seq .. 'B']]) - write_file(table.concat({after_indent_folder, 'new-ft.vim'}, sep), [[let g:seq ..= 'a']]) - write_file(table.concat({after_indent_folder, 'new-ft.lua'}, sep), [[vim.g.seq = vim.g.seq .. 'b']]) + write_file(table.concat({ indent_folder, 'new-ft.vim' }, sep), [[let g:seq ..= 'A']]) + write_file( + table.concat({ indent_folder, 'new-ft.lua' }, sep), + [[vim.g.seq = vim.g.seq .. 'B']] + ) + write_file(table.concat({ after_indent_folder, 'new-ft.vim' }, sep), [[let g:seq ..= 'a']]) + write_file( + table.concat({ after_indent_folder, 'new-ft.lua' }, sep), + [[vim.g.seq = vim.g.seq .. 'b']] + ) exec('setfiletype new-ft') eq('ABab', eval('g:seq')) end) end) describe('syntax', function() - local syntax_folder = table.concat({plug_dir, 'syntax'}, sep) + local syntax_folder = table.concat({ plug_dir, 'syntax' }, sep) before_each(function() mkdir_p(syntax_folder) - local syntax_file = table.concat({syntax_folder , 'my-lang.lua'}, sep) - write_file(syntax_file , [[vim.b.current_syntax = 'my-lang']]) + local syntax_file = table.concat({ syntax_folder, 'my-lang.lua' }, sep) + write_file(syntax_file, [[vim.b.current_syntax = 'my-lang']]) exec([[let b:current_syntax = '']]) end) @@ -263,27 +338,42 @@ describe('runtime:', function() end) it('lua syntaxes are included in cmdline completion', function() - eq({'my-lang'}, funcs.getcompletion('my-l', 'filetype')) - eq({'my-lang'}, funcs.getcompletion('my-l', 'syntax')) - eq({'syntax/my-lang.lua'}, funcs.getcompletion('syntax/my-l', 'runtime')) + eq({ 'my-lang' }, fn.getcompletion('my-l', 'filetype')) + eq({ 'my-lang' }, fn.getcompletion('my-l', 'syntax')) + eq({ 'syntax/my-lang.lua' }, fn.getcompletion('syntax/my-l', 'runtime')) end) it("'rtp' order is respected", function() - local after_syntax_folder = table.concat({plug_dir, 'after', 'syntax'}, sep) - mkdir_p(table.concat({syntax_folder, 'my-lang'}, sep)) - mkdir_p(table.concat({after_syntax_folder, 'my-lang'}, sep)) + local after_syntax_folder = table.concat({ plug_dir, 'after', 'syntax' }, sep) + mkdir_p(table.concat({ syntax_folder, 'my-lang' }, sep)) + mkdir_p(table.concat({ after_syntax_folder, 'my-lang' }, sep)) exec('set rtp+=' .. plug_dir .. '/after') exec('let g:seq = ""') -- A .lua file is loaded after a .vim file if they only differ in extension. -- All files in after/syntax/ are loaded after all files in syntax/. - write_file(table.concat({syntax_folder, 'my-lang.vim'}, sep), [[let g:seq ..= 'A']]) - write_file(table.concat({syntax_folder, 'my-lang.lua'}, sep), [[vim.g.seq = vim.g.seq .. 'B']]) - write_file(table.concat({syntax_folder, 'my-lang', 'a.vim'}, sep), [[let g:seq ..= 'C']]) - write_file(table.concat({syntax_folder, 'my-lang', 'a.lua'}, sep), [[vim.g.seq = vim.g.seq .. 'D']]) - write_file(table.concat({after_syntax_folder, 'my-lang.vim'}, sep), [[let g:seq ..= 'a']]) - write_file(table.concat({after_syntax_folder, 'my-lang.lua'}, sep), [[vim.g.seq = vim.g.seq .. 'b']]) - write_file(table.concat({after_syntax_folder, 'my-lang', 'a.vim'}, sep), [[let g:seq ..= 'c']]) - write_file(table.concat({after_syntax_folder, 'my-lang', 'a.lua'}, sep), [[vim.g.seq = vim.g.seq .. 'd']]) + write_file(table.concat({ syntax_folder, 'my-lang.vim' }, sep), [[let g:seq ..= 'A']]) + write_file( + table.concat({ syntax_folder, 'my-lang.lua' }, sep), + [[vim.g.seq = vim.g.seq .. 'B']] + ) + write_file(table.concat({ syntax_folder, 'my-lang', 'a.vim' }, sep), [[let g:seq ..= 'C']]) + write_file( + table.concat({ syntax_folder, 'my-lang', 'a.lua' }, sep), + [[vim.g.seq = vim.g.seq .. 'D']] + ) + write_file(table.concat({ after_syntax_folder, 'my-lang.vim' }, sep), [[let g:seq ..= 'a']]) + write_file( + table.concat({ after_syntax_folder, 'my-lang.lua' }, sep), + [[vim.g.seq = vim.g.seq .. 'b']] + ) + write_file( + table.concat({ after_syntax_folder, 'my-lang', 'a.vim' }, sep), + [[let g:seq ..= 'c']] + ) + write_file( + table.concat({ after_syntax_folder, 'my-lang', 'a.lua' }, sep), + [[vim.g.seq = vim.g.seq .. 'd']] + ) exec('setfiletype my-lang') eq('ABCDabcd', eval('g:seq')) end) @@ -291,21 +381,23 @@ describe('runtime:', function() describe('spell', function() it("loads spell/LANG.{vim,lua} respecting 'rtp' order", function() - local spell_folder = table.concat({plug_dir, 'spell'}, sep) - local after_spell_folder = table.concat({plug_dir, 'after', 'spell'}, sep) - mkdir_p(table.concat({spell_folder, 'Xtest'}, sep)) - mkdir_p(table.concat({after_spell_folder, 'Xtest'}, sep)) + local spell_folder = table.concat({ plug_dir, 'spell' }, sep) + local after_spell_folder = table.concat({ plug_dir, 'after', 'spell' }, sep) + mkdir_p(table.concat({ spell_folder, 'Xtest' }, sep)) + mkdir_p(table.concat({ after_spell_folder, 'Xtest' }, sep)) exec('set rtp+=' .. plug_dir .. '/after') exec('let g:seq = ""') -- A .lua file is loaded after a .vim file if they only differ in extension. -- All files in after/spell/ are loaded after all files in spell/. - write_file(table.concat({spell_folder, 'Xtest.vim'}, sep), [[let g:seq ..= 'A']]) - write_file(table.concat({spell_folder, 'Xtest.lua'}, sep), [[vim.g.seq = vim.g.seq .. 'B']]) - write_file(table.concat({after_spell_folder, 'Xtest.vim'}, sep), [[let g:seq ..= 'a']]) - write_file(table.concat({after_spell_folder, 'Xtest.lua'}, sep), [[vim.g.seq = vim.g.seq .. 'b']]) + write_file(table.concat({ spell_folder, 'Xtest.vim' }, sep), [[let g:seq ..= 'A']]) + write_file(table.concat({ spell_folder, 'Xtest.lua' }, sep), [[vim.g.seq = vim.g.seq .. 'B']]) + write_file(table.concat({ after_spell_folder, 'Xtest.vim' }, sep), [[let g:seq ..= 'a']]) + write_file( + table.concat({ after_spell_folder, 'Xtest.lua' }, sep), + [[vim.g.seq = vim.g.seq .. 'b']] + ) exec('set spelllang=Xtest') eq('ABab', eval('g:seq')) end) end) - end) diff --git a/test/functional/lua/secure_spec.lua b/test/functional/lua/secure_spec.lua index fc20a06390..7aed711b23 100644 --- a/test/functional/lua/secure_spec.lua +++ b/test/functional/lua/secure_spec.lua @@ -6,11 +6,11 @@ local clear = helpers.clear local command = helpers.command local pathsep = helpers.get_pathsep() local is_os = helpers.is_os -local meths = helpers.meths +local api = helpers.api local exec_lua = helpers.exec_lua local feed_command = helpers.feed_command local feed = helpers.feed -local funcs = helpers.funcs +local fn = helpers.fn local pcall_err = helpers.pcall_err local matches = helpers.matches @@ -19,11 +19,14 @@ describe('vim.secure', function() local xstate = 'Xstate' setup(function() - clear{env={XDG_STATE_HOME=xstate}} + clear { env = { XDG_STATE_HOME = xstate } } helpers.mkdir_p(xstate .. pathsep .. (is_os('win') and 'nvim-data' or 'nvim')) - helpers.write_file('Xfile', [[ + helpers.write_file( + 'Xfile', + [[ let g:foobar = 42 - ]]) + ]] + ) end) teardown(function() @@ -35,132 +38,139 @@ describe('vim.secure', function() local screen = Screen.new(80, 8) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {bold = true, reverse = true}, - [3] = {bold = true, foreground = Screen.colors.SeaGreen}, - [4] = {reverse = true}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { bold = true, reverse = true }, + [3] = { bold = true, foreground = Screen.colors.SeaGreen }, + [4] = { reverse = true }, }) --- XXX: screen:expect() may fail if this path is too long. - local cwd = funcs.getcwd() + local cwd = fn.getcwd() -- Need to use feed_command instead of exec_lua because of the confirmation prompt feed_command([[lua vim.secure.read('Xfile')]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2: }| :lua vim.secure.read('Xfile') | - {3:]] .. cwd .. pathsep .. [[Xfile is not trusted.}{MATCH:%s+}| + {3:]] + .. cwd + .. pathsep + .. [[Xfile is not trusted.}{MATCH:%s+}| {3:[i]gnore, (v)iew, (d)eny, (a)llow: }^ | - ]]} + ]], + } feed('d') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | - ]]} + ]], + } - local trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + local trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(string.format('! %s', cwd .. pathsep .. 'Xfile'), vim.trim(trust)) - eq(helpers.NIL, exec_lua([[return vim.secure.read('Xfile')]])) + eq(vim.NIL, exec_lua([[return vim.secure.read('Xfile')]])) - os.remove(funcs.stdpath('state') .. pathsep .. 'trust') + os.remove(fn.stdpath('state') .. pathsep .. 'trust') feed_command([[lua vim.secure.read('Xfile')]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2: }| :lua vim.secure.read('Xfile') | - {3:]] .. cwd .. pathsep .. [[Xfile is not trusted.}{MATCH:%s+}| + {3:]] + .. cwd + .. pathsep + .. [[Xfile is not trusted.}{MATCH:%s+}| {3:[i]gnore, (v)iew, (d)eny, (a)llow: }^ | - ]]} + ]], + } feed('a') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | - ]]} + ]], + } - local hash = funcs.sha256(helpers.read_file('Xfile')) - trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + local hash = fn.sha256(helpers.read_file('Xfile')) + trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(string.format('%s %s', hash, cwd .. pathsep .. 'Xfile'), vim.trim(trust)) - eq(helpers.NIL, exec_lua([[vim.secure.read('Xfile')]])) + eq(vim.NIL, exec_lua([[vim.secure.read('Xfile')]])) - os.remove(funcs.stdpath('state') .. pathsep .. 'trust') + os.remove(fn.stdpath('state') .. pathsep .. 'trust') feed_command([[lua vim.secure.read('Xfile')]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2: }| :lua vim.secure.read('Xfile') | - {3:]] .. cwd .. pathsep .. [[Xfile is not trusted.}{MATCH:%s+}| + {3:]] + .. cwd + .. pathsep + .. [[Xfile is not trusted.}{MATCH:%s+}| {3:[i]gnore, (v)iew, (d)eny, (a)llow: }^ | - ]]} + ]], + } feed('i') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | - ]]} + ]], + } -- Trust database is not updated - trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(nil, trust) feed_command([[lua vim.secure.read('Xfile')]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2: }| :lua vim.secure.read('Xfile') | - {3:]] .. cwd .. pathsep .. [[Xfile is not trusted.}{MATCH:%s+}| + {3:]] + .. cwd + .. pathsep + .. [[Xfile is not trusted.}{MATCH:%s+}| {3:[i]gnore, (v)iew, (d)eny, (a)llow: }^ | - ]]} + ]], + } feed('v') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^let g:foobar = 42 | - {1:~ }| - {1:~ }| - {2:]] .. funcs.fnamemodify(cwd, ':~') .. pathsep .. [[Xfile [RO]{MATCH:%s+}}| + {1:~ }|*2 + {2:]] + .. fn.fnamemodify(cwd, ':~') + .. pathsep + .. [[Xfile [RO]{MATCH:%s+}}| | {1:~ }| {4:[No Name] }| | - ]]} + ]], + } -- Trust database is not updated - trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(nil, trust) -- Cannot write file pcall_err(command, 'write') - eq(true, meths.get_option_value('readonly', {})) + eq(true, api.nvim_get_option_value('readonly', {})) end) end) @@ -168,7 +178,7 @@ describe('vim.secure', function() local xstate = 'Xstate' setup(function() - clear{env={XDG_STATE_HOME=xstate}} + clear { env = { XDG_STATE_HOME = xstate } } helpers.mkdir_p(xstate .. pathsep .. (is_os('win') and 'nvim-data' or 'nvim')) end) @@ -185,95 +195,113 @@ describe('vim.secure', function() end) it('returns error when passing both path and bufnr', function() - matches('"path" and "bufnr" are mutually exclusive', - pcall_err(exec_lua, [[vim.secure.trust({action='deny', bufnr=0, path='test_file'})]])) + matches( + '"path" and "bufnr" are mutually exclusive', + pcall_err(exec_lua, [[vim.secure.trust({action='deny', bufnr=0, path='test_file'})]]) + ) end) it('returns error when passing neither path or bufnr', function() - matches('one of "path" or "bufnr" is required', - pcall_err(exec_lua, [[vim.secure.trust({action='deny'})]])) + matches( + 'one of "path" or "bufnr" is required', + pcall_err(exec_lua, [[vim.secure.trust({action='deny'})]]) + ) end) it('trust then deny then remove a file using bufnr', function() - local cwd = funcs.getcwd() - local hash = funcs.sha256(helpers.read_file('test_file')) + local cwd = fn.getcwd() + local hash = fn.sha256(helpers.read_file('test_file')) local full_path = cwd .. pathsep .. 'test_file' command('edit test_file') - eq({true, full_path}, exec_lua([[return {vim.secure.trust({action='allow', bufnr=0})}]])) - local trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + eq({ true, full_path }, exec_lua([[return {vim.secure.trust({action='allow', bufnr=0})}]])) + local trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(string.format('%s %s', hash, full_path), vim.trim(trust)) - eq({true, full_path}, exec_lua([[return {vim.secure.trust({action='deny', bufnr=0})}]])) - trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + eq({ true, full_path }, exec_lua([[return {vim.secure.trust({action='deny', bufnr=0})}]])) + trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(string.format('! %s', full_path), vim.trim(trust)) - eq({true, full_path}, exec_lua([[return {vim.secure.trust({action='remove', bufnr=0})}]])) - trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + eq({ true, full_path }, exec_lua([[return {vim.secure.trust({action='remove', bufnr=0})}]])) + trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq('', vim.trim(trust)) end) it('deny then trust then remove a file using bufnr', function() - local cwd = funcs.getcwd() - local hash = funcs.sha256(helpers.read_file('test_file')) + local cwd = fn.getcwd() + local hash = fn.sha256(helpers.read_file('test_file')) local full_path = cwd .. pathsep .. 'test_file' command('edit test_file') - eq({true, full_path}, exec_lua([[return {vim.secure.trust({action='deny', bufnr=0})}]])) - local trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + eq({ true, full_path }, exec_lua([[return {vim.secure.trust({action='deny', bufnr=0})}]])) + local trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(string.format('! %s', full_path), vim.trim(trust)) - eq({true, full_path}, exec_lua([[return {vim.secure.trust({action='allow', bufnr=0})}]])) - trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + eq({ true, full_path }, exec_lua([[return {vim.secure.trust({action='allow', bufnr=0})}]])) + trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(string.format('%s %s', hash, full_path), vim.trim(trust)) - eq({true, full_path}, exec_lua([[return {vim.secure.trust({action='remove', bufnr=0})}]])) - trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + eq({ true, full_path }, exec_lua([[return {vim.secure.trust({action='remove', bufnr=0})}]])) + trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq('', vim.trim(trust)) end) it('trust using bufnr then deny then remove a file using path', function() - local cwd = funcs.getcwd() - local hash = funcs.sha256(helpers.read_file('test_file')) + local cwd = fn.getcwd() + local hash = fn.sha256(helpers.read_file('test_file')) local full_path = cwd .. pathsep .. 'test_file' command('edit test_file') - eq({true, full_path}, exec_lua([[return {vim.secure.trust({action='allow', bufnr=0})}]])) - local trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + eq({ true, full_path }, exec_lua([[return {vim.secure.trust({action='allow', bufnr=0})}]])) + local trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(string.format('%s %s', hash, full_path), vim.trim(trust)) - eq({true, full_path}, exec_lua([[return {vim.secure.trust({action='deny', path='test_file'})}]])) - trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + eq( + { true, full_path }, + exec_lua([[return {vim.secure.trust({action='deny', path='test_file'})}]]) + ) + trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(string.format('! %s', full_path), vim.trim(trust)) - eq({true, full_path}, exec_lua([[return {vim.secure.trust({action='remove', path='test_file'})}]])) - trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + eq( + { true, full_path }, + exec_lua([[return {vim.secure.trust({action='remove', path='test_file'})}]]) + ) + trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq('', vim.trim(trust)) end) it('deny then trust then remove a file using bufnr', function() - local cwd = funcs.getcwd() - local hash = funcs.sha256(helpers.read_file('test_file')) + local cwd = fn.getcwd() + local hash = fn.sha256(helpers.read_file('test_file')) local full_path = cwd .. pathsep .. 'test_file' command('edit test_file') - eq({true, full_path}, exec_lua([[return {vim.secure.trust({action='deny', path='test_file'})}]])) - local trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + eq( + { true, full_path }, + exec_lua([[return {vim.secure.trust({action='deny', path='test_file'})}]]) + ) + local trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(string.format('! %s', full_path), vim.trim(trust)) - eq({true, full_path}, exec_lua([[return {vim.secure.trust({action='allow', bufnr=0})}]])) - trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + eq({ true, full_path }, exec_lua([[return {vim.secure.trust({action='allow', bufnr=0})}]])) + trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq(string.format('%s %s', hash, full_path), vim.trim(trust)) - eq({true, full_path}, exec_lua([[return {vim.secure.trust({action='remove', path='test_file'})}]])) - trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust') + eq( + { true, full_path }, + exec_lua([[return {vim.secure.trust({action='remove', path='test_file'})}]]) + ) + trust = helpers.read_file(fn.stdpath('state') .. pathsep .. 'trust') eq('', vim.trim(trust)) end) it('trust returns error when buffer not associated to file', function() command('new') - eq({false, 'buffer is not associated with a file'}, - exec_lua([[return {vim.secure.trust({action='allow', bufnr=0})}]])) + eq( + { false, 'buffer is not associated with a file' }, + exec_lua([[return {vim.secure.trust({action='allow', bufnr=0})}]]) + ) end) end) end) diff --git a/test/functional/lua/snippet_spec.lua b/test/functional/lua/snippet_spec.lua index f0b3b44139..e981bc6261 100644 --- a/test/functional/lua/snippet_spec.lua +++ b/test/functional/lua/snippet_spec.lua @@ -5,9 +5,11 @@ local clear = helpers.clear local eq = helpers.eq local exec_lua = helpers.exec_lua local feed = helpers.feed +local fn = helpers.fn local matches = helpers.matches local pcall_err = helpers.pcall_err -local sleep = helpers.sleep +local poke_eventloop = helpers.poke_eventloop +local retry = helpers.retry describe('vim.snippet', function() before_each(function() @@ -35,6 +37,12 @@ describe('vim.snippet', function() eq(expected, buf_lines(0)) end + local function wait_for_pum() + retry(nil, nil, function() + eq(1, fn.pumvisible()) + end) + end + --- @param snippet string --- @param err string local function test_expand_fail(snippet, err) @@ -154,7 +162,10 @@ describe('vim.snippet', function() end) it('errors with multiple placeholders for the same index', function() - test_expand_fail('class ${1:Foo} { void ${1:foo}() {} }', 'multiple placeholders for tabstop $1') + test_expand_fail( + 'class ${1:Foo} { void ${1:foo}() {} }', + 'multiple placeholders for tabstop $1' + ) end) it('errors with multiple $0 tabstops', function() @@ -162,30 +173,36 @@ describe('vim.snippet', function() end) it('cancels session when deleting the snippet', function() - test_expand_success({ 'local function $1()', ' $0', 'end' }, { 'local function ()', ' ', 'end' }) + test_expand_success( + { 'local function $1()', ' $0', 'end' }, + { 'local function ()', ' ', 'end' } + ) feed('<esc>Vjjd') eq(false, exec_lua('return vim.snippet.active()')) end) it('cancels session when inserting outside snippet region', function() feed('i<cr>') - test_expand_success({ 'local function $1()', ' $0', 'end' }, { '', 'local function ()', ' ', 'end' }) + test_expand_success( + { 'local function $1()', ' $0', 'end' }, + { '', 'local function ()', ' ', 'end' } + ) feed('<esc>O-- A comment') eq(false, exec_lua('return vim.snippet.active()')) end) - it('inserts choice', function () + it('inserts choice', function() test_expand_success({ 'console.${1|assert,log,error|}()' }, { 'console.()' }) - sleep(100) + wait_for_pum() feed('<Down><C-y>') eq({ 'console.log()' }, buf_lines(0)) end) - it('closes the choice completion menu when jumping', function () + it('closes the choice completion menu when jumping', function() test_expand_success({ 'console.${1|assert,log,error|}($2)' }, { 'console.()' }) - sleep(100) + wait_for_pum() exec_lua('vim.snippet.jump(1)') - eq(0, exec_lua('return vim.fn.pumvisible()')) + eq(0, fn.pumvisible()) end) it('jumps to next tabstop after inserting choice', function() @@ -193,10 +210,34 @@ describe('vim.snippet', function() { '${1|public,protected,private|} function ${2:name}() {', '\t$0', '}' }, { ' function name() {', '\t', '}' } ) - sleep(100) + wait_for_pum() feed('<C-y><Tab>') - sleep(10) + poke_eventloop() feed('foo') eq({ 'public function foo() {', '\t', '}' }, buf_lines(0)) end) + + it('jumps through adjacent tabstops', function() + test_expand_success( + { 'for i=1,${1:to}${2:,step} do\n\t$3\nend' }, + { 'for i=1,to,step do', '\t', 'end' } + ) + feed('10') + feed('<Tab>') + poke_eventloop() + feed(',2') + eq({ 'for i=1,10,2 do', '\t', 'end' }, buf_lines(0)) + end) + + it('updates snippet state when built-in completion menu is visible', function() + test_expand_success({ '$1 = function($2)\n$3\nend' }, { ' = function()', '', 'end' }) + -- Show the completion menu. + feed('<C-n>') + -- Make sure no item is selected. + feed('<C-p>') + -- Jump forward (the 2nd tabstop). + exec_lua('vim.snippet.jump(1)') + feed('foo') + eq({ ' = function(foo)', '', 'end' }, buf_lines(0)) + end) end) diff --git a/test/functional/lua/spell_spec.lua b/test/functional/lua/spell_spec.lua index b3de6a0912..e82dd7b4a0 100644 --- a/test/functional/lua/spell_spec.lua +++ b/test/functional/lua/spell_spec.lua @@ -11,43 +11,32 @@ describe('vim.spell', function() describe('.check', function() local check = function(x, exp) - return eq(exp, exec_lua("return vim.spell.check(...)", x)) + return eq(exp, exec_lua('return vim.spell.check(...)', x)) end it('can handle nil', function() - eq([[bad argument #1 to 'check' (expected string)]], - pcall_err(exec_lua, [[vim.spell.check(nil)]])) + eq( + [[bad argument #1 to 'check' (expected string)]], + pcall_err(exec_lua, [[vim.spell.check(nil)]]) + ) end) it('can check spellings', function() check('hello', {}) - check( - 'helloi', - {{"helloi", "bad", 1}} - ) + check('helloi', { { 'helloi', 'bad', 1 } }) - check( - 'hello therei', - {{"therei", "bad", 7}} - ) + check('hello therei', { { 'therei', 'bad', 7 } }) - check( - 'hello. there', - {{"there", "caps", 8}} - ) + check('hello. there', { { 'there', 'caps', 8 } }) - check( - 'neovim cna chkc spellins. okay?', - { - {"neovim" , "bad" , 1}, - {"cna" , "bad" , 8}, - {"chkc" , "bad" , 12}, - {"spellins", "bad" , 17}, - {"okay" , "caps", 27} - } - ) + check('neovim cna chkc spellins. okay?', { + { 'neovim', 'bad', 1 }, + { 'cna', 'bad', 8 }, + { 'chkc', 'bad', 12 }, + { 'spellins', 'bad', 17 }, + { 'okay', 'caps', 27 }, + }) end) - end) end) diff --git a/test/functional/lua/system_spec.lua b/test/functional/lua/system_spec.lua index a988d3f0d7..cb561f0771 100644 --- a/test/functional/lua/system_spec.lua +++ b/test/functional/lua/system_spec.lua @@ -4,7 +4,8 @@ local exec_lua = helpers.exec_lua local eq = helpers.eq local function system_sync(cmd, opts) - return exec_lua([[ + return exec_lua( + [[ local cmd, opts = ... local obj = vim.system(...) @@ -21,11 +22,15 @@ local function system_sync(cmd, opts) assert(not proc, 'process still exists') return res - ]], cmd, opts) + ]], + cmd, + opts + ) end local function system_async(cmd, opts) - return exec_lua([[ + return exec_lua( + [[ local cmd, opts = ... _G.done = false local obj = vim.system(cmd, opts, function(obj) @@ -44,7 +49,10 @@ local function system_async(cmd, opts) assert(not proc, 'process still exists') return _G.ret - ]], cmd, opts) + ]], + cmd, + opts + ) end describe('vim.system', function() @@ -52,10 +60,10 @@ describe('vim.system', function() clear() end) - for name, system in pairs{ sync = system_sync, async = system_async, } do - describe('('..name..')', function() + for name, system in pairs { sync = system_sync, async = system_async } do + describe('(' .. name .. ')', function() it('can run simple commands', function() - eq('hello\n', system({'echo', 'hello' }, { text = true }).stdout) + eq('hello\n', system({ 'echo', 'hello' }, { text = true }).stdout) end) it('handle input', function() @@ -67,7 +75,7 @@ describe('vim.system', function() code = 124, signal = 15, stdout = '', - stderr = '' + stderr = '', }, system({ 'sleep', '10' }, { timeout = 1000 })) end) end) @@ -97,4 +105,17 @@ describe('vim.system', function() ]]) end) + it('SystemObj:wait() does not process non-fast events #27292', function() + eq( + false, + exec_lua([[ + _G.processed = false + local cmd = vim.system({ 'sleep', '1' }) + vim.schedule(function() _G.processed = true end) + cmd:wait() + return _G.processed + ]]) + ) + eq(true, exec_lua([[return _G.processed]])) + end) end) diff --git a/test/functional/lua/text_spec.lua b/test/functional/lua/text_spec.lua index 68206557c3..e31aa63768 100644 --- a/test/functional/lua/text_spec.lua +++ b/test/functional/lua/text_spec.lua @@ -20,4 +20,3 @@ describe('vim.text', function() end) end) end) - diff --git a/test/functional/lua/thread_spec.lua b/test/functional/lua/thread_spec.lua index e79d26a641..c1981e19d4 100644 --- a/test/functional/lua/thread_spec.lua +++ b/test/functional/lua/thread_spec.lua @@ -6,7 +6,7 @@ local feed = helpers.feed local eq = helpers.eq local exec_lua = helpers.exec_lua local next_msg = helpers.next_msg -local NIL = helpers.NIL +local NIL = vim.NIL local pcall_err = helpers.pcall_err describe('thread', function() @@ -17,11 +17,11 @@ describe('thread', function() screen = Screen.new(50, 10) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {bold = true, reverse = true}, - [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [4] = {bold = true, foreground = Screen.colors.SeaGreen4}, - [5] = {bold = true}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { bold = true, reverse = true }, + [3] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [5] = { bold = true }, }) end) @@ -35,11 +35,7 @@ describe('thread', function() screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2: }| {3:Error in luv thread:} | {3:[string "<nvim>"]:2: Error in thread entry func} | @@ -66,11 +62,7 @@ describe('thread', function() screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2: }| {3:Error in luv callback, thread:} | {3:[string "<nvim>"]:6: Error in thread callback} | @@ -91,14 +83,7 @@ describe('thread', function() screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 print in thread | ]]) end) @@ -113,14 +98,7 @@ describe('thread', function() screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 { 1, 2 } | ]]) end) @@ -172,7 +150,7 @@ describe('thread', function() thread_test:do_test() ]] - eq({'notification', 'result', {true}}, next_msg()) + eq({ 'notification', 'result', { true } }, next_msg()) end) it('uv', function() @@ -204,7 +182,7 @@ describe('thread', function() thread_test:do_test() ]] - eq({'notification', 'result', {{33, NIL, 'text'}}}, next_msg()) + eq({ 'notification', 'result', { { 33, NIL, 'text' } } }, next_msg()) end) it('json', function() @@ -219,7 +197,7 @@ describe('thread', function() thread_test:do_test() ]] - eq({'notification', 'result', {{33, NIL, 'text'}}}, next_msg()) + eq({ 'notification', 'result', { { 33, NIL, 'text' } } }, next_msg()) end) it('diff', function() @@ -234,14 +212,18 @@ describe('thread', function() thread_test:do_test() ]] - eq({'notification', 'result', - {table.concat({ + eq({ + 'notification', + 'result', + { + table.concat({ '@@ -1 +1 @@', '-Hello', '+Helli', - '' - }, '\n')}}, - next_msg()) + '', + }, '\n'), + }, + }, next_msg()) end) end) end) @@ -263,28 +245,30 @@ describe('threadpool', function() work:queue() ]] - eq({'notification', 'result', {true}}, next_msg()) + eq({ 'notification', 'result', { true } }, next_msg()) end) it('with invalid argument', function() - local status = pcall_err(exec_lua, [[ + local status = pcall_err( + exec_lua, + [[ local work = vim.uv.new_thread(function() end, function() end) work:queue({}) - ]]) + ]] + ) - eq([[Error: thread arg not support type 'function' at 1]], - status) + eq([[Error: thread arg not support type 'function' at 1]], status) end) it('with invalid return value', function() local screen = Screen.new(50, 10) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {bold = true, reverse = true}, - [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [4] = {bold = true, foreground = Screen.colors.SeaGreen4}, - [5] = {bold = true}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { bold = true, reverse = true }, + [3] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [5] = { bold = true }, }) exec_lua [[ @@ -294,11 +278,7 @@ describe('threadpool', function() screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2: }| {3:Error in luv thread:} | {3:Error: thread arg not support type 'table' at 1} | @@ -364,7 +344,7 @@ describe('threadpool', function() threadpool_test:do_test() ]] - eq({'notification', 'result', {{33, NIL, 'text'}}}, next_msg()) + eq({ 'notification', 'result', { { 33, NIL, 'text' } } }, next_msg()) end) it('json', function() @@ -380,7 +360,7 @@ describe('threadpool', function() threadpool_test:do_test() ]] - eq({'notification', 'result', {{33, NIL, 'text'}}}, next_msg()) + eq({ 'notification', 'result', { { 33, NIL, 'text' } } }, next_msg()) end) it('work', function() @@ -395,14 +375,18 @@ describe('threadpool', function() threadpool_test:do_test() ]] - eq({'notification', 'result', - {table.concat({ + eq({ + 'notification', + 'result', + { + table.concat({ '@@ -1 +1 @@', '-Hello', '+Helli', - '' - }, '\n')}}, - next_msg()) + '', + }, '\n'), + }, + }, next_msg()) end) end) end) diff --git a/test/functional/lua/ui_event_spec.lua b/test/functional/lua/ui_event_spec.lua index 373d45da61..3e46018682 100644 --- a/test/functional/lua/ui_event_spec.lua +++ b/test/functional/lua/ui_event_spec.lua @@ -4,8 +4,7 @@ local eq = helpers.eq local exec_lua = helpers.exec_lua local clear = helpers.clear local feed = helpers.feed -local funcs = helpers.funcs -local inspect = require'vim.inspect' +local fn = helpers.fn describe('vim.ui_attach', function() local screen @@ -26,60 +25,67 @@ describe('vim.ui_attach', function() end ]] - screen = Screen.new(40,5) + screen = Screen.new(40, 5) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}; - [2] = {bold = true}; - [3] = {background = Screen.colors.Grey}; - [4] = {background = Screen.colors.LightMagenta}; + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { bold = true }, + [3] = { background = Screen.colors.Grey }, + [4] = { background = Screen.colors.LightMagenta }, }) screen:attach() end) local function expect_events(expected) - local evs = exec_lua "return get_events(...)" - eq(expected, evs, inspect(evs)) + local evs = exec_lua 'return get_events(...)' + eq(expected, evs, vim.inspect(evs)) end it('can receive popupmenu events', function() exec_lua [[ vim.ui_attach(ns, {ext_popupmenu=true}, on_event) ]] feed('ifo') - screen:expect{grid=[[ + screen:expect { + grid = [[ fo^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2:-- INSERT --} | - ]]} + ]], + } - funcs.complete(1, {'food', 'foobar', 'foo'}) - screen:expect{grid=[[ + fn.complete(1, { 'food', 'foobar', 'foo' }) + screen:expect { + grid = [[ food^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2:-- INSERT --} | - ]]} + ]], + } expect_events { - { "popupmenu_show", { { "food", "", "", "" }, { "foobar", "", "", "" }, { "foo", "", "", "" } }, 0, 0, 0, 1 }; + { + 'popupmenu_show', + { { 'food', '', '', '' }, { 'foobar', '', '', '' }, { 'foo', '', '', '' } }, + 0, + 0, + 0, + 1, + }, } feed '<c-n>' - screen:expect{grid=[[ + screen:expect { + grid = [[ foobar^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2:-- INSERT --} | - ]]} + ]], + } expect_events { - { "popupmenu_select", 1 }; + { 'popupmenu_select', 1 }, } feed '<c-y>' screen:expect_unchanged() expect_events { - { "popupmenu_hide" }; + { 'popupmenu_hide' }, } -- vim.ui_detach() stops events, and reenables builtin pum immediately @@ -88,26 +94,31 @@ describe('vim.ui_attach', function() vim.fn.complete(1, {'food', 'foobar', 'foo'}) ]] - screen:expect{grid=[[ + screen:expect { + grid = [[ food^ | {3:food }{1: }| {4:foobar }{1: }| {4:foo }{1: }| {2:-- INSERT --} | - ]]} - expect_events { + ]], } - + expect_events {} end) it('does not crash on exit', function() - helpers.funcs.system({ + fn.system({ helpers.nvim_prog, - '-u', 'NONE', - '-i', 'NONE', - '--cmd', [[ lua ns = vim.api.nvim_create_namespace 'testspace' ]], - '--cmd', [[ lua vim.ui_attach(ns, {ext_popupmenu=true}, function() end) ]], - '--cmd', 'quitall!', + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + [[ lua ns = vim.api.nvim_create_namespace 'testspace' ]], + '--cmd', + [[ lua vim.ui_attach(ns, {ext_popupmenu=true}, function() end) ]], + '--cmd', + 'quitall!', }) eq(0, helpers.eval('v:shell_error')) end) @@ -136,6 +147,6 @@ describe('vim.ui_attach', function() { 'echomsg', { { 0, 'message3' } } }, }, }, - }, actual, inspect(actual)) + }, actual, vim.inspect(actual)) end) end) diff --git a/test/functional/lua/ui_spec.lua b/test/functional/lua/ui_spec.lua index d4c150c5f2..e769843b19 100644 --- a/test/functional/lua/ui_spec.lua +++ b/test/functional/lua/ui_spec.lua @@ -16,7 +16,7 @@ describe('vim.ui', function() describe('select()', function() it('can select an item', function() - local result = exec_lua[[ + local result = exec_lua [[ local items = { { name = 'Item 1' }, { name = 'Item 2' }, @@ -51,7 +51,7 @@ describe('vim.ui', function() describe('input()', function() it('can input text', function() - local result = exec_lua[[ + local result = exec_lua [[ local opts = { prompt = 'Input: ', } @@ -117,38 +117,44 @@ describe('vim.ui', function() it('can return nil when interrupted with Ctrl-C #18144', function() feed(':lua result = "on_confirm not called"<cr>') feed(':lua vim.ui.input({}, function(input) result = input end)<cr>') - poke_eventloop() -- This is needed because Ctrl-C flushes input + poke_eventloop() -- This is needed because Ctrl-C flushes input feed('Inputted Text<c-c>') eq(true, exec_lua('return (nil == result)')) end) - it('can return the identical object when an arbitrary opts.cancelreturn object is given', function() - feed(':lua fn = function() return 42 end<CR>') - eq(42, exec_lua('return fn()')) - feed(':lua vim.ui.input({ cancelreturn = fn }, function(input) result = input end)<cr>') - feed('cancel<esc>') - eq(true, exec_lua('return (result == fn)')) - eq(42, exec_lua('return result()')) - end) - + it( + 'can return the identical object when an arbitrary opts.cancelreturn object is given', + function() + feed(':lua fn = function() return 42 end<CR>') + eq(42, exec_lua('return fn()')) + feed(':lua vim.ui.input({ cancelreturn = fn }, function(input) result = input end)<cr>') + feed('cancel<esc>') + eq(true, exec_lua('return (result == fn)')) + eq(42, exec_lua('return result()')) + end + ) end) describe('open()', function() it('validation', function() if is_os('win') or not is_ci('github') then - exec_lua[[vim.system = function() return { wait=function() return { code=3} end } end]] + exec_lua [[vim.system = function() return { wait=function() return { code=3} end } end]] end if not is_os('bsd') then - matches('vim.ui.open: command failed %(%d%): { "[^"]+", .*"non%-existent%-file" }', - exec_lua[[local _, err = vim.ui.open('non-existent-file') ; return err]]) + matches( + 'vim.ui.open: command failed %(%d%): { "[^"]+", .*"non%-existent%-file" }', + exec_lua [[local _, err = vim.ui.open('non-existent-file') ; return err]] + ) end - exec_lua[[ + exec_lua [[ vim.fn.has = function() return 0 end vim.fn.executable = function() return 0 end ]] - eq('vim.ui.open: no handler found (tried: wslview, xdg-open)', - exec_lua[[local _, err = vim.ui.open('foo') ; return err]]) + eq( + 'vim.ui.open: no handler found (tried: explorer.exe, xdg-open)', + exec_lua [[local _, err = vim.ui.open('foo') ; return err]] + ) end) end) end) diff --git a/test/functional/lua/uri_spec.lua b/test/functional/lua/uri_spec.lua index 416e9e1f02..dacaf95867 100644 --- a/test/functional/lua/uri_spec.lua +++ b/test/functional/lua/uri_spec.lua @@ -16,20 +16,23 @@ describe('URI methods', function() it('file path includes only ascii characters', function() exec_lua("filepath = '/Foo/Bar/Baz.txt'") - eq('file:///Foo/Bar/Baz.txt', exec_lua("return vim.uri_from_fname(filepath)")) + eq('file:///Foo/Bar/Baz.txt', exec_lua('return vim.uri_from_fname(filepath)')) end) it('file path including white space', function() exec_lua("filepath = '/Foo /Bar/Baz.txt'") - eq('file:///Foo%20/Bar/Baz.txt', exec_lua("return vim.uri_from_fname(filepath)")) + eq('file:///Foo%20/Bar/Baz.txt', exec_lua('return vim.uri_from_fname(filepath)')) end) it('file path including Unicode characters', function() exec_lua("filepath = '/xy/åäö/ɧ/汉语/↥/🤦/🦄/å/بِيَّ.txt'") -- The URI encoding should be case-insensitive - eq('file:///xy/%c3%a5%c3%a4%c3%b6/%c9%a7/%e6%b1%89%e8%af%ad/%e2%86%a5/%f0%9f%a4%a6/%f0%9f%a6%84/a%cc%8a/%d8%a8%d9%90%d9%8a%d9%8e%d9%91.txt', exec_lua("return vim.uri_from_fname(filepath)")) + eq( + 'file:///xy/%c3%a5%c3%a4%c3%b6/%c9%a7/%e6%b1%89%e8%af%ad/%e2%86%a5/%f0%9f%a4%a6/%f0%9f%a6%84/a%cc%8a/%d8%a8%d9%90%d9%8a%d9%8e%d9%91.txt', + exec_lua('return vim.uri_from_fname(filepath)') + ) end) end) @@ -37,19 +40,22 @@ describe('URI methods', function() it('file path includes only ascii characters', function() exec_lua([[filepath = 'C:\\Foo\\Bar\\Baz.txt']]) - eq('file:///C:/Foo/Bar/Baz.txt', exec_lua("return vim.uri_from_fname(filepath)")) + eq('file:///C:/Foo/Bar/Baz.txt', exec_lua('return vim.uri_from_fname(filepath)')) end) it('file path including white space', function() exec_lua([[filepath = 'C:\\Foo \\Bar\\Baz.txt']]) - eq('file:///C:/Foo%20/Bar/Baz.txt', exec_lua("return vim.uri_from_fname(filepath)")) + eq('file:///C:/Foo%20/Bar/Baz.txt', exec_lua('return vim.uri_from_fname(filepath)')) end) it('file path including Unicode characters', function() exec_lua([[filepath = 'C:\\xy\\åäö\\ɧ\\汉语\\↥\\🤦\\🦄\\å\\بِيَّ.txt']]) - eq('file:///C:/xy/%c3%a5%c3%a4%c3%b6/%c9%a7/%e6%b1%89%e8%af%ad/%e2%86%a5/%f0%9f%a4%a6/%f0%9f%a6%84/a%cc%8a/%d8%a8%d9%90%d9%8a%d9%8e%d9%91.txt', exec_lua("return vim.uri_from_fname(filepath)")) + eq( + 'file:///C:/xy/%c3%a5%c3%a4%c3%b6/%c9%a7/%e6%b1%89%e8%af%ad/%e2%86%a5/%f0%9f%a4%a6/%f0%9f%a6%84/a%cc%8a/%d8%a8%d9%90%d9%8a%d9%8e%d9%91.txt', + exec_lua('return vim.uri_from_fname(filepath)') + ) end) end) end) @@ -59,19 +65,19 @@ describe('URI methods', function() it('file path includes only ascii characters', function() exec_lua("uri = 'file:///Foo/Bar/Baz.txt'") - eq('/Foo/Bar/Baz.txt', exec_lua("return vim.uri_to_fname(uri)")) + eq('/Foo/Bar/Baz.txt', exec_lua('return vim.uri_to_fname(uri)')) end) it('local file path without hostname', function() exec_lua("uri = 'file:/Foo/Bar/Baz.txt'") - eq('/Foo/Bar/Baz.txt', exec_lua("return vim.uri_to_fname(uri)")) + eq('/Foo/Bar/Baz.txt', exec_lua('return vim.uri_to_fname(uri)')) end) it('file path including white space', function() exec_lua("uri = 'file:///Foo%20/Bar/Baz.txt'") - eq('/Foo /Bar/Baz.txt', exec_lua("return vim.uri_to_fname(uri)")) + eq('/Foo /Bar/Baz.txt', exec_lua('return vim.uri_to_fname(uri)')) end) it('file path including Unicode characters', function() @@ -82,6 +88,12 @@ describe('URI methods', function() eq('/xy/åäö/ɧ/汉语/↥/🤦/🦄/å/بِيَّ.txt', exec_lua(test_case)) end) + + it('file path with uri fragment', function() + exec_lua("uri = 'file:///Foo/Bar/Baz.txt#fragment'") + + eq('/Foo/Bar/Baz.txt', exec_lua('return vim.uri_to_fname(uri)')) + end) end) describe('decode Windows filepath', function() @@ -133,73 +145,109 @@ describe('URI methods', function() describe('decode non-file URI', function() it('uri_to_fname returns non-file URI unchanged', function() - eq('jdt1.23+x-z://content/%5C/', exec_lua [[ + eq( + 'jdt1.23+x-z://content/%5C/', + exec_lua [[ return vim.uri_to_fname('jdt1.23+x-z://content/%5C/') - ]]) + ]] + ) end) it('uri_to_fname returns non-file upper-case scheme URI unchanged', function() - eq('JDT://content/%5C/', exec_lua [[ + eq( + 'JDT://content/%5C/', + exec_lua [[ return vim.uri_to_fname('JDT://content/%5C/') - ]]) + ]] + ) end) it('uri_to_fname returns non-file scheme URI without authority unchanged', function() - eq('zipfile:///path/to/archive.zip%3A%3Afilename.txt', exec_lua [[ + eq( + 'zipfile:///path/to/archive.zip%3A%3Afilename.txt', + exec_lua [[ return vim.uri_to_fname('zipfile:///path/to/archive.zip%3A%3Afilename.txt') - ]]) + ]] + ) end) end) describe('decode URI without scheme', function() it('fails because URI must have a scheme', function() - eq(false, exec_lua [[ + eq( + false, + exec_lua [[ return pcall(vim.uri_to_fname, 'not_an_uri.txt') - ]]) + ]] + ) end) it('uri_to_fname should not treat comma as a scheme character', function() - eq(false, exec_lua [[ + eq( + false, + exec_lua [[ return pcall(vim.uri_to_fname, 'foo,://bar') - ]]) + ]] + ) end) - end) + it('uri_to_fname returns non-file schema URI with fragment unchanged', function() + eq( + 'scheme://path#fragment', + exec_lua [[ + return vim.uri_to_fname('scheme://path#fragment') + ]] + ) + end) + end) end) describe('uri from bufnr', function() it('Windows paths should not be treated as uris', function() - skip(not is_os('win'), "Not applicable on non-Windows") + skip(not is_os('win'), 'Not applicable on non-Windows') local file = helpers.tmpname() write_file(file, 'Test content') - local test_case = string.format([[ + local test_case = string.format( + [[ local file = '%s' return vim.uri_from_bufnr(vim.fn.bufadd(file)) - ]], file) - local expected_uri = 'file:///' .. file:gsub("\\", "/") - eq(expected_uri, exec_lua(test_case)) - os.remove(file) + ]], + file + ) + local expected_uri = 'file:///' .. file:gsub('\\', '/') + eq(expected_uri, exec_lua(test_case)) + os.remove(file) end) end) describe('uri to bufnr', function() it('uri_to_bufnr & uri_from_bufnr returns original uri for non-file uris', function() - local uri = 'jdt://contents/java.base/java.util/List.class?=sql/%5C/home%5C/user%5C/.jabba%5C/jdk%5C/openjdk%5C@1.14.0%5C/lib%5C/jrt-fs.jar%60java.base=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/en%5C/java%5C/javase%5C/14%5C/docs%5C/api%5C/=/%3Cjava.util(List.class' - local test_case = string.format([[ + local uri = + 'jdt://contents/java.base/java.util/List.class?=sql/%5C/home%5C/user%5C/.jabba%5C/jdk%5C/openjdk%5C@1.14.0%5C/lib%5C/jrt-fs.jar%60java.base=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/en%5C/java%5C/javase%5C/14%5C/docs%5C/api%5C/=/%3Cjava.util(List.class' + local test_case = string.format( + [[ local uri = '%s' return vim.uri_from_bufnr(vim.uri_to_bufnr(uri)) - ]], uri) + ]], + uri + ) eq(uri, exec_lua(test_case)) end) - it('uri_to_bufnr & uri_from_bufnr returns original uri for non-file uris without authority', function() - local uri = 'zipfile:///path/to/archive.zip%3A%3Afilename.txt' - local test_case = string.format([[ + it( + 'uri_to_bufnr & uri_from_bufnr returns original uri for non-file uris without authority', + function() + local uri = 'zipfile:///path/to/archive.zip%3A%3Afilename.txt' + local test_case = string.format( + [[ local uri = '%s' return vim.uri_from_bufnr(vim.uri_to_bufnr(uri)) - ]], uri) - eq(uri, exec_lua(test_case)) - end) + ]], + uri + ) + eq(uri, exec_lua(test_case)) + end + ) end) end) diff --git a/test/functional/lua/version_spec.lua b/test/functional/lua/version_spec.lua index d1c981c388..3bc9e26d41 100644 --- a/test/functional/lua/version_spec.lua +++ b/test/functional/lua/version_spec.lua @@ -11,7 +11,6 @@ local function v(ver) end describe('version', function() - it('package', function() clear() eq({ major = 42, minor = 3, patch = 99 }, exec_lua("return vim.version.parse('v42.3.99')")) @@ -35,7 +34,13 @@ describe('version', function() ['v1.2'] = { major = 1, minor = 2, patch = 0 }, ['v1.2.3-prerelease'] = { major = 1, minor = 2, patch = 3, prerelease = 'prerelease' }, ['v1.2-prerelease'] = { major = 1, minor = 2, patch = 0, prerelease = 'prerelease' }, - ['v1.2.3-prerelease+build'] = { major = 1, minor = 2, patch = 3, prerelease = 'prerelease', build = 'build' }, + ['v1.2.3-prerelease+build'] = { + major = 1, + minor = 2, + patch = 3, + prerelease = 'prerelease', + build = 'build', + }, ['1.2.3+build'] = { major = 1, minor = 2, patch = 3, build = 'build' }, } for input, output in pairs(tests) do @@ -108,86 +113,114 @@ describe('version', function() describe('cmp()', function() local testcases = { - { v1 = 'v0.0.99', v2 = 'v9.0.0', want = -1, }, - { v1 = 'v0.4.0', v2 = 'v0.9.99', want = -1, }, - { v1 = 'v0.2.8', v2 = 'v1.0.9', want = -1, }, - { v1 = 'v0.0.0', v2 = 'v0.0.0', want = 0, }, - { v1 = 'v9.0.0', v2 = 'v0.9.0', want = 1, }, - { v1 = 'v0.9.0', v2 = 'v0.0.0', want = 1, }, - { v1 = 'v0.0.9', v2 = 'v0.0.0', want = 1, }, - { v1 = 'v0.0.9+aaa', v2 = 'v0.0.9+bbb', want = 0, }, + { v1 = 'v0.0.99', v2 = 'v9.0.0', want = -1 }, + { v1 = 'v0.4.0', v2 = 'v0.9.99', want = -1 }, + { v1 = 'v0.2.8', v2 = 'v1.0.9', want = -1 }, + { v1 = 'v0.0.0', v2 = 'v0.0.0', want = 0 }, + { v1 = 'v9.0.0', v2 = 'v0.9.0', want = 1 }, + { v1 = 'v0.9.0', v2 = 'v0.0.0', want = 1 }, + { v1 = 'v0.0.9', v2 = 'v0.0.0', want = 1 }, + { v1 = 'v0.0.9+aaa', v2 = 'v0.0.9+bbb', want = 0 }, -- prerelease 💩 https://semver.org/#spec-item-11 - { v1 = 'v1.0.0-alpha', v2 = 'v1.0.0', want = -1, }, - { v1 = '1.0.0', v2 = '1.0.0-alpha', want = 1, }, - { v1 = '1.0.0-2', v2 = '1.0.0-1', want = 1, }, - { v1 = '1.0.0-2', v2 = '1.0.0-9', want = -1, }, - { v1 = '1.0.0-2', v2 = '1.0.0-2.0', want = -1, }, - { v1 = '1.0.0-2.0', v2 = '1.0.0-2', want = 1, }, - { v1 = '1.0.0-2.0', v2 = '1.0.0-2.0', want = 0, }, - { v1 = '1.0.0-alpha', v2 = '1.0.0-alpha', want = 0, }, - { v1 = '1.0.0-alpha', v2 = '1.0.0-beta', want = -1, }, - { v1 = '1.0.0-beta', v2 = '1.0.0-alpha', want = 1, }, - { v1 = '1.0.0-alpha', v2 = '1.0.0-alpha.1', want = -1, }, - { v1 = '1.0.0-alpha.1', v2 = '1.0.0-alpha', want = 1, }, - { v1 = '1.0.0-alpha.beta', v2 = '1.0.0-alpha', want = 1, }, - { v1 = '1.0.0-alpha', v2 = '1.0.0-alpha.beta', want = -1, }, - { v1 = '1.0.0-alpha.beta', v2 = '1.0.0-beta', want = -1, }, - { v1 = '1.0.0-beta.2', v2 = '1.0.0-beta.11', want = -1, }, - { v1 = '1.0.0-beta.20', v2 = '1.0.0-beta.11', want = 1, }, - { v1 = '1.0.0-alpha.20', v2 = '1.0.0-beta.11', want = -1, }, - { v1 = '1.0.0-a.01.x.3', v2 = '1.0.0-a.1.x.003', want = 0, }, - { v1 = 'v0.9.0-dev-92+9', v2 = 'v0.9.0-dev-120+3', want = -1, }, + { v1 = 'v1.0.0-alpha', v2 = 'v1.0.0', want = -1 }, + { v1 = '1.0.0', v2 = '1.0.0-alpha', want = 1 }, + { v1 = '1.0.0-2', v2 = '1.0.0-1', want = 1 }, + { v1 = '1.0.0-2', v2 = '1.0.0-9', want = -1 }, + { v1 = '1.0.0-2', v2 = '1.0.0-2.0', want = -1 }, + { v1 = '1.0.0-2.0', v2 = '1.0.0-2', want = 1 }, + { v1 = '1.0.0-2.0', v2 = '1.0.0-2.0', want = 0 }, + { v1 = '1.0.0-alpha', v2 = '1.0.0-alpha', want = 0 }, + { v1 = '1.0.0-alpha', v2 = '1.0.0-beta', want = -1 }, + { v1 = '1.0.0-beta', v2 = '1.0.0-alpha', want = 1 }, + { v1 = '1.0.0-alpha', v2 = '1.0.0-alpha.1', want = -1 }, + { v1 = '1.0.0-alpha.1', v2 = '1.0.0-alpha', want = 1 }, + { v1 = '1.0.0-alpha.beta', v2 = '1.0.0-alpha', want = 1 }, + { v1 = '1.0.0-alpha', v2 = '1.0.0-alpha.beta', want = -1 }, + { v1 = '1.0.0-alpha.beta', v2 = '1.0.0-beta', want = -1 }, + { v1 = '1.0.0-beta.2', v2 = '1.0.0-beta.11', want = -1 }, + { v1 = '1.0.0-beta.20', v2 = '1.0.0-beta.11', want = 1 }, + { v1 = '1.0.0-alpha.20', v2 = '1.0.0-beta.11', want = -1 }, + { v1 = '1.0.0-a.01.x.3', v2 = '1.0.0-a.1.x.003', want = 0 }, + { v1 = 'v0.9.0-dev-92+9', v2 = 'v0.9.0-dev-120+3', want = -1 }, } for _, tc in ipairs(testcases) do - local msg = function(s) return ('v1 %s v2'):format(s == 0 and '==' or (s == 1 and '>' or '<')) end - it(string.format('(v1 = %s, v2 = %s)', tc.v1, tc.v2), - function() - local rv = vim.version.cmp(tc.v1, tc.v2, { strict = true }) - ok(tc.want == rv, msg(tc.want), msg(rv)) - end - ) + local msg = function(s) + return ('v1 %s v2'):format(s == 0 and '==' or (s == 1 and '>' or '<')) + end + it(string.format('(v1 = %s, v2 = %s)', tc.v1, tc.v2), function() + local rv = vim.version.cmp(tc.v1, tc.v2, { strict = true }) + ok(tc.want == rv, msg(tc.want), msg(rv)) + end) end end) describe('parse()', function() describe('strict=true', function() local testcases = { - { desc = 'Nvim version', version = 'v0.9.0-dev-1233+g210120dde81e', want = { major = 0, minor = 9, patch = 0, prerelease = 'dev-1233', build = 'g210120dde81e', }, }, - { desc = 'no v', version = '10.20.123', want = { major = 10, minor = 20, patch = 123, prerelease = nil, build = nil, }, }, - { desc = 'with v', version = 'v1.2.3', want = { major = 1, minor = 2, patch = 3 }, }, - { desc = 'prerelease', version = '1.2.3-alpha', want = { major = 1, minor = 2, patch = 3, prerelease = 'alpha' }, }, - { desc = 'prerelease.x', version = '1.2.3-alpha.1', want = { major = 1, minor = 2, patch = 3, prerelease = 'alpha.1' }, }, - { desc = 'build.x', version = '1.2.3+build.15', want = { major = 1, minor = 2, patch = 3, build = 'build.15' }, }, - { desc = 'prerelease and build', version = '1.2.3-rc1+build.15', want = { major = 1, minor = 2, patch = 3, prerelease = 'rc1', build = 'build.15', }, }, + { + desc = 'Nvim version', + version = 'v0.9.0-dev-1233+g210120dde81e', + want = { + major = 0, + minor = 9, + patch = 0, + prerelease = 'dev-1233', + build = 'g210120dde81e', + }, + }, + { + desc = 'no v', + version = '10.20.123', + want = { major = 10, minor = 20, patch = 123, prerelease = nil, build = nil }, + }, + { + desc = 'with v', + version = 'v1.2.3', + want = { major = 1, minor = 2, patch = 3 }, + }, + { + desc = 'prerelease', + version = '1.2.3-alpha', + want = { major = 1, minor = 2, patch = 3, prerelease = 'alpha' }, + }, + { + desc = 'prerelease.x', + version = '1.2.3-alpha.1', + want = { major = 1, minor = 2, patch = 3, prerelease = 'alpha.1' }, + }, + { + desc = 'build.x', + version = '1.2.3+build.15', + want = { major = 1, minor = 2, patch = 3, build = 'build.15' }, + }, + { + desc = 'prerelease and build', + version = '1.2.3-rc1+build.15', + want = { major = 1, minor = 2, patch = 3, prerelease = 'rc1', build = 'build.15' }, + }, } for _, tc in ipairs(testcases) do - it( - string.format('%q: version = %q', tc.desc, tc.version), - function() - eq(tc.want, vim.version.parse(tc.version)) - end - ) + it(string.format('%q: version = %q', tc.desc, tc.version), function() + eq(tc.want, vim.version.parse(tc.version)) + end) end end) describe('strict=false', function() local testcases = { - { version = '1.2', want = { major = 1, minor = 2, patch = 0 }, }, - { version = '1', want = { major = 1, minor = 0, patch = 0 }, }, - { version = '1.1-0', want = { major = 1, minor = 1, patch = 0, prerelease = '0' }, }, - { version = '1-1.0', want = { major = 1, minor = 0, patch = 0, prerelease = '1.0' }, }, - { version = 'v1.2.3 ', want = { major = 1, minor = 2, patch = 3 }, }, - { version = ' v1.2.3', want = { major = 1, minor = 2, patch = 3 }, }, - { version = 'tmux 3.2a', want = { major = 3, minor = 2, patch = 0, }, }, + { version = '1.2', want = { major = 1, minor = 2, patch = 0 } }, + { version = '1', want = { major = 1, minor = 0, patch = 0 } }, + { version = '1.1-0', want = { major = 1, minor = 1, patch = 0, prerelease = '0' } }, + { version = '1-1.0', want = { major = 1, minor = 0, patch = 0, prerelease = '1.0' } }, + { version = 'v1.2.3 ', want = { major = 1, minor = 2, patch = 3 } }, + { version = ' v1.2.3', want = { major = 1, minor = 2, patch = 3 } }, + { version = 'tmux 3.2a', want = { major = 3, minor = 2, patch = 0 } }, } for _, tc in ipairs(testcases) do - it( - string.format('version = %q', tc.version), - function() - eq(tc.want, vim.version.parse(tc.version, { strict = false })) - end - ) + it(string.format('version = %q', tc.version), function() + eq(tc.want, vim.version.parse(tc.version, { strict = false })) + end) end end) @@ -205,8 +238,8 @@ describe('version', function() { version = '1.2.3-%?' }, { version = '1.2.3+%?' }, { version = '1.2.3+build.0-rc1' }, - { version = '3.2a', }, - { version = 'tmux 3.2a', }, + { version = '3.2a' }, + { version = 'tmux 3.2a' }, } local function quote_empty(s) @@ -230,8 +263,10 @@ describe('version', function() } for _, tc in ipairs(testcases) do it(string.format('(%s): %s', tc.desc, tostring(tc.version)), function() - local expected = string.format(type(tc.version) == 'string' - and 'invalid version: "%s"' or 'invalid version: %s', tostring(tc.version)) + local expected = string.format( + type(tc.version) == 'string' and 'invalid version: "%s"' or 'invalid version: %s', + tostring(tc.version) + ) matches(expected, pcall_err(vim.version.parse, tc.version, { strict = true })) end) end @@ -253,21 +288,55 @@ describe('version', function() eq(vim.version.last({ v('2.0.0'), v('1.2.3') }), v('2.0.0')) end) + it('le()', function() + eq(true, vim.version.le('1', '1')) + eq(true, vim.version.le({ 3, 1, 4 }, '3.1.4')) + eq(true, vim.version.le('1', '2')) + eq(true, vim.version.le({ 0, 7, 4 }, { 3 })) + eq(false, vim.version.le({ 3 }, { 0, 7, 4 })) + eq(false, vim.version.le({ major = 3, minor = 3, patch = 0 }, { 3, 2, 0 })) + eq(false, vim.version.le('2', '1')) + end) + it('lt()', function() + eq(false, vim.version.lt('1', '1')) + eq(false, vim.version.lt({ 3, 1, 4 }, '3.1.4')) eq(true, vim.version.lt('1', '2')) - eq(false, vim.version.lt({3}, {0, 7, 4})) - eq(false, vim.version.lt({major=3, minor=3, patch=0}, {3, 2, 0})) + eq(true, vim.version.lt({ 0, 7, 4 }, { 3 })) + eq(false, vim.version.lt({ 3 }, { 0, 7, 4 })) + eq(false, vim.version.lt({ major = 3, minor = 3, patch = 0 }, { 3, 2, 0 })) + eq(false, vim.version.lt('2', '1')) + end) + + it('ge()', function() + eq(true, vim.version.ge('1', '1')) + eq(true, vim.version.ge({ 3, 1, 4 }, '3.1.4')) + eq(true, vim.version.ge('2', '1')) + eq(true, vim.version.ge({ 3 }, { 0, 7, 4 })) + eq(true, vim.version.ge({ major = 3, minor = 3, patch = 0 }, { 3, 2, 0 })) + eq(false, vim.version.ge('1', '2')) + eq(false, vim.version.ge({ 0, 7, 4 }, { 3 })) end) it('gt()', function() + eq(false, vim.version.gt('1', '1')) + eq(false, vim.version.gt({ 3, 1, 4 }, '3.1.4')) eq(true, vim.version.gt('2', '1')) - eq(true, vim.version.gt({3}, {0, 7, 4})) - eq(true, vim.version.gt({major=3, minor=3, patch=0}, {3, 2, 0})) + eq(true, vim.version.gt({ 3 }, { 0, 7, 4 })) + eq(true, vim.version.gt({ major = 3, minor = 3, patch = 0 }, { 3, 2, 0 })) + eq(false, vim.version.gt('1', '2')) + eq(false, vim.version.gt({ 0, 7, 4 }, { 3 })) end) it('eq()', function() eq(true, vim.version.eq('2', '2')) - eq(true, vim.version.eq({3, 1, 0}, '3.1.0')) - eq(true, vim.version.eq({major=3, minor=3, patch=0}, {3, 3, 0})) + eq(true, vim.version.eq({ 3, 1, 0 }, '3.1.0')) + eq(true, vim.version.eq({ major = 3, minor = 3, patch = 0 }, { 3, 3, 0 })) + eq(false, vim.version.eq('2', '3')) + + -- semver: v3 == v3.0 == v3.0.0 + eq(true, vim.version.eq('3', { 3, 0, 0 })) + eq(true, vim.version.eq({ 3, 0 }, { 3 })) + eq(true, vim.version.eq({ 3, 0, 0 }, { 3 })) end) end) diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index ebe5fc254e..a262d239e8 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -3,22 +3,22 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local nvim_prog = helpers.nvim_prog -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api 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 pesc = vim.pesc local eval = helpers.eval local feed = helpers.feed local pcall_err = helpers.pcall_err local exec_lua = helpers.exec_lua local matches = helpers.matches local exec = helpers.exec -local NIL = helpers.NIL +local NIL = vim.NIL local retry = helpers.retry local next_msg = helpers.next_msg local remove_trace = helpers.remove_trace @@ -39,204 +39,479 @@ describe('lua stdlib', function() -- Note: Built-in Nvim comparison (on systems lacking `strcasecmp`) works -- only on ASCII characters. it('vim.stricmp', function() - eq(0, funcs.luaeval('vim.stricmp("a", "A")')) - eq(0, funcs.luaeval('vim.stricmp("A", "a")')) - eq(0, funcs.luaeval('vim.stricmp("a", "a")')) - eq(0, funcs.luaeval('vim.stricmp("A", "A")')) - - eq(0, funcs.luaeval('vim.stricmp("", "")')) - eq(0, funcs.luaeval('vim.stricmp("\\0", "\\0")')) - eq(0, funcs.luaeval('vim.stricmp("\\0\\0", "\\0\\0")')) - eq(0, funcs.luaeval('vim.stricmp("\\0\\0\\0", "\\0\\0\\0")')) - eq(0, funcs.luaeval('vim.stricmp("\\0\\0\\0A", "\\0\\0\\0a")')) - eq(0, funcs.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0A")')) - eq(0, funcs.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0a")')) - - eq(0, funcs.luaeval('vim.stricmp("a\\0", "A\\0")')) - eq(0, funcs.luaeval('vim.stricmp("A\\0", "a\\0")')) - eq(0, funcs.luaeval('vim.stricmp("a\\0", "a\\0")')) - eq(0, funcs.luaeval('vim.stricmp("A\\0", "A\\0")')) - - eq(0, funcs.luaeval('vim.stricmp("\\0a", "\\0A")')) - eq(0, funcs.luaeval('vim.stricmp("\\0A", "\\0a")')) - eq(0, funcs.luaeval('vim.stricmp("\\0a", "\\0a")')) - eq(0, funcs.luaeval('vim.stricmp("\\0A", "\\0A")')) - - eq(0, funcs.luaeval('vim.stricmp("\\0a\\0", "\\0A\\0")')) - eq(0, funcs.luaeval('vim.stricmp("\\0A\\0", "\\0a\\0")')) - eq(0, funcs.luaeval('vim.stricmp("\\0a\\0", "\\0a\\0")')) - eq(0, funcs.luaeval('vim.stricmp("\\0A\\0", "\\0A\\0")')) - - eq(-1, funcs.luaeval('vim.stricmp("a", "B")')) - eq(-1, funcs.luaeval('vim.stricmp("A", "b")')) - eq(-1, funcs.luaeval('vim.stricmp("a", "b")')) - eq(-1, funcs.luaeval('vim.stricmp("A", "B")')) - - eq(-1, funcs.luaeval('vim.stricmp("", "\\0")')) - eq(-1, funcs.luaeval('vim.stricmp("\\0", "\\0\\0")')) - eq(-1, funcs.luaeval('vim.stricmp("\\0\\0", "\\0\\0\\0")')) - eq(-1, funcs.luaeval('vim.stricmp("\\0\\0\\0A", "\\0\\0\\0b")')) - eq(-1, funcs.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0B")')) - eq(-1, funcs.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0b")')) - - eq(-1, funcs.luaeval('vim.stricmp("a\\0", "B\\0")')) - eq(-1, funcs.luaeval('vim.stricmp("A\\0", "b\\0")')) - eq(-1, funcs.luaeval('vim.stricmp("a\\0", "b\\0")')) - eq(-1, funcs.luaeval('vim.stricmp("A\\0", "B\\0")')) - - eq(-1, funcs.luaeval('vim.stricmp("\\0a", "\\0B")')) - eq(-1, funcs.luaeval('vim.stricmp("\\0A", "\\0b")')) - eq(-1, funcs.luaeval('vim.stricmp("\\0a", "\\0b")')) - eq(-1, funcs.luaeval('vim.stricmp("\\0A", "\\0B")')) - - eq(-1, funcs.luaeval('vim.stricmp("\\0a\\0", "\\0B\\0")')) - eq(-1, funcs.luaeval('vim.stricmp("\\0A\\0", "\\0b\\0")')) - eq(-1, funcs.luaeval('vim.stricmp("\\0a\\0", "\\0b\\0")')) - eq(-1, funcs.luaeval('vim.stricmp("\\0A\\0", "\\0B\\0")')) - - eq(1, funcs.luaeval('vim.stricmp("c", "B")')) - eq(1, funcs.luaeval('vim.stricmp("C", "b")')) - eq(1, funcs.luaeval('vim.stricmp("c", "b")')) - eq(1, funcs.luaeval('vim.stricmp("C", "B")')) - - eq(1, funcs.luaeval('vim.stricmp("\\0", "")')) - eq(1, funcs.luaeval('vim.stricmp("\\0\\0", "\\0")')) - eq(1, funcs.luaeval('vim.stricmp("\\0\\0\\0", "\\0\\0")')) - eq(1, funcs.luaeval('vim.stricmp("\\0\\0\\0\\0", "\\0\\0\\0")')) - eq(1, funcs.luaeval('vim.stricmp("\\0\\0\\0C", "\\0\\0\\0b")')) - eq(1, funcs.luaeval('vim.stricmp("\\0\\0\\0c", "\\0\\0\\0B")')) - eq(1, funcs.luaeval('vim.stricmp("\\0\\0\\0c", "\\0\\0\\0b")')) - - eq(1, funcs.luaeval('vim.stricmp("c\\0", "B\\0")')) - eq(1, funcs.luaeval('vim.stricmp("C\\0", "b\\0")')) - eq(1, funcs.luaeval('vim.stricmp("c\\0", "b\\0")')) - eq(1, funcs.luaeval('vim.stricmp("C\\0", "B\\0")')) - - eq(1, funcs.luaeval('vim.stricmp("c\\0", "B")')) - eq(1, funcs.luaeval('vim.stricmp("C\\0", "b")')) - eq(1, funcs.luaeval('vim.stricmp("c\\0", "b")')) - eq(1, funcs.luaeval('vim.stricmp("C\\0", "B")')) - - eq(1, funcs.luaeval('vim.stricmp("\\0c", "\\0B")')) - eq(1, funcs.luaeval('vim.stricmp("\\0C", "\\0b")')) - eq(1, funcs.luaeval('vim.stricmp("\\0c", "\\0b")')) - eq(1, funcs.luaeval('vim.stricmp("\\0C", "\\0B")')) - - eq(1, funcs.luaeval('vim.stricmp("\\0c\\0", "\\0B\\0")')) - eq(1, funcs.luaeval('vim.stricmp("\\0C\\0", "\\0b\\0")')) - eq(1, funcs.luaeval('vim.stricmp("\\0c\\0", "\\0b\\0")')) - 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)) + eq(0, fn.luaeval('vim.stricmp("a", "A")')) + eq(0, fn.luaeval('vim.stricmp("A", "a")')) + eq(0, fn.luaeval('vim.stricmp("a", "a")')) + eq(0, fn.luaeval('vim.stricmp("A", "A")')) + + eq(0, fn.luaeval('vim.stricmp("", "")')) + eq(0, fn.luaeval('vim.stricmp("\\0", "\\0")')) + eq(0, fn.luaeval('vim.stricmp("\\0\\0", "\\0\\0")')) + eq(0, fn.luaeval('vim.stricmp("\\0\\0\\0", "\\0\\0\\0")')) + eq(0, fn.luaeval('vim.stricmp("\\0\\0\\0A", "\\0\\0\\0a")')) + eq(0, fn.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0A")')) + eq(0, fn.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0a")')) + + eq(0, fn.luaeval('vim.stricmp("a\\0", "A\\0")')) + eq(0, fn.luaeval('vim.stricmp("A\\0", "a\\0")')) + eq(0, fn.luaeval('vim.stricmp("a\\0", "a\\0")')) + eq(0, fn.luaeval('vim.stricmp("A\\0", "A\\0")')) + + eq(0, fn.luaeval('vim.stricmp("\\0a", "\\0A")')) + eq(0, fn.luaeval('vim.stricmp("\\0A", "\\0a")')) + eq(0, fn.luaeval('vim.stricmp("\\0a", "\\0a")')) + eq(0, fn.luaeval('vim.stricmp("\\0A", "\\0A")')) + + eq(0, fn.luaeval('vim.stricmp("\\0a\\0", "\\0A\\0")')) + eq(0, fn.luaeval('vim.stricmp("\\0A\\0", "\\0a\\0")')) + eq(0, fn.luaeval('vim.stricmp("\\0a\\0", "\\0a\\0")')) + eq(0, fn.luaeval('vim.stricmp("\\0A\\0", "\\0A\\0")')) + + eq(-1, fn.luaeval('vim.stricmp("a", "B")')) + eq(-1, fn.luaeval('vim.stricmp("A", "b")')) + eq(-1, fn.luaeval('vim.stricmp("a", "b")')) + eq(-1, fn.luaeval('vim.stricmp("A", "B")')) + + eq(-1, fn.luaeval('vim.stricmp("", "\\0")')) + eq(-1, fn.luaeval('vim.stricmp("\\0", "\\0\\0")')) + eq(-1, fn.luaeval('vim.stricmp("\\0\\0", "\\0\\0\\0")')) + eq(-1, fn.luaeval('vim.stricmp("\\0\\0\\0A", "\\0\\0\\0b")')) + eq(-1, fn.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0B")')) + eq(-1, fn.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0b")')) + + eq(-1, fn.luaeval('vim.stricmp("a\\0", "B\\0")')) + eq(-1, fn.luaeval('vim.stricmp("A\\0", "b\\0")')) + eq(-1, fn.luaeval('vim.stricmp("a\\0", "b\\0")')) + eq(-1, fn.luaeval('vim.stricmp("A\\0", "B\\0")')) + + eq(-1, fn.luaeval('vim.stricmp("\\0a", "\\0B")')) + eq(-1, fn.luaeval('vim.stricmp("\\0A", "\\0b")')) + eq(-1, fn.luaeval('vim.stricmp("\\0a", "\\0b")')) + eq(-1, fn.luaeval('vim.stricmp("\\0A", "\\0B")')) + + eq(-1, fn.luaeval('vim.stricmp("\\0a\\0", "\\0B\\0")')) + eq(-1, fn.luaeval('vim.stricmp("\\0A\\0", "\\0b\\0")')) + eq(-1, fn.luaeval('vim.stricmp("\\0a\\0", "\\0b\\0")')) + eq(-1, fn.luaeval('vim.stricmp("\\0A\\0", "\\0B\\0")')) + + eq(1, fn.luaeval('vim.stricmp("c", "B")')) + eq(1, fn.luaeval('vim.stricmp("C", "b")')) + eq(1, fn.luaeval('vim.stricmp("c", "b")')) + eq(1, fn.luaeval('vim.stricmp("C", "B")')) + + eq(1, fn.luaeval('vim.stricmp("\\0", "")')) + eq(1, fn.luaeval('vim.stricmp("\\0\\0", "\\0")')) + eq(1, fn.luaeval('vim.stricmp("\\0\\0\\0", "\\0\\0")')) + eq(1, fn.luaeval('vim.stricmp("\\0\\0\\0\\0", "\\0\\0\\0")')) + eq(1, fn.luaeval('vim.stricmp("\\0\\0\\0C", "\\0\\0\\0b")')) + eq(1, fn.luaeval('vim.stricmp("\\0\\0\\0c", "\\0\\0\\0B")')) + eq(1, fn.luaeval('vim.stricmp("\\0\\0\\0c", "\\0\\0\\0b")')) + + eq(1, fn.luaeval('vim.stricmp("c\\0", "B\\0")')) + eq(1, fn.luaeval('vim.stricmp("C\\0", "b\\0")')) + eq(1, fn.luaeval('vim.stricmp("c\\0", "b\\0")')) + eq(1, fn.luaeval('vim.stricmp("C\\0", "B\\0")')) + + eq(1, fn.luaeval('vim.stricmp("c\\0", "B")')) + eq(1, fn.luaeval('vim.stricmp("C\\0", "b")')) + eq(1, fn.luaeval('vim.stricmp("c\\0", "b")')) + eq(1, fn.luaeval('vim.stricmp("C\\0", "B")')) + + eq(1, fn.luaeval('vim.stricmp("\\0c", "\\0B")')) + eq(1, fn.luaeval('vim.stricmp("\\0C", "\\0b")')) + eq(1, fn.luaeval('vim.stricmp("\\0c", "\\0b")')) + eq(1, fn.luaeval('vim.stricmp("\\0C", "\\0B")')) + + eq(1, fn.luaeval('vim.stricmp("\\0c\\0", "\\0B\\0")')) + eq(1, fn.luaeval('vim.stricmp("\\0C\\0", "\\0b\\0")')) + eq(1, fn.luaeval('vim.stricmp("\\0c\\0", "\\0b\\0")')) + eq(1, fn.luaeval('vim.stricmp("\\0C\\0", "\\0B\\0")')) end) - it('vim.startswith', function() - eq(true, funcs.luaeval('vim.startswith("123", "1")')) - eq(true, funcs.luaeval('vim.startswith("123", "")')) - eq(true, funcs.luaeval('vim.startswith("123", "123")')) - eq(true, funcs.luaeval('vim.startswith("", "")')) + local function test_vim_deprecate(current_version) + -- vim.deprecate(name, alternative, version, plugin, backtrace) + -- See MAINTAIN.md for the soft/hard deprecation policy - eq(false, funcs.luaeval('vim.startswith("123", " ")')) - eq(false, funcs.luaeval('vim.startswith("123", "2")')) - eq(false, funcs.luaeval('vim.startswith("123", "1234")')) + describe(('vim.deprecate [current_version = %s]'):format(current_version), function() + before_each(function() + -- mock vim.version() behavior, should be pinned for consistent testing + exec_lua( + [[ + local current_version_mock = vim.version.parse(...) + getmetatable(vim.version).__call = function() + return current_version_mock + end + ]], + current_version + ) + end) - matches("prefix: expected string, got nil", - pcall_err(exec_lua, 'return vim.startswith("123", nil)')) - matches("s: expected string, got nil", - pcall_err(exec_lua, 'return vim.startswith(nil, "123")')) - end) + it('when plugin = nil', function() + eq( + dedent [[ + foo.bar() is deprecated, use zub.wooo{ok=yay} instead. :help deprecated + This feature will be removed in Nvim version 0.10]], + exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', '0.10') + ) + -- Same message, skipped. + eq(vim.NIL, exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', '0.10')) + + -- Don't show error if not hard-deprecated (only soft-deprecated) + eq( + vim.NIL, + exec_lua('return vim.deprecate(...)', 'foo.baz()', 'foo.better_baz()', '0.12.0') + ) + + -- Show error if hard-deprecated + eq( + dedent [[ + foo.hard_dep() is deprecated, use vim.new_api() instead. :help deprecated + This feature will be removed in Nvim version 0.11]], + exec_lua('return vim.deprecate(...)', 'foo.hard_dep()', 'vim.new_api()', '0.11') + ) + + -- To be deleted in the next major version (1.0) + eq( + dedent [[ + foo.baz() is deprecated. :help deprecated + This feature will be removed in Nvim version 1.0]], + exec_lua [[ return vim.deprecate('foo.baz()', nil, '1.0') ]] + ) + end) - it('vim.endswith', function() - eq(true, funcs.luaeval('vim.endswith("123", "3")')) - eq(true, funcs.luaeval('vim.endswith("123", "")')) - eq(true, funcs.luaeval('vim.endswith("123", "123")')) - eq(true, funcs.luaeval('vim.endswith("", "")')) + it('when plugin is specified', function() + -- 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 + ) + ) + + -- plugins: no soft deprecation period + eq( + dedent [[ + foo.bar() is deprecated, use zub.wooo{ok=yay} instead. + This feature will be removed in my-plugin.nvim version 0.11.0]], + exec_lua( + 'return vim.deprecate(...)', + 'foo.bar()', + 'zub.wooo{ok=yay}', + '0.11.0', + 'my-plugin.nvim', + false + ) + ) + end) + end) + end - eq(false, funcs.luaeval('vim.endswith("123", " ")')) - eq(false, funcs.luaeval('vim.endswith("123", "2")')) - eq(false, funcs.luaeval('vim.endswith("123", "1234")')) + test_vim_deprecate('0.10') + test_vim_deprecate('0.10-dev+g0000000') - matches("suffix: expected string, got nil", - pcall_err(exec_lua, 'return vim.endswith("123", nil)')) - matches("s: expected string, got nil", - pcall_err(exec_lua, 'return vim.endswith(nil, "123")')) + it('vim.startswith', function() + eq(true, fn.luaeval('vim.startswith("123", "1")')) + eq(true, fn.luaeval('vim.startswith("123", "")')) + eq(true, fn.luaeval('vim.startswith("123", "123")')) + eq(true, fn.luaeval('vim.startswith("", "")')) + + eq(false, fn.luaeval('vim.startswith("123", " ")')) + eq(false, fn.luaeval('vim.startswith("123", "2")')) + eq(false, fn.luaeval('vim.startswith("123", "1234")')) + + matches( + 'prefix: expected string, got nil', + pcall_err(exec_lua, 'return vim.startswith("123", nil)') + ) + matches('s: expected string, got nil', pcall_err(exec_lua, 'return vim.startswith(nil, "123")')) + end) + + it('vim.endswith', function() + eq(true, fn.luaeval('vim.endswith("123", "3")')) + eq(true, fn.luaeval('vim.endswith("123", "")')) + eq(true, fn.luaeval('vim.endswith("123", "123")')) + eq(true, fn.luaeval('vim.endswith("", "")')) + + eq(false, fn.luaeval('vim.endswith("123", " ")')) + eq(false, fn.luaeval('vim.endswith("123", "2")')) + eq(false, fn.luaeval('vim.endswith("123", "1234")')) + + matches( + 'suffix: expected string, got nil', + pcall_err(exec_lua, 'return vim.endswith("123", nil)') + ) + matches('s: expected string, got nil', pcall_err(exec_lua, 'return vim.endswith(nil, "123")')) end) - it("vim.str_utfindex/str_byteindex", function() + it('vim.str_utfindex/str_byteindex', function() exec_lua([[_G.test_text = "xy åäö ɧ 汉语 ↥ 🤦x🦄 å بِيَّ\000ъ"]]) - local indices32 = {[0]=0,1,2,3,5,7,9,10,12,13,16,19,20,23,24,28,29,33,34,35,37,38,40,42,44,46,48,49,51} - local indices16 = {[0]=0,1,2,3,5,7,9,10,12,13,16,19,20,23,24,28,28,29,33,33,34,35,37,38,40,42,44,46,48,49,51} - for i,k in pairs(indices32) do - eq(k, exec_lua("return vim.str_byteindex(_G.test_text, ...)", i), i) + local indices32 = { + [0] = 0, + 1, + 2, + 3, + 5, + 7, + 9, + 10, + 12, + 13, + 16, + 19, + 20, + 23, + 24, + 28, + 29, + 33, + 34, + 35, + 37, + 38, + 40, + 42, + 44, + 46, + 48, + 49, + 51, + } + local indices16 = { + [0] = 0, + 1, + 2, + 3, + 5, + 7, + 9, + 10, + 12, + 13, + 16, + 19, + 20, + 23, + 24, + 28, + 28, + 29, + 33, + 33, + 34, + 35, + 37, + 38, + 40, + 42, + 44, + 46, + 48, + 49, + 51, + } + for i, k in pairs(indices32) do + eq(k, exec_lua('return vim.str_byteindex(_G.test_text, ...)', i), i) end - for i,k in pairs(indices16) do - eq(k, exec_lua("return vim.str_byteindex(_G.test_text, ..., true)", i), i) + for i, k in pairs(indices16) do + eq(k, exec_lua('return vim.str_byteindex(_G.test_text, ..., true)', i), i) end - eq("index out of range", pcall_err(exec_lua, "return vim.str_byteindex(_G.test_text, ...)", #indices32 + 1)) - eq("index out of range", pcall_err(exec_lua, "return vim.str_byteindex(_G.test_text, ..., true)", #indices16 + 1)) + eq( + 'index out of range', + pcall_err(exec_lua, 'return vim.str_byteindex(_G.test_text, ...)', #indices32 + 1) + ) + eq( + 'index out of range', + pcall_err(exec_lua, 'return vim.str_byteindex(_G.test_text, ..., true)', #indices16 + 1) + ) local i32, i16 = 0, 0 local len = 51 - for k = 0,len do + for k = 0, len do if indices32[i32] < k then i32 = i32 + 1 end if indices16[i16] < k then i16 = i16 + 1 - if indices16[i16+1] == indices16[i16] then + if indices16[i16 + 1] == indices16[i16] then i16 = i16 + 1 end end - eq({i32, i16}, exec_lua("return {vim.str_utfindex(_G.test_text, ...)}", k), k) + eq({ i32, i16 }, exec_lua('return {vim.str_utfindex(_G.test_text, ...)}', k), k) end - eq("index out of range", pcall_err(exec_lua, "return vim.str_utfindex(_G.test_text, ...)", len + 1)) + eq( + 'index out of range', + pcall_err(exec_lua, 'return vim.str_utfindex(_G.test_text, ...)', len + 1) + ) end) - it("vim.str_utf_start", function() + it('vim.str_utf_start', function() exec_lua([[_G.test_text = "xy åäö ɧ 汉语 ↥ 🤦x🦄 å بِيَّ"]]) - local expected_positions = {0,0,0,0,-1,0,-1,0,-1,0,0,-1,0,0,-1,-2,0,-1,-2,0,0,-1,-2,0,0,-1,-2,-3,0,0,-1,-2,-3,0,0,0,-1,0,0,-1,0,-1,0,-1,0,-1,0,-1} - eq(expected_positions, exec_lua([[ + local expected_positions = { + 0, + 0, + 0, + 0, + -1, + 0, + -1, + 0, + -1, + 0, + 0, + -1, + 0, + 0, + -1, + -2, + 0, + -1, + -2, + 0, + 0, + -1, + -2, + 0, + 0, + -1, + -2, + -3, + 0, + 0, + -1, + -2, + -3, + 0, + 0, + 0, + -1, + 0, + 0, + -1, + 0, + -1, + 0, + -1, + 0, + -1, + 0, + -1, + } + eq( + expected_positions, + exec_lua([[ local start_codepoint_positions = {} for idx = 1, #_G.test_text do table.insert(start_codepoint_positions, vim.str_utf_start(_G.test_text, idx)) end return start_codepoint_positions - ]])) + ]]) + ) end) - it("vim.str_utf_end", function() + it('vim.str_utf_end', function() exec_lua([[_G.test_text = "xy åäö ɧ 汉语 ↥ 🤦x🦄 å بِيَّ"]]) - local expected_positions = {0,0,0,1,0,1,0,1,0,0,1,0,0,2,1,0,2,1,0,0,2,1,0,0,3,2,1,0,0,3,2,1,0,0,0,1,0,0,1,0,1,0,1,0,1,0,1,0 } - eq(expected_positions, exec_lua([[ + local expected_positions = { + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 2, + 1, + 0, + 2, + 1, + 0, + 0, + 2, + 1, + 0, + 0, + 3, + 2, + 1, + 0, + 0, + 3, + 2, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + } + eq( + expected_positions, + exec_lua([[ local end_codepoint_positions = {} for idx = 1, #_G.test_text do table.insert(end_codepoint_positions, vim.str_utf_end(_G.test_text, idx)) end return end_codepoint_positions - ]])) + ]]) + ) end) - - it("vim.str_utf_pos", function() + it('vim.str_utf_pos', function() exec_lua([[_G.test_text = "xy åäö ɧ 汉语 ↥ 🤦x🦄 å بِيَّ"]]) - local expected_positions = { 1,2,3,4,6,8,10,11,13,14,17,20,21,24,25,29,30,34,35,36,38,39,41,43,45,47 } - eq(expected_positions, exec_lua("return vim.str_utf_pos(_G.test_text)")) + local expected_positions = { + 1, + 2, + 3, + 4, + 6, + 8, + 10, + 11, + 13, + 14, + 17, + 20, + 21, + 24, + 25, + 29, + 30, + 34, + 35, + 36, + 38, + 39, + 41, + 43, + 45, + 47, + } + eq(expected_positions, exec_lua('return vim.str_utf_pos(_G.test_text)')) end) - it("vim.schedule", function() + it('vim.schedule', function() exec_lua([[ test_table = {} vim.schedule(function() @@ -244,13 +519,11 @@ describe('lua stdlib', function() end) table.insert(test_table, "yy") ]]) - eq({"yy","xx"}, exec_lua("return test_table")) + eq({ 'yy', 'xx' }, exec_lua('return test_table')) -- Validates args. - matches('vim.schedule: expected function', - pcall_err(exec_lua, "vim.schedule('stringly')")) - matches('vim.schedule: expected function', - pcall_err(exec_lua, "vim.schedule()")) + matches('vim.schedule: expected function', pcall_err(exec_lua, "vim.schedule('stringly')")) + matches('vim.schedule: expected function', pcall_err(exec_lua, 'vim.schedule()')) exec_lua([[ vim.schedule(function() @@ -258,24 +531,24 @@ describe('lua stdlib', function() end) ]]) - feed("<cr>") - matches('big failure\nvery async', remove_trace(eval("v:errmsg"))) + feed('<cr>') + matches('big failure\nvery async', remove_trace(eval('v:errmsg'))) - local screen = Screen.new(60,5) + local screen = Screen.new(60, 5) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {bold = true, reverse = true}, - [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [4] = {bold = true, foreground = Screen.colors.SeaGreen4}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { bold = true, reverse = true }, + [3] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen4 }, }) screen:attach() - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]]} + ]], + } -- nvim_command causes a Vimscript exception, check that it is properly caught -- and propagated as an error message in async contexts.. #10809 @@ -284,62 +557,61 @@ describe('lua stdlib', function() vim.api.nvim_command(":echo 'err") end) ]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:stack traceback:} | {3: [C]: in function 'nvim_command'} | {3: [string "<nvim>"]:2: in function <[string "<nvim>"]:}| {3:1>} | {4:Press ENTER or type command to continue}^ | - ]]} + ]], + } end) it('vim.gsplit, vim.split', function() local tests = { -- 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' } }, + { '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], vim.split(t[1], t[2], {plain=t[3], trimempty=t[4]}), t[1]) + 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'}, vim.split("x*yz*oo*l", "*", true)) + eq({ 'x', 'yz', 'oo', 'l' }, vim.split('x*yz*oo*l', '*', true)) local loops = { - { "abc", ".-" }, + { 'abc', '.-' }, } for _, t in ipairs(loops) do - matches("Infinite loop detected", pcall_err(vim.split, t[1], t[2])) + matches('Infinite loop detected', pcall_err(vim.split, t[1], t[2])) end -- Validates args. eq(true, pcall(vim.split, 'string', 'string')) - matches('s: expected string, got number', - pcall_err(vim.split, 1, 'string')) - matches('sep: expected string, got number', - pcall_err(vim.split, 'string', 1)) - matches('opts: expected table, got number', - pcall_err(vim.split, 'string', 'string', 1)) + matches('s: expected string, got number', pcall_err(vim.split, 1, 'string')) + matches('sep: expected string, got number', pcall_err(vim.split, 'string', 1)) + matches('opts: expected table, got number', pcall_err(vim.split, 'string', 'string', 1)) end) it('vim.trim', function() @@ -348,10 +620,10 @@ describe('lua stdlib', function() end local trims = { - { " a", "a" }, - { " b ", "b" }, - { "\tc" , "c" }, - { "r\n", "r" }, + { ' a', 'a' }, + { ' b ', 'b' }, + { '\tc', 'c' }, + { 'r\n', 'r' }, } for _, t in ipairs(trims) do @@ -359,8 +631,7 @@ describe('lua stdlib', function() end -- Validates args. - matches('s: expected string, got number', - pcall_err(trim, 2)) + matches('s: expected string, got number', pcall_err(trim, 2)) end) it('vim.inspect', function() @@ -370,21 +641,23 @@ describe('lua stdlib', function() end eq('2', inspect(2)) - eq('{+a = {+b = 1+}+}', - inspect({ a = { b = 1 } }, { newline = '+', indent = '' })) + eq('{+a = {+b = 1+}+}', inspect({ a = { b = 1 } }, { newline = '+', indent = '' })) -- special value vim.inspect.KEY works - eq('{ KEY_a = "x", KEY_b = "y"}', exec_lua([[ + eq( + '{ KEY_a = "x", KEY_b = "y"}', + exec_lua([[ return vim.inspect({a="x", b="y"}, {newline = '', process = function(item, path) if path[#path] == vim.inspect.KEY then return 'KEY_'..item end return item end}) - ]])) + ]]) + ) end) - it("vim.deepcopy", function() + it('vim.deepcopy', function() ok(exec_lua([[ local a = { x = { 1, 2 }, y = 5} local b = vim.deepcopy(a) @@ -445,23 +718,27 @@ describe('lua stdlib', function() return t2.a == vim.NIL ]])) - matches('Cannot deepcopy object of type thread', - pcall_err(exec_lua, [[ + matches( + 'Cannot deepcopy object of type thread', + pcall_err( + exec_lua, + [[ local thread = coroutine.create(function () return 0 end) local t = {thr = thread} vim.deepcopy(t) - ]])) + ]] + ) + ) end) it('vim.pesc', function() eq('foo%-bar', exec_lua([[return vim.pesc('foo-bar')]])) eq('foo%%%-bar', exec_lua([[return vim.pesc(vim.pesc('foo-bar'))]])) -- pesc() returns one result. #20751 - eq({'x'}, exec_lua([[return {vim.pesc('x')}]])) + eq({ 'x' }, exec_lua([[return {vim.pesc('x')}]])) -- Validates args. - matches('s: expected string, got number', - pcall_err(exec_lua, [[return vim.pesc(2)]])) + matches('s: expected string, got number', pcall_err(exec_lua, [[return vim.pesc(2)]])) end) it('vim.list_contains', function() @@ -473,97 +750,131 @@ describe('lua stdlib', 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([[ + 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({})")) + eq({}, exec_lua('return vim.tbl_keys({})')) for _, v in pairs(exec_lua("return vim.tbl_keys({'a', 'b', 'c'})")) do - eq(true, exec_lua("return vim.tbl_contains({ 1, 2, 3 }, ...)", v)) + eq(true, exec_lua('return vim.tbl_contains({ 1, 2, 3 }, ...)', v)) end - for _, v in pairs(exec_lua("return vim.tbl_keys({a=1, b=2, c=3})")) do + for _, v in pairs(exec_lua('return vim.tbl_keys({a=1, b=2, c=3})')) do eq(true, exec_lua("return vim.tbl_contains({ 'a', 'b', 'c' }, ...)", v)) end end) it('vim.tbl_values', function() - eq({}, exec_lua("return vim.tbl_values({})")) + eq({}, exec_lua('return vim.tbl_values({})')) for _, v in pairs(exec_lua("return vim.tbl_values({'a', 'b', 'c'})")) do eq(true, exec_lua("return vim.tbl_contains({ 'a', 'b', 'c' }, ...)", v)) end - for _, v in pairs(exec_lua("return vim.tbl_values({a=1, b=2, c=3})")) do - eq(true, exec_lua("return vim.tbl_contains({ 1, 2, 3 }, ...)", v)) + for _, v in pairs(exec_lua('return vim.tbl_values({a=1, b=2, c=3})')) do + eq(true, exec_lua('return vim.tbl_contains({ 1, 2, 3 }, ...)', v)) end end) it('vim.tbl_map', function() - eq({}, exec_lua([[ + eq( + {}, + exec_lua([[ return vim.tbl_map(function(v) return v * 2 end, {}) - ]])) - eq({2, 4, 6}, exec_lua([[ + ]]) + ) + eq( + { 2, 4, 6 }, + exec_lua([[ return vim.tbl_map(function(v) return v * 2 end, {1, 2, 3}) - ]])) - eq({{i=2}, {i=4}, {i=6}}, exec_lua([[ + ]]) + ) + eq( + { { i = 2 }, { i = 4 }, { i = 6 } }, + exec_lua([[ return vim.tbl_map(function(v) return { i = v.i * 2 } end, {{i=1}, {i=2}, {i=3}}) - ]])) + ]]) + ) end) it('vim.tbl_filter', function() - eq({}, exec_lua([[ + eq( + {}, + exec_lua([[ return vim.tbl_filter(function(v) return (v % 2) == 0 end, {}) - ]])) - eq({2}, exec_lua([[ + ]]) + ) + eq( + { 2 }, + exec_lua([[ return vim.tbl_filter(function(v) return (v % 2) == 0 end, {1, 2, 3}) - ]])) - eq({{i=2}}, exec_lua([[ + ]]) + ) + eq( + { { i = 2 } }, + exec_lua([[ return vim.tbl_filter(function(v) return (v.i % 2) == 0 end, {{i=1}, {i=2}, {i=3}}) - ]])) + ]]) + ) 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({})')) + 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})")) + 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())")) + eq(true, exec_lua('return vim.tbl_islist({})')) + eq(false, exec_lua('return vim.tbl_islist(vim.empty_dict())')) eq(true, exec_lua("return vim.tbl_islist({'a', 'b', 'c'})")) eq(false, exec_lua("return vim.tbl_islist({'a', '32', a='hello', b='baz'})")) 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})")) + 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() - eq(true, exec_lua("return vim.tbl_isempty({})")) - eq(false, exec_lua("return vim.tbl_isempty({ 1, 2, 3 })")) - eq(false, exec_lua("return vim.tbl_isempty({a=1, b=2, c=3})")) + eq(true, exec_lua('return vim.tbl_isempty({})')) + eq(false, exec_lua('return vim.tbl_isempty({ 1, 2, 3 })')) + eq(false, exec_lua('return vim.tbl_isempty({a=1, b=2, c=3})')) end) it('vim.tbl_get', function() - eq(true, exec_lua("return vim.tbl_get({ test = { nested_test = true }}, 'test', 'nested_test')")) + eq( + true, + exec_lua("return vim.tbl_get({ test = { nested_test = true }}, 'test', 'nested_test')") + ) eq(NIL, exec_lua("return vim.tbl_get({ unindexable = true }, 'unindexable', 'missing_key')")) eq(NIL, exec_lua("return vim.tbl_get({ unindexable = 1 }, 'unindexable', 'missing_key')")) - eq(NIL, exec_lua("return vim.tbl_get({ unindexable = coroutine.create(function () end) }, 'unindexable', 'missing_key')")) - eq(NIL, exec_lua("return vim.tbl_get({ unindexable = function () end }, 'unindexable', 'missing_key')")) + eq( + NIL, + exec_lua( + "return vim.tbl_get({ unindexable = coroutine.create(function () end) }, 'unindexable', 'missing_key')" + ) + ) + eq( + NIL, + exec_lua( + "return vim.tbl_get({ unindexable = function () end }, 'unindexable', 'missing_key')" + ) + ) eq(NIL, exec_lua("return vim.tbl_get({}, 'missing_key')")) - eq(NIL, exec_lua("return vim.tbl_get({})")) + eq(NIL, exec_lua('return vim.tbl_get({})')) eq(1, exec_lua("return select('#', vim.tbl_get({}))")) eq(1, exec_lua("return select('#', vim.tbl_get({ nested = {} }, 'nested', 'missing_key'))")) end) @@ -629,22 +940,34 @@ describe('lua stdlib', function() return c.x.a == 1 and c.x.b == 2 and c.x.c == nil and count == 1 ]])) - matches('invalid "behavior": nil', - pcall_err(exec_lua, [[ + matches( + 'invalid "behavior": nil', + pcall_err( + exec_lua, + [[ return vim.tbl_extend() - ]]) + ]] + ) ) - matches('wrong number of arguments %(given 1, expected at least 3%)', - pcall_err(exec_lua, [[ + matches( + 'wrong number of arguments %(given 1, expected at least 3%)', + pcall_err( + exec_lua, + [[ return vim.tbl_extend("keep") - ]]) + ]] + ) ) - matches('wrong number of arguments %(given 2, expected at least 3%)', - pcall_err(exec_lua, [[ + matches( + 'wrong number of arguments %(given 2, expected at least 3%)', + pcall_err( + exec_lua, + [[ return vim.tbl_extend("keep", {}) - ]]) + ]] + ) ) end) @@ -717,17 +1040,23 @@ describe('lua stdlib', function() return vim.tbl_islist(c) and count == 0 ]])) - eq({a = {b = 1}}, exec_lua([[ + eq( + { a = { b = 1 } }, + exec_lua([[ local a = { a = { b = 1 } } local b = { a = {} } return vim.tbl_deep_extend("force", a, b) - ]])) + ]]) + ) - eq({a = {b = 1}}, exec_lua([[ + eq( + { a = { b = 1 } }, + exec_lua([[ local a = { a = 123 } local b = { a = { b = 1} } return vim.tbl_deep_extend("force", a, b) - ]])) + ]]) + ) ok(exec_lua([[ local a = { a = {[2] = 3} } @@ -736,28 +1065,43 @@ describe('lua stdlib', function() return vim.deep_equal(c, {a = {[3] = 3}}) ]])) - eq({a = 123}, exec_lua([[ + eq( + { a = 123 }, + exec_lua([[ local a = { a = { b = 1} } local b = { a = 123 } return vim.tbl_deep_extend("force", a, b) - ]])) + ]]) + ) - matches('invalid "behavior": nil', - pcall_err(exec_lua, [[ + matches( + 'invalid "behavior": nil', + pcall_err( + exec_lua, + [[ return vim.tbl_deep_extend() - ]]) + ]] + ) ) - matches('wrong number of arguments %(given 1, expected at least 3%)', - pcall_err(exec_lua, [[ + matches( + 'wrong number of arguments %(given 1, expected at least 3%)', + pcall_err( + exec_lua, + [[ return vim.tbl_deep_extend("keep") - ]]) + ]] + ) ) - matches('wrong number of arguments %(given 2, expected at least 3%)', - pcall_err(exec_lua, [[ + matches( + 'wrong number of arguments %(given 2, expected at least 3%)', + pcall_err( + exec_lua, + [[ return vim.tbl_deep_extend("keep", {}) - ]]) + ]] + ) ) end) @@ -786,23 +1130,28 @@ describe('lua stdlib', function() end) it('vim.list_extend', function() - eq({1,2,3}, exec_lua [[ return vim.list_extend({1}, {2,3}) ]]) - matches('src: expected table, got nil', - pcall_err(exec_lua, [[ return vim.list_extend({1}, nil) ]])) - eq({1,2}, exec_lua [[ return vim.list_extend({1}, {2;a=1}) ]]) + eq({ 1, 2, 3 }, exec_lua [[ return vim.list_extend({1}, {2,3}) ]]) + matches( + 'src: expected table, got nil', + pcall_err(exec_lua, [[ return vim.list_extend({1}, nil) ]]) + ) + eq({ 1, 2 }, exec_lua [[ return vim.list_extend({1}, {2;a=1}) ]]) eq(true, exec_lua [[ local a = {1} return vim.list_extend(a, {2;a=1}) == a ]]) - eq({2}, exec_lua [[ return vim.list_extend({}, {2;a=1}, 1) ]]) + eq({ 2 }, exec_lua [[ return vim.list_extend({}, {2;a=1}, 1) ]]) eq({}, exec_lua [[ return vim.list_extend({}, {2;a=1}, 2) ]]) eq({}, exec_lua [[ return vim.list_extend({}, {2;a=1}, 1, -1) ]]) - eq({2}, exec_lua [[ return vim.list_extend({}, {2;a=1}, -1, 2) ]]) + eq({ 2 }, exec_lua [[ return vim.list_extend({}, {2;a=1}, -1, 2) ]]) end) it('vim.tbl_add_reverse_lookup', function() - eq(true, exec_lua [[ + eq( + true, + exec_lua [[ local a = { A = 1 } vim.tbl_add_reverse_lookup(a) return vim.deep_equal(a, { A = 1; [1] = 'A'; }) - ]]) + ]] + ) -- Throw an error for trying to do it twice (run into an existing key) local code = [[ local res = {} @@ -811,17 +1160,19 @@ describe('lua stdlib', function() assert(vim.deep_equal(a, { A = 1; [1] = 'A'; })) vim.tbl_add_reverse_lookup(a) ]] - matches('The reverse lookup found an existing value for "[1A]" while processing key "[1A]"$', - pcall_err(exec_lua, code)) + matches( + 'The reverse lookup found an existing value for "[1A]" while processing key "[1A]"$', + pcall_err(exec_lua, code) + ) end) it('vim.spairs', function() local res = '' local table = { - ccc=1, - bbb=2, - ddd=3, - aaa=4 + ccc = 1, + bbb = 2, + ddd = 3, + aaa = 4, } for key, _ in vim.spairs(table) do res = res .. key @@ -848,37 +1199,51 @@ describe('lua stdlib', function() endfunc ]]) eq(true, exec_lua([[return next(vim.fn.FooFunc(3)) == nil ]])) - eq(3, eval("g:test")) + eq(3, eval('g:test')) -- compat: nvim_call_function uses "special" value for empty dict eq(true, exec_lua([[return next(vim.api.nvim_call_function("FooFunc", {5})) == true ]])) - eq(5, eval("g:test")) + eq(5, eval('g:test')) - eq({2, "foo", true}, exec_lua([[return vim.fn.VarArg(2, "foo", true)]])) + eq({ 2, 'foo', true }, exec_lua([[return vim.fn.VarArg(2, "foo", true)]])) - eq(true, exec_lua([[ + eq( + true, + exec_lua([[ local x = vim.fn.Nilly() return #x == 2 and x[1] == vim.NIL and x[2] == vim.NIL - ]])) - eq({NIL, NIL}, exec_lua([[return vim.fn.Nilly()]])) + ]]) + ) + eq({ NIL, NIL }, exec_lua([[return vim.fn.Nilly()]])) -- error handling - eq({false, 'Vim:E897: List or Blob required'}, exec_lua([[return {pcall(vim.fn.add, "aa", "bb")}]])) + eq( + { false, 'Vim:E897: List or Blob required' }, + exec_lua([[return {pcall(vim.fn.add, "aa", "bb")}]]) + ) -- conversion between LuaRef and Vim Funcref - eq(true, exec_lua([[ + eq( + true, + exec_lua([[ local x = vim.fn.VarArg(function() return 'foo' end, function() return 'bar' end) return #x == 2 and x[1]() == 'foo' and x[2]() == 'bar' - ]])) + ]]) + ) -- Test for #20211 - eq('a (b) c', exec_lua([[ + eq( + 'a (b) c', + exec_lua([[ return vim.fn.substitute('a b c', 'b', function(m) return '(' .. m[1] .. ')' end, 'g') - ]])) + ]]) + ) end) it('vim.fn should error when calling API function', function() - matches('Tried to call API function with vim.fn: use vim.api.nvim_get_current_line instead', - pcall_err(exec_lua, "vim.fn.nvim_get_current_line()")) + matches( + 'Tried to call API function with vim.fn: use vim.api.nvim_get_current_line instead', + pcall_err(exec_lua, 'vim.fn.nvim_get_current_line()') + ) end) it('vim.fn is allowed in "fast" context by some functions #18306', function() @@ -891,8 +1256,8 @@ describe('lua stdlib', function() end) ]]) - helpers.poke_eventloop() - eq('hello', exec_lua[[return vim.g.fnres]]) + poke_eventloop() + eq('hello', exec_lua [[return vim.g.fnres]]) end) it('vim.rpcrequest and vim.rpcnotify', function() @@ -900,52 +1265,60 @@ describe('lua stdlib', function() chan = vim.fn.jobstart({'cat'}, {rpc=true}) vim.rpcrequest(chan, 'nvim_set_current_line', 'meow') ]]) - eq('meow', meths.get_current_line()) + eq('meow', api.nvim_get_current_line()) command("let x = [3, 'aa', v:true, v:null]") - eq(true, exec_lua([[ + eq( + true, + exec_lua([[ ret = vim.rpcrequest(chan, 'nvim_get_var', 'x') return #ret == 4 and ret[1] == 3 and ret[2] == 'aa' and ret[3] == true and ret[4] == vim.NIL - ]])) - eq({3, 'aa', true, NIL}, exec_lua([[return ret]])) + ]]) + ) + eq({ 3, 'aa', true, NIL }, exec_lua([[return ret]])) - eq({{}, {}, false, true}, exec_lua([[ + eq( + { {}, {}, false, true }, + exec_lua([[ vim.rpcrequest(chan, 'nvim_exec', 'let xx = {}\nlet yy = []', false) local dict = vim.rpcrequest(chan, 'nvim_eval', 'xx') local list = vim.rpcrequest(chan, 'nvim_eval', 'yy') return {dict, list, vim.tbl_islist(dict), vim.tbl_islist(list)} - ]])) + ]]) + ) - exec_lua([[ + exec_lua([[ vim.rpcrequest(chan, 'nvim_set_var', 'aa', {}) vim.rpcrequest(chan, 'nvim_set_var', 'bb', vim.empty_dict()) ]]) - eq({1, 1}, eval('[type(g:aa) == type([]), type(g:bb) == type({})]')) + eq({ 1, 1 }, eval('[type(g:aa) == type([]), type(g:bb) == type({})]')) -- error handling - eq({false, 'Invalid channel: 23'}, - exec_lua([[return {pcall(vim.rpcrequest, 23, 'foo')}]])) - eq({false, 'Invalid channel: 23'}, - exec_lua([[return {pcall(vim.rpcnotify, 23, 'foo')}]])) - - eq({false, 'Vim:E121: Undefined variable: foobar'}, - exec_lua([[return {pcall(vim.rpcrequest, chan, 'nvim_eval', "foobar")}]])) + eq({ false, 'Invalid channel: 23' }, exec_lua([[return {pcall(vim.rpcrequest, 23, 'foo')}]])) + eq({ false, 'Invalid channel: 23' }, exec_lua([[return {pcall(vim.rpcnotify, 23, 'foo')}]])) + eq( + { false, 'Vim:E121: Undefined variable: foobar' }, + exec_lua([[return {pcall(vim.rpcrequest, chan, 'nvim_eval', "foobar")}]]) + ) -- rpcnotify doesn't wait on request - eq('meow', exec_lua([[ + eq( + 'meow', + exec_lua([[ vim.rpcnotify(chan, 'nvim_set_current_line', 'foo') return vim.api.nvim_get_current_line() - ]])) + ]]) + ) retry(10, nil, function() - eq('foo', meths.get_current_line()) + eq('foo', api.nvim_get_current_line()) end) - local screen = Screen.new(50,7) + local screen = Screen.new(50, 7) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {bold = true, reverse = true}, - [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [4] = {bold = true, foreground = Screen.colors.SeaGreen4}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { bold = true, reverse = true }, + [3] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen4 }, }) screen:attach() exec_lua([[ @@ -957,7 +1330,8 @@ describe('lua stdlib', function() vim.rpcrequest(chan, 'nvim_set_current_line', 'bork') end) ]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:[string "<nvim>"]:6: E5560: rpcrequest must not be}| {3: called in a lua loop callback} | {3:stack traceback:} | @@ -965,35 +1339,42 @@ describe('lua stdlib', function() {3: [string "<nvim>"]:6: in function <[string }| {3:"<nvim>"]:2>} | {4:Press ENTER or type command to continue}^ | - ]]} + ]], + } feed('<cr>') - eq({3, NIL}, meths.get_var('yy')) + eq({ 3, NIL }, api.nvim_get_var('yy')) exec_lua([[timer:close()]]) end) it('vim.empty_dict()', function() - eq({true, false, true, true}, exec_lua([[ + eq( + { true, false, true, true }, + exec_lua([[ vim.api.nvim_set_var('listy', {}) vim.api.nvim_set_var('dicty', vim.empty_dict()) local listy = vim.fn.eval("listy") local dicty = vim.fn.eval("dicty") return {vim.tbl_islist(listy), vim.tbl_islist(dicty), next(listy) == nil, next(dicty) == nil} - ]])) + ]]) + ) -- vim.empty_dict() gives new value each time -- equality is not overridden (still by ref) -- non-empty table uses the usual heuristics (ignores the tag) - eq({false, {"foo"}, {namey="bar"}}, exec_lua([[ + eq( + { false, { 'foo' }, { namey = 'bar' } }, + exec_lua([[ local aa = vim.empty_dict() local bb = vim.empty_dict() local equally = (aa == bb) aa[1] = "foo" bb["namey"] = "bar" return {equally, aa, bb} - ]])) + ]]) + ) - eq("{ {}, vim.empty_dict() }", exec_lua("return vim.inspect({{}, vim.empty_dict()})")) + eq('{ {}, vim.empty_dict() }', exec_lua('return vim.inspect({{}, vim.empty_dict()})')) eq('{}', exec_lua([[ return vim.fn.json_encode(vim.empty_dict()) ]])) eq('{"a": {}, "b": []}', exec_lua([[ return vim.fn.json_encode({a=vim.empty_dict(), b={}}) ]])) end) @@ -1028,56 +1409,72 @@ describe('lua stdlib', function() exec_lua("vim.validate{arg1={2, function(a) return (a % 2) == 0 end, 'even number' }}") exec_lua("vim.validate{arg1={5, {'n', 's'} }, arg2={ 'foo', {'n', 's'} }}") - matches('expected table, got number', - pcall_err(exec_lua, "vim.validate{ 1, 'x' }")) - matches('invalid type name: x', - pcall_err(exec_lua, "vim.validate{ arg1={ 1, 'x' }}")) - matches('invalid type name: 1', - pcall_err(exec_lua, "vim.validate{ arg1={ 1, 1 }}")) - matches('invalid type name: nil', - pcall_err(exec_lua, "vim.validate{ arg1={ 1 }}")) + matches('expected table, got number', pcall_err(exec_lua, "vim.validate{ 1, 'x' }")) + matches('invalid type name: x', pcall_err(exec_lua, "vim.validate{ arg1={ 1, 'x' }}")) + matches('invalid type name: 1', pcall_err(exec_lua, 'vim.validate{ arg1={ 1, 1 }}')) + matches('invalid type name: nil', pcall_err(exec_lua, 'vim.validate{ arg1={ 1 }}')) -- Validated parameters are required by default. - matches('arg1: expected string, got nil', - pcall_err(exec_lua, "vim.validate{ arg1={ nil, 's' }}")) + matches( + 'arg1: expected string, got nil', + pcall_err(exec_lua, "vim.validate{ arg1={ nil, 's' }}") + ) -- Explicitly required. - matches('arg1: expected string, got nil', - pcall_err(exec_lua, "vim.validate{ arg1={ nil, 's', false }}")) - - matches('arg1: expected table, got number', - pcall_err(exec_lua, "vim.validate{arg1={1, 't'}}")) - matches('arg2: expected string, got number', - pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={1, 's'}}")) - matches('arg2: expected string, got nil', - pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={nil, 's'}}")) - matches('arg2: expected string, got nil', - pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={nil, 's'}}")) - matches('arg1: expected even number, got 3', - pcall_err(exec_lua, "vim.validate{arg1={3, function(a) return a == 1 end, 'even number'}}")) - matches('arg1: expected %?, got 3', - pcall_err(exec_lua, "vim.validate{arg1={3, function(a) return a == 1 end}}")) - matches('arg1: expected number|string, got nil', - pcall_err(exec_lua, "vim.validate{ arg1={ nil, {'n', 's'} }}")) + matches( + 'arg1: expected string, got nil', + pcall_err(exec_lua, "vim.validate{ arg1={ nil, 's', false }}") + ) + + matches('arg1: expected table, got number', pcall_err(exec_lua, "vim.validate{arg1={1, 't'}}")) + matches( + 'arg2: expected string, got number', + pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={1, 's'}}") + ) + matches( + 'arg2: expected string, got nil', + pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={nil, 's'}}") + ) + matches( + 'arg2: expected string, got nil', + pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={nil, 's'}}") + ) + matches( + 'arg1: expected even number, got 3', + pcall_err(exec_lua, "vim.validate{arg1={3, function(a) return a == 1 end, 'even number'}}") + ) + matches( + 'arg1: expected %?, got 3', + pcall_err(exec_lua, 'vim.validate{arg1={3, function(a) return a == 1 end}}') + ) + matches( + 'arg1: expected number|string, got nil', + pcall_err(exec_lua, "vim.validate{ arg1={ nil, {'n', 's'} }}") + ) -- Pass an additional message back. - matches('arg1: expected %?, got 3. Info: TEST_MSG', - pcall_err(exec_lua, "vim.validate{arg1={3, function(a) return a == 1, 'TEST_MSG' end}}")) + matches( + 'arg1: expected %?, got 3. Info: TEST_MSG', + pcall_err(exec_lua, "vim.validate{arg1={3, function(a) return a == 1, 'TEST_MSG' end}}") + ) end) it('vim.is_callable', function() - eq(true, exec_lua("return vim.is_callable(function()end)")) - eq(true, exec_lua([[ + eq(true, exec_lua('return vim.is_callable(function()end)')) + eq( + true, + exec_lua([[ local meta = { __call = function()end } local function new_callable() return setmetatable({}, meta) end local callable = new_callable() return vim.is_callable(callable) - ]])) + ]]) + ) - eq(false, exec_lua("return vim.is_callable(1)")) + eq(false, exec_lua('return vim.is_callable(1)')) eq(false, exec_lua("return vim.is_callable('foo')")) - eq(false, exec_lua("return vim.is_callable({})")) + eq(false, exec_lua('return vim.is_callable({})')) end) it('vim.g', function() @@ -1089,24 +1486,26 @@ describe('lua stdlib', function() vim.api.nvim_set_var("to_delete", {hello="world"}) ]] - eq('hi', funcs.luaeval "vim.g.testing") - eq(123, funcs.luaeval "vim.g.other") - eq(5120.1, funcs.luaeval "vim.g.floaty") - eq(NIL, funcs.luaeval "vim.g.nonexistent") - eq(NIL, funcs.luaeval "vim.g.nullvar") + 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 [[ + eq( + { false, true }, + exec_lua [[ return {vim.g.nonexistent == vim.NIL, vim.g.nullvar == vim.NIL} - ]]) + ]] + ) - eq({hello="world"}, funcs.luaeval "vim.g.to_delete") + eq({ hello = 'world' }, fn.luaeval 'vim.g.to_delete') exec_lua [[ vim.g.to_delete = nil ]] - eq(NIL, funcs.luaeval "vim.g.to_delete") + eq(NIL, fn.luaeval 'vim.g.to_delete') - matches([[attempt to index .* nil value]], - pcall_err(exec_lua, 'return vim.g[0].testing')) + matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.g[0].testing')) exec_lua [[ local counter = 0 @@ -1114,7 +1513,7 @@ describe('lua stdlib', function() local function get_counter() return counter end vim.g.AddCounter = add_counter vim.g.GetCounter = get_counter - vim.g.funcs = {add = add_counter, get = get_counter} + vim.g.fn = {add = add_counter, get = get_counter} vim.g.AddParens = function(s) return '(' .. s .. ')' end ]] @@ -1127,10 +1526,10 @@ describe('lua stdlib', function() 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.funcs.add()]]) - eq(5, exec_lua([[return vim.g.funcs.get()]])) - exec_lua([[vim.api.nvim_get_var('funcs').add()]]) - eq(6, exec_lua([[return vim.api.nvim_get_var('funcs').get()]])) + 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 [[ @@ -1139,7 +1538,7 @@ describe('lua stdlib', function() 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('funcs', {add = add_counter, get = 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) ]] @@ -1152,10 +1551,10 @@ describe('lua stdlib', function() 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.funcs.add()]]) - eq(5, exec_lua([[return vim.g.funcs.get()]])) - exec_lua([[vim.api.nvim_get_var('funcs').add()]]) - eq(6, exec_lua([[return vim.api.nvim_get_var('funcs').get()]])) + 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([[ @@ -1173,12 +1572,12 @@ describe('lua stdlib', function() local pathsep = helpers.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) + 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]]) + write_file(autoload_file, [[let testload#value = 2]]) - clear{ args_rm={'-u'}, env={ XDG_CONFIG_HOME=xconfig, XDG_DATA_HOME=xdata } } + clear { args_rm = { '-u' }, env = { XDG_CONFIG_HOME = xconfig, XDG_DATA_HOME = xdata } } eq(2, exec_lua("return vim.g['testload#value']")) rmdir('Xhome') @@ -1195,26 +1594,28 @@ describe('lua stdlib', function() vim.api.nvim_buf_set_var(BUF, "testing", "bye") ]] - eq('hi', funcs.luaeval "vim.b.testing") - eq('bye', funcs.luaeval "vim.b[BUF].testing") - eq(123, funcs.luaeval "vim.b.other") - eq(5120.1, funcs.luaeval "vim.b.floaty") - eq(NIL, funcs.luaeval "vim.b.nonexistent") - eq(NIL, funcs.luaeval "vim.b[BUF].nonexistent") - eq(NIL, funcs.luaeval "vim.b.nullvar") + 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 [[ + 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')) + matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.b[BUF][0].testing')) - eq({hello="world"}, funcs.luaeval "vim.b.to_delete") + eq({ hello = 'world' }, fn.luaeval 'vim.b.to_delete') exec_lua [[ vim.b.to_delete = nil ]] - eq(NIL, funcs.luaeval "vim.b.to_delete") + eq(NIL, fn.luaeval 'vim.b.to_delete') exec_lua [[ local counter = 0 @@ -1222,7 +1623,7 @@ describe('lua stdlib', function() local function get_counter() return counter end vim.b.AddCounter = add_counter vim.b.GetCounter = get_counter - vim.b.funcs = {add = add_counter, get = get_counter} + vim.b.fn = {add = add_counter, get = get_counter} vim.b.AddParens = function(s) return '(' .. s .. ')' end ]] @@ -1235,10 +1636,10 @@ describe('lua stdlib', function() 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.funcs.add()]]) - eq(5, exec_lua([[return vim.b.funcs.get()]])) - exec_lua([[vim.api.nvim_buf_get_var(0, 'funcs').add()]]) - eq(6, exec_lua([[return vim.api.nvim_buf_get_var(0, 'funcs').get()]])) + 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 [[ @@ -1247,7 +1648,7 @@ describe('lua stdlib', function() 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, 'funcs', {add = add_counter, get = 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) ]] @@ -1260,10 +1661,10 @@ describe('lua stdlib', function() 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.funcs.add()]]) - eq(5, exec_lua([[return vim.b.funcs.get()]])) - exec_lua([[vim.api.nvim_buf_get_var(0, 'funcs').add()]]) - eq(6, exec_lua([[return vim.api.nvim_buf_get_var(0, 'funcs').get()]])) + 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([[ @@ -1281,9 +1682,9 @@ describe('lua stdlib', function() vim.cmd "vnew" ]] - eq(NIL, funcs.luaeval "vim.b.testing") - eq(NIL, funcs.luaeval "vim.b.other") - eq(NIL, funcs.luaeval "vim.b.nonexistent") + 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() @@ -1299,20 +1700,19 @@ describe('lua stdlib', function() vim.api.nvim_win_set_var(WIN, "testing", "bye") ]] - eq('hi', funcs.luaeval "vim.w.testing") - eq('bye', funcs.luaeval "vim.w[WIN].testing") - eq(123, funcs.luaeval "vim.w.other") - eq(NIL, funcs.luaeval "vim.w.nonexistent") - eq(NIL, funcs.luaeval "vim.w[WIN].nonexistent") + 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')) + matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.w[WIN][0].testing')) - eq({hello="world"}, funcs.luaeval "vim.w.to_delete") + eq({ hello = 'world' }, fn.luaeval 'vim.w.to_delete') exec_lua [[ vim.w.to_delete = nil ]] - eq(NIL, funcs.luaeval "vim.w.to_delete") + eq(NIL, fn.luaeval 'vim.w.to_delete') exec_lua [[ local counter = 0 @@ -1320,7 +1720,7 @@ describe('lua stdlib', function() local function get_counter() return counter end vim.w.AddCounter = add_counter vim.w.GetCounter = get_counter - vim.w.funcs = {add = add_counter, get = get_counter} + vim.w.fn = {add = add_counter, get = get_counter} vim.w.AddParens = function(s) return '(' .. s .. ')' end ]] @@ -1333,10 +1733,10 @@ describe('lua stdlib', function() 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.funcs.add()]]) - eq(5, exec_lua([[return vim.w.funcs.get()]])) - exec_lua([[vim.api.nvim_win_get_var(0, 'funcs').add()]]) - eq(6, exec_lua([[return vim.api.nvim_win_get_var(0, 'funcs').get()]])) + 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 [[ @@ -1345,7 +1745,7 @@ describe('lua stdlib', function() 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, 'funcs', {add = add_counter, get = 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) ]] @@ -1358,10 +1758,10 @@ describe('lua stdlib', function() 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.funcs.add()]]) - eq(5, exec_lua([[return vim.w.funcs.get()]])) - exec_lua([[vim.api.nvim_win_get_var(0, 'funcs').add()]]) - eq(6, exec_lua([[return vim.api.nvim_win_get_var(0, 'funcs').get()]])) + 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([[ @@ -1379,9 +1779,9 @@ describe('lua stdlib', function() vim.cmd "vnew" ]] - eq(NIL, funcs.luaeval "vim.w.testing") - eq(NIL, funcs.luaeval "vim.w.other") - eq(NIL, funcs.luaeval "vim.w.nonexistent") + 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() @@ -1391,21 +1791,20 @@ describe('lua stdlib', function() vim.api.nvim_tabpage_set_var(0, "to_delete", {hello="world"}) ]] - eq('hi', funcs.luaeval "vim.t.testing") - eq(123, funcs.luaeval "vim.t.other") - eq(NIL, funcs.luaeval "vim.t.nonexistent") - eq('hi', funcs.luaeval "vim.t[0].testing") - eq(123, funcs.luaeval "vim.t[0].other") - eq(NIL, funcs.luaeval "vim.t[0].nonexistent") + 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')) + matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.t[0][0].testing')) - eq({hello="world"}, funcs.luaeval "vim.t.to_delete") + eq({ hello = 'world' }, fn.luaeval 'vim.t.to_delete') exec_lua [[ vim.t.to_delete = nil ]] - eq(NIL, funcs.luaeval "vim.t.to_delete") + eq(NIL, fn.luaeval 'vim.t.to_delete') exec_lua [[ local counter = 0 @@ -1413,7 +1812,7 @@ describe('lua stdlib', function() local function get_counter() return counter end vim.t.AddCounter = add_counter vim.t.GetCounter = get_counter - vim.t.funcs = {add = add_counter, get = get_counter} + vim.t.fn = {add = add_counter, get = get_counter} vim.t.AddParens = function(s) return '(' .. s .. ')' end ]] @@ -1426,10 +1825,10 @@ describe('lua stdlib', function() 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.funcs.add()]]) - eq(5, exec_lua([[return vim.t.funcs.get()]])) - exec_lua([[vim.api.nvim_tabpage_get_var(0, 'funcs').add()]]) - eq(6, exec_lua([[return vim.api.nvim_tabpage_get_var(0, 'funcs').get()]])) + 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 [[ @@ -1438,7 +1837,7 @@ describe('lua stdlib', function() 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, 'funcs', {add = add_counter, get = 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) ]] @@ -1451,47 +1850,46 @@ describe('lua stdlib', function() 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.funcs.add()]]) - eq(5, exec_lua([[return vim.t.funcs.get()]])) - exec_lua([[vim.api.nvim_tabpage_get_var(0, 'funcs').add()]]) - eq(6, exec_lua([[return vim.api.nvim_tabpage_get_var(0, 'funcs').get()]])) + 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, funcs.luaeval "vim.t.testing") - eq(NIL, funcs.luaeval "vim.t.other") - eq(NIL, funcs.luaeval "vim.t.nonexistent") + 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', funcs.luaeval('vim.env.A')) + eq('123', fn.luaeval('vim.env.A')) exec_lua([[vim.env.A = 456]]) - eq('456', funcs.luaeval('vim.env.A')) + eq('456', fn.luaeval('vim.env.A')) exec_lua([[vim.env.A = nil]]) - eq(NIL, funcs.luaeval('vim.env.A')) + eq(NIL, fn.luaeval('vim.env.A')) - eq(true, funcs.luaeval('vim.env.B == nil')) + eq(true, fn.luaeval('vim.env.B == nil')) command([[let $HOME = 'foo']]) - eq('foo', funcs.expand('~')) - eq('foo', funcs.luaeval('vim.env.HOME')) + eq('foo', fn.expand('~')) + eq('foo', fn.luaeval('vim.env.HOME')) exec_lua([[vim.env.HOME = nil]]) - eq('foo', funcs.expand('~')) + eq('foo', fn.expand('~')) exec_lua([[vim.env.HOME = 'bar']]) - eq('bar', funcs.expand('~')) - eq('bar', funcs.luaeval('vim.env.HOME')) + eq('bar', fn.expand('~')) + eq('bar', fn.luaeval('vim.env.HOME')) end) it('vim.v', function() - eq(funcs.luaeval "vim.api.nvim_get_vvar('progpath')", funcs.luaeval "vim.v.progpath") - eq(false, funcs.luaeval "vim.v['false']") - eq(NIL, funcs.luaeval "vim.v.null") - matches([[attempt to index .* nil value]], - pcall_err(exec_lua, 'return vim.v[0].progpath')) + 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('Dictionary is locked', pcall_err(exec_lua, [[vim.v.nosuchvar = 42]])) eq('Key is fixed: errmsg', pcall_err(exec_lua, [[vim.v.errmsg = nil]])) @@ -1507,69 +1905,72 @@ describe('lua stdlib', function() eq({}, eval('v:oldfiles')) feed('i foo foo foo<Esc>0/foo<CR>') - eq({1, 1}, meths.win_get_cursor(0)) + eq({ 1, 1 }, api.nvim_win_get_cursor(0)) eq(1, eval('v:searchforward')) feed('n') - eq({1, 5}, meths.win_get_cursor(0)) + 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}, meths.win_get_cursor(0)) + 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}, meths.win_get_cursor(0)) + eq({ 1, 5 }, api.nvim_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}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { background = Screen.colors.Yellow }, }) screen:attach() eq(1, eval('v:hlsearch')) - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:foo} {1:^foo} {1:foo} | {0:~ }| | - ]]} + ]], + } exec_lua([[vim.v.hlsearch = 0]]) eq(0, eval('v:hlsearch')) - screen:expect{grid=[[ + screen:expect { + grid = [[ foo ^foo foo | {0:~ }| | - ]]} + ]], + } exec_lua([[vim.v.hlsearch = 1]]) eq(1, eval('v:hlsearch')) - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:foo} {1:^foo} {1:foo} | {0:~ }| | - ]]} + ]], + } end) it('vim.bo', function() - eq('', funcs.luaeval "vim.bo.filetype") + eq('', fn.luaeval 'vim.bo.filetype') exec_lua [[ vim.api.nvim_set_option_value("filetype", "markdown", {}) BUF = vim.api.nvim_create_buf(false, true) vim.api.nvim_set_option_value("modifiable", false, {buf = BUF}) ]] - eq(false, funcs.luaeval "vim.bo.modified") - eq('markdown', funcs.luaeval "vim.bo.filetype") - eq(false, funcs.luaeval "vim.bo[BUF].modifiable") + eq(false, fn.luaeval 'vim.bo.modified') + eq('markdown', fn.luaeval 'vim.bo.filetype') + eq(false, fn.luaeval 'vim.bo[BUF].modifiable') exec_lua [[ vim.bo.filetype = '' vim.bo[BUF].modifiable = true ]] - eq('', funcs.luaeval "vim.bo.filetype") - eq(true, funcs.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')) + 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() @@ -1578,34 +1979,32 @@ describe('lua stdlib', function() vim.cmd "split" vim.api.nvim_set_option_value("cole", 2, {}) ]] - eq(2, funcs.luaeval "vim.wo.cole") + eq(2, fn.luaeval 'vim.wo.cole') exec_lua [[ vim.wo.conceallevel = 0 ]] - eq(0, funcs.luaeval "vim.wo.cole") - eq(0, funcs.luaeval "vim.wo[0].cole") - eq(0, funcs.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, funcs.luaeval "vim.wo[1000].cole") + 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 [[ vim.wo[1000].cole = 0 ]] - eq(0, funcs.luaeval "vim.wo[1000].cole") + 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, funcs.luaeval "vim.wo.scrolloff") + eq(200, fn.luaeval 'vim.wo.scrolloff') exec_lua [[vim.wo.scrolloff = -1]] - eq(100, funcs.luaeval "vim.wo.scrolloff") + eq(100, fn.luaeval 'vim.wo.scrolloff') exec_lua [[ vim.wo[0][0].scrolloff = 200 vim.cmd "enew" ]] - eq(100, funcs.luaeval "vim.wo.scrolloff") + eq(100, fn.luaeval 'vim.wo.scrolloff') end) describe('vim.opt', function() @@ -1638,7 +2037,7 @@ describe('lua stdlib', function() vim.opt.wildignore = { 'hello', 'world' } return vim.o.wildignore ]] - eq(wildignore, "hello,world") + eq(wildignore, 'hello,world') end) it('should allow setting tables with shortnames', function() @@ -1646,7 +2045,7 @@ describe('lua stdlib', function() vim.opt.wig = { 'hello', 'world' } return vim.o.wildignore ]] - eq(wildignore, "hello,world") + eq(wildignore, 'hello,world') end) it('should error when you attempt to set string values to numeric options', function() @@ -1668,7 +2067,9 @@ describe('lua stdlib', function() end) it('should allow you to set boolean values', function() - eq({true, false, true}, exec_lua [[ + eq( + { true, false, true }, + exec_lua [[ local results = {} vim.opt.autoindent = true @@ -1681,7 +2082,8 @@ describe('lua stdlib', function() table.insert(results, vim.bo.autoindent) return results - ]]) + ]] + ) end) it('should change current buffer values and defaults for global local values', function() @@ -1707,20 +2109,20 @@ describe('lua stdlib', function() ]] -- Set -> global & local - eq("global-local", result[1]) - eq("", result[2]) + eq('global-local', result[1]) + eq('', result[2]) -- Setlocal -> only local - eq("global-local", result[3]) - eq("only-local", result[4]) + eq('global-local', result[3]) + eq('only-local', result[4]) -- Setglobal -> only global - eq("only-global", result[5]) - eq("only-local", result[6]) + 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]) + eq('global-local', result[7]) + eq('', result[8]) end) it('should allow you to retrieve window opts even if they have not been set', function() @@ -1735,11 +2137,13 @@ describe('lua stdlib', function() return result ]] - eq({false, false, true, true}, result) + eq({ false, false, true, true }, result) end) it('should allow all sorts of string manipulation', function() - eq({'hello', 'hello world', 'start hello world'}, exec_lua [[ + eq( + { 'hello', 'hello world', 'start hello world' }, + exec_lua [[ local results = {} vim.opt.makeprg = "hello" @@ -1752,19 +2156,23 @@ describe('lua stdlib', function() table.insert(results, vim.o.makeprg) return results - ]]) + ]] + ) end) describe('option:get()', function() it('should work for boolean values', function() - eq(false, exec_lua [[ + eq( + false, + exec_lua [[ vim.opt.number = false return vim.opt.number:get() - ]]) + ]] + ) end) it('should work for number values', function() - local tabstop = exec_lua[[ + local tabstop = exec_lua [[ vim.opt.tabstop = 10 return vim.opt.tabstop:get() ]] @@ -1773,10 +2181,13 @@ describe('lua stdlib', function() end) it('should work for string values', function() - eq("hello world", exec_lua [[ + eq( + 'hello world', + exec_lua [[ vim.opt.makeprg = "hello world" return vim.opt.makeprg:get() - ]]) + ]] + ) end) it('should work for set type flaglists', function() @@ -1806,7 +2217,7 @@ describe('lua stdlib', function() ]] eq(3, #wildignore) - eq("*.c", wildignore[1]) + eq('*.c', wildignore[1]) end) it('should work for options that are both commalist and flaglist', function() @@ -1815,14 +2226,14 @@ describe('lua stdlib', function() return vim.opt.whichwrap:get() ]] - eq({b = true, s = true}, result) + eq({ b = true, s = true }, result) result = exec_lua [[ vim.opt.whichwrap = { b = true, s = false, h = true } return vim.opt.whichwrap:get() ]] - eq({b = true, h = true}, result) + eq({ b = true, h = true }, result) end) it('should work for key-value pair options', function() @@ -1832,25 +2243,31 @@ describe('lua stdlib', function() ]] eq({ - tab = "> ", - space = "_", + tab = '> ', + space = '_', }, listchars) end) it('should allow you to add numeric options', function() - eq(16, exec_lua [[ + eq( + 16, + exec_lua [[ vim.opt.tabstop = 12 vim.opt.tabstop = vim.opt.tabstop + 4 return vim.bo.tabstop - ]]) + ]] + ) end) it('should allow you to subtract numeric options', function() - eq(2, exec_lua [[ + eq( + 2, + exec_lua [[ vim.opt.tabstop = 4 vim.opt.tabstop = vim.opt.tabstop - 2 return vim.bo.tabstop - ]]) + ]] + ) end) end) @@ -1864,7 +2281,7 @@ describe('lua stdlib', function() return vim.o.listchars ]] - eq("eol:~,space:.", listchars) + eq('eol:~,space:.', listchars) end) it('should allow adding dictionary style', function() @@ -1879,7 +2296,7 @@ describe('lua stdlib', function() return vim.o.listchars ]] - eq("eol:~,space:-", listchars) + eq('eol:~,space:-', listchars) end) it('should allow adding dictionary style', function() @@ -1893,7 +2310,7 @@ describe('lua stdlib', function() return vim.o.listchars ]] - eq("eol:~,space:_", listchars) + eq('eol:~,space:_', listchars) end) it('should allow completely new keys', function() @@ -1907,7 +2324,7 @@ describe('lua stdlib', function() return vim.o.listchars ]] - eq("eol:~,space:.,tab:>>>", listchars) + eq('eol:~,space:.,tab:>>>', listchars) end) it('should allow subtracting dictionary style', function() @@ -1921,7 +2338,7 @@ describe('lua stdlib', function() return vim.o.listchars ]] - eq("eol:~", listchars) + eq('eol:~', listchars) end) it('should allow subtracting dictionary style', function() @@ -1935,7 +2352,7 @@ describe('lua stdlib', function() return vim.o.listchars ]] - eq("", listchars) + eq('', listchars) end) it('should allow subtracting dictionary style multiple times', function() @@ -1949,7 +2366,7 @@ describe('lua stdlib', function() return vim.o.listchars ]] - eq("eol:~", listchars) + eq('eol:~', listchars) end) it('should allow adding a key:value string to a listchars', function() @@ -1963,7 +2380,7 @@ describe('lua stdlib', function() return vim.o.listchars ]] - eq("eol:~,space:.,tab:>~", listchars) + eq('eol:~,space:.,tab:>~', listchars) end) it('should allow prepending a key:value string to a listchars', function() @@ -1977,44 +2394,56 @@ describe('lua stdlib', function() return vim.o.listchars ]] - eq("eol:~,space:.,tab:>~", listchars) + eq('eol:~,space:.,tab:>~', listchars) end) end) it('should automatically set when calling remove', function() - eq("foo,baz", exec_lua [[ + eq( + 'foo,baz', + exec_lua [[ vim.opt.wildignore = "foo,bar,baz" vim.opt.wildignore:remove("bar") return vim.o.wildignore - ]]) + ]] + ) end) it('should automatically set when calling remove with a table', function() - eq("foo", exec_lua [[ + eq( + 'foo', + exec_lua [[ vim.opt.wildignore = "foo,bar,baz" vim.opt.wildignore:remove { "bar", "baz" } return vim.o.wildignore - ]]) + ]] + ) end) it('should automatically set when calling append', function() - eq("foo,bar,baz,bing", exec_lua [[ + eq( + 'foo,bar,baz,bing', + exec_lua [[ vim.opt.wildignore = "foo,bar,baz" vim.opt.wildignore:append("bing") return vim.o.wildignore - ]]) + ]] + ) end) it('should automatically set when calling append with a table', function() - eq("foo,bar,baz,bing,zap", exec_lua [[ + eq( + 'foo,bar,baz,bing,zap', + exec_lua [[ vim.opt.wildignore = "foo,bar,baz" vim.opt.wildignore:append { "bing", "zap" } return vim.o.wildignore - ]]) + ]] + ) end) it('should allow adding tables', function() @@ -2106,96 +2535,198 @@ describe('lua stdlib', function() describe('option types', function() it('should allow to set option with numeric value', function() - eq(4, exec_lua [[ + eq( + 4, + exec_lua [[ vim.opt.tabstop = 4 return vim.bo.tabstop - ]]) + ]] + ) - matches("Invalid option type 'string' for 'tabstop'", pcall_err(exec_lua, [[ + 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, [[ + ]] + ) + ) + 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, [[ + ]] + ) + ) + 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, [[ + ]] + ) + ) + matches( + "Invalid option type 'function' for 'tabstop'", + pcall_err( + exec_lua, + [[ vim.opt.tabstop = function() return 4 end - ]])) + ]] + ) + ) end) it('should allow to set option with boolean value', function() - eq(true, exec_lua [[ + eq( + true, + exec_lua [[ vim.opt.undofile = true return vim.bo.undofile - ]]) + ]] + ) - matches("Invalid option type 'number' for 'undofile'", pcall_err(exec_lua, [[ + 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, [[ + ]] + ) + ) + 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, [[ + ]] + ) + ) + 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, [[ + ]] + ) + ) + matches( + "Invalid option type 'function' for 'undofile'", + pcall_err( + exec_lua, + [[ vim.opt.undofile = function() return true end - ]])) + ]] + ) + ) end) it('should allow to set option with array or string value', function() - eq('indent,eol,start', exec_lua [[ + eq( + 'indent,eol,start', + exec_lua [[ vim.opt.backspace = {'indent','eol','start'} return vim.go.backspace - ]]) - eq('indent,eol,start', exec_lua [[ + ]] + ) + eq( + 'indent,eol,start', + exec_lua [[ vim.opt.backspace = 'indent,eol,start' return vim.go.backspace - ]]) + ]] + ) - matches("Invalid option type 'boolean' for 'backspace'", pcall_err(exec_lua, [[ + 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, [[ + ]] + ) + ) + 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, [[ + ]] + ) + ) + matches( + "Invalid option type 'function' for 'backspace'", + pcall_err( + exec_lua, + [[ vim.opt.backspace = function() return 'indent,eol,start' end - ]])) + ]] + ) + ) end) it('should allow set option with map or string value', function() - eq("eol:~,space:.", exec_lua [[ + eq( + 'eol:~,space:.', + exec_lua [[ vim.opt.listchars = { eol = "~", space = ".", } return vim.o.listchars - ]]) - eq("eol:~,space:.,tab:>~", exec_lua [[ + ]] + ) + eq( + 'eol:~,space:.,tab:>~', + exec_lua [[ vim.opt.listchars = "eol:~,space:.,tab:>~" return vim.o.listchars - ]]) + ]] + ) - matches("Invalid option type 'boolean' for 'listchars'", pcall_err(exec_lua, [[ + 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, [[ + ]] + ) + ) + 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, [[ + ]] + ) + ) + matches( + "Invalid option type 'function' for 'listchars'", + pcall_err( + exec_lua, + [[ vim.opt.listchars = function() return "eol:~,space:.,tab:>~" end - ]])) + ]] + ) + ) end) it('should allow set option with set or string value', function() @@ -2207,23 +2738,44 @@ describe('lua stdlib', function() return vim.go.whichwrap ]] - eq(ww, "b,s") - eq("b,s,<,>,[,]", exec_lua [[ + eq(ww, 'b,s') + eq( + 'b,s,<,>,[,]', + exec_lua [[ vim.opt.whichwrap = "b,s,<,>,[,]" return vim.go.whichwrap - ]]) + ]] + ) - matches("Invalid option type 'boolean' for 'whichwrap'", pcall_err(exec_lua, [[ + 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, [[ + ]] + ) + ) + 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, [[ + ]] + ) + ) + matches( + "Invalid option type 'function' for 'whichwrap'", + pcall_err( + exec_lua, + [[ vim.opt.whichwrap = function() return "b,s,<,>,[,]" end - ]])) + ]] + ) + ) end) end) @@ -2234,7 +2786,7 @@ describe('lua stdlib', function() return { vim.opt.isfname:get(), vim.go.isfname } ]] - eq({{",", "a", "b", "c"}, "a,b,,,c"}, result) + eq({ { ',', 'a', 'b', 'c' }, 'a,b,,,c' }, result) end) -- isfname=a,b,c,^,,def @@ -2244,77 +2796,101 @@ describe('lua stdlib', function() return { vim.opt.isfname:get(), vim.go.isfname } ]] - eq({{"^,", "a", "b", "c"}, "a,b,^,,c"}, result) + eq({ { '^,', 'a', 'b', 'c' }, 'a,b,^,,c' }, result) end) - - describe('https://github.com/neovim/neovim/issues/14828', function() it('gives empty list when item is empty:array', function() - eq({}, exec_lua [[ + eq( + {}, + exec_lua [[ vim.cmd("set wildignore=") return vim.opt.wildignore:get() - ]]) + ]] + ) - eq({}, exec_lua [[ + eq( + {}, + exec_lua [[ vim.opt.wildignore = {} return vim.opt.wildignore:get() - ]]) + ]] + ) end) it('gives empty list when item is empty:set', function() - eq({}, exec_lua [[ + eq( + {}, + exec_lua [[ vim.cmd("set formatoptions=") return vim.opt.formatoptions:get() - ]]) + ]] + ) - eq({}, exec_lua [[ + eq( + {}, + exec_lua [[ vim.opt.formatoptions = {} return vim.opt.formatoptions:get() - ]]) + ]] + ) end) it('does not append to empty item', function() - eq({"*.foo", "*.bar"}, exec_lua [[ + eq( + { '*.foo', '*.bar' }, + exec_lua [[ vim.opt.wildignore = {} vim.opt.wildignore:append { "*.foo", "*.bar" } return vim.opt.wildignore:get() - ]]) + ]] + ) end) it('does not prepend to empty item', function() - eq({"*.foo", "*.bar"}, exec_lua [[ + eq( + { '*.foo', '*.bar' }, + exec_lua [[ vim.opt.wildignore = {} vim.opt.wildignore:prepend { "*.foo", "*.bar" } return vim.opt.wildignore:get() - ]]) + ]] + ) end) it('append to empty set', function() - eq({ t = true }, exec_lua [[ + eq( + { t = true }, + exec_lua [[ vim.opt.formatoptions = {} vim.opt.formatoptions:append("t") return vim.opt.formatoptions:get() - ]]) + ]] + ) end) it('prepend to empty set', function() - eq({ t = true }, exec_lua [[ + eq( + { t = true }, + exec_lua [[ vim.opt.formatoptions = {} vim.opt.formatoptions:prepend("t") return vim.opt.formatoptions:get() - ]]) + ]] + ) end) end) end) -- vim.opt describe('vim.opt_local', function() it('appends into global value when changing local option value', function() - eq({ "foo,bar,baz,qux" }, exec_lua [[ + eq( + { 'foo,bar,baz,qux' }, + exec_lua [[ local result = {} vim.opt.tags = "foo,bar" @@ -2324,20 +2900,24 @@ describe('lua stdlib', function() table.insert(result, vim.bo.tags) return result - ]]) + ]] + ) end) end) describe('vim.opt_global', function() it('gets current global option value', function() - eq({ "yes" }, exec_lua [[ + eq( + { 'yes' }, + exec_lua [[ local result = {} vim.cmd "setglobal signcolumn=yes" table.insert(result, vim.opt_global.signcolumn:get()) return result - ]]) + ]] + ) end) end) @@ -2346,15 +2926,15 @@ describe('lua stdlib', function() vim.cmd "autocmd BufNew * ++once lua BUF = vim.fn.expand('<abuf>')" vim.cmd "new" ]] - eq('2', funcs.luaeval "BUF") - eq(2, funcs.luaeval "#vim.api.nvim_list_bufs()") + eq('2', fn.luaeval 'BUF') + eq(2, fn.luaeval '#vim.api.nvim_list_bufs()') -- vim.cmd can be indexed with a command name exec_lua [[ vim.cmd.let 'g:var = 2' ]] - eq(2, funcs.luaeval "vim.g.var") + eq(2, fn.luaeval 'vim.g.var') end) it('vim.regex', function() @@ -2363,16 +2943,16 @@ describe('lua stdlib', function() vim.cmd "set nomagic ignorecase" re2 = vim.regex"xYz" ]] - eq({}, exec_lua[[return {re1:match_str("x ac")}]]) - eq({3,7}, exec_lua[[return {re1:match_str("ac abbc")}]]) + eq({}, exec_lua [[return {re1:match_str("x ac")}]]) + eq({ 3, 7 }, exec_lua [[return {re1:match_str("ac abbc")}]]) - meths.buf_set_lines(0, 0, -1, true, {"yy", "abc abbc"}) - eq({}, exec_lua[[return {re1:match_line(0, 0)}]]) - eq({0,3}, exec_lua[[return {re1:match_line(0, 1)}]]) - eq({3,7}, exec_lua[[return {re1:match_line(0, 1, 1)}]]) - eq({3,7}, exec_lua[[return {re1:match_line(0, 1, 1, 8)}]]) - eq({}, exec_lua[[return {re1:match_line(0, 1, 1, 7)}]]) - eq({0,3}, exec_lua[[return {re1:match_line(0, 1, 0, 7)}]]) + api.nvim_buf_set_lines(0, 0, -1, true, { 'yy', 'abc abbc' }) + eq({}, exec_lua [[return {re1:match_line(0, 0)}]]) + eq({ 0, 3 }, exec_lua [[return {re1:match_line(0, 1)}]]) + eq({ 3, 7 }, exec_lua [[return {re1:match_line(0, 1, 1)}]]) + eq({ 3, 7 }, exec_lua [[return {re1:match_line(0, 1, 1, 8)}]]) + eq({}, exec_lua [[return {re1:match_line(0, 1, 1, 7)}]]) + eq({ 0, 3 }, exec_lua [[return {re1:match_line(0, 1, 0, 7)}]]) -- vim.regex() error inside :silent! should not crash. #20546 command([[silent! lua vim.regex('\\z')]]) @@ -2380,46 +2960,49 @@ describe('lua stdlib', function() end) it('vim.defer_fn', function() - eq(false, exec_lua [[ + eq( + false, + exec_lua [[ vim.g.test = false vim.defer_fn(function() vim.g.test = true end, 150) return vim.g.test - ]]) + ]] + ) exec_lua [[vim.wait(1000, function() return vim.g.test end)]] - eq(true, exec_lua[[return vim.g.test]]) + eq(true, exec_lua [[return vim.g.test]]) end) describe('vim.region', function() it('charwise', function() - insert(dedent( [[ + insert(dedent([[ text tααt tααt text text tαxt txtα tex text tαxt tαxt ]])) - 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] ]]) + 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] ]]) + eq({ 0, 5 }, exec_lua [[ return vim.region(0,{0,0},{0,4},'3',true)[0] ]]) end) it('linewise', function() - insert(dedent( [[ + 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] ]]) + 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] ]]) + eq({ 0, 6 }, exec_lua [[ return vim.region(0,{0,0},'.','v',true)[0] ]]) end) end) @@ -2447,10 +3030,10 @@ describe('lua stdlib', function() 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') + api.nvim_create_namespace('unused1') + api.nvim_create_namespace('unused2') + api.nvim_create_namespace('unused3') + api.nvim_create_namespace('unused4') insert([[hello world]]) @@ -2518,9 +3101,9 @@ describe('lua stdlib', function() table.insert(keys, buf) end) ]] - insert("hello") + insert('hello') - eq('iworld<ESC>', exec_lua[[return table.concat(keys, '')]]) + eq('iworld<ESC>', exec_lua [[return table.concat(keys, '')]]) end) it('can call vim.fn functions on Ctrl-C #17273', function() @@ -2534,7 +3117,7 @@ describe('lua stdlib', function() end) ]]) feed('/') - poke_eventloop() -- This is needed because Ctrl-C flushes input + poke_eventloop() -- This is needed because Ctrl-C flushes input feed('<C-C>') eq('/', exec_lua([[return _G.ctrl_c_cmdtype]])) end) @@ -2542,7 +3125,7 @@ describe('lua stdlib', function() describe('vim.wait', function() before_each(function() - exec_lua[[ + exec_lua [[ -- high precision timer get_time = function() return vim.fn.reltimefloat(vim.fn.reltime()) @@ -2551,11 +3134,13 @@ describe('lua stdlib', function() end) it('should run from lua', function() - exec_lua[[vim.wait(100, function() return true end)]] + exec_lua [[vim.wait(100, function() return true end)]] end) it('should wait the expected time if false', function() - eq({time = true, wait_result = {false, -1}}, exec_lua[[ + eq( + { time = true, wait_result = { false, -1 } }, + exec_lua [[ start_time = get_time() wait_succeed, wait_fail_val = vim.wait(200, function() return false end) @@ -2564,11 +3149,14 @@ describe('lua stdlib', function() time = (start_time + 0.15) < get_time(), wait_result = {wait_succeed, wait_fail_val} } - ]]) + ]] + ) end) it('should not block other events', function() - eq({time = true, wait_result = true}, exec_lua[[ + eq( + { time = true, wait_result = true }, + exec_lua [[ start_time = get_time() vim.g.timer_result = false @@ -2586,11 +3174,14 @@ describe('lua stdlib', function() time = (start_time + 5) > get_time(), wait_result = wait_result, } - ]]) + ]] + ) end) it('should not process non-fast events when commanded', function() - eq({wait_result = false}, exec_lua[[ + eq( + { wait_result = false }, + exec_lua [[ start_time = get_time() vim.g.timer_result = false @@ -2606,11 +3197,14 @@ describe('lua stdlib', function() return { wait_result = wait_result, } - ]]) + ]] + ) end) it('should work with vim.defer_fn', function() - eq({time = true, wait_result = true}, exec_lua[[ + eq( + { time = true, wait_result = true }, + exec_lua [[ start_time = get_time() vim.defer_fn(function() vim.g.timer_result = true end, 100) @@ -2620,94 +3214,124 @@ describe('lua stdlib', function() time = (start_time + 5) > get_time(), wait_result = wait_result, } - ]]) + ]] + ) end) it('should not crash when callback errors', function() local result = exec_lua [[ return {pcall(function() vim.wait(1000, function() error("As Expected") end) end)} ]] - eq({false, '[string "<nvim>"]:1: As Expected'}, {result[1], remove_trace(result[2])}) + eq({ false, '[string "<nvim>"]:1: As Expected' }, { result[1], remove_trace(result[2]) }) end) it('if callback is passed, it must be a function', function() - eq({false, 'vim.wait: if passed, condition must be a function'}, exec_lua [[ + eq( + { false, 'vim.wait: if passed, condition must be a function' }, + exec_lua [[ return {pcall(function() vim.wait(1000, 13) end)} - ]]) + ]] + ) end) it('should allow waiting with no callback, explicit', function() - eq(true, exec_lua [[ + eq( + true, + exec_lua [[ local start_time = vim.uv.hrtime() vim.wait(50, nil) return vim.uv.hrtime() - start_time > 25000 - ]]) + ]] + ) end) it('should allow waiting with no callback, implicit', function() - eq(true, exec_lua [[ + eq( + true, + exec_lua [[ local start_time = vim.uv.hrtime() vim.wait(50) return vim.uv.hrtime() - start_time > 25000 - ]]) + ]] + ) end) it('should call callbacks exactly once if they return true immediately', function() - eq(true, exec_lua [[ + eq( + true, + exec_lua [[ vim.g.wait_count = 0 vim.wait(1000, function() vim.g.wait_count = vim.g.wait_count + 1 return true end, 20) return vim.g.wait_count == 1 - ]]) + ]] + ) end) it('should call callbacks few times with large `interval`', function() - eq(true, exec_lua [[ + eq( + true, + exec_lua [[ vim.g.wait_count = 0 vim.wait(50, function() vim.g.wait_count = vim.g.wait_count + 1 end, 200) return vim.g.wait_count < 5 - ]]) + ]] + ) end) it('should play nice with `not` when fails', function() - eq(true, exec_lua [[ + eq( + true, + exec_lua [[ if not vim.wait(50, function() end) then return true end return false - ]]) + ]] + ) end) it('should play nice with `if` when success', function() - eq(true, exec_lua [[ + eq( + true, + exec_lua [[ if vim.wait(50, function() return true end) then return true end return false - ]]) + ]] + ) end) it('should return immediately with false if timeout is 0', function() - eq({false, -1}, exec_lua [[ + eq( + { false, -1 }, + exec_lua [[ return { vim.wait(0, function() return false end) } - ]]) + ]] + ) end) it('should work with tables with __call', function() - eq(true, exec_lua [[ + eq( + true, + exec_lua [[ local t = setmetatable({}, {__call = function(...) return true end}) return vim.wait(100, t, 10) - ]]) + ]] + ) end) it('should work with tables with __call that change', function() - eq(true, exec_lua [[ + eq( + true, + exec_lua [[ local t = {count = 0} setmetatable(t, { __call = function() @@ -2717,7 +3341,8 @@ describe('lua stdlib', function() }) return vim.wait(1000, t, 10) - ]]) + ]] + ) end) it('should not work with negative intervals', function() @@ -2738,8 +3363,8 @@ describe('lua stdlib', function() describe('returns -2 when interrupted', function() before_each(function() - local channel = meths.get_api_info()[1] - meths.set_var('channel', channel) + local channel = api.nvim_get_chan_info(0).id + api.nvim_set_var('channel', channel) end) it('without callback', function() @@ -2751,9 +3376,9 @@ describe('lua stdlib', function() end ]]) feed(':lua _G.Wait()<CR>') - eq({'notification', 'ready', {}}, next_msg(500)) + eq({ 'notification', 'ready', {} }, next_msg(500)) feed('<C-C>') - eq({'notification', 'wait', {-2}}, next_msg(500)) + eq({ 'notification', 'wait', { -2 } }, next_msg(500)) end) it('with callback', function() @@ -2765,9 +3390,9 @@ describe('lua stdlib', function() end ]]) feed(':lua _G.Wait()<CR>') - eq({'notification', 'ready', {}}, next_msg(500)) + eq({ 'notification', 'ready', {} }, next_msg(500)) feed('<C-C>') - eq({'notification', 'wait', {-2}}, next_msg(500)) + eq({ 'notification', 'wait', { -2 } }, next_msg(500)) end) end) @@ -2790,35 +3415,35 @@ describe('lua stdlib', function() end) it('vim.notify_once', function() - local screen = Screen.new(60,5) + local screen = Screen.new(60, 5) screen:set_default_attr_ids({ - [0] = {bold=true, foreground=Screen.colors.Blue}, - [1] = {foreground=Screen.colors.Red}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { foreground = Screen.colors.Red }, }) screen:attach() - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | - ]]} + ]], + } exec_lua [[vim.notify_once("I'll only tell you this once...", vim.log.levels.WARN)]] - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {1:I'll only tell you this once...} | - ]]} + ]], + } feed('<C-l>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | - ]]} + ]], + } exec_lua [[vim.notify_once("I'll only tell you this once...")]] screen:expect_unchanged() end) @@ -2831,26 +3456,26 @@ describe('lua stdlib', function() end) fun("BOB", nil, "MIKE") ]] - eq({'notification', 'mayday_mayday', {{a='BOB', c='MIKE'}}}, next_msg()) + eq({ 'notification', 'mayday_mayday', { { a = 'BOB', c = 'MIKE' } } }, next_msg()) -- let's gooooo exec_lua [[ vim.schedule_wrap(function(...) vim.rpcnotify(1, 'boogalo', select('#', ...)) end)(nil,nil,nil,nil) ]] - eq({'notification', 'boogalo', {4}}, next_msg()) + eq({ 'notification', 'boogalo', { 4 } }, next_msg()) end) end) describe('vim.api.nvim_buf_call', function() it('can access buf options', function() - local buf1 = meths.get_current_buf().id + local buf1 = api.nvim_get_current_buf() local buf2 = exec_lua [[ buf2 = vim.api.nvim_create_buf(false, true) return buf2 ]] - eq(false, meths.get_option_value('autoindent', {buf=buf1})) - eq(false, meths.get_option_value('autoindent', {buf=buf2})) + eq(false, api.nvim_get_option_value('autoindent', { buf = buf1 })) + eq(false, api.nvim_get_option_value('autoindent', { buf = buf2 })) local val = exec_lua [[ return vim.api.nvim_buf_call(buf2, function() @@ -2859,9 +3484,9 @@ describe('lua stdlib', function() end) ]] - 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(false, api.nvim_get_option_value('autoindent', { buf = buf1 })) + eq(true, api.nvim_get_option_value('autoindent', { buf = buf2 })) + eq(buf1, api.nvim_get_current_buf()) eq(buf2, val) end) @@ -2877,7 +3502,9 @@ describe('lua stdlib', function() end) it('can be nested crazily with hidden buffers', function() - eq(true, exec_lua([[ + eq( + true, + exec_lua([[ local function scratch_buf_call(fn) local buf = vim.api.nvim_create_buf(false, true) vim.api.nvim_set_option_value('cindent', true, {buf = buf}) @@ -2913,14 +3540,27 @@ describe('lua stdlib', function() end) end) end) - ]])) + ]]) + ) + end) + + it('can return values by reference', function() + eq( + { 4, 7 }, + exec_lua [[ + local val = {4, 10} + local ref = vim.api.nvim_buf_call(0, function() return val end) + ref[2] = 7 + return val + ]] + ) end) end) describe('vim.api.nvim_win_call', function() it('can access window options', function() command('vsplit') - local win1 = meths.get_current_win().id + local win1 = api.nvim_get_current_win() command('wincmd w') local win2 = exec_lua [[ win2 = vim.api.nvim_get_current_win() @@ -2928,8 +3568,8 @@ describe('lua stdlib', function() ]] command('wincmd p') - eq('', meths.get_option_value('winhighlight', {win=win1})) - eq('', meths.get_option_value('winhighlight', {win=win2})) + eq('', api.nvim_get_option_value('winhighlight', { win = win1 })) + eq('', api.nvim_get_option_value('winhighlight', { win = win2 })) local val = exec_lua [[ return vim.api.nvim_win_call(win2, function() @@ -2938,9 +3578,9 @@ describe('lua stdlib', function() end) ]] - 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('', api.nvim_get_option_value('winhighlight', { win = win1 })) + eq('Normal:Normal', api.nvim_get_option_value('winhighlight', { win = win2 })) + eq(win1, api.nvim_get_current_win()) eq(win2, val) end) @@ -2978,8 +3618,8 @@ describe('lua stdlib', function() -- Fixed for win_execute in vim-patch:8.1.2124, but should've applied to nvim_win_call too! local screen = Screen.new(30, 5) screen:set_default_attr_ids { - [1] = {reverse = true}, - [2] = {bold = true, reverse = true}, + [1] = { reverse = true }, + [2] = { bold = true, reverse = true }, } screen:attach() exec_lua [[ @@ -3012,75 +3652,110 @@ describe('lua stdlib', function() | ]] end) + + it('can return values by reference', function() + eq( + { 7, 10 }, + exec_lua [[ + local val = {4, 10} + local ref = vim.api.nvim_win_call(0, function() return val end) + ref[1] = 7 + return val + ]] + ) + end) end) describe('vim.iconv', function() it('can convert strings', function() - eq('hello', exec_lua[[ + eq( + 'hello', + exec_lua [[ return vim.iconv('hello', 'latin1', 'utf-8') - ]]) + ]] + ) end) it('can validate arguments', function() - eq({false, 'Expected at least 3 arguments'}, exec_lua[[ + eq( + { false, 'Expected at least 3 arguments' }, + exec_lua [[ return {pcall(vim.iconv, 'hello')} - ]]) + ]] + ) - eq({false, 'bad argument #3 to \'?\' (expected string)'}, exec_lua[[ + eq( + { false, "bad argument #3 to '?' (expected string)" }, + exec_lua [[ return {pcall(vim.iconv, 'hello', 'utf-8', true)} - ]]) + ]] + ) end) it('can handle bad encodings', function() - eq(NIL, exec_lua[[ + eq( + NIL, + exec_lua [[ return vim.iconv('hello', 'foo', 'bar') - ]]) + ]] + ) end) it('can handle strings with NUL bytes', function() - eq(7, exec_lua[[ + eq( + 7, + exec_lua [[ local a = string.char(97, 98, 99, 0, 100, 101, 102) -- abc\0def return string.len(vim.iconv(a, 'latin1', 'utf-8')) - ]]) + ]] + ) end) - end) - describe("vim.defaulttable", function() - it("creates nested table by default", function() - eq({ b = {c = 1 } }, exec_lua[[ + describe('vim.defaulttable', function() + it('creates nested table by default', function() + eq( + { b = { c = 1 } }, + exec_lua [[ local a = vim.defaulttable() a.b.c = 1 return a - ]]) + ]] + ) end) - it("allows to create default objects", function() - eq({ b = 1 }, exec_lua[[ + it('allows to create default objects', function() + eq( + { b = 1 }, + exec_lua [[ local a = vim.defaulttable(function() return 0 end) a.b = a.b + 1 return a - ]]) + ]] + ) end) it('accepts the key name', function() - eq({ b = 'b', c = 'c' }, exec_lua [[ + 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) + 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}; + [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 ]] @@ -3088,22 +3763,27 @@ describe('lua stdlib', function() -- 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=[[ + 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 }})}]]) + eq( + { 42, 'abc', { a = { b = 77 } } }, + exec_lua [[return {vim.print(42, 'abc', { a = { b = 77 }})}]] + ) -- vim.print() pretty-prints the args. - eq(dedent[[ + eq( + dedent [[ 42 abc @@ -3112,12 +3792,14 @@ describe('lua stdlib', function() b = 77 } }]], - eval[[execute('lua vim.print(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([[ + return exec_lua( + [[ local args = {...} local nargs = select('#', ...) for i = 1, nargs do @@ -3126,7 +3808,9 @@ describe('lua stdlib', function() end end return vim.F.if_nil(unpack(args, 1, nargs)) - ]], ...) + ]], + ... + ) end local a = NIL @@ -3142,15 +3826,18 @@ describe('lua stdlib', function() end) it('lpeg', function() - eq(5, exec_lua [[ + 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() + it('vim.ringbuf', function() local results = exec_lua([[ local ringbuf = vim.ringbuf(3) ringbuf:push("a") -- idx: 0 @@ -3178,14 +3865,14 @@ describe('lua stdlib', function() } ]]) local expected = { - peeka1 = "a", - peeka2 = "a", - pop1 = "a", + peeka1 = 'a', + peeka2 = 'a', + pop1 = 'a', pop2 = nil, - pop3 = "b", - pop4 = "c", - pop5 = "d", - pop_after_add_b = "a", + pop3 = 'b', + pop4 = 'c', + pop5 = 'd', + pop_after_add_b = 'a', } eq(expected, results) end) @@ -3193,8 +3880,8 @@ end) describe('lua: builtin modules', function() local function do_tests() - eq(2, exec_lua[[return vim.tbl_count {x=1,y=2}]]) - eq('{ 10, "spam" }', exec_lua[[return vim.inspect {10, 'spam'}]]) + eq(2, exec_lua [[return vim.tbl_count {x=1,y=2}]]) + eq('{ 10, "spam" }', exec_lua [[return vim.inspect {10, 'spam'}]]) end it('works', function() @@ -3208,17 +3895,21 @@ describe('lua: builtin modules', function() end) it('works without runtime', function() - clear{env={VIMRUNTIME='fixtures/a'}} + clear { env = { VIMRUNTIME = 'fixtures/a' } } do_tests() end) - it('fails when disabled without runtime', function() clear() command("let $VIMRUNTIME='fixtures/a'") -- Use system([nvim,…]) instead of clear() to avoid stderr noise. #21844 - local out = funcs.system({nvim_prog, '--clean', '--luamod-dev', - [[+call nvim_exec_lua('return vim.tbl_count {x=1,y=2}')]], '+qa!'}):gsub('\r\n', '\n') + local out = fn.system({ + nvim_prog, + '--clean', + '--luamod-dev', + [[+call nvim_exec_lua('return vim.tbl_count {x=1,y=2}')]], + '+qa!', + }):gsub('\r\n', '\n') eq(1, eval('v:shell_error')) matches("'vim%.shared' not found", out) end) @@ -3235,7 +3926,7 @@ describe('lua: require("mod") from packages', function() return err ]] - matches("unexpected symbol", syntax_error_msg) + matches('unexpected symbol', syntax_error_msg) end) it('uses the right order of mod.lua vs mod/init.lua', function() @@ -3252,15 +3943,18 @@ describe('vim.keymap', function() before_each(clear) it('can make a mapping', function() - eq(0, exec_lua [[ + eq( + 0, + exec_lua [[ GlobalCount = 0 vim.keymap.set('n', 'asdf', function() GlobalCount = GlobalCount + 1 end) return GlobalCount - ]]) + ]] + ) feed('asdf\n') - eq(1, exec_lua[[return GlobalCount]]) + eq(1, exec_lua [[return GlobalCount]]) end) it('can make an expr mapping', function() @@ -3270,19 +3964,22 @@ describe('vim.keymap', function() feed('aa') - eq({'π<M-π>foo<'}, meths.buf_get_lines(0, 0, -1, false)) + eq({ 'π<M-π>foo<' }, api.nvim_buf_get_lines(0, 0, -1, false)) end) it('can overwrite a mapping', function() - eq(0, exec_lua [[ + eq( + 0, + exec_lua [[ GlobalCount = 0 vim.keymap.set('n', 'asdf', function() GlobalCount = GlobalCount + 1 end) return GlobalCount - ]]) + ]] + ) feed('asdf\n') - eq(1, exec_lua[[return GlobalCount]]) + eq(1, exec_lua [[return GlobalCount]]) exec_lua [[ vim.keymap.set('n', 'asdf', function() GlobalCount = GlobalCount - 1 end) @@ -3290,19 +3987,22 @@ describe('vim.keymap', function() feed('asdf\n') - eq(0, exec_lua[[return GlobalCount]]) + eq(0, exec_lua [[return GlobalCount]]) end) it('can unmap a mapping', function() - eq(0, exec_lua [[ + eq( + 0, + exec_lua [[ GlobalCount = 0 vim.keymap.set('n', 'asdf', function() GlobalCount = GlobalCount + 1 end) return GlobalCount - ]]) + ]] + ) feed('asdf\n') - eq(1, exec_lua[[return GlobalCount]]) + eq(1, exec_lua [[return GlobalCount]]) exec_lua [[ vim.keymap.del('n', 'asdf') @@ -3310,20 +4010,23 @@ describe('vim.keymap', function() feed('asdf\n') - eq(1, exec_lua[[return GlobalCount]]) + eq(1, exec_lua [[return GlobalCount]]) eq('\nNo mapping found', helpers.exec_capture('nmap asdf')) end) it('works with buffer-local mappings', function() - eq(0, exec_lua [[ + eq( + 0, + exec_lua [[ GlobalCount = 0 vim.keymap.set('n', 'asdf', function() GlobalCount = GlobalCount + 1 end, {buffer=true}) return GlobalCount - ]]) + ]] + ) feed('asdf\n') - eq(1, exec_lua[[return GlobalCount]]) + eq(1, exec_lua [[return GlobalCount]]) exec_lua [[ vim.keymap.del('n', 'asdf', {buffer=true}) @@ -3331,33 +4034,63 @@ describe('vim.keymap', function() feed('asdf\n') - eq(1, exec_lua[[return GlobalCount]]) + eq(1, exec_lua [[return GlobalCount]]) eq('\nNo mapping found', helpers.exec_capture('nmap asdf')) end) it('does not mutate the opts parameter', function() - eq(true, exec_lua [[ + eq( + true, + exec_lua [[ opts = {buffer=true} vim.keymap.set('n', 'asdf', function() end, opts) return opts.buffer - ]]) - eq(true, exec_lua [[ + ]] + ) + eq( + true, + exec_lua [[ vim.keymap.del('n', 'asdf', opts) return opts.buffer - ]]) + ]] + ) end) it('can do <Plug> mappings', function() - eq(0, exec_lua [[ + eq( + 0, + exec_lua [[ GlobalCount = 0 vim.keymap.set('n', '<plug>(asdf)', function() GlobalCount = GlobalCount + 1 end) vim.keymap.set('n', 'ww', '<plug>(asdf)') return GlobalCount - ]]) + ]] + ) feed('ww\n') - eq(1, exec_lua[[return GlobalCount]]) + eq(1, exec_lua [[return GlobalCount]]) end) +end) +describe('Vimscript function exists()', function() + it('can check a lua function', function() + eq( + 1, + exec_lua [[ + _G.test = function() print("hello") end + return vim.fn.exists('*v:lua.test') + ]] + ) + + eq(1, fn.exists('*v:lua.require("mpack").decode')) + eq(1, fn.exists("*v:lua.require('mpack').decode")) + eq(1, fn.exists('*v:lua.require"mpack".decode')) + eq(1, fn.exists("*v:lua.require'mpack'.decode")) + eq(1, fn.exists("*v:lua.require('vim.lsp').start")) + eq(1, fn.exists('*v:lua.require"vim.lsp".start')) + eq(1, fn.exists("*v:lua.require'vim.lsp'.start")) + eq(0, fn.exists("*v:lua.require'vim.lsp'.unknown")) + eq(0, fn.exists('*v:lua.?')) + end) end) diff --git a/test/functional/lua/watch_spec.lua b/test/functional/lua/watch_spec.lua index cdcef08a1a..115fee8091 100644 --- a/test/functional/lua/watch_spec.lua +++ b/test/functional/lua/watch_spec.lua @@ -2,72 +2,113 @@ local helpers = require('test.functional.helpers')(after_each) local eq = helpers.eq local exec_lua = helpers.exec_lua local clear = helpers.clear +local is_ci = helpers.is_ci local is_os = helpers.is_os local skip = helpers.skip +-- Create a file via a rename to avoid multiple +-- events which can happen with some backends on some platforms +local function touch(path) + local tmp = helpers.tmpname() + io.open(tmp, 'w'):close() + assert(vim.uv.fs_rename(tmp, path)) +end + describe('vim._watch', function() before_each(function() clear() end) - describe('watch', function() - it('detects file changes', function() - skip(is_os('bsd'), "Stopped working on bsd after 3ca967387c49c754561c3b11a574797504d40f38") - local root_dir = vim.uv.fs_mkdtemp(vim.fs.dirname(helpers.tmpname()) .. '/nvim_XXXXXXXXXX') + local function run(watchfunc) + it('detects file changes (watchfunc=' .. watchfunc .. '())', function() + if watchfunc == 'fswatch' then + skip(is_os('mac'), 'flaky test on mac') + skip( + not is_ci() and helpers.fn.executable('fswatch') == 0, + 'fswatch not installed and not on CI' + ) + skip(is_os('win'), 'not supported on windows') + end - local result = exec_lua( - [[ - local root_dir = ... + if watchfunc == 'watch' then + skip(is_os('bsd'), 'Stopped working on bsd after 3ca967387c49c754561c3b11a574797504d40f38') + else + skip( + is_os('bsd'), + 'kqueue only reports events on watched folder itself, not contained files #26110' + ) + end + + local root_dir = vim.uv.fs_mkdtemp(vim.fs.dirname(helpers.tmpname()) .. '/nvim_XXXXXXXXXX') - local events = {} + local expected_events = 0 - local expected_events = 0 - local function wait_for_events() - assert(vim.wait(100, function() return #events == expected_events end), 'Timed out waiting for expected number of events. Current events seen so far: ' .. vim.inspect(events)) - end + local function wait_for_event() + expected_events = expected_events + 1 + exec_lua( + [[ + local expected_events = ... + assert( + vim.wait(3000, function() + return #_G.events == expected_events + end), + string.format( + 'Timed out waiting for expected event no. %d. Current events seen so far: %s', + expected_events, + vim.inspect(events) + ) + ) + ]], + expected_events + ) + end - local stop = vim._watch.watch(root_dir, {}, function(path, change_type) - table.insert(events, { path = path, change_type = change_type }) - end) + local unwatched_path = root_dir .. '/file.unwatched' + local watched_path = root_dir .. '/file' - -- Only BSD seems to need some extra time for the watch to be ready to respond to events - if vim.fn.has('bsd') then - vim.wait(50) - end + exec_lua( + [[ + local root_dir, watchfunc = ... - local watched_path = root_dir .. '/file' - local watched, err = io.open(watched_path, 'w') - assert(not err, err) + _G.events = {} - expected_events = expected_events + 1 - wait_for_events() + _G.stop_watch = vim._watch[watchfunc](root_dir, { + debounce = 100, + include_pattern = vim.lpeg.P(root_dir) * vim.lpeg.P("/file") ^ -1, + exclude_pattern = vim.lpeg.P(root_dir .. '/file.unwatched'), + }, function(path, change_type) + table.insert(_G.events, { path = path, change_type = change_type }) + end) + ]], + root_dir, + watchfunc + ) - watched:close() - os.remove(watched_path) + if watchfunc ~= 'watch' then + vim.uv.sleep(200) + end - expected_events = expected_events + 1 - wait_for_events() + touch(watched_path) + touch(unwatched_path) - stop() - -- No events should come through anymore + wait_for_event() - local watched_path = root_dir .. '/file' - local watched, err = io.open(watched_path, 'w') - assert(not err, err) + os.remove(watched_path) + os.remove(unwatched_path) - vim.wait(50) + wait_for_event() - watched:close() - os.remove(watched_path) + exec_lua [[_G.stop_watch()]] - vim.wait(50) + -- No events should come through anymore - return events - ]], - root_dir - ) + vim.uv.sleep(100) + touch(watched_path) + vim.uv.sleep(100) + os.remove(watched_path) + vim.uv.sleep(100) - local expected = { + eq({ { change_type = exec_lua([[return vim._watch.FileChangeType.Created]]), path = root_dir .. '/file', @@ -76,103 +117,11 @@ describe('vim._watch', function() change_type = exec_lua([[return vim._watch.FileChangeType.Deleted]]), path = root_dir .. '/file', }, - } - - -- kqueue only reports events on the watched path itself, so creating a file within a - -- watched directory results in a "rename" libuv event on the directory. - if is_os('bsd') then - expected = { - { - change_type = exec_lua([[return vim._watch.FileChangeType.Created]]), - path = root_dir, - }, - { - change_type = exec_lua([[return vim._watch.FileChangeType.Created]]), - path = root_dir, - }, - } - end - - eq(expected, result) + }, exec_lua [[return _G.events]]) end) - end) + end - describe('poll', function() - it('detects file changes', function() - skip(is_os('bsd'), "bsd only reports rename on folders if file inside change") - local root_dir = vim.uv.fs_mkdtemp(vim.fs.dirname(helpers.tmpname()) .. '/nvim_XXXXXXXXXX') - - local result = exec_lua( - [[ - local root_dir = ... - local lpeg = vim.lpeg - - local events = {} - - local debounce = 100 - local wait_ms = debounce + 200 - - local expected_events = 0 - local function wait_for_events() - assert(vim.wait(wait_ms, function() return #events == expected_events end), 'Timed out waiting for expected number of events. Current events seen so far: ' .. vim.inspect(events)) - end - - local incl = lpeg.P(root_dir) * lpeg.P("/file")^-1 - local excl = lpeg.P(root_dir..'/file.unwatched') - local stop = vim._watch.poll(root_dir, { - debounce = debounce, - include_pattern = incl, - exclude_pattern = excl, - }, function(path, change_type) - table.insert(events, { path = path, change_type = change_type }) - end) - - local watched_path = root_dir .. '/file' - local watched, err = io.open(watched_path, 'w') - assert(not err, err) - local unwatched_path = root_dir .. '/file.unwatched' - local unwatched, err = io.open(unwatched_path, 'w') - assert(not err, err) - - expected_events = expected_events + 1 - wait_for_events() - - watched:close() - os.remove(watched_path) - unwatched:close() - os.remove(unwatched_path) - - expected_events = expected_events + 1 - wait_for_events() - - stop() - -- No events should come through anymore - - local watched_path = root_dir .. '/file' - local watched, err = io.open(watched_path, 'w') - assert(not err, err) - - watched:close() - os.remove(watched_path) - - return events - ]], - root_dir - ) - - local created = exec_lua([[return vim._watch.FileChangeType.Created]]) - local deleted = exec_lua([[return vim._watch.FileChangeType.Deleted]]) - local expected = { - { - change_type = created, - path = root_dir .. "/file", - }, - { - change_type = deleted, - path = root_dir .. "/file", - } - } - eq(expected, result) - end) - end) + run('watch') + run('watchdirs') + run('fswatch') end) diff --git a/test/functional/lua/xdiff_spec.lua b/test/functional/lua/xdiff_spec.lua index 3121ac051f..c21309c2e4 100644 --- a/test/functional/lua/xdiff_spec.lua +++ b/test/functional/lua/xdiff_spec.lua @@ -11,7 +11,7 @@ describe('xdiff bindings', function() describe('can diff text', function() before_each(function() - exec_lua[[ + exec_lua [[ a1 = 'Hello\n' b1 = 'Helli\n' @@ -21,15 +21,14 @@ describe('xdiff bindings', function() end) it('with no callback', function() - eq( table.concat({ '@@ -1 +1 @@', '-Hello', '+Helli', - '' + '', }, '\n'), - exec_lua("return vim.diff(a1, b1)") + exec_lua('return vim.diff(a1, b1)') ) eq( @@ -41,11 +40,10 @@ describe('xdiff bindings', function() '-foo', '+bar', '+baz', - '' + '', }, '\n'), - exec_lua("return vim.diff(a2, b2)") + exec_lua('return vim.diff(a2, b2)') ) - end) it('with callback', function() @@ -53,43 +51,55 @@ describe('xdiff bindings', function() exp[#exp+1] = {sa, ca, sb, cb} end]]) - eq({{1, 1, 1, 1}}, exec_lua[[ + eq( + { { 1, 1, 1, 1 } }, + exec_lua [[ exp = {} assert(vim.diff(a1, b1, {on_hunk = on_hunk}) == nil) return exp - ]]) + ]] + ) - eq({{1, 1, 1, 1}, {3, 1, 3, 2}}, exec_lua[[ + eq( + { { 1, 1, 1, 1 }, { 3, 1, 3, 2 } }, + exec_lua [[ exp = {} assert(vim.diff(a2, b2, {on_hunk = on_hunk}) == nil) return exp - ]]) + ]] + ) -- gives higher precedence to on_hunk over result_type - eq({{1, 1, 1, 1}, {3, 1, 3, 2}}, exec_lua[[ + eq( + { { 1, 1, 1, 1 }, { 3, 1, 3, 2 } }, + exec_lua [[ exp = {} assert(vim.diff(a2, b2, {on_hunk = on_hunk, result_type='indices'}) == nil) return exp - ]]) + ]] + ) end) it('with error callback', function() - exec_lua[[ + exec_lua [[ on_hunk = function(sa, ca, sb, cb) error('ERROR1') end ]] - eq([[error running function on_hunk: [string "<nvim>"]:0: ERROR1]], - pcall_err(exec_lua, [[vim.diff(a1, b1, {on_hunk = on_hunk})]])) + eq( + [[error running function on_hunk: [string "<nvim>"]:0: ERROR1]], + pcall_err(exec_lua, [[vim.diff(a1, b1, {on_hunk = on_hunk})]]) + ) end) it('with hunk_lines', function() - eq({{1, 1, 1, 1}}, - exec_lua([[return vim.diff(a1, b1, {result_type = 'indices'})]])) + eq({ { 1, 1, 1, 1 } }, exec_lua([[return vim.diff(a1, b1, {result_type = 'indices'})]])) - eq({{1, 1, 1, 1}, {3, 1, 3, 2}}, - exec_lua([[return vim.diff(a2, b2, {result_type = 'indices'})]])) + eq( + { { 1, 1, 1, 1 }, { 3, 1, 3, 2 } }, + exec_lua([[return vim.diff(a2, b2, {result_type = 'indices'})]]) + ) end) it('can run different algorithms', function() @@ -101,7 +111,8 @@ describe('xdiff bindings', function() '.bar {', ' margin: 0;', '}', - ''}, '\n') + '', + }, '\n') local b = table.concat({ '.bar {', @@ -112,10 +123,12 @@ describe('xdiff bindings', function() ' margin: 0;', ' color: green;', '}', - ''}, '\n') + '', + }, '\n') eq( - table.concat({'@@ -1,4 +0,0 @@', + table.concat({ + '@@ -1,4 +0,0 @@', '-.foo1 {', '- margin: 0;', '-}', @@ -126,31 +139,37 @@ describe('xdiff bindings', function() '+ margin: 0;', '+ color: green;', '+}', - ''}, '\n'), - exec_lua([[ + '', + }, '\n'), + exec_lua( + [[ local args = {...} return vim.diff(args[1], args[2], { algorithm = 'patience' }) - ]], a, b)) + ]], + a, + b + ) + ) end) end) it('can handle bad args', function() - eq([[Expected at least 2 arguments]], - pcall_err(exec_lua, [[vim.diff('a')]])) - - eq([[bad argument #1 to 'diff' (expected string)]], - pcall_err(exec_lua, [[vim.diff(1, 2)]])) + eq([[Expected at least 2 arguments]], pcall_err(exec_lua, [[vim.diff('a')]])) - eq([[bad argument #3 to 'diff' (expected table)]], - pcall_err(exec_lua, [[vim.diff('a', 'b', true)]])) + eq([[bad argument #1 to 'diff' (expected string)]], pcall_err(exec_lua, [[vim.diff(1, 2)]])) - eq([[unexpected key: bad_key]], - pcall_err(exec_lua, [[vim.diff('a', 'b', { bad_key = true })]])) + eq( + [[bad argument #3 to 'diff' (expected table)]], + pcall_err(exec_lua, [[vim.diff('a', 'b', true)]]) + ) - eq([[on_hunk is not a function]], - pcall_err(exec_lua, [[vim.diff('a', 'b', { on_hunk = true })]])) + eq([[invalid key: bad_key]], pcall_err(exec_lua, [[vim.diff('a', 'b', { bad_key = true })]])) + eq( + [[on_hunk is not a function]], + pcall_err(exec_lua, [[vim.diff('a', 'b', { on_hunk = true })]]) + ) end) end) diff --git a/test/functional/options/autochdir_spec.lua b/test/functional/options/autochdir_spec.lua index c75a98f35b..11f71912a9 100644 --- a/test/functional/options/autochdir_spec.lua +++ b/test/functional/options/autochdir_spec.lua @@ -1,8 +1,7 @@ -local luv = require('luv') local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local eq = helpers.eq -local funcs = helpers.funcs +local fn = helpers.fn local command = helpers.command local mkdir = helpers.mkdir @@ -11,34 +10,34 @@ describe("'autochdir'", function() local targetdir = 'test/functional/fixtures' -- By default 'autochdir' is off, thus getcwd() returns the repo root. - clear(targetdir..'/tty-test.c') - local rootdir = funcs.getcwd() + clear(targetdir .. '/tty-test.c') + local rootdir = fn.getcwd() local expected = rootdir .. '/' .. targetdir -- With 'autochdir' on, we should get the directory of tty-test.c. - clear('--cmd', 'set autochdir', targetdir..'/tty-test.c') - eq(helpers.is_os('win') and expected:gsub('/', '\\') or expected, funcs.getcwd()) + clear('--cmd', 'set autochdir', targetdir .. '/tty-test.c') + eq(helpers.is_os('win') and expected:gsub('/', '\\') or expected, fn.getcwd()) end) - it('is not overwritten by getwinvar() call #17609',function() - local curdir = string.gsub(luv.cwd(), '\\', '/') - local dir_a = curdir..'/Xtest-functional-options-autochdir.dir_a' - local dir_b = curdir..'/Xtest-functional-options-autochdir.dir_b' + it('is not overwritten by getwinvar() call #17609', function() + local curdir = vim.uv.cwd():gsub('\\', '/') + local dir_a = curdir .. '/Xtest-functional-options-autochdir.dir_a' + local dir_b = curdir .. '/Xtest-functional-options-autochdir.dir_b' mkdir(dir_a) mkdir(dir_b) clear() command('set shellslash') command('set autochdir') - command('edit '..dir_a..'/file1') - eq(dir_a, funcs.getcwd()) - command('lcd '..dir_b) - eq(dir_b, funcs.getcwd()) + command('edit ' .. dir_a .. '/file1') + eq(dir_a, fn.getcwd()) + command('lcd ' .. dir_b) + eq(dir_b, fn.getcwd()) command('botright vnew ../file2') - eq(curdir, funcs.getcwd()) + eq(curdir, fn.getcwd()) command('wincmd w') - eq(dir_a, funcs.getcwd()) - funcs.getwinvar(2, 'foo') - eq(dir_a, funcs.getcwd()) + eq(dir_a, fn.getcwd()) + fn.getwinvar(2, 'foo') + eq(dir_a, fn.getcwd()) helpers.rmdir(dir_a) helpers.rmdir(dir_b) end) diff --git a/test/functional/options/chars_spec.lua b/test/functional/options/chars_spec.lua index a082204980..e9c20b5da9 100644 --- a/test/functional/options/chars_spec.lua +++ b/test/functional/options/chars_spec.lua @@ -1,11 +1,12 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local clear, command = helpers.clear, helpers.command +local pcall_err = helpers.pcall_err local eval = helpers.eval local eq = helpers.eq -local exc_exec = helpers.exc_exec local insert = helpers.insert local feed = helpers.feed +local api = helpers.api describe("'fillchars'", function() local screen @@ -16,91 +17,124 @@ describe("'fillchars'", function() screen:attach() end) - local function shouldfail(val,errval) - errval = errval or val - eq('Vim(set):E474: Invalid argument: fillchars='..errval, - exc_exec('set fillchars='..val)) - end - describe('"eob" flag', function() it("uses '~' by default", function() eq('', eval('&fillchars')) screen:expect([[ ^ | - ~ | - ~ | - ~ | + ~ |*3 | ]]) end) + it('supports whitespace', function() screen:expect([[ ^ | - ~ | - ~ | - ~ | + ~ |*3 | ]]) command('set fillchars=eob:\\ ') screen:expect([[ ^ | - | - | - | - | + |*4 ]]) end) + it('supports multibyte char', function() command('set fillchars=eob:ñ') screen:expect([[ ^ | - ñ | - ñ | - ñ | + ñ |*3 | ]]) end) + + it('supports composing multibyte char', function() + command('set fillchars=eob:å̲') + screen:expect([[ + ^ | + å̲ |*3 + | + ]]) + end) + it('handles invalid values', function() - shouldfail('eob:') -- empty string - shouldfail('eob:馬') -- doublewidth char - shouldfail('eob:å̲') -- composing chars - shouldfail('eob:xy') -- two ascii chars - shouldfail('eob:\255', 'eob:<ff>') -- invalid UTF-8 + eq( + 'Vim(set):E1511: Wrong number of characters for field "eob": fillchars=eob:', + pcall_err(command, 'set fillchars=eob:') -- empty string + ) + eq( + 'Vim(set):E1512: Wrong character width for field "eob": fillchars=eob:馬', + pcall_err(command, 'set fillchars=eob:馬') -- doublewidth char + ) + eq( + 'Vim(set):E1511: Wrong number of characters for field "eob": fillchars=eob:xy', + pcall_err(command, 'set fillchars=eob:xy') -- two ascii chars + ) + eq( + 'Vim(set):E1512: Wrong character width for field "eob": fillchars=eob:<ff>', + pcall_err(command, 'set fillchars=eob:\255') -- invalid UTF-8 + ) end) end) + + it('"diff" flag', function() + screen:try_resize(45, 8) + screen:set_default_attr_ids({ + [1] = { background = Screen.colors.Grey, foreground = Screen.colors.DarkBlue }, + [2] = { background = Screen.colors.LightCyan1, bold = true, foreground = Screen.colors.Blue1 }, + [3] = { background = Screen.colors.LightBlue }, + [4] = { reverse = true }, + [5] = { reverse = true, bold = true }, + }) + command('set fillchars=diff:…') + insert('a\nb\nc\nd\ne') + command('vnew') + insert('a\nd\ne\nf') + command('windo diffthis') + screen:expect([[ + {1: }a │{1: }a | + {1: }{2:……………………………………………………}│{1: }{3:b }| + {1: }{2:……………………………………………………}│{1: }{3:c }| + {1: }d │{1: }d | + {1: }e │{1: }^e | + {1: }{3:f }│{1: }{2:……………………………………………………}| + {4:[No Name] [+] }{5:[No Name] [+] }| + | + ]]) + end) + it('has global value', function() screen:try_resize(50, 5) - insert("foo\nbar") + insert('foo\nbar') command('set laststatus=0') command('1,2fold') command('vsplit') command('set fillchars=fold:x') screen:expect([[ ^+-- 2 lines: fooxxxxxxxx│+-- 2 lines: fooxxxxxxx| - ~ │~ | - ~ │~ | - ~ │~ | + ~ │~ |*3 | ]]) end) + it('has window-local value', function() screen:try_resize(50, 5) - insert("foo\nbar") + insert('foo\nbar') command('set laststatus=0') command('1,2fold') command('vsplit') command('setl fillchars=fold:x') screen:expect([[ ^+-- 2 lines: fooxxxxxxxx│+-- 2 lines: foo·······| - ~ │~ | - ~ │~ | - ~ │~ | + ~ │~ |*3 | ]]) end) + it('using :set clears window-local value', function() screen:try_resize(50, 5) - insert("foo\nbar") + insert('foo\nbar') command('set laststatus=0') command('setl fillchars=fold:x') command('1,2fold') @@ -108,9 +142,7 @@ describe("'fillchars'", function() command('set fillchars&') screen:expect([[ ^+-- 2 lines: foo········│+-- 2 lines: fooxxxxxxx| - ~ │~ | - ~ │~ | - ~ │~ | + ~ │~ |*3 | ]]) end) @@ -132,12 +164,11 @@ describe("'listchars'", function() command('set listchars=tab:<->') screen:expect([[ <------><------>^<------> │<------><------><------>| - ~ │~ | - ~ │~ | - ~ │~ | + ~ │~ |*3 | ]]) end) + it('has window-local value', function() feed('i<tab><tab><tab><esc>') command('set list laststatus=0') @@ -146,12 +177,11 @@ describe("'listchars'", function() command('setl listchars<') screen:expect([[ > > ^> │<------><------><------>| - ~ │~ | - ~ │~ | - ~ │~ | + ~ │~ |*3 | ]]) end) + it('using :set clears window-local value', function() feed('i<tab><tab><tab><esc>') command('set list laststatus=0') @@ -160,9 +190,31 @@ describe("'listchars'", function() command('set listchars=tab:>-,eol:$') screen:expect([[ >------->-------^>-------$│<------><------><------>| - ~ │~ | - ~ │~ | - ~ │~ | + ~ │~ |*3 + | + ]]) + end) + + it('supports composing chars', function() + screen:set_default_attr_ids { + [1] = { foreground = Screen.colors.Blue1, bold = true }, + } + feed('i<tab><tab><tab>x<esc>') + command('set list laststatus=0') + -- tricky: the tab value forms three separate one-cell chars, + -- thus it should be accepted despite being a mess. + command('set listchars=tab:d̞̄̃̒̉̎ò́̌̌̂̐l̞̀̄̆̌̚,eol:å̲') + screen:expect([[ + {1:d̞̄̃̒̉̎ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐l̞̀̄̆̌̚d̞̄̃̒̉̎ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐l̞̀̄̆̌̚d̞̄̃̒̉̎ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐l̞̀̄̆̌̚}^x{1:å̲} | + {1:~ }|*3 + | + ]]) + + api.nvim__invalidate_glyph_cache() + screen:_reset() + screen:expect([[ + {1:d̞̄̃̒̉̎ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐l̞̀̄̆̌̚d̞̄̃̒̉̎ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐l̞̀̄̆̌̚d̞̄̃̒̉̎ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐l̞̀̄̆̌̚}^x{1:å̲} | + {1:~ }|*3 | ]]) end) diff --git a/test/functional/options/cursorbind_spec.lua b/test/functional/options/cursorbind_spec.lua index 498206936a..cafdc83de2 100644 --- a/test/functional/options/cursorbind_spec.lua +++ b/test/functional/options/cursorbind_spec.lua @@ -12,10 +12,10 @@ describe("'cursorbind'", function() it("behaves consistently whether 'cursorline' is set or not vim-patch:8.2.4795", function() local screen = Screen.new(60, 8) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [2] = {bold = true, reverse = true}, -- StatusLine - [3] = {reverse = true}, -- StatusLineNC - [4] = {background = Screen.colors.Grey90}, -- CursorLine, CursorColumn + [1] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [2] = { bold = true, reverse = true }, -- StatusLine + [3] = { reverse = true }, -- StatusLineNC + [4] = { background = Screen.colors.Grey90 }, -- CursorLine, CursorColumn }) screen:attach() exec([[ @@ -32,10 +32,7 @@ describe("'cursorbind'", function() feed('20l') screen:expect([[ a bb cc dd ee ff gg │aa bb cc dd ee ff gg^ hh ii jj kk ll mm | - {4: }│ {4: } | - {4: }│ {4: } | - {4: }│ {4: } | - {4: }│ {4: } | + {4: }│ {4: } |*4 {1:~ }│{1:~ }| {3:[No Name] [+] }{2:[No Name] [+] }| | @@ -43,10 +40,7 @@ describe("'cursorbind'", function() feed('10l') screen:expect([[ hh ii jj kk ll mm n│aa bb cc dd ee ff gg hh ii jj ^kk ll mm | - {4: } │ {4: } | - {4: } │ {4: } | - {4: } │ {4: } | - {4: } │ {4: } | + {4: } │ {4: } |*4 {1:~ }│{1:~ }| {3:[No Name] [+] }{2:[No Name] [+] }| | @@ -56,10 +50,7 @@ describe("'cursorbind'", function() feed('20l') screen:expect([[ {4:a bb cc dd ee ff gg }│{4:aa bb cc dd ee ff gg^ hh ii jj kk ll mm }| - {4: }│ {4: } | - {4: }│ {4: } | - {4: }│ {4: } | - {4: }│ {4: } | + {4: }│ {4: } |*4 {1:~ }│{1:~ }| {3:[No Name] [+] }{2:[No Name] [+] }| | @@ -67,10 +58,7 @@ describe("'cursorbind'", function() feed('10l') screen:expect([[ {4: hh ii jj kk ll mm n}│{4:aa bb cc dd ee ff gg hh ii jj ^kk ll mm }| - {4: } │ {4: } | - {4: } │ {4: } | - {4: } │ {4: } | - {4: } │ {4: } | + {4: } │ {4: } |*4 {1:~ }│{1:~ }| {3:[No Name] [+] }{2:[No Name] [+] }| | @@ -80,10 +68,7 @@ describe("'cursorbind'", function() feed('40l') screen:expect([[ kk ll mm nn oo pp qq│ bb cc dd ee ff gg hh ii jj kk ll mm n^n| - │ | - │ | - │ | - │ | + │ |*4 {1:~ }│{1:~ }| {3:[No Name] [+] }{2:[No Name] [+] }| | diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua index 7858b626de..d27fa375ee 100644 --- a/test/functional/options/defaults_spec.lua +++ b/test/functional/options/defaults_spec.lua @@ -4,7 +4,7 @@ local Screen = require('test.functional.ui.screen') local assert_alive = helpers.assert_alive local assert_log = helpers.assert_log -local meths = helpers.meths +local api = helpers.api local command = helpers.command local clear = helpers.clear local exc_exec = helpers.exc_exec @@ -12,13 +12,13 @@ local exec_lua = helpers.exec_lua local eval = helpers.eval local eq = helpers.eq local ok = helpers.ok -local funcs = helpers.funcs +local fn = helpers.fn local insert = helpers.insert local neq = helpers.neq local mkdir = helpers.mkdir local rmdir = helpers.rmdir local alter_slashes = helpers.alter_slashes -local tbl_contains = helpers.tbl_contains +local tbl_contains = vim.tbl_contains local expect_exit = helpers.expect_exit local is_os = helpers.is_os @@ -32,51 +32,39 @@ describe('startup defaults', function() command('filetype') screen:expect([[ ^ | - ~ | - ~ | - ]]..expected - ) + ~ |*2 + ]] .. expected) end it('all ON after `-u NORC`', function() clear('-u', 'NORC') - expect_filetype( - 'filetype detection:ON plugin:ON indent:ON |') + expect_filetype('filetype detection:ON plugin:ON indent:ON |') end) it('all ON after `:syntax …` #7765', function() clear('-u', 'NORC', '--cmd', 'syntax on') - expect_filetype( - 'filetype detection:ON plugin:ON indent:ON |') + expect_filetype('filetype detection:ON plugin:ON indent:ON |') clear('-u', 'NORC', '--cmd', 'syntax off') - expect_filetype( - 'filetype detection:ON plugin:ON indent:ON |') + expect_filetype('filetype detection:ON plugin:ON indent:ON |') end) it('all OFF after `-u NONE`', function() clear('-u', 'NONE') - expect_filetype( - 'filetype detection:OFF plugin:OFF indent:OFF |') + expect_filetype('filetype detection:OFF plugin:OFF indent:OFF |') end) it('explicit OFF stays OFF', function() - clear('-u', 'NORC', '--cmd', - 'syntax off | filetype off | filetype plugin indent off') - expect_filetype( - 'filetype detection:OFF plugin:OFF indent:OFF |') + clear('-u', 'NORC', '--cmd', 'syntax off | filetype off | filetype plugin indent off') + expect_filetype('filetype detection:OFF plugin:OFF indent:OFF |') clear('-u', 'NORC', '--cmd', 'syntax off | filetype plugin indent off') - expect_filetype( - 'filetype detection:ON plugin:OFF indent:OFF |') + expect_filetype('filetype detection:ON plugin:OFF indent:OFF |') clear('-u', 'NORC', '--cmd', 'filetype indent off') - expect_filetype( - 'filetype detection:ON plugin:ON indent:OFF |') + expect_filetype('filetype detection:ON plugin:ON indent:OFF |') clear('-u', 'NORC', '--cmd', 'syntax off | filetype off') - expect_filetype( - 'filetype detection:OFF plugin:(on) indent:(on) |') + expect_filetype('filetype detection:OFF plugin:(on) indent:(on) |') -- Swap the order. clear('-u', 'NORC', '--cmd', 'filetype off | syntax off') - expect_filetype( - 'filetype detection:OFF plugin:(on) indent:(on) |') + expect_filetype('filetype detection:OFF plugin:(on) indent:(on) |') end) it('all ON after early `:filetype … on`', function() @@ -84,26 +72,20 @@ describe('startup defaults', function() -- Only an explicit `:filetype … off` sets OFF. clear('-u', 'NORC', '--cmd', 'filetype on') - expect_filetype( - 'filetype detection:ON plugin:ON indent:ON |') + expect_filetype('filetype detection:ON plugin:ON indent:ON |') clear('-u', 'NORC', '--cmd', 'filetype plugin on') - expect_filetype( - 'filetype detection:ON plugin:ON indent:ON |') + expect_filetype('filetype detection:ON plugin:ON indent:ON |') clear('-u', 'NORC', '--cmd', 'filetype indent on') - expect_filetype( - 'filetype detection:ON plugin:ON indent:ON |') + expect_filetype('filetype detection:ON plugin:ON indent:ON |') end) it('late `:filetype … off` stays OFF', function() clear('-u', 'NORC', '-c', 'filetype off') - expect_filetype( - 'filetype detection:OFF plugin:(on) indent:(on) |') + expect_filetype('filetype detection:OFF plugin:(on) indent:(on) |') clear('-u', 'NORC', '-c', 'filetype plugin off') - expect_filetype( - 'filetype detection:ON plugin:OFF indent:ON |') + expect_filetype('filetype detection:ON plugin:OFF indent:ON |') clear('-u', 'NORC', '-c', 'filetype indent off') - expect_filetype( - 'filetype detection:ON plugin:ON indent:OFF |') + expect_filetype('filetype detection:ON plugin:ON indent:OFF |') end) end) @@ -167,7 +149,7 @@ describe('startup defaults', function() ]]) -- change "vert" character to single-cell - funcs.setcellwidths({{0x2502, 0x2502, 1}}) + fn.setcellwidths({ { 0x2502, 0x2502, 1 } }) screen:expect([[ 1 │1 | ^+-- 2 lines: 2----------│+-- 2 lines: 2---------| @@ -177,7 +159,7 @@ describe('startup defaults', function() ]]) -- change "vert" character to double-cell - funcs.setcellwidths({{0x2502, 0x2502, 2}}) + fn.setcellwidths({ { 0x2502, 0x2502, 2 } }) screen:expect([[ 1 |1 | ^+-- 2 lines: 2----------|+-- 2 lines: 2---------| @@ -199,18 +181,22 @@ describe('startup defaults', function() end) it("'shadafile' ('viminfofile')", function() - local env = {XDG_DATA_HOME='Xtest-userdata', XDG_STATE_HOME='Xtest-userstate', XDG_CONFIG_HOME='Xtest-userconfig'} + local env = { + XDG_DATA_HOME = 'Xtest-userdata', + XDG_STATE_HOME = 'Xtest-userstate', + XDG_CONFIG_HOME = 'Xtest-userconfig', + } finally(function() - command('set shadafile=NONE') -- Avoid writing shada file on exit + command('set shadafile=NONE') -- Avoid writing shada file on exit rmdir('Xtest-userstate') os.remove('Xtest-foo') end) - clear{args={}, args_rm={'-i'}, env=env} + clear { args = {}, args_rm = { '-i' }, env = env } -- Default 'shadafile' is empty. -- This means use the default location. :help shada-file-name - eq('', meths.get_option_value('shadafile', {})) - eq('', meths.get_option_value('viminfofile', {})) + eq('', api.nvim_get_option_value('shadafile', {})) + eq('', api.nvim_get_option_value('viminfofile', {})) -- Handles viminfo/viminfofile as alias for shada/shadafile. eq('\n shadafile=', eval('execute("set shadafile?")')) eq('\n shadafile=', eval('execute("set viminfofile?")')) @@ -223,22 +209,22 @@ describe('startup defaults', function() local f = eval('fnamemodify(@%,":p")') assert(string.len(f) > 3) expect_exit(command, 'qall') - clear{args={}, args_rm={'-i'}, env=env} + clear { args = {}, args_rm = { '-i' }, env = env } eq({ f }, eval('v:oldfiles')) end) it("'packpath'", function() - clear{ - args_rm={'runtimepath'}, + clear { + args_rm = { 'runtimepath' }, } -- Defaults to &runtimepath. - eq(meths.get_option_value('runtimepath', {}), meths.get_option_value('packpath', {})) + eq(api.nvim_get_option_value('runtimepath', {}), api.nvim_get_option_value('packpath', {})) -- Does not follow modifications to runtimepath. - meths.command('set runtimepath+=foo') - neq(meths.get_option_value('runtimepath', {}), meths.get_option_value('packpath', {})) - meths.command('set packpath+=foo') - eq(meths.get_option_value('runtimepath', {}), meths.get_option_value('packpath', {})) + command('set runtimepath+=foo') + neq(api.nvim_get_option_value('runtimepath', {}), api.nvim_get_option_value('packpath', {})) + command('set packpath+=foo') + eq(api.nvim_get_option_value('runtimepath', {}), api.nvim_get_option_value('packpath', {})) end) it('v:progpath is set to the absolute path', function() @@ -248,33 +234,37 @@ describe('startup defaults', function() describe('$NVIM_LOG_FILE', function() local xdgdir = 'Xtest-startup-xdg-logpath' - local xdgstatedir = is_os('win') and xdgdir..'/nvim-data' or xdgdir..'/nvim' + local xdgstatedir = is_os('win') and xdgdir .. '/nvim-data' or xdgdir .. '/nvim' after_each(function() os.remove('Xtest-logpath') rmdir(xdgdir) end) it('is used if expansion succeeds', function() - clear({env={ - NVIM_LOG_FILE='Xtest-logpath', - }}) + clear({ env = { + NVIM_LOG_FILE = 'Xtest-logpath', + } }) eq('Xtest-logpath', eval('$NVIM_LOG_FILE')) end) it('defaults to stdpath("log")/log if empty', function() eq(true, mkdir(xdgdir) and mkdir(xdgstatedir)) - clear({env={ - XDG_STATE_HOME=xdgdir, - NVIM_LOG_FILE='', -- Empty is invalid. - }}) - eq(xdgstatedir..'/log', string.gsub(eval('$NVIM_LOG_FILE'), '\\', '/')) + clear({ + env = { + XDG_STATE_HOME = xdgdir, + NVIM_LOG_FILE = '', -- Empty is invalid. + }, + }) + eq(xdgstatedir .. '/log', string.gsub(eval('$NVIM_LOG_FILE'), '\\', '/')) end) it('defaults to stdpath("log")/log if invalid', function() eq(true, mkdir(xdgdir) and mkdir(xdgstatedir)) - clear({env={ - XDG_STATE_HOME=xdgdir, - NVIM_LOG_FILE='.', -- Any directory is invalid. - }}) - eq(xdgstatedir..'/log', string.gsub(eval('$NVIM_LOG_FILE'), '\\', '/')) + clear({ + env = { + XDG_STATE_HOME = xdgdir, + NVIM_LOG_FILE = '.', -- Any directory is invalid. + }, + }) + eq(xdgstatedir .. '/log', string.gsub(eval('$NVIM_LOG_FILE'), '\\', '/')) end) end) end) @@ -291,11 +281,12 @@ describe('XDG defaults', function() clear() local rtp = eval('split(&runtimepath, ",")') local rv = {} - local expected = (is_os('win') - and { [[\nvim-data\site]], [[\nvim-data\site\after]], } - or { '/nvim/site', '/nvim/site/after', }) + local expected = ( + is_os('win') and { [[\nvim-data\site]], [[\nvim-data\site\after]] } + or { '/nvim/site', '/nvim/site/after' } + ) - for _,v in ipairs(rtp) do + for _, v in ipairs(rtp) do local m = string.match(v, [=[[/\]nvim[^/\]*[/\]site.*$]=]) if m and not tbl_contains(rv, m) then table.insert(rv, m) @@ -306,28 +297,30 @@ describe('XDG defaults', function() describe('with empty/broken environment', function() it('sets correct defaults', function() - clear({env={ - XDG_CONFIG_HOME=nil, - XDG_DATA_HOME=nil, - XDG_CACHE_HOME=nil, - XDG_STATE_HOME=nil, - XDG_RUNTIME_DIR=nil, - XDG_CONFIG_DIRS=nil, - XDG_DATA_DIRS=nil, - LOCALAPPDATA=nil, - HOMEPATH=nil, - HOMEDRIVE=nil, - HOME=nil, - TEMP=nil, - VIMRUNTIME=nil, - USER=nil, - }}) - - eq('.', meths.get_option_value('backupdir', {})) - eq('.', meths.get_option_value('viewdir', {})) - eq('.', meths.get_option_value('directory', {})) - eq('.', meths.get_option_value('undodir', {})) - ok((funcs.tempname()):len() > 4) + clear({ + env = { + XDG_CONFIG_HOME = nil, + XDG_DATA_HOME = nil, + XDG_CACHE_HOME = nil, + XDG_STATE_HOME = nil, + XDG_RUNTIME_DIR = nil, + XDG_CONFIG_DIRS = nil, + XDG_DATA_DIRS = nil, + LOCALAPPDATA = nil, + HOMEPATH = nil, + HOMEDRIVE = nil, + HOME = nil, + TEMP = nil, + VIMRUNTIME = nil, + USER = nil, + }, + }) + + eq('.', api.nvim_get_option_value('backupdir', {})) + eq('.', api.nvim_get_option_value('viewdir', {})) + eq('.', api.nvim_get_option_value('directory', {})) + eq('.', api.nvim_get_option_value('undodir', {})) + ok((fn.tempname()):len() > 4) end) end) @@ -335,7 +328,7 @@ describe('XDG defaults', function() local vimruntime = eval('$VIMRUNTIME') -- libdir is hard to calculate reliably across various ci platforms -- local libdir = string.gsub(vimruntime, "share/nvim/runtime$", "lib/nvim") - local libdir = meths._get_lib_dir() + local libdir = api.nvim__get_lib_dir() return vimruntime, libdir end @@ -347,20 +340,21 @@ describe('XDG defaults', function() describe('with too long XDG variables', function() before_each(function() clear({ - args_rm={'runtimepath'}, - env={ - NVIM_LOG_FILE=testlog, - XDG_CONFIG_HOME=(root_path .. ('/x'):rep(4096)), - XDG_CONFIG_DIRS=(root_path .. ('/a'):rep(2048) - .. env_sep.. root_path .. ('/b'):rep(2048) - .. (env_sep .. root_path .. '/c'):rep(512)), - XDG_DATA_HOME=(root_path .. ('/X'):rep(4096)), - XDG_RUNTIME_DIR=(root_path .. ('/X'):rep(4096)), - XDG_STATE_HOME=(root_path .. ('/X'):rep(4096)), - XDG_DATA_DIRS=(root_path .. ('/A'):rep(2048) - .. env_sep .. root_path .. ('/B'):rep(2048) - .. (env_sep .. root_path .. '/C'):rep(512)), - }}) + args_rm = { 'runtimepath' }, + env = { + NVIM_LOG_FILE = testlog, + XDG_CONFIG_HOME = (root_path .. ('/x'):rep(4096)), + XDG_CONFIG_DIRS = (root_path .. ('/a'):rep(2048) .. env_sep .. root_path .. ('/b'):rep( + 2048 + ) .. (env_sep .. root_path .. '/c'):rep(512)), + XDG_DATA_HOME = (root_path .. ('/X'):rep(4096)), + XDG_RUNTIME_DIR = (root_path .. ('/X'):rep(4096)), + XDG_STATE_HOME = (root_path .. ('/X'):rep(4096)), + XDG_DATA_DIRS = (root_path .. ('/A'):rep(2048) .. env_sep .. root_path .. ('/B'):rep( + 2048 + ) .. (env_sep .. root_path .. '/C'):rep(512)), + }, + }) end) it('are correctly set', function() @@ -370,209 +364,506 @@ describe('XDG defaults', function() local vimruntime, libdir = vimruntime_and_libdir() - eq(((root_path .. ('/x'):rep(4096) .. '/nvim' - .. ',' .. root_path .. ('/a'):rep(2048) .. '/nvim' - .. ',' .. root_path .. ('/b'):rep(2048) .. '/nvim' - .. (',' .. root_path .. '/c/nvim'):rep(512) - .. ',' .. root_path .. ('/X'):rep(4096) .. '/' .. data_dir .. '/site' - .. ',' .. root_path .. ('/A'):rep(2048) .. '/nvim/site' - .. ',' .. root_path .. ('/B'):rep(2048) .. '/nvim/site' - .. (',' .. root_path .. '/C/nvim/site'):rep(512) - .. ',' .. vimruntime - .. ',' .. libdir - .. (',' .. root_path .. '/C/nvim/site/after'):rep(512) - .. ',' .. root_path .. ('/B'):rep(2048) .. '/nvim/site/after' - .. ',' .. root_path .. ('/A'):rep(2048) .. '/nvim/site/after' - .. ',' .. root_path .. ('/X'):rep(4096) .. '/' .. data_dir .. '/site/after' - .. (',' .. root_path .. '/c/nvim/after'):rep(512) - .. ',' .. root_path .. ('/b'):rep(2048) .. '/nvim/after' - .. ',' .. root_path .. ('/a'):rep(2048) .. '/nvim/after' - .. ',' .. root_path .. ('/x'):rep(4096) .. '/nvim/after' - ):gsub('\\', '/')), (meths.get_option_value('runtimepath', {})):gsub('\\', '/')) - meths.command('set runtimepath&') - meths.command('set backupdir&') - meths.command('set directory&') - meths.command('set undodir&') - meths.command('set viewdir&') - eq(((root_path .. ('/x'):rep(4096) .. '/nvim' - .. ',' .. root_path .. ('/a'):rep(2048) .. '/nvim' - .. ',' .. root_path .. ('/b'):rep(2048) .. '/nvim' - .. (',' .. root_path .. '/c/nvim'):rep(512) - .. ',' .. root_path .. ('/X'):rep(4096) .. '/' .. data_dir .. '/site' - .. ',' .. root_path .. ('/A'):rep(2048) .. '/nvim/site' - .. ',' .. root_path .. ('/B'):rep(2048) .. '/nvim/site' - .. (',' .. root_path .. '/C/nvim/site'):rep(512) - .. ',' .. vimruntime - .. ',' .. libdir - .. (',' .. root_path .. '/C/nvim/site/after'):rep(512) - .. ',' .. root_path .. ('/B'):rep(2048) .. '/nvim/site/after' - .. ',' .. root_path .. ('/A'):rep(2048) .. '/nvim/site/after' - .. ',' .. root_path .. ('/X'):rep(4096) .. '/' .. data_dir .. '/site/after' - .. (',' .. root_path .. '/c/nvim/after'):rep(512) - .. ',' .. root_path .. ('/b'):rep(2048) .. '/nvim/after' - .. ',' .. root_path .. ('/a'):rep(2048) .. '/nvim/after' - .. ',' .. root_path .. ('/x'):rep(4096) .. '/nvim/after' - ):gsub('\\', '/')), (meths.get_option_value('runtimepath', {})):gsub('\\', '/')) - eq('.,' .. root_path .. ('/X'):rep(4096).. '/' .. state_dir .. '/backup//', - (meths.get_option_value('backupdir', {}):gsub('\\', '/'))) - eq(root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/swap//', - (meths.get_option_value('directory', {})):gsub('\\', '/')) - eq(root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/undo//', - (meths.get_option_value('undodir', {})):gsub('\\', '/')) - eq(root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/view//', - (meths.get_option_value('viewdir', {})):gsub('\\', '/')) + eq( + ( + ( + root_path + .. ('/x'):rep(4096) + .. '/nvim' + .. ',' + .. root_path + .. ('/a'):rep(2048) + .. '/nvim' + .. ',' + .. root_path + .. ('/b'):rep(2048) + .. '/nvim' + .. (',' .. root_path .. '/c/nvim'):rep(512) + .. ',' + .. root_path + .. ('/X'):rep(4096) + .. '/' + .. data_dir + .. '/site' + .. ',' + .. root_path + .. ('/A'):rep(2048) + .. '/nvim/site' + .. ',' + .. root_path + .. ('/B'):rep(2048) + .. '/nvim/site' + .. (',' .. root_path .. '/C/nvim/site'):rep(512) + .. ',' + .. vimruntime + .. ',' + .. libdir + .. (',' .. root_path .. '/C/nvim/site/after'):rep(512) + .. ',' + .. root_path + .. ('/B'):rep(2048) + .. '/nvim/site/after' + .. ',' + .. root_path + .. ('/A'):rep(2048) + .. '/nvim/site/after' + .. ',' + .. root_path + .. ('/X'):rep(4096) + .. '/' + .. data_dir + .. '/site/after' + .. (',' .. root_path .. '/c/nvim/after'):rep(512) + .. ',' + .. root_path + .. ('/b'):rep(2048) + .. '/nvim/after' + .. ',' + .. root_path + .. ('/a'):rep(2048) + .. '/nvim/after' + .. ',' + .. root_path + .. ('/x'):rep(4096) + .. '/nvim/after' + ):gsub('\\', '/') + ), + (api.nvim_get_option_value('runtimepath', {})):gsub('\\', '/') + ) + command('set runtimepath&') + command('set backupdir&') + command('set directory&') + command('set undodir&') + command('set viewdir&') + eq( + ( + ( + root_path + .. ('/x'):rep(4096) + .. '/nvim' + .. ',' + .. root_path + .. ('/a'):rep(2048) + .. '/nvim' + .. ',' + .. root_path + .. ('/b'):rep(2048) + .. '/nvim' + .. (',' .. root_path .. '/c/nvim'):rep(512) + .. ',' + .. root_path + .. ('/X'):rep(4096) + .. '/' + .. data_dir + .. '/site' + .. ',' + .. root_path + .. ('/A'):rep(2048) + .. '/nvim/site' + .. ',' + .. root_path + .. ('/B'):rep(2048) + .. '/nvim/site' + .. (',' .. root_path .. '/C/nvim/site'):rep(512) + .. ',' + .. vimruntime + .. ',' + .. libdir + .. (',' .. root_path .. '/C/nvim/site/after'):rep(512) + .. ',' + .. root_path + .. ('/B'):rep(2048) + .. '/nvim/site/after' + .. ',' + .. root_path + .. ('/A'):rep(2048) + .. '/nvim/site/after' + .. ',' + .. root_path + .. ('/X'):rep(4096) + .. '/' + .. data_dir + .. '/site/after' + .. (',' .. root_path .. '/c/nvim/after'):rep(512) + .. ',' + .. root_path + .. ('/b'):rep(2048) + .. '/nvim/after' + .. ',' + .. root_path + .. ('/a'):rep(2048) + .. '/nvim/after' + .. ',' + .. root_path + .. ('/x'):rep(4096) + .. '/nvim/after' + ):gsub('\\', '/') + ), + (api.nvim_get_option_value('runtimepath', {})):gsub('\\', '/') + ) + eq( + '.,' .. root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/backup//', + (api.nvim_get_option_value('backupdir', {}):gsub('\\', '/')) + ) + eq( + root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/swap//', + (api.nvim_get_option_value('directory', {})):gsub('\\', '/') + ) + eq( + root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/undo//', + (api.nvim_get_option_value('undodir', {})):gsub('\\', '/') + ) + eq( + root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/view//', + (api.nvim_get_option_value('viewdir', {})):gsub('\\', '/') + ) end) end) describe('with XDG variables that can be expanded', function() before_each(function() clear({ - args_rm={'runtimepath'}, - env={ - NVIM_LOG_FILE=testlog, - XDG_CONFIG_HOME='$XDG_DATA_HOME', - XDG_CONFIG_DIRS='$XDG_DATA_DIRS', - XDG_DATA_HOME='$XDG_CONFIG_HOME', - XDG_RUNTIME_DIR='$XDG_RUNTIME_DIR', - XDG_STATE_HOME='$XDG_CONFIG_HOME', - XDG_DATA_DIRS='$XDG_CONFIG_DIRS', - } + args_rm = { 'runtimepath' }, + env = { + NVIM_LOG_FILE = testlog, + XDG_CONFIG_HOME = '$XDG_DATA_HOME', + XDG_CONFIG_DIRS = '$XDG_DATA_DIRS', + XDG_DATA_HOME = '$XDG_CONFIG_HOME', + XDG_RUNTIME_DIR = '$XDG_RUNTIME_DIR', + XDG_STATE_HOME = '$XDG_CONFIG_HOME', + XDG_DATA_DIRS = '$XDG_CONFIG_DIRS', + }, }) end) after_each(function() - command('set shadafile=NONE') -- Avoid writing shada file on exit + command('set shadafile=NONE') -- Avoid writing shada file on exit end) it('are not expanded', function() if not is_os('win') then - assert_log('Failed to start server: no such file or directory: %$XDG_RUNTIME_DIR%/', testlog, 10) + assert_log( + 'Failed to start server: no such file or directory: %$XDG_RUNTIME_DIR%/', + testlog, + 10 + ) end local vimruntime, libdir = vimruntime_and_libdir() - eq((('$XDG_DATA_HOME/nvim' - .. ',$XDG_DATA_DIRS/nvim' - .. ',$XDG_CONFIG_HOME/' .. data_dir .. '/site' - .. ',$XDG_CONFIG_DIRS/nvim/site' - .. ',' .. vimruntime - .. ',' .. libdir - .. ',$XDG_CONFIG_DIRS/nvim/site/after' - .. ',$XDG_CONFIG_HOME/' .. data_dir .. '/site/after' - .. ',$XDG_DATA_DIRS/nvim/after' - .. ',$XDG_DATA_HOME/nvim/after' - ):gsub('\\', '/')), (meths.get_option_value('runtimepath', {})):gsub('\\', '/')) - meths.command('set runtimepath&') - meths.command('set backupdir&') - meths.command('set directory&') - meths.command('set undodir&') - meths.command('set viewdir&') - eq((('$XDG_DATA_HOME/nvim' - .. ',$XDG_DATA_DIRS/nvim' - .. ',$XDG_CONFIG_HOME/' .. data_dir .. '/site' - .. ',$XDG_CONFIG_DIRS/nvim/site' - .. ',' .. vimruntime - .. ',' .. libdir - .. ',$XDG_CONFIG_DIRS/nvim/site/after' - .. ',$XDG_CONFIG_HOME/' .. data_dir .. '/site/after' - .. ',$XDG_DATA_DIRS/nvim/after' - .. ',$XDG_DATA_HOME/nvim/after' - ):gsub('\\', '/')), (meths.get_option_value('runtimepath', {})):gsub('\\', '/')) - eq(('.,$XDG_CONFIG_HOME/' .. state_dir .. '/backup//'), - meths.get_option_value('backupdir', {}):gsub('\\', '/')) - eq(('$XDG_CONFIG_HOME/' .. state_dir .. '/swap//'), - meths.get_option_value('directory', {}):gsub('\\', '/')) - eq(('$XDG_CONFIG_HOME/' .. state_dir .. '/undo//'), - meths.get_option_value('undodir', {}):gsub('\\', '/')) - eq(('$XDG_CONFIG_HOME/' .. state_dir .. '/view//'), - meths.get_option_value('viewdir', {}):gsub('\\', '/')) - meths.command('set all&') - eq(('$XDG_DATA_HOME/nvim' + eq( + ( + ( + '$XDG_DATA_HOME/nvim' + .. ',$XDG_DATA_DIRS/nvim' + .. ',$XDG_CONFIG_HOME/' + .. data_dir + .. '/site' + .. ',$XDG_CONFIG_DIRS/nvim/site' + .. ',' + .. vimruntime + .. ',' + .. libdir + .. ',$XDG_CONFIG_DIRS/nvim/site/after' + .. ',$XDG_CONFIG_HOME/' + .. data_dir + .. '/site/after' + .. ',$XDG_DATA_DIRS/nvim/after' + .. ',$XDG_DATA_HOME/nvim/after' + ):gsub('\\', '/') + ), + (api.nvim_get_option_value('runtimepath', {})):gsub('\\', '/') + ) + command('set runtimepath&') + command('set backupdir&') + command('set directory&') + command('set undodir&') + command('set viewdir&') + eq( + ( + ( + '$XDG_DATA_HOME/nvim' + .. ',$XDG_DATA_DIRS/nvim' + .. ',$XDG_CONFIG_HOME/' + .. data_dir + .. '/site' + .. ',$XDG_CONFIG_DIRS/nvim/site' + .. ',' + .. vimruntime + .. ',' + .. libdir + .. ',$XDG_CONFIG_DIRS/nvim/site/after' + .. ',$XDG_CONFIG_HOME/' + .. data_dir + .. '/site/after' + .. ',$XDG_DATA_DIRS/nvim/after' + .. ',$XDG_DATA_HOME/nvim/after' + ):gsub('\\', '/') + ), + (api.nvim_get_option_value('runtimepath', {})):gsub('\\', '/') + ) + eq( + ('.,$XDG_CONFIG_HOME/' .. state_dir .. '/backup//'), + api.nvim_get_option_value('backupdir', {}):gsub('\\', '/') + ) + eq( + ('$XDG_CONFIG_HOME/' .. state_dir .. '/swap//'), + api.nvim_get_option_value('directory', {}):gsub('\\', '/') + ) + eq( + ('$XDG_CONFIG_HOME/' .. state_dir .. '/undo//'), + api.nvim_get_option_value('undodir', {}):gsub('\\', '/') + ) + eq( + ('$XDG_CONFIG_HOME/' .. state_dir .. '/view//'), + api.nvim_get_option_value('viewdir', {}):gsub('\\', '/') + ) + command('set all&') + eq( + ( + '$XDG_DATA_HOME/nvim' .. ',$XDG_DATA_DIRS/nvim' - .. ',$XDG_CONFIG_HOME/' .. data_dir .. '/site' + .. ',$XDG_CONFIG_HOME/' + .. data_dir + .. '/site' .. ',$XDG_CONFIG_DIRS/nvim/site' - .. ',' .. vimruntime - .. ',' .. libdir + .. ',' + .. vimruntime + .. ',' + .. libdir .. ',$XDG_CONFIG_DIRS/nvim/site/after' - .. ',$XDG_CONFIG_HOME/' .. data_dir .. '/site/after' + .. ',$XDG_CONFIG_HOME/' + .. data_dir + .. '/site/after' .. ',$XDG_DATA_DIRS/nvim/after' .. ',$XDG_DATA_HOME/nvim/after' - ):gsub('\\', '/'), (meths.get_option_value('runtimepath', {})):gsub('\\', '/')) - eq(('.,$XDG_CONFIG_HOME/' .. state_dir .. '/backup//'), - meths.get_option_value('backupdir', {}):gsub('\\', '/')) - eq(('$XDG_CONFIG_HOME/' .. state_dir .. '/swap//'), - meths.get_option_value('directory', {}):gsub('\\', '/')) - eq(('$XDG_CONFIG_HOME/' .. state_dir .. '/undo//'), - meths.get_option_value('undodir', {}):gsub('\\', '/')) - eq(('$XDG_CONFIG_HOME/' .. state_dir .. '/view//'), - meths.get_option_value('viewdir', {}):gsub('\\', '/')) - eq(nil, (funcs.tempname()):match('XDG_RUNTIME_DIR')) + ):gsub('\\', '/'), + (api.nvim_get_option_value('runtimepath', {})):gsub('\\', '/') + ) + eq( + ('.,$XDG_CONFIG_HOME/' .. state_dir .. '/backup//'), + api.nvim_get_option_value('backupdir', {}):gsub('\\', '/') + ) + eq( + ('$XDG_CONFIG_HOME/' .. state_dir .. '/swap//'), + api.nvim_get_option_value('directory', {}):gsub('\\', '/') + ) + eq( + ('$XDG_CONFIG_HOME/' .. state_dir .. '/undo//'), + api.nvim_get_option_value('undodir', {}):gsub('\\', '/') + ) + eq( + ('$XDG_CONFIG_HOME/' .. state_dir .. '/view//'), + api.nvim_get_option_value('viewdir', {}):gsub('\\', '/') + ) + eq(nil, (fn.tempname()):match('XDG_RUNTIME_DIR')) end) end) describe('with commas', function() before_each(function() clear({ - args_rm={'runtimepath'}, - env={ - XDG_CONFIG_HOME=', , ,', - XDG_CONFIG_DIRS=',-,-,' .. env_sep .. '-,-,-', - XDG_DATA_HOME=',=,=,', - XDG_STATE_HOME=',=,=,', - XDG_DATA_DIRS=',≡,≡,' .. env_sep .. '≡,≡,≡', - }}) + args_rm = { 'runtimepath' }, + env = { + XDG_CONFIG_HOME = ', , ,', + XDG_CONFIG_DIRS = ',-,-,' .. env_sep .. '-,-,-', + XDG_DATA_HOME = ',=,=,', + XDG_STATE_HOME = ',=,=,', + XDG_DATA_DIRS = ',≡,≡,' .. env_sep .. '≡,≡,≡', + }, + }) end) it('are escaped properly', function() local vimruntime, libdir = vimruntime_and_libdir() local path_sep = is_os('win') and '\\' or '/' - eq(('\\, \\, \\,' .. path_sep .. 'nvim' - .. ',\\,-\\,-\\,' .. path_sep .. 'nvim' - .. ',-\\,-\\,-' .. path_sep .. 'nvim' - .. ',\\,=\\,=\\,' .. path_sep .. data_dir .. path_sep .. 'site' - .. ',\\,≡\\,≡\\,' .. path_sep .. 'nvim' .. path_sep .. 'site' - .. ',≡\\,≡\\,≡' .. path_sep .. 'nvim' .. path_sep .. 'site' - .. ',' .. vimruntime - .. ',' .. libdir - .. ',≡\\,≡\\,≡' .. path_sep .. 'nvim' .. path_sep .. 'site' .. path_sep .. 'after' - .. ',\\,≡\\,≡\\,' .. path_sep .. 'nvim' .. path_sep .. 'site' .. path_sep .. 'after' - .. ',\\,=\\,=\\,' .. path_sep.. data_dir .. path_sep .. 'site' .. path_sep .. 'after' - .. ',-\\,-\\,-' .. path_sep .. 'nvim' .. path_sep .. 'after' - .. ',\\,-\\,-\\,' .. path_sep .. 'nvim' .. path_sep .. 'after' - .. ',\\, \\, \\,' .. path_sep .. 'nvim' .. path_sep .. 'after' - ), meths.get_option_value('runtimepath', {})) - meths.command('set runtimepath&') - meths.command('set backupdir&') - meths.command('set directory&') - meths.command('set undodir&') - meths.command('set viewdir&') - eq(('\\, \\, \\,' .. path_sep .. 'nvim' - .. ',\\,-\\,-\\,' .. path_sep ..'nvim' - .. ',-\\,-\\,-' .. path_sep ..'nvim' - .. ',\\,=\\,=\\,' .. path_sep ..'' .. data_dir .. '' .. path_sep ..'site' - .. ',\\,≡\\,≡\\,' .. path_sep ..'nvim' .. path_sep ..'site' - .. ',≡\\,≡\\,≡' .. path_sep ..'nvim' .. path_sep ..'site' - .. ',' .. vimruntime - .. ',' .. libdir - .. ',≡\\,≡\\,≡' .. path_sep ..'nvim' .. path_sep ..'site' .. path_sep ..'after' - .. ',\\,≡\\,≡\\,' .. path_sep ..'nvim' .. path_sep ..'site' .. path_sep ..'after' - .. ',\\,=\\,=\\,' .. path_sep ..'' .. data_dir .. '' .. path_sep ..'site' .. path_sep ..'after' - .. ',-\\,-\\,-' .. path_sep ..'nvim' .. path_sep ..'after' - .. ',\\,-\\,-\\,' .. path_sep ..'nvim' .. path_sep ..'after' - .. ',\\, \\, \\,' .. path_sep ..'nvim' .. path_sep ..'after' - ), meths.get_option_value('runtimepath', {})) - eq('.,\\,=\\,=\\,' .. path_sep .. state_dir .. '' .. path_sep ..'backup' .. (path_sep):rep(2), - meths.get_option_value('backupdir', {})) - eq('\\,=\\,=\\,' .. path_sep ..'' .. state_dir .. '' .. path_sep ..'swap' .. (path_sep):rep(2), - meths.get_option_value('directory', {})) - eq('\\,=\\,=\\,' .. path_sep ..'' .. state_dir .. '' .. path_sep ..'undo' .. (path_sep):rep(2), - meths.get_option_value('undodir', {})) - eq('\\,=\\,=\\,' .. path_sep ..'' .. state_dir .. '' .. path_sep ..'view' .. (path_sep):rep(2), - meths.get_option_value('viewdir', {})) + eq( + ( + '\\, \\, \\,' + .. path_sep + .. 'nvim' + .. ',\\,-\\,-\\,' + .. path_sep + .. 'nvim' + .. ',-\\,-\\,-' + .. path_sep + .. 'nvim' + .. ',\\,=\\,=\\,' + .. path_sep + .. data_dir + .. path_sep + .. 'site' + .. ',\\,≡\\,≡\\,' + .. path_sep + .. 'nvim' + .. path_sep + .. 'site' + .. ',≡\\,≡\\,≡' + .. path_sep + .. 'nvim' + .. path_sep + .. 'site' + .. ',' + .. vimruntime + .. ',' + .. libdir + .. ',≡\\,≡\\,≡' + .. path_sep + .. 'nvim' + .. path_sep + .. 'site' + .. path_sep + .. 'after' + .. ',\\,≡\\,≡\\,' + .. path_sep + .. 'nvim' + .. path_sep + .. 'site' + .. path_sep + .. 'after' + .. ',\\,=\\,=\\,' + .. path_sep + .. data_dir + .. path_sep + .. 'site' + .. path_sep + .. 'after' + .. ',-\\,-\\,-' + .. path_sep + .. 'nvim' + .. path_sep + .. 'after' + .. ',\\,-\\,-\\,' + .. path_sep + .. 'nvim' + .. path_sep + .. 'after' + .. ',\\, \\, \\,' + .. path_sep + .. 'nvim' + .. path_sep + .. 'after' + ), + api.nvim_get_option_value('runtimepath', {}) + ) + command('set runtimepath&') + command('set backupdir&') + command('set directory&') + command('set undodir&') + command('set viewdir&') + eq( + ( + '\\, \\, \\,' + .. path_sep + .. 'nvim' + .. ',\\,-\\,-\\,' + .. path_sep + .. 'nvim' + .. ',-\\,-\\,-' + .. path_sep + .. 'nvim' + .. ',\\,=\\,=\\,' + .. path_sep + .. '' + .. data_dir + .. '' + .. path_sep + .. 'site' + .. ',\\,≡\\,≡\\,' + .. path_sep + .. 'nvim' + .. path_sep + .. 'site' + .. ',≡\\,≡\\,≡' + .. path_sep + .. 'nvim' + .. path_sep + .. 'site' + .. ',' + .. vimruntime + .. ',' + .. libdir + .. ',≡\\,≡\\,≡' + .. path_sep + .. 'nvim' + .. path_sep + .. 'site' + .. path_sep + .. 'after' + .. ',\\,≡\\,≡\\,' + .. path_sep + .. 'nvim' + .. path_sep + .. 'site' + .. path_sep + .. 'after' + .. ',\\,=\\,=\\,' + .. path_sep + .. '' + .. data_dir + .. '' + .. path_sep + .. 'site' + .. path_sep + .. 'after' + .. ',-\\,-\\,-' + .. path_sep + .. 'nvim' + .. path_sep + .. 'after' + .. ',\\,-\\,-\\,' + .. path_sep + .. 'nvim' + .. path_sep + .. 'after' + .. ',\\, \\, \\,' + .. path_sep + .. 'nvim' + .. path_sep + .. 'after' + ), + api.nvim_get_option_value('runtimepath', {}) + ) + eq( + '.,\\,=\\,=\\,' .. path_sep .. state_dir .. '' .. path_sep .. 'backup' .. (path_sep):rep(2), + api.nvim_get_option_value('backupdir', {}) + ) + eq( + '\\,=\\,=\\,' + .. path_sep + .. '' + .. state_dir + .. '' + .. path_sep + .. 'swap' + .. (path_sep):rep(2), + api.nvim_get_option_value('directory', {}) + ) + eq( + '\\,=\\,=\\,' + .. path_sep + .. '' + .. state_dir + .. '' + .. path_sep + .. 'undo' + .. (path_sep):rep(2), + api.nvim_get_option_value('undodir', {}) + ) + eq( + '\\,=\\,=\\,' + .. path_sep + .. '' + .. state_dir + .. '' + .. path_sep + .. 'view' + .. (path_sep):rep(2), + api.nvim_get_option_value('viewdir', {}) + ) end) end) end) - describe('stdpath()', function() -- Windows appends 'nvim-data' instead of just 'nvim' to prevent collisions -- due to XDG_CONFIG_HOME, XDG_DATA_HOME and XDG_STATE_HOME being the same. @@ -585,41 +876,45 @@ describe('stdpath()', function() local env_sep = is_os('win') and ';' or ':' it('acceptance', function() - clear() -- Do not explicitly set any env vars. - - eq('nvim', funcs.fnamemodify(funcs.stdpath('cache'), ':t')) - eq('nvim', funcs.fnamemodify(funcs.stdpath('config'), ':t')) - eq(datadir, funcs.fnamemodify(funcs.stdpath('data'), ':t')) - eq(statedir, funcs.fnamemodify(funcs.stdpath('state'), ':t')) - eq('table', type(funcs.stdpath('config_dirs'))) - eq('table', type(funcs.stdpath('data_dirs'))) - eq('string', type(funcs.stdpath('run'))) - assert_alive() -- Check for crash. #8393 + clear() -- Do not explicitly set any env vars. + + eq('nvim', fn.fnamemodify(fn.stdpath('cache'), ':t')) + eq('nvim', fn.fnamemodify(fn.stdpath('config'), ':t')) + eq(datadir, fn.fnamemodify(fn.stdpath('data'), ':t')) + eq(statedir, fn.fnamemodify(fn.stdpath('state'), ':t')) + eq('table', type(fn.stdpath('config_dirs'))) + eq('table', type(fn.stdpath('data_dirs'))) + eq('string', type(fn.stdpath('run'))) + assert_alive() -- Check for crash. #8393 end) it('reacts to $NVIM_APPNAME', function() local appname = 'NVIM_APPNAME_TEST' .. ('_'):rep(106) - clear({env={ NVIM_APPNAME=appname }}) - eq(appname, funcs.fnamemodify(funcs.stdpath('config'), ':t')) - eq(appname, funcs.fnamemodify(funcs.stdpath('cache'), ':t')) - eq(maybe_data(appname), funcs.fnamemodify(funcs.stdpath('log'), ':t')) - eq(maybe_data(appname), funcs.fnamemodify(funcs.stdpath('data'), ':t')) - eq(maybe_data(appname), funcs.fnamemodify(funcs.stdpath('state'), ':t')) + clear({ env = { NVIM_APPNAME = appname } }) + eq(appname, fn.fnamemodify(fn.stdpath('config'), ':t')) + eq(appname, fn.fnamemodify(fn.stdpath('cache'), ':t')) + eq(maybe_data(appname), fn.fnamemodify(fn.stdpath('log'), ':t')) + eq(maybe_data(appname), fn.fnamemodify(fn.stdpath('data'), ':t')) + eq(maybe_data(appname), fn.fnamemodify(fn.stdpath('state'), ':t')) -- config_dirs and data_dirs are empty on windows, so don't check them on -- that platform if not is_os('win') then - eq(appname, funcs.fnamemodify(funcs.stdpath('config_dirs')[1], ':t')) - eq(appname, funcs.fnamemodify(funcs.stdpath('data_dirs')[1], ':t')) + eq(appname, fn.fnamemodify(fn.stdpath('config_dirs')[1], ':t')) + eq(appname, fn.fnamemodify(fn.stdpath('data_dirs')[1], ':t')) end - assert_alive() -- Check for crash. #8393 + assert_alive() -- Check for crash. #8393 -- Check that Nvim rejects invalid APPNAMEs -- Call jobstart() and jobwait() in the same RPC request to reduce flakiness. local function test_appname(testAppname, expected_exitcode) - local lua_code = string.format([[ + local lua_code = string.format( + [[ local child = vim.fn.jobstart({ vim.v.progpath, '--clean', '--headless', '+qall!' }, { env = { NVIM_APPNAME = %q } }) return vim.fn.jobwait({ child }, %d)[1] - ]], alter_slashes(testAppname), 3000) + ]], + alter_slashes(testAppname), + 3000 + ) eq(expected_exitcode, exec_lua(lua_code)) end -- Invalid appnames: @@ -636,136 +931,149 @@ describe('stdpath()', function() end) describe('returns a String', function() - - describe('with "config"' , function () + describe('with "config"', function() it('knows XDG_CONFIG_HOME', function() - clear({env={ - XDG_CONFIG_HOME=alter_slashes('/home/docwhat/.config'), - }}) - eq(alter_slashes('/home/docwhat/.config/nvim'), funcs.stdpath('config')) + clear({ + env = { + XDG_CONFIG_HOME = alter_slashes('/home/docwhat/.config'), + }, + }) + eq(alter_slashes('/home/docwhat/.config/nvim'), fn.stdpath('config')) end) it('handles changes during runtime', function() - clear({env={ - XDG_CONFIG_HOME=alter_slashes('/home/original'), - }}) - eq(alter_slashes('/home/original/nvim'), funcs.stdpath('config')) - command("let $XDG_CONFIG_HOME='"..alter_slashes('/home/new').."'") - eq(alter_slashes('/home/new/nvim'), funcs.stdpath('config')) + clear({ env = { + XDG_CONFIG_HOME = alter_slashes('/home/original'), + } }) + eq(alter_slashes('/home/original/nvim'), fn.stdpath('config')) + command("let $XDG_CONFIG_HOME='" .. alter_slashes('/home/new') .. "'") + eq(alter_slashes('/home/new/nvim'), fn.stdpath('config')) end) it("doesn't expand $VARIABLES", function() - clear({env={ - XDG_CONFIG_HOME='$VARIABLES', - VARIABLES='this-should-not-happen', - }}) - eq(alter_slashes('$VARIABLES/nvim'), funcs.stdpath('config')) + clear({ + env = { + XDG_CONFIG_HOME = '$VARIABLES', + VARIABLES = 'this-should-not-happen', + }, + }) + eq(alter_slashes('$VARIABLES/nvim'), fn.stdpath('config')) end) it("doesn't expand ~/", function() - clear({env={ - XDG_CONFIG_HOME=alter_slashes('~/frobnitz'), - }}) - eq(alter_slashes('~/frobnitz/nvim'), funcs.stdpath('config')) + clear({ env = { + XDG_CONFIG_HOME = alter_slashes('~/frobnitz'), + } }) + eq(alter_slashes('~/frobnitz/nvim'), fn.stdpath('config')) end) end) - describe('with "data"' , function () + describe('with "data"', function() it('knows XDG_DATA_HOME', function() - clear({env={ - XDG_DATA_HOME=alter_slashes('/home/docwhat/.local'), - }}) - eq(alter_slashes('/home/docwhat/.local/'..datadir), funcs.stdpath('data')) + clear({ env = { + XDG_DATA_HOME = alter_slashes('/home/docwhat/.local'), + } }) + eq(alter_slashes('/home/docwhat/.local/' .. datadir), fn.stdpath('data')) end) it('handles changes during runtime', function() - clear({env={ - XDG_DATA_HOME=alter_slashes('/home/original'), - }}) - eq(alter_slashes('/home/original/'..datadir), funcs.stdpath('data')) - command("let $XDG_DATA_HOME='"..alter_slashes('/home/new').."'") - eq(alter_slashes('/home/new/'..datadir), funcs.stdpath('data')) + clear({ env = { + XDG_DATA_HOME = alter_slashes('/home/original'), + } }) + eq(alter_slashes('/home/original/' .. datadir), fn.stdpath('data')) + command("let $XDG_DATA_HOME='" .. alter_slashes('/home/new') .. "'") + eq(alter_slashes('/home/new/' .. datadir), fn.stdpath('data')) end) it("doesn't expand $VARIABLES", function() - clear({env={ - XDG_DATA_HOME='$VARIABLES', - VARIABLES='this-should-not-happen', - }}) - eq(alter_slashes('$VARIABLES/'..datadir), funcs.stdpath('data')) + clear({ + env = { + XDG_DATA_HOME = '$VARIABLES', + VARIABLES = 'this-should-not-happen', + }, + }) + eq(alter_slashes('$VARIABLES/' .. datadir), fn.stdpath('data')) end) it("doesn't expand ~/", function() - clear({env={ - XDG_DATA_HOME=alter_slashes('~/frobnitz'), - }}) - eq(alter_slashes('~/frobnitz/'..datadir), funcs.stdpath('data')) + clear({ env = { + XDG_DATA_HOME = alter_slashes('~/frobnitz'), + } }) + eq(alter_slashes('~/frobnitz/' .. datadir), fn.stdpath('data')) end) end) - describe('with "state"' , function () + describe('with "state"', function() it('knows XDG_STATE_HOME', function() - clear({env={ - XDG_STATE_HOME=alter_slashes('/home/docwhat/.local'), - }}) - eq(alter_slashes('/home/docwhat/.local/'..statedir), funcs.stdpath('state')) + clear({ + env = { + XDG_STATE_HOME = alter_slashes('/home/docwhat/.local'), + }, + }) + eq(alter_slashes('/home/docwhat/.local/' .. statedir), fn.stdpath('state')) end) it('handles changes during runtime', function() - clear({env={ - XDG_STATE_HOME=alter_slashes('/home/original'), - }}) - eq(alter_slashes('/home/original/'..statedir), funcs.stdpath('state')) - command("let $XDG_STATE_HOME='"..alter_slashes('/home/new').."'") - eq(alter_slashes('/home/new/'..statedir), funcs.stdpath('state')) + clear({ env = { + XDG_STATE_HOME = alter_slashes('/home/original'), + } }) + eq(alter_slashes('/home/original/' .. statedir), fn.stdpath('state')) + command("let $XDG_STATE_HOME='" .. alter_slashes('/home/new') .. "'") + eq(alter_slashes('/home/new/' .. statedir), fn.stdpath('state')) end) it("doesn't expand $VARIABLES", function() - clear({env={ - XDG_STATE_HOME='$VARIABLES', - VARIABLES='this-should-not-happen', - }}) - eq(alter_slashes('$VARIABLES/'..statedir), funcs.stdpath('state')) + clear({ + env = { + XDG_STATE_HOME = '$VARIABLES', + VARIABLES = 'this-should-not-happen', + }, + }) + eq(alter_slashes('$VARIABLES/' .. statedir), fn.stdpath('state')) end) it("doesn't expand ~/", function() - clear({env={ - XDG_STATE_HOME=alter_slashes('~/frobnitz'), - }}) - eq(alter_slashes('~/frobnitz/'..statedir), funcs.stdpath('state')) + clear({ env = { + XDG_STATE_HOME = alter_slashes('~/frobnitz'), + } }) + eq(alter_slashes('~/frobnitz/' .. statedir), fn.stdpath('state')) end) end) - describe('with "cache"' , function () + describe('with "cache"', function() it('knows XDG_CACHE_HOME', function() - clear({env={ - XDG_CACHE_HOME=alter_slashes('/home/docwhat/.cache'), - }}) - eq(alter_slashes('/home/docwhat/.cache/nvim'), funcs.stdpath('cache')) + clear({ + env = { + XDG_CACHE_HOME = alter_slashes('/home/docwhat/.cache'), + }, + }) + eq(alter_slashes('/home/docwhat/.cache/nvim'), fn.stdpath('cache')) end) it('handles changes during runtime', function() - clear({env={ - XDG_CACHE_HOME=alter_slashes('/home/original'), - }}) - eq(alter_slashes('/home/original/nvim'), funcs.stdpath('cache')) - command("let $XDG_CACHE_HOME='"..alter_slashes('/home/new').."'") - eq(alter_slashes('/home/new/nvim'), funcs.stdpath('cache')) + clear({ env = { + XDG_CACHE_HOME = alter_slashes('/home/original'), + } }) + eq(alter_slashes('/home/original/nvim'), fn.stdpath('cache')) + command("let $XDG_CACHE_HOME='" .. alter_slashes('/home/new') .. "'") + eq(alter_slashes('/home/new/nvim'), fn.stdpath('cache')) end) it("doesn't expand $VARIABLES", function() - clear({env={ - XDG_CACHE_HOME='$VARIABLES', - VARIABLES='this-should-not-happen', - }}) - eq(alter_slashes('$VARIABLES/nvim'), funcs.stdpath('cache')) + clear({ + env = { + XDG_CACHE_HOME = '$VARIABLES', + VARIABLES = 'this-should-not-happen', + }, + }) + eq(alter_slashes('$VARIABLES/nvim'), fn.stdpath('cache')) end) it("doesn't expand ~/", function() - clear({env={ - XDG_CACHE_HOME=alter_slashes('~/frobnitz'), - }}) - eq(alter_slashes('~/frobnitz/nvim'), funcs.stdpath('cache')) + clear({ env = { + XDG_CACHE_HOME = alter_slashes('~/frobnitz'), + } }) + eq(alter_slashes('~/frobnitz/nvim'), fn.stdpath('cache')) end) end) end) @@ -775,23 +1083,23 @@ describe('stdpath()', function() local function base_env() if is_os('win') then return { - HOME='C:\\Users\\docwhat', -- technically, is not a usual PATH - HOMEDRIVE='C:', - HOMEPATH='\\Users\\docwhat', - LOCALAPPDATA='C:\\Users\\docwhat\\AppData\\Local', - TEMP='C:\\Users\\docwhat\\AppData\\Local\\Temp', - TMPDIR='C:\\Users\\docwhat\\AppData\\Local\\Temp', - TMP='C:\\Users\\docwhat\\AppData\\Local\\Temp', + HOME = 'C:\\Users\\docwhat', -- technically, is not a usual PATH + HOMEDRIVE = 'C:', + HOMEPATH = '\\Users\\docwhat', + LOCALAPPDATA = 'C:\\Users\\docwhat\\AppData\\Local', + TEMP = 'C:\\Users\\docwhat\\AppData\\Local\\Temp', + TMPDIR = 'C:\\Users\\docwhat\\AppData\\Local\\Temp', + TMP = 'C:\\Users\\docwhat\\AppData\\Local\\Temp', } else return { - HOME='/home/docwhat', - HOMEDRIVE='HOMEDRIVE-should-be-ignored', - HOMEPATH='HOMEPATH-should-be-ignored', - LOCALAPPDATA='LOCALAPPDATA-should-be-ignored', - TEMP='TEMP-should-be-ignored', - TMPDIR='TMPDIR-should-be-ignored', - TMP='TMP-should-be-ignored', + HOME = '/home/docwhat', + HOMEDRIVE = 'HOMEDRIVE-should-be-ignored', + HOMEPATH = 'HOMEPATH-should-be-ignored', + LOCALAPPDATA = 'LOCALAPPDATA-should-be-ignored', + TEMP = 'TEMP-should-be-ignored', + TMPDIR = 'TMPDIR-should-be-ignored', + TMP = 'TMP-should-be-ignored', } end end @@ -799,12 +1107,12 @@ describe('stdpath()', function() local function set_paths_via_system(var_name, paths) local env = base_env() env[var_name] = table.concat(paths, env_sep) - clear({env=env}) + clear({ env = env }) end local function set_paths_at_runtime(var_name, paths) - clear({env=base_env()}) - meths.set_var('env_val', table.concat(paths, env_sep)) + clear({ env = base_env() }) + api.nvim_set_var('env_val', table.concat(paths, env_sep)) command(('let $%s=g:env_val'):format(var_name)) end @@ -812,105 +1120,102 @@ describe('stdpath()', function() describe(msg, function() it('set via system', function() set_paths_via_system(env_var_name, paths) - eq(expected_paths, funcs.stdpath(stdpath_arg)) + eq(expected_paths, fn.stdpath(stdpath_arg)) end) it('set at runtime', function() set_paths_at_runtime(env_var_name, paths) - eq(expected_paths, funcs.stdpath(stdpath_arg)) + eq(expected_paths, fn.stdpath(stdpath_arg)) end) end) end - describe('with "config_dirs"' , function () + describe('with "config_dirs"', function() behaves_like_dir_list_env( 'handles XDG_CONFIG_DIRS with one path', - 'config_dirs', 'XDG_CONFIG_DIRS', + 'config_dirs', + 'XDG_CONFIG_DIRS', { - alter_slashes('/home/docwhat/.config') + alter_slashes('/home/docwhat/.config'), }, { - alter_slashes('/home/docwhat/.config/nvim') - }) + alter_slashes('/home/docwhat/.config/nvim'), + } + ) behaves_like_dir_list_env( 'handles XDG_CONFIG_DIRS with two paths', - 'config_dirs', 'XDG_CONFIG_DIRS', + 'config_dirs', + 'XDG_CONFIG_DIRS', { alter_slashes('/home/docwhat/.config'), - alter_slashes('/etc/config') + alter_slashes('/etc/config'), }, { alter_slashes('/home/docwhat/.config/nvim'), - alter_slashes('/etc/config/nvim') - }) + alter_slashes('/etc/config/nvim'), + } + ) behaves_like_dir_list_env( "doesn't expand $VAR and $IBLES", - 'config_dirs', 'XDG_CONFIG_DIRS', + 'config_dirs', + 'XDG_CONFIG_DIRS', { '$HOME', '$TMP' }, { alter_slashes('$HOME/nvim'), - alter_slashes('$TMP/nvim') - }) - + alter_slashes('$TMP/nvim'), + } + ) - behaves_like_dir_list_env( - "doesn't expand ~/", - 'config_dirs', 'XDG_CONFIG_DIRS', - { - alter_slashes('~/.oldconfig'), - alter_slashes('~/.olderconfig') - }, - { - alter_slashes('~/.oldconfig/nvim'), - alter_slashes('~/.olderconfig/nvim') - }) + behaves_like_dir_list_env("doesn't expand ~/", 'config_dirs', 'XDG_CONFIG_DIRS', { + alter_slashes('~/.oldconfig'), + alter_slashes('~/.olderconfig'), + }, { + alter_slashes('~/.oldconfig/nvim'), + alter_slashes('~/.olderconfig/nvim'), + }) end) - describe('with "data_dirs"' , function () - behaves_like_dir_list_env( - 'knows XDG_DATA_DIRS with one path', - 'data_dirs', 'XDG_DATA_DIRS', - { - alter_slashes('/home/docwhat/.data') - }, - { - alter_slashes('/home/docwhat/.data/nvim') - }) + describe('with "data_dirs"', function() + behaves_like_dir_list_env('knows XDG_DATA_DIRS with one path', 'data_dirs', 'XDG_DATA_DIRS', { + alter_slashes('/home/docwhat/.data'), + }, { + alter_slashes('/home/docwhat/.data/nvim'), + }) behaves_like_dir_list_env( 'knows XDG_DATA_DIRS with two paths', - 'data_dirs', 'XDG_DATA_DIRS', + 'data_dirs', + 'XDG_DATA_DIRS', { alter_slashes('/home/docwhat/.data'), - alter_slashes('/etc/local') + alter_slashes('/etc/local'), }, { alter_slashes('/home/docwhat/.data/nvim'), alter_slashes('/etc/local/nvim'), - }) + } + ) behaves_like_dir_list_env( "doesn't expand $VAR and $IBLES", - 'data_dirs', 'XDG_DATA_DIRS', + 'data_dirs', + 'XDG_DATA_DIRS', { '$HOME', '$TMP' }, { alter_slashes('$HOME/nvim'), - alter_slashes('$TMP/nvim') - }) + alter_slashes('$TMP/nvim'), + } + ) - behaves_like_dir_list_env( - "doesn't expand ~/", - 'data_dirs', 'XDG_DATA_DIRS', - { - alter_slashes('~/.oldconfig'), - alter_slashes('~/.olderconfig') - }, - { - alter_slashes('~/.oldconfig/nvim'), - alter_slashes('~/.olderconfig/nvim'), - }) + behaves_like_dir_list_env("doesn't expand ~/", 'data_dirs', 'XDG_DATA_DIRS', { + alter_slashes('~/.oldconfig'), + alter_slashes('~/.olderconfig'), + }, { + alter_slashes('~/.oldconfig/nvim'), + alter_slashes('~/.olderconfig/nvim'), + }) end) end) @@ -927,3 +1232,22 @@ describe('stdpath()', function() end) end) end) + +describe('autocommands', function() + it('closes terminal with default shell on success', function() + api.nvim_set_option_value('shell', helpers.testprg('shell-test'), {}) + command('set shellcmdflag=EXIT shellredir= shellpipe= shellquote= shellxquote=') + + -- Should not block other events + command('let g:n=0') + command('au BufEnter * let g:n = g:n + 1') + + command('terminal') + eq(eval('get(g:, "n", 0)'), 1) + + helpers.retry(nil, 1000, function() + neq(api.nvim_get_option_value('buftype', { buf = 0 }), 'terminal') + eq(eval('get(g:, "n", 0)'), 2) + end) + end) +end) diff --git a/test/functional/options/keymap_spec.lua b/test/functional/options/keymap_spec.lua index c390e3d943..7be58888bc 100644 --- a/test/functional/options/keymap_spec.lua +++ b/test/functional/options/keymap_spec.lua @@ -1,6 +1,6 @@ local helpers = require('test.functional.helpers')(after_each) local clear, feed, eq = helpers.clear, helpers.feed, helpers.eq -local expect, command, eval = helpers.expect, helpers.command, helpers.eval +local expect, command, eval = helpers.expect, helpers.command, helpers.eval local insert, call = helpers.insert, helpers.call local exec_capture, dedent = helpers.exec_capture, helpers.dedent @@ -10,7 +10,7 @@ describe("'keymap' / :lmap", function() clear() before_each(function() clear() - insert("lllaaa") + insert('lllaaa') command('set iminsert=1') command('set imsearch=1') command('lmap l a') @@ -31,7 +31,8 @@ describe("'keymap' / :lmap", function() command('set keymap=dvorak') command('set nomore') local bindings = exec_capture('lmap') - eq(dedent([[ + eq( + dedent([[ l " @_ l ' @- @@ -104,20 +105,22 @@ describe("'keymap' / :lmap", function() l z @; l { @? l | @| - l } @+]]), bindings) + l } @+]]), + bindings + ) end) end) describe("'iminsert' option", function() - it("Uses :lmap in insert mode when ON", function() + it('Uses :lmap in insert mode when ON', function() feed('il<esc>') expect('alllaaa') end) - it("Ignores :lmap in insert mode when OFF", function() + it('Ignores :lmap in insert mode when OFF', function() command('set iminsert=0') feed('il<esc>') expect('llllaaa') end) - it("Can be toggled with <C-^> in insert mode", function() + it('Can be toggled with <C-^> in insert mode', function() feed('i<C-^>l<C-^>l<esc>') expect('lalllaaa') eq(1, eval('&iminsert')) @@ -126,16 +129,16 @@ describe("'keymap' / :lmap", function() end) end) describe("'imsearch' option", function() - it("Uses :lmap at search prompt when ON", function() + it('Uses :lmap at search prompt when ON', function() feed('/lll<cr>3x') expect('lll') end) - it("Ignores :lmap at search prompt when OFF", function() + it('Ignores :lmap at search prompt when OFF', function() command('set imsearch=0') feed('gg/lll<cr>3x') expect('aaa') end) - it("Can be toggled with C-^", function() + it('Can be toggled with C-^', function() eq(1, eval('&imsearch')) feed('/<C-^>lll<cr>3x') expect('aaa') @@ -156,28 +159,28 @@ describe("'keymap' / :lmap", function() eq(0, eval('&iminsert')) end) end) - it(":lmap not applied to macros", function() + it(':lmap not applied to macros', function() command("call setreg('a', 'il')") feed('@a') expect('llllaaa') eq('il', call('getreg', 'a')) end) - it(":lmap applied to macro recording", function() + it(':lmap applied to macro recording', function() feed('qail<esc>q@a') expect('aalllaaa') eq('ia', call('getreg', 'a')) end) - it(":lmap not applied to mappings", function() + it(':lmap not applied to mappings', function() command('imap t l') feed('it<esc>') expect('llllaaa') end) - it("mappings applied to keys created with :lmap", function() + it('mappings applied to keys created with :lmap', function() command('imap a x') feed('il<esc>') expect('xlllaaa') end) - it("mappings not applied to keys gotten with :lnoremap", function() + it('mappings not applied to keys gotten with :lnoremap', function() command('lmapclear') command('lnoremap l a') command('imap a x') @@ -196,7 +199,7 @@ describe("'keymap' / :lmap", function() feed('@a') expect('aalllaaa') end) - it("is applied when using f/F t/T", function() + it('is applied when using f/F t/T', function() feed('flx') expect('lllaa') feed('0ia<esc>4lFlx') diff --git a/test/functional/options/mousescroll_spec.lua b/test/functional/options/mousescroll_spec.lua index 38a9692792..96af8987b8 100644 --- a/test/functional/options/mousescroll_spec.lua +++ b/test/functional/options/mousescroll_spec.lua @@ -23,11 +23,11 @@ describe("'mousescroll'", function() local digit_expected = 'Vim(set):E5080: Digit expected: mousescroll=' local function should_fail(val, errorstr) - eq(errorstr..val, exc_exec('set mousescroll='..val)) + eq(errorstr .. val, exc_exec('set mousescroll=' .. val)) end local function should_succeed(val) - eq(0, exc_exec('set mousescroll='..val)) + eq(0, exc_exec('set mousescroll=' .. val)) end before_each(function() @@ -147,15 +147,15 @@ describe("'mousescroll'", function() command('set mousescroll=hor:1') scroll('right') - eq(9, screencol()) + eq(9, screencol()) command('set mousescroll=hor:3') scroll('right') - eq(6, screencol()) + eq(6, screencol()) command('set mousescroll=hor:2') scroll('left') - eq(8, screencol()) + eq(8, screencol()) end it('controls horizontal scrolling in normal mode', function() diff --git a/test/functional/options/num_options_spec.lua b/test/functional/options/num_options_spec.lua index 16a53c75e6..0614bcf814 100644 --- a/test/functional/options/num_options_spec.lua +++ b/test/functional/options/num_options_spec.lua @@ -1,40 +1,40 @@ -- Tests for :setlocal and :setglobal local helpers = require('test.functional.helpers')(after_each) -local clear, feed_command, eval, eq, meths = - helpers.clear, helpers.feed_command, helpers.eval, helpers.eq, helpers.meths +local clear, feed_command, eval, eq, api = + helpers.clear, helpers.feed_command, helpers.eval, helpers.eq, helpers.api local function should_fail(opt, value, errmsg) feed_command('setglobal ' .. opt .. '=' .. value) - eq(errmsg, eval("v:errmsg"):match("E%d*")) + eq(errmsg, eval('v:errmsg'):match('E%d*')) feed_command('let v:errmsg = ""') feed_command('setlocal ' .. opt .. '=' .. value) - eq(errmsg, eval("v:errmsg"):match("E%d*")) + eq(errmsg, eval('v:errmsg'):match('E%d*')) feed_command('let v:errmsg = ""') - local status, err = pcall(meths.set_option_value, opt, value, {}) + local status, err = pcall(api.nvim_set_option_value, opt, value, {}) eq(status, false) - eq(errmsg, err:match("E%d*")) - eq('', eval("v:errmsg")) + eq(errmsg, err:match('E%d*')) + eq('', eval('v:errmsg')) end local function should_succeed(opt, value) feed_command('setglobal ' .. opt .. '=' .. value) feed_command('setlocal ' .. opt .. '=' .. value) - meths.set_option_value(opt, value, {}) - eq(value, meths.get_option_value(opt, {})) - eq('', eval("v:errmsg")) + api.nvim_set_option_value(opt, value, {}) + eq(value, api.nvim_get_option_value(opt, {})) + eq('', eval('v:errmsg')) end describe(':setlocal', function() before_each(clear) it('setlocal sets only local value', function() - eq(0, meths.get_option_value('iminsert', {scope='global'})) + eq(0, api.nvim_get_option_value('iminsert', { scope = 'global' })) feed_command('setlocal iminsert=1') - eq(0, meths.get_option_value('iminsert', {scope='global'})) - eq(-1, meths.get_option_value('imsearch', {scope='global'})) + eq(0, api.nvim_get_option_value('iminsert', { scope = 'global' })) + eq(-1, api.nvim_get_option_value('imsearch', { scope = 'global' })) feed_command('setlocal imsearch=1') - eq(-1, meths.get_option_value('imsearch', {scope='global'})) + eq(-1, api.nvim_get_option_value('imsearch', { scope = 'global' })) end) end) @@ -77,44 +77,44 @@ describe(':set validation', function() -- If smaller than 1 this one is set to 'lines'-1 feed_command('setglobal window=-10') - meths.set_option_value('window', -10, {}) - eq(23, meths.get_option_value('window', {})) - eq('', eval("v:errmsg")) + api.nvim_set_option_value('window', -10, {}) + eq(23, api.nvim_get_option_value('window', {})) + eq('', eval('v:errmsg')) -- 'scrolloff' and 'sidescrolloff' can have a -1 value when -- set for the current window, but not globally feed_command('setglobal scrolloff=-1') - eq('E487', eval("v:errmsg"):match("E%d*")) + eq('E487', eval('v:errmsg'):match('E%d*')) feed_command('setglobal sidescrolloff=-1') - eq('E487', eval("v:errmsg"):match("E%d*")) + eq('E487', eval('v:errmsg'):match('E%d*')) feed_command('let v:errmsg=""') feed_command('setlocal scrolloff=-1') - eq('', eval("v:errmsg")) + eq('', eval('v:errmsg')) feed_command('setlocal sidescrolloff=-1') - eq('', eval("v:errmsg")) + eq('', eval('v:errmsg')) end) it('set wmh/wh wmw/wiw checks', function() feed_command('set winheight=2') feed_command('set winminheight=3') - eq('E591', eval("v:errmsg"):match("E%d*")) + eq('E591', eval('v:errmsg'):match('E%d*')) feed_command('set winwidth=2') feed_command('set winminwidth=3') - eq('E592', eval("v:errmsg"):match("E%d*")) + eq('E592', eval('v:errmsg'):match('E%d*')) end) it('set maxcombine resets to 6', function() local function setto(value) feed_command('setglobal maxcombine=' .. value) feed_command('setlocal maxcombine=' .. value) - meths.set_option_value('maxcombine', value, {}) - eq(6, meths.get_option_value('maxcombine', {})) - eq('', eval("v:errmsg")) + api.nvim_set_option_value('maxcombine', value, {}) + eq(6, api.nvim_get_option_value('maxcombine', {})) + eq('', eval('v:errmsg')) end setto(0) setto(1) diff --git a/test/functional/options/shortmess_spec.lua b/test/functional/options/shortmess_spec.lua index a56e9c09b4..6bc00ca1c5 100644 --- a/test/functional/options/shortmess_spec.lua +++ b/test/functional/options/shortmess_spec.lua @@ -22,9 +22,7 @@ describe("'shortmess'", function() feed(':edit foo<CR>') screen:expect([[ ^ | - ~ | - ~ | - ~ | + ~ |*3 "foo" [New] | ]]) eq(1, eval('bufnr("%")')) @@ -33,9 +31,7 @@ describe("'shortmess'", function() feed(':edit bar<CR>') screen:expect([[ ^ | - ~ | - ~ | - ~ | + ~ |*3 :edit bar | ]]) eq(2, eval('bufnr("%")')) @@ -47,27 +43,21 @@ describe("'shortmess'", function() feed(':edit foo<CR>') screen:expect([[ ^ | - ~ | - ~ | - ~ | + ~ |*3 "foo" [New] | ]]) eq(1, eval('bufnr("%")')) feed(':edit bar<CR>') screen:expect([[ ^ | - ~ | - ~ | - ~ | + ~ |*3 "bar" [New] | ]]) eq(2, eval('bufnr("%")')) feed(':bprevious<CR>') screen:expect([[ ^ | - ~ | - ~ | - ~ | + ~ |*3 "foo" [New] --No lines in buffer-- | ]]) eq(1, eval('bufnr("%")')) @@ -76,18 +66,14 @@ describe("'shortmess'", function() feed(':bnext<CR>') screen:expect([[ ^ | - ~ | - ~ | - ~ | + ~ |*3 :bnext | ]]) eq(2, eval('bufnr("%")')) feed(':bprevious<CR>') screen:expect([[ ^ | - ~ | - ~ | - ~ | + ~ |*3 :bprevious | ]]) eq(1, eval('bufnr("%")')) diff --git a/test/functional/options/tabstop_spec.lua b/test/functional/options/tabstop_spec.lua index e34f678650..9070db8257 100644 --- a/test/functional/options/tabstop_spec.lua +++ b/test/functional/options/tabstop_spec.lua @@ -11,7 +11,7 @@ describe("'tabstop' option", function() -- NOTE: Setting 'tabstop' to a big number reproduces crash #2838. -- Disallowing big 'tabstop' would not fix #2838, only hide it. - it("tabstop=<big-number> does not crash #2838", function() + it('tabstop=<big-number> does not crash #2838', function() -- Insert a <Tab> character for 'tabstop' to work with. feed('i<Tab><Esc>') -- Set 'tabstop' to a very high value. diff --git a/test/functional/plugin/cfilter_spec.lua b/test/functional/plugin/cfilter_spec.lua index 8b1e75b495..37261d59df 100644 --- a/test/functional/plugin/cfilter_spec.lua +++ b/test/functional/plugin/cfilter_spec.lua @@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local command = helpers.command local eq = helpers.eq -local funcs = helpers.funcs +local fn = helpers.fn describe('cfilter.lua', function() before_each(function() @@ -13,16 +13,16 @@ describe('cfilter.lua', function() for _, list in ipairs({ { name = 'Cfilter', - get = funcs.getqflist, - set = funcs.setqflist, + get = fn.getqflist, + set = fn.setqflist, }, { name = 'Lfilter', get = function() - return funcs.getloclist(0) + return fn.getloclist(0) end, set = function(items) - return funcs.setloclist(0, items) + return fn.setloclist(0, items) end, }, }) do @@ -39,7 +39,7 @@ describe('cfilter.lua', function() describe((':%s'):format(list.name), function() it('does not error on empty list', function() filter('nothing') - eq({}, funcs.getqflist()) + eq({}, fn.getqflist()) end) it('requires an argument', function() @@ -66,7 +66,7 @@ describe('cfilter.lua', function() end local toname = function(qflist) - return funcs.map(qflist, 'v:val.text') + return fn.map(qflist, 'v:val.text') end test('filters with no matches', 'does not match', {}) @@ -83,7 +83,7 @@ describe('cfilter.lua', function() { filename = 'foo', lnum = 3, text = 'zed' }, }) - funcs.setreg('/', 'ba') + fn.setreg('/', 'ba') filter('/') eq({ 'bar', 'baz' }, toname(list.get())) @@ -96,7 +96,7 @@ describe('cfilter.lua', function() { filename = 'foo', lnum = 3, text = 'zed' }, }) - funcs.setreg('/', 'ba') + fn.setreg('/', 'ba') filter('/', true) eq({ 'zed' }, toname(list.get())) diff --git a/test/functional/plugin/editorconfig_spec.lua b/test/functional/plugin/editorconfig_spec.lua index ac78003a8c..115c28fbf6 100644 --- a/test/functional/plugin/editorconfig_spec.lua +++ b/test/functional/plugin/editorconfig_spec.lua @@ -3,8 +3,8 @@ local clear = helpers.clear local command = helpers.command local eq = helpers.eq local pathsep = helpers.get_pathsep() -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local exec_lua = helpers.exec_lua local testdir = 'Xtest-editorconfig' @@ -13,7 +13,7 @@ local function test_case(name, expected) local filename = testdir .. pathsep .. name command('edit ' .. filename) for opt, val in pairs(expected) do - eq(val, meths.get_option_value(opt, {buf=0}), name) + eq(val, api.nvim_get_option_value(opt, { buf = 0 }), name) end end @@ -195,15 +195,15 @@ But not this one end) it('can be disabled globally', function() - meths.set_var('editorconfig', false) - meths.set_option_value('shiftwidth', 42, {}) + api.nvim_set_var('editorconfig', false) + api.nvim_set_option_value('shiftwidth', 42, {}) test_case('3_space.txt', { shiftwidth = 42 }) end) it('can be disabled per-buffer', function() - meths.set_option_value('shiftwidth', 42, {}) - local bufnr = funcs.bufadd(testdir .. pathsep .. '3_space.txt') - meths.buf_set_var(bufnr, 'editorconfig', false) + api.nvim_set_option_value('shiftwidth', 42, {}) + local bufnr = fn.bufadd(testdir .. pathsep .. '3_space.txt') + api.nvim_buf_set_var(bufnr, 'editorconfig', false) test_case('3_space.txt', { shiftwidth = 42 }) test_case('4_space.py', { shiftwidth = 4 }) end) diff --git a/test/functional/plugin/health_spec.lua b/test/functional/plugin/health_spec.lua index 50b1d03f36..8564ec7c9b 100644 --- a/test/functional/plugin/health_spec.lua +++ b/test/functional/plugin/health_spec.lua @@ -5,12 +5,15 @@ local clear = helpers.clear local curbuf_contents = helpers.curbuf_contents local command = helpers.command local eq, neq, matches = helpers.eq, helpers.neq, helpers.matches -local getcompletion = helpers.funcs.getcompletion +local getcompletion = helpers.fn.getcompletion +local insert = helpers.insert +local source = helpers.source +local exec_lua = helpers.exec_lua describe(':checkhealth', function() - it("detects invalid $VIMRUNTIME", function() + it('detects invalid $VIMRUNTIME', function() clear({ - env={ VIMRUNTIME='bogus', }, + env = { VIMRUNTIME = 'bogus' }, }) local status, err = pcall(command, 'checkhealth') eq(false, status) @@ -23,32 +26,32 @@ describe(':checkhealth', function() eq(false, status) eq("Invalid 'runtimepath'", string.match(err, 'Invalid.*')) end) - it("detects invalid $VIM", function() + it('detects invalid $VIM', function() clear() -- Do this after startup, otherwise it just breaks $VIMRUNTIME. command("let $VIM='zub'") - command("checkhealth nvim") + command('checkhealth nvim') matches('ERROR $VIM .* zub', curbuf_contents()) end) it('completions can be listed via getcompletion()', function() clear() eq('nvim', getcompletion('nvim', 'checkhealth')[1]) - eq('provider', getcompletion('prov', 'checkhealth')[1]) + eq('provider.clipboard', getcompletion('prov', 'checkhealth')[1]) eq('vim.lsp', getcompletion('vim.ls', 'checkhealth')[1]) - neq('vim', getcompletion('^vim', 'checkhealth')[1]) -- should not complete vim.health + neq('vim', getcompletion('^vim', 'checkhealth')[1]) -- should not complete vim.health end) end) describe('health.vim', function() before_each(function() - clear{args={'-u', 'NORC'}} + clear { args = { '-u', 'NORC' } } -- Provides healthcheck functions - command("set runtimepath+=test/functional/fixtures") + command('set runtimepath+=test/functional/fixtures') end) - describe(":checkhealth", function() - it("functions report_*() render correctly", function() - command("checkhealth full_render") + describe(':checkhealth', function() + it('functions report_*() render correctly', function() + command('checkhealth full_render') helpers.expect([[ ============================================================================== @@ -70,8 +73,8 @@ describe('health.vim', function() ]]) end) - it("concatenates multiple reports", function() - command("checkhealth success1 success2 test_plug") + it('concatenates multiple reports', function() + command('checkhealth success1 success2 test_plug') helpers.expect([[ ============================================================================== @@ -100,8 +103,8 @@ describe('health.vim', function() ]]) end) - it("lua plugins submodules", function() - command("checkhealth test_plug.submodule") + it('lua plugins submodules', function() + command('checkhealth test_plug.submodule') helpers.expect([[ ============================================================================== @@ -115,8 +118,8 @@ describe('health.vim', function() ]]) end) - it("... including empty reports", function() - command("checkhealth test_plug.submodule_empty") + it('... including empty reports', function() + command('checkhealth test_plug.submodule_empty') helpers.expect([[ ============================================================================== @@ -126,7 +129,7 @@ describe('health.vim', function() ]]) end) - it("highlights OK, ERROR", function() + it('highlights OK, ERROR', function() local screen = Screen.new(50, 12) screen:attach() screen:set_default_attr_ids({ @@ -135,9 +138,10 @@ describe('health.vim', function() Heading = { foreground = tonumber('0x6a0dad') }, Bar = { foreground = Screen.colors.LightGrey, background = Screen.colors.DarkGrey }, }) - command("checkhealth foo success1") - command("set nofoldenable nowrap laststatus=0") - screen:expect{grid=[[ + command('checkhealth foo success1') + command('set nofoldenable nowrap laststatus=0') + screen:expect { + grid = [[ ^ | {Bar:──────────────────────────────────────────────────}| {Heading:foo: } | @@ -150,15 +154,17 @@ describe('health.vim', function() {Heading:report 1} | - {Ok:OK} everything is fine | | - ]]} + ]], + } end) - it("fold healthchecks", function() + it('fold healthchecks', function() local screen = Screen.new(50, 7) screen:attach() - command("checkhealth foo success1") - command("set nowrap laststatus=0") - screen:expect{grid=[[ + command('checkhealth foo success1') + command('set nowrap laststatus=0') + screen:expect { + grid = [[ ^ | ──────────────────────────────────────────────────| +WE 4 lines: foo: ·······························| @@ -166,11 +172,12 @@ describe('health.vim', function() +-- 8 lines: test_plug.success1: require("test_pl| ~ | | - ]]} + ]], + } end) - it("gracefully handles invalid healthcheck", function() - command("checkhealth non_existent_healthcheck") + it('gracefully handles invalid healthcheck', function() + command('checkhealth non_existent_healthcheck') -- luacheck: ignore 613 helpers.expect([[ @@ -181,9 +188,9 @@ describe('health.vim', function() ]]) end) - it("does not use vim.health as a healtcheck", function() + it('does not use vim.health as a healtcheck', function() -- vim.health is not a healthcheck - command("checkhealth vim") + command('checkhealth vim') helpers.expect([[ ERROR: No healthchecks found.]]) end) @@ -200,3 +207,187 @@ describe(':checkhealth provider', function() eq(nil, string.match(curbuf_contents(), 'WRONG!!!')) end) end) + +describe(':checkhealth window', function() + before_each(function() + clear { args = { '-u', 'NORC' } } + -- Provides healthcheck functions + command('set runtimepath+=test/functional/fixtures') + command('set nofoldenable nowrap laststatus=0') + end) + + it('opens directly if no buffer created', function() + local screen = Screen.new(50, 12) + screen:attach({ ext_multigrid = true }) + command('checkhealth success1') + screen:expect { + grid = [[ + ## grid 1 + [2:--------------------------------------------------]|*11 + [3:--------------------------------------------------]| + ## grid 2 + ^ | + ──────────────────────────────────────────────────| + ──────────────────────────── | + test_plug.success1: require("test_plug.success1. | + health").check() | + | + report 1 | + - OK everything is fine | + | + report 2 | + - OK nothing to see here | + ## grid 3 + | + ]], + } + end) + + local function test_health_vsplit(left, emptybuf, mods) + local screen = Screen.new(50, 20) + screen:attach({ ext_multigrid = true }) + if not emptybuf then + insert('hello') + end + command(mods .. ' checkhealth success1') + screen:expect( + ([[ + ## grid 1 + %s + [3:--------------------------------------------------]| + ## grid 2 + %s | + ~ |*18 + ## grid 3 + | + ## grid 4 + ^ | + ─────────────────────────|*3 + ─── | + test_plug.success1: | + require("test_plug. | + success1.health").check()| + | + report 1 | + - OK everything is fine | + | + report 2 | + - OK nothing to see here | + | + ~ |*4 + ]]):format( + left and '[4:-------------------------]│[2:------------------------]|*19' + or '[2:------------------------]│[4:-------------------------]|*19', + emptybuf and ' ' or 'hello' + ) + ) + end + + for _, mods in ipairs({ 'vertical', 'leftabove vertical', 'topleft vertical' }) do + it(('opens in left vsplit window with :%s and no buffer created'):format(mods), function() + test_health_vsplit(true, true, mods) + end) + it(('opens in left vsplit window with :%s and non-empty buffer'):format(mods), function() + test_health_vsplit(true, false, mods) + end) + end + + for _, mods in ipairs({ 'rightbelow vertical', 'botright vertical' }) do + it(('opens in right vsplit window with :%s and no buffer created'):format(mods), function() + test_health_vsplit(false, true, mods) + end) + it(('opens in right vsplit window with :%s and non-empty buffer'):format(mods), function() + test_health_vsplit(false, false, mods) + end) + end + + local function test_health_split(top, emptybuf, mods) + local screen = Screen.new(50, 25) + screen:attach({ ext_multigrid = true }) + if not emptybuf then + insert('hello') + end + command(mods .. ' checkhealth success1') + screen:expect( + ([[ + ## grid 1 +%s + [3:--------------------------------------------------]| + ## grid 2 + %s | + ~ |*10 + ## grid 3 + | + ## grid 4 + ^ | + ──────────────────────────────────────────────────| + ──────────────────────────── | + test_plug.success1: require("test_plug.success1. | + health").check() | + | + report 1 | + - OK everything is fine | + | + report 2 | + - OK nothing to see here | + | + ]]):format( + top + and [[ + [4:--------------------------------------------------]|*12 + health:// | + [2:--------------------------------------------------]|*11]] + or ([[ + [2:--------------------------------------------------]|*11 + [No Name] %s | + [4:--------------------------------------------------]|*12]]):format( + emptybuf and ' ' or '[+]' + ), + emptybuf and ' ' or 'hello' + ) + ) + end + + for _, mods in ipairs({ 'horizontal', 'leftabove', 'topleft' }) do + it(('opens in top split window with :%s and no buffer created'):format(mods), function() + test_health_split(true, true, mods) + end) + it(('opens in top split window with :%s and non-empty buffer'):format(mods), function() + test_health_split(true, false, mods) + end) + end + + for _, mods in ipairs({ 'rightbelow', 'botright' }) do + it(('opens in bottom split window with :%s and no buffer created'):format(mods), function() + test_health_split(false, true, mods) + end) + it(('opens in bottom split window with :%s and non-empty buffer'):format(mods), function() + test_health_split(false, false, mods) + end) + end + + it('opens in tab', function() + -- create an empty buffer called "my_buff" + exec_lua 'vim.api.nvim_create_buf(false, true)' + command('file my_buff') + command('checkhealth success1') + -- define a function that collects all buffers in each tab + -- returns a dictionary like {tab1 = ["buf1", "buf2"], tab2 = ["buf3"]} + source([[ + function CollectBuffersPerTab() + let buffs = {} + for i in range(tabpagenr('$')) + let key = 'tab' . (i + 1) + let value = [] + for j in tabpagebuflist(i + 1) + call add(value, bufname(j)) + endfor + let buffs[key] = value + endfor + return buffs + endfunction + ]]) + local buffers_per_tab = exec_lua('return vim.fn.CollectBuffersPerTab()') + eq(buffers_per_tab, { tab1 = { 'my_buff' }, tab2 = { 'health://' } }) + end) +end) diff --git a/test/functional/plugin/lsp/codelens_spec.lua b/test/functional/plugin/lsp/codelens_spec.lua index 3d7a15a191..29daf7a066 100644 --- a/test/functional/plugin/lsp/codelens_spec.lua +++ b/test/functional/plugin/lsp/codelens_spec.lua @@ -11,17 +11,21 @@ describe('vim.lsp.codelens', function() after_each(helpers.clear) it('on_codelens_stores_and_displays_lenses', function() - local fake_uri = "file:///fake/uri" - local bufnr = exec_lua([[ + local fake_uri = 'file:///fake/uri' + local bufnr = exec_lua( + [[ fake_uri = ... local bufnr = vim.uri_to_bufnr(fake_uri) local lines = {'So', 'many', 'lines'} vim.fn.bufload(bufnr) vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines) return bufnr - ]], fake_uri) + ]], + fake_uri + ) - exec_lua([[ + exec_lua( + [[ local bufnr = ... local lenses = { { @@ -33,14 +37,16 @@ describe('vim.lsp.codelens', function() }, } vim.lsp.codelens.on_codelens(nil, lenses, {method='textDocument/codeLens', client_id=1, bufnr=bufnr}) - ]], bufnr) + ]], + bufnr + ) local stored_lenses = exec_lua('return vim.lsp.codelens.get(...)', bufnr) local expected = { { range = { start = { line = 0, character = 0 }, - ['end'] = { line = 0, character = 0 } + ['end'] = { line = 0, character = 0 }, }, command = { title = 'Lens1', @@ -50,28 +56,35 @@ describe('vim.lsp.codelens', function() } eq(expected, stored_lenses) - local virtual_text_chunks = exec_lua([[ + local virtual_text_chunks = exec_lua( + [[ local bufnr = ... local ns = vim.lsp.codelens.__namespaces[1] local extmarks = vim.api.nvim_buf_get_extmarks(bufnr, ns, 0, -1, {}) return vim.api.nvim_buf_get_extmark_by_id(bufnr, ns, extmarks[1][1], { details = true })[3].virt_text - ]], bufnr) + ]], + bufnr + ) - eq({[1] = {'Lens1', 'LspCodeLens'}}, virtual_text_chunks) + eq({ [1] = { 'Lens1', 'LspCodeLens' } }, virtual_text_chunks) end) it('can clear all lens', function() - local fake_uri = "file:///fake/uri" - local bufnr = exec_lua([[ + local fake_uri = 'file:///fake/uri' + local bufnr = exec_lua( + [[ fake_uri = ... local bufnr = vim.uri_to_bufnr(fake_uri) local lines = {'So', 'many', 'lines'} vim.fn.bufload(bufnr) vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines) return bufnr - ]], fake_uri) + ]], + fake_uri + ) - exec_lua([[ + exec_lua( + [[ local bufnr = ... local lenses = { { @@ -83,7 +96,9 @@ describe('vim.lsp.codelens', function() }, } vim.lsp.codelens.on_codelens(nil, lenses, {method='textDocument/codeLens', client_id=1, bufnr=bufnr}) - ]], bufnr) + ]], + bufnr + ) local stored_lenses = exec_lua('return vim.lsp.codelens.get(...)', bufnr) eq(1, #stored_lenses) diff --git a/test/functional/plugin/lsp/completion_spec.lua b/test/functional/plugin/lsp/completion_spec.lua index 9354654afe..655eb76be6 100644 --- a/test/functional/plugin/lsp/completion_spec.lua +++ b/test/functional/plugin/lsp/completion_spec.lua @@ -3,7 +3,6 @@ local helpers = require('test.functional.helpers')(after_each) local eq = helpers.eq local exec_lua = helpers.exec_lua - --- Convert completion results. --- ---@param line string line contents. Mark cursor position with `|` @@ -13,9 +12,10 @@ local exec_lua = helpers.exec_lua local function complete(line, candidates, lnum) lnum = lnum or 0 -- nvim_win_get_cursor returns 0 based column, line:find returns 1 based - local cursor_col = line:find("|") - 1 - line = line:gsub("|", "") - return exec_lua([[ + local cursor_col = line:find('|') - 1 + line = line:gsub('|', '') + return exec_lua( + [[ local line, cursor_col, lnum, result = ... local line_to_cursor = line:sub(1, cursor_col) local client_start_boundary = vim.fn.match(line_to_cursor, '\\k*$') @@ -32,18 +32,22 @@ local function complete(line, candidates, lnum) items = items, server_start_boundary = server_start_boundary } - ]], line, cursor_col, lnum, candidates) + ]], + line, + cursor_col, + lnum, + candidates + ) end - -describe("vim.lsp._completion", function() +describe('vim.lsp._completion', function() before_each(helpers.clear) -- https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion it('prefers textEdit over label as word', function() local range0 = { start = { line = 0, character = 0 }, - ["end"] = { line = 0, character = 0 }, + ['end'] = { line = 0, character = 0 }, } local completion_list = { -- resolves into label @@ -57,7 +61,12 @@ describe("vim.lsp._completion", function() { label = 'foocar', sortText = 'c', insertText = 'foobar' }, { label = 'foocar', sortText = 'd', insertText = 'foobar' }, -- resolves into textEdit.newText - { label = 'foocar', sortText = 'e', insertText = 'foodar', textEdit = { newText = 'foobar', range = range0 } }, + { + label = 'foocar', + sortText = 'e', + insertText = 'foodar', + textEdit = { newText = 'foobar', range = range0 }, + }, { label = 'foocar', sortText = 'f', textEdit = { newText = 'foobar', range = range0 } }, -- real-world snippet text { @@ -65,7 +74,10 @@ describe("vim.lsp._completion", function() sortText = 'g', insertText = 'foodar', insertTextFormat = 2, - textEdit = { newText = 'foobar(${1:place holder}, ${2:more ...holder{\\}})', range = range0 }, + textEdit = { + newText = 'foobar(${1:place holder}, ${2:more ...holder{\\}})', + range = range0, + }, }, { label = 'foocar', @@ -81,7 +93,7 @@ describe("vim.lsp._completion", function() insertTextFormat = 2, }, -- braced tabstop - { label = 'foocar', sortText = 'j', insertText = 'foodar()${0}', insertTextFormat = 2}, + { label = 'foocar', sortText = 'j', insertText = 'foodar()${0}', insertTextFormat = 2 }, -- plain text { label = 'foocar', @@ -140,32 +152,32 @@ describe("vim.lsp._completion", function() result = vim.tbl_map(function(x) return { abbr = x.abbr, - word = x.word + word = x.word, } end, result.items) eq(expected, result) end) - it("uses correct start boundary", function() + it('uses correct start boundary', function() local completion_list = { isIncomplete = false, items = { { - filterText = "this_thread", - insertText = "this_thread", + filterText = 'this_thread', + insertText = 'this_thread', insertTextFormat = 1, kind = 9, - label = " this_thread", + label = ' this_thread', score = 1.3205767869949, - sortText = "4056f757this_thread", + sortText = '4056f757this_thread', textEdit = { - newText = "this_thread", + newText = 'this_thread', range = { start = { line = 0, character = 7 }, - ["end"] = { line = 0, character = 11 }, + ['end'] = { line = 0, character = 11 }, }, - } + }, }, - } + }, } local expected = { abbr = ' this_thread', @@ -176,50 +188,50 @@ describe("vim.lsp._completion", function() menu = '', word = 'this_thread', } - local result = complete(" std::this|", completion_list) + local result = complete(' std::this|', completion_list) eq(7, result.server_start_boundary) local item = result.items[1] item.user_data = nil eq(expected, item) end) - it("should search from start boundary to cursor position", function() + it('should search from start boundary to cursor position', function() local completion_list = { isIncomplete = false, items = { { - filterText = "this_thread", - insertText = "this_thread", + filterText = 'this_thread', + insertText = 'this_thread', insertTextFormat = 1, kind = 9, - label = " this_thread", + label = ' this_thread', score = 1.3205767869949, - sortText = "4056f757this_thread", + sortText = '4056f757this_thread', textEdit = { - newText = "this_thread", + newText = 'this_thread', range = { start = { line = 0, character = 7 }, - ["end"] = { line = 0, character = 11 }, + ['end'] = { line = 0, character = 11 }, }, - } + }, }, { - filterText = "notthis_thread", - insertText = "notthis_thread", + filterText = 'notthis_thread', + insertText = 'notthis_thread', insertTextFormat = 1, kind = 9, - label = " notthis_thread", + label = ' notthis_thread', score = 1.3205767869949, - sortText = "4056f757this_thread", + sortText = '4056f757this_thread', textEdit = { - newText = "notthis_thread", + newText = 'notthis_thread', range = { start = { line = 0, character = 7 }, - ["end"] = { line = 0, character = 11 }, + ['end'] = { line = 0, character = 11 }, }, - } + }, }, - } + }, } local expected = { abbr = ' this_thread', @@ -230,10 +242,38 @@ describe("vim.lsp._completion", function() menu = '', word = 'this_thread', } - local result = complete(" std::this|is", completion_list) + local result = complete(' std::this|is', completion_list) eq(1, #result.items) local item = result.items[1] item.user_data = nil eq(expected, item) end) + + it('uses defaults from itemDefaults', function() + --- @type lsp.CompletionList + local completion_list = { + isIncomplete = false, + itemDefaults = { + editRange = { + start = { line = 1, character = 1 }, + ['end'] = { line = 1, character = 4 }, + }, + insertTextFormat = 2, + data = 'foobar', + }, + items = { + { + label = 'hello', + data = 'item-property-has-priority', + textEditText = 'hello', + }, + }, + } + local result = complete('|', completion_list) + eq(1, #result.items) + local item = result.items[1].user_data.nvim.lsp.completion_item --- @type lsp.CompletionItem + eq(2, item.insertTextFormat) + eq('item-property-has-priority', item.data) + eq({ line = 1, character = 1 }, item.textEdit.range.start) + end) end) diff --git a/test/functional/plugin/lsp/diagnostic_spec.lua b/test/functional/plugin/lsp/diagnostic_spec.lua index 1da0222114..705c182df7 100644 --- a/test/functional/plugin/lsp/diagnostic_spec.lua +++ b/test/functional/plugin/lsp/diagnostic_spec.lua @@ -12,10 +12,10 @@ describe('vim.lsp.diagnostic', function() local fake_uri before_each(function() - clear {env={ - NVIM_LUA_NOTRACK="1"; - VIMRUNTIME=os.getenv"VIMRUNTIME"; - }} + clear { env = { + NVIM_LUA_NOTRACK = '1', + VIMRUNTIME = os.getenv 'VIMRUNTIME', + } } exec_lua [[ require('vim.lsp') @@ -76,9 +76,10 @@ describe('vim.lsp.diagnostic', function() } ]] - fake_uri = "file:///fake/uri" + fake_uri = 'file:///fake/uri' - exec_lua([[ + exec_lua( + [[ fake_uri = ... diagnostic_bufnr = vim.uri_to_bufnr(fake_uri) local lines = {"1st line of text", "2nd line of text", "wow", "cool", "more", "lines"} @@ -86,7 +87,9 @@ describe('vim.lsp.diagnostic', function() vim.api.nvim_buf_set_lines(diagnostic_bufnr, 0, 1, false, lines) vim.api.nvim_win_set_buf(0, diagnostic_bufnr) return diagnostic_bufnr - ]], fake_uri) + ]], + fake_uri + ) end) after_each(function() @@ -113,17 +116,18 @@ describe('vim.lsp.diagnostic', function() vim.lsp.diagnostic.get_line_diagnostics(diagnostic_bufnr, 1)[1], } ]] - eq({code = 42, data = "Hello world"}, result[1].user_data.lsp) + eq({ code = 42, data = 'Hello world' }, result[1].user_data.lsp) eq(42, result[1].code) eq(42, result[2].code) - eq("Hello world", result[2].data) + eq('Hello world', result[2].data) end) end) - describe("vim.lsp.diagnostic.on_publish_diagnostics", function() + describe('vim.lsp.diagnostic.on_publish_diagnostics', function() it('allows configuring the virtual text via vim.lsp.with', function() local expected_spacing = 10 - local extmarks = exec_lua([[ + local extmarks = exec_lua( + [[ PublishDiagnostics = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { virtual_text = { spacing = ..., @@ -139,7 +143,9 @@ describe('vim.lsp.diagnostic', function() ) return get_extmarks(diagnostic_bufnr, client_id) - ]], expected_spacing) + ]], + expected_spacing + ) local virt_text = extmarks[1][4].virt_text local spacing = virt_text[1][1] @@ -149,7 +155,8 @@ describe('vim.lsp.diagnostic', function() it('allows configuring the virtual text via vim.lsp.with using a function', function() local expected_spacing = 10 - local extmarks = exec_lua([[ + local extmarks = exec_lua( + [[ spacing = ... PublishDiagnostics = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { @@ -169,7 +176,9 @@ describe('vim.lsp.diagnostic', function() ) return get_extmarks(diagnostic_bufnr, client_id) - ]], expected_spacing) + ]], + expected_spacing + ) local virt_text = extmarks[1][4].virt_text local spacing = virt_text[1][1] @@ -179,11 +188,12 @@ describe('vim.lsp.diagnostic', function() it('allows filtering via severity limit', function() local get_extmark_count_with_severity = function(severity_limit) - return exec_lua([[ + return exec_lua( + [[ PublishDiagnostics = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { underline = false, virtual_text = { - severity_limit = ... + severity = { min = ... } }, }) @@ -196,20 +206,23 @@ describe('vim.lsp.diagnostic', function() ) return #get_extmarks(diagnostic_bufnr, client_id) - ]], severity_limit) + ]], + severity_limit + ) end -- No messages with Error or higher - eq(0, get_extmark_count_with_severity("Error")) + eq(0, get_extmark_count_with_severity('ERROR')) -- But now we don't filter it - eq(1, get_extmark_count_with_severity("Warning")) - eq(1, get_extmark_count_with_severity("Hint")) + eq(1, get_extmark_count_with_severity('WARN')) + eq(1, get_extmark_count_with_severity('HINT')) end) it('correctly handles UTF-16 offsets', function() - local line = "All 💼 and no 🎉 makes Jack a dull 👦" - local result = exec_lua([[ + local line = 'All 💼 and no 🎉 makes Jack a dull 👦' + local result = exec_lua( + [[ local line = ... vim.api.nvim_buf_set_lines(diagnostic_bufnr, 0, -1, false, {line}) @@ -225,7 +238,9 @@ describe('vim.lsp.diagnostic', function() vim.lsp.stop_client(client_id) vim.api.nvim_exec_autocmds('VimLeavePre', { modeline = false }) return diags - ]], line) + ]], + line + ) eq(1, #result) eq(exec_lua([[return vim.str_byteindex(..., 7, true)]], line), result[1].col) eq(exec_lua([[return vim.str_byteindex(..., 8, true)]], line), result[1].end_col) diff --git a/test/functional/plugin/lsp/handler_spec.lua b/test/functional/plugin/lsp/handler_spec.lua index 3086c23fe8..56e29e7337 100644 --- a/test/functional/plugin/lsp/handler_spec.lua +++ b/test/functional/plugin/lsp/handler_spec.lua @@ -8,21 +8,30 @@ local matches = helpers.matches describe('lsp-handlers', function() describe('vim.lsp._with_extend', function() it('should return a table with the default keys', function() - eq({hello = 'world' }, exec_lua [[ + eq( + { hello = 'world' }, + exec_lua [[ return vim.lsp._with_extend('test', { hello = 'world' }) - ]]) + ]] + ) end) it('should override with config keys', function() - eq({hello = 'universe', other = true}, exec_lua [[ + eq( + { hello = 'universe', other = true }, + exec_lua [[ return vim.lsp._with_extend('test', { other = true, hello = 'world' }, { hello = 'universe' }) - ]]) + ]] + ) end) it('should not allow invalid keys', function() matches( '.*Invalid option for `test`.*', - pcall_err(exec_lua, "return vim.lsp._with_extend('test', { hello = 'world' }, { invalid = true })") + pcall_err( + exec_lua, + "return vim.lsp._with_extend('test', { hello = 'world' }, { invalid = true })" + ) ) end) end) diff --git a/test/functional/plugin/lsp/helpers.lua b/test/functional/plugin/lsp/helpers.lua index 15e6a62781..97fa108500 100644 --- a/test/functional/plugin/lsp/helpers.lua +++ b/test/functional/plugin/lsp/helpers.lua @@ -4,18 +4,20 @@ local clear = helpers.clear local exec_lua = helpers.exec_lua local run = helpers.run local stop = helpers.stop -local NIL = helpers.NIL +local NIL = vim.NIL local M = {} function M.clear_notrace() -- problem: here be dragons -- solution: don't look too closely for dragons - clear {env={ - NVIM_LUA_NOTRACK="1"; - NVIM_APPNAME="nvim_lsp_test"; - VIMRUNTIME=os.getenv"VIMRUNTIME"; - }} + clear { + env = { + NVIM_LUA_NOTRACK = '1', + NVIM_APPNAME = 'nvim_lsp_test', + VIMRUNTIME = os.getenv 'VIMRUNTIME', + }, + } end M.create_server_definition = [[ @@ -79,7 +81,8 @@ M.fake_lsp_code = 'test/functional/fixtures/fake-lsp-server.lua' M.fake_lsp_logfile = 'Xtest-fake-lsp.log' local function fake_lsp_server_setup(test_name, timeout_ms, options, settings) - exec_lua([=[ + exec_lua( + [=[ lsp = require('vim.lsp') local test_name, fake_lsp_code, fake_lsp_logfile, timeout, options, settings = ... TEST_RPC_CLIENT_ID = lsp.start_client { @@ -115,33 +118,49 @@ local function fake_lsp_server_setup(test_name, timeout_ms, options, settings) vim.rpcnotify(1, "exit", ...) end; } - ]=], test_name, M.fake_lsp_code, M.fake_lsp_logfile, timeout_ms or 1e3, options or {}, settings or {}) + ]=], + test_name, + M.fake_lsp_code, + M.fake_lsp_logfile, + timeout_ms or 1e3, + options or {}, + settings or {} + ) end function M.test_rpc_server(config) if config.test_name then M.clear_notrace() - fake_lsp_server_setup(config.test_name, config.timeout_ms or 1e3, config.options, config.settings) + fake_lsp_server_setup( + config.test_name, + config.timeout_ms or 1e3, + config.options, + config.settings + ) end local client = setmetatable({}, { __index = function(_, name) -- Workaround for not being able to yield() inside __index for Lua 5.1 :( -- Otherwise I would just return the value here. return function(...) - return exec_lua([=[ + return exec_lua( + [=[ local name = ... if type(TEST_RPC_CLIENT[name]) == 'function' then return TEST_RPC_CLIENT[name](select(2, ...)) else return TEST_RPC_CLIENT[name] end - ]=], name, ...) + ]=], + name, + ... + ) end - end; + end, }) local code, signal local function on_request(method, args) - if method == "init" then + if method == 'init' then if config.on_init then config.on_init(client, unpack(args)) end diff --git a/test/functional/plugin/lsp/incremental_sync_spec.lua b/test/functional/plugin/lsp/incremental_sync_spec.lua index 724b3efb97..bd1842ceb5 100644 --- a/test/functional/plugin/lsp/incremental_sync_spec.lua +++ b/test/functional/plugin/lsp/incremental_sync_spec.lua @@ -1,13 +1,13 @@ -- Test suite for testing interactions with the incremental sync algorithms powering the LSP client local helpers = require('test.functional.helpers')(after_each) -local meths = helpers.meths +local api = helpers.api local clear = helpers.clear local eq = helpers.eq local exec_lua = helpers.exec_lua local feed = helpers.feed -before_each(function () +before_each(function() clear() exec_lua [[ local evname = ... @@ -52,19 +52,24 @@ before_each(function () ]] end) -local function test_edit(prev_buffer, edit_operations, expected_text_changes, offset_encoding, line_ending) +local function test_edit( + prev_buffer, + edit_operations, + expected_text_changes, + offset_encoding, + line_ending +) offset_encoding = offset_encoding or 'utf-16' line_ending = line_ending or '\n' - meths.buf_set_lines(0, 0, -1, true, prev_buffer) - exec_lua("return test_register(...)", 0, "test1", offset_encoding, line_ending) + api.nvim_buf_set_lines(0, 0, -1, true, prev_buffer) + exec_lua('return test_register(...)', 0, 'test1', offset_encoding, line_ending) for _, edit in ipairs(edit_operations) do feed(edit) end - eq(expected_text_changes, exec_lua("return get_events(...)" )) + eq(expected_text_changes, exec_lua('return get_events(...)')) exec_lua("test_unreg = 'test1'") - end describe('incremental synchronization', function() @@ -75,18 +80,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 0 + line = 0, }, ['end'] = { character = 0, - line = 0 - } + line = 0, + }, }, rangeLength = 0, - text = 'a' - } + text = 'a', + }, } - test_edit({""}, {"ia"}, expected_text_changes, 'utf-16', '\n') + test_edit({ '' }, { 'ia' }, expected_text_changes, 'utf-16', '\n') end) it('inserting a character in the middle of a the first line', function() local expected_text_changes = { @@ -94,18 +99,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 1, - line = 0 + line = 0, }, ['end'] = { character = 1, - line = 0 - } + line = 0, + }, }, rangeLength = 0, - text = 'a' - } + text = 'a', + }, } - test_edit({"ab"}, {"lia"}, expected_text_changes, 'utf-16', '\n') + test_edit({ 'ab' }, { 'lia' }, expected_text_changes, 'utf-16', '\n') end) it('deleting the only character in a buffer', function() local expected_text_changes = { @@ -113,18 +118,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 0 + line = 0, }, ['end'] = { character = 1, - line = 0 - } + line = 0, + }, }, rangeLength = 1, - text = '' - } + text = '', + }, } - test_edit({"a"}, {"x"}, expected_text_changes, 'utf-16', '\n') + test_edit({ 'a' }, { 'x' }, expected_text_changes, 'utf-16', '\n') end) it('deleting a character in the middle of the line', function() local expected_text_changes = { @@ -132,18 +137,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 1, - line = 0 + line = 0, }, ['end'] = { character = 2, - line = 0 - } + line = 0, + }, }, rangeLength = 1, - text = '' - } + text = '', + }, } - test_edit({"abc"}, {"lx"}, expected_text_changes, 'utf-16', '\n') + test_edit({ 'abc' }, { 'lx' }, expected_text_changes, 'utf-16', '\n') end) it('replacing a character', function() local expected_text_changes = { @@ -151,18 +156,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 0 + line = 0, }, ['end'] = { character = 1, - line = 0 - } + line = 0, + }, }, rangeLength = 1, - text = 'b' - } + text = 'b', + }, } - test_edit({"a"}, {"rb"}, expected_text_changes, 'utf-16', '\n') + test_edit({ 'a' }, { 'rb' }, expected_text_changes, 'utf-16', '\n') end) it('deleting a line', function() local expected_text_changes = { @@ -170,18 +175,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 0 + line = 0, }, ['end'] = { character = 0, - line = 1 - } + line = 1, + }, }, rangeLength = 12, - text = '' - } + text = '', + }, } - test_edit({"hello world"}, {"dd"}, expected_text_changes, 'utf-16', '\n') + test_edit({ 'hello world' }, { 'dd' }, expected_text_changes, 'utf-16', '\n') end) it('deleting an empty line', function() local expected_text_changes = { @@ -189,18 +194,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 1 + line = 1, }, ['end'] = { character = 0, - line = 2 - } + line = 2, + }, }, rangeLength = 1, - text = '' - } + text = '', + }, } - test_edit({"hello world", ""}, {"jdd"}, expected_text_changes, 'utf-16', '\n') + test_edit({ 'hello world', '' }, { 'jdd' }, expected_text_changes, 'utf-16', '\n') end) it('adding a line', function() local expected_text_changes = { @@ -212,14 +217,14 @@ describe('incremental synchronization', function() }, ['end'] = { character = 0, - line = 1 - } + line = 1, + }, }, rangeLength = 1, - text = '\nhello world\n' - } + text = '\nhello world\n', + }, } - test_edit({"hello world"}, {"yyp"}, expected_text_changes, 'utf-16', '\n') + test_edit({ 'hello world' }, { 'yyp' }, expected_text_changes, 'utf-16', '\n') end) it('adding an empty line', function() local expected_text_changes = { @@ -227,18 +232,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 11, - line = 0 + line = 0, }, ['end'] = { character = 0, - line = 1 - } + line = 1, + }, }, rangeLength = 1, - text = '\n\n' - } + text = '\n\n', + }, } - test_edit({"hello world"}, {"o"}, expected_text_changes, 'utf-16', '\n') + test_edit({ 'hello world' }, { 'o' }, expected_text_changes, 'utf-16', '\n') end) it('adding a line to an empty buffer', function() local expected_text_changes = { @@ -246,18 +251,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 0 + line = 0, }, ['end'] = { character = 0, - line = 1 - } + line = 1, + }, }, rangeLength = 1, - text = '\n\n' - } + text = '\n\n', + }, } - test_edit({""}, {"o"}, expected_text_changes, 'utf-16', '\n') + test_edit({ '' }, { 'o' }, expected_text_changes, 'utf-16', '\n') end) it('insert a line above the current line', function() local expected_text_changes = { @@ -265,18 +270,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 0 + line = 0, }, ['end'] = { character = 0, - line = 0 - } + line = 0, + }, }, rangeLength = 0, - text = '\n' - } + text = '\n', + }, } - test_edit({""}, {"O"}, expected_text_changes, 'utf-16', '\n') + test_edit({ '' }, { 'O' }, expected_text_changes, 'utf-16', '\n') end) end) describe('multi line edit', function() @@ -287,115 +292,115 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 4, - line = 1 + line = 1, }, ['end'] = { character = 9, - line = 1 - } + line = 1, + }, }, rangeLength = 5, - text = '' + text = '', }, -- delete "hello world\n" from line 2 { range = { ['start'] = { character = 0, - line = 2 + line = 2, }, ['end'] = { character = 0, - line = 3 - } + line = 3, + }, }, rangeLength = 12, - text = '' + text = '', }, -- delete "1234" from beginning of line 2 { range = { ['start'] = { character = 0, - line = 2 + line = 2, }, ['end'] = { character = 4, - line = 2 - } + line = 2, + }, }, rangeLength = 4, - text = '' + text = '', }, -- add " asdf" to end of line 1 { range = { ['start'] = { character = 4, - line = 1 + line = 1, }, ['end'] = { character = 4, - line = 1 - } + line = 1, + }, }, rangeLength = 0, - text = ' asdf' + text = ' asdf', }, -- delete " asdf\n" from line 2 { range = { ['start'] = { character = 0, - line = 2 + line = 2, }, ['end'] = { character = 0, - line = 3 - } + line = 3, + }, }, rangeLength = 6, - text = '' + text = '', }, -- undo entire deletion { range = { ['start'] = { character = 4, - line = 1 + line = 1, }, ['end'] = { character = 9, - line = 1 - } + line = 1, + }, }, rangeLength = 5, - text = "_fdsa\nhello world\n1234 asdf" + text = '_fdsa\nhello world\n1234 asdf', }, -- redo entire deletion { range = { ['start'] = { character = 4, - line = 1 + line = 1, }, ['end'] = { character = 9, - line = 3 - } + line = 3, + }, }, rangeLength = 27, - text = ' asdf' + text = ' asdf', }, } local original_lines = { - "\\begin{document}", - "test_fdsa", - "hello world", - "1234 asdf", - "\\end{document}" + '\\begin{document}', + 'test_fdsa', + 'hello world', + '1234 asdf', + '\\end{document}', } - test_edit(original_lines, {"jf_vejjbhhdu<C-R>"}, expected_text_changes, 'utf-16', '\n') + test_edit(original_lines, { 'jf_vejjbhhdu<C-R>' }, expected_text_changes, 'utf-16', '\n') end) end) @@ -404,64 +409,83 @@ describe('incremental synchronization', function() local expected_text_changes = { { range = { - ["end"] = { - character = 11, - line = 2 }, - ["start"] = { - character = 10, - line = 2 } }, + ['end'] = { + character = 11, + line = 2, + }, + ['start'] = { + character = 10, + line = 2, + }, + }, rangeLength = 1, text = '', - },{ + }, + { range = { - ["end"] = { + ['end'] = { character = 10, - line = 2 }, + line = 2, + }, start = { character = 10, - line = 2 } }, + line = 2, + }, + }, rangeLength = 0, text = '2', - },{ + }, + { range = { - ["end"] = { + ['end'] = { character = 11, - line = 3 }, - ["start"] = { + line = 3, + }, + ['start'] = { character = 10, - line = 3 } }, + line = 3, + }, + }, rangeLength = 1, - text = '' - },{ + text = '', + }, + { range = { ['end'] = { character = 10, - line = 3 }, + line = 3, + }, ['start'] = { character = 10, - line = 3 } }, + line = 3, + }, + }, rangeLength = 0, - text = '3' }, + text = '3', + }, { range = { ['end'] = { character = 0, - line = 3 }, + line = 3, + }, ['start'] = { character = 12, - line = 2 } }, + line = 2, + }, + }, rangeLength = 1, - text = '\n' - } + text = '\n', + }, } local original_lines = { - "\\begin{document}", - "\\section*{1}", - "\\section*{1}", - "\\section*{1}", - "\\end{document}" + '\\begin{document}', + '\\section*{1}', + '\\section*{1}', + '\\section*{1}', + '\\end{document}', } - test_edit(original_lines, {"3gg$h<C-V>jg<C-A>"}, expected_text_changes, 'utf-16', '\n') + test_edit(original_lines, { '3gg$h<C-V>jg<C-A>' }, expected_text_changes, 'utf-16', '\n') end) it('join and undo', function() local expected_text_changes = { @@ -469,44 +493,46 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 11, - line = 0 + line = 0, }, ['end'] = { character = 11, - line = 0 - } + line = 0, + }, }, rangeLength = 0, - text = ' test3' - },{ + text = ' test3', + }, + { range = { ['start'] = { character = 0, - line = 1 + line = 1, }, ['end'] = { character = 0, - line = 2 - } + line = 2, + }, }, rangeLength = 6, - text = '' - },{ + text = '', + }, + { range = { ['start'] = { character = 11, - line = 0 + line = 0, }, ['end'] = { character = 17, - line = 0 - } + line = 0, + }, }, rangeLength = 6, - text = '\ntest3' + text = '\ntest3', }, } - test_edit({"test1 test2", "test3"}, {"J", "u"}, expected_text_changes, 'utf-16', '\n') + test_edit({ 'test1 test2', 'test3' }, { 'J', 'u' }, expected_text_changes, 'utf-16', '\n') end) end) @@ -517,18 +543,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 0 + line = 0, }, ['end'] = { character = 2, - line = 0 - } + line = 0, + }, }, rangeLength = 2, - text = '' - } + text = '', + }, } - test_edit({"🔥"}, {"x"}, expected_text_changes, 'utf-16', '\n') + test_edit({ '🔥' }, { 'x' }, expected_text_changes, 'utf-16', '\n') end) it('replacing a multibyte character with matching prefix', function() local expected_text_changes = { @@ -536,24 +562,24 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 1 + line = 1, }, ['end'] = { character = 1, - line = 1 - } + line = 1, + }, }, rangeLength = 1, - text = '⟩' - } + text = '⟩', + }, } -- ⟨ is e29fa8, ⟩ is e29fa9 local original_lines = { - "\\begin{document}", - "⟨", - "\\end{document}", + '\\begin{document}', + '⟨', + '\\end{document}', } - test_edit(original_lines, {"jr⟩"}, expected_text_changes, 'utf-16', '\n') + test_edit(original_lines, { 'jr⟩' }, expected_text_changes, 'utf-16', '\n') end) it('replacing a multibyte character with matching suffix', function() local expected_text_changes = { @@ -561,24 +587,24 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 1 + line = 1, }, ['end'] = { character = 1, - line = 1 - } + line = 1, + }, }, rangeLength = 1, - text = 'ḟ' - } + text = 'ḟ', + }, } -- ฟ is e0b89f, ḟ is e1b89f local original_lines = { - "\\begin{document}", - "ฟ", - "\\end{document}", + '\\begin{document}', + 'ฟ', + '\\end{document}', } - test_edit(original_lines, {"jrḟ"}, expected_text_changes, 'utf-16', '\n') + test_edit(original_lines, { 'jrḟ' }, expected_text_changes, 'utf-16', '\n') end) it('inserting before a multibyte character', function() local expected_text_changes = { @@ -586,23 +612,23 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 1 + line = 1, }, ['end'] = { character = 0, - line = 1 - } + line = 1, + }, }, rangeLength = 0, - text = ' ' - } + text = ' ', + }, } local original_lines = { - "\\begin{document}", - "→", - "\\end{document}", + '\\begin{document}', + '→', + '\\end{document}', } - test_edit(original_lines, {"ji "}, expected_text_changes, 'utf-16', '\n') + test_edit(original_lines, { 'ji ' }, expected_text_changes, 'utf-16', '\n') end) it('deleting a multibyte character from a long line', function() local expected_text_changes = { @@ -610,23 +636,23 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 85, - line = 1 + line = 1, }, ['end'] = { character = 86, - line = 1 - } + line = 1, + }, }, rangeLength = 1, - text = '' - } + text = '', + }, } local original_lines = { - "\\begin{document}", - "→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→", - "\\end{document}", + '\\begin{document}', + '→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→', + '\\end{document}', } - test_edit(original_lines, {"jx"}, expected_text_changes, 'utf-16', '\n') + test_edit(original_lines, { 'jx' }, expected_text_changes, 'utf-16', '\n') end) it('deleting multiple lines containing multibyte characters', function() local expected_text_changes = { @@ -634,19 +660,25 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 1 + line = 1, }, ['end'] = { character = 0, - line = 3 - } + line = 3, + }, }, --utf 16 len of 🔥 is 2 rangeLength = 8, - text = '' - } + text = '', + }, } - test_edit({"a🔥", "b🔥", "c🔥", "d🔥"}, {"j2dd"}, expected_text_changes, 'utf-16', '\n') + test_edit( + { 'a🔥', 'b🔥', 'c🔥', 'd🔥' }, + { 'j2dd' }, + expected_text_changes, + 'utf-16', + '\n' + ) end) end) end) diff --git a/test/functional/plugin/lsp/inlay_hint_spec.lua b/test/functional/plugin/lsp/inlay_hint_spec.lua index d0d55df72b..192797b312 100644 --- a/test/functional/plugin/lsp/inlay_hint_spec.lua +++ b/test/functional/plugin/lsp/inlay_hint_spec.lua @@ -40,7 +40,7 @@ local grid_without_inlay_hints = [[ | ]] -local grid_with_inlay_hints = [[ +local grid_with_inlay_hints = [[ auto add(int a, int b)-> int { return a + b; } | | int main() { | @@ -60,7 +60,8 @@ before_each(function() screen:attach() exec_lua(create_server_definition) - exec_lua([[ + exec_lua( + [[ local response = ... server = _create_server({ capabilities = { @@ -77,7 +78,9 @@ before_each(function() vim.api.nvim_win_set_buf(0, bufnr) client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd }) - ]], response) + ]], + response + ) insert(text) exec_lua([[vim.lsp.inlay_hint.enable(bufnr)]]) @@ -145,7 +148,8 @@ describe('vim.lsp.inlay_hint', function() paddingRight = false, } - exec_lua([[ + exec_lua( + [[ local expected2 = ... server2 = _create_server({ capabilities = { @@ -159,7 +163,9 @@ describe('vim.lsp.inlay_hint', function() }) client2 = vim.lsp.start({ name = 'dummy2', cmd = server2.cmd }) vim.lsp.inlay_hint.enable(bufnr) - ]], expected2) + ]], + expected2 + ) --- @type vim.lsp.inlay_hint.get.ret local res = exec_lua([[return vim.lsp.inlay_hint.get()]]) diff --git a/test/functional/plugin/lsp/semantic_tokens_spec.lua b/test/functional/plugin/lsp/semantic_tokens_spec.lua index b7ac53f270..77e39c81c8 100644 --- a/test/functional/plugin/lsp/semantic_tokens_spec.lua +++ b/test/functional/plugin/lsp/semantic_tokens_spec.lua @@ -23,21 +23,20 @@ after_each(function() end) describe('semantic token highlighting', function() - local screen before_each(function() screen = Screen.new(40, 16) screen:attach() screen:set_default_attr_ids { - [1] = { bold = true, foreground = Screen.colors.Blue1 }; - [2] = { foreground = Screen.colors.DarkCyan }; - [3] = { foreground = Screen.colors.SlateBlue }; - [4] = { bold = true, foreground = Screen.colors.SeaGreen }; - [5] = { foreground = tonumber('0x6a0dad') }; - [6] = { foreground = Screen.colors.Blue1 }; - [7] = { bold = true, foreground = Screen.colors.DarkCyan }; - [8] = { bold = true, foreground = Screen.colors.SlateBlue }; - [9] = { bold = true, foreground = tonumber('0x6a0dad') }; + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.DarkCyan }, + [3] = { foreground = Screen.colors.SlateBlue }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen }, + [5] = { foreground = tonumber('0x6a0dad') }, + [6] = { foreground = Screen.colors.Blue1 }, + [7] = { bold = true, foreground = Screen.colors.DarkCyan }, + [8] = { bold = true, foreground = Screen.colors.SlateBlue }, + [9] = { bold = true, foreground = tonumber('0x6a0dad') }, } command([[ hi link @lsp.type.namespace Type ]]) command([[ hi link @lsp.type.function Special ]]) @@ -81,7 +80,8 @@ describe('semantic token highlighting', function() before_each(function() exec_lua(create_server_definition) - exec_lua([[ + exec_lua( + [[ local legend, response, edit_response = ... server = _create_server({ capabilities = { @@ -99,7 +99,11 @@ describe('semantic token highlighting', function() end, } }) - ]], legend, response, edit_response) + ]], + legend, + response, + edit_response + ) end) it('buffer is highlighted when attached', function() @@ -112,7 +116,8 @@ describe('semantic token highlighting', function() insert(text) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -125,11 +130,10 @@ describe('semantic token highlighting', function() {6:#endif} | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } + ]], + } end) it('use LspTokenUpdate and highlight_token', function() @@ -151,7 +155,8 @@ describe('semantic token highlighting', function() insert(text) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int {9:main}() | @@ -164,12 +169,10 @@ describe('semantic token highlighting', function() {6:#endif} | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } - + ]], + } end) it('buffer is unhighlighted when client is detached', function() @@ -186,7 +189,8 @@ describe('semantic token highlighting', function() vim.lsp.buf_detach_client(bufnr, client_id) ]]) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int main() | @@ -199,29 +203,30 @@ describe('semantic token highlighting', function() #endif | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } + ]], + } end) - it('buffer is highlighted and unhighlighted when semantic token highlighting is started and stopped' - , function() - exec_lua([[ + it( + 'buffer is highlighted and unhighlighted when semantic token highlighting is started and stopped', + function() + exec_lua([[ bufnr = vim.api.nvim_get_current_buf() vim.api.nvim_win_set_buf(0, bufnr) client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd }) ]]) - insert(text) + insert(text) - exec_lua([[ + exec_lua([[ vim.notify = function() end vim.lsp.semantic_tokens.stop(bufnr, client_id) ]]) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int main() | @@ -234,17 +239,17 @@ describe('semantic token highlighting', function() #endif | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } + ]], + } - exec_lua([[ + exec_lua([[ vim.lsp.semantic_tokens.start(bufnr, client_id) ]]) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -257,12 +262,12 @@ describe('semantic token highlighting', function() {6:#endif} | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } - end) + ]], + } + end + ) it('buffer is re-highlighted when force refreshed', function() exec_lua([[ @@ -273,7 +278,8 @@ describe('semantic token highlighting', function() insert(text) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -286,17 +292,17 @@ describe('semantic token highlighting', function() {6:#endif} | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } + ]], + } exec_lua([[ vim.lsp.semantic_tokens.force_refresh(bufnr) ]]) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -309,11 +315,11 @@ describe('semantic token highlighting', function() {6:#endif} | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], unchanged = true } + ]], + unchanged = true, + } local messages = exec_lua('return server.messages') local token_request_count = 0 @@ -352,7 +358,8 @@ describe('semantic token highlighting', function() ]]) insert(text) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -365,14 +372,14 @@ describe('semantic token highlighting', function() {6:#endif} | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } + ]], + } feed_command('%s/int x/int x()/') feed_command('noh') - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -383,13 +390,11 @@ describe('semantic token highlighting', function() {6:#else} | {6: printf("%d\n", x);} | {6:#endif} | - } | - } | - {1:~ }| - {1:~ }| - {1:~ }| + } |*2 + {1:~ }|*3 :noh | - ]] } + ]], + } end) it('prevents starting semantic token highlighting with invalid conditions', function() @@ -400,7 +405,7 @@ describe('semantic token highlighting', function() notifications = {} vim.notify = function(...) table.insert(notifications, 1, {...}) end ]]) - eq(false, exec_lua("return vim.lsp.buf_is_attached(bufnr, client_id)")) + eq(false, exec_lua('return vim.lsp.buf_is_attached(bufnr, client_id)')) insert(text) @@ -417,7 +422,8 @@ describe('semantic token highlighting', function() matches('%[LSP%] No client with id %d', notifications[1][1]) end) - it('opt-out: does not activate semantic token highlighting if disabled in client attach', + it( + 'opt-out: does not activate semantic token highlighting if disabled in client attach', function() exec_lua([[ bufnr = vim.api.nvim_get_current_buf() @@ -430,11 +436,12 @@ describe('semantic token highlighting', function() end), }) ]]) - eq(true, exec_lua("return vim.lsp.buf_is_attached(bufnr, client_id)")) + eq(true, exec_lua('return vim.lsp.buf_is_attached(bufnr, client_id)')) insert(text) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int main() | @@ -447,11 +454,10 @@ describe('semantic token highlighting', function() #endif | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } + ]], + } local notifications = exec_lua([[ local notifications = {} @@ -461,7 +467,8 @@ describe('semantic token highlighting', function() ]]) eq('[LSP] Server does not support semantic tokens', notifications[1][1]) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int main() | @@ -474,14 +481,15 @@ describe('semantic token highlighting', function() #endif | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], unchanged = true } - end) + ]], + unchanged = true, + } + end + ) - it('ignores null responses from the server', function() + it('ignores null responses from the server', function() exec_lua([[ local legend, response, edit_response = ... server2 = _create_server({ @@ -503,11 +511,12 @@ describe('semantic token highlighting', function() vim.api.nvim_win_set_buf(0, bufnr) client_id = vim.lsp.start({ name = 'dummy', cmd = server2.cmd }) ]]) - eq(true, exec_lua("return vim.lsp.buf_is_attached(bufnr, client_id)")) + eq(true, exec_lua('return vim.lsp.buf_is_attached(bufnr, client_id)')) insert(text) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int main() | @@ -520,15 +529,15 @@ describe('semantic token highlighting', function() #endif | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } + ]], + } end) it('does not send delta requests if not supported by server', function() - exec_lua([[ + exec_lua( + [[ local legend, response, edit_response = ... server2 = _create_server({ capabilities = { @@ -549,10 +558,15 @@ describe('semantic token highlighting', function() bufnr = vim.api.nvim_get_current_buf() vim.api.nvim_win_set_buf(0, bufnr) client_id = vim.lsp.start({ name = 'dummy', cmd = server2.cmd }) - ]], legend, response, edit_response) + ]], + legend, + response, + edit_response + ) insert(text) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -565,18 +579,18 @@ describe('semantic token highlighting', function() {6:#endif} | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } + ]], + } feed_command('%s/int x/int x()/') feed_command('noh') -- the highlights don't change because our fake server sent the exact -- same result for the same method (the full request). "x" would have -- changed to highlight index 3 had we sent a delta request - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -587,13 +601,11 @@ describe('semantic token highlighting', function() {6:#else} | {6: printf("%d\n", x);} | {6:#endif} | - } | - } | - {1:~ }| - {1:~ }| - {1:~ }| + } |*2 + {1:~ }|*3 :noh | - ]] } + ]], + } local messages = exec_lua('return server2.messages') local token_request_count = 0 for _, message in ipairs(messages) do @@ -631,24 +643,13 @@ describe('semantic token highlighting', function() }, }, expected_screen = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ char* {7:foo} = "\n"^; | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*14 | - ]]} + ]], + } end, }, { @@ -763,7 +764,8 @@ int main() }, }, expected_screen = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ #include <iostream> | int {8:main}() | { | @@ -774,13 +776,10 @@ int main() {6: comment} | {6: #endif} | ^} | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | - ]]} + ]], + } end, }, { @@ -824,24 +823,15 @@ b = "as"]], }, }, expected_screen = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ {6:-- comment} | local {7:a} = 1 | {2:b} = "as^" | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*12 | - ]]} + ]], + } end, }, { @@ -954,30 +944,24 @@ b = "as"]], }, }, expected_screen = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ pub fn {8:main}() { | break rust; | //{6:/ what?} | } | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*10 | - ]]} + ]], + } end, }, }) do it(test.it, function() exec_lua(create_server_definition) - exec_lua([[ + exec_lua( + [[ local legend, resp = ... server = _create_server({ capabilities = { @@ -995,7 +979,10 @@ b = "as"]], bufnr = vim.api.nvim_get_current_buf() vim.api.nvim_win_set_buf(0, bufnr) client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd }) - ]], test.legend, test.response) + ]], + test.legend, + test.response + ) insert(test.text) @@ -1037,7 +1024,7 @@ b = "as"]], end_col = 9, type = 'variable', marked = true, - } + }, }, expected2 = { { @@ -1050,47 +1037,26 @@ b = "as"]], end_col = 9, type = 'variable', marked = true, - } + }, }, expected_screen1 = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ char* {7:foo} = "\n"^; | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*14 | - ]]} + ]], + } end, expected_screen2 = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | char* {7:foo} = "\n"; | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*13 | - ]]} + ]], + } end, }, { @@ -1207,7 +1173,7 @@ int main() modifiers = {}, type = 'comment', marked = true, - } + }, }, expected2 = { { @@ -1289,10 +1255,11 @@ int main() modifiers = {}, type = 'comment', marked = true, - } + }, }, expected_screen1 = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -1304,15 +1271,14 @@ int main() {6: printf("%d\n", x);} | {6:#endif} | ^} | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | - ]]} + ]], + } end, expected_screen2 = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -1325,11 +1291,10 @@ int main() {6: printf("%d\n", x);} | {6:^#endif} | } | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]]} + ]], + } end, }, { @@ -1356,55 +1321,33 @@ int main() end_col = 6, type = 'variable', marked = true, - } - }, - expected2 = { + }, }, + expected2 = {}, expected_screen1 = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ {7:string} = "test^" | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*14 | - ]]} + ]], + } end, expected_screen2 = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*14 | - ]]} + ]], + } end, }, }) do it(test.it, function() exec_lua(create_server_definition) - exec_lua([[ + exec_lua( + [[ local legend, resp1, resp2 = ... server = _create_server({ capabilities = { @@ -1432,7 +1375,11 @@ int main() semantic_tokens.stop(bufnr, client_id) semantic_tokens.start(bufnr, client_id, { debounce = 10 }) end) - ]], test.legend, test.response1, test.response2) + ]], + test.legend, + test.response1, + test.response2 + ) insert(test.text1) @@ -1447,11 +1394,14 @@ int main() if test.edit then feed(test.edit) else - exec_lua([[ + exec_lua( + [[ local text = ... vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, vim.fn.split(text, "\n")) vim.wait(15) -- wait for debounce - ]], test.text2) + ]], + test.text2 + ) end test.expected_screen2() diff --git a/test/functional/plugin/lsp/utils_spec.lua b/test/functional/plugin/lsp/utils_spec.lua index 804dc32f0d..bb9cdb8390 100644 --- a/test/functional/plugin/lsp/utils_spec.lua +++ b/test/functional/plugin/lsp/utils_spec.lua @@ -10,7 +10,8 @@ describe('vim.lsp.util', function() describe('stylize_markdown', function() local stylize_markdown = function(content, opts) - return exec_lua([[ + return exec_lua( + [[ local bufnr = vim.uri_to_bufnr("file:///fake/uri") vim.fn.bufload(bufnr) @@ -20,14 +21,17 @@ describe('vim.lsp.util', function() local stripped_content = vim.lsp.util.stylize_markdown(bufnr, content, opts) return stripped_content - ]], content, opts) + ]], + content, + opts + ) end it('code fences', function() local lines = { - "```lua", + '```lua', "local hello = 'world'", - "```", + '```', } local expected = { "local hello = 'world'", @@ -38,9 +42,9 @@ describe('vim.lsp.util', function() it('code fences with whitespace surrounded info string', function() local lines = { - "``` lua ", + '``` lua ', "local hello = 'world'", - "```", + '```', } local expected = { "local hello = 'world'", @@ -51,16 +55,16 @@ describe('vim.lsp.util', function() it('adds separator after code block', function() local lines = { - "```lua", + '```lua', "local hello = 'world'", - "```", - "", - "something", + '```', + '', + 'something', } local expected = { "local hello = 'world'", - "─────────────────────", - "something", + '─────────────────────', + 'something', } local opts = { separator = true } eq(expected, stylize_markdown(lines, opts)) @@ -68,28 +72,28 @@ describe('vim.lsp.util', function() it('replaces supported HTML entities', function() local lines = { - "1 < 2", - "3 > 2", - ""quoted"", - "'apos'", - "   ", - "&", + '1 < 2', + '3 > 2', + '"quoted"', + ''apos'', + '   ', + '&', } local expected = { - "1 < 2", - "3 > 2", + '1 < 2', + '3 > 2', '"quoted"', "'apos'", - " ", - "&", + ' ', + '&', } local opts = {} eq(expected, stylize_markdown(lines, opts)) end) end) - describe('normalize_markdown', function () - it('collapses consecutive blank lines', function () + describe('normalize_markdown', function() + it('collapses consecutive blank lines', function() local result = exec_lua [[ local lines = { 'foo', @@ -102,11 +106,11 @@ describe('vim.lsp.util', function() } return vim.lsp.util._normalize_markdown(lines) ]] - local expected = {'foo', '', 'bar', '', 'baz'} + local expected = { 'foo', '', 'bar', '', 'baz' } eq(expected, result) end) - it('removes preceding and trailing empty lines', function () + it('removes preceding and trailing empty lines', function() local result = exec_lua [[ local lines = { '', @@ -117,103 +121,105 @@ describe('vim.lsp.util', function() } return vim.lsp.util._normalize_markdown(lines) ]] - local expected = {'foo', 'bar'} + local expected = { 'foo', 'bar' } eq(expected, result) end) end) - describe("make_floating_popup_options", function () - + describe('make_floating_popup_options', function() local function assert_anchor(anchor_bias, expected_anchor) - local opts = exec_lua([[ + local opts = exec_lua( + [[ local args = { ... } local anchor_bias = args[1] return vim.lsp.util.make_floating_popup_options(30, 10, { anchor_bias = anchor_bias }) - ]], anchor_bias) + ]], + anchor_bias + ) - eq(expected_anchor, string.sub(opts.anchor, 1, 1)) + eq(expected_anchor, string.sub(opts.anchor, 1, 1)) end local screen - before_each(function () + before_each(function() helpers.clear() screen = Screen.new(80, 80) screen:attach() - feed("79i<CR><Esc>") -- fill screen with empty lines + feed('79i<CR><Esc>') -- fill screen with empty lines end) - describe('when on the first line it places window below', function () - before_each(function () + describe('when on the first line it places window below', function() + before_each(function() feed('gg') end) - it('for anchor_bias = "auto"', function () + it('for anchor_bias = "auto"', function() assert_anchor('auto', 'N') end) - it('for anchor_bias = "above"', function () + it('for anchor_bias = "above"', function() assert_anchor('above', 'N') end) - it('for anchor_bias = "below"', function () + it('for anchor_bias = "below"', function() assert_anchor('below', 'N') end) end) - describe('when on the last line it places window above', function () - before_each(function () + describe('when on the last line it places window above', function() + before_each(function() feed('G') end) - it('for anchor_bias = "auto"', function () + it('for anchor_bias = "auto"', function() assert_anchor('auto', 'S') end) - it('for anchor_bias = "above"', function () + it('for anchor_bias = "above"', function() assert_anchor('above', 'S') end) - it('for anchor_bias = "below"', function () + it('for anchor_bias = "below"', function() assert_anchor('below', 'S') end) end) - describe('with 20 lines above, 59 lines below', function () - before_each(function () + describe('with 20 lines above, 59 lines below', function() + before_each(function() feed('gg20j') end) - it('places window below for anchor_bias = "auto"', function () + it('places window below for anchor_bias = "auto"', function() assert_anchor('auto', 'N') end) - it('places window above for anchor_bias = "above"', function () + it('places window above for anchor_bias = "above"', function() assert_anchor('above', 'S') end) - it('places window below for anchor_bias = "below"', function () + it('places window below for anchor_bias = "below"', function() assert_anchor('below', 'N') end) end) - describe('with 59 lines above, 20 lines below', function () - before_each(function () + describe('with 59 lines above, 20 lines below', function() + before_each(function() feed('G20k') end) - it('places window above for anchor_bias = "auto"', function () + it('places window above for anchor_bias = "auto"', function() assert_anchor('auto', 'S') end) - it('places window above for anchor_bias = "above"', function () + it('places window above for anchor_bias = "above"', function() assert_anchor('above', 'S') end) - it('places window below for anchor_bias = "below"', function () + it('places window below for anchor_bias = "below"', function() assert_anchor('below', 'N') end) - it('bordered window truncates dimensions correctly', function () + it('bordered window truncates dimensions correctly', function() local opts = exec_lua([[ return vim.lsp.util.make_floating_popup_options(100, 100, { border = 'single' }) ]]) @@ -222,5 +228,4 @@ describe('vim.lsp.util', function() end) end) end) - end) diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 56d31a0e44..4826153edb 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -11,19 +11,20 @@ local eq = helpers.eq local eval = helpers.eval local matches = helpers.matches local pcall_err = helpers.pcall_err -local pesc = helpers.pesc +local pesc = vim.pesc local insert = helpers.insert -local funcs = helpers.funcs +local fn = helpers.fn local retry = helpers.retry local stop = helpers.stop -local NIL = helpers.NIL +local NIL = vim.NIL local read_file = require('test.helpers').read_file local write_file = require('test.helpers').write_file local is_ci = helpers.is_ci -local meths = helpers.meths +local api = helpers.api local is_os = helpers.is_os local skip = helpers.skip local mkdir = helpers.mkdir +local tmpname = helpers.tmpname local clear_notrace = lsp_helpers.clear_notrace local create_server_definition = lsp_helpers.create_server_definition @@ -32,14 +33,16 @@ local fake_lsp_logfile = lsp_helpers.fake_lsp_logfile local test_rpc_server = lsp_helpers.test_rpc_server local function get_buf_option(name, bufnr) - bufnr = bufnr or "BUFFER" - return exec_lua( - string.format("return vim.api.nvim_get_option_value('%s', { buf = %s })", name, bufnr) - ) + bufnr = bufnr or 'BUFFER' + return exec_lua( + string.format("return vim.api.nvim_get_option_value('%s', { buf = %s })", name, bufnr) + ) end -- TODO(justinmk): hangs on Windows https://github.com/neovim/neovim/pull/11837 -if skip(is_os('win')) then return end +if skip(is_os('win')) then + return +end teardown(function() os.remove(fake_lsp_logfile) @@ -51,8 +54,9 @@ describe('LSP', function() -- Run an instance of nvim on the file which contains our "scripts". -- Pass TEST_NAME to pick the script. - local test_name = "basic_init" - exec_lua([=[ + local test_name = 'basic_init' + exec_lua( + [=[ lsp = require('vim.lsp') local test_name, fake_lsp_code, fake_lsp_logfile = ... function test__start_client() @@ -71,12 +75,16 @@ describe('LSP', function() } end TEST_CLIENT1 = test__start_client() - ]=], test_name, fake_lsp_code, fake_lsp_logfile) + ]=], + test_name, + fake_lsp_code, + fake_lsp_logfile + ) end) after_each(function() exec_lua("vim.api.nvim_exec_autocmds('VimLeavePre', { modeline = false })") - -- exec_lua("lsp.stop_all_clients(true)") + -- exec_lua("lsp.stop_all_clients(true)") end) describe('server_name specified', function() @@ -84,14 +92,20 @@ describe('LSP', function() retry(nil, 4000, function() eq(1, exec_lua('return #lsp.get_clients()')) end) - eq(2, exec_lua([[ + eq( + 2, + exec_lua([[ TEST_CLIENT2 = test__start_client() return TEST_CLIENT2 - ]])) - eq(3, exec_lua([[ + ]]) + ) + eq( + 3, + exec_lua([[ TEST_CLIENT3 = test__start_client() return TEST_CLIENT3 - ]])) + ]]) + ) retry(nil, 4000, function() eq(3, exec_lua('return #lsp.get_clients()')) end) @@ -125,80 +139,62 @@ describe('LSP', function() end) end) end) - - describe('lsp._cmd_parts test', function() - local function _cmd_parts(input) - return exec_lua([[ - lsp = require('vim.lsp') - return lsp._cmd_parts(...) - ]], input) - end - it('should valid cmd argument', function() - eq(true, pcall(_cmd_parts, {"nvim"})) - eq(true, pcall(_cmd_parts, {"nvim", "--head"})) - end) - - it('should invalid cmd argument', function() - eq('.../lsp.lua:0: cmd: expected list, got nvim', - pcall_err(_cmd_parts, 'nvim')) - eq('.../lsp.lua:0: cmd argument: expected string, got number', - pcall_err(_cmd_parts, {'nvim', 1})) - end) - end) end) describe('LSP', function() describe('basic_init test', function() after_each(function() stop() - exec_lua("lsp.stop_client(lsp.get_clients(), true)") + exec_lua('lsp.stop_client(lsp.get_clients(), true)') exec_lua("vim.api.nvim_exec_autocmds('VimLeavePre', { modeline = false })") end) it('should run correctly', function() local expected_handlers = { - {NIL, {}, {method="test", client_id=1}}; + { NIL, {}, { method = 'test', client_id = 1 } }, } test_rpc_server { - test_name = "basic_init"; + test_name = 'basic_init', on_init = function(client, _) -- client is a dummy object which will queue up commands to be run -- once the server initializes. It can't accept lua callbacks or -- other types that may be unserializable for now. client.stop() - end; + end, -- If the program timed out, then code will be nil. on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, -- Note that NIL must be used here. -- on_handler(err, method, result, client_id) on_handler = function(...) - eq(table.remove(expected_handlers), {...}) - end; + eq(table.remove(expected_handlers), { ... }) + end, } end) it('should fail', function() local expected_handlers = { - {NIL, {}, {method="test", client_id=1}}; + { NIL, {}, { method = 'test', client_id = 1 } }, } test_rpc_server { - test_name = "basic_init"; + test_name = 'basic_init', on_init = function(client) client.notify('test') client.stop() - end; + end, on_exit = function(code, signal) - eq(101, code, "exit code") -- See fake-lsp-server.lua - eq(0, signal, "exit signal") - assert_log(pesc([[assert_eq failed: left == "\"shutdown\"", right == "\"test\""]]), - fake_lsp_logfile) - end; + eq(101, code, 'exit code') -- See fake-lsp-server.lua + eq(0, signal, 'exit signal') + assert_log( + pesc([[assert_eq failed: left == "\"shutdown\"", right == "\"test\""]]), + fake_lsp_logfile + ) + end, on_handler = function(...) - eq(table.remove(expected_handlers), {...}, "expected handler") - end; + eq(table.remove(expected_handlers), { ... }, 'expected handler') + end, } end) @@ -209,8 +205,8 @@ describe('LSP', function() client.stop() end, on_exit = function(code, signal) - eq(0, code, 'exit code', fake_lsp_logfile) - eq(0, signal, 'exit signal', fake_lsp_logfile) + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') end, settings = { dummy = 1, @@ -218,10 +214,12 @@ describe('LSP', function() }) end) - it("should set the client's offset_encoding when positionEncoding capability is supported", function() - clear() - exec_lua(create_server_definition) - local result = exec_lua([[ + it( + "should set the client's offset_encoding when positionEncoding capability is supported", + function() + clear() + exec_lua(create_server_definition) + local result = exec_lua([[ local server = _create_server({ capabilities = { positionEncoding = "utf-8" @@ -243,8 +241,9 @@ describe('LSP', function() end return client.offset_encoding ]]) - eq('utf-8', result) - end) + eq('utf-8', result) + end + ) it('should succeed with manual shutdown', function() if is_ci() then @@ -254,68 +253,68 @@ describe('LSP', function() return end local expected_handlers = { - {NIL, {}, {method="shutdown", bufnr=1, client_id=1}}; - {NIL, {}, {method="test", client_id=1}}; + { NIL, {}, { method = 'shutdown', bufnr = 1, client_id = 1 } }, + { NIL, {}, { method = 'test', client_id = 1 } }, } test_rpc_server { - test_name = "basic_init"; + test_name = 'basic_init', on_init = function(client) eq(0, client.server_capabilities().textDocumentSync.change) client.request('shutdown') client.notify('exit') client.stop() - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(...) - eq(table.remove(expected_handlers), {...}, "expected handler") - end; + eq(table.remove(expected_handlers), { ... }, 'expected handler') + end, } end) it('should detach buffer in response to nvim_buf_detach', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="finish", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'finish', client_id = 1 } }, } local client test_rpc_server { - test_name = "basic_finish"; + test_name = 'basic_finish', on_setup = function() exec_lua [[ BUFFER = vim.api.nvim_create_buf(false, true) ]] - eq(true, exec_lua("return lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)")) - eq(true, exec_lua("return lsp.buf_is_attached(BUFFER, TEST_RPC_CLIENT_ID)")) + eq(true, exec_lua('return lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)')) + eq(true, exec_lua('return lsp.buf_is_attached(BUFFER, TEST_RPC_CLIENT_ID)')) exec_lua [[ vim.api.nvim_command(BUFFER.."bwipeout") ]] - end; + end, on_init = function(_client) client = _client client.notify('finish') - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(err, result, ctx) - eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler") + eq(table.remove(expected_handlers), { err, result, ctx }, 'expected handler') if ctx.method == 'finish' then - exec_lua("return lsp.buf_detach_client(BUFFER, TEST_RPC_CLIENT_ID)") - eq(false, exec_lua("return lsp.buf_is_attached(BUFFER, TEST_RPC_CLIENT_ID)")) + exec_lua('return lsp.buf_detach_client(BUFFER, TEST_RPC_CLIENT_ID)') + eq(false, exec_lua('return lsp.buf_is_attached(BUFFER, TEST_RPC_CLIENT_ID)')) client.stop() end - end; + end, } end) it('should fire autocommands on attach and detach', function() local client test_rpc_server { - test_name = "basic_init"; + test_name = 'basic_init', on_setup = function() exec_lua [[ BUFFER = vim.api.nvim_create_buf(false, true) @@ -332,69 +331,75 @@ describe('LSP', function() end, }) ]] - end; + end, on_init = function(_client) client = _client - eq(true, exec_lua("return lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)")) + eq(true, exec_lua('return lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)')) client.notify('finish') - end; + end, on_handler = function(_, _, ctx) if ctx.method == 'finish' then - eq('basic_init', meths.get_var('lsp_attached')) - exec_lua("return lsp.buf_detach_client(BUFFER, TEST_RPC_CLIENT_ID)") - eq('basic_init', meths.get_var('lsp_detached')) + eq('basic_init', api.nvim_get_var('lsp_attached')) + exec_lua('return lsp.buf_detach_client(BUFFER, TEST_RPC_CLIENT_ID)') + eq('basic_init', api.nvim_get_var('lsp_detached')) client.stop() end - end; + end, } end) it('should set default options on attach', function() local client test_rpc_server { - test_name = "set_defaults_all_capabilities"; + test_name = 'set_defaults_all_capabilities', on_init = function(_client) client = _client exec_lua [[ BUFFER = vim.api.nvim_create_buf(false, true) lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID) ]] - end; + end, on_handler = function(_, _, ctx) if ctx.method == 'test' then - eq('v:lua.vim.lsp.tagfunc', get_buf_option("tagfunc")) - eq('v:lua.vim.lsp.omnifunc', get_buf_option("omnifunc")) - eq('v:lua.vim.lsp.formatexpr()', get_buf_option("formatexpr")) - eq('', get_buf_option("keywordprg")) - eq(true, exec_lua[[ + eq('v:lua.vim.lsp.tagfunc', get_buf_option('tagfunc')) + eq('v:lua.vim.lsp.omnifunc', get_buf_option('omnifunc')) + eq('v:lua.vim.lsp.formatexpr()', get_buf_option('formatexpr')) + eq('', get_buf_option('keywordprg')) + eq( + true, + exec_lua [[ local keymap vim.api.nvim_buf_call(BUFFER, function() keymap = vim.fn.maparg("K", "n", false, true) end) return keymap.callback == vim.lsp.buf.hover - ]]) + ]] + ) client.stop() end - end; + end, on_exit = function(_, _) - eq('', get_buf_option("tagfunc")) - eq('', get_buf_option("omnifunc")) - eq('', get_buf_option("formatexpr")) - eq('', exec_lua[[ + eq('', get_buf_option('tagfunc')) + eq('', get_buf_option('omnifunc')) + eq('', get_buf_option('formatexpr')) + eq( + '', + exec_lua [[ local keymap vim.api.nvim_buf_call(BUFFER, function() keymap = vim.fn.maparg("K", "n", false, false) end) return keymap - ]]) - end; + ]] + ) + end, } end) it('should overwrite options set by ftplugins', function() local client test_rpc_server { - test_name = "set_defaults_all_capabilities"; + test_name = 'set_defaults_all_capabilities', on_init = function(_client) client = _client exec_lua [[ @@ -406,35 +411,35 @@ describe('LSP', function() ]] -- Sanity check to ensure that some values are set after setting filetype. - eq('v:lua.require\'man\'.goto_tag', get_buf_option("tagfunc", "BUFFER_1")) - eq('xmlcomplete#CompleteTags', get_buf_option("omnifunc", "BUFFER_2")) - eq('xmlformat#Format()', get_buf_option("formatexpr", "BUFFER_2")) + eq("v:lua.require'man'.goto_tag", get_buf_option('tagfunc', 'BUFFER_1')) + eq('xmlcomplete#CompleteTags', get_buf_option('omnifunc', 'BUFFER_2')) + eq('xmlformat#Format()', get_buf_option('formatexpr', 'BUFFER_2')) exec_lua [[ lsp.buf_attach_client(BUFFER_1, TEST_RPC_CLIENT_ID) lsp.buf_attach_client(BUFFER_2, TEST_RPC_CLIENT_ID) ]] - end; + end, on_handler = function(_, _, ctx) if ctx.method == 'test' then - eq('v:lua.vim.lsp.tagfunc', get_buf_option("tagfunc", "BUFFER_1")) - eq('v:lua.vim.lsp.omnifunc', get_buf_option("omnifunc", "BUFFER_2")) - eq('v:lua.vim.lsp.formatexpr()', get_buf_option("formatexpr", "BUFFER_2")) + eq('v:lua.vim.lsp.tagfunc', get_buf_option('tagfunc', 'BUFFER_1')) + eq('v:lua.vim.lsp.omnifunc', get_buf_option('omnifunc', 'BUFFER_2')) + eq('v:lua.vim.lsp.formatexpr()', get_buf_option('formatexpr', 'BUFFER_2')) client.stop() end - end; + end, on_exit = function(_, _) - eq('', get_buf_option("tagfunc", "BUFFER_1")) - eq('', get_buf_option("omnifunc", "BUFFER_2")) - eq('', get_buf_option("formatexpr", "BUFFER_2")) - end; + eq('', get_buf_option('tagfunc', 'BUFFER_1')) + eq('', get_buf_option('omnifunc', 'BUFFER_2')) + eq('', get_buf_option('formatexpr', 'BUFFER_2')) + end, } end) it('should not overwrite user-defined options', function() local client test_rpc_server { - test_name = "set_defaults_all_capabilities"; + test_name = 'set_defaults_all_capabilities', on_init = function(_client) client = _client exec_lua [[ @@ -444,20 +449,20 @@ describe('LSP', function() vim.api.nvim_set_option_value('formatexpr', 'fex', { buf = BUFFER }) lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID) ]] - end; + end, on_handler = function(_, _, ctx) if ctx.method == 'test' then - eq('tfu', get_buf_option("tagfunc")) - eq('ofu', get_buf_option("omnifunc")) - eq('fex', get_buf_option("formatexpr")) + eq('tfu', get_buf_option('tagfunc')) + eq('ofu', get_buf_option('omnifunc')) + eq('fex', get_buf_option('formatexpr')) client.stop() end - end; + end, on_exit = function(_, _) - eq('tfu', get_buf_option("tagfunc")) - eq('ofu', get_buf_option("omnifunc")) - eq('fex', get_buf_option("formatexpr")) - end; + eq('tfu', get_buf_option('tagfunc')) + eq('ofu', get_buf_option('omnifunc')) + eq('fex', get_buf_option('formatexpr')) + end, } end) @@ -481,62 +486,76 @@ describe('LSP', function() num_attached_after = num_attached_after, } ]]) - eq(true, result ~= nil, "exec_lua must return result") + eq(true, result ~= nil, 'exec_lua must return result') eq(1, result.num_attached_before) eq(0, result.num_attached_after) end) it('client should return settings via workspace/configuration handler', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, { items = { - { section = "testSetting1" }; - { section = "testSetting2" }; - { section = "test.Setting3" }; - { section = "test.Setting4" }; - }}, { method="workspace/configuration", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { + NIL, + { + items = { + { section = 'testSetting1' }, + { section = 'testSetting2' }, + { section = 'test.Setting3' }, + { section = 'test.Setting4' }, + }, + }, + { method = 'workspace/configuration', client_id = 1 }, + }, + { NIL, {}, { method = 'start', client_id = 1 } }, } local client test_rpc_server { - test_name = "check_workspace_configuration"; + test_name = 'check_workspace_configuration', on_init = function(_client) client = _client - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(err, result, ctx) - eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler") + eq(table.remove(expected_handlers), { err, result, ctx }, 'expected handler') if ctx.method == 'start' then exec_lua([=[ local client = vim.lsp.get_client_by_id(TEST_RPC_CLIENT_ID) - client.config.settings = { + client.settings = { testSetting1 = true; testSetting2 = false; test = {Setting3 = 'nested' }; }]=]) end if ctx.method == 'workspace/configuration' then - local server_result = exec_lua([=[ + local server_result = exec_lua( + [=[ local method, params = ... - return require'vim.lsp.handlers'['workspace/configuration'](err, params, {method=method, client_id=TEST_RPC_CLIENT_ID})]=], ctx.method, result) + return require'vim.lsp.handlers'['workspace/configuration'](err, params, {method=method, client_id=TEST_RPC_CLIENT_ID})]=], + ctx.method, + result + ) client.notify('workspace/configuration', server_result) end if ctx.method == 'shutdown' then client.stop() end - end; + end, } end) - it('workspace/configuration returns NIL per section if client was started without config.settings', function() - local result = nil - test_rpc_server { - test_name = 'basic_init'; - on_init = function(c) c.stop() end, - on_setup = function() - result = exec_lua [[ + it( + 'workspace/configuration returns NIL per section if client was started without config.settings', + function() + local result = nil + test_rpc_server { + test_name = 'basic_init', + on_init = function(c) + c.stop() + end, + on_setup = function() + result = exec_lua [[ local result = { items = { {section = 'foo'}, @@ -545,52 +564,53 @@ describe('LSP', function() } return vim.lsp.handlers['workspace/configuration'](nil, result, {client_id=TEST_RPC_CLIENT_ID}) ]] - end - } - eq({ NIL, NIL }, result) - end) + end, + } + eq({ NIL, NIL }, result) + end + ) it('should verify capabilities sent', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, } test_rpc_server { - test_name = "basic_check_capabilities"; + test_name = 'basic_check_capabilities', on_init = function(client) client.stop() local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") eq(full_kind, client.server_capabilities().textDocumentSync.change) - eq({includeText = false}, client.server_capabilities().textDocumentSync.save) + eq({ includeText = false }, client.server_capabilities().textDocumentSync.save) eq(false, client.server_capabilities().codeLensProvider) - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(...) - eq(table.remove(expected_handlers), {...}, "expected handler") - end; + eq(table.remove(expected_handlers), { ... }, 'expected handler') + end, } end) it('BufWritePost sends didSave with bool textDocumentSync.save', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, } local client test_rpc_server { - test_name = "text_document_sync_save_bool"; + test_name = 'text_document_sync_save_bool', on_init = function(c) client = c - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(err, result, ctx) - eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler") - if ctx.method == "start" then + eq(table.remove(expected_handlers), { err, result, ctx }, 'expected handler') + if ctx.method == 'start' then exec_lua([=[ BUFFER = vim.api.nvim_get_current_buf() lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID) @@ -599,7 +619,7 @@ describe('LSP', function() else client.stop() end - end; + end, } end) @@ -664,7 +684,7 @@ describe('LSP', function() local messages = result.messages eq('textDocument/willSave', messages[3].method) eq('textDocument/willSaveWaitUntil', messages[4].method) - eq({'Hello'}, result.lines) + eq({ 'Hello' }, result.lines) end) it('saveas sends didOpen if filename changed', function() @@ -685,8 +705,8 @@ describe('LSP', function() on_handler = function(err, result, ctx) eq(table.remove(expected_handlers), { err, result, ctx }, 'expected handler') if ctx.method == 'start' then - local tmpfile_old = helpers.tmpname() - local tmpfile_new = helpers.tmpname() + local tmpfile_old = tmpname() + local tmpfile_new = tmpname() os.remove(tmpfile_new) exec_lua( [=[ @@ -709,22 +729,22 @@ describe('LSP', function() it('BufWritePost sends didSave including text if server capability is set', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, } local client test_rpc_server { - test_name = "text_document_sync_save_includeText"; + test_name = 'text_document_sync_save_includeText', on_init = function(c) client = c - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(err, result, ctx) - eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler") - if ctx.method == "start" then + eq(table.remove(expected_handlers), { err, result, ctx }, 'expected handler') + if ctx.method == 'start' then exec_lua([=[ BUFFER = vim.api.nvim_get_current_buf() vim.api.nvim_buf_set_lines(BUFFER, 0, -1, true, {"help me"}) @@ -734,16 +754,16 @@ describe('LSP', function() else client.stop() end - end; + end, } end) it('client.supports_methods() should validate capabilities', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, } test_rpc_server { - test_name = "capabilities_for_client_supports_method"; + test_name = 'capabilities_for_client_supports_method', on_init = function(client) client.stop() local expected_sync_capabilities = { @@ -761,268 +781,285 @@ describe('LSP', function() eq(true, client.server_capabilities().codeLensProvider.resolveProvider) -- known methods for resolved capabilities - eq(true, client.supports_method("textDocument/hover")) - eq(false, client.supports_method("textDocument/definition")) + eq(true, client.supports_method('textDocument/hover')) + eq(false, client.supports_method('textDocument/definition')) -- unknown methods are assumed to be supported. - eq(true, client.supports_method("unknown-method")) - end; + eq(true, client.supports_method('unknown-method')) + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(...) - eq(table.remove(expected_handlers), {...}, "expected handler") - end; + eq(table.remove(expected_handlers), { ... }, 'expected handler') + end, } end) it('should not call unsupported_method when trying to call an unsupported method', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, } test_rpc_server { - test_name = "capabilities_for_client_supports_method"; + test_name = 'capabilities_for_client_supports_method', on_setup = function() - exec_lua([=[ + exec_lua([=[ BUFFER = vim.api.nvim_get_current_buf() lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID) vim.lsp.handlers['textDocument/typeDefinition'] = function() end ]=]) - end; + end, on_init = function(client) client.stop() - exec_lua("vim.lsp.buf.type_definition()") + exec_lua('vim.lsp.buf.type_definition()') exec_lua [[ vim.api.nvim_command(BUFFER.."bwipeout") ]] - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(...) - eq(table.remove(expected_handlers), {...}, "expected handler") - end; + eq(table.remove(expected_handlers), { ... }, 'expected handler') + end, } end) - it('should not call unsupported_method when no client and trying to call an unsupported method', function() - local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - } - test_rpc_server { - test_name = "capabilities_for_client_supports_method"; - on_setup = function() + it( + 'should not call unsupported_method when no client and trying to call an unsupported method', + function() + local expected_handlers = { + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + } + test_rpc_server { + test_name = 'capabilities_for_client_supports_method', + on_setup = function() exec_lua([=[ vim.lsp.handlers['textDocument/typeDefinition'] = function() end ]=]) - end; - on_init = function(client) - client.stop() - exec_lua("vim.lsp.buf.type_definition()") - end; - on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; - on_handler = function(...) - eq(table.remove(expected_handlers), {...}, "expected handler") - end; - } - end) + end, + on_init = function(client) + client.stop() + exec_lua('vim.lsp.buf.type_definition()') + end, + on_exit = function(code, signal) + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, + on_handler = function(...) + eq(table.remove(expected_handlers), { ... }, 'expected handler') + end, + } + end + ) it('should not forward RequestCancelled to callback', function() local expected_handlers = { - {NIL, {}, {method="finish", client_id=1}}; + { NIL, {}, { method = 'finish', client_id = 1 } }, } local client test_rpc_server { - test_name = "check_forward_request_cancelled"; + test_name = 'check_forward_request_cancelled', on_init = function(_client) - _client.request("error_code_test") + _client.request('error_code_test') client = _client - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - eq(0, #expected_handlers, "did not call expected handler") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + eq(0, #expected_handlers, 'did not call expected handler') + end, on_handler = function(err, _, ctx) - eq(table.remove(expected_handlers), {err, {}, ctx}, "expected handler") - if ctx.method == 'finish' then client.stop() end - end; + eq(table.remove(expected_handlers), { err, {}, ctx }, 'expected handler') + if ctx.method == 'finish' then + client.stop() + end + end, } end) it('should forward ContentModified to callback', function() local expected_handlers = { - {NIL, {}, {method="finish", client_id=1}}; - {{code = -32801}, NIL, {method = "error_code_test", bufnr=1, client_id=1}}; + { NIL, {}, { method = 'finish', client_id = 1 } }, + { { code = -32801 }, NIL, { method = 'error_code_test', bufnr = 1, client_id = 1 } }, } local client test_rpc_server { - test_name = "check_forward_content_modified"; + test_name = 'check_forward_content_modified', on_init = function(_client) - _client.request("error_code_test") + _client.request('error_code_test') client = _client - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - eq(0, #expected_handlers, "did not call expected handler") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + eq(0, #expected_handlers, 'did not call expected handler') + end, on_handler = function(err, _, ctx) - eq(table.remove(expected_handlers), {err, _, ctx}, "expected handler") + eq(table.remove(expected_handlers), { err, _, ctx }, 'expected handler') -- if ctx.method == 'error_code_test' then client.notify("finish") end - if ctx.method ~= 'finish' then client.notify('finish') end - if ctx.method == 'finish' then client.stop() end - end; + if ctx.method ~= 'finish' then + client.notify('finish') + end + if ctx.method == 'finish' then + client.stop() + end + end, } end) it('should track pending requests to the language server', function() local expected_handlers = { - {NIL, {}, {method="finish", client_id=1}}; - {NIL, {}, {method="slow_request", bufnr=1, client_id=1}}; + { NIL, {}, { method = 'finish', client_id = 1 } }, + { NIL, {}, { method = 'slow_request', bufnr = 1, client_id = 1 } }, } local client test_rpc_server { - test_name = "check_pending_request_tracked"; + test_name = 'check_pending_request_tracked', on_init = function(_client) client = _client - client.request("slow_request") + client.request('slow_request') local request = exec_lua([=[ return TEST_RPC_CLIENT.requests[2] ]=]) - eq("slow_request", request.method) - eq("pending", request.type) - client.notify("release") - end; + eq('slow_request', request.method) + eq('pending', request.type) + client.notify('release') + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - eq(0, #expected_handlers, "did not call expected handler") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + eq(0, #expected_handlers, 'did not call expected handler') + end, on_handler = function(err, _, ctx) - eq(table.remove(expected_handlers), {err, {}, ctx}, "expected handler") + eq(table.remove(expected_handlers), { err, {}, ctx }, 'expected handler') if ctx.method == 'slow_request' then local request = exec_lua([=[ return TEST_RPC_CLIENT.requests[2] ]=]) eq(NIL, request) - client.notify("finish") + client.notify('finish') + end + if ctx.method == 'finish' then + client.stop() end - if ctx.method == 'finish' then client.stop() end - end; + end, } end) it('should track cancel requests to the language server', function() local expected_handlers = { - {NIL, {}, {method="finish", client_id=1}}; + { NIL, {}, { method = 'finish', client_id = 1 } }, } local client test_rpc_server { - test_name = "check_cancel_request_tracked"; + test_name = 'check_cancel_request_tracked', on_init = function(_client) client = _client - client.request("slow_request") + client.request('slow_request') client.cancel_request(2) local request = exec_lua([=[ return TEST_RPC_CLIENT.requests[2] ]=]) - eq("slow_request", request.method) - eq("cancel", request.type) - client.notify("release") - end; + eq('slow_request', request.method) + eq('cancel', request.type) + client.notify('release') + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - eq(0, #expected_handlers, "did not call expected handler") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + eq(0, #expected_handlers, 'did not call expected handler') + end, on_handler = function(err, _, ctx) - eq(table.remove(expected_handlers), {err, {}, ctx}, "expected handler") + eq(table.remove(expected_handlers), { err, {}, ctx }, 'expected handler') local request = exec_lua([=[ return TEST_RPC_CLIENT.requests[2] ]=]) eq(NIL, request) - if ctx.method == 'finish' then client.stop() end - end; + if ctx.method == 'finish' then + client.stop() + end + end, } end) it('should clear pending and cancel requests on reply', function() local expected_handlers = { - {NIL, {}, {method="finish", client_id=1}}; - {NIL, {}, {method="slow_request", bufnr=1, client_id=1}}; + { NIL, {}, { method = 'finish', client_id = 1 } }, + { NIL, {}, { method = 'slow_request', bufnr = 1, client_id = 1 } }, } local client test_rpc_server { - test_name = "check_tracked_requests_cleared"; + test_name = 'check_tracked_requests_cleared', on_init = function(_client) client = _client - client.request("slow_request") + client.request('slow_request') local request = exec_lua([=[ return TEST_RPC_CLIENT.requests[2] ]=]) - eq("slow_request", request.method) - eq("pending", request.type) + eq('slow_request', request.method) + eq('pending', request.type) client.cancel_request(2) request = exec_lua([=[ return TEST_RPC_CLIENT.requests[2] ]=]) - eq("slow_request", request.method) - eq("cancel", request.type) - client.notify("release") - end; + eq('slow_request', request.method) + eq('cancel', request.type) + client.notify('release') + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - eq(0, #expected_handlers, "did not call expected handler") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + eq(0, #expected_handlers, 'did not call expected handler') + end, on_handler = function(err, _, ctx) - eq(table.remove(expected_handlers), {err, {}, ctx}, "expected handler") + eq(table.remove(expected_handlers), { err, {}, ctx }, 'expected handler') if ctx.method == 'slow_request' then local request = exec_lua([=[ return TEST_RPC_CLIENT.requests[2] ]=]) eq(NIL, request) - client.notify("finish") + client.notify('finish') end - if ctx.method == 'finish' then client.stop() end - end; + if ctx.method == 'finish' then + client.stop() + end + end, } end) it('should trigger LspRequest autocmd when requests table changes', function() local expected_handlers = { - {NIL, {}, {method="finish", client_id=1}}; - {NIL, {}, {method="slow_request", bufnr=1, client_id=1}}; + { NIL, {}, { method = 'finish', client_id = 1 } }, + { NIL, {}, { method = 'slow_request', bufnr = 1, client_id = 1 } }, } local client test_rpc_server { - test_name = "check_tracked_requests_cleared"; + test_name = 'check_tracked_requests_cleared', on_init = function(_client) command('let g:requests = 0') command('autocmd LspRequest * let g:requests+=1') client = _client - client.request("slow_request") + client.request('slow_request') eq(1, eval('g:requests')) client.cancel_request(2) eq(2, eval('g:requests')) - client.notify("release") - end; + client.notify('release') + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - eq(0, #expected_handlers, "did not call expected handler") + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + eq(0, #expected_handlers, 'did not call expected handler') eq(3, eval('g:requests')) - end; + end, on_handler = function(err, _, ctx) - eq(table.remove(expected_handlers), {err, {}, ctx}, "expected handler") + eq(table.remove(expected_handlers), { err, {}, ctx }, 'expected handler') if ctx.method == 'slow_request' then - client.notify("finish") + client.notify('finish') + end + if ctx.method == 'finish' then + client.stop() end - if ctx.method == 'finish' then client.stop() end - end; + end, } end) it('should not send didOpen if the buffer closes before init', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="finish", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'finish', client_id = 1 } }, } local client test_rpc_server { - test_name = "basic_finish"; + test_name = 'basic_finish', on_setup = function() exec_lua [[ BUFFER = vim.api.nvim_create_buf(false, true) @@ -1031,42 +1068,42 @@ describe('LSP', function() "123"; }) ]] - eq(1, exec_lua("return TEST_RPC_CLIENT_ID")) - eq(true, exec_lua("return lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)")) - eq(true, exec_lua("return lsp.buf_is_attached(BUFFER, TEST_RPC_CLIENT_ID)")) + eq(1, exec_lua('return TEST_RPC_CLIENT_ID')) + eq(true, exec_lua('return lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)')) + eq(true, exec_lua('return lsp.buf_is_attached(BUFFER, TEST_RPC_CLIENT_ID)')) exec_lua [[ vim.api.nvim_command(BUFFER.."bwipeout") ]] - end; + end, on_init = function(_client) client = _client local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") eq(full_kind, client.server_capabilities().textDocumentSync.change) eq(true, client.server_capabilities().textDocumentSync.openClose) client.notify('finish') - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(err, result, ctx) - eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler") + eq(table.remove(expected_handlers), { err, result, ctx }, 'expected handler') if ctx.method == 'finish' then client.stop() end - end; + end, } end) it('should check the body sent attaching before init', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="finish", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'finish', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, } local client test_rpc_server { - test_name = "basic_check_buffer_open"; + test_name = 'basic_check_buffer_open', on_setup = function() exec_lua [[ BUFFER = vim.api.nvim_create_buf(false, true) @@ -1078,7 +1115,7 @@ describe('LSP', function() exec_lua [[ assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) ]] - end; + end, on_init = function(_client) client = _client local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") @@ -1087,32 +1124,32 @@ describe('LSP', function() exec_lua [[ assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID), "Already attached, returns true") ]] - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(err, result, ctx) if ctx.method == 'start' then client.notify('finish') end - eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler") + eq(table.remove(expected_handlers), { err, result, ctx }, 'expected handler') if ctx.method == 'finish' then client.stop() end - end; + end, } end) it('should check the body sent attaching after init', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="finish", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'finish', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, } local client test_rpc_server { - test_name = "basic_check_buffer_open"; + test_name = 'basic_check_buffer_open', on_setup = function() exec_lua [[ BUFFER = vim.api.nvim_create_buf(false, true) @@ -1121,7 +1158,7 @@ describe('LSP', function() "123"; }) ]] - end; + end, on_init = function(_client) client = _client local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") @@ -1130,32 +1167,32 @@ describe('LSP', function() exec_lua [[ assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) ]] - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(err, result, ctx) if ctx.method == 'start' then client.notify('finish') end - eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler") + eq(table.remove(expected_handlers), { err, result, ctx }, 'expected handler') if ctx.method == 'finish' then client.stop() end - end; + end, } end) it('should check the body and didChange full', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="finish", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'finish', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, } local client test_rpc_server { - test_name = "basic_check_buffer_open_and_change"; + test_name = 'basic_check_buffer_open_and_change', on_setup = function() exec_lua [[ BUFFER = vim.api.nvim_create_buf(false, true) @@ -1164,7 +1201,7 @@ describe('LSP', function() "123"; }) ]] - end; + end, on_init = function(_client) client = _client local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") @@ -1173,11 +1210,11 @@ describe('LSP', function() exec_lua [[ assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) ]] - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(err, result, ctx) if ctx.method == 'start' then exec_lua [[ @@ -1187,23 +1224,23 @@ describe('LSP', function() ]] client.notify('finish') end - eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler") + eq(table.remove(expected_handlers), { err, result, ctx }, 'expected handler') if ctx.method == 'finish' then client.stop() end - end; + end, } end) it('should check the body and didChange full with noeol', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="finish", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'finish', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, } local client test_rpc_server { - test_name = "basic_check_buffer_open_and_change_noeol"; + test_name = 'basic_check_buffer_open_and_change_noeol', on_setup = function() exec_lua [[ BUFFER = vim.api.nvim_create_buf(false, true) @@ -1213,7 +1250,7 @@ describe('LSP', function() }) vim.bo[BUFFER].eol = false ]] - end; + end, on_init = function(_client) client = _client local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") @@ -1222,11 +1259,11 @@ describe('LSP', function() exec_lua [[ assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) ]] - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(err, result, ctx) if ctx.method == 'start' then exec_lua [[ @@ -1236,37 +1273,41 @@ describe('LSP', function() ]] client.notify('finish') end - eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler") + eq(table.remove(expected_handlers), { err, result, ctx }, 'expected handler') if ctx.method == 'finish' then client.stop() end - end; + end, } end) it('should send correct range for inlay hints with noeol', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="finish", client_id=1}}; - {NIL, {}, { - method="textDocument/inlayHint", - params = { - textDocument = { - uri = 'file://', + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'finish', client_id = 1 } }, + { + NIL, + {}, + { + method = 'textDocument/inlayHint', + params = { + textDocument = { + uri = 'file://', + }, + range = { + start = { line = 0, character = 0 }, + ['end'] = { line = 1, character = 3 }, + }, }, - range = { - start = { line = 0, character = 0 }, - ['end'] = { line = 1, character = 3 }, - } + bufnr = 2, + client_id = 1, }, - bufnr=2, - client_id=1, - }}; - {NIL, {}, {method="start", client_id=1}}; + }, + { NIL, {}, { method = 'start', client_id = 1 } }, } local client test_rpc_server { - test_name = "inlay_hint"; + test_name = 'inlay_hint', on_setup = function() exec_lua [[ BUFFER = vim.api.nvim_create_buf(false, true) @@ -1276,18 +1317,18 @@ describe('LSP', function() }) vim.bo[BUFFER].eol = false ]] - end; + end, on_init = function(_client) client = _client eq(true, client.supports_method('textDocument/inlayHint')) exec_lua [[ assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) ]] - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(err, result, ctx) if ctx.method == 'start' then exec_lua [[ @@ -1297,26 +1338,26 @@ describe('LSP', function() if ctx.method == 'textDocument/inlayHint' then client.notify('finish') end - eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler") + eq(table.remove(expected_handlers), { err, result, ctx }, 'expected handler') if ctx.method == 'finish' then client.stop() end - end; + end, } end) it('should check the body and didChange incremental', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="finish", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'finish', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, } local client test_rpc_server { - test_name = "basic_check_buffer_open_and_change_incremental"; + test_name = 'basic_check_buffer_open_and_change_incremental', options = { allow_incremental_sync = true, - }; + }, on_setup = function() exec_lua [[ BUFFER = vim.api.nvim_create_buf(false, true) @@ -1325,20 +1366,21 @@ describe('LSP', function() "123"; }) ]] - end; + end, on_init = function(_client) client = _client - local sync_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Incremental") + local sync_kind = + exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Incremental") eq(sync_kind, client.server_capabilities().textDocumentSync.change) eq(true, client.server_capabilities().textDocumentSync.openClose) exec_lua [[ assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) ]] - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(err, result, ctx) if ctx.method == 'start' then exec_lua [[ @@ -1348,26 +1390,26 @@ describe('LSP', function() ]] client.notify('finish') end - eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler") + eq(table.remove(expected_handlers), { err, result, ctx }, 'expected handler') if ctx.method == 'finish' then client.stop() end - end; + end, } end) it('should check the body and didChange incremental with debounce', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="finish", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'finish', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, } local client test_rpc_server { - test_name = "basic_check_buffer_open_and_change_incremental"; + test_name = 'basic_check_buffer_open_and_change_incremental', options = { allow_incremental_sync = true, - debounce_text_changes = 5 - }; + debounce_text_changes = 5, + }, on_setup = function() exec_lua [[ BUFFER = vim.api.nvim_create_buf(false, true) @@ -1376,20 +1418,21 @@ describe('LSP', function() "123"; }) ]] - end; + end, on_init = function(_client) client = _client - local sync_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Incremental") + local sync_kind = + exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Incremental") eq(sync_kind, client.server_capabilities().textDocumentSync.change) eq(true, client.server_capabilities().textDocumentSync.openClose) exec_lua [[ assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) ]] - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(err, result, ctx) if ctx.method == 'start' then exec_lua [[ @@ -1399,24 +1442,24 @@ describe('LSP', function() ]] client.notify('finish') end - eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler") + eq(table.remove(expected_handlers), { err, result, ctx }, 'expected handler') if ctx.method == 'finish' then client.stop() end - end; + end, } end) -- TODO(askhan) we don't support full for now, so we can disable these tests. pending('should check the body and didChange incremental normal mode editing', function() local expected_handlers = { - {NIL, {}, {method="shutdown", bufnr=1, client_id=1}}; - {NIL, {}, {method="finish", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', bufnr = 1, client_id = 1 } }, + { NIL, {}, { method = 'finish', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, } local client test_rpc_server { - test_name = "basic_check_buffer_open_and_change_incremental_editing"; + test_name = 'basic_check_buffer_open_and_change_incremental_editing', on_setup = function() exec_lua [[ BUFFER = vim.api.nvim_create_buf(false, true) @@ -1425,42 +1468,43 @@ describe('LSP', function() "123"; }) ]] - end; + end, on_init = function(_client) client = _client - local sync_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Incremental") + local sync_kind = + exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Incremental") eq(sync_kind, client.server_capabilities().textDocumentSync.change) eq(true, client.server_capabilities().textDocumentSync.openClose) exec_lua [[ assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) ]] - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(err, result, ctx) if ctx.method == 'start' then - helpers.command("normal! 1Go") + helpers.command('normal! 1Go') client.notify('finish') end - eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler") + eq(table.remove(expected_handlers), { err, result, ctx }, 'expected handler') if ctx.method == 'finish' then client.stop() end - end; + end, } end) it('should check the body and didChange full with 2 changes', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="finish", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'finish', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, } local client test_rpc_server { - test_name = "basic_check_buffer_open_and_change_multi"; + test_name = 'basic_check_buffer_open_and_change_multi', on_setup = function() exec_lua [[ BUFFER = vim.api.nvim_create_buf(false, true) @@ -1469,7 +1513,7 @@ describe('LSP', function() "123"; }) ]] - end; + end, on_init = function(_client) client = _client local sync_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") @@ -1478,11 +1522,11 @@ describe('LSP', function() exec_lua [[ assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) ]] - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(err, result, ctx) if ctx.method == 'start' then exec_lua [[ @@ -1495,23 +1539,23 @@ describe('LSP', function() ]] client.notify('finish') end - eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler") + eq(table.remove(expected_handlers), { err, result, ctx }, 'expected handler') if ctx.method == 'finish' then client.stop() end - end; + end, } end) it('should check the body and didChange full lifecycle', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="finish", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'finish', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, } local client test_rpc_server { - test_name = "basic_check_buffer_open_and_change_multi_and_close"; + test_name = 'basic_check_buffer_open_and_change_multi_and_close', on_setup = function() exec_lua [[ BUFFER = vim.api.nvim_create_buf(false, true) @@ -1520,7 +1564,7 @@ describe('LSP', function() "123"; }) ]] - end; + end, on_init = function(_client) client = _client local sync_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") @@ -1529,12 +1573,12 @@ describe('LSP', function() exec_lua [[ assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) ]] - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; - on_handler = function(err, result,ctx) + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, + on_handler = function(err, result, ctx) if ctx.method == 'start' then exec_lua [[ vim.api.nvim_buf_set_lines(BUFFER, 1, 2, false, { @@ -1547,55 +1591,58 @@ describe('LSP', function() ]] client.notify('finish') end - eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler") + eq(table.remove(expected_handlers), { err, result, ctx }, 'expected handler') if ctx.method == 'finish' then client.stop() end - end; + end, } end) end) - describe("parsing tests", function() + describe('parsing tests', function() it('should handle invalid content-length correctly', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="finish", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'finish', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, } local client test_rpc_server { - test_name = "invalid_header"; - on_setup = function() - end; + test_name = 'invalid_header', + on_setup = function() end, on_init = function(_client) client = _client client.stop(true) - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(err, result, ctx) - eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler") - end; + eq(table.remove(expected_handlers), { err, result, ctx }, 'expected handler') + end, } end) it('should not trim vim.NIL from the end of a list', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="finish", client_id=1}}; - {NIL,{ - arguments = { "EXTRACT_METHOD", {metadata = {}}, 3, 0, 6123, NIL }, - command = "refactor.perform", - title = "EXTRACT_METHOD" - }, {method="workspace/executeCommand", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'finish', client_id = 1 } }, + { + NIL, + { + arguments = { 'EXTRACT_METHOD', { metadata = {} }, 3, 0, 6123, NIL }, + command = 'refactor.perform', + title = 'EXTRACT_METHOD', + }, + { method = 'workspace/executeCommand', client_id = 1 }, + }, + { NIL, {}, { method = 'start', client_id = 1 } }, } local client test_rpc_server { - test_name = "decode_nil"; + test_name = 'decode_nil', on_setup = function() exec_lua [[ BUFFER = vim.api.nvim_create_buf(false, true) @@ -1604,23 +1651,23 @@ describe('LSP', function() "123"; }) ]] - end; + end, on_init = function(_client) client = _client exec_lua [[ assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) ]] - end; + end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, on_handler = function(err, result, ctx) - eq(table.remove(expected_handlers), {err, result, ctx}, "expected handler") + eq(table.remove(expected_handlers), { err, result, ctx }, 'expected handler') if ctx.method == 'finish' then client.stop() end - end; + end, } end) end) @@ -1634,10 +1681,10 @@ describe('LSP', function() local function make_edit(y_0, x_0, y_1, x_1, text) return { range = { - start = { line = y_0, character = x_0 }; - ["end"] = { line = y_1, character = x_1 }; - }; - newText = type(text) == 'table' and table.concat(text, '\n') or (text or ""); + start = { line = y_0, character = x_0 }, + ['end'] = { line = y_1, character = x_1 }, + }, + newText = type(text) == 'table' and table.concat(text, '\n') or (text or ''), } end @@ -1652,121 +1699,121 @@ describe('LSP', function() end) it('applies simple edits', function() local edits = { - make_edit(0, 0, 0, 0, {"123"}); - make_edit(1, 0, 1, 1, {"2"}); - make_edit(2, 0, 2, 2, {"3"}); - make_edit(3, 2, 3, 4, {""}); + make_edit(0, 0, 0, 0, { '123' }), + make_edit(1, 0, 1, 1, { '2' }), + make_edit(2, 0, 2, 2, { '3' }), + make_edit(3, 2, 3, 4, { '' }), } - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-16") + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16') eq({ - '123First line of text'; - '2econd line of text'; - '3ird line of text'; - 'Foth line of text'; - 'å å ɧ 汉语 ↥ 🤦 🦄'; + '123First line of text', + '2econd line of text', + '3ird line of text', + 'Foth line of text', + 'å å ɧ 汉语 ↥ 🤦 🦄', }, buf_lines(1)) end) it('applies complex edits', function() local edits = { - make_edit(0, 0, 0, 0, {"", "12"}); - make_edit(0, 0, 0, 0, {"3", "foo"}); - make_edit(0, 1, 0, 1, {"bar", "123"}); - make_edit(0, #"First ", 0, #"First line of text", {"guy"}); - make_edit(1, 0, 1, #'Second', {"baz"}); - make_edit(2, #'Th', 2, #"Third", {"e next"}); - make_edit(3, #'', 3, #"Fourth", {"another line of text", "before this"}); - make_edit(3, #'Fourth', 3, #"Fourth line of text", {"!"}); + make_edit(0, 0, 0, 0, { '', '12' }), + make_edit(0, 0, 0, 0, { '3', 'foo' }), + make_edit(0, 1, 0, 1, { 'bar', '123' }), + make_edit(0, #'First ', 0, #'First line of text', { 'guy' }), + make_edit(1, 0, 1, #'Second', { 'baz' }), + make_edit(2, #'Th', 2, #'Third', { 'e next' }), + make_edit(3, #'', 3, #'Fourth', { 'another line of text', 'before this' }), + make_edit(3, #'Fourth', 3, #'Fourth line of text', { '!' }), } - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-16") + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16') eq({ - ''; - '123'; - 'fooFbar'; - '123irst guy'; - 'baz line of text'; - 'The next line of text'; - 'another line of text'; - 'before this!'; - 'å å ɧ 汉语 ↥ 🤦 🦄'; + '', + '123', + 'fooFbar', + '123irst guy', + 'baz line of text', + 'The next line of text', + 'another line of text', + 'before this!', + 'å å ɧ 汉语 ↥ 🤦 🦄', }, buf_lines(1)) end) it('applies complex edits (reversed range)', function() local edits = { - make_edit(0, 0, 0, 0, {"", "12"}); - make_edit(0, 0, 0, 0, {"3", "foo"}); - make_edit(0, 1, 0, 1, {"bar", "123"}); - make_edit(0, #"First line of text", 0, #"First ", {"guy"}); - make_edit(1, #'Second', 1, 0, {"baz"}); - make_edit(2, #"Third", 2, #'Th', {"e next"}); - make_edit(3, #"Fourth", 3, #'', {"another line of text", "before this"}); - make_edit(3, #"Fourth line of text", 3, #'Fourth', {"!"}); + make_edit(0, 0, 0, 0, { '', '12' }), + make_edit(0, 0, 0, 0, { '3', 'foo' }), + make_edit(0, 1, 0, 1, { 'bar', '123' }), + make_edit(0, #'First line of text', 0, #'First ', { 'guy' }), + make_edit(1, #'Second', 1, 0, { 'baz' }), + make_edit(2, #'Third', 2, #'Th', { 'e next' }), + make_edit(3, #'Fourth', 3, #'', { 'another line of text', 'before this' }), + make_edit(3, #'Fourth line of text', 3, #'Fourth', { '!' }), } - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-16") + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16') eq({ - ''; - '123'; - 'fooFbar'; - '123irst guy'; - 'baz line of text'; - 'The next line of text'; - 'another line of text'; - 'before this!'; - 'å å ɧ 汉语 ↥ 🤦 🦄'; + '', + '123', + 'fooFbar', + '123irst guy', + 'baz line of text', + 'The next line of text', + 'another line of text', + 'before this!', + 'å å ɧ 汉语 ↥ 🤦 🦄', }, buf_lines(1)) end) it('applies non-ASCII characters edits', function() local edits = { - make_edit(4, 3, 4, 4, {"ä"}); + make_edit(4, 3, 4, 4, { 'ä' }), } - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-16") + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16') eq({ - 'First line of text'; - 'Second line of text'; - 'Third line of text'; - 'Fourth line of text'; - 'å ä ɧ 汉语 ↥ 🤦 🦄'; + 'First line of text', + 'Second line of text', + 'Third line of text', + 'Fourth line of text', + 'å ä ɧ 汉语 ↥ 🤦 🦄', }, buf_lines(1)) end) it('applies text edits at the end of the document', function() local edits = { - make_edit(5, 0, 5, 0, "foobar"); + make_edit(5, 0, 5, 0, 'foobar'), } - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-16") + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16') eq({ - 'First line of text'; - 'Second line of text'; - 'Third line of text'; - 'Fourth line of text'; - 'å å ɧ 汉语 ↥ 🤦 🦄'; - 'foobar'; + 'First line of text', + 'Second line of text', + 'Third line of text', + 'Fourth line of text', + 'å å ɧ 汉语 ↥ 🤦 🦄', + 'foobar', }, buf_lines(1)) end) it('applies multiple text edits at the end of the document', function() local edits = { - make_edit(4, 0, 5, 0, ""); - make_edit(5, 0, 5, 0, "foobar"); + make_edit(4, 0, 5, 0, ''), + make_edit(5, 0, 5, 0, 'foobar'), } - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-16") + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16') eq({ - 'First line of text'; - 'Second line of text'; - 'Third line of text'; - 'Fourth line of text'; - 'foobar'; + 'First line of text', + 'Second line of text', + 'Third line of text', + 'Fourth line of text', + 'foobar', }, buf_lines(1)) end) it('it restores marks', function() local edits = { - make_edit(1, 0, 2, 5, "foobar"); - make_edit(4, 0, 5, 0, "barfoo"); + make_edit(1, 0, 2, 5, 'foobar'), + make_edit(4, 0, 5, 0, 'barfoo'), } eq(true, exec_lua('return vim.api.nvim_buf_set_mark(1, "a", 2, 1, {})')) - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-16") + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16') eq({ - 'First line of text'; - 'foobar line of text'; - 'Fourth line of text'; - 'barfoo'; + 'First line of text', + 'foobar line of text', + 'Fourth line of text', + 'barfoo', }, buf_lines(1)) local mark = exec_lua('return vim.api.nvim_buf_get_mark(1, "a")') eq({ 2, 1 }, mark) @@ -1774,16 +1821,16 @@ describe('LSP', function() it('it restores marks to last valid col', function() local edits = { - make_edit(1, 0, 2, 15, "foobar"); - make_edit(4, 0, 5, 0, "barfoo"); + make_edit(1, 0, 2, 15, 'foobar'), + make_edit(4, 0, 5, 0, 'barfoo'), } eq(true, exec_lua('return vim.api.nvim_buf_set_mark(1, "a", 2, 10, {})')) - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-16") + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16') eq({ - 'First line of text'; - 'foobarext'; - 'Fourth line of text'; - 'barfoo'; + 'First line of text', + 'foobarext', + 'Fourth line of text', + 'barfoo', }, buf_lines(1)) local mark = exec_lua('return vim.api.nvim_buf_get_mark(1, "a")') eq({ 2, 9 }, mark) @@ -1791,138 +1838,138 @@ describe('LSP', function() it('it restores marks to last valid line', function() local edits = { - make_edit(1, 0, 4, 5, "foobar"); - make_edit(4, 0, 5, 0, "barfoo"); + make_edit(1, 0, 4, 5, 'foobar'), + make_edit(4, 0, 5, 0, 'barfoo'), } eq(true, exec_lua('return vim.api.nvim_buf_set_mark(1, "a", 4, 1, {})')) - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-16") + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16') eq({ - 'First line of text'; - 'foobaro'; + 'First line of text', + 'foobaro', }, buf_lines(1)) local mark = exec_lua('return vim.api.nvim_buf_get_mark(1, "a")') eq({ 2, 1 }, mark) end) describe('cursor position', function() - it('don\'t fix the cursor if the range contains the cursor', function() - funcs.nvim_win_set_cursor(0, { 2, 6 }) + it("don't fix the cursor if the range contains the cursor", function() + fn.nvim_win_set_cursor(0, { 2, 6 }) local edits = { - make_edit(1, 0, 1, 19, 'Second line of text') + make_edit(1, 0, 1, 19, 'Second line of text'), } - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-16") + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16') eq({ - 'First line of text'; - 'Second line of text'; - 'Third line of text'; - 'Fourth line of text'; - 'å å ɧ 汉语 ↥ 🤦 🦄'; + 'First line of text', + 'Second line of text', + 'Third line of text', + 'Fourth line of text', + 'å å ɧ 汉语 ↥ 🤦 🦄', }, buf_lines(1)) - eq({ 2, 6 }, funcs.nvim_win_get_cursor(0)) + eq({ 2, 6 }, fn.nvim_win_get_cursor(0)) end) it('fix the cursor to the valid col if the content was removed', function() - funcs.nvim_win_set_cursor(0, { 2, 6 }) + fn.nvim_win_set_cursor(0, { 2, 6 }) local edits = { make_edit(1, 0, 1, 6, ''), - make_edit(1, 6, 1, 19, '') + make_edit(1, 6, 1, 19, ''), } - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-16") + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16') eq({ - 'First line of text'; - ''; - 'Third line of text'; - 'Fourth line of text'; - 'å å ɧ 汉语 ↥ 🤦 🦄'; + 'First line of text', + '', + 'Third line of text', + 'Fourth line of text', + 'å å ɧ 汉语 ↥ 🤦 🦄', }, buf_lines(1)) - eq({ 2, 0 }, funcs.nvim_win_get_cursor(0)) + eq({ 2, 0 }, fn.nvim_win_get_cursor(0)) end) it('fix the cursor to the valid row if the content was removed', function() - funcs.nvim_win_set_cursor(0, { 2, 6 }) + fn.nvim_win_set_cursor(0, { 2, 6 }) local edits = { make_edit(1, 0, 1, 6, ''), - make_edit(0, 18, 5, 0, '') + make_edit(0, 18, 5, 0, ''), } - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-16") + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16') eq({ - 'First line of text'; + 'First line of text', }, buf_lines(1)) - eq({ 1, 17 }, funcs.nvim_win_get_cursor(0)) + eq({ 1, 17 }, fn.nvim_win_get_cursor(0)) end) it('fix the cursor row', function() - funcs.nvim_win_set_cursor(0, { 3, 0 }) + fn.nvim_win_set_cursor(0, { 3, 0 }) local edits = { - make_edit(1, 0, 2, 0, '') + make_edit(1, 0, 2, 0, ''), } - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-16") + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16') eq({ - 'First line of text'; - 'Third line of text'; - 'Fourth line of text'; - 'å å ɧ 汉语 ↥ 🤦 🦄'; + 'First line of text', + 'Third line of text', + 'Fourth line of text', + 'å å ɧ 汉语 ↥ 🤦 🦄', }, buf_lines(1)) - eq({ 2, 0 }, funcs.nvim_win_get_cursor(0)) + eq({ 2, 0 }, fn.nvim_win_get_cursor(0)) end) it('fix the cursor col', function() -- append empty last line. See #22636 - exec_lua('vim.api.nvim_buf_set_lines(...)', 1, -1, -1, true, {''}) + exec_lua('vim.api.nvim_buf_set_lines(...)', 1, -1, -1, true, { '' }) - funcs.nvim_win_set_cursor(0, { 2, 11 }) + fn.nvim_win_set_cursor(0, { 2, 11 }) local edits = { - make_edit(1, 7, 1, 11, '') + make_edit(1, 7, 1, 11, ''), } - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-16") + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16') eq({ - 'First line of text'; - 'Second of text'; - 'Third line of text'; - 'Fourth line of text'; - 'å å ɧ 汉语 ↥ 🤦 🦄'; - ''; + 'First line of text', + 'Second of text', + 'Third line of text', + 'Fourth line of text', + 'å å ɧ 汉语 ↥ 🤦 🦄', + '', }, buf_lines(1)) - eq({ 2, 7 }, funcs.nvim_win_get_cursor(0)) + eq({ 2, 7 }, fn.nvim_win_get_cursor(0)) end) it('fix the cursor row and col', function() - funcs.nvim_win_set_cursor(0, { 2, 12 }) + fn.nvim_win_set_cursor(0, { 2, 12 }) local edits = { - make_edit(0, 11, 1, 12, '') + make_edit(0, 11, 1, 12, ''), } - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-16") + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16') eq({ - 'First line of text'; - 'Third line of text'; - 'Fourth line of text'; - 'å å ɧ 汉语 ↥ 🤦 🦄'; + 'First line of text', + 'Third line of text', + 'Fourth line of text', + 'å å ɧ 汉语 ↥ 🤦 🦄', }, buf_lines(1)) - eq({ 1, 11 }, funcs.nvim_win_get_cursor(0)) + eq({ 1, 11 }, fn.nvim_win_get_cursor(0)) end) end) describe('with LSP end line after what Vim considers to be the end line', function() it('applies edits when the last linebreak is considered a new line', function() local edits = { - make_edit(0, 0, 5, 0, {"All replaced"}); + make_edit(0, 0, 5, 0, { 'All replaced' }), } - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-16") - eq({'All replaced'}, buf_lines(1)) + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16') + eq({ 'All replaced' }, buf_lines(1)) end) - it('applies edits when the end line is 2 larger than vim\'s', function() + it("applies edits when the end line is 2 larger than vim's", function() local edits = { - make_edit(0, 0, 6, 0, {"All replaced"}); + make_edit(0, 0, 6, 0, { 'All replaced' }), } - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-16") - eq({'All replaced'}, buf_lines(1)) + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16') + eq({ 'All replaced' }, buf_lines(1)) end) it('applies edits with a column offset', function() local edits = { - make_edit(0, 0, 5, 2, {"All replaced"}); + make_edit(0, 0, 5, 2, { 'All replaced' }), } - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-16") - eq({'All replaced'}, buf_lines(1)) + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16') + eq({ 'All replaced' }, buf_lines(1)) end) end) end) @@ -1936,33 +1983,39 @@ describe('LSP', function() describe('with LSP end column out of bounds and start column at 0', function() it('applies edits at the end of the buffer', function() local edits = { - make_edit(0, 0, 1, 22, {'#include "whatever.h"\r\n#include <algorithm>\r'}); + make_edit(0, 0, 1, 22, { '#include "whatever.h"\r\n#include <algorithm>\r' }), } - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-8") - eq({'#include "whatever.h"', '#include <algorithm>'}, buf_lines(1)) + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-8') + eq({ '#include "whatever.h"', '#include <algorithm>' }, buf_lines(1)) end) it('applies edits in the middle of the buffer', function() local edits = { - make_edit(0, 0, 0, 22, {'#include "whatever.h"\r\n#include <algorithm>\r'}); + make_edit(0, 0, 0, 22, { '#include "whatever.h"\r\n#include <algorithm>\r' }), } - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-8") - eq({'#include "whatever.h"', '#include <algorithm>', 'Test line two 21 char'}, buf_lines(1)) + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-8') + eq( + { '#include "whatever.h"', '#include <algorithm>', 'Test line two 21 char' }, + buf_lines(1) + ) end) end) describe('with LSP end column out of bounds and start column NOT at 0', function() it('applies edits at the end of the buffer', function() local edits = { - make_edit(0, 2, 1, 22, {'#include "whatever.h"\r\n#include <algorithm>\r'}); + make_edit(0, 2, 1, 22, { '#include "whatever.h"\r\n#include <algorithm>\r' }), } - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-8") - eq({'Te#include "whatever.h"', '#include <algorithm>'}, buf_lines(1)) + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-8') + eq({ 'Te#include "whatever.h"', '#include <algorithm>' }, buf_lines(1)) end) it('applies edits in the middle of the buffer', function() local edits = { - make_edit(0, 2, 0, 22, {'#include "whatever.h"\r\n#include <algorithm>\r'}); + make_edit(0, 2, 0, 22, { '#include "whatever.h"\r\n#include <algorithm>\r' }), } - exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, "utf-8") - eq({'Te#include "whatever.h"', '#include <algorithm>', 'Test line two 21 char'}, buf_lines(1)) + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-8') + eq( + { 'Te#include "whatever.h"', '#include <algorithm>', 'Test line two 21 char' }, + buf_lines(1) + ) end) end) end) @@ -1972,12 +2025,12 @@ describe('LSP', function() local text_document_edit = function(editVersion) return { edits = { - make_edit(0, 0, 0, 3, "First ↥ 🤦 🦄") + make_edit(0, 0, 0, 3, 'First ↥ 🤦 🦄'), }, textDocument = { - uri = "file:///fake/uri"; - version = editVersion - } + uri = 'file:///fake/uri', + version = editVersion, + }, } end before_each(function() @@ -1991,49 +2044,63 @@ describe('LSP', function() it('correctly goes ahead with the edit if all is normal', function() exec_lua("vim.lsp.util.apply_text_document_edit(..., nil, 'utf-16')", text_document_edit(5)) eq({ - 'First ↥ 🤦 🦄 line of text'; - '2nd line of 语text'; + 'First ↥ 🤦 🦄 line of text', + '2nd line of 语text', }, buf_lines(target_bufnr)) end) it('always accepts edit with version = 0', function() - exec_lua([[ + exec_lua( + [[ local args = {...} local bufnr = select(1, ...) local text_edit = select(2, ...) vim.lsp.util.buf_versions[bufnr] = 10 vim.lsp.util.apply_text_document_edit(text_edit, nil, 'utf-16') - ]], target_bufnr, text_document_edit(0)) + ]], + target_bufnr, + text_document_edit(0) + ) eq({ - 'First ↥ 🤦 🦄 line of text'; - '2nd line of 语text'; + 'First ↥ 🤦 🦄 line of text', + '2nd line of 语text', }, buf_lines(target_bufnr)) end) it('skips the edit if the version of the edit is behind the local buffer ', function() local apply_edit_mocking_current_version = function(edit, versionedBuf) - exec_lua([[ + exec_lua( + [[ local args = {...} local versionedBuf = args[2] vim.lsp.util.buf_versions[versionedBuf.bufnr] = versionedBuf.currentVersion vim.lsp.util.apply_text_document_edit(args[1], nil, 'utf-16') - ]], edit, versionedBuf) + ]], + edit, + versionedBuf + ) end local baseText = { - '1st line of text'; - '2nd line of 语text'; + '1st line of text', + '2nd line of 语text', } eq(baseText, buf_lines(target_bufnr)) -- Apply an edit for an old version, should skip - apply_edit_mocking_current_version(text_document_edit(2), {currentVersion=7; bufnr=target_bufnr}) + apply_edit_mocking_current_version( + text_document_edit(2), + { currentVersion = 7, bufnr = target_bufnr } + ) eq(baseText, buf_lines(target_bufnr)) -- no change -- Sanity check that next version to current does apply change - apply_edit_mocking_current_version(text_document_edit(8), {currentVersion=7; bufnr=target_bufnr}) + apply_edit_mocking_current_version( + text_document_edit(8), + { currentVersion = 7, bufnr = target_bufnr } + ) eq({ - 'First ↥ 🤦 🦄 line of text'; - '2nd line of 语text'; + 'First ↥ 🤦 🦄 line of text', + '2nd line of 语text', }, buf_lines(target_bufnr)) end) end) @@ -2041,34 +2108,37 @@ describe('LSP', function() describe('workspace_apply_edit', function() it('workspace/applyEdit returns ApplyWorkspaceEditResponse', function() local expected_handlers = { - {NIL, {}, {method="test", client_id=1}}; + { NIL, {}, { method = 'test', client_id = 1 } }, } test_rpc_server { - test_name = "basic_init"; + test_name = 'basic_init', on_init = function(client, _) client.stop() - end; + end, -- If the program timed out, then code will be nil. on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, -- Note that NIL must be used here. -- on_handler(err, method, result, client_id) on_handler = function(...) local expected = { - applied = true; - failureReason = nil; + applied = true, + failureReason = nil, } - eq(expected, exec_lua [[ + eq( + expected, + exec_lua [[ local apply_edit = { label = nil; edit = {}; } return vim.lsp.handlers['workspace/applyEdit'](nil, apply_edit, {client_id = TEST_RPC_CLIENT_ID}) - ]]) - eq(table.remove(expected_handlers), {...}) - end; + ]] + ) + eq(table.remove(expected_handlers), { ... }) + end, } end) end) @@ -2078,12 +2148,12 @@ describe('LSP', function() return { edits = { -- NOTE: This is a hack if you have a line longer than 1000 it won't replace it - make_edit(row, 0, row, 1000, new_line) + make_edit(row, 0, row, 1000, new_line), }, textDocument = { - uri = "file:///fake/uri"; - version = editVersion - } + uri = 'file:///fake/uri', + version = editVersion, + }, } end @@ -2091,7 +2161,7 @@ describe('LSP', function() -- We should not stop applying the edits local make_workspace_edit = function(changes) return { - documentChanges = changes + documentChanges = changes, } end @@ -2127,7 +2197,7 @@ describe('LSP', function() it('apply_workspace_edit applies a single edit', function() local new_lines = { - "First Line", + 'First Line', } local edits = {} @@ -2135,10 +2205,13 @@ describe('LSP', function() table.insert(edits, replace_line_edit(row - 1, line, changedtick)) end - eq({ - "First Line", - "Original Line #2", - }, exec_lua([[ + eq( + { + 'First Line', + 'Original Line #2', + }, + exec_lua( + [[ local args = {...} local workspace_edits = args[1] local target_bufnr = args[2] @@ -2146,13 +2219,17 @@ describe('LSP', function() vim.lsp.util.apply_workspace_edit(workspace_edits, 'utf-16') return vim.api.nvim_buf_get_lines(target_bufnr, 0, -1, false) - ]], make_workspace_edit(edits), target_bufnr)) + ]], + make_workspace_edit(edits), + target_bufnr + ) + ) end) it('apply_workspace_edit applies multiple edits', function() local new_lines = { - "First Line", - "Second Line", + 'First Line', + 'Second Line', } local edits = {} @@ -2160,7 +2237,10 @@ describe('LSP', function() table.insert(edits, replace_line_edit(row - 1, line, changedtick)) end - eq(new_lines, exec_lua([[ + eq( + new_lines, + exec_lua( + [[ local args = {...} local workspace_edits = args[1] local target_bufnr = args[2] @@ -2168,10 +2248,14 @@ describe('LSP', function() vim.lsp.util.apply_workspace_edit(workspace_edits, 'utf-16') return vim.api.nvim_buf_get_lines(target_bufnr, 0, -1, false) - ]], make_workspace_edit(edits), target_bufnr)) + ]], + make_workspace_edit(edits), + target_bufnr + ) + ) end) it('Supports file creation with CreateFile payload', function() - local tmpfile = helpers.tmpname() + local tmpfile = tmpname() os.remove(tmpfile) -- Should not exist, only interested in a tmpname local uri = exec_lua('return vim.uri_from_fname(...)', tmpfile) local edit = { @@ -2180,29 +2264,32 @@ describe('LSP', function() kind = 'create', uri = uri, }, - } + }, } exec_lua('vim.lsp.util.apply_workspace_edit(...)', edit, 'utf-16') eq(true, exec_lua('return vim.uv.fs_stat(...) ~= nil', tmpfile)) end) - it('Supports file creation in folder that needs to be created with CreateFile payload', function() - local tmpfile = helpers.tmpname() - os.remove(tmpfile) -- Should not exist, only interested in a tmpname - tmpfile = tmpfile .. '/dummy/x/' - local uri = exec_lua('return vim.uri_from_fname(...)', tmpfile) - local edit = { - documentChanges = { - { - kind = 'create', - uri = uri, + it( + 'Supports file creation in folder that needs to be created with CreateFile payload', + function() + local tmpfile = tmpname() + os.remove(tmpfile) -- Should not exist, only interested in a tmpname + tmpfile = tmpfile .. '/dummy/x/' + local uri = exec_lua('return vim.uri_from_fname(...)', tmpfile) + local edit = { + documentChanges = { + { + kind = 'create', + uri = uri, + }, }, } - } - exec_lua('vim.lsp.util.apply_workspace_edit(...)', edit, 'utf-16') - eq(true, exec_lua('return vim.uv.fs_stat(...) ~= nil', tmpfile)) - end) + exec_lua('vim.lsp.util.apply_workspace_edit(...)', edit, 'utf-16') + eq(true, exec_lua('return vim.uv.fs_stat(...) ~= nil', tmpfile)) + end + ) it('createFile does not touch file if it exists and ignoreIfExists is set', function() - local tmpfile = helpers.tmpname() + local tmpfile = tmpname() write_file(tmpfile, 'Dummy content') local uri = exec_lua('return vim.uri_from_fname(...)', tmpfile) local edit = { @@ -2214,14 +2301,14 @@ describe('LSP', function() ignoreIfExists = true, }, }, - } + }, } exec_lua('vim.lsp.util.apply_workspace_edit(...)', edit, 'utf-16') eq(true, exec_lua('return vim.uv.fs_stat(...) ~= nil', tmpfile)) eq('Dummy content', read_file(tmpfile)) end) it('createFile overrides file if overwrite is set', function() - local tmpfile = helpers.tmpname() + local tmpfile = tmpname() write_file(tmpfile, 'Dummy content') local uri = exec_lua('return vim.uri_from_fname(...)', tmpfile) local edit = { @@ -2234,35 +2321,38 @@ describe('LSP', function() ignoreIfExists = true, -- overwrite must win over ignoreIfExists }, }, - } + }, } exec_lua('vim.lsp.util.apply_workspace_edit(...)', edit, 'utf-16') eq(true, exec_lua('return vim.uv.fs_stat(...) ~= nil', tmpfile)) eq('', read_file(tmpfile)) end) it('DeleteFile delete file and buffer', function() - local tmpfile = helpers.tmpname() + local tmpfile = tmpname() write_file(tmpfile, 'Be gone') - local uri = exec_lua([[ + local uri = exec_lua( + [[ local fname = select(1, ...) local bufnr = vim.fn.bufadd(fname) vim.fn.bufload(bufnr) return vim.uri_from_fname(fname) - ]], tmpfile) + ]], + tmpfile + ) local edit = { documentChanges = { { kind = 'delete', uri = uri, - } - } + }, + }, } eq(true, pcall(exec_lua, 'vim.lsp.util.apply_workspace_edit(...)', edit, 'utf-16')) eq(false, exec_lua('return vim.uv.fs_stat(...) ~= nil', tmpfile)) eq(false, exec_lua('return vim.api.nvim_buf_is_loaded(vim.fn.bufadd(...))', tmpfile)) end) it('DeleteFile fails if file does not exist and ignoreIfNotExists is false', function() - local tmpfile = helpers.tmpname() + local tmpfile = tmpname() os.remove(tmpfile) local uri = exec_lua('return vim.uri_from_fname(...)', tmpfile) local edit = { @@ -2272,9 +2362,9 @@ describe('LSP', function() uri = uri, options = { ignoreIfNotExists = false, - } - } - } + }, + }, + }, } eq(false, pcall(exec_lua, 'vim.lsp.util.apply_workspace_edit(...)', edit)) eq(false, exec_lua('return vim.uv.fs_stat(...) ~= nil', tmpfile)) @@ -2285,46 +2375,36 @@ describe('LSP', function() local pathsep = helpers.get_pathsep() it('Can rename an existing file', function() - local old = helpers.tmpname() + local old = tmpname() write_file(old, 'Test content') - local new = helpers.tmpname() - os.remove(new) -- only reserve the name, file must not exist for the test scenario - local lines = exec_lua([[ + local new = tmpname() + os.remove(new) -- only reserve the name, file must not exist for the test scenario + local lines = exec_lua( + [[ local old = select(1, ...) local new = select(2, ...) + local old_bufnr = vim.fn.bufadd(old) + vim.fn.bufload(old_bufnr) vim.lsp.util.rename(old, new) - - -- after rename the target file must have the contents of the source file - local bufnr = vim.fn.bufadd(new) - vim.fn.bufload(new) - return vim.api.nvim_buf_get_lines(bufnr, 0, -1, true) - ]], old, new) - eq({'Test content'}, lines) + -- the existing buffer is renamed in-place and its contents is kept + local new_bufnr = vim.fn.bufadd(new) + vim.fn.bufload(new_bufnr) + return (old_bufnr == new_bufnr) and vim.api.nvim_buf_get_lines(new_bufnr, 0, -1, true) + ]], + old, + new + ) + eq({ 'Test content' }, lines) local exists = exec_lua('return vim.uv.fs_stat(...) ~= nil', old) eq(false, exists) exists = exec_lua('return vim.uv.fs_stat(...) ~= nil', new) eq(true, exists) os.remove(new) end) - it("Kills old buffer after renaming an existing file", function() - local old = helpers.tmpname() - write_file(old, 'Test content') - local new = helpers.tmpname() - os.remove(new) -- only reserve the name, file must not exist for the test scenario - local lines = exec_lua([[ - local old = select(1, ...) - local oldbufnr = vim.fn.bufadd(old) - local new = select(2, ...) - vim.lsp.util.rename(old, new) - return vim.fn.bufloaded(oldbufnr) - ]], old, new) - eq(0, lines) - os.remove(new) - end) it('Can rename a directory', function() -- only reserve the name, file must not exist for the test scenario - local old_dir = helpers.tmpname() - local new_dir = helpers.tmpname() + local old_dir = tmpname() + local new_dir = tmpname() os.remove(old_dir) os.remove(new_dir) @@ -2333,64 +2413,211 @@ describe('LSP', function() local file = 'file.txt' write_file(old_dir .. pathsep .. file, 'Test content') - local lines = exec_lua([[ + local lines = exec_lua( + [[ local old_dir = select(1, ...) local new_dir = select(2, ...) - local pathsep = select(3, ...) - local oldbufnr = vim.fn.bufadd(old_dir .. pathsep .. 'file') - + local pathsep = select(3, ...) + local file = select(4, ...) + local old_bufnr = vim.fn.bufadd(old_dir .. pathsep .. file) + vim.fn.bufload(old_bufnr) vim.lsp.util.rename(old_dir, new_dir) - return vim.fn.bufloaded(oldbufnr) - ]], old_dir, new_dir, pathsep) - eq(0, lines) + -- the existing buffer is renamed in-place and its contents is kept + local new_bufnr = vim.fn.bufadd(new_dir .. pathsep .. file) + vim.fn.bufload(new_bufnr) + return (old_bufnr == new_bufnr) and vim.api.nvim_buf_get_lines(new_bufnr, 0, -1, true) + ]], + old_dir, + new_dir, + pathsep, + file + ) + eq({ 'Test content' }, lines) eq(false, exec_lua('return vim.uv.fs_stat(...) ~= nil', old_dir)) eq(true, exec_lua('return vim.uv.fs_stat(...) ~= nil', new_dir)) eq(true, exec_lua('return vim.uv.fs_stat(...) ~= nil', new_dir .. pathsep .. file)) - eq('Test content', read_file(new_dir .. pathsep .. file)) os.remove(new_dir) end) - it('Does not rename file if target exists and ignoreIfExists is set or overwrite is false', function() - local old = helpers.tmpname() - write_file(old, 'Old File') - local new = helpers.tmpname() - write_file(new, 'New file') + it('Does not touch buffers that do not match path prefix', function() + local old = tmpname() + local new = tmpname() + os.remove(old) + os.remove(new) + helpers.mkdir_p(old) - exec_lua([[ + local result = exec_lua( + [[ + local old = select(1, ...) + local new = select(2, ...) + + local old_prefixed = 'explorer://' .. old + local old_suffixed = old .. '.bak' + local new_prefixed = 'explorer://' .. new + local new_suffixed = new .. '.bak' + + local old_prefixed_buf = vim.fn.bufadd(old_prefixed) + local old_suffixed_buf = vim.fn.bufadd(old_suffixed) + local new_prefixed_buf = vim.fn.bufadd(new_prefixed) + local new_suffixed_buf = vim.fn.bufadd(new_suffixed) + + vim.lsp.util.rename(old, new) + + return + vim.api.nvim_buf_is_valid(old_prefixed_buf) and + vim.api.nvim_buf_is_valid(old_suffixed_buf) and + vim.api.nvim_buf_is_valid(new_prefixed_buf) and + vim.api.nvim_buf_is_valid(new_suffixed_buf) and + vim.api.nvim_buf_get_name(old_prefixed_buf) == old_prefixed and + vim.api.nvim_buf_get_name(old_suffixed_buf) == old_suffixed and + vim.api.nvim_buf_get_name(new_prefixed_buf) == new_prefixed and + vim.api.nvim_buf_get_name(new_suffixed_buf) == new_suffixed + ]], + old, + new + ) + eq(true, result) + + os.remove(new) + end) + it( + 'Does not rename file if target exists and ignoreIfExists is set or overwrite is false', + function() + local old = tmpname() + write_file(old, 'Old File') + local new = tmpname() + write_file(new, 'New file') + + exec_lua( + [[ local old = select(1, ...) local new = select(2, ...) vim.lsp.util.rename(old, new, { ignoreIfExists = true }) - ]], old, new) + ]], + old, + new + ) - eq(true, exec_lua('return vim.uv.fs_stat(...) ~= nil', old)) - eq('New file', read_file(new)) + eq(true, exec_lua('return vim.uv.fs_stat(...) ~= nil', old)) + eq('New file', read_file(new)) - exec_lua([[ + exec_lua( + [[ local old = select(1, ...) local new = select(2, ...) vim.lsp.util.rename(old, new, { overwrite = false }) - ]], old, new) + ]], + old, + new + ) - eq(true, exec_lua('return vim.uv.fs_stat(...) ~= nil', old)) - eq('New file', read_file(new)) + eq(true, exec_lua('return vim.uv.fs_stat(...) ~= nil', old)) + eq('New file', read_file(new)) + end + ) + it('Maintains undo information for loaded buffer', function() + local old = tmpname() + write_file(old, 'line') + local new = tmpname() + os.remove(new) + + local undo_kept = exec_lua( + [[ + local old = select(1, ...) + local new = select(2, ...) + vim.opt.undofile = true + vim.cmd.edit(old) + vim.cmd.normal('dd') + vim.cmd.write() + local undotree = vim.fn.undotree() + vim.lsp.util.rename(old, new) + -- Renaming uses :saveas, which updates the "last write" information. + -- Other than that, the undotree should remain the same. + undotree.save_cur = undotree.save_cur + 1 + undotree.save_last = undotree.save_last + 1 + undotree.entries[1].save = undotree.entries[1].save + 1 + return vim.deep_equal(undotree, vim.fn.undotree()) + ]], + old, + new + ) + eq(false, exec_lua('return vim.uv.fs_stat(...) ~= nil', old)) + eq(true, exec_lua('return vim.uv.fs_stat(...) ~= nil', new)) + eq(true, undo_kept) + end) + it('Maintains undo information for unloaded buffer', function() + local old = tmpname() + write_file(old, 'line') + local new = tmpname() + os.remove(new) + + local undo_kept = exec_lua( + [[ + local old = select(1, ...) + local new = select(2, ...) + vim.opt.undofile = true + vim.cmd.split(old) + vim.cmd.normal('dd') + vim.cmd.write() + local undotree = vim.fn.undotree() + vim.cmd.bdelete() + vim.lsp.util.rename(old, new) + vim.cmd.edit(new) + return vim.deep_equal(undotree, vim.fn.undotree()) + ]], + old, + new + ) + eq(false, exec_lua('return vim.uv.fs_stat(...) ~= nil', old)) + eq(true, exec_lua('return vim.uv.fs_stat(...) ~= nil', new)) + eq(true, undo_kept) + end) + it('Does not rename file when it conflicts with a buffer without file', function() + local old = tmpname() + write_file(old, 'Old File') + local new = tmpname() + os.remove(new) + + local lines = exec_lua( + [[ + local old = select(1, ...) + local new = select(2, ...) + local old_buf = vim.fn.bufadd(old) + vim.fn.bufload(old_buf) + local conflict_buf = vim.api.nvim_create_buf(true, false) + vim.api.nvim_buf_set_name(conflict_buf, new) + vim.api.nvim_buf_set_lines(conflict_buf, 0, -1, true, {'conflict'}) + vim.api.nvim_win_set_buf(0, conflict_buf) + vim.lsp.util.rename(old, new) + return vim.api.nvim_buf_get_lines(conflict_buf, 0, -1, true) + ]], + old, + new + ) + eq({ 'conflict' }, lines) + eq('Old File', read_file(old)) end) it('Does override target if overwrite is true', function() - local old = helpers.tmpname() + local old = tmpname() write_file(old, 'Old file') - local new = helpers.tmpname() + local new = tmpname() write_file(new, 'New file') - exec_lua([[ + exec_lua( + [[ local old = select(1, ...) local new = select(2, ...) vim.lsp.util.rename(old, new, { overwrite = true }) - ]], old, new) + ]], + old, + new + ) eq(false, exec_lua('return vim.uv.fs_stat(...) ~= nil', old)) eq(true, exec_lua('return vim.uv.fs_stat(...) ~= nil', new)) - eq('Old file\n', read_file(new)) + eq('Old file', read_file(new)) end) end) @@ -2407,8 +2634,8 @@ describe('LSP', function() range = { start = { line = 0, character = 2 }, ['end'] = { line = 0, character = 3 }, - } - } + }, + }, }, } local actual = exec_lua [[ @@ -2436,7 +2663,7 @@ describe('LSP', function() col = 3, text = 'testing', user_data = { - targetUri = "file:///fake/uri", + targetUri = 'file:///fake/uri', targetRange = { start = { line = 0, character = 2 }, ['end'] = { line = 0, character = 3 }, @@ -2444,8 +2671,8 @@ describe('LSP', function() targetSelectionRange = { start = { line = 0, character = 2 }, ['end'] = { line = 0, character = 3 }, - } - } + }, + }, }, } local actual = exec_lua [[ @@ -2479,24 +2706,26 @@ describe('LSP', function() filename = '', kind = 'File', lnum = 2, - text = '[File] TestA' + text = '[File] TestA', }, { col = 1, filename = '', kind = 'Module', lnum = 4, - text = '[Module] TestB' + text = '[Module] TestB', }, { col = 1, filename = '', kind = 'Namespace', lnum = 6, - text = '[Namespace] TestC' - } + text = '[Namespace] TestC', + }, } - eq(expected, exec_lua [[ + eq( + expected, + exec_lua [[ local doc_syms = { { deprecated = false, @@ -2581,7 +2810,8 @@ describe('LSP', function() } } return vim.lsp.util.symbols_to_items(doc_syms, nil) - ]]) + ]] + ) end) it('DocumentSymbol has no children', function() local expected = { @@ -2590,17 +2820,19 @@ describe('LSP', function() filename = '', kind = 'File', lnum = 2, - text = '[File] TestA' + text = '[File] TestA', }, { col = 1, filename = '', kind = 'Namespace', lnum = 6, - text = '[Namespace] TestC' - } + text = '[Namespace] TestC', + }, } - eq(expected, exec_lua [[ + eq( + expected, + exec_lua [[ local doc_syms = { { deprecated = false, @@ -2656,27 +2888,30 @@ describe('LSP', function() } } return vim.lsp.util.symbols_to_items(doc_syms, nil) - ]]) + ]] + ) end) end) it('convert SymbolInformation[] to items', function() - local expected = { - { - col = 1, - filename = '/test_a', - kind = 'File', - lnum = 2, - text = '[File] TestA' - }, - { - col = 1, - filename = '/test_b', - kind = 'Module', - lnum = 4, - text = '[Module] TestB' - } - } - eq(expected, exec_lua [[ + local expected = { + { + col = 1, + filename = '/test_a', + kind = 'File', + lnum = 2, + text = '[File] TestA', + }, + { + col = 1, + filename = '/test_b', + kind = 'Module', + lnum = 4, + text = '[Module] TestB', + }, + } + eq( + expected, + exec_lua [[ local sym_info = { { deprecated = false, @@ -2718,19 +2953,20 @@ describe('LSP', function() } } return vim.lsp.util.symbols_to_items(sym_info, nil) - ]]) + ]] + ) end) end) describe('lsp.util._get_symbol_kind_name', function() it('returns the name specified by protocol', function() - eq("File", exec_lua("return vim.lsp.util._get_symbol_kind_name(1)")) - eq("TypeParameter", exec_lua("return vim.lsp.util._get_symbol_kind_name(26)")) + eq('File', exec_lua('return vim.lsp.util._get_symbol_kind_name(1)')) + eq('TypeParameter', exec_lua('return vim.lsp.util._get_symbol_kind_name(26)')) end) it('returns the name not specified by protocol', function() - eq("Unknown", exec_lua("return vim.lsp.util._get_symbol_kind_name(nil)")) - eq("Unknown", exec_lua("return vim.lsp.util._get_symbol_kind_name(vim.NIL)")) - eq("Unknown", exec_lua("return vim.lsp.util._get_symbol_kind_name(1000)")) + eq('Unknown', exec_lua('return vim.lsp.util._get_symbol_kind_name(nil)')) + eq('Unknown', exec_lua('return vim.lsp.util._get_symbol_kind_name(vim.NIL)')) + eq('Unknown', exec_lua('return vim.lsp.util._get_symbol_kind_name(1000)')) end) end) @@ -2748,20 +2984,20 @@ describe('LSP', function() local location = function(start_line, start_char, end_line, end_char) return { - uri = "file:///fake/uri", + uri = 'file:///fake/uri', range = { start = { line = start_line, character = start_char }, - ["end"] = { line = end_line, character = end_char }, + ['end'] = { line = end_line, character = end_char }, }, } end local jump = function(msg) - eq(true, exec_lua('return vim.lsp.util.jump_to_location(...)', msg, "utf-16")) - eq(target_bufnr, exec_lua[[return vim.fn.bufnr('%')]]) + eq(true, exec_lua('return vim.lsp.util.jump_to_location(...)', msg, 'utf-16')) + eq(target_bufnr, exec_lua [[return vim.fn.bufnr('%')]]) return { - line = exec_lua[[return vim.fn.line('.')]], - col = exec_lua[[return vim.fn.col('.')]], + line = exec_lua [[return vim.fn.line('.')]], + col = exec_lua [[return vim.fn.col('.')]], } end @@ -2773,16 +3009,16 @@ describe('LSP', function() it('jumps to a LocationLink', function() local pos = jump({ - targetUri = "file:///fake/uri", - targetSelectionRange = { - start = { line = 0, character = 4 }, - ["end"] = { line = 0, character = 4 }, - }, - targetRange = { - start = { line = 1, character = 5 }, - ["end"] = { line = 1, character = 5 }, - }, - }) + targetUri = 'file:///fake/uri', + targetSelectionRange = { + start = { line = 0, character = 4 }, + ['end'] = { line = 0, character = 4 }, + }, + targetRange = { + start = { line = 1, character = 5 }, + ['end'] = { line = 1, character = 5 }, + }, + }) eq(1, pos.line) eq(5, pos.col) end) @@ -2791,18 +3027,18 @@ describe('LSP', function() local pos = jump(location(1, 2, 1, 2)) eq(2, pos.line) eq(4, pos.col) - eq('å', exec_lua[[return vim.fn.expand('<cword>')]]) + eq('å', exec_lua [[return vim.fn.expand('<cword>')]]) end) it('adds current position to jumplist before jumping', function() - funcs.nvim_win_set_buf(0, target_bufnr) - local mark = funcs.nvim_buf_get_mark(target_bufnr, "'") + fn.nvim_win_set_buf(0, target_bufnr) + local mark = fn.nvim_buf_get_mark(target_bufnr, "'") eq({ 1, 0 }, mark) - funcs.nvim_win_set_cursor(0, { 2, 3 }) + fn.nvim_win_set_cursor(0, { 2, 3 }) jump(location(0, 9, 0, 9)) - mark = funcs.nvim_buf_get_mark(target_bufnr, "'") + mark = fn.nvim_buf_get_mark(target_bufnr, "'") eq({ 2, 3 }, mark) end) end) @@ -2896,101 +3132,101 @@ describe('LSP', function() end) it('does not add current position to jumplist if not focus', function() - funcs.nvim_win_set_buf(0, target_bufnr) - local mark = funcs.nvim_buf_get_mark(target_bufnr, "'") + fn.nvim_win_set_buf(0, target_bufnr) + local mark = fn.nvim_buf_get_mark(target_bufnr, "'") eq({ 1, 0 }, mark) - funcs.nvim_win_set_cursor(0, { 2, 3 }) + fn.nvim_win_set_cursor(0, { 2, 3 }) show_document(location(0, 9, 0, 9), false, true) show_document(location(0, 9, 0, 9, true), false, true) - mark = funcs.nvim_buf_get_mark(target_bufnr, "'") + mark = fn.nvim_buf_get_mark(target_bufnr, "'") eq({ 1, 0 }, mark) end) it('does not change cursor position if not focus and not reuse_win', function() - funcs.nvim_win_set_buf(0, target_bufnr) - local cursor = funcs.nvim_win_get_cursor(0) + fn.nvim_win_set_buf(0, target_bufnr) + local cursor = fn.nvim_win_get_cursor(0) show_document(location(0, 9, 0, 9), false, false) - eq(cursor, funcs.nvim_win_get_cursor(0)) + eq(cursor, fn.nvim_win_get_cursor(0)) end) it('does not change window if not focus', function() - funcs.nvim_win_set_buf(0, target_bufnr) - local win = funcs.nvim_get_current_win() + fn.nvim_win_set_buf(0, target_bufnr) + local win = fn.nvim_get_current_win() -- same document/bufnr show_document(location(0, 9, 0, 9), false, true) - eq(win, funcs.nvim_get_current_win()) + eq(win, fn.nvim_get_current_win()) -- different document/bufnr, new window/split show_document(location(0, 9, 0, 9, true), false, true) - eq(2, #funcs.nvim_list_wins()) - eq(win, funcs.nvim_get_current_win()) + eq(2, #fn.nvim_list_wins()) + eq(win, fn.nvim_get_current_win()) end) it("respects 'reuse_win' parameter", function() - funcs.nvim_win_set_buf(0, target_bufnr) + fn.nvim_win_set_buf(0, target_bufnr) -- does not create a new window if the buffer is already open show_document(location(0, 9, 0, 9), false, true) - eq(1, #funcs.nvim_list_wins()) + eq(1, #fn.nvim_list_wins()) -- creates a new window even if the buffer is already open show_document(location(0, 9, 0, 9), false, false) - eq(2, #funcs.nvim_list_wins()) + eq(2, #fn.nvim_list_wins()) end) it('correctly sets the cursor of the split if range is given without focus', function() - funcs.nvim_win_set_buf(0, target_bufnr) + fn.nvim_win_set_buf(0, target_bufnr) show_document(location(0, 9, 0, 9, true), false, true) - local wins = funcs.nvim_list_wins() + local wins = fn.nvim_list_wins() eq(2, #wins) table.sort(wins) - eq({ 1, 0 }, funcs.nvim_win_get_cursor(wins[1])) - eq({ 1, 9 }, funcs.nvim_win_get_cursor(wins[2])) + eq({ 1, 0 }, fn.nvim_win_get_cursor(wins[1])) + eq({ 1, 9 }, fn.nvim_win_get_cursor(wins[2])) end) it('does not change cursor of the split if not range and not focus', function() - funcs.nvim_win_set_buf(0, target_bufnr) - funcs.nvim_win_set_cursor(0, { 2, 3 }) + fn.nvim_win_set_buf(0, target_bufnr) + fn.nvim_win_set_cursor(0, { 2, 3 }) exec_lua([[vim.cmd.new()]]) - funcs.nvim_win_set_buf(0, target_bufnr2) - funcs.nvim_win_set_cursor(0, { 2, 3 }) + fn.nvim_win_set_buf(0, target_bufnr2) + fn.nvim_win_set_cursor(0, { 2, 3 }) show_document({ uri = 'file:///fake/uri2' }, false, true) - local wins = funcs.nvim_list_wins() + local wins = fn.nvim_list_wins() eq(2, #wins) - eq({ 2, 3 }, funcs.nvim_win_get_cursor(wins[1])) - eq({ 2, 3 }, funcs.nvim_win_get_cursor(wins[2])) + eq({ 2, 3 }, fn.nvim_win_get_cursor(wins[1])) + eq({ 2, 3 }, fn.nvim_win_get_cursor(wins[2])) end) it('respects existing buffers', function() - funcs.nvim_win_set_buf(0, target_bufnr) - local win = funcs.nvim_get_current_win() + fn.nvim_win_set_buf(0, target_bufnr) + local win = fn.nvim_get_current_win() exec_lua([[vim.cmd.new()]]) - funcs.nvim_win_set_buf(0, target_bufnr2) - funcs.nvim_win_set_cursor(0, { 2, 3 }) - local split = funcs.nvim_get_current_win() + fn.nvim_win_set_buf(0, target_bufnr2) + fn.nvim_win_set_cursor(0, { 2, 3 }) + local split = fn.nvim_get_current_win() -- reuse win for open document/bufnr if called from split show_document(location(0, 9, 0, 9, true), false, true) - eq({ 1, 9 }, funcs.nvim_win_get_cursor(split)) - eq(2, #funcs.nvim_list_wins()) + eq({ 1, 9 }, fn.nvim_win_get_cursor(split)) + eq(2, #fn.nvim_list_wins()) - funcs.nvim_set_current_win(win) + fn.nvim_set_current_win(win) -- reuse win for open document/bufnr if called outside the split show_document(location(0, 9, 0, 9, true), false, true) - eq({ 1, 9 }, funcs.nvim_win_get_cursor(split)) - eq(2, #funcs.nvim_list_wins()) + eq({ 1, 9 }, fn.nvim_win_get_cursor(split)) + eq(2, #fn.nvim_list_wins()) end) end) @@ -3004,11 +3240,14 @@ describe('LSP', function() end) it('calculates size correctly', function() - eq({19,3}, exec_lua[[ return {vim.lsp.util._make_floating_popup_size(contents)} ]]) + eq({ 19, 3 }, exec_lua [[ return {vim.lsp.util._make_floating_popup_size(contents)} ]]) end) it('calculates size correctly with wrapping', function() - eq({15,5}, exec_lua[[ return {vim.lsp.util._make_floating_popup_size(contents,{width = 15, wrap_at = 14})} ]]) + eq( + { 15, 5 }, + exec_lua [[ return {vim.lsp.util._make_floating_popup_size(contents,{width = 15, wrap_at = 14})} ]] + ) end) it('handles NUL bytes in text', function() @@ -3018,21 +3257,24 @@ describe('LSP', function() '\020\021\022\023\024\025\026\027\028\029', } ]]) command('set list listchars=') - eq({20,3}, exec_lua[[ return {vim.lsp.util._make_floating_popup_size(contents)} ]]) + eq({ 20, 3 }, exec_lua [[ return {vim.lsp.util._make_floating_popup_size(contents)} ]]) command('set display+=uhex') - eq({40,3}, exec_lua[[ return {vim.lsp.util._make_floating_popup_size(contents)} ]]) + eq({ 40, 3 }, exec_lua [[ return {vim.lsp.util._make_floating_popup_size(contents)} ]]) end) end) describe('lsp.util.trim.trim_empty_lines', function() it('properly trims empty lines', function() - eq({{"foo", "bar"}}, exec_lua[[ return vim.lsp.util.trim_empty_lines({{ "foo", "bar" }, nil}) ]]) + eq( + { { 'foo', 'bar' } }, + exec_lua [[ return vim.lsp.util.trim_empty_lines({{ "foo", "bar" }, nil}) ]] + ) end) end) describe('lsp.util.convert_signature_help_to_markdown_lines', function() it('can handle negative activeSignature', function() - local result = exec_lua[[ + local result = exec_lua [[ local signature_help = { activeParameter = 0, activeSignature = -1, @@ -3046,22 +3288,29 @@ describe('LSP', function() } return vim.lsp.util.convert_signature_help_to_markdown_lines(signature_help, 'cs', {','}) ]] - local expected = {'```cs', 'TestEntity.TestEntity()', '```', 'some doc'} + local expected = { '```cs', 'TestEntity.TestEntity()', '```', 'some doc' } eq(expected, result) end) end) describe('lsp.util.get_effective_tabstop', function() local function test_tabstop(tabsize, shiftwidth) - exec_lua(string.format([[ + exec_lua(string.format( + [[ vim.bo.shiftwidth = %d vim.bo.tabstop = 2 - ]], shiftwidth)) + ]], + shiftwidth + )) eq(tabsize, exec_lua('return vim.lsp.util.get_effective_tabstop()')) end - it('with shiftwidth = 1', function() test_tabstop(1, 1) end) - it('with shiftwidth = 0', function() test_tabstop(2, 0) end) + it('with shiftwidth = 1', function() + test_tabstop(1, 1) + end) + it('with shiftwidth = 0', function() + test_tabstop(2, 0) + end) end) describe('vim.lsp.buf.outgoing_calls', function() @@ -3118,20 +3367,22 @@ describe('LSP', function() return vim.fn.getqflist() ]=]) - local expected = { { - bufnr = 2, - col = 5, - end_col = 0, - lnum = 4, - end_lnum = 0, - module = "", - nr = 0, - pattern = "", - text = "foo", - type = "", - valid = 1, - vcol = 0 - } } + local expected = { + { + bufnr = 2, + col = 5, + end_col = 0, + lnum = 4, + end_lnum = 0, + module = '', + nr = 0, + pattern = '', + text = 'foo', + type = '', + valid = 1, + vcol = 0, + }, + } eq(expected, qflist) end) @@ -3192,20 +3443,22 @@ describe('LSP', function() return vim.fn.getqflist() ]=]) - local expected = { { - bufnr = 2, - col = 5, - end_col = 0, - lnum = 4, - end_lnum = 0, - module = "", - nr = 0, - pattern = "", - text = "main", - type = "", - valid = 1, - vcol = 0 - } } + local expected = { + { + bufnr = 2, + col = 5, + end_col = 0, + lnum = 4, + end_lnum = 0, + module = '', + nr = 0, + pattern = '', + text = 'main', + type = '', + valid = 1, + vcol = 0, + }, + } eq(expected, qflist) end) @@ -3214,52 +3467,52 @@ describe('LSP', function() describe('vim.lsp.buf.rename', function() for _, test in ipairs({ { - it = "does not attempt to rename on nil response", - name = "prepare_rename_nil", + it = 'does not attempt to rename on nil response', + name = 'prepare_rename_nil', expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, }, }, { - it = "handles prepareRename placeholder response", - name = "prepare_rename_placeholder", + it = 'handles prepareRename placeholder response', + name = 'prepare_rename_placeholder', expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, NIL, {method="textDocument/rename", client_id=1, bufnr=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, NIL, { method = 'textDocument/rename', client_id = 1, bufnr = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, }, - expected_text = "placeholder", -- see fake lsp response + expected_text = 'placeholder', -- see fake lsp response }, { - it = "handles range response", - name = "prepare_rename_range", + it = 'handles range response', + name = 'prepare_rename_range', expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, NIL, {method="textDocument/rename", client_id=1, bufnr=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, NIL, { method = 'textDocument/rename', client_id = 1, bufnr = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, }, - expected_text = "line", -- see test case and fake lsp response + expected_text = 'line', -- see test case and fake lsp response }, { - it = "handles error", - name = "prepare_rename_error", + it = 'handles error', + name = 'prepare_rename_error', expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, }, }, }) do - it(test.it, function() - local client - test_rpc_server { - test_name = test.name; - on_init = function(_client) - client = _client - eq(true, client.server_capabilities().renameProvider.prepareProvider) - end; - on_setup = function() - exec_lua([=[ + it(test.it, function() + local client + test_rpc_server { + test_name = test.name, + on_init = function(_client) + client = _client + eq(true, client.server_capabilities().renameProvider.prepareProvider) + end, + on_setup = function() + exec_lua([=[ local bufnr = vim.api.nvim_get_current_buf() lsp.buf_attach_client(bufnr, TEST_RPC_CLIENT_ID) vim.lsp._stubs = {} @@ -3271,31 +3524,31 @@ describe('LSP', function() vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {'', 'this is line two'}) vim.fn.cursor(2, 13) -- the space between "line" and "two" ]=]) - end; - on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") - end; - on_handler = function(err, result, ctx) - -- Don't compare & assert params and version, they're not relevant for the testcase - -- This allows us to be lazy and avoid declaring them - ctx.params = nil - ctx.version = nil - - eq(table.remove(test.expected_handlers), {err, result, ctx}, "expected handler") - if ctx.method == 'start' then - exec_lua("vim.lsp.buf.rename()") - end - if ctx.method == 'shutdown' then - if test.expected_text then - eq("New Name: ", exec_lua("return vim.lsp._stubs.input_prompt")) - eq(test.expected_text, exec_lua("return vim.lsp._stubs.input_text")) + end, + on_exit = function(code, signal) + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') + end, + on_handler = function(err, result, ctx) + -- Don't compare & assert params and version, they're not relevant for the testcase + -- This allows us to be lazy and avoid declaring them + ctx.params = nil + ctx.version = nil + + eq(table.remove(test.expected_handlers), { err, result, ctx }, 'expected handler') + if ctx.method == 'start' then + exec_lua('vim.lsp.buf.rename()') end - client.stop() - end - end; - } - end) + if ctx.method == 'shutdown' then + if test.expected_text then + eq('New Name: ', exec_lua('return vim.lsp._stubs.input_prompt')) + eq(test.expected_text, exec_lua('return vim.lsp._stubs.input_text')) + end + client.stop() + end + end, + } + end) end end) @@ -3303,22 +3556,21 @@ describe('LSP', function() it('Calls client side command if available', function() local client local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, } test_rpc_server { test_name = 'code_action_with_resolve', on_init = function(client_) client = client_ end, - on_setup = function() - end, + on_setup = function() end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') end, on_handler = function(err, result, ctx) - eq(table.remove(expected_handlers), {err, result, ctx}) + eq(table.remove(expected_handlers), { err, result, ctx }) if ctx.method == 'start' then exec_lua([[ vim.lsp.commands['dummy1'] = function(cmd) @@ -3333,10 +3585,10 @@ describe('LSP', function() vim.lsp.buf.code_action() ]]) elseif ctx.method == 'shutdown' then - eq('function', exec_lua[[return type(vim.lsp.commands['dummy2'])]]) + eq('function', exec_lua [[return type(vim.lsp.commands['dummy2'])]]) client.stop() end - end + end, } end) it('Calls workspace/executeCommand if no client side command', function() @@ -3382,22 +3634,21 @@ describe('LSP', function() it('Filters and automatically applies action if requested', function() local client local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, } test_rpc_server { test_name = 'code_action_filter', on_init = function(client_) client = client_ end, - on_setup = function() - end, + on_setup = function() end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') end, on_handler = function(err, result, ctx) - eq(table.remove(expected_handlers), {err, result, ctx}) + eq(table.remove(expected_handlers), { err, result, ctx }) if ctx.method == 'start' then exec_lua([[ vim.lsp.commands['preferred_command'] = function(cmd) @@ -3428,15 +3679,15 @@ describe('LSP', function() }) ]]) elseif ctx.method == 'shutdown' then - eq('function', exec_lua[[return type(vim.lsp.commands['executed_preferred'])]]) - eq('function', exec_lua[[return type(vim.lsp.commands['filtered_type_annotate_foo'])]]) - eq('function', exec_lua[[return type(vim.lsp.commands['executed_type_annotate'])]]) + eq('function', exec_lua [[return type(vim.lsp.commands['executed_preferred'])]]) + eq('function', exec_lua [[return type(vim.lsp.commands['filtered_type_annotate_foo'])]]) + eq('function', exec_lua [[return type(vim.lsp.commands['executed_type_annotate'])]]) client.stop() end - end + end, } end) - it("Fallback to command execution on resolve error", function() + it('Fallback to command execution on resolve error', function() clear() exec_lua(create_server_definition) local result = exec_lua([[ @@ -3476,9 +3727,9 @@ describe('LSP', function() vim.lsp.stop_client(client_id) return server.messages ]]) - eq("codeAction/resolve", result[4].method) - eq("workspace/executeCommand", result[5].method) - eq("command:1", result[5].params.command) + eq('codeAction/resolve', result[4].method) + eq('workspace/executeCommand', result[5].method) + eq('command:1', result[5].params.command) end) end) describe('vim.lsp.commands', function() @@ -3499,25 +3750,25 @@ describe('LSP', function() it('uses client commands', function() local client local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, } test_rpc_server { test_name = 'clientside_commands', on_init = function(client_) client = client_ end, - on_setup = function() - end, + on_setup = function() end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') end, on_handler = function(err, result, ctx) - eq(table.remove(expected_handlers), {err, result, ctx}) + eq(table.remove(expected_handlers), { err, result, ctx }) if ctx.method == 'start' then - local fake_uri = "file:///fake/uri" - local cmd = exec_lua([[ + local fake_uri = 'file:///fake/uri' + local cmd = exec_lua( + [[ fake_uri = ... local bufnr = vim.uri_to_bufnr(fake_uri) vim.fn.bufload(bufnr) @@ -3539,20 +3790,22 @@ describe('LSP', function() vim.api.nvim_set_current_buf(bufnr) vim.lsp.codelens.run() return cmd_called - ]], fake_uri) - eq({ command = 'Dummy', title = 'Lens1' }, cmd) - elseif ctx.method == 'shutdown' then - client.stop() + ]], + fake_uri + ) + eq({ command = 'Dummy', title = 'Lens1' }, cmd) + elseif ctx.method == 'shutdown' then + client.stop() end - end + end, } end) it('releases buffer refresh lock', function() local client local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, } test_rpc_server { test_name = 'codelens_refresh_lock', @@ -3576,11 +3829,11 @@ describe('LSP', function() ]=]) end, on_exit = function(code, signal) - eq(0, code, "exit code") - eq(0, signal, "exit signal") + eq(0, code, 'exit code') + eq(0, signal, 'exit signal') end, on_handler = function(err, result, ctx) - eq(table.remove(expected_handlers), {err, result, ctx}) + eq(table.remove(expected_handlers), { err, result, ctx }) if ctx.method == 'start' then -- 1. first codelens request errors local response = exec_lua([=[ @@ -3589,7 +3842,7 @@ describe('LSP', function() vim.wait(100, function () return CALLED end) return RESPONSE ]=]) - eq( { err = { code = -32002, message = "ServerNotInitialized" } }, response) + eq({ err = { code = -32002, message = 'ServerNotInitialized' } }, response) -- 2. second codelens request runs response = exec_lua([=[ @@ -3604,7 +3857,7 @@ describe('LSP', function() vim.wait(100, function () return cmd_called end) return cmd_called ]=]) - eq( { command = "Dummy", title = "Lens1" }, response) + eq({ command = 'Dummy', title = 'Lens1' }, response) -- 3. third codelens request runs response = exec_lua([=[ @@ -3619,20 +3872,20 @@ describe('LSP', function() vim.wait(100, function () return cmd_called end) return cmd_called ]=]) - eq( { command = "Dummy", title = "Lens2" }, response) - elseif ctx.method == 'shutdown' then - client.stop() + eq({ command = 'Dummy', title = 'Lens2' }, response) + elseif ctx.method == 'shutdown' then + client.stop() end - end + end, } end) end) - describe("vim.lsp.buf.format", function() - it("Aborts with notify if no client matches filter", function() + describe('vim.lsp.buf.format', function() + it('Aborts with notify if no client matches filter', function() local client test_rpc_server { - test_name = "basic_init", + test_name = 'basic_init', on_init = function(c) client = c end, @@ -3649,25 +3902,25 @@ describe('LSP', function() vim.notify = notify return notify_msg ]]) - eq("[LSP] Format request failed, no matching language servers.", notify_msg) + eq('[LSP] Format request failed, no matching language servers.', notify_msg) client.stop() end, } end) - it("Sends textDocument/formatting request to format buffer", function() + it('Sends textDocument/formatting request to format buffer', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, } local client test_rpc_server { - test_name = "basic_formatting", + test_name = 'basic_formatting', on_init = function(c) client = c end, on_handler = function(_, _, ctx) table.remove(expected_handlers) - if ctx.method == "start" then + if ctx.method == 'start' then local notify_msg = exec_lua([[ local bufnr = vim.api.nvim_get_current_buf() vim.lsp.buf_attach_client(bufnr, TEST_RPC_CLIENT_ID) @@ -3681,7 +3934,7 @@ describe('LSP', function() return notify_msg ]]) eq(NIL, notify_msg) - elseif ctx.method == "shutdown" then + elseif ctx.method == 'shutdown' then client.stop() end end, @@ -3689,18 +3942,18 @@ describe('LSP', function() end) it('Can format async', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; - {NIL, {}, {method="start", client_id=1}}; + { NIL, {}, { method = 'shutdown', client_id = 1 } }, + { NIL, {}, { method = 'start', client_id = 1 } }, } local client test_rpc_server { - test_name = "basic_formatting", + test_name = 'basic_formatting', on_init = function(c) client = c end, on_handler = function(_, _, ctx) table.remove(expected_handlers) - if ctx.method == "start" then + if ctx.method == 'start' then local result = exec_lua([[ local bufnr = vim.api.nvim_get_current_buf() vim.lsp.buf_attach_client(bufnr, TEST_RPC_CLIENT_ID) @@ -3724,8 +3977,8 @@ describe('LSP', function() vim.lsp.handlers['textDocument/formatting'] = handler return {notify = notify_msg, handler_called = handler_called} ]]) - eq({handler_called=true}, result) - elseif ctx.method == "shutdown" then + eq({ handler_called = true }, result) + elseif ctx.method == 'shutdown' then client.stop() end end, @@ -3749,7 +4002,7 @@ describe('LSP', function() vim.lsp.stop_client(client_id) return server.messages ]]) - eq("textDocument/rangeFormatting", result[3].method) + eq('textDocument/rangeFormatting', result[3].method) local expected_range = { start = { line = 0, character = 0 }, ['end'] = { line = 1, character = 4 }, @@ -3784,16 +4037,21 @@ describe('LSP', function() return server.messages ]]) local expected_methods = { - "initialize", - "initialized", - "textDocument/rangeFormatting", - "$/cancelRequest", - "textDocument/rangeFormatting", - "$/cancelRequest", - "shutdown", - "exit", + 'initialize', + 'initialized', + 'textDocument/rangeFormatting', + '$/cancelRequest', + 'textDocument/rangeFormatting', + '$/cancelRequest', + 'shutdown', + 'exit', } - eq(expected_methods, vim.tbl_map(function(x) return x.method end, result)) + eq( + expected_methods, + vim.tbl_map(function(x) + return x.method + end, result) + ) -- uses first column of start line and last column of end line local expected_range = { start = { line = 0, character = 0 }, @@ -3809,10 +4067,11 @@ describe('LSP', function() notify_msg = msg end ]]) - local fail_msg = "[LSP] Format request failed, no matching language servers." + local fail_msg = '[LSP] Format request failed, no matching language servers.' local function check_notify(name, formatting, range_formatting) - local timeout_msg = "[LSP][" .. name .. "] timeout" - exec_lua([[ + local timeout_msg = '[LSP][' .. name .. '] timeout' + exec_lua( + [[ local formatting, range_formatting, name = ... local server = _create_server({ capabilities = { documentFormattingProvider = formatting, @@ -3821,7 +4080,11 @@ describe('LSP', function() vim.lsp.start({ name = name, cmd = server.cmd }) notify_msg = nil vim.lsp.buf.format({ name = name, timeout_ms = 1 }) - ]], formatting, range_formatting, name) + ]], + formatting, + range_formatting, + name + ) eq(formatting and timeout_msg or fail_msg, exec_lua('return notify_msg')) exec_lua([[ notify_msg = nil @@ -3829,12 +4092,111 @@ describe('LSP', function() ]]) eq(range_formatting and timeout_msg or fail_msg, exec_lua('return notify_msg')) end - check_notify("none", false, false) - check_notify("formatting", true, false) - check_notify("rangeFormatting", false, true) - check_notify("both", true, true) + check_notify('none', false, false) + check_notify('formatting', true, false) + check_notify('rangeFormatting', false, true) + check_notify('both', true, true) + end) + end) + + describe('vim.lsp.tagfunc', function() + before_each(function() + clear() + ---@type lsp.Location[] + local mock_locations = { + { + range = { + ['start'] = { line = 5, character = 23 }, + ['end'] = { line = 10, character = 0 }, + }, + uri = 'test://buf', + }, + { + range = { + ['start'] = { line = 42, character = 10 }, + ['end'] = { line = 44, character = 0 }, + }, + uri = 'test://another-file', + }, + } + exec_lua(create_server_definition) + exec_lua( + [[ + _G.mock_locations = ... + _G.server = _create_server({ + ---@type lsp.ServerCapabilities + capabilities = { + definitionProvider = true, + workspaceSymbolProvider = true, + }, + handlers = { + ---@return lsp.Location[] + ['textDocument/definition'] = function() + return { _G.mock_locations[1] } + end, + ---@return lsp.WorkspaceSymbol[] + ['workspace/symbol'] = function(_, request) + assert(request.query == 'foobar') + return { + { + name = 'foobar', + kind = 13, ---@type lsp.SymbolKind + location = _G.mock_locations[1], + }, + { + name = 'vim.foobar', + kind = 12, ---@type lsp.SymbolKind + location = _G.mock_locations[2], + } + } + end, + }, + }) + _G.client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd }) + ]], + mock_locations + ) + end) + after_each(function() + exec_lua [[ + vim.lsp.stop_client(_G.client_id) + ]] + end) + + it('with flags=c, returns matching tags using textDocument/definition', function() + local result = exec_lua [[ + return vim.lsp.tagfunc('foobar', 'c') + ]] + eq({ + { + cmd = '/\\%6l\\%1c/', -- for location (5, 23) + filename = 'test://buf', + name = 'foobar', + }, + }, result) + end) + + it('without flags=c, returns all matching tags using workspace/symbol', function() + local result = exec_lua [[ + return vim.lsp.tagfunc('foobar', '') + ]] + eq({ + { + cmd = '/\\%6l\\%1c/', -- for location (5, 23) + filename = 'test://buf', + kind = 'Variable', + name = 'foobar', + }, + { + cmd = '/\\%43l\\%1c/', -- for location (42, 10) + filename = 'test://another-file', + kind = 'Function', + name = 'vim.foobar', + }, + }, result) end) end) + describe('cmd', function() it('can connect to lsp server via rpc.connect', function() local result = exec_lua [[ @@ -3859,7 +4221,43 @@ describe('LSP', function() server:shutdown() return vim.json.decode(init) ]] - eq(result.method, "initialize") + eq(result.method, 'initialize') + end) + it('can connect to lsp server via rpc.domain_socket_connect', function() + local tmpfile + if is_os('win') then + tmpfile = '\\\\.\\\\pipe\\pipe.test' + else + tmpfile = tmpname() + os.remove(tmpfile) + end + local result = exec_lua( + [[ + local SOCK = ... + local uv = vim.uv + local server = uv.new_pipe(false) + server:bind(SOCK) + local init = nil + + server:listen(127, function(err) + assert(not err, err) + local client = uv.new_pipe() + server:accept(client) + client:read_start(require("vim.lsp.rpc").create_read_loop(function(body) + init = body + client:close() + end)) + end) + vim.lsp.start({ name = "dummy", cmd = vim.lsp.rpc.domain_socket_connect(SOCK) }) + vim.wait(1000, function() return init ~= nil end) + assert(init, "server must receive `initialize` request") + server:close() + server:shutdown() + return vim.json.decode(init) + ]], + tmpfile + ) + eq(result.method, 'initialize') end) end) @@ -3926,9 +4324,9 @@ describe('LSP', function() { id = 10, jsonrpc = '2.0', - result = false - } - } + result = false, + }, + }, } eq(expected, result) end) @@ -3936,15 +4334,19 @@ describe('LSP', function() describe('#dynamic vim.lsp._dynamic', function() it('supports dynamic registration', function() - local root_dir = helpers.tmpname() + ---@type string + local root_dir = tmpname() os.remove(root_dir) mkdir(root_dir) local tmpfile = root_dir .. '/dynamic.foo' local file = io.open(tmpfile, 'w') - file:close() + if file then + file:close() + end exec_lua(create_server_definition) - local result = exec_lua([[ + local result = exec_lua( + [[ local root_dir, tmpfile = ... local server = _create_server() @@ -3952,6 +4354,9 @@ describe('LSP', function() name = 'dynamic-test', cmd = server.cmd, root_dir = root_dir, + get_language_id = function() + return "dummy-lang" + end, capabilities = { textDocument = { formatting = { @@ -3985,6 +4390,13 @@ describe('LSP', function() { id = 'range-formatting', method = 'textDocument/rangeFormatting', + registerOptions = { + documentSelector = { + { + language = "dummy-lang" + }, + } + } }, }, }, { client_id = client_id }) @@ -4002,7 +4414,11 @@ describe('LSP', function() local function check(method, fname) local bufnr = fname and vim.fn.bufadd(fname) or nil local client = vim.lsp.get_client_by_id(client_id) - result[#result + 1] = {method = method, fname = fname, supported = client.supports_method(method, {bufnr = bufnr})} + result[#result + 1] = { + method = method, + fname = fname, + supported = client.supports_method(method, {bufnr = bufnr}) + } end @@ -4013,120 +4429,161 @@ describe('LSP', function() check("textDocument/completion") return result - ]], root_dir, tmpfile) + ]], + root_dir, + tmpfile + ) eq(5, #result) - eq({method = 'textDocument/formatting', supported = false}, result[1]) - eq({method = 'textDocument/formatting', supported = true, fname = tmpfile}, result[2]) - eq({method = 'textDocument/rangeFormatting', supported = true}, result[3]) - eq({method = 'textDocument/rangeFormatting', supported = true, fname = tmpfile}, result[4]) - eq({method = 'textDocument/completion', supported = false}, result[5]) + eq({ method = 'textDocument/formatting', supported = false }, result[1]) + eq({ method = 'textDocument/formatting', supported = true, fname = tmpfile }, result[2]) + eq({ method = 'textDocument/rangeFormatting', supported = true }, result[3]) + eq({ method = 'textDocument/rangeFormatting', supported = true, fname = tmpfile }, result[4]) + eq({ method = 'textDocument/completion', supported = false }, result[5]) end) end) describe('vim.lsp._watchfiles', function() - it('sends notifications when files change', function() - skip(is_os('bsd'), "bsd only reports rename on folders if file inside change") - local root_dir = helpers.tmpname() - os.remove(root_dir) - mkdir(root_dir) + local function test_filechanges(watchfunc) + it( + string.format('sends notifications when files change (watchfunc=%s)', watchfunc), + function() + if watchfunc == 'fswatch' then + skip( + not is_ci() and fn.executable('fswatch') == 0, + 'fswatch not installed and not on CI' + ) + skip(is_os('win'), 'not supported on windows') + skip(is_os('mac'), 'flaky') + end - exec_lua(create_server_definition) - local result = exec_lua([[ - local root_dir = ... + skip( + is_os('bsd'), + 'kqueue only reports events on watched folder itself, not contained files #26110' + ) - local server = _create_server() - local client_id = vim.lsp.start({ - name = 'watchfiles-test', - cmd = server.cmd, - root_dir = root_dir, - capabilities = { - workspace = { - didChangeWatchedFiles = { - dynamicRegistration = true, + local root_dir = tmpname() + os.remove(root_dir) + mkdir(root_dir) + + exec_lua(create_server_definition) + local result = exec_lua( + [[ + local root_dir, watchfunc = ... + + local server = _create_server() + local client_id = vim.lsp.start({ + name = 'watchfiles-test', + cmd = server.cmd, + root_dir = root_dir, + capabilities = { + workspace = { + didChangeWatchedFiles = { + dynamicRegistration = true, + }, }, }, - }, - }) + }) - local expected_messages = 2 -- initialize, initialized + require('vim.lsp._watchfiles')._watchfunc = require('vim._watch')[watchfunc] - local watchfunc = require('vim.lsp._watchfiles')._watchfunc - local msg_wait_timeout = watchfunc == vim._watch.poll and 2500 or 200 - local function wait_for_messages() - assert(vim.wait(msg_wait_timeout, function() return #server.messages == expected_messages end), 'Timed out waiting for expected number of messages. Current messages seen so far: ' .. vim.inspect(server.messages)) - end + local expected_messages = 0 - wait_for_messages() + local msg_wait_timeout = watchfunc == 'watch' and 200 or 2500 - vim.lsp.handlers['client/registerCapability'](nil, { - registrations = { - { - id = 'watchfiles-test-0', - method = 'workspace/didChangeWatchedFiles', - registerOptions = { - watchers = { - { - globPattern = '**/watch', - kind = 7, + local function wait_for_message(incr) + expected_messages = expected_messages + (incr or 1) + assert( + vim.wait(msg_wait_timeout, function() + return #server.messages == expected_messages + end), + 'Timed out waiting for expected number of messages. Current messages seen so far: ' + .. vim.inspect(server.messages) + ) + end + + wait_for_message(2) -- initialize, initialized + + vim.lsp.handlers['client/registerCapability'](nil, { + registrations = { + { + id = 'watchfiles-test-0', + method = 'workspace/didChangeWatchedFiles', + registerOptions = { + watchers = { + { + globPattern = '**/watch', + kind = 7, + }, }, }, }, }, - }, - }, { client_id = client_id }) + }, { client_id = client_id }) - if watchfunc == vim._watch.poll then - vim.wait(100) - end + if watchfunc ~= 'watch' then + vim.wait(100) + end - local path = root_dir .. '/watch' - local file = io.open(path, 'w') - file:close() + local path = root_dir .. '/watch' + local tmp = vim.fn.tempname() + io.open(tmp, 'w'):close() + vim.uv.fs_rename(tmp, path) - expected_messages = expected_messages + 1 - wait_for_messages() + wait_for_message() - os.remove(path) + os.remove(path) - expected_messages = expected_messages + 1 - wait_for_messages() + wait_for_message() - return server.messages - ]], root_dir) + vim.lsp.stop_client(client_id) - local function watched_uri(fname) - return exec_lua([[ - local root_dir, fname = ... - return vim.uri_from_fname(root_dir .. '/' .. fname) - ]], root_dir, fname) - end + return server.messages + ]], + root_dir, + watchfunc + ) - eq(4, #result) - eq('workspace/didChangeWatchedFiles', result[3].method) - eq({ - changes = { - { - type = exec_lua([[return vim.lsp.protocol.FileChangeType.Created]]), - uri = watched_uri('watch'), - }, - }, - }, result[3].params) - eq('workspace/didChangeWatchedFiles', result[4].method) - eq({ - changes = { - { - type = exec_lua([[return vim.lsp.protocol.FileChangeType.Deleted]]), - uri = watched_uri('watch'), - }, - }, - }, result[4].params) - end) + local uri = vim.uri_from_fname(root_dir .. '/watch') + + eq(6, #result) + + eq({ + method = 'workspace/didChangeWatchedFiles', + params = { + changes = { + { + type = exec_lua([[return vim.lsp.protocol.FileChangeType.Created]]), + uri = uri, + }, + }, + }, + }, result[3]) + + eq({ + method = 'workspace/didChangeWatchedFiles', + params = { + changes = { + { + type = exec_lua([[return vim.lsp.protocol.FileChangeType.Deleted]]), + uri = uri, + }, + }, + }, + }, result[4]) + end + ) + end + + test_filechanges('watch') + test_filechanges('watchdirs') + test_filechanges('fswatch') it('correctly registers and unregisters', function() local root_dir = '/some_dir' exec_lua(create_server_definition) - local result = exec_lua([[ + local result = exec_lua( + [[ local root_dir = ... local server = _create_server() @@ -4217,13 +4674,19 @@ describe('LSP', function() wait_for_messages() return server.messages - ]], root_dir) + ]], + root_dir + ) local function watched_uri(fname) - return exec_lua([[ + return exec_lua( + [[ local root_dir, fname = ... return vim.uri_from_fname(root_dir .. '/' .. fname) - ]], root_dir, fname) + ]], + root_dir, + fname + ) end eq(4, #result) @@ -4250,7 +4713,8 @@ describe('LSP', function() it('correctly handles the registered watch kind', function() local root_dir = 'some_dir' exec_lua(create_server_definition) - local result = exec_lua([[ + local result = exec_lua( + [[ local root_dir = ... local server = _create_server() @@ -4323,13 +4787,18 @@ describe('LSP', function() wait_for_messages() return server.messages - ]], root_dir) + ]], + root_dir + ) local function watched_uri(fname) - return exec_lua([[ + return exec_lua( + [[ local fname = ... return vim.uri_from_fname('/dir/' .. fname) - ]], fname) + ]], + fname + ) end eq(3, #result) @@ -4391,7 +4860,8 @@ describe('LSP', function() it('prunes duplicate events', function() local root_dir = 'some_dir' exec_lua(create_server_definition) - local result = exec_lua([[ + local result = exec_lua( + [[ local root_dir = ... local server = _create_server() @@ -4449,12 +4919,17 @@ describe('LSP', function() wait_for_messages() return server.messages - ]], root_dir) + ]], + root_dir + ) local function watched_uri(fname) - return exec_lua([[ + return exec_lua( + [[ return vim.uri_from_fname(...) - ]], fname) + ]], + fname + ) end eq(3, #result) @@ -4489,7 +4964,8 @@ describe('LSP', function() ]]) local function check_registered(capabilities) - return exec_lua([[ + return exec_lua( + [[ watching = false local client_id = vim.lsp.start({ name = 'watchfiles-test', @@ -4528,31 +5004,41 @@ describe('LSP', function() vim.lsp.stop_client(client_id, true) return watching - ]], capabilities) + ]], + capabilities + ) end - eq(true, check_registered(nil)) -- start{_client}() defaults to make_client_capabilities(). + eq(true, check_registered(nil)) -- start{_client}() defaults to make_client_capabilities(). eq(false, check_registered(vim.empty_dict())) - eq(false, check_registered({ + eq( + false, + check_registered({ workspace = { ignoreMe = true, }, - })) - eq(false, check_registered({ + }) + ) + eq( + false, + check_registered({ workspace = { didChangeWatchedFiles = { dynamicRegistration = false, }, }, - })) - eq(true, check_registered({ + }) + ) + eq( + true, + check_registered({ workspace = { didChangeWatchedFiles = { dynamicRegistration = true, }, }, - })) + }) + ) end) end) end) - diff --git a/test/functional/plugin/man_spec.lua b/test/functional/plugin/man_spec.lua index 815ddbc523..5bfa566729 100644 --- a/test/functional/plugin/man_spec.lua +++ b/test/functional/plugin/man_spec.lua @@ -3,13 +3,13 @@ local Screen = require('test.functional.ui.screen') local command, rawfeed = helpers.command, helpers.rawfeed local clear = helpers.clear local exec_lua = helpers.exec_lua -local funcs = helpers.funcs +local fn = helpers.fn local nvim_prog = helpers.nvim_prog local matches = helpers.matches local write_file = helpers.write_file local tmpname = helpers.tmpname local eq = helpers.eq -local pesc = helpers.pesc +local pesc = vim.pesc local skip = helpers.skip local is_ci = helpers.is_ci @@ -33,7 +33,7 @@ local function get_search_history(name) end clear() -if funcs.executable('man') == 0 then +if fn.executable('man') == 0 then pending('missing "man" command', function() end) return end @@ -49,7 +49,7 @@ describe(':Man', function() before_each(function() command('syntax on') command('set filetype=man') - command('syntax off') -- Ignore syntax groups + command('syntax off') -- Ignore syntax groups screen = Screen.new(52, 5) screen:set_default_attr_ids({ b = { bold = true }, @@ -58,80 +58,87 @@ describe(':Man', function() bi = { bold = true, italic = true }, biu = { bold = true, italic = true, underline = true }, c = { foreground = Screen.colors.Blue }, -- control chars - eob = { bold = true, foreground = Screen.colors.Blue } -- empty line '~'s + eob = { bold = true, foreground = Screen.colors.Blue }, -- empty line '~'s }) screen:attach() end) it('clears backspaces from text and adds highlights', function() - rawfeed([[ + rawfeed( + [[ ithis i<C-v><C-h>is<C-v><C-h>s a<C-v><C-h>a test - with _<C-v><C-h>o_<C-v><C-h>v_<C-v><C-h>e_<C-v><C-h>r_<C-v><C-h>s_<C-v><C-h>t_<C-v><C-h>r_<C-v><C-h>u_<C-v><C-h>c_<C-v><C-h>k text<ESC>]]) + with _<C-v><C-h>o_<C-v><C-h>v_<C-v><C-h>e_<C-v><C-h>r_<C-v><C-h>s_<C-v><C-h>t_<C-v><C-h>r_<C-v><C-h>u_<C-v><C-h>c_<C-v><C-h>k text<ESC>]] + ) - screen:expect{grid=[[ + screen:expect { + grid = [[ this i{c:^H}is{c:^H}s a{c:^H}a test | with _{c:^H}o_{c:^H}v_{c:^H}e_{c:^H}r_{c:^H}s_{c:^H}t_{c:^H}r_{c:^H}u_{c:^H}c_{c:^H}k tex^t | - {eob:~ }| - {eob:~ }| + {eob:~ }|*2 | - ]]} + ]], + } - exec_lua[[require'man'.init_pager()]] + exec_lua [[require'man'.init_pager()]] screen:expect([[ ^this {b:is} {b:a} test | with {i:overstruck} text | - {eob:~ }| - {eob:~ }| + {eob:~ }|*2 | ]]) end) it('clears escape sequences from text and adds highlights', function() - rawfeed([[ + rawfeed( + [[ ithis <C-v><ESC>[1mis <C-v><ESC>[3ma <C-v><ESC>[4mtest<C-v><ESC>[0m - <C-v><ESC>[4mwith<C-v><ESC>[24m <C-v><ESC>[4mescaped<C-v><ESC>[24m <C-v><ESC>[4mtext<C-v><ESC>[24m<ESC>]]) + <C-v><ESC>[4mwith<C-v><ESC>[24m <C-v><ESC>[4mescaped<C-v><ESC>[24m <C-v><ESC>[4mtext<C-v><ESC>[24m<ESC>]] + ) - screen:expect{grid=[=[ + screen:expect { + grid = [=[ this {c:^[}[1mis {c:^[}[3ma {c:^[}[4mtest{c:^[}[0m | {c:^[}[4mwith{c:^[}[24m {c:^[}[4mescaped{c:^[}[24m {c:^[}[4mtext{c:^[}[24^m | - {eob:~ }| - {eob:~ }| + {eob:~ }|*2 | - ]=]} + ]=], + } - exec_lua[[require'man'.init_pager()]] + exec_lua [[require'man'.init_pager()]] screen:expect([[ ^this {b:is }{bi:a }{biu:test} | {u:with} {u:escaped} {u:text} | - {eob:~ }| - {eob:~ }| + {eob:~ }|*2 | ]]) end) it('highlights multibyte text', function() - rawfeed([[ + rawfeed( + [[ ithis i<C-v><C-h>is<C-v><C-h>s あ<C-v><C-h>あ test - with _<C-v><C-h>ö_<C-v><C-h>v_<C-v><C-h>e_<C-v><C-h>r_<C-v><C-h>s_<C-v><C-h>t_<C-v><C-h>r_<C-v><C-h>u_<C-v><C-h>̃_<C-v><C-h>c_<C-v><C-h>k te<C-v><ESC>[3mxt¶<C-v><ESC>[0m<ESC>]]) - exec_lua[[require'man'.init_pager()]] + with _<C-v><C-h>ö_<C-v><C-h>v_<C-v><C-h>e_<C-v><C-h>r_<C-v><C-h>s_<C-v><C-h>t_<C-v><C-h>r_<C-v><C-h>u_<C-v><C-h>̃_<C-v><C-h>c_<C-v><C-h>k te<C-v><ESC>[3mxt¶<C-v><ESC>[0m<ESC>]] + ) + exec_lua [[require'man'.init_pager()]] screen:expect([[ ^this {b:is} {b:あ} test | with {i:överstrũck} te{i:xt¶} | - {eob:~ }| - {eob:~ }| + {eob:~ }|*2 | ]]) end) it('highlights underscores based on context', function() - rawfeed([[ + rawfeed( + [[ i_<C-v><C-h>_b<C-v><C-h>be<C-v><C-h>eg<C-v><C-h>gi<C-v><C-h>in<C-v><C-h>ns<C-v><C-h>s m<C-v><C-h>mi<C-v><C-h>id<C-v><C-h>d_<C-v><C-h>_d<C-v><C-h>dl<C-v><C-h>le<C-v><C-h>e - _<C-v><C-h>m_<C-v><C-h>i_<C-v><C-h>d_<C-v><C-h>__<C-v><C-h>d_<C-v><C-h>l_<C-v><C-h>e<ESC>]]) - exec_lua[[require'man'.init_pager()]] + _<C-v><C-h>m_<C-v><C-h>i_<C-v><C-h>d_<C-v><C-h>__<C-v><C-h>d_<C-v><C-h>l_<C-v><C-h>e<ESC>]] + ) + exec_lua [[require'man'.init_pager()]] screen:expect([[ {b:^_begins} | @@ -147,7 +154,7 @@ describe(':Man', function() i· ·<C-v><C-h>· +<C-v><C-h>o +<C-v><C-h>+<C-v><C-h>o<C-v><C-h>o double<ESC>]]) - exec_lua[[require'man'.init_pager()]] + exec_lua [[require'man'.init_pager()]] screen:expect([[ ^· {b:·} | @@ -164,7 +171,7 @@ describe(':Man', function() <C-v><C-[>[44m 4 <C-v><C-[>[45m 5 <C-v><C-[>[46m 6 <C-v><C-[>[47m 7 <C-v><C-[>[100m 8 <C-v><C-[>[101m 9 <C-v><C-[>[102m 10 <C-v><C-[>[103m 11 <C-v><C-[>[104m 12 <C-v><C-[>[105m 13 <C-v><C-[>[106m 14 <C-v><C-[>[107m 15 <C-v><C-[>[48:5:16m 16 <ESC>]]) - exec_lua[[require'man'.init_pager()]] + exec_lua [[require'man'.init_pager()]] screen:expect([[ ^ 0 1 2 3 | @@ -178,8 +185,14 @@ describe(':Man', function() it('q quits in "$MANPAGER mode" (:Man!) #18281', function() -- This will hang if #18281 regresses. - local args = {nvim_prog, '--headless', '+autocmd VimLeave * echo "quit works!!"', '+Man!', '+call nvim_input("q")'} - matches('quit works!!', funcs.system(args, {'manpage contents'})) + local args = { + nvim_prog, + '--headless', + '+autocmd VimLeave * echo "quit works!!"', + '+Man!', + '+call nvim_input("q")', + } + matches('quit works!!', fn.system(args, { 'manpage contents' })) end) it('reports non-existent man pages for absolute paths', function() @@ -188,41 +201,44 @@ describe(':Man', function() -- actual_file must be an absolute path to an existent file for us to test against it matches('^/.+', actual_file) write_file(actual_file, '') - local args = {nvim_prog, '--headless', '+:Man ' .. actual_file, '+q'} - matches(('Error detected while processing command line:\r\n' .. - 'man.lua: "no manual entry for %s"'):format(pesc(actual_file)), - funcs.system(args, {''})) + local args = { nvim_prog, '--headless', '+:Man ' .. actual_file, '+q' } + matches( + ('Error detected while processing command line:\r\n' .. 'man.lua: "no manual entry for %s"'):format( + pesc(actual_file) + ), + fn.system(args, { '' }) + ) os.remove(actual_file) end) it('tries variants with spaces, underscores #22503', function() eq({ - {'', 'NAME WITH SPACES'}, - {'', 'NAME_WITH_SPACES'}, - }, get_search_history('NAME WITH SPACES')) + { '', 'NAME WITH SPACES' }, + { '', 'NAME_WITH_SPACES' }, + }, get_search_history('NAME WITH SPACES')) eq({ - {'3', 'some other man'}, - {'3', 'some_other_man'}, - }, get_search_history('3 some other man')) + { '3', 'some other man' }, + { '3', 'some_other_man' }, + }, get_search_history('3 some other man')) eq({ - {'3x', 'some other man'}, - {'3x', 'some_other_man'}, - }, get_search_history('3X some other man')) + { '3x', 'some other man' }, + { '3x', 'some_other_man' }, + }, get_search_history('3X some other man')) eq({ - {'3tcl', 'some other man'}, - {'3tcl', 'some_other_man'}, - }, get_search_history('3tcl some other man')) + { '3tcl', 'some other man' }, + { '3tcl', 'some_other_man' }, + }, get_search_history('3tcl some other man')) eq({ - {'n', 'some other man'}, - {'n', 'some_other_man'}, - }, get_search_history('n some other man')) + { 'n', 'some other man' }, + { 'n', 'some_other_man' }, + }, get_search_history('n some other man')) eq({ - {'', '123some other man'}, - {'', '123some_other_man'}, - }, get_search_history('123some other man')) + { '', '123some other man' }, + { '', '123some_other_man' }, + }, get_search_history('123some other man')) eq({ - {'1', 'other_man'}, - {'1', 'other_man'}, - }, get_search_history('other_man(1)')) + { '1', 'other_man' }, + { '1', 'other_man' }, + }, get_search_history('other_man(1)')) end) end) diff --git a/test/functional/plugin/matchparen_spec.lua b/test/functional/plugin/matchparen_spec.lua index 2670734c1a..530afd16e4 100644 --- a/test/functional/plugin/matchparen_spec.lua +++ b/test/functional/plugin/matchparen_spec.lua @@ -3,7 +3,7 @@ local Screen = require('test.functional.ui.screen') local clear = helpers.clear local command = helpers.command -local meths = helpers.meths +local api = helpers.api local feed = helpers.feed local eq = helpers.eq @@ -11,18 +11,18 @@ describe('matchparen', function() local screen before_each(function() - clear{args={'-u', 'NORC'}} - screen = Screen.new(20,5) + clear { args = { '-u', 'NORC' } } + screen = Screen.new(20, 5) screen:attach() - screen:set_default_attr_ids( { - [0] = {bold=true, foreground=255}, - [1] = {bold=true}, - } ) + screen:set_default_attr_ids({ + [0] = { bold = true, foreground = 255 }, + [1] = { bold = true }, + }) end) it('uses correct column after i_<Up>. Vim patch 7.4.1296', function() command('set noautoindent nosmartindent nocindent laststatus=0') - eq(1, meths.get_var('loaded_matchparen')) + eq(1, api.nvim_get_var('loaded_matchparen')) feed('ivoid f_test()<cr>') feed('{<cr>') feed('}') @@ -39,6 +39,5 @@ describe('matchparen', function() } | {1:-- INSERT --} | ]]) - end) end) diff --git a/test/functional/plugin/msgpack_spec.lua b/test/functional/plugin/msgpack_spec.lua index d841cb8ce0..8511e6c703 100644 --- a/test/functional/plugin/msgpack_spec.lua +++ b/test/functional/plugin/msgpack_spec.lua @@ -1,14 +1,16 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear -local meths = helpers.meths -local eq, nvim_eval, nvim_command, exc_exec = - helpers.eq, helpers.eval, helpers.command, helpers.exc_exec +local api = helpers.api +local eq = helpers.eq +local nvim_eval = helpers.eval +local nvim_command = helpers.command +local exc_exec = helpers.exc_exec local ok = helpers.ok -local NIL = helpers.NIL +local NIL = vim.NIL describe('autoload/msgpack.vim', function() before_each(function() - clear{args={'-u', 'NORC'}} + clear { args = { '-u', 'NORC' } } end) local sp = function(typ, val) @@ -16,16 +18,15 @@ describe('autoload/msgpack.vim', function() end local mapsp = function(...) local val = '' - for i=1,(select('#', ...)/2) do - val = ('%s[%s,%s],'):format(val, select(i * 2 - 1, ...), - select(i * 2, ...)) + for i = 1, (select('#', ...) / 2) do + val = ('%s[%s,%s],'):format(val, select(i * 2 - 1, ...), select(i * 2, ...)) end return sp('map', '[' .. val .. ']') end - local nan = -(1.0/0.0-1.0/0.0) - local inf = 1.0/0.0 - local minus_inf = -(1.0/0.0) + local nan = -(1.0 / 0.0 - 1.0 / 0.0) + local inf = 1.0 / 0.0 + local minus_inf = -(1.0 / 0.0) describe('function msgpack#equal', function() local msgpack_eq = function(expected, a, b) @@ -39,10 +40,8 @@ describe('autoload/msgpack.vim', function() msgpack_eq(0, '1', '0') end) it('compares integer specials correctly', function() - msgpack_eq(1, sp('integer', '[-1, 1, 0, 0]'), - sp('integer', '[-1, 1, 0, 0]')) - msgpack_eq(0, sp('integer', '[-1, 1, 0, 0]'), - sp('integer', '[ 1, 1, 0, 0]')) + msgpack_eq(1, sp('integer', '[-1, 1, 0, 0]'), sp('integer', '[-1, 1, 0, 0]')) + msgpack_eq(0, sp('integer', '[-1, 1, 0, 0]'), sp('integer', '[ 1, 1, 0, 0]')) end) it('compares integer specials with raw integer correctly', function() msgpack_eq(1, sp('integer', '[-1, 0, 0, 1]'), '-1') @@ -58,27 +57,21 @@ describe('autoload/msgpack.vim', function() msgpack_eq(0, '"abc\\ndef"', '"abc\\nghi"') end) it('compares binary specials correctly', function() - msgpack_eq(1, sp('binary', '["abc\\n", "def"]'), - sp('binary', '["abc\\n", "def"]')) - msgpack_eq(0, sp('binary', '["abc", "def"]'), - sp('binary', '["abc\\n", "def"]')) + msgpack_eq(1, sp('binary', '["abc\\n", "def"]'), sp('binary', '["abc\\n", "def"]')) + msgpack_eq(0, sp('binary', '["abc", "def"]'), sp('binary', '["abc\\n", "def"]')) end) it('compares binary specials with raw binaries correctly', function() msgpack_eq(1, sp('binary', '["abc", "def"]'), '"abc\\ndef"') msgpack_eq(0, sp('binary', '["abc", "def"]'), '"abcdef"') end) it('compares string specials correctly', function() - msgpack_eq(1, sp('string', '["abc\\n", "def"]'), - sp('string', '["abc\\n", "def"]')) - msgpack_eq(0, sp('string', '["abc", "def"]'), - sp('string', '["abc\\n", "def"]')) + msgpack_eq(1, sp('string', '["abc\\n", "def"]'), sp('string', '["abc\\n", "def"]')) + msgpack_eq(0, sp('string', '["abc", "def"]'), sp('string', '["abc\\n", "def"]')) end) it('compares string specials with binary correctly', function() - msgpack_eq(0, sp('string', '["abc\\n", "def"]'), - sp('binary', '["abc\\n", "def"]')) + msgpack_eq(0, sp('string', '["abc\\n", "def"]'), sp('binary', '["abc\\n", "def"]')) msgpack_eq(0, sp('string', '["abc", "def"]'), '"abc\\ndef"') - msgpack_eq(0, sp('binary', '["abc\\n", "def"]'), - sp('string', '["abc\\n", "def"]')) + msgpack_eq(0, sp('binary', '["abc\\n", "def"]'), sp('string', '["abc\\n", "def"]')) msgpack_eq(0, '"abc\\ndef"', sp('string', '["abc", "def"]')) end) it('compares ext specials correctly', function() @@ -97,44 +90,54 @@ describe('autoload/msgpack.vim', function() end) it('compares map specials correctly', function() msgpack_eq(1, mapsp(), mapsp()) - msgpack_eq(1, mapsp(sp('binary', '[""]'), '""'), - mapsp(sp('binary', '[""]'), '""')) - msgpack_eq(1, mapsp(mapsp('1', '1'), mapsp('1', '1')), - mapsp(mapsp('1', '1'), mapsp('1', '1'))) + msgpack_eq(1, mapsp(sp('binary', '[""]'), '""'), mapsp(sp('binary', '[""]'), '""')) + msgpack_eq( + 1, + mapsp(mapsp('1', '1'), mapsp('1', '1')), + mapsp(mapsp('1', '1'), mapsp('1', '1')) + ) msgpack_eq(0, mapsp(), mapsp('1', '1')) - msgpack_eq(0, mapsp(sp('binary', '["a"]'), '""'), - mapsp(sp('binary', '[""]'), '""')) - msgpack_eq(0, mapsp(sp('binary', '[""]'), '"a"'), - mapsp(sp('binary', '[""]'), '""')) - msgpack_eq(0, mapsp(sp('binary', '["a"]'), '"a"'), - mapsp(sp('binary', '[""]'), '""')) - msgpack_eq(0, mapsp(mapsp('1', '1'), mapsp('1', '1')), - mapsp(sp('binary', '[""]'), mapsp('1', '1'))) - msgpack_eq(0, mapsp(mapsp('1', '1'), mapsp('1', '1')), - mapsp(mapsp('2', '1'), mapsp('1', '1'))) - msgpack_eq(0, mapsp(mapsp('1', '1'), mapsp('1', '1')), - mapsp(mapsp('1', '2'), mapsp('1', '1'))) - msgpack_eq(0, mapsp(mapsp('1', '1'), mapsp('1', '1')), - mapsp(mapsp('1', '1'), mapsp('2', '1'))) - msgpack_eq(0, mapsp(mapsp('1', '1'), mapsp('1', '1')), - mapsp(mapsp('1', '1'), mapsp('1', '2'))) - msgpack_eq(1, mapsp(mapsp('2', '1'), mapsp('1', '1'), - mapsp('1', '1'), mapsp('1', '1')), - mapsp(mapsp('1', '1'), mapsp('1', '1'), - mapsp('2', '1'), mapsp('1', '1'))) + msgpack_eq(0, mapsp(sp('binary', '["a"]'), '""'), mapsp(sp('binary', '[""]'), '""')) + msgpack_eq(0, mapsp(sp('binary', '[""]'), '"a"'), mapsp(sp('binary', '[""]'), '""')) + msgpack_eq(0, mapsp(sp('binary', '["a"]'), '"a"'), mapsp(sp('binary', '[""]'), '""')) + msgpack_eq( + 0, + mapsp(mapsp('1', '1'), mapsp('1', '1')), + mapsp(sp('binary', '[""]'), mapsp('1', '1')) + ) + msgpack_eq( + 0, + mapsp(mapsp('1', '1'), mapsp('1', '1')), + mapsp(mapsp('2', '1'), mapsp('1', '1')) + ) + msgpack_eq( + 0, + mapsp(mapsp('1', '1'), mapsp('1', '1')), + mapsp(mapsp('1', '2'), mapsp('1', '1')) + ) + msgpack_eq( + 0, + mapsp(mapsp('1', '1'), mapsp('1', '1')), + mapsp(mapsp('1', '1'), mapsp('2', '1')) + ) + msgpack_eq( + 0, + mapsp(mapsp('1', '1'), mapsp('1', '1')), + mapsp(mapsp('1', '1'), mapsp('1', '2')) + ) + msgpack_eq( + 1, + mapsp(mapsp('2', '1'), mapsp('1', '1'), mapsp('1', '1'), mapsp('1', '1')), + mapsp(mapsp('1', '1'), mapsp('1', '1'), mapsp('2', '1'), mapsp('1', '1')) + ) end) it('compares map specials with raw maps correctly', function() msgpack_eq(1, mapsp(), '{}') msgpack_eq(1, mapsp(sp('string', '["1"]'), '1'), '{"1": 1}') - msgpack_eq(1, mapsp(sp('string', '["1"]'), sp('integer', '[1, 0, 0, 1]')), - '{"1": 1}') - msgpack_eq(0, mapsp(sp('integer', '[1, 0, 0, 1]'), sp('string', '["1"]')), - '{1: "1"}') - msgpack_eq(0, mapsp('"1"', sp('integer', '[1, 0, 0, 1]')), - '{"1": 1}') - msgpack_eq(0, - mapsp(sp('string', '["1"]'), '1', sp('string', '["2"]'), '2'), - '{"1": 1}') + msgpack_eq(1, mapsp(sp('string', '["1"]'), sp('integer', '[1, 0, 0, 1]')), '{"1": 1}') + msgpack_eq(0, mapsp(sp('integer', '[1, 0, 0, 1]'), sp('string', '["1"]')), '{1: "1"}') + msgpack_eq(0, mapsp('"1"', sp('integer', '[1, 0, 0, 1]')), '{"1": 1}') + msgpack_eq(0, mapsp(sp('string', '["1"]'), '1', sp('string', '["2"]'), '2'), '{"1": 1}') msgpack_eq(0, mapsp(sp('string', '["1"]'), '1'), '{"1": 1, "2": 2}') end) it('compares raw arrays correctly', function() @@ -195,8 +198,7 @@ describe('autoload/msgpack.vim', function() end) it('compares float specials correctly', function() msgpack_eq(1, sp('float', '0.0'), sp('float', '0.0')) - msgpack_eq(1, sp('float', '(1.0/0.0-1.0/0.0)'), - sp('float', '(1.0/0.0-1.0/0.0)')) + msgpack_eq(1, sp('float', '(1.0/0.0-1.0/0.0)'), sp('float', '(1.0/0.0-1.0/0.0)')) msgpack_eq(1, sp('float', '1.0/0.0'), sp('float', '1.0/0.0')) msgpack_eq(1, sp('float', '-(1.0/0.0)'), sp('float', '-(1.0/0.0)')) msgpack_eq(1, sp('float', '0.0'), sp('float', '0.0')) @@ -206,10 +208,8 @@ describe('autoload/msgpack.vim', function() msgpack_eq(0, sp('float', '0.0'), sp('float', '-(1.0/0.0)')) msgpack_eq(0, sp('float', '1.0/0.0'), sp('float', '-(1.0/0.0)')) msgpack_eq(0, sp('float', '(1.0/0.0-1.0/0.0)'), sp('float', '-(1.0/0.0)')) - msgpack_eq(1, sp('float', '(1.0/0.0-1.0/0.0)'), - sp('float', '-(1.0/0.0-1.0/0.0)')) - msgpack_eq(1, sp('float', '-(1.0/0.0-1.0/0.0)'), - sp('float', '-(1.0/0.0-1.0/0.0)')) + msgpack_eq(1, sp('float', '(1.0/0.0-1.0/0.0)'), sp('float', '-(1.0/0.0-1.0/0.0)')) + msgpack_eq(1, sp('float', '-(1.0/0.0-1.0/0.0)'), sp('float', '-(1.0/0.0-1.0/0.0)')) msgpack_eq(0, sp('float', '(1.0/0.0-1.0/0.0)'), sp('float', '1.0/0.0')) end) it('compares boolean specials correctly', function() @@ -219,8 +219,7 @@ describe('autoload/msgpack.vim', function() it('compares nil specials correctly', function() msgpack_eq(1, sp('nil', '1'), sp('nil', '0')) end) - it('compares nil, boolean and integer values with each other correctly', - function() + it('compares nil, boolean and integer values with each other correctly', function() msgpack_eq(0, sp('boolean', '1'), '1') msgpack_eq(0, sp('boolean', '1'), sp('nil', '0')) msgpack_eq(0, sp('boolean', '1'), sp('nil', '1')) @@ -238,16 +237,11 @@ describe('autoload/msgpack.vim', function() it('works', function() eq(1, nvim_eval('msgpack#is_int(1)')) eq(1, nvim_eval('msgpack#is_int(-1)')) - eq(1, nvim_eval(('msgpack#is_int(%s)'):format( - sp('integer', '[1, 0, 0, 1]')))) - eq(1, nvim_eval(('msgpack#is_int(%s)'):format( - sp('integer', '[-1, 0, 0, 1]')))) - eq(0, nvim_eval(('msgpack#is_int(%s)'):format( - sp('float', '0.0')))) - eq(0, nvim_eval(('msgpack#is_int(%s)'):format( - sp('boolean', '0')))) - eq(0, nvim_eval(('msgpack#is_int(%s)'):format( - sp('nil', '0')))) + eq(1, nvim_eval(('msgpack#is_int(%s)'):format(sp('integer', '[1, 0, 0, 1]')))) + eq(1, nvim_eval(('msgpack#is_int(%s)'):format(sp('integer', '[-1, 0, 0, 1]')))) + eq(0, nvim_eval(('msgpack#is_int(%s)'):format(sp('float', '0.0')))) + eq(0, nvim_eval(('msgpack#is_int(%s)'):format(sp('boolean', '0')))) + eq(0, nvim_eval(('msgpack#is_int(%s)'):format(sp('nil', '0')))) eq(0, nvim_eval('msgpack#is_int("")')) end) end) @@ -256,16 +250,11 @@ describe('autoload/msgpack.vim', function() it('works', function() eq(1, nvim_eval('msgpack#is_uint(1)')) eq(0, nvim_eval('msgpack#is_uint(-1)')) - eq(1, nvim_eval(('msgpack#is_uint(%s)'):format( - sp('integer', '[1, 0, 0, 1]')))) - eq(0, nvim_eval(('msgpack#is_uint(%s)'):format( - sp('integer', '[-1, 0, 0, 1]')))) - eq(0, nvim_eval(('msgpack#is_uint(%s)'):format( - sp('float', '0.0')))) - eq(0, nvim_eval(('msgpack#is_uint(%s)'):format( - sp('boolean', '0')))) - eq(0, nvim_eval(('msgpack#is_uint(%s)'):format( - sp('nil', '0')))) + eq(1, nvim_eval(('msgpack#is_uint(%s)'):format(sp('integer', '[1, 0, 0, 1]')))) + eq(0, nvim_eval(('msgpack#is_uint(%s)'):format(sp('integer', '[-1, 0, 0, 1]')))) + eq(0, nvim_eval(('msgpack#is_uint(%s)'):format(sp('float', '0.0')))) + eq(0, nvim_eval(('msgpack#is_uint(%s)'):format(sp('boolean', '0')))) + eq(0, nvim_eval(('msgpack#is_uint(%s)'):format(sp('nil', '0')))) eq(0, nvim_eval('msgpack#is_uint("")')) end) end) @@ -274,18 +263,20 @@ describe('autoload/msgpack.vim', function() it('works', function() local epoch = os.date('%Y-%m-%dT%H:%M:%S', 0) eq(epoch, nvim_eval('msgpack#strftime("%Y-%m-%dT%H:%M:%S", 0)')) - eq(epoch, nvim_eval( - ('msgpack#strftime("%%Y-%%m-%%dT%%H:%%M:%%S", %s)'):format(sp( - 'integer', '[1, 0, 0, 0]')))) + eq( + epoch, + nvim_eval( + ('msgpack#strftime("%%Y-%%m-%%dT%%H:%%M:%%S", %s)'):format(sp('integer', '[1, 0, 0, 0]')) + ) + ) end) end) describe('function msgpack#strptime', function() it('works', function() - for _, v in ipairs({0, 10, 100000, 204, 1000000000}) do + for _, v in ipairs({ 0, 10, 100000, 204, 1000000000 }) do local time = os.date('%Y-%m-%dT%H:%M:%S', v) - eq(v, nvim_eval('msgpack#strptime("%Y-%m-%dT%H:%M:%S", ' - .. '"' .. time .. '")')) + eq(v, nvim_eval('msgpack#strptime("%Y-%m-%dT%H:%M:%S", ' .. '"' .. time .. '")')) end end) end) @@ -367,25 +358,27 @@ describe('autoload/msgpack.vim', function() string_eq('[[[[{}]]]]', sp('array', '[[[[{}]]]]')) string_eq('{}', sp('map', '[]')) string_eq('{2: 10}', sp('map', '[[2, 10]]')) - string_eq('{{1: 1}: {1: 1}, {2: 1}: {1: 1}}', - mapsp(mapsp('2', '1'), mapsp('1', '1'), - mapsp('1', '1'), mapsp('1', '1'))) - string_eq('{{1: 1}: {1: 1}, {2: 1}: {1: 1}}', - mapsp(mapsp('1', '1'), mapsp('1', '1'), - mapsp('2', '1'), mapsp('1', '1'))) - string_eq('{[1, 2, {{1: 2}: 1}]: [1, 2, {{1: 2}: 1}]}', - mapsp(('[1, 2, %s]'):format(mapsp(mapsp('1', '2'), '1')), - ('[1, 2, %s]'):format(mapsp(mapsp('1', '2'), '1')))) + string_eq( + '{{1: 1}: {1: 1}, {2: 1}: {1: 1}}', + mapsp(mapsp('2', '1'), mapsp('1', '1'), mapsp('1', '1'), mapsp('1', '1')) + ) + string_eq( + '{{1: 1}: {1: 1}, {2: 1}: {1: 1}}', + mapsp(mapsp('1', '1'), mapsp('1', '1'), mapsp('2', '1'), mapsp('1', '1')) + ) + string_eq( + '{[1, 2, {{1: 2}: 1}]: [1, 2, {{1: 2}: 1}]}', + mapsp( + ('[1, 2, %s]'):format(mapsp(mapsp('1', '2'), '1')), + ('[1, 2, %s]'):format(mapsp(mapsp('1', '2'), '1')) + ) + ) string_eq('0x0000000000000000', sp('integer', '[1, 0, 0, 0]')) string_eq('-0x0000000100000000', sp('integer', '[-1, 0, 2, 0]')) - string_eq('0x123456789abcdef0', - sp('integer', '[ 1, 0, 610839793, 448585456]')) - string_eq('-0x123456789abcdef0', - sp('integer', '[-1, 0, 610839793, 448585456]')) - string_eq('0xf23456789abcdef0', - sp('integer', '[ 1, 3, 1684581617, 448585456]')) - string_eq('-0x723456789abcdef0', - sp('integer', '[-1, 1, 1684581617, 448585456]')) + string_eq('0x123456789abcdef0', sp('integer', '[ 1, 0, 610839793, 448585456]')) + string_eq('-0x123456789abcdef0', sp('integer', '[-1, 0, 610839793, 448585456]')) + string_eq('0xf23456789abcdef0', sp('integer', '[ 1, 3, 1684581617, 448585456]')) + string_eq('-0x723456789abcdef0', sp('integer', '[-1, 1, 1684581617, 448585456]')) string_eq('0.0', sp('float', '0.0')) string_eq('inf', sp('float', '(1.0/0.0)')) string_eq('-inf', sp('float', '-(1.0/0.0)')) @@ -466,15 +459,15 @@ describe('autoload/msgpack.vim', function() nvim_command('let spbln._VAL = 1') nvim_command('let spnil._VAL = 1') - eq({_TYPE={}, _VAL={{{}}}}, nvim_eval('sparr2')) - eq({_TYPE={}, _VAL={{'abc', {{}}}}}, nvim_eval('spmap2')) - eq({_TYPE={}, _VAL={1, 0, 0, 0}}, nvim_eval('spint2')) - eq({_TYPE={}, _VAL=1.0}, nvim_eval('spflt2')) - eq({_TYPE={}, _VAL={2, {'abc', 'def'}}}, nvim_eval('spext2')) - eq({_TYPE={}, _VAL={'abc', 'def'}}, nvim_eval('spstr2')) - eq({_TYPE={}, _VAL={'abc', 'def'}}, nvim_eval('spbin2')) - eq({_TYPE={}, _VAL=0}, nvim_eval('spbln2')) - eq({_TYPE={}, _VAL=0}, nvim_eval('spnil2')) + eq({ _TYPE = {}, _VAL = { { {} } } }, nvim_eval('sparr2')) + eq({ _TYPE = {}, _VAL = { { 'abc', { {} } } } }, nvim_eval('spmap2')) + eq({ _TYPE = {}, _VAL = { 1, 0, 0, 0 } }, nvim_eval('spint2')) + eq({ _TYPE = {}, _VAL = 1.0 }, nvim_eval('spflt2')) + eq({ _TYPE = {}, _VAL = { 2, { 'abc', 'def' } } }, nvim_eval('spext2')) + eq({ _TYPE = {}, _VAL = { 'abc', 'def' } }, nvim_eval('spstr2')) + eq({ _TYPE = {}, _VAL = { 'abc', 'def' } }, nvim_eval('spbin2')) + eq({ _TYPE = {}, _VAL = 0 }, nvim_eval('spbln2')) + eq({ _TYPE = {}, _VAL = 0 }, nvim_eval('spnil2')) nvim_command('let sparr._TYPE = []') nvim_command('let spmap._TYPE = []') @@ -525,38 +518,40 @@ describe('autoload/msgpack.vim', function() nvim_command('let flt = 3.0') nvim_command('let bin = ""') - eq({{{}}}, nvim_eval('arr2')) - eq({['1']={}}, nvim_eval('map2')) + eq({ { {} } }, nvim_eval('arr2')) + eq({ ['1'] = {} }, nvim_eval('map2')) eq(1, nvim_eval('int2')) eq(2.0, nvim_eval('flt2')) eq('abc', nvim_eval('bin2')) end) it('works for special v: values like v:true', function() - meths.set_var('true', true) - meths.set_var('false', false) - meths.set_var('nil', NIL) + api.nvim_set_var('true', true) + api.nvim_set_var('false', false) + api.nvim_set_var('nil', NIL) nvim_command('let true2 = msgpack#deepcopy(true)') nvim_command('let false2 = msgpack#deepcopy(false)') nvim_command('let nil2 = msgpack#deepcopy(nil)') - eq(true, meths.get_var('true')) - eq(false, meths.get_var('false')) - eq(NIL, meths.get_var('nil')) + eq(true, api.nvim_get_var('true')) + eq(false, api.nvim_get_var('false')) + eq(NIL, api.nvim_get_var('nil')) end) end) describe('function msgpack#eval', function() local eval_eq = function(expected_type, expected_val, str, ...) - nvim_command(('let g:__val = msgpack#eval(\'%s\', %s)'):format(str:gsub( - '\'', '\'\''), select(1, ...) or '{}')) + nvim_command( + ("let g:__val = msgpack#eval('%s', %s)"):format(str:gsub("'", "''"), select(1, ...) or '{}') + ) eq(expected_type, nvim_eval('msgpack#type(g:__val)')) local expected_val_full = expected_val - if (not (({float=true, integer=true})[expected_type] - and type(expected_val) ~= 'table') - and expected_type ~= 'array') then - expected_val_full = {_TYPE={}, _VAL=expected_val_full} + if + not (({ float = true, integer = true })[expected_type] and type(expected_val) ~= 'table') + and expected_type ~= 'array' + then + expected_val_full = { _TYPE = {}, _VAL = expected_val_full } end if expected_val_full == expected_val_full then eq(expected_val_full, nvim_eval('g:__val')) @@ -570,68 +565,65 @@ describe('autoload/msgpack.vim', function() end it('correctly loads binary strings', function() - eval_eq('binary', {'abcdef'}, '"abcdef"') - eval_eq('binary', {'abc', 'def'}, '"abc\\ndef"') - eval_eq('binary', {'abc\ndef'}, '"abc\\0def"') - eval_eq('binary', {'\nabc\ndef\n'}, '"\\0abc\\0def\\0"') - eval_eq('binary', {'abc\n\n\ndef'}, '"abc\\0\\0\\0def"') - eval_eq('binary', {'abc\n', '\ndef'}, '"abc\\0\\n\\0def"') - eval_eq('binary', {'abc', '', '', 'def'}, '"abc\\n\\n\\ndef"') - eval_eq('binary', {'abc', '', '', 'def', ''}, '"abc\\n\\n\\ndef\\n"') - eval_eq('binary', {'', 'abc', '', '', 'def'}, '"\\nabc\\n\\n\\ndef"') - eval_eq('binary', {''}, '""') - eval_eq('binary', {'"'}, '"\\""') - eval_eq('binary', {'py3 print(sys.version_info)'}, - '"py3 print(sys.version_info)"') + eval_eq('binary', { 'abcdef' }, '"abcdef"') + eval_eq('binary', { 'abc', 'def' }, '"abc\\ndef"') + eval_eq('binary', { 'abc\ndef' }, '"abc\\0def"') + eval_eq('binary', { '\nabc\ndef\n' }, '"\\0abc\\0def\\0"') + eval_eq('binary', { 'abc\n\n\ndef' }, '"abc\\0\\0\\0def"') + eval_eq('binary', { 'abc\n', '\ndef' }, '"abc\\0\\n\\0def"') + eval_eq('binary', { 'abc', '', '', 'def' }, '"abc\\n\\n\\ndef"') + eval_eq('binary', { 'abc', '', '', 'def', '' }, '"abc\\n\\n\\ndef\\n"') + eval_eq('binary', { '', 'abc', '', '', 'def' }, '"\\nabc\\n\\n\\ndef"') + eval_eq('binary', { '' }, '""') + eval_eq('binary', { '"' }, '"\\""') + eval_eq('binary', { 'py3 print(sys.version_info)' }, '"py3 print(sys.version_info)"') end) it('correctly loads strings', function() - eval_eq('string', {'abcdef'}, '="abcdef"') - eval_eq('string', {'abc', 'def'}, '="abc\\ndef"') - eval_eq('string', {'abc\ndef'}, '="abc\\0def"') - eval_eq('string', {'\nabc\ndef\n'}, '="\\0abc\\0def\\0"') - eval_eq('string', {'abc\n\n\ndef'}, '="abc\\0\\0\\0def"') - eval_eq('string', {'abc\n', '\ndef'}, '="abc\\0\\n\\0def"') - eval_eq('string', {'abc', '', '', 'def'}, '="abc\\n\\n\\ndef"') - eval_eq('string', {'abc', '', '', 'def', ''}, '="abc\\n\\n\\ndef\\n"') - eval_eq('string', {'', 'abc', '', '', 'def'}, '="\\nabc\\n\\n\\ndef"') - eval_eq('string', {''}, '=""') - eval_eq('string', {'"'}, '="\\""') - eval_eq('string', {'py3 print(sys.version_info)'}, - '="py3 print(sys.version_info)"') + eval_eq('string', { 'abcdef' }, '="abcdef"') + eval_eq('string', { 'abc', 'def' }, '="abc\\ndef"') + eval_eq('string', { 'abc\ndef' }, '="abc\\0def"') + eval_eq('string', { '\nabc\ndef\n' }, '="\\0abc\\0def\\0"') + eval_eq('string', { 'abc\n\n\ndef' }, '="abc\\0\\0\\0def"') + eval_eq('string', { 'abc\n', '\ndef' }, '="abc\\0\\n\\0def"') + eval_eq('string', { 'abc', '', '', 'def' }, '="abc\\n\\n\\ndef"') + eval_eq('string', { 'abc', '', '', 'def', '' }, '="abc\\n\\n\\ndef\\n"') + eval_eq('string', { '', 'abc', '', '', 'def' }, '="\\nabc\\n\\n\\ndef"') + eval_eq('string', { '' }, '=""') + eval_eq('string', { '"' }, '="\\""') + eval_eq('string', { 'py3 print(sys.version_info)' }, '="py3 print(sys.version_info)"') end) it('correctly loads ext values', function() - eval_eq('ext', {0, {'abcdef'}}, '+(0)"abcdef"') - eval_eq('ext', {0, {'abc', 'def'}}, '+(0)"abc\\ndef"') - eval_eq('ext', {0, {'abc\ndef'}}, '+(0)"abc\\0def"') - eval_eq('ext', {0, {'\nabc\ndef\n'}}, '+(0)"\\0abc\\0def\\0"') - eval_eq('ext', {0, {'abc\n\n\ndef'}}, '+(0)"abc\\0\\0\\0def"') - eval_eq('ext', {0, {'abc\n', '\ndef'}}, '+(0)"abc\\0\\n\\0def"') - eval_eq('ext', {0, {'abc', '', '', 'def'}}, '+(0)"abc\\n\\n\\ndef"') - eval_eq('ext', {0, {'abc', '', '', 'def', ''}}, - '+(0)"abc\\n\\n\\ndef\\n"') - eval_eq('ext', {0, {'', 'abc', '', '', 'def'}}, - '+(0)"\\nabc\\n\\n\\ndef"') - eval_eq('ext', {0, {''}}, '+(0)""') - eval_eq('ext', {0, {'"'}}, '+(0)"\\""') - - eval_eq('ext', {-1, {'abcdef'}}, '+(-1)"abcdef"') - eval_eq('ext', {-1, {'abc', 'def'}}, '+(-1)"abc\\ndef"') - eval_eq('ext', {-1, {'abc\ndef'}}, '+(-1)"abc\\0def"') - eval_eq('ext', {-1, {'\nabc\ndef\n'}}, '+(-1)"\\0abc\\0def\\0"') - eval_eq('ext', {-1, {'abc\n\n\ndef'}}, '+(-1)"abc\\0\\0\\0def"') - eval_eq('ext', {-1, {'abc\n', '\ndef'}}, '+(-1)"abc\\0\\n\\0def"') - eval_eq('ext', {-1, {'abc', '', '', 'def'}}, '+(-1)"abc\\n\\n\\ndef"') - eval_eq('ext', {-1, {'abc', '', '', 'def', ''}}, - '+(-1)"abc\\n\\n\\ndef\\n"') - eval_eq('ext', {-1, {'', 'abc', '', '', 'def'}}, - '+(-1)"\\nabc\\n\\n\\ndef"') - eval_eq('ext', {-1, {''}}, '+(-1)""') - eval_eq('ext', {-1, {'"'}}, '+(-1)"\\""') - - eval_eq('ext', {42, {'py3 print(sys.version_info)'}}, - '+(42)"py3 print(sys.version_info)"') + eval_eq('ext', { 0, { 'abcdef' } }, '+(0)"abcdef"') + eval_eq('ext', { 0, { 'abc', 'def' } }, '+(0)"abc\\ndef"') + eval_eq('ext', { 0, { 'abc\ndef' } }, '+(0)"abc\\0def"') + eval_eq('ext', { 0, { '\nabc\ndef\n' } }, '+(0)"\\0abc\\0def\\0"') + eval_eq('ext', { 0, { 'abc\n\n\ndef' } }, '+(0)"abc\\0\\0\\0def"') + eval_eq('ext', { 0, { 'abc\n', '\ndef' } }, '+(0)"abc\\0\\n\\0def"') + eval_eq('ext', { 0, { 'abc', '', '', 'def' } }, '+(0)"abc\\n\\n\\ndef"') + eval_eq('ext', { 0, { 'abc', '', '', 'def', '' } }, '+(0)"abc\\n\\n\\ndef\\n"') + eval_eq('ext', { 0, { '', 'abc', '', '', 'def' } }, '+(0)"\\nabc\\n\\n\\ndef"') + eval_eq('ext', { 0, { '' } }, '+(0)""') + eval_eq('ext', { 0, { '"' } }, '+(0)"\\""') + + eval_eq('ext', { -1, { 'abcdef' } }, '+(-1)"abcdef"') + eval_eq('ext', { -1, { 'abc', 'def' } }, '+(-1)"abc\\ndef"') + eval_eq('ext', { -1, { 'abc\ndef' } }, '+(-1)"abc\\0def"') + eval_eq('ext', { -1, { '\nabc\ndef\n' } }, '+(-1)"\\0abc\\0def\\0"') + eval_eq('ext', { -1, { 'abc\n\n\ndef' } }, '+(-1)"abc\\0\\0\\0def"') + eval_eq('ext', { -1, { 'abc\n', '\ndef' } }, '+(-1)"abc\\0\\n\\0def"') + eval_eq('ext', { -1, { 'abc', '', '', 'def' } }, '+(-1)"abc\\n\\n\\ndef"') + eval_eq('ext', { -1, { 'abc', '', '', 'def', '' } }, '+(-1)"abc\\n\\n\\ndef\\n"') + eval_eq('ext', { -1, { '', 'abc', '', '', 'def' } }, '+(-1)"\\nabc\\n\\n\\ndef"') + eval_eq('ext', { -1, { '' } }, '+(-1)""') + eval_eq('ext', { -1, { '"' } }, '+(-1)"\\""') + + eval_eq( + 'ext', + { 42, { 'py3 print(sys.version_info)' } }, + '+(42)"py3 print(sys.version_info)"' + ) end) it('correctly loads floats', function() @@ -650,17 +642,17 @@ describe('autoload/msgpack.vim', function() it('correctly loads integers', function() eval_eq('integer', 10, '10') eval_eq('integer', -10, '-10') - eval_eq('integer', { 1, 0, 610839793, 448585456}, ' 0x123456789ABCDEF0') - eval_eq('integer', {-1, 0, 610839793, 448585456}, '-0x123456789ABCDEF0') - eval_eq('integer', { 1, 3, 1684581617, 448585456}, ' 0xF23456789ABCDEF0') - eval_eq('integer', {-1, 1, 1684581617, 448585456}, '-0x723456789ABCDEF0') - eval_eq('integer', { 1, 0, 0, 0x100}, '0x100') - eval_eq('integer', {-1, 0, 0, 0x100}, '-0x100') + eval_eq('integer', { 1, 0, 610839793, 448585456 }, ' 0x123456789ABCDEF0') + eval_eq('integer', { -1, 0, 610839793, 448585456 }, '-0x123456789ABCDEF0') + eval_eq('integer', { 1, 3, 1684581617, 448585456 }, ' 0xF23456789ABCDEF0') + eval_eq('integer', { -1, 1, 1684581617, 448585456 }, '-0x723456789ABCDEF0') + eval_eq('integer', { 1, 0, 0, 0x100 }, '0x100') + eval_eq('integer', { -1, 0, 0, 0x100 }, '-0x100') - eval_eq('integer', ('a'):byte(), '\'a\'') - eval_eq('integer', 0xAB, '\'«\'') - eval_eq('integer', 0, '\'\\0\'') - eval_eq('integer', 10246567, '\'\\10246567\'') + eval_eq('integer', ('a'):byte(), "'a'") + eval_eq('integer', 0xAB, "'«'") + eval_eq('integer', 0, "'\\0'") + eval_eq('integer', 10246567, "'\\10246567'") end) it('correctly loads constants', function() @@ -668,71 +660,94 @@ describe('autoload/msgpack.vim', function() eval_eq('boolean', 0, 'FALSE') eval_eq('nil', 0, 'NIL') eval_eq('nil', 0, 'NIL', '{"NIL": 1, "nan": 2, "T": 3}') - eval_eq('float', nan, 'nan', - '{"NIL": "1", "nan": "2", "T": "3"}') + eval_eq('float', nan, 'nan', '{"NIL": "1", "nan": "2", "T": "3"}') eval_eq('integer', 3, 'T', '{"NIL": "1", "nan": "2", "T": "3"}') - eval_eq('integer', {1, 0, 0, 0}, 'T', - ('{"NIL": "1", "nan": "2", "T": \'%s\'}'):format( - sp('integer', '[1, 0, 0, 0]'))) + eval_eq( + 'integer', + { 1, 0, 0, 0 }, + 'T', + ('{"NIL": "1", "nan": "2", "T": \'%s\'}'):format(sp('integer', '[1, 0, 0, 0]')) + ) end) it('correctly loads maps', function() eval_eq('map', {}, '{}') - eval_eq('map', {{{_TYPE={}, _VAL={{1, 2}}}, {_TYPE={}, _VAL={{3, 4}}}}}, - '{{1: 2}: {3: 4}}') - eval_eq('map', {{{_TYPE={}, _VAL={{1, 2}}}, {_TYPE={}, _VAL={{3, 4}}}}, - {1, 2}}, - '{{1: 2}: {3: 4}, 1: 2}') - - eval_eq('map', {{{_TYPE={}, _VAL={ - {{_TYPE={}, _VAL={'py3 print(sys.version_info)'}}, - 2}}}, - {_TYPE={}, _VAL={{3, 4}}}}, - {1, 2}}, - '{{"py3 print(sys.version_info)": 2}: {3: 4}, 1: 2}') + eval_eq( + 'map', + { { { _TYPE = {}, _VAL = { { 1, 2 } } }, { _TYPE = {}, _VAL = { { 3, 4 } } } } }, + '{{1: 2}: {3: 4}}' + ) + eval_eq( + 'map', + { { { _TYPE = {}, _VAL = { { 1, 2 } } }, { _TYPE = {}, _VAL = { { 3, 4 } } } }, { 1, 2 } }, + '{{1: 2}: {3: 4}, 1: 2}' + ) + + eval_eq('map', { + { + { + _TYPE = {}, + _VAL = { + { { _TYPE = {}, _VAL = { 'py3 print(sys.version_info)' } }, 2 }, + }, + }, + { _TYPE = {}, _VAL = { { 3, 4 } } }, + }, + { 1, 2 }, + }, '{{"py3 print(sys.version_info)": 2}: {3: 4}, 1: 2}') end) it('correctly loads arrays', function() eval_eq('array', {}, '[]') - eval_eq('array', {1}, '[1]') - eval_eq('array', {{_TYPE={}, _VAL=1}}, '[TRUE]') - eval_eq('array', {{{_TYPE={}, _VAL={{1, 2}}}}, {_TYPE={}, _VAL={{3, 4}}}}, - '[[{1: 2}], {3: 4}]') + eval_eq('array', { 1 }, '[1]') + eval_eq('array', { { _TYPE = {}, _VAL = 1 } }, '[TRUE]') + eval_eq( + 'array', + { { { _TYPE = {}, _VAL = { { 1, 2 } } } }, { _TYPE = {}, _VAL = { { 3, 4 } } } }, + '[[{1: 2}], {3: 4}]' + ) - eval_eq('array', {{_TYPE={}, _VAL={'py3 print(sys.version_info)'}}}, - '["py3 print(sys.version_info)"]') + eval_eq( + 'array', + { { _TYPE = {}, _VAL = { 'py3 print(sys.version_info)' } } }, + '["py3 print(sys.version_info)"]' + ) end) it('errors out when needed', function() - eq('empty:Parsed string is empty', - exc_exec('call msgpack#eval("", {})')) - eq('unknown:Invalid non-space character: ^', - exc_exec('call msgpack#eval("^", {})')) - eq('char-invalid:Invalid integer character literal format: \'\'', - exc_exec('call msgpack#eval("\'\'", {})')) - eq('char-invalid:Invalid integer character literal format: \'ab\'', - exc_exec('call msgpack#eval("\'ab\'", {})')) - eq('char-invalid:Invalid integer character literal format: \'', - exc_exec('call msgpack#eval("\'", {})')) - eq('"-invalid:Invalid string: "', - exc_exec('call msgpack#eval("\\"", {})')) - eq('"-invalid:Invalid string: ="', - exc_exec('call msgpack#eval("=\\"", {})')) - eq('"-invalid:Invalid string: +(0)"', - exc_exec('call msgpack#eval("+(0)\\"", {})')) - eq('0.-nodigits:Decimal dot must be followed by digit(s): .e1', - exc_exec('call msgpack#eval("0.e1", {})')) - eq('0x-long:Must have at most 16 hex digits: FEDCBA98765432100', - exc_exec('call msgpack#eval("0xFEDCBA98765432100", {})')) - eq('0x-empty:Must have number after 0x: ', - exc_exec('call msgpack#eval("0x", {})')) - eq('name-unknown:Unknown name FOO: FOO', - exc_exec('call msgpack#eval("FOO", {})')) - - eq('name-unknown:Unknown name py3: py3 print(sys.version_info)', - exc_exec('call msgpack#eval("py3 print(sys.version_info)", {})')) - eq('name-unknown:Unknown name o: o', - exc_exec('call msgpack#eval("-info", {})')) + eq('empty:Parsed string is empty', exc_exec('call msgpack#eval("", {})')) + eq('unknown:Invalid non-space character: ^', exc_exec('call msgpack#eval("^", {})')) + eq( + "char-invalid:Invalid integer character literal format: ''", + exc_exec('call msgpack#eval("\'\'", {})') + ) + eq( + "char-invalid:Invalid integer character literal format: 'ab'", + exc_exec('call msgpack#eval("\'ab\'", {})') + ) + eq( + "char-invalid:Invalid integer character literal format: '", + exc_exec('call msgpack#eval("\'", {})') + ) + eq('"-invalid:Invalid string: "', exc_exec('call msgpack#eval("\\"", {})')) + eq('"-invalid:Invalid string: ="', exc_exec('call msgpack#eval("=\\"", {})')) + eq('"-invalid:Invalid string: +(0)"', exc_exec('call msgpack#eval("+(0)\\"", {})')) + eq( + '0.-nodigits:Decimal dot must be followed by digit(s): .e1', + exc_exec('call msgpack#eval("0.e1", {})') + ) + eq( + '0x-long:Must have at most 16 hex digits: FEDCBA98765432100', + exc_exec('call msgpack#eval("0xFEDCBA98765432100", {})') + ) + eq('0x-empty:Must have number after 0x: ', exc_exec('call msgpack#eval("0x", {})')) + eq('name-unknown:Unknown name FOO: FOO', exc_exec('call msgpack#eval("FOO", {})')) + + eq( + 'name-unknown:Unknown name py3: py3 print(sys.version_info)', + exc_exec('call msgpack#eval("py3 print(sys.version_info)", {})') + ) + eq('name-unknown:Unknown name o: o', exc_exec('call msgpack#eval("-info", {})')) end) end) end) diff --git a/test/functional/plugin/shada_spec.lua b/test/functional/plugin/shada_spec.lua index 8d37100607..1c20548321 100644 --- a/test/functional/plugin/shada_spec.lua +++ b/test/functional/plugin/shada_spec.lua @@ -1,25 +1,22 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local clear = helpers.clear -local eq, meths, nvim_eval, nvim_command, nvim, exc_exec, funcs, nvim_feed, curbuf = - helpers.eq, helpers.meths, helpers.eval, helpers.command, helpers.nvim, helpers.exc_exec, - helpers.funcs, helpers.feed, helpers.curbuf +local eq, api, nvim_eval, nvim_command, exc_exec, fn, nvim_feed = + helpers.eq, helpers.api, helpers.eval, helpers.command, helpers.exc_exec, helpers.fn, helpers.feed local neq = helpers.neq local read_file = helpers.read_file -local mpack = require('mpack') - local shada_helpers = require('test.functional.shada.helpers') local get_shada_rw = shada_helpers.get_shada_rw local function reset(shada_file) - clear{ args={'-u', 'NORC', '-i', shada_file or 'NONE', }} + clear { args = { '-u', 'NORC', '-i', shada_file or 'NONE' } } end local mpack_eq = function(expected, mpack_result) - local mpack_keys = {'type', 'timestamp', 'length', 'value'} + local mpack_keys = { 'type', 'timestamp', 'length', 'value' } - local unpack = mpack.Unpacker() + local unpack = vim.mpack.Unpacker() local actual = {} local cur, val local i = 0 @@ -44,8 +41,7 @@ end local wshada, _, fname = get_shada_rw('Xtest-functional-plugin-shada.shada') -local wshada_tmp, _, fname_tmp = - get_shada_rw('Xtest-functional-plugin-shada.shada.tmp.f') +local wshada_tmp, _, fname_tmp = get_shada_rw('Xtest-functional-plugin-shada.shada.tmp.f') describe('autoload/shada.vim', function() local epoch = os.date('%Y-%m-%dT%H:%M:%S', 0) @@ -89,29 +85,38 @@ describe('autoload/shada.vim', function() it('works', function() eq({}, nvim_eval(mpack2sd('[]'))) - eq({{type=1, timestamp=5, length=1, data=7}}, - nvim_eval(mpack2sd('[1, 5, 1, 7]'))) - eq({{type=1, timestamp=5, length=1, data=7}, - {type=1, timestamp=10, length=1, data=5}}, - nvim_eval(mpack2sd('[1, 5, 1, 7, 1, 10, 1, 5]'))) - eq('zero-uint:Entry 1 has type element which is zero', - exc_exec('call ' .. mpack2sd('[0, 5, 1, 7]'))) - eq('zero-uint:Entry 1 has type element which is zero', - exc_exec('call ' .. mpack2sd(('[%s, 5, 1, 7]'):format( - sp('integer', '[1, 0, 0, 0]'))))) - eq('not-uint:Entry 1 has timestamp element which is not an unsigned integer', - exc_exec('call ' .. mpack2sd('[1, -1, 1, 7]'))) - eq('not-uint:Entry 1 has length element which is not an unsigned integer', - exc_exec('call ' .. mpack2sd('[1, 1, -1, 7]'))) - eq('not-uint:Entry 1 has type element which is not an unsigned integer', - exc_exec('call ' .. mpack2sd('["", 1, -1, 7]'))) + eq({ { type = 1, timestamp = 5, length = 1, data = 7 } }, nvim_eval(mpack2sd('[1, 5, 1, 7]'))) + eq({ + { type = 1, timestamp = 5, length = 1, data = 7 }, + { type = 1, timestamp = 10, length = 1, data = 5 }, + }, nvim_eval(mpack2sd('[1, 5, 1, 7, 1, 10, 1, 5]'))) + eq( + 'zero-uint:Entry 1 has type element which is zero', + exc_exec('call ' .. mpack2sd('[0, 5, 1, 7]')) + ) + eq( + 'zero-uint:Entry 1 has type element which is zero', + exc_exec('call ' .. mpack2sd(('[%s, 5, 1, 7]'):format(sp('integer', '[1, 0, 0, 0]')))) + ) + eq( + 'not-uint:Entry 1 has timestamp element which is not an unsigned integer', + exc_exec('call ' .. mpack2sd('[1, -1, 1, 7]')) + ) + eq( + 'not-uint:Entry 1 has length element which is not an unsigned integer', + exc_exec('call ' .. mpack2sd('[1, 1, -1, 7]')) + ) + eq( + 'not-uint:Entry 1 has type element which is not an unsigned integer', + exc_exec('call ' .. mpack2sd('["", 1, -1, 7]')) + ) end) end) describe('function shada#sd_to_strings', function() local sd2strings_eq = function(expected, arg) if type(arg) == 'table' then - eq(expected, funcs['shada#sd_to_strings'](arg)) + eq(expected, fn['shada#sd_to_strings'](arg)) else eq(expected, nvim_eval(('shada#sd_to_strings(%s)'):format(arg))) end @@ -124,15 +129,18 @@ describe('autoload/shada.vim', function() it('works with unknown items', function() sd2strings_eq({ 'Unknown (0x64) with timestamp ' .. epoch .. ':', - ' = 100' - }, {{type=100, timestamp=0, length=1, data=100}}) - - sd2strings_eq({ - 'Unknown (0x4000001180000006) with timestamp ' .. epoch .. ':', - ' = 100' - }, ('[{"type": %s, "timestamp": 0, "length": 1, "data": 100}]'):format( - sp('integer', '[1, 1, 35, 6]') - )) + ' = 100', + }, { { type = 100, timestamp = 0, length = 1, data = 100 } }) + + sd2strings_eq( + { + 'Unknown (0x4000001180000006) with timestamp ' .. epoch .. ':', + ' = 100', + }, + ('[{"type": %s, "timestamp": 0, "length": 1, "data": 100}]'):format( + sp('integer', '[1, 1, 35, 6]') + ) + ) end) it('works with multiple unknown items', function() @@ -141,8 +149,10 @@ describe('autoload/shada.vim', function() ' = 100', 'Unknown (0x65) with timestamp ' .. epoch .. ':', ' = 500', - }, {{type=100, timestamp=0, length=1, data=100}, - {type=101, timestamp=0, length=1, data=500}}) + }, { + { type = 100, timestamp = 0, length = 1, data = 100 }, + { type = 101, timestamp = 0, length = 1, data = 500 }, + }) end) it('works with header items', function() @@ -150,7 +160,7 @@ describe('autoload/shada.vim', function() 'Header with timestamp ' .. epoch .. ':', ' % Key______ Value', ' + generator "test"', - }, {{type=1, timestamp=0, data={generator='test'}}}) + }, { { type = 1, timestamp = 0, data = { generator = 'test' } } }) sd2strings_eq({ 'Header with timestamp ' .. epoch .. ':', ' % Key Description Value', @@ -158,42 +168,44 @@ describe('autoload/shada.vim', function() ' + b 2', ' + c column 3', ' + d 4', - }, {{type=1, timestamp=0, data={a=1, b=2, c=3, d=4}}}) + }, { { type = 1, timestamp = 0, data = { a = 1, b = 2, c = 3, d = 4 } } }) sd2strings_eq({ 'Header with timestamp ' .. epoch .. ':', ' % Key Value', ' + t "test"', - }, {{type=1, timestamp=0, data={t='test'}}}) + }, { { type = 1, timestamp = 0, data = { t = 'test' } } }) sd2strings_eq({ 'Header with timestamp ' .. epoch .. ':', ' # Unexpected type: array instead of map', ' = [1, 2, 3]', - }, {{type=1, timestamp=0, data={1, 2, 3}}}) + }, { { type = 1, timestamp = 0, data = { 1, 2, 3 } } }) end) it('processes standard keys correctly, even in header', function() - sd2strings_eq({ - 'Header with timestamp ' .. epoch .. ':', - ' % Key Description________ Value', - ' + c column 0', - ' + f file name "/tmp/foo"', - ' + l line number 10', - ' + n name \'@\'', - ' + rc contents ["abc", "def"]', - ' + rt type CHARACTERWISE', - ' + ru is_unnamed FALSE', - ' + rw block width 10', - ' + sb search backward TRUE', - ' + sc smartcase value FALSE', - ' + se place cursor at end TRUE', - ' + sh v:hlsearch value TRUE', - ' + sl has line offset FALSE', - ' + sm magic value TRUE', - ' + so offset value 10', - ' + sp pattern "100"', - ' + ss is :s pattern TRUE', - ' + su is last used FALSE', - }, ([[ [{'type': 1, 'timestamp': 0, 'data': { + sd2strings_eq( + { + 'Header with timestamp ' .. epoch .. ':', + ' % Key Description________ Value', + ' + c column 0', + ' + f file name "/tmp/foo"', + ' + l line number 10', + " + n name '@'", + ' + rc contents ["abc", "def"]', + ' + rt type CHARACTERWISE', + ' + ru is_unnamed FALSE', + ' + rw block width 10', + ' + sb search backward TRUE', + ' + sc smartcase value FALSE', + ' + se place cursor at end TRUE', + ' + sh v:hlsearch value TRUE', + ' + sl has line offset FALSE', + ' + sm magic value TRUE', + ' + so offset value 10', + ' + sp pattern "100"', + ' + ss is :s pattern TRUE', + ' + su is last used FALSE', + }, + ([[ [{'type': 1, 'timestamp': 0, 'data': { 'sm': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1}, 'sc': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0}, 'sl': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0}, @@ -212,34 +224,37 @@ describe('autoload/shada.vim', function() 'l': 10, 'c': 0, 'f': '/tmp/foo', - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Header with timestamp ' .. epoch .. ':', - ' % Key Description____ Value', - ' # Expected integer', - ' + c column "abc"', - ' # Expected no NUL bytes', - ' + f file name "abc\\0def"', - ' # Value is negative', - ' + l line number -10', - ' # Value is negative', - ' + n name -64', - ' # Expected array value', - ' + rc contents "10"', - ' # Unexpected enum value: expected one of ' - .. '0 (CHARACTERWISE), 1 (LINEWISE), 2 (BLOCKWISE)', - ' + rt type 10', - ' # Expected boolean', - ' + ru is_unnamed 10', - ' # Expected boolean', - ' + sc smartcase value NIL', - ' # Expected boolean', - ' + sm magic value "TRUE"', - ' # Expected integer', - ' + so offset value "TRUE"', - ' # Expected binary string', - ' + sp pattern ="abc"', - }, ([[ [{'type': 1, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Header with timestamp ' .. epoch .. ':', + ' % Key Description____ Value', + ' # Expected integer', + ' + c column "abc"', + ' # Expected no NUL bytes', + ' + f file name "abc\\0def"', + ' # Value is negative', + ' + l line number -10', + ' # Value is negative', + ' + n name -64', + ' # Expected array value', + ' + rc contents "10"', + ' # Unexpected enum value: expected one of ' + .. '0 (CHARACTERWISE), 1 (LINEWISE), 2 (BLOCKWISE)', + ' + rt type 10', + ' # Expected boolean', + ' + ru is_unnamed 10', + ' # Expected boolean', + ' + sc smartcase value NIL', + ' # Expected boolean', + ' + sm magic value "TRUE"', + ' # Expected integer', + ' + so offset value "TRUE"', + ' # Expected binary string', + ' + sp pattern ="abc"', + }, + ([[ [{'type': 1, 'timestamp': 0, 'data': { 'sm': 'TRUE', 'sc': {'_TYPE': v:msgpack_types.nil, '_VAL': 0}, 'so': 'TRUE', @@ -251,29 +266,36 @@ describe('autoload/shada.vim', function() 'l': -10, 'c': 'abc', 'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]}, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Header with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' # Expected no NUL bytes', - ' + f file name "abc\\0def"', - ' # Expected array of binary strings', - ' + rc contents ["abc", ="abc"]', - ' # Expected integer', - ' + rt type "ABC"', - }, ([[ [{'type': 1, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Header with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' # Expected no NUL bytes', + ' + f file name "abc\\0def"', + ' # Expected array of binary strings', + ' + rc contents ["abc", ="abc"]', + ' # Expected integer', + ' + rt type "ABC"', + }, + ([[ [{'type': 1, 'timestamp': 0, 'data': { 'rt': 'ABC', 'rc': ["abc", {'_TYPE': v:msgpack_types.string, '_VAL': ["abc"]}], 'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]}, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Header with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' # Expected no NUL bytes', - ' + rc contents ["abc", "a\\nd\\0"]', - }, ([[ [{'type': 1, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Header with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' # Expected no NUL bytes', + ' + rc contents ["abc", "a\\nd\\0"]', + }, + ([[ [{'type': 1, 'timestamp': 0, 'data': { 'rc': ["abc", {'_TYPE': v:msgpack_types.binary, '_VAL': ["a", "d\n"]}], - }}] ]]):gsub('\n', '')) + }}] ]]):gsub('\n', '') + ) end) it('works with search pattern items', function() @@ -281,59 +303,67 @@ describe('autoload/shada.vim', function() 'Search pattern with timestamp ' .. epoch .. ':', ' # Unexpected type: array instead of map', ' = [1, 2, 3]', - }, {{type=2, timestamp=0, data={1, 2, 3}}}) - sd2strings_eq({ - 'Search pattern with timestamp ' .. epoch .. ':', - ' % Key Description________ Value', - ' + sp pattern "abc"', - ' + sh v:hlsearch value FALSE', - ' + ss is :s pattern FALSE', - ' + sb search backward FALSE', - ' + sm magic value TRUE', - ' + sc smartcase value FALSE', - ' + sl has line offset FALSE', - ' + se place cursor at end FALSE', - ' + so offset value 0', - ' + su is last used TRUE', - }, ([[ [{'type': 2, 'timestamp': 0, 'data': { + }, { { type = 2, timestamp = 0, data = { 1, 2, 3 } } }) + sd2strings_eq( + { + 'Search pattern with timestamp ' .. epoch .. ':', + ' % Key Description________ Value', + ' + sp pattern "abc"', + ' + sh v:hlsearch value FALSE', + ' + ss is :s pattern FALSE', + ' + sb search backward FALSE', + ' + sm magic value TRUE', + ' + sc smartcase value FALSE', + ' + sl has line offset FALSE', + ' + se place cursor at end FALSE', + ' + so offset value 0', + ' + su is last used TRUE', + }, + ([[ [{'type': 2, 'timestamp': 0, 'data': { 'sp': 'abc', - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Search pattern with timestamp ' .. epoch .. ':', - ' % Key Description________ Value', - ' + sp pattern "abc"', - ' + sh v:hlsearch value FALSE', - ' + ss is :s pattern FALSE', - ' + sb search backward FALSE', - ' + sm magic value TRUE', - ' + sc smartcase value FALSE', - ' + sl has line offset FALSE', - ' + se place cursor at end FALSE', - ' + so offset value 0', - ' + su is last used TRUE', - ' + sX NIL', - ' + sY NIL', - ' + sZ NIL', - }, ([[ [{'type': 2, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Search pattern with timestamp ' .. epoch .. ':', + ' % Key Description________ Value', + ' + sp pattern "abc"', + ' + sh v:hlsearch value FALSE', + ' + ss is :s pattern FALSE', + ' + sb search backward FALSE', + ' + sm magic value TRUE', + ' + sc smartcase value FALSE', + ' + sl has line offset FALSE', + ' + se place cursor at end FALSE', + ' + so offset value 0', + ' + su is last used TRUE', + ' + sX NIL', + ' + sY NIL', + ' + sZ NIL', + }, + ([[ [{'type': 2, 'timestamp': 0, 'data': { 'sp': 'abc', 'sZ': {'_TYPE': v:msgpack_types.nil, '_VAL': 0}, 'sY': {'_TYPE': v:msgpack_types.nil, '_VAL': 0}, 'sX': {'_TYPE': v:msgpack_types.nil, '_VAL': 0}, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Search pattern with timestamp ' .. epoch .. ':', - ' % Key Description________ Value', - ' + sp pattern "abc"', - ' + sh v:hlsearch value FALSE', - ' + ss is :s pattern FALSE', - ' + sb search backward FALSE', - ' + sm magic value TRUE', - ' + sc smartcase value FALSE', - ' + sl has line offset FALSE', - ' + se place cursor at end FALSE', - ' + so offset value 0', - ' + su is last used TRUE', - }, ([[ [{'type': 2, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Search pattern with timestamp ' .. epoch .. ':', + ' % Key Description________ Value', + ' + sp pattern "abc"', + ' + sh v:hlsearch value FALSE', + ' + ss is :s pattern FALSE', + ' + sb search backward FALSE', + ' + sm magic value TRUE', + ' + sc smartcase value FALSE', + ' + sl has line offset FALSE', + ' + se place cursor at end FALSE', + ' + so offset value 0', + ' + su is last used TRUE', + }, + ([[ [{'type': 2, 'timestamp': 0, 'data': { 'sp': 'abc', 'sh': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0}, 'ss': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0}, @@ -344,36 +374,42 @@ describe('autoload/shada.vim', function() 'se': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0}, 'so': 0, 'su': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1}, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Search pattern with timestamp ' .. epoch .. ':', - ' % Key Description________ Value', - ' # Required key missing: sp', - ' + sh v:hlsearch value FALSE', - ' + ss is :s pattern FALSE', - ' + sb search backward FALSE', - ' + sm magic value TRUE', - ' + sc smartcase value FALSE', - ' + sl has line offset FALSE', - ' + se place cursor at end FALSE', - ' + so offset value 0', - ' + su is last used TRUE', - }, ([[ [{'type': 2, 'timestamp': 0, 'data': { - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Search pattern with timestamp ' .. epoch .. ':', - ' % Key Description________ Value', - ' + sp pattern ""', - ' + sh v:hlsearch value TRUE', - ' + ss is :s pattern TRUE', - ' + sb search backward TRUE', - ' + sm magic value FALSE', - ' + sc smartcase value TRUE', - ' + sl has line offset TRUE', - ' + se place cursor at end TRUE', - ' + so offset value -10', - ' + su is last used FALSE', - }, ([[ [{'type': 2, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Search pattern with timestamp ' .. epoch .. ':', + ' % Key Description________ Value', + ' # Required key missing: sp', + ' + sh v:hlsearch value FALSE', + ' + ss is :s pattern FALSE', + ' + sb search backward FALSE', + ' + sm magic value TRUE', + ' + sc smartcase value FALSE', + ' + sl has line offset FALSE', + ' + se place cursor at end FALSE', + ' + so offset value 0', + ' + su is last used TRUE', + }, + ([[ [{'type': 2, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Search pattern with timestamp ' .. epoch .. ':', + ' % Key Description________ Value', + ' + sp pattern ""', + ' + sh v:hlsearch value TRUE', + ' + ss is :s pattern TRUE', + ' + sb search backward TRUE', + ' + sm magic value FALSE', + ' + sc smartcase value TRUE', + ' + sl has line offset TRUE', + ' + se place cursor at end TRUE', + ' + so offset value -10', + ' + su is last used FALSE', + }, + ([[ [{'type': 2, 'timestamp': 0, 'data': { 'sp': '', 'sh': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1}, 'ss': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1}, @@ -384,31 +420,34 @@ describe('autoload/shada.vim', function() 'se': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1}, 'so': -10, 'su': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0}, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Search pattern with timestamp ' .. epoch .. ':', - ' % Key Description________ Value', - ' # Expected binary string', - ' + sp pattern 0', - ' # Expected boolean', - ' + sh v:hlsearch value 0', - ' # Expected boolean', - ' + ss is :s pattern 0', - ' # Expected boolean', - ' + sb search backward 0', - ' # Expected boolean', - ' + sm magic value 0', - ' # Expected boolean', - ' + sc smartcase value 0', - ' # Expected boolean', - ' + sl has line offset 0', - ' # Expected boolean', - ' + se place cursor at end 0', - ' # Expected integer', - ' + so offset value ""', - ' # Expected boolean', - ' + su is last used 0', - }, ([[ [{'type': 2, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Search pattern with timestamp ' .. epoch .. ':', + ' % Key Description________ Value', + ' # Expected binary string', + ' + sp pattern 0', + ' # Expected boolean', + ' + sh v:hlsearch value 0', + ' # Expected boolean', + ' + ss is :s pattern 0', + ' # Expected boolean', + ' + sb search backward 0', + ' # Expected boolean', + ' + sm magic value 0', + ' # Expected boolean', + ' + sc smartcase value 0', + ' # Expected boolean', + ' + sl has line offset 0', + ' # Expected boolean', + ' + se place cursor at end 0', + ' # Expected integer', + ' + so offset value ""', + ' # Expected boolean', + ' + su is last used 0', + }, + ([[ [{'type': 2, 'timestamp': 0, 'data': { 'sp': 0, 'sh': 0, 'ss': 0, @@ -419,7 +458,8 @@ describe('autoload/shada.vim', function() 'se': 0, 'so': '', 'su': 0, - }}] ]]):gsub('\n', '')) + }}] ]]):gsub('\n', '') + ) end) it('works with replacement string items', function() @@ -427,45 +467,60 @@ describe('autoload/shada.vim', function() 'Replacement string with timestamp ' .. epoch .. ':', ' # Unexpected type: map instead of array', ' = {="a": [10]}', - }, {{type=3, timestamp=0, data={a={10}}}}) - sd2strings_eq({ - 'Replacement string with timestamp ' .. epoch .. ':', - ' @ Description__________ Value', - ' # Expected more elements in list' - }, ([[ [{'type': 3, 'timestamp': 0, 'data': [ - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Replacement string with timestamp ' .. epoch .. ':', - ' @ Description__________ Value', - ' # Expected binary string', - ' - :s replacement string 0', - }, ([[ [{'type': 3, 'timestamp': 0, 'data': [ + }, { { type = 3, timestamp = 0, data = { a = { 10 } } } }) + sd2strings_eq( + { + 'Replacement string with timestamp ' .. epoch .. ':', + ' @ Description__________ Value', + ' # Expected more elements in list', + }, + ([[ [{'type': 3, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Replacement string with timestamp ' .. epoch .. ':', + ' @ Description__________ Value', + ' # Expected binary string', + ' - :s replacement string 0', + }, + ([[ [{'type': 3, 'timestamp': 0, 'data': [ 0, - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Replacement string with timestamp ' .. epoch .. ':', - ' @ Description__________ Value', - ' # Expected no NUL bytes', - ' - :s replacement string "abc\\0def"', - }, ([[ [{'type': 3, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Replacement string with timestamp ' .. epoch .. ':', + ' @ Description__________ Value', + ' # Expected no NUL bytes', + ' - :s replacement string "abc\\0def"', + }, + ([[ [{'type': 3, 'timestamp': 0, 'data': [ {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]}, - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Replacement string with timestamp ' .. epoch .. ':', - ' @ Description__________ Value', - ' - :s replacement string "abc\\ndef"', - }, ([[ [{'type': 3, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Replacement string with timestamp ' .. epoch .. ':', + ' @ Description__________ Value', + ' - :s replacement string "abc\\ndef"', + }, + ([[ [{'type': 3, 'timestamp': 0, 'data': [ {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc", "def"]}, - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Replacement string with timestamp ' .. epoch .. ':', - ' @ Description__________ Value', - ' - :s replacement string "abc\\ndef"', - ' - 0', - }, ([[ [{'type': 3, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Replacement string with timestamp ' .. epoch .. ':', + ' @ Description__________ Value', + ' - :s replacement string "abc\\ndef"', + ' - 0', + }, + ([[ [{'type': 3, 'timestamp': 0, 'data': [ {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc", "def"]}, 0, - ]}] ]]):gsub('\n', '')) + ]}] ]]):gsub('\n', '') + ) end) it('works with history entry items', function() @@ -473,161 +528,206 @@ describe('autoload/shada.vim', function() 'History entry with timestamp ' .. epoch .. ':', ' # Unexpected type: map instead of array', ' = {="a": [10]}', - }, {{type=4, timestamp=0, data={a={10}}}}) - sd2strings_eq({ - 'History entry with timestamp ' .. epoch .. ':', - ' @ Description_ Value', - ' # Expected more elements in list' - }, ([[ [{'type': 4, 'timestamp': 0, 'data': [ - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'History entry with timestamp ' .. epoch .. ':', - ' @ Description_ Value', - ' # Expected integer', - ' - history type ""', - ' # Expected more elements in list' - }, ([[ [{'type': 4, 'timestamp': 0, 'data': [ + }, { { type = 4, timestamp = 0, data = { a = { 10 } } } }) + sd2strings_eq( + { + 'History entry with timestamp ' .. epoch .. ':', + ' @ Description_ Value', + ' # Expected more elements in list', + }, + ([[ [{'type': 4, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'History entry with timestamp ' .. epoch .. ':', + ' @ Description_ Value', + ' # Expected integer', + ' - history type ""', + ' # Expected more elements in list', + }, + ([[ [{'type': 4, 'timestamp': 0, 'data': [ '', - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'History entry with timestamp ' .. epoch .. ':', - ' @ Description_ Value', - ' # Unexpected enum value: expected one of 0 (CMD), 1 (SEARCH), ' + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'History entry with timestamp ' .. epoch .. ':', + ' @ Description_ Value', + ' # Unexpected enum value: expected one of 0 (CMD), 1 (SEARCH), ' .. '2 (EXPR), 3 (INPUT), 4 (DEBUG)', - ' - history type 5', - ' - contents ""', - }, ([[ [{'type': 4, 'timestamp': 0, 'data': [ + ' - history type 5', + ' - contents ""', + }, + ([[ [{'type': 4, 'timestamp': 0, 'data': [ 5, '' - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'History entry with timestamp ' .. epoch .. ':', - ' @ Description_ Value', - ' # Unexpected enum value: expected one of 0 (CMD), 1 (SEARCH), ' + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'History entry with timestamp ' .. epoch .. ':', + ' @ Description_ Value', + ' # Unexpected enum value: expected one of 0 (CMD), 1 (SEARCH), ' .. '2 (EXPR), 3 (INPUT), 4 (DEBUG)', - ' - history type 5', - ' - contents ""', - ' - 32', - }, ([[ [{'type': 4, 'timestamp': 0, 'data': [ + ' - history type 5', + ' - contents ""', + ' - 32', + }, + ([[ [{'type': 4, 'timestamp': 0, 'data': [ 5, '', 0x20 - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'History entry with timestamp ' .. epoch .. ':', - ' @ Description_ Value', - ' - history type CMD', - ' - contents ""', - ' - 32', - }, ([[ [{'type': 4, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'History entry with timestamp ' .. epoch .. ':', + ' @ Description_ Value', + ' - history type CMD', + ' - contents ""', + ' - 32', + }, + ([[ [{'type': 4, 'timestamp': 0, 'data': [ 0, '', 0x20 - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'History entry with timestamp ' .. epoch .. ':', - ' @ Description_ Value', - ' - history type SEARCH', - ' - contents ""', - ' - separator \' \'', - }, ([[ [{'type': 4, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'History entry with timestamp ' .. epoch .. ':', + ' @ Description_ Value', + ' - history type SEARCH', + ' - contents ""', + " - separator ' '", + }, + ([[ [{'type': 4, 'timestamp': 0, 'data': [ 1, '', 0x20 - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'History entry with timestamp ' .. epoch .. ':', - ' @ Description_ Value', - ' - history type SEARCH', - ' - contents ""', - ' # Expected more elements in list', - }, ([[ [{'type': 4, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'History entry with timestamp ' .. epoch .. ':', + ' @ Description_ Value', + ' - history type SEARCH', + ' - contents ""', + ' # Expected more elements in list', + }, + ([[ [{'type': 4, 'timestamp': 0, 'data': [ 1, '', - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'History entry with timestamp ' .. epoch .. ':', - ' @ Description_ Value', - ' - history type EXPR', - ' - contents ""', - }, ([[ [{'type': 4, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'History entry with timestamp ' .. epoch .. ':', + ' @ Description_ Value', + ' - history type EXPR', + ' - contents ""', + }, + ([[ [{'type': 4, 'timestamp': 0, 'data': [ 2, '', - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'History entry with timestamp ' .. epoch .. ':', - ' @ Description_ Value', - ' - history type INPUT', - ' - contents ""', - }, ([[ [{'type': 4, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'History entry with timestamp ' .. epoch .. ':', + ' @ Description_ Value', + ' - history type INPUT', + ' - contents ""', + }, + ([[ [{'type': 4, 'timestamp': 0, 'data': [ 3, '', - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'History entry with timestamp ' .. epoch .. ':', - ' @ Description_ Value', - ' - history type DEBUG', - ' - contents ""', - }, ([[ [{'type': 4, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'History entry with timestamp ' .. epoch .. ':', + ' @ Description_ Value', + ' - history type DEBUG', + ' - contents ""', + }, + ([[ [{'type': 4, 'timestamp': 0, 'data': [ 4, '', - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'History entry with timestamp ' .. epoch .. ':', - ' @ Description_ Value', - ' - history type DEBUG', - ' # Expected binary string', - ' - contents 10', - }, ([[ [{'type': 4, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'History entry with timestamp ' .. epoch .. ':', + ' @ Description_ Value', + ' - history type DEBUG', + ' # Expected binary string', + ' - contents 10', + }, + ([[ [{'type': 4, 'timestamp': 0, 'data': [ 4, 10, - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'History entry with timestamp ' .. epoch .. ':', - ' @ Description_ Value', - ' - history type DEBUG', - ' # Expected no NUL bytes', - ' - contents "abc\\0def"', - }, ([[ [{'type': 4, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'History entry with timestamp ' .. epoch .. ':', + ' @ Description_ Value', + ' - history type DEBUG', + ' # Expected no NUL bytes', + ' - contents "abc\\0def"', + }, + ([[ [{'type': 4, 'timestamp': 0, 'data': [ 4, {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]}, - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'History entry with timestamp ' .. epoch .. ':', - ' @ Description_ Value', - ' - history type SEARCH', - ' - contents "abc"', - ' # Expected integer', - ' - separator ""', - }, ([[ [{'type': 4, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'History entry with timestamp ' .. epoch .. ':', + ' @ Description_ Value', + ' - history type SEARCH', + ' - contents "abc"', + ' # Expected integer', + ' - separator ""', + }, + ([[ [{'type': 4, 'timestamp': 0, 'data': [ 1, 'abc', '', - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'History entry with timestamp ' .. epoch .. ':', - ' @ Description_ Value', - ' - history type SEARCH', - ' - contents "abc"', - ' # Value is negative', - ' - separator -1', - }, ([[ [{'type': 4, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'History entry with timestamp ' .. epoch .. ':', + ' @ Description_ Value', + ' - history type SEARCH', + ' - contents "abc"', + ' # Value is negative', + ' - separator -1', + }, + ([[ [{'type': 4, 'timestamp': 0, 'data': [ 1, 'abc', -1, - ]}] ]]):gsub('\n', '')) + ]}] ]]):gsub('\n', '') + ) -- Regression: NUL separator must be properly supported - sd2strings_eq({ - 'History entry with timestamp ' .. epoch .. ':', - ' @ Description_ Value', - ' - history type SEARCH', - ' - contents ""', - ' - separator \'\\0\'', - }, ([[ [{'type': 4, 'timestamp': 0, 'data': [ + sd2strings_eq( + { + 'History entry with timestamp ' .. epoch .. ':', + ' @ Description_ Value', + ' - history type SEARCH', + ' - contents ""', + " - separator '\\0'", + }, + ([[ [{'type': 4, 'timestamp': 0, 'data': [ 1, '', 0x0 - ]}] ]]):gsub('\n', '')) + ]}] ]]):gsub('\n', '') + ) end) it('works with register items', function() @@ -635,145 +735,172 @@ describe('autoload/shada.vim', function() 'Register with timestamp ' .. epoch .. ':', ' # Unexpected type: array instead of map', ' = [1, 2, 3]', - }, {{type=5, timestamp=0, data={1, 2, 3}}}) - sd2strings_eq({ - 'Register with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' # Required key missing: n', - ' # Required key missing: rc', - ' + rw block width 0', - ' + rt type CHARACTERWISE', - ' + ru is_unnamed FALSE', - }, ([[ [{'type': 5, 'timestamp': 0, 'data': { - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Register with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + n name \' \'', - ' # Required key missing: rc', - ' + rw block width 0', - ' + rt type CHARACTERWISE', - ' + ru is_unnamed FALSE', - }, ([[ [{'type': 5, 'timestamp': 0, 'data': { + }, { { type = 5, timestamp = 0, data = { 1, 2, 3 } } }) + sd2strings_eq( + { + 'Register with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' # Required key missing: n', + ' # Required key missing: rc', + ' + rw block width 0', + ' + rt type CHARACTERWISE', + ' + ru is_unnamed FALSE', + }, + ([[ [{'type': 5, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Register with timestamp ' .. epoch .. ':', + ' % Key Description Value', + " + n name ' '", + ' # Required key missing: rc', + ' + rw block width 0', + ' + rt type CHARACTERWISE', + ' + ru is_unnamed FALSE', + }, + ([[ [{'type': 5, 'timestamp': 0, 'data': { 'n': 0x20, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Register with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + n name \' \'', - ' + rc contents ["abc", "def"]', - ' + rw block width 0', - ' + rt type CHARACTERWISE', - ' + ru is_unnamed FALSE', - }, ([[ [{'type': 5, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Register with timestamp ' .. epoch .. ':', + ' % Key Description Value', + " + n name ' '", + ' + rc contents ["abc", "def"]', + ' + rw block width 0', + ' + rt type CHARACTERWISE', + ' + ru is_unnamed FALSE', + }, + ([[ [{'type': 5, 'timestamp': 0, 'data': { 'n': 0x20, 'rc': ["abc", "def"], 'ru': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0}, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Register with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + n name \' \'', - ' + rc contents @', - ' | - "abcdefghijklmnopqrstuvwxyz"', - ' | - "abcdefghijklmnopqrstuvwxyz"', - ' + rw block width 0', - ' + rt type CHARACTERWISE', - ' + ru is_unnamed TRUE', - }, ([[ [{'type': 5, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Register with timestamp ' .. epoch .. ':', + ' % Key Description Value', + " + n name ' '", + ' + rc contents @', + ' | - "abcdefghijklmnopqrstuvwxyz"', + ' | - "abcdefghijklmnopqrstuvwxyz"', + ' + rw block width 0', + ' + rt type CHARACTERWISE', + ' + ru is_unnamed TRUE', + }, + ([[ [{'type': 5, 'timestamp': 0, 'data': { 'n': 0x20, 'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'], 'ru': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1}, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Register with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + n name \' \'', - ' + rc contents @', - ' | - "abcdefghijklmnopqrstuvwxyz"', - ' | - "abcdefghijklmnopqrstuvwxyz"', - ' + rw block width 0', - ' + rt type CHARACTERWISE', - ' + ru is_unnamed FALSE', - }, ([[ [{'type': 5, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Register with timestamp ' .. epoch .. ':', + ' % Key Description Value', + " + n name ' '", + ' + rc contents @', + ' | - "abcdefghijklmnopqrstuvwxyz"', + ' | - "abcdefghijklmnopqrstuvwxyz"', + ' + rw block width 0', + ' + rt type CHARACTERWISE', + ' + ru is_unnamed FALSE', + }, + ([[ [{'type': 5, 'timestamp': 0, 'data': { 'n': 0x20, 'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'], 'rw': 0, 'rt': 0, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Register with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + n name \' \'', - ' + rc contents @', - ' | - "abcdefghijklmnopqrstuvwxyz"', - ' | - "abcdefghijklmnopqrstuvwxyz"', - ' + rw block width 5', - ' + rt type LINEWISE', - ' + ru is_unnamed FALSE', - }, ([[ [{'type': 5, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Register with timestamp ' .. epoch .. ':', + ' % Key Description Value', + " + n name ' '", + ' + rc contents @', + ' | - "abcdefghijklmnopqrstuvwxyz"', + ' | - "abcdefghijklmnopqrstuvwxyz"', + ' + rw block width 5', + ' + rt type LINEWISE', + ' + ru is_unnamed FALSE', + }, + ([[ [{'type': 5, 'timestamp': 0, 'data': { 'n': 0x20, 'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'], 'rw': 5, 'rt': 1, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Register with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + n name \' \'', - ' + rc contents @', - ' | - "abcdefghijklmnopqrstuvwxyz"', - ' | - "abcdefghijklmnopqrstuvwxyz"', - ' # Expected integer', - ' + rw block width ""', - ' + rt type BLOCKWISE', - ' # Expected boolean', - ' + ru is_unnamed ""', - }, ([[ [{'type': 5, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Register with timestamp ' .. epoch .. ':', + ' % Key Description Value', + " + n name ' '", + ' + rc contents @', + ' | - "abcdefghijklmnopqrstuvwxyz"', + ' | - "abcdefghijklmnopqrstuvwxyz"', + ' # Expected integer', + ' + rw block width ""', + ' + rt type BLOCKWISE', + ' # Expected boolean', + ' + ru is_unnamed ""', + }, + ([[ [{'type': 5, 'timestamp': 0, 'data': { 'n': 0x20, 'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'], 'rw': "", 'rt': 2, 'ru': "" - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Register with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + n name \' \'', - ' # Expected array value', - ' + rc contents 0', - ' # Value is negative', - ' + rw block width -1', - ' # Unexpected enum value: expected one of 0 (CHARACTERWISE), ' - .. '1 (LINEWISE), 2 (BLOCKWISE)', - ' + rt type 10', - ' # Expected boolean', - ' + ru is_unnamed ["abc", "def"]', - }, ([[ [{'type': 5, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Register with timestamp ' .. epoch .. ':', + ' % Key Description Value', + " + n name ' '", + ' # Expected array value', + ' + rc contents 0', + ' # Value is negative', + ' + rw block width -1', + ' # Unexpected enum value: expected one of 0 (CHARACTERWISE), ' + .. '1 (LINEWISE), 2 (BLOCKWISE)', + ' + rt type 10', + ' # Expected boolean', + ' + ru is_unnamed ["abc", "def"]', + }, + ([[ [{'type': 5, 'timestamp': 0, 'data': { 'n': 0x20, 'rc': 0, 'rw': -1, 'rt': 10, 'ru': ['abc', 'def'], - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Register with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + n name \' \'', - ' + rc contents @', - ' | - "abcdefghijklmnopqrstuvwxyz"', - ' | - "abcdefghijklmnopqrstuvwxyz"', - ' + rw block width 5', - ' + rt type LINEWISE', - ' # Expected boolean', - ' + ru is_unnamed 0', - }, ([[ [{'type': 5, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Register with timestamp ' .. epoch .. ':', + ' % Key Description Value', + " + n name ' '", + ' + rc contents @', + ' | - "abcdefghijklmnopqrstuvwxyz"', + ' | - "abcdefghijklmnopqrstuvwxyz"', + ' + rw block width 5', + ' + rt type LINEWISE', + ' # Expected boolean', + ' + ru is_unnamed 0', + }, + ([[ [{'type': 5, 'timestamp': 0, 'data': { 'n': 0x20, 'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'], 'rw': 5, 'rt': 1, 'ru': 0, - }}] ]]):gsub('\n', '')) + }}] ]]):gsub('\n', '') + ) end) it('works with variable items', function() @@ -781,59 +908,77 @@ describe('autoload/shada.vim', function() 'Variable with timestamp ' .. epoch .. ':', ' # Unexpected type: map instead of array', ' = {="a": [10]}', - }, {{type=6, timestamp=0, data={a={10}}}}) - sd2strings_eq({ - 'Variable with timestamp ' .. epoch .. ':', - ' @ Description Value', - ' # Expected more elements in list' - }, ([[ [{'type': 6, 'timestamp': 0, 'data': [ - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Variable with timestamp ' .. epoch .. ':', - ' @ Description Value', - ' # Expected binary string', - ' - name 1', - ' # Expected more elements in list', - }, ([[ [{'type': 6, 'timestamp': 0, 'data': [ + }, { { type = 6, timestamp = 0, data = { a = { 10 } } } }) + sd2strings_eq( + { + 'Variable with timestamp ' .. epoch .. ':', + ' @ Description Value', + ' # Expected more elements in list', + }, + ([[ [{'type': 6, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Variable with timestamp ' .. epoch .. ':', + ' @ Description Value', + ' # Expected binary string', + ' - name 1', + ' # Expected more elements in list', + }, + ([[ [{'type': 6, 'timestamp': 0, 'data': [ 1 - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Variable with timestamp ' .. epoch .. ':', - ' @ Description Value', - ' # Expected no NUL bytes', - ' - name "\\0"', - ' # Expected more elements in list', - }, ([[ [{'type': 6, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Variable with timestamp ' .. epoch .. ':', + ' @ Description Value', + ' # Expected no NUL bytes', + ' - name "\\0"', + ' # Expected more elements in list', + }, + ([[ [{'type': 6, 'timestamp': 0, 'data': [ {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]}, - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Variable with timestamp ' .. epoch .. ':', - ' @ Description Value', - ' - name "foo"', - ' # Expected more elements in list', - }, ([[ [{'type': 6, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Variable with timestamp ' .. epoch .. ':', + ' @ Description Value', + ' - name "foo"', + ' # Expected more elements in list', + }, + ([[ [{'type': 6, 'timestamp': 0, 'data': [ {'_TYPE': v:msgpack_types.binary, '_VAL': ["foo"]}, - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Variable with timestamp ' .. epoch .. ':', - ' @ Description Value', - ' - name "foo"', - ' - value NIL', - }, ([[ [{'type': 6, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Variable with timestamp ' .. epoch .. ':', + ' @ Description Value', + ' - name "foo"', + ' - value NIL', + }, + ([[ [{'type': 6, 'timestamp': 0, 'data': [ {'_TYPE': v:msgpack_types.binary, '_VAL': ["foo"]}, {'_TYPE': v:msgpack_types.nil, '_VAL': ["foo"]}, - ]}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Variable with timestamp ' .. epoch .. ':', - ' @ Description Value', - ' - name "foo"', - ' - value NIL', - ' - NIL', - }, ([[ [{'type': 6, 'timestamp': 0, 'data': [ + ]}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Variable with timestamp ' .. epoch .. ':', + ' @ Description Value', + ' - name "foo"', + ' - value NIL', + ' - NIL', + }, + ([[ [{'type': 6, 'timestamp': 0, 'data': [ {'_TYPE': v:msgpack_types.binary, '_VAL': ["foo"]}, {'_TYPE': v:msgpack_types.nil, '_VAL': ["foo"]}, {'_TYPE': v:msgpack_types.nil, '_VAL': ["foo"]}, - ]}] ]]):gsub('\n', '')) + ]}] ]]):gsub('\n', '') + ) end) it('works with global mark items', function() @@ -841,110 +986,134 @@ describe('autoload/shada.vim', function() 'Global mark with timestamp ' .. epoch .. ':', ' # Unexpected type: array instead of map', ' = [1, 2, 3]', - }, {{type=7, timestamp=0, data={1, 2, 3}}}) - sd2strings_eq({ - 'Global mark with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' # Required key missing: n', - ' # Required key missing: f', - ' + l line number 1', - ' + c column 0', - }, ([[ [{'type': 7, 'timestamp': 0, 'data': { - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Global mark with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' # Expected integer', - ' + n name "foo"', - ' # Required key missing: f', - ' + l line number 1', - ' + c column 0', - }, ([[ [{'type': 7, 'timestamp': 0, 'data': { + }, { { type = 7, timestamp = 0, data = { 1, 2, 3 } } }) + sd2strings_eq( + { + 'Global mark with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' # Required key missing: n', + ' # Required key missing: f', + ' + l line number 1', + ' + c column 0', + }, + ([[ [{'type': 7, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Global mark with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' # Expected integer', + ' + n name "foo"', + ' # Required key missing: f', + ' + l line number 1', + ' + c column 0', + }, + ([[ [{'type': 7, 'timestamp': 0, 'data': { 'n': 'foo', - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Global mark with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' # Required key missing: n', - ' + f file name "foo"', - ' + l line number 1', - ' + c column 0', - }, ([[ [{'type': 7, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Global mark with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' # Required key missing: n', + ' + f file name "foo"', + ' + l line number 1', + ' + c column 0', + }, + ([[ [{'type': 7, 'timestamp': 0, 'data': { 'f': 'foo', - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Global mark with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' # Value is negative', - ' + n name -10', - ' # Expected no NUL bytes', - ' + f file name "\\0"', - ' + l line number 1', - ' + c column 0', - }, ([[ [{'type': 7, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Global mark with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' # Value is negative', + ' + n name -10', + ' # Expected no NUL bytes', + ' + f file name "\\0"', + ' + l line number 1', + ' + c column 0', + }, + ([[ [{'type': 7, 'timestamp': 0, 'data': { 'n': -10, 'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]}, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Global mark with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + n name \'\\20\'', - ' + f file name "foo"', - ' # Value is negative', - ' + l line number -10', - ' # Value is negative', - ' + c column -10', - }, ([[ [{'type': 7, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Global mark with timestamp ' .. epoch .. ':', + ' % Key Description Value', + " + n name '\\20'", + ' + f file name "foo"', + ' # Value is negative', + ' + l line number -10', + ' # Value is negative', + ' + c column -10', + }, + ([[ [{'type': 7, 'timestamp': 0, 'data': { 'n': 20, 'f': 'foo', 'l': -10, 'c': -10, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Global mark with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + n name 128', - ' + f file name "foo"', - ' + l line number 1', - ' + c column 0', - }, ([[ [{'type': 7, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Global mark with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' + n name 128', + ' + f file name "foo"', + ' + l line number 1', + ' + c column 0', + }, + ([[ [{'type': 7, 'timestamp': 0, 'data': { 'n': 128, 'f': 'foo', - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Global mark with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + n name \'\\20\'', - ' + f file name "foo"', - ' # Expected integer', - ' + l line number "FOO"', - ' # Expected integer', - ' + c column "foo"', - ' + mX 10', - }, ([[ [{'type': 7, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Global mark with timestamp ' .. epoch .. ':', + ' % Key Description Value', + " + n name '\\20'", + ' + f file name "foo"', + ' # Expected integer', + ' + l line number "FOO"', + ' # Expected integer', + ' + c column "foo"', + ' + mX 10', + }, + ([[ [{'type': 7, 'timestamp': 0, 'data': { 'n': 20, 'f': 'foo', 'l': 'FOO', 'c': 'foo', 'mX': 10, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Global mark with timestamp ' .. epoch .. ':', - ' % Key________ Description Value', - ' + n name \'A\'', - ' + f file name "foo"', - ' + l line number 2', - ' + c column 200', - ' + mX 10', - ' + mYYYYYYYYYY 10', - }, ([[ [{'type': 7, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Global mark with timestamp ' .. epoch .. ':', + ' % Key________ Description Value', + " + n name 'A'", + ' + f file name "foo"', + ' + l line number 2', + ' + c column 200', + ' + mX 10', + ' + mYYYYYYYYYY 10', + }, + ([[ [{'type': 7, 'timestamp': 0, 'data': { 'n': char2nr('A'), 'f': 'foo', 'l': 2, 'c': 200, 'mX': 10, 'mYYYYYYYYYY': 10, - }}] ]]):gsub('\n', '')) + }}] ]]):gsub('\n', '') + ) end) it('works with jump items', function() @@ -952,93 +1121,114 @@ describe('autoload/shada.vim', function() 'Jump with timestamp ' .. epoch .. ':', ' # Unexpected type: array instead of map', ' = [1, 2, 3]', - }, {{type=8, timestamp=0, data={1, 2, 3}}}) - sd2strings_eq({ - 'Jump with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' # Required key missing: f', - ' + l line number 1', - ' + c column 0', - }, ([[ [{'type': 8, 'timestamp': 0, 'data': { - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Jump with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' # Required key missing: f', - ' + l line number 1', - ' + c column 0', - ' # Expected integer', - ' + n name "foo"', - }, ([[ [{'type': 8, 'timestamp': 0, 'data': { + }, { { type = 8, timestamp = 0, data = { 1, 2, 3 } } }) + sd2strings_eq( + { + 'Jump with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' # Required key missing: f', + ' + l line number 1', + ' + c column 0', + }, + ([[ [{'type': 8, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Jump with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' # Required key missing: f', + ' + l line number 1', + ' + c column 0', + ' # Expected integer', + ' + n name "foo"', + }, + ([[ [{'type': 8, 'timestamp': 0, 'data': { 'n': 'foo', - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Jump with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + f file name "foo"', - ' + l line number 1', - ' + c column 0', - }, ([[ [{'type': 8, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Jump with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' + f file name "foo"', + ' + l line number 1', + ' + c column 0', + }, + ([[ [{'type': 8, 'timestamp': 0, 'data': { 'f': 'foo', - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Jump with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' # Expected no NUL bytes', - ' + f file name "\\0"', - ' + l line number 1', - ' + c column 0', - ' # Value is negative', - ' + n name -10', - }, ([[ [{'type': 8, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Jump with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' # Expected no NUL bytes', + ' + f file name "\\0"', + ' + l line number 1', + ' + c column 0', + ' # Value is negative', + ' + n name -10', + }, + ([[ [{'type': 8, 'timestamp': 0, 'data': { 'n': -10, 'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]}, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Jump with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + f file name "foo"', - ' # Value is negative', - ' + l line number -10', - ' # Value is negative', - ' + c column -10', - }, ([[ [{'type': 8, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Jump with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' + f file name "foo"', + ' # Value is negative', + ' + l line number -10', + ' # Value is negative', + ' + c column -10', + }, + ([[ [{'type': 8, 'timestamp': 0, 'data': { 'f': 'foo', 'l': -10, 'c': -10, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Jump with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + f file name "foo"', - ' # Expected integer', - ' + l line number "FOO"', - ' # Expected integer', - ' + c column "foo"', - ' + mX 10', - }, ([[ [{'type': 8, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Jump with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' + f file name "foo"', + ' # Expected integer', + ' + l line number "FOO"', + ' # Expected integer', + ' + c column "foo"', + ' + mX 10', + }, + ([[ [{'type': 8, 'timestamp': 0, 'data': { 'f': 'foo', 'l': 'FOO', 'c': 'foo', 'mX': 10, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Jump with timestamp ' .. epoch .. ':', - ' % Key________ Description Value', - ' + f file name "foo"', - ' + l line number 2', - ' + c column 200', - ' + mX 10', - ' + mYYYYYYYYYY 10', - ' + n name \' \'', - }, ([[ [{'type': 8, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Jump with timestamp ' .. epoch .. ':', + ' % Key________ Description Value', + ' + f file name "foo"', + ' + l line number 2', + ' + c column 200', + ' + mX 10', + ' + mYYYYYYYYYY 10', + " + n name ' '", + }, + ([[ [{'type': 8, 'timestamp': 0, 'data': { 'n': 0x20, 'f': 'foo', 'l': 2, 'c': 200, 'mX': 10, 'mYYYYYYYYYY': 10, - }}] ]]):gsub('\n', '')) + }}] ]]):gsub('\n', '') + ) end) it('works with buffer list items', function() @@ -1046,17 +1236,17 @@ describe('autoload/shada.vim', function() 'Buffer list with timestamp ' .. epoch .. ':', ' # Unexpected type: map instead of array', ' = {="a": [10]}', - }, {{type=9, timestamp=0, data={a={10}}}}) + }, { { type = 9, timestamp = 0, data = { a = { 10 } } } }) sd2strings_eq({ 'Buffer list with timestamp ' .. epoch .. ':', ' # Expected array of maps', ' = [[], []]', - }, {{type=9, timestamp=0, data={{}, {}}}}) + }, { { type = 9, timestamp = 0, data = { {}, {} } } }) sd2strings_eq({ 'Buffer list with timestamp ' .. epoch .. ':', ' # Expected array of maps', ' = [{="a": 10}, []]', - }, {{type=9, timestamp=0, data={{a=10}, {}}}}) + }, { { type = 9, timestamp = 0, data = { { a = 10 }, {} } } }) sd2strings_eq({ 'Buffer list with timestamp ' .. epoch .. ':', ' % Key Description Value', @@ -1064,7 +1254,7 @@ describe('autoload/shada.vim', function() ' + l line number 1', ' + c column 0', ' + a 10', - }, {{type=9, timestamp=0, data={{a=10}}}}) + }, { { type = 9, timestamp = 0, data = { { a = 10 } } } }) sd2strings_eq({ 'Buffer list with timestamp ' .. epoch .. ':', ' % Key Description Value', @@ -1074,7 +1264,7 @@ describe('autoload/shada.vim', function() ' # Expected integer', ' + c column "10"', ' + a 10', - }, {{type=9, timestamp=0, data={{l='10', c='10', a=10}}}}) + }, { { type = 9, timestamp = 0, data = { { l = '10', c = '10', a = 10 } } } }) sd2strings_eq({ 'Buffer list with timestamp ' .. epoch .. ':', ' % Key Description Value', @@ -1082,7 +1272,7 @@ describe('autoload/shada.vim', function() ' + l line number 10', ' + c column 10', ' + a 10', - }, {{type=9, timestamp=0, data={{l=10, c=10, a=10}}}}) + }, { { type = 9, timestamp = 0, data = { { l = 10, c = 10, a = 10 } } } }) sd2strings_eq({ 'Buffer list with timestamp ' .. epoch .. ':', ' % Key Description Value', @@ -1091,14 +1281,14 @@ describe('autoload/shada.vim', function() ' + l line number -10', ' # Value is negative', ' + c column -10', - }, {{type=9, timestamp=0, data={{l=-10, c=-10}}}}) + }, { { type = 9, timestamp = 0, data = { { l = -10, c = -10 } } } }) sd2strings_eq({ 'Buffer list with timestamp ' .. epoch .. ':', ' % Key Description Value', ' + f file name "abc"', ' + l line number 1', ' + c column 0', - }, {{type=9, timestamp=0, data={{f='abc'}}}}) + }, { { type = 9, timestamp = 0, data = { { f = 'abc' } } } }) sd2strings_eq({ 'Buffer list with timestamp ' .. epoch .. ':', ' % Key Description Value', @@ -1112,24 +1302,27 @@ describe('autoload/shada.vim', function() ' + f file name 20', ' + l line number 1', ' + c column 0', - }, {{type=9, timestamp=0, data={{f=10}, {f=20}}}}) - sd2strings_eq({ - 'Buffer list with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' # Expected binary string', - ' + f file name 10', - ' + l line number 1', - ' + c column 0', - '', - ' % Key Description Value', - ' # Expected no NUL bytes', - ' + f file name "\\0"', - ' + l line number 1', - ' + c column 0', - }, ([[ [{'type': 9, 'timestamp': 0, 'data': [ + }, { { type = 9, timestamp = 0, data = { { f = 10 }, { f = 20 } } } }) + sd2strings_eq( + { + 'Buffer list with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' # Expected binary string', + ' + f file name 10', + ' + l line number 1', + ' + c column 0', + '', + ' % Key Description Value', + ' # Expected no NUL bytes', + ' + f file name "\\0"', + ' + l line number 1', + ' + c column 0', + }, + ([[ [{'type': 9, 'timestamp': 0, 'data': [ {'f': 10}, {'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]}}, - ]}] ]]):gsub('\n', '')) + ]}] ]]):gsub('\n', '') + ) end) it('works with local mark items', function() @@ -1137,99 +1330,120 @@ describe('autoload/shada.vim', function() 'Local mark with timestamp ' .. epoch .. ':', ' # Unexpected type: array instead of map', ' = [1, 2, 3]', - }, {{type=10, timestamp=0, data={1, 2, 3}}}) - sd2strings_eq({ - 'Local mark with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' # Required key missing: f', - ' + n name \'"\'', - ' + l line number 1', - ' + c column 0', - }, ([[ [{'type': 10, 'timestamp': 0, 'data': { - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Local mark with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' # Required key missing: f', - ' # Expected integer', - ' + n name "foo"', - ' + l line number 1', - ' + c column 0', - }, ([[ [{'type': 10, 'timestamp': 0, 'data': { + }, { { type = 10, timestamp = 0, data = { 1, 2, 3 } } }) + sd2strings_eq( + { + 'Local mark with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' # Required key missing: f', + " + n name '\"'", + ' + l line number 1', + ' + c column 0', + }, + ([[ [{'type': 10, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Local mark with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' # Required key missing: f', + ' # Expected integer', + ' + n name "foo"', + ' + l line number 1', + ' + c column 0', + }, + ([[ [{'type': 10, 'timestamp': 0, 'data': { 'n': 'foo', - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Local mark with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + f file name "foo"', - ' + n name \'"\'', - ' + l line number 1', - ' + c column 0', - }, ([[ [{'type': 10, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Local mark with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' + f file name "foo"', + " + n name '\"'", + ' + l line number 1', + ' + c column 0', + }, + ([[ [{'type': 10, 'timestamp': 0, 'data': { 'f': 'foo', - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Local mark with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' # Expected no NUL bytes', - ' + f file name "\\0"', - ' # Value is negative', - ' + n name -10', - ' + l line number 1', - ' + c column 0', - }, ([[ [{'type': 10, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Local mark with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' # Expected no NUL bytes', + ' + f file name "\\0"', + ' # Value is negative', + ' + n name -10', + ' + l line number 1', + ' + c column 0', + }, + ([[ [{'type': 10, 'timestamp': 0, 'data': { 'n': -10, 'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]}, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Local mark with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + f file name "foo"', - ' + n name \'\\20\'', - ' # Value is negative', - ' + l line number -10', - ' # Value is negative', - ' + c column -10', - }, ([[ [{'type': 10, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Local mark with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' + f file name "foo"', + " + n name '\\20'", + ' # Value is negative', + ' + l line number -10', + ' # Value is negative', + ' + c column -10', + }, + ([[ [{'type': 10, 'timestamp': 0, 'data': { 'n': 20, 'f': 'foo', 'l': -10, 'c': -10, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Local mark with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + f file name "foo"', - ' + n name \'\\20\'', - ' # Expected integer', - ' + l line number "FOO"', - ' # Expected integer', - ' + c column "foo"', - ' + mX 10', - }, ([[ [{'type': 10, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Local mark with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' + f file name "foo"', + " + n name '\\20'", + ' # Expected integer', + ' + l line number "FOO"', + ' # Expected integer', + ' + c column "foo"', + ' + mX 10', + }, + ([[ [{'type': 10, 'timestamp': 0, 'data': { 'n': 20, 'f': 'foo', 'l': 'FOO', 'c': 'foo', 'mX': 10, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Local mark with timestamp ' .. epoch .. ':', - ' % Key________ Description Value', - ' + f file name "foo"', - ' + n name \'a\'', - ' + l line number 2', - ' + c column 200', - ' + mX 10', - ' + mYYYYYYYYYY 10', - }, ([[ [{'type': 10, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Local mark with timestamp ' .. epoch .. ':', + ' % Key________ Description Value', + ' + f file name "foo"', + " + n name 'a'", + ' + l line number 2', + ' + c column 200', + ' + mX 10', + ' + mYYYYYYYYYY 10', + }, + ([[ [{'type': 10, 'timestamp': 0, 'data': { 'n': char2nr('a'), 'f': 'foo', 'l': 2, 'c': 200, 'mX': 10, 'mYYYYYYYYYY': 10, - }}] ]]):gsub('\n', '')) + }}] ]]):gsub('\n', '') + ) end) it('works with change items', function() @@ -1237,93 +1451,114 @@ describe('autoload/shada.vim', function() 'Change with timestamp ' .. epoch .. ':', ' # Unexpected type: array instead of map', ' = [1, 2, 3]', - }, {{type=11, timestamp=0, data={1, 2, 3}}}) - sd2strings_eq({ - 'Change with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' # Required key missing: f', - ' + l line number 1', - ' + c column 0', - }, ([[ [{'type': 11, 'timestamp': 0, 'data': { - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Change with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' # Required key missing: f', - ' + l line number 1', - ' + c column 0', - ' # Expected integer', - ' + n name "foo"', - }, ([[ [{'type': 11, 'timestamp': 0, 'data': { + }, { { type = 11, timestamp = 0, data = { 1, 2, 3 } } }) + sd2strings_eq( + { + 'Change with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' # Required key missing: f', + ' + l line number 1', + ' + c column 0', + }, + ([[ [{'type': 11, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Change with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' # Required key missing: f', + ' + l line number 1', + ' + c column 0', + ' # Expected integer', + ' + n name "foo"', + }, + ([[ [{'type': 11, 'timestamp': 0, 'data': { 'n': 'foo', - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Change with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + f file name "foo"', - ' + l line number 1', - ' + c column 0', - }, ([[ [{'type': 11, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Change with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' + f file name "foo"', + ' + l line number 1', + ' + c column 0', + }, + ([[ [{'type': 11, 'timestamp': 0, 'data': { 'f': 'foo', - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Change with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' # Expected no NUL bytes', - ' + f file name "\\0"', - ' + l line number 1', - ' + c column 0', - ' # Value is negative', - ' + n name -10', - }, ([[ [{'type': 11, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Change with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' # Expected no NUL bytes', + ' + f file name "\\0"', + ' + l line number 1', + ' + c column 0', + ' # Value is negative', + ' + n name -10', + }, + ([[ [{'type': 11, 'timestamp': 0, 'data': { 'n': -10, 'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]}, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Change with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + f file name "foo"', - ' # Value is negative', - ' + l line number -10', - ' # Value is negative', - ' + c column -10', - }, ([[ [{'type': 11, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Change with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' + f file name "foo"', + ' # Value is negative', + ' + l line number -10', + ' # Value is negative', + ' + c column -10', + }, + ([[ [{'type': 11, 'timestamp': 0, 'data': { 'f': 'foo', 'l': -10, 'c': -10, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Change with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' + f file name "foo"', - ' # Expected integer', - ' + l line number "FOO"', - ' # Expected integer', - ' + c column "foo"', - ' + mX 10', - }, ([[ [{'type': 11, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Change with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' + f file name "foo"', + ' # Expected integer', + ' + l line number "FOO"', + ' # Expected integer', + ' + c column "foo"', + ' + mX 10', + }, + ([[ [{'type': 11, 'timestamp': 0, 'data': { 'f': 'foo', 'l': 'FOO', 'c': 'foo', 'mX': 10, - }}] ]]):gsub('\n', '')) - sd2strings_eq({ - 'Change with timestamp ' .. epoch .. ':', - ' % Key________ Description Value', - ' + f file name "foo"', - ' + l line number 2', - ' + c column 200', - ' + mX 10', - ' + mYYYYYYYYYY 10', - ' + n name \' \'', - }, ([[ [{'type': 11, 'timestamp': 0, 'data': { + }}] ]]):gsub('\n', '') + ) + sd2strings_eq( + { + 'Change with timestamp ' .. epoch .. ':', + ' % Key________ Description Value', + ' + f file name "foo"', + ' + l line number 2', + ' + c column 200', + ' + mX 10', + ' + mYYYYYYYYYY 10', + " + n name ' '", + }, + ([[ [{'type': 11, 'timestamp': 0, 'data': { 'n': 0x20, 'f': 'foo', 'l': 2, 'c': 200, 'mX': 10, 'mYYYYYYYYYY': 10, - }}] ]]):gsub('\n', '')) + }}] ]]):gsub('\n', '') + ) end) end) @@ -1337,15 +1572,16 @@ describe('autoload/shada.vim', function() end) describe('function shada#strings_to_sd', function() - local strings2sd_eq = function(expected, input) - nvim('set_var', '__input', input) - nvim_command('let g:__actual = map(shada#strings_to_sd(g:__input), ' - .. '"filter(v:val, \\"v:key[0] isnot# \'_\' ' - .. '&& v:key isnot# \'length\'\\")")') + api.nvim_set_var('__input', input) + nvim_command( + 'let g:__actual = map(shada#strings_to_sd(g:__input), ' + .. '"filter(v:val, \\"v:key[0] isnot# \'_\' ' + .. '&& v:key isnot# \'length\'\\")")' + ) -- print() if type(expected) == 'table' then - nvim('set_var', '__expected', expected) + api.nvim_set_var('__expected', expected) nvim_command('let g:__expected = ModifyVal(g:__expected)') expected = 'g:__expected' -- print(nvim_eval('msgpack#string(g:__expected)')) @@ -1360,29 +1596,36 @@ describe('autoload/shada.vim', function() end it('works with multiple items', function() - strings2sd_eq({{ - type=11, timestamp=0, data={ - f='foo', - l=2, - c=200, - mX=10, - mYYYYYYYYYY=10, - n=(' '):byte(), - } + strings2sd_eq({ + { + type = 11, + timestamp = 0, + data = { + f = 'foo', + l = 2, + c = 200, + mX = 10, + mYYYYYYYYYY = 10, + n = (' '):byte(), + }, + }, + { + type = 1, + timestamp = 0, + data = { + c = 'abc', + f = { '!binary', { 'abc\ndef' } }, + l = -10, + n = -64, + rc = '10', + rt = 10, + sc = { '!nil', 0 }, + sm = 'TRUE', + so = 'TRUE', + sp = { '!string', { 'abc' } }, + }, + }, }, { - type=1, timestamp=0, data={ - c='abc', - f={'!binary', {'abc\ndef'}}, - l=-10, - n=-64, - rc='10', - rt=10, - sc={'!nil', 0}, - sm='TRUE', - so='TRUE', - sp={'!string', {'abc'}}, - } - }}, { 'Change with timestamp ' .. epoch .. ':', ' % Key________ Description Value', ' + f file name "foo"', @@ -1390,7 +1633,7 @@ describe('autoload/shada.vim', function() ' + c column 200', ' + mX 10', ' + mYYYYYYYYYY 10', - ' + n name \' \'', + " + n name ' '", 'Header with timestamp ' .. epoch .. ':', ' % Key Description____ Value', ' # Expected integer', @@ -1404,7 +1647,7 @@ describe('autoload/shada.vim', function() ' # Expected array value', ' + rc contents "10"', ' # Unexpected enum value: expected one of ' - .. '0 (CHARACTERWISE), 1 (LINEWISE), 2 (BLOCKWISE)', + .. '0 (CHARACTERWISE), 1 (LINEWISE), 2 (BLOCKWISE)', ' + rt type 10', ' # Expected boolean', ' + sc smartcase value NIL', @@ -1422,23 +1665,37 @@ describe('autoload/shada.vim', function() end) it('works with header items', function() - strings2sd_eq({{type=1, timestamp=0, data={ - generator='test', - }}}, { + strings2sd_eq({ { type = 1, timestamp = 0, data = { + generator = 'test', + } } }, { 'Header with timestamp ' .. epoch .. ':', ' % Key______ Value', ' + generator "test"', }) - strings2sd_eq({{type=1, timestamp=0, data={ - 1, 2, 3, - }}}, { - 'Header with timestamp ' .. epoch .. ':', - ' # Unexpected type: array instead of map', - ' = [1, 2, 3]', - }) - strings2sd_eq({{type=1, timestamp=0, data={ - a=1, b=2, c=3, d=4, - }}}, { + strings2sd_eq( + { { type = 1, timestamp = 0, data = { + 1, + 2, + 3, + } } }, + { + 'Header with timestamp ' .. epoch .. ':', + ' # Unexpected type: array instead of map', + ' = [1, 2, 3]', + } + ) + strings2sd_eq({ + { + type = 1, + timestamp = 0, + data = { + a = 1, + b = 2, + c = 3, + d = 4, + }, + }, + }, { 'Header with timestamp ' .. epoch .. ':', ' % Key Description Value', ' + a 1', @@ -1446,18 +1703,24 @@ describe('autoload/shada.vim', function() ' + c column 3', ' + d 4', }) - strings2sd_eq({{type=1, timestamp=0, data={ - c='abc', - f={'!binary', {'abc\ndef'}}, - l=-10, - n=-64, - rc='10', - rt=10, - sc={'!nil', 0}, - sm='TRUE', - so='TRUE', - sp={'!string', {'abc'}}, - }}}, { + strings2sd_eq({ + { + type = 1, + timestamp = 0, + data = { + c = 'abc', + f = { '!binary', { 'abc\ndef' } }, + l = -10, + n = -64, + rc = '10', + rt = 10, + sc = { '!nil', 0 }, + sm = 'TRUE', + so = 'TRUE', + sp = { '!string', { 'abc' } }, + }, + }, + }, { 'Header with timestamp ' .. epoch .. ':', ' % Key Description____ Value', ' # Expected integer', @@ -1471,7 +1734,7 @@ describe('autoload/shada.vim', function() ' # Expected array value', ' + rc contents "10"', ' # Unexpected enum value: expected one of ' - .. '0 (CHARACTERWISE), 1 (LINEWISE), 2 (BLOCKWISE)', + .. '0 (CHARACTERWISE), 1 (LINEWISE), 2 (BLOCKWISE)', ' + rt type 10', ' # Expected boolean', ' + sc smartcase value NIL', @@ -1485,16 +1748,21 @@ describe('autoload/shada.vim', function() end) it('works with search pattern items', function() - strings2sd_eq({{type=2, timestamp=0, data={ - 1, 2, 3 - }}}, { - 'Search pattern with timestamp ' .. epoch .. ':', - ' # Unexpected type: array instead of map', - ' = [1, 2, 3]', - }) - strings2sd_eq({{type=2, timestamp=0, data={ - sp='abc', - }}}, { + strings2sd_eq( + { { type = 2, timestamp = 0, data = { + 1, + 2, + 3, + } } }, + { + 'Search pattern with timestamp ' .. epoch .. ':', + ' # Unexpected type: array instead of map', + ' = [1, 2, 3]', + } + ) + strings2sd_eq({ { type = 2, timestamp = 0, data = { + sp = 'abc', + } } }, { 'Search pattern with timestamp ' .. epoch .. ':', ' % Key Description________ Value', ' + sp pattern "abc"', @@ -1507,12 +1775,18 @@ describe('autoload/shada.vim', function() ' + so offset value 0', ' + su is last used TRUE', }) - strings2sd_eq({{type=2, timestamp=0, data={ - sp='abc', - sX={'!nil', 0}, - sY={'!nil', 0}, - sZ={'!nil', 0}, - }}}, { + strings2sd_eq({ + { + type = 2, + timestamp = 0, + data = { + sp = 'abc', + sX = { '!nil', 0 }, + sY = { '!nil', 0 }, + sZ = { '!nil', 0 }, + }, + }, + }, { 'Search pattern with timestamp ' .. epoch .. ':', ' % Key Description________ Value', ' + sp pattern "abc"', @@ -1528,8 +1802,7 @@ describe('autoload/shada.vim', function() ' + sY NIL', ' + sZ NIL', }) - strings2sd_eq({{type=2, timestamp=0, data={'!map', { - }}}}, { + strings2sd_eq({ { type = 2, timestamp = 0, data = { '!map', {} } } }, { 'Search pattern with timestamp ' .. epoch .. ':', ' % Key Description________ Value', ' # Required key missing: sp', @@ -1542,17 +1815,23 @@ describe('autoload/shada.vim', function() ' + so offset value 0', ' + su is last used TRUE', }) - strings2sd_eq({{type=2, timestamp=0, data={ - sp='', - sh={'!boolean', 1}, - ss={'!boolean', 1}, - sc={'!boolean', 1}, - sl={'!boolean', 1}, - se={'!boolean', 1}, - sm={'!boolean', 0}, - su={'!boolean', 0}, - so=-10, - }}}, { + strings2sd_eq({ + { + type = 2, + timestamp = 0, + data = { + sp = '', + sh = { '!boolean', 1 }, + ss = { '!boolean', 1 }, + sc = { '!boolean', 1 }, + sl = { '!boolean', 1 }, + se = { '!boolean', 1 }, + sm = { '!boolean', 0 }, + su = { '!boolean', 0 }, + so = -10, + }, + }, + }, { 'Search pattern with timestamp ' .. epoch .. ':', ' % Key Description________ Value', ' + sp pattern ""', @@ -1565,17 +1844,23 @@ describe('autoload/shada.vim', function() ' + so offset value -10', ' + su is last used FALSE', }) - strings2sd_eq({{type=2, timestamp=0, data={ - sp=0, - sh=0, - ss=0, - sc=0, - sl=0, - se=0, - sm=0, - su=0, - so='', - }}}, { + strings2sd_eq({ + { + type = 2, + timestamp = 0, + data = { + sp = 0, + sh = 0, + ss = 0, + sc = 0, + sl = 0, + se = 0, + sm = 0, + su = 0, + so = '', + }, + }, + }, { 'Search pattern with timestamp ' .. epoch .. ':', ' % Key Description________ Value', ' # Expected binary string', @@ -1600,38 +1885,41 @@ describe('autoload/shada.vim', function() end) it('works with replacement string items', function() - strings2sd_eq({{type=3, timestamp=0, data={ - a={10} - }}}, { + strings2sd_eq({ { type = 3, timestamp = 0, data = { + a = { 10 }, + } } }, { 'Replacement string with timestamp ' .. epoch .. ':', ' # Unexpected type: map instead of array', ' = {="a": [10]}', }) - strings2sd_eq({{type=3, timestamp=0, data={ - }}}, { + strings2sd_eq({ { type = 3, timestamp = 0, data = {} } }, { 'Replacement string with timestamp ' .. epoch .. ':', ' @ Description__________ Value', - ' # Expected more elements in list' + ' # Expected more elements in list', }) - strings2sd_eq({{type=3, timestamp=0, data={ - 0 - }}}, { + strings2sd_eq({ { type = 3, timestamp = 0, data = { + 0, + } } }, { 'Replacement string with timestamp ' .. epoch .. ':', ' @ Description__________ Value', ' # Expected binary string', ' - :s replacement string 0', }) - strings2sd_eq({{type=3, timestamp=0, data={ - 'abc\ndef', 0, - }}}, { - 'Replacement string with timestamp ' .. epoch .. ':', - ' @ Description__________ Value', - ' - :s replacement string "abc\\ndef"', - ' - 0', - }) - strings2sd_eq({{type=3, timestamp=0, data={ + strings2sd_eq( + { { type = 3, timestamp = 0, data = { + 'abc\ndef', + 0, + } } }, + { + 'Replacement string with timestamp ' .. epoch .. ':', + ' @ Description__________ Value', + ' - :s replacement string "abc\\ndef"', + ' - 0', + } + ) + strings2sd_eq({ { type = 3, timestamp = 0, data = { 'abc\ndef', - }}}, { + } } }, { 'Replacement string with timestamp ' .. epoch .. ':', ' @ Description__________ Value', ' - :s replacement string "abc\\ndef"', @@ -1639,95 +1927,114 @@ describe('autoload/shada.vim', function() end) it('works with history entry items', function() - strings2sd_eq({{type=4, timestamp=0, data={ - a={10}, - }}}, { + strings2sd_eq({ { type = 4, timestamp = 0, data = { + a = { 10 }, + } } }, { 'History entry with timestamp ' .. epoch .. ':', ' # Unexpected type: map instead of array', ' = {="a": [10]}', }) - strings2sd_eq({{type=4, timestamp=0, data={ - }}}, { + strings2sd_eq({ { type = 4, timestamp = 0, data = {} } }, { 'History entry with timestamp ' .. epoch .. ':', ' @ Description_ Value', - ' # Expected more elements in list' + ' # Expected more elements in list', }) - strings2sd_eq({{type=4, timestamp=0, data={ + strings2sd_eq({ { type = 4, timestamp = 0, data = { '', - }}}, { + } } }, { 'History entry with timestamp ' .. epoch .. ':', ' @ Description_ Value', ' # Expected integer', ' - history type ""', - ' # Expected more elements in list' + ' # Expected more elements in list', }) - strings2sd_eq({{type=4, timestamp=0, data={ - 5, '', - }}}, { + strings2sd_eq({ { type = 4, timestamp = 0, data = { + 5, + '', + } } }, { 'History entry with timestamp ' .. epoch .. ':', ' @ Description_ Value', ' # Unexpected enum value: expected one of 0 (CMD), 1 (SEARCH), ' - .. '2 (EXPR), 3 (INPUT), 4 (DEBUG)', + .. '2 (EXPR), 3 (INPUT), 4 (DEBUG)', ' - history type 5', ' - contents ""', }) - strings2sd_eq({{type=4, timestamp=0, data={ - 5, '', 32, - }}}, { - 'History entry with timestamp ' .. epoch .. ':', - ' @ Description_ Value', - ' # Unexpected enum value: expected one of 0 (CMD), 1 (SEARCH), ' + strings2sd_eq( + { { type = 4, timestamp = 0, data = { + 5, + '', + 32, + } } }, + { + 'History entry with timestamp ' .. epoch .. ':', + ' @ Description_ Value', + ' # Unexpected enum value: expected one of 0 (CMD), 1 (SEARCH), ' .. '2 (EXPR), 3 (INPUT), 4 (DEBUG)', - ' - history type 5', - ' - contents ""', - ' - 32', - }) - strings2sd_eq({{type=4, timestamp=0, data={ - 0, '', 32, - }}}, { - 'History entry with timestamp ' .. epoch .. ':', - ' @ Description_ Value', - ' - history type CMD', - ' - contents ""', - ' - 32', - }) - strings2sd_eq({{type=4, timestamp=0, data={ - 1, '', 32, - }}}, { - 'History entry with timestamp ' .. epoch .. ':', - ' @ Description_ Value', - ' - history type SEARCH', - ' - contents ""', - ' - separator \' \'', - }) - strings2sd_eq({{type=4, timestamp=0, data={ - 1, '', - }}}, { + ' - history type 5', + ' - contents ""', + ' - 32', + } + ) + strings2sd_eq( + { { type = 4, timestamp = 0, data = { + 0, + '', + 32, + } } }, + { + 'History entry with timestamp ' .. epoch .. ':', + ' @ Description_ Value', + ' - history type CMD', + ' - contents ""', + ' - 32', + } + ) + strings2sd_eq( + { { type = 4, timestamp = 0, data = { + 1, + '', + 32, + } } }, + { + 'History entry with timestamp ' .. epoch .. ':', + ' @ Description_ Value', + ' - history type SEARCH', + ' - contents ""', + " - separator ' '", + } + ) + strings2sd_eq({ { type = 4, timestamp = 0, data = { + 1, + '', + } } }, { 'History entry with timestamp ' .. epoch .. ':', ' @ Description_ Value', ' - history type SEARCH', ' - contents ""', ' # Expected more elements in list', }) - strings2sd_eq({{type=4, timestamp=0, data={ - 2, '', - }}}, { + strings2sd_eq({ { type = 4, timestamp = 0, data = { + 2, + '', + } } }, { 'History entry with timestamp ' .. epoch .. ':', ' @ Description_ Value', ' - history type EXPR', ' - contents ""', }) - strings2sd_eq({{type=4, timestamp=0, data={ - 3, '' - }}}, { + strings2sd_eq({ { type = 4, timestamp = 0, data = { + 3, + '', + } } }, { 'History entry with timestamp ' .. epoch .. ':', ' @ Description_ Value', ' - history type INPUT', ' - contents ""', }) - strings2sd_eq({{type=4, timestamp=0, data={ - 4, '' - }}}, { + strings2sd_eq({ { type = 4, timestamp = 0, data = { + 4, + '', + } } }, { 'History entry with timestamp ' .. epoch .. ':', ' @ Description_ Value', ' - history type DEBUG', @@ -1736,15 +2043,19 @@ describe('autoload/shada.vim', function() end) it('works with register items', function() - strings2sd_eq({{type=5, timestamp=0, data={ - 1, 2, 3 - }}}, { - 'Register with timestamp ' .. epoch .. ':', - ' # Unexpected type: array instead of map', - ' = [1, 2, 3]', - }) - strings2sd_eq({{type=5, timestamp=0, data={'!map', { - }}}}, { + strings2sd_eq( + { { type = 5, timestamp = 0, data = { + 1, + 2, + 3, + } } }, + { + 'Register with timestamp ' .. epoch .. ':', + ' # Unexpected type: array instead of map', + ' = [1, 2, 3]', + } + ) + strings2sd_eq({ { type = 5, timestamp = 0, data = { '!map', {} } } }, { 'Register with timestamp ' .. epoch .. ':', ' % Key Description Value', ' # Required key missing: n', @@ -1752,121 +2063,166 @@ describe('autoload/shada.vim', function() ' + rw block width 0', ' + rt type CHARACTERWISE', }) - strings2sd_eq({{type=5, timestamp=0, data={ - n=(' '):byte() - }}}, { + strings2sd_eq({ { type = 5, timestamp = 0, data = { + n = (' '):byte(), + } } }, { 'Register with timestamp ' .. epoch .. ':', ' % Key Description Value', - ' + n name \' \'', + " + n name ' '", ' # Required key missing: rc', ' + rw block width 0', ' + rt type CHARACTERWISE', }) - strings2sd_eq({{type=5, timestamp=0, data={ - n=(' '):byte(), rc={'abc', 'def'} - }}}, { + strings2sd_eq({ + { + type = 5, + timestamp = 0, + data = { + n = (' '):byte(), + rc = { 'abc', 'def' }, + }, + }, + }, { 'Register with timestamp ' .. epoch .. ':', ' % Key Description Value', - ' + n name \' \'', + " + n name ' '", ' + rc contents ["abc", "def"]', ' + rw block width 0', ' + rt type CHARACTERWISE', }) - strings2sd_eq({{type=5, timestamp=0, data={ - n=(' '):byte(), - rc={'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'}, - }}}, { + strings2sd_eq({ + { + type = 5, + timestamp = 0, + data = { + n = (' '):byte(), + rc = { 'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz' }, + }, + }, + }, { 'Register with timestamp ' .. epoch .. ':', ' % Key Description Value', - ' + n name \' \'', + " + n name ' '", ' + rc contents @', ' | - "abcdefghijklmnopqrstuvwxyz"', ' | - "abcdefghijklmnopqrstuvwxyz"', ' + rw block width 0', ' + rt type CHARACTERWISE', }) - strings2sd_eq({{type=5, timestamp=0, data={ - n=(' '):byte(), - rc={'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'}, - rw=5, - rt=1, - }}}, { + strings2sd_eq({ + { + type = 5, + timestamp = 0, + data = { + n = (' '):byte(), + rc = { 'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz' }, + rw = 5, + rt = 1, + }, + }, + }, { 'Register with timestamp ' .. epoch .. ':', ' % Key Description Value', - ' + n name \' \'', + " + n name ' '", ' + rc contents @', ' | - "abcdefghijklmnopqrstuvwxyz"', ' | - "abcdefghijklmnopqrstuvwxyz"', ' + rw block width 5', ' + rt type LINEWISE', }) - strings2sd_eq({{type=5, timestamp=0, data={ - n=(' '):byte(), - rc={'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'}, - rw=5, - rt=2, - }}}, { + strings2sd_eq({ + { + type = 5, + timestamp = 0, + data = { + n = (' '):byte(), + rc = { 'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz' }, + rw = 5, + rt = 2, + }, + }, + }, { 'Register with timestamp ' .. epoch .. ':', ' % Key Description Value', - ' + n name \' \'', + " + n name ' '", ' + rc contents @', ' | - "abcdefghijklmnopqrstuvwxyz"', ' | - "abcdefghijklmnopqrstuvwxyz"', ' + rw block width 5', ' + rt type BLOCKWISE', }) - strings2sd_eq({{type=5, timestamp=0, data={ - n=(' '):byte(), - rc=0, - rw=-1, - rt=10, - }}}, { + strings2sd_eq({ + { + type = 5, + timestamp = 0, + data = { + n = (' '):byte(), + rc = 0, + rw = -1, + rt = 10, + }, + }, + }, { 'Register with timestamp ' .. epoch .. ':', ' % Key Description Value', - ' + n name \' \'', + " + n name ' '", ' # Expected array value', ' + rc contents 0', ' # Value is negative', ' + rw block width -1', ' # Unexpected enum value: expected one of 0 (CHARACTERWISE), ' - .. '1 (LINEWISE), 2 (BLOCKWISE)', + .. '1 (LINEWISE), 2 (BLOCKWISE)', ' + rt type 10', }) end) it('works with variable items', function() - strings2sd_eq({{type=6, timestamp=0, data={ - a={10} - }}}, { + strings2sd_eq({ { type = 6, timestamp = 0, data = { + a = { 10 }, + } } }, { 'Variable with timestamp ' .. epoch .. ':', ' # Unexpected type: map instead of array', ' = {="a": [10]}', }) - strings2sd_eq({{type=6, timestamp=0, data={ - }}}, { + strings2sd_eq({ { type = 6, timestamp = 0, data = {} } }, { 'Variable with timestamp ' .. epoch .. ':', ' @ Description Value', - ' # Expected more elements in list' + ' # Expected more elements in list', }) - strings2sd_eq({{type=6, timestamp=0, data={ + strings2sd_eq({ { type = 6, timestamp = 0, data = { 'foo', - }}}, { + } } }, { 'Variable with timestamp ' .. epoch .. ':', ' @ Description Value', ' - name "foo"', ' # Expected more elements in list', }) - strings2sd_eq({{type=6, timestamp=0, data={ - 'foo', {'!nil', 0}, - }}}, { + strings2sd_eq({ + { + type = 6, + timestamp = 0, + data = { + 'foo', + { '!nil', 0 }, + }, + }, + }, { 'Variable with timestamp ' .. epoch .. ':', ' @ Description Value', ' - name "foo"', ' - value NIL', }) - strings2sd_eq({{type=6, timestamp=0, data={ - 'foo', {'!nil', 0}, {'!nil', 0} - }}}, { + strings2sd_eq({ + { + type = 6, + timestamp = 0, + data = { + 'foo', + { '!nil', 0 }, + { '!nil', 0 }, + }, + }, + }, { 'Variable with timestamp ' .. epoch .. ':', ' @ Description Value', ' - name "foo"', @@ -1876,19 +2232,35 @@ describe('autoload/shada.vim', function() end) it('works with global mark items', function() - strings2sd_eq({{type=7, timestamp=0, data={ - 1, 2, 3 - }}}, { - 'Global mark with timestamp ' .. epoch .. ':', - ' # Unexpected type: array instead of map', - ' = [1, 2, 3]', - }) - strings2sd_eq({{type=7, timestamp=0, data={ - n=('A'):byte(), f='foo', l=2, c=200, mX=10, mYYYYYYYYYY=10, - }}}, { + strings2sd_eq( + { { type = 7, timestamp = 0, data = { + 1, + 2, + 3, + } } }, + { + 'Global mark with timestamp ' .. epoch .. ':', + ' # Unexpected type: array instead of map', + ' = [1, 2, 3]', + } + ) + strings2sd_eq({ + { + type = 7, + timestamp = 0, + data = { + n = ('A'):byte(), + f = 'foo', + l = 2, + c = 200, + mX = 10, + mYYYYYYYYYY = 10, + }, + }, + }, { 'Global mark with timestamp ' .. epoch .. ':', ' % Key________ Description Value', - ' + n name \'A\'', + " + n name 'A'", ' + f file name "foo"', ' + l line number 2', ' + c column 200', @@ -1898,19 +2270,35 @@ describe('autoload/shada.vim', function() end) it('works with jump items', function() - strings2sd_eq({{type=8, timestamp=0, data={ - 1, 2, 3 - }}}, { - 'Jump with timestamp ' .. epoch .. ':', - ' # Unexpected type: array instead of map', - ' = [1, 2, 3]', - }) - strings2sd_eq({{type=8, timestamp=0, data={ - n=('A'):byte(), f='foo', l=2, c=200, mX=10, mYYYYYYYYYY=10, - }}}, { + strings2sd_eq( + { { type = 8, timestamp = 0, data = { + 1, + 2, + 3, + } } }, + { + 'Jump with timestamp ' .. epoch .. ':', + ' # Unexpected type: array instead of map', + ' = [1, 2, 3]', + } + ) + strings2sd_eq({ + { + type = 8, + timestamp = 0, + data = { + n = ('A'):byte(), + f = 'foo', + l = 2, + c = 200, + mX = 10, + mYYYYYYYYYY = 10, + }, + }, + }, { 'Jump with timestamp ' .. epoch .. ':', ' % Key________ Description Value', - ' + n name \'A\'', + " + n name 'A'", ' + f file name "foo"', ' + l line number 2', ' + c column 200', @@ -1920,23 +2308,27 @@ describe('autoload/shada.vim', function() end) it('works with buffer list items', function() - strings2sd_eq({{type=9, timestamp=0, data={ - a={10} - }}}, { + strings2sd_eq({ { type = 9, timestamp = 0, data = { + a = { 10 }, + } } }, { 'Buffer list with timestamp ' .. epoch .. ':', ' # Unexpected type: map instead of array', ' = {="a": [10]}', }) - strings2sd_eq({{type=9, timestamp=0, data={ - {a=10}, {} - }}}, { - 'Buffer list with timestamp ' .. epoch .. ':', - ' # Expected array of maps', - ' = [{="a": 10}, []]', - }) - strings2sd_eq({{type=9, timestamp=0, data={ - {a=10}, - }}}, { + strings2sd_eq( + { { type = 9, timestamp = 0, data = { + { a = 10 }, + {}, + } } }, + { + 'Buffer list with timestamp ' .. epoch .. ':', + ' # Expected array of maps', + ' = [{="a": 10}, []]', + } + ) + strings2sd_eq({ { type = 9, timestamp = 0, data = { + { a = 10 }, + } } }, { 'Buffer list with timestamp ' .. epoch .. ':', ' % Key Description Value', ' # Required key missing: f', @@ -1944,9 +2336,15 @@ describe('autoload/shada.vim', function() ' + c column 0', ' + a 10', }) - strings2sd_eq({{type=9, timestamp=0, data={ - {l='10', c='10', a=10}, - }}}, { + strings2sd_eq({ + { + type = 9, + timestamp = 0, + data = { + { l = '10', c = '10', a = 10 }, + }, + }, + }, { 'Buffer list with timestamp ' .. epoch .. ':', ' % Key Description Value', ' # Required key missing: f', @@ -1956,59 +2354,79 @@ describe('autoload/shada.vim', function() ' + c column "10"', ' + a 10', }) - strings2sd_eq({{type=9, timestamp=0, data={ - {l=10, c=10, a=10}, - }}}, { - 'Buffer list with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' # Required key missing: f', - ' + l line number 10', - ' + c column 10', - ' + a 10', - }) - strings2sd_eq({{type=9, timestamp=0, data={ - {l=-10, c=-10}, - }}}, { - 'Buffer list with timestamp ' .. epoch .. ':', - ' % Key Description Value', - ' # Required key missing: f', - ' # Value is negative', - ' + l line number -10', - ' # Value is negative', - ' + c column -10', - }) - strings2sd_eq({{type=9, timestamp=0, data={ - {f='abc'}, - }}}, { + strings2sd_eq( + { { type = 9, timestamp = 0, data = { + { l = 10, c = 10, a = 10 }, + } } }, + { + 'Buffer list with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' # Required key missing: f', + ' + l line number 10', + ' + c column 10', + ' + a 10', + } + ) + strings2sd_eq( + { { type = 9, timestamp = 0, data = { + { l = -10, c = -10 }, + } } }, + { + 'Buffer list with timestamp ' .. epoch .. ':', + ' % Key Description Value', + ' # Required key missing: f', + ' # Value is negative', + ' + l line number -10', + ' # Value is negative', + ' + c column -10', + } + ) + strings2sd_eq({ { type = 9, timestamp = 0, data = { + { f = 'abc' }, + } } }, { 'Buffer list with timestamp ' .. epoch .. ':', ' % Key Description Value', ' + f file name "abc"', ' + l line number 1', ' + c column 0', }) - strings2sd_eq({{type=9, timestamp=0, data={ - {f=10}, {f=20}, - }}}, { + strings2sd_eq({ + { + type = 9, + timestamp = 0, + data = { + { f = 10 }, + { f = 20 }, + }, + }, + }, { 'Buffer list with timestamp ' .. epoch .. ':', ' % Key Description Value', ' # Expected binary string', - ' + f file name \'\\10\'', + " + f file name '\\10'", ' + l line number 1', ' + c column 0', '', ' % Key Description Value', ' # Expected binary string', - ' + f file name \'\\20\'', + " + f file name '\\20'", ' + l line number 1', ' + c column 0', }) - strings2sd_eq({{type=9, timestamp=0, data={ - {f=10}, {f={'!binary', {'\n'}}}, - }}}, { + strings2sd_eq({ + { + type = 9, + timestamp = 0, + data = { + { f = 10 }, + { f = { '!binary', { '\n' } } }, + }, + }, + }, { 'Buffer list with timestamp ' .. epoch .. ':', ' % Key Description Value', ' # Expected binary string', - ' + f file name \'\\10\'', + " + f file name '\\10'", ' + l line number 1', ' + c column 0', '', @@ -2021,19 +2439,35 @@ describe('autoload/shada.vim', function() end) it('works with local mark items', function() - strings2sd_eq({{type=10, timestamp=0, data={ - 1, 2, 3 - }}}, { - 'Local mark with timestamp ' .. epoch .. ':', - ' # Unexpected type: array instead of map', - ' = [1, 2, 3]', - }) - strings2sd_eq({{type=10, timestamp=0, data={ - n=('A'):byte(), f='foo', l=2, c=200, mX=10, mYYYYYYYYYY=10, - }}}, { + strings2sd_eq( + { { type = 10, timestamp = 0, data = { + 1, + 2, + 3, + } } }, + { + 'Local mark with timestamp ' .. epoch .. ':', + ' # Unexpected type: array instead of map', + ' = [1, 2, 3]', + } + ) + strings2sd_eq({ + { + type = 10, + timestamp = 0, + data = { + n = ('A'):byte(), + f = 'foo', + l = 2, + c = 200, + mX = 10, + mYYYYYYYYYY = 10, + }, + }, + }, { 'Local mark with timestamp ' .. epoch .. ':', ' % Key________ Description Value', - ' + n name \'A\'', + " + n name 'A'", ' + f file name "foo"', ' + l line number 2', ' + c column 200', @@ -2043,19 +2477,35 @@ describe('autoload/shada.vim', function() end) it('works with change items', function() - strings2sd_eq({{type=11, timestamp=0, data={ - 1, 2, 3 - }}}, { - 'Change with timestamp ' .. epoch .. ':', - ' # Unexpected type: array instead of map', - ' = [1, 2, 3]', - }) - strings2sd_eq({{type=11, timestamp=0, data={ - n=('A'):byte(), f='foo', l=2, c=200, mX=10, mYYYYYYYYYY=10, - }}}, { + strings2sd_eq( + { { type = 11, timestamp = 0, data = { + 1, + 2, + 3, + } } }, + { + 'Change with timestamp ' .. epoch .. ':', + ' # Unexpected type: array instead of map', + ' = [1, 2, 3]', + } + ) + strings2sd_eq({ + { + type = 11, + timestamp = 0, + data = { + n = ('A'):byte(), + f = 'foo', + l = 2, + c = 200, + mX = 10, + mYYYYYYYYYY = 10, + }, + }, + }, { 'Change with timestamp ' .. epoch .. ':', ' % Key________ Description Value', - ' + n name \'A\'', + " + n name 'A'", ' + f file name "foo"', ' + l line number 2', ' + c column 200', @@ -2067,7 +2517,7 @@ describe('autoload/shada.vim', function() describe('function shada#get_binstrings', function() local getbstrings_eq = function(expected, input) - local result = funcs['shada#get_binstrings'](input) + local result = fn['shada#get_binstrings'](input) for i, s in ipairs(result) do result[i] = s:gsub('\n', '\0') end @@ -2076,53 +2526,75 @@ describe('autoload/shada.vim', function() end it('works', function() - local version = nvim('get_vvar', 'version') - getbstrings_eq({{timestamp='current', type=1, value={ - generator='shada.vim', - version=version, - }}}, {}) + local version = api.nvim_get_vvar('version') getbstrings_eq({ - {timestamp='current', type=1, value={ - generator='shada.vim', version=version - }}, - {timestamp=0, type=1, value={generator='test'}} + { + timestamp = 'current', + type = 1, + value = { + generator = 'shada.vim', + version = version, + }, + }, + }, {}) + getbstrings_eq({ + { + timestamp = 'current', + type = 1, + value = { + generator = 'shada.vim', + version = version, + }, + }, + { timestamp = 0, type = 1, value = { generator = 'test' } }, }, { 'Header with timestamp ' .. epoch .. ':', ' % Key______ Value', ' + generator "test"', }) - nvim('set_var', 'shada#add_own_header', 1) - getbstrings_eq({{timestamp='current', type=1, value={ - generator='shada.vim', - version=version, - }}}, {}) + api.nvim_set_var('shada#add_own_header', 1) + getbstrings_eq({ + { + timestamp = 'current', + type = 1, + value = { + generator = 'shada.vim', + version = version, + }, + }, + }, {}) getbstrings_eq({ - {timestamp='current', type=1, value={ - generator='shada.vim', version=version - }}, - {timestamp=0, type=1, value={generator='test'}} + { + timestamp = 'current', + type = 1, + value = { + generator = 'shada.vim', + version = version, + }, + }, + { timestamp = 0, type = 1, value = { generator = 'test' } }, }, { 'Header with timestamp ' .. epoch .. ':', ' % Key______ Value', ' + generator "test"', }) - nvim('set_var', 'shada#add_own_header', 0) + api.nvim_set_var('shada#add_own_header', 0) getbstrings_eq({}, {}) - getbstrings_eq({{timestamp=0, type=1, value={generator='test'}}}, { + getbstrings_eq({ { timestamp = 0, type = 1, value = { generator = 'test' } } }, { 'Header with timestamp ' .. epoch .. ':', ' % Key______ Value', ' + generator "test"', }) - nvim('set_var', 'shada#keep_old_header', 0) + api.nvim_set_var('shada#keep_old_header', 0) getbstrings_eq({}, { 'Header with timestamp ' .. epoch .. ':', ' % Key______ Value', ' + generator "test"', }) getbstrings_eq({ - {type=3, timestamp=0, value={'abc\ndef'}}, - {type=3, timestamp=0, value={'abc\ndef'}}, - {type=3, timestamp=0, value={'abc\ndef'}}, + { type = 3, timestamp = 0, value = { 'abc\ndef' } }, + { type = 3, timestamp = 0, value = { 'abc\ndef' } }, + { type = 3, timestamp = 0, value = { 'abc\ndef' } }, }, { 'Replacement string with timestamp ' .. epoch .. ':', ' @ Description__________ Value', @@ -2164,8 +2636,8 @@ describe('plugin/shada.vim', function() wshada('\004\000\009\147\000\196\002ab\196\001a') wshada_tmp('\004\000\009\147\000\196\002ab\196\001b') - - local bufread_commands = meths.get_autocmds({ group = "ShaDaCommands", event = "BufReadCmd" }) + local bufread_commands = + api.nvim_get_autocmds({ group = 'ShaDaCommands', event = 'BufReadCmd' }) eq(2, #bufread_commands--[[, vim.inspect(bufread_commands) ]]) -- Need to set nohidden so that the buffer containing 'fname' is not unloaded @@ -2181,8 +2653,8 @@ describe('plugin/shada.vim', function() ' - contents "ab"', ' - "a"', }, nvim_eval('getline(1, "$")')) - eq(false, nvim('get_option_value', 'modified', {})) - eq('shada', nvim('get_option_value', 'filetype', {})) + eq(false, api.nvim_get_option_value('modified', {})) + eq('shada', api.nvim_get_option_value('filetype', {})) nvim_command('edit ' .. fname_tmp) eq({ 'History entry with timestamp ' .. epoch .. ':', @@ -2191,8 +2663,8 @@ describe('plugin/shada.vim', function() ' - contents "ab"', ' - "b"', }, nvim_eval('getline(1, "$")')) - eq(false, nvim('get_option_value', 'modified', {})) - eq('shada', nvim('get_option_value', 'filetype', {})) + eq(false, api.nvim_get_option_value('modified', {})) + eq('shada', api.nvim_get_option_value('filetype', {})) eq('++opt not supported', exc_exec('edit ++enc=latin1 ' .. fname)) neq({ 'History entry with timestamp ' .. epoch .. ':', @@ -2201,7 +2673,7 @@ describe('plugin/shada.vim', function() ' - contents "ab"', ' - "a"', }, nvim_eval('getline(1, "$")')) - neq(true, nvim('get_option_value', 'modified', {})) + neq(true, api.nvim_get_option_value('modified', {})) end) it('event FileReadCmd', function() @@ -2217,8 +2689,8 @@ describe('plugin/shada.vim', function() ' - contents "ab"', ' - "a"', }, nvim_eval('getline(1, "$")')) - eq(true, nvim('get_option_value', 'modified', {})) - neq('shada', nvim('get_option_value', 'filetype', {})) + eq(true, api.nvim_get_option_value('modified', {})) + neq('shada', api.nvim_get_option_value('filetype', {})) nvim_command('1,$read ' .. fname_tmp) eq({ '', @@ -2233,9 +2705,9 @@ describe('plugin/shada.vim', function() ' - contents "ab"', ' - "b"', }, nvim_eval('getline(1, "$")')) - eq(true, nvim('get_option_value', 'modified', {})) - neq('shada', nvim('get_option_value', 'filetype', {})) - nvim('set_option_value', 'modified', false, {}) + eq(true, api.nvim_get_option_value('modified', {})) + neq('shada', api.nvim_get_option_value('filetype', {})) + api.nvim_set_option_value('modified', false, {}) eq('++opt not supported', exc_exec('$read ++enc=latin1 ' .. fname)) eq({ '', @@ -2250,22 +2722,22 @@ describe('plugin/shada.vim', function() ' - contents "ab"', ' - "b"', }, nvim_eval('getline(1, "$")')) - neq(true, nvim('get_option_value', 'modified', {})) + neq(true, api.nvim_get_option_value('modified', {})) end) it('event BufWriteCmd', function() reset() - nvim('set_var', 'shada#add_own_header', 0) - curbuf('set_lines', 0, 1, true, { + api.nvim_set_var('shada#add_own_header', 0) + api.nvim_buf_set_lines(0, 0, 1, true, { 'Jump with timestamp ' .. epoch .. ':', ' % Key________ Description Value', - ' + n name \'A\'', + " + n name 'A'", ' + f file name ["foo"]', ' + l line number 2', ' + c column -200', 'Jump with timestamp ' .. epoch .. ':', ' % Key________ Description Value', - ' + n name \'A\'', + " + n name 'A'", ' + f file name ["foo"]', ' + l line number 2', ' + c column -200', @@ -2277,50 +2749,56 @@ describe('plugin/shada.vim', function() eq(table.concat({ 'Jump with timestamp ' .. epoch .. ':', ' % Key________ Description Value', - ' + n name \'A\'', + " + n name 'A'", ' + f file name ["foo"]', ' + l line number 2', ' + c column -200', 'Jump with timestamp ' .. epoch .. ':', ' % Key________ Description Value', - ' + n name \'A\'', + " + n name 'A'", ' + f file name ["foo"]', ' + l line number 2', ' + c column -200', }, eol) .. eol, read_file(fname .. '.tst')) - shada_eq({{ - timestamp=0, - type=8, - value={c=-200, f={'foo'}, l=2, n=('A'):byte()}, - }, { - timestamp=0, - type=8, - value={c=-200, f={'foo'}, l=2, n=('A'):byte()}, - }}, fname) - shada_eq({{ - timestamp=0, - type=8, - value={c=-200, f={'foo'}, l=2, n=('A'):byte()}, - }, { - timestamp=0, - type=8, - value={c=-200, f={'foo'}, l=2, n=('A'):byte()}, - }}, fname_tmp) + shada_eq({ + { + timestamp = 0, + type = 8, + value = { c = -200, f = { 'foo' }, l = 2, n = ('A'):byte() }, + }, + { + timestamp = 0, + type = 8, + value = { c = -200, f = { 'foo' }, l = 2, n = ('A'):byte() }, + }, + }, fname) + shada_eq({ + { + timestamp = 0, + type = 8, + value = { c = -200, f = { 'foo' }, l = 2, n = ('A'):byte() }, + }, + { + timestamp = 0, + type = 8, + value = { c = -200, f = { 'foo' }, l = 2, n = ('A'):byte() }, + }, + }, fname_tmp) end) it('event FileWriteCmd', function() reset() - nvim('set_var', 'shada#add_own_header', 0) - curbuf('set_lines', 0, 1, true, { + api.nvim_set_var('shada#add_own_header', 0) + api.nvim_buf_set_lines(0, 0, 1, true, { 'Jump with timestamp ' .. epoch .. ':', ' % Key________ Description Value', - ' + n name \'A\'', + " + n name 'A'", ' + f file name ["foo"]', ' + l line number 2', ' + c column -200', 'Jump with timestamp ' .. epoch .. ':', ' % Key________ Description Value', - ' + n name \'A\'', + " + n name 'A'", ' + f file name ["foo"]', ' + l line number 2', ' + c column -200', @@ -2332,40 +2810,46 @@ describe('plugin/shada.vim', function() eq(table.concat({ 'Jump with timestamp ' .. epoch .. ':', ' % Key________ Description Value', - ' + n name \'A\'', + " + n name 'A'", }, eol) .. eol, read_file(fname .. '.tst')) - shada_eq({{ - timestamp=0, - type=8, - value={n=('A'):byte()}, - }}, fname) - shada_eq({{ - timestamp=0, - type=8, - value={n=('A'):byte()}, - }}, fname_tmp) + shada_eq( + { { + timestamp = 0, + type = 8, + value = { n = ('A'):byte() }, + } }, + fname + ) + shada_eq( + { { + timestamp = 0, + type = 8, + value = { n = ('A'):byte() }, + } }, + fname_tmp + ) end) it('event FileAppendCmd', function() reset() - nvim('set_var', 'shada#add_own_header', 0) - curbuf('set_lines', 0, 1, true, { + api.nvim_set_var('shada#add_own_header', 0) + api.nvim_buf_set_lines(0, 0, 1, true, { 'Jump with timestamp ' .. epoch .. ':', ' % Key________ Description Value', - ' + n name \'A\'', + " + n name 'A'", ' + f file name ["foo"]', ' + l line number 2', ' + c column -200', 'Jump with timestamp ' .. epoch .. ':', ' % Key________ Description Value', - ' + n name \'A\'', + " + n name 'A'", ' + f file name ["foo"]', ' + l line number 2', ' + c column -200', }) - funcs.writefile({''}, fname .. '.tst', 'b') - funcs.writefile({''}, fname, 'b') - funcs.writefile({''}, fname_tmp, 'b') + fn.writefile({ '' }, fname .. '.tst', 'b') + fn.writefile({ '' }, fname, 'b') + fn.writefile({ '' }, fname_tmp, 'b') nvim_command('1,3w >> ' .. fname .. '.tst') nvim_command('1,3w >> ' .. fname) nvim_command('1,3w >> ' .. fname_tmp) @@ -2376,59 +2860,67 @@ describe('plugin/shada.vim', function() eq(table.concat({ 'Jump with timestamp ' .. epoch .. ':', ' % Key________ Description Value', - ' + n name \'A\'', + " + n name 'A'", 'Jump with timestamp ' .. epoch .. ':', ' % Key________ Description Value', - ' + n name \'A\'', + " + n name 'A'", ' + f file name ["foo"]', ' + l line number 2', ' + c column -200', 'Jump with timestamp ' .. epoch .. ':', ' % Key________ Description Value', - ' + n name \'A\'', + " + n name 'A'", ' + f file name ["foo"]', ' + l line number 2', ' + c column -200', }, eol) .. eol, read_file(fname .. '.tst')) - shada_eq({{ - timestamp=0, - type=8, - value={n=('A'):byte()}, - }, { - timestamp=0, - type=8, - value={c=-200, f={'foo'}, l=2, n=('A'):byte()}, - }, { - timestamp=0, - type=8, - value={c=-200, f={'foo'}, l=2, n=('A'):byte()}, - }}, fname) - shada_eq({{ - timestamp=0, - type=8, - value={n=('A'):byte()}, - }, { - timestamp=0, - type=8, - value={c=-200, f={'foo'}, l=2, n=('A'):byte()}, - }, { - timestamp=0, - type=8, - value={c=-200, f={'foo'}, l=2, n=('A'):byte()}, - }}, fname_tmp) + shada_eq({ + { + timestamp = 0, + type = 8, + value = { n = ('A'):byte() }, + }, + { + timestamp = 0, + type = 8, + value = { c = -200, f = { 'foo' }, l = 2, n = ('A'):byte() }, + }, + { + timestamp = 0, + type = 8, + value = { c = -200, f = { 'foo' }, l = 2, n = ('A'):byte() }, + }, + }, fname) + shada_eq({ + { + timestamp = 0, + type = 8, + value = { n = ('A'):byte() }, + }, + { + timestamp = 0, + type = 8, + value = { c = -200, f = { 'foo' }, l = 2, n = ('A'):byte() }, + }, + { + timestamp = 0, + type = 8, + value = { c = -200, f = { 'foo' }, l = 2, n = ('A'):byte() }, + }, + }, fname_tmp) end) it('event SourceCmd', function() reset(fname) finally(function() - nvim_command('set shadafile=NONE') -- Avoid writing shada file on exit + nvim_command('set shadafile=NONE') -- Avoid writing shada file on exit end) wshada('\004\000\006\146\000\196\002ab') wshada_tmp('\004\001\006\146\000\196\002bc') eq(0, exc_exec('source ' .. fname)) eq(0, exc_exec('source ' .. fname_tmp)) - eq('bc', funcs.histget(':', -1)) - eq('ab', funcs.histget(':', -2)) + eq('bc', fn.histget(':', -1)) + eq('ab', fn.histget(':', -2)) end) end) @@ -2439,10 +2931,10 @@ describe('ftplugin/shada.vim', function() it('sets indentexpr correctly', function() nvim_command('filetype plugin indent on') nvim_command('setlocal filetype=shada') - funcs.setline(1, { + fn.setline(1, { 'Jump with timestamp ' .. epoch .. ':', '% Key________ Description Value', - '+ n name \'A\'', + "+ n name 'A'", '+ f file name "foo"', '+ l line number 2', '+ c column 200', @@ -2450,7 +2942,7 @@ describe('ftplugin/shada.vim', function() '+ mYYYYYYYYYY 10', 'Register with timestamp ' .. epoch .. ':', '% Key Description Value', - '+ n name \' \'', + "+ n name ' '", '+ rc contents @', '| - "abcdefghijklmnopqrstuvwxyz"', '| - "abcdefghijklmnopqrstuvwxyz"', @@ -2479,7 +2971,7 @@ describe('ftplugin/shada.vim', function() eq({ 'Jump with timestamp ' .. epoch .. ':', ' % Key________ Description Value', - ' + n name \'A\'', + " + n name 'A'", ' + f file name "foo"', ' + l line number 2', ' + c column 200', @@ -2487,7 +2979,7 @@ describe('ftplugin/shada.vim', function() ' + mYYYYYYYYYY 10', 'Register with timestamp ' .. epoch .. ':', ' % Key Description Value', - ' + n name \' \'', + " + n name ' '", ' + rc contents @', ' | - "abcdefghijklmnopqrstuvwxyz"', ' | - "abcdefghijklmnopqrstuvwxyz"', @@ -2511,34 +3003,34 @@ describe('ftplugin/shada.vim', function() ' + f file name 20', ' + l line number 1', ' + c column 0', - }, funcs.getline(1, funcs.line('$'))) + }, fn.getline(1, fn.line('$'))) end) it('sets options correctly', function() nvim_command('filetype plugin indent on') nvim_command('setlocal filetype=shada') - eq(true, nvim('get_option_value', 'expandtab', {})) - eq(2, nvim('get_option_value', 'tabstop', {})) - eq(2, nvim('get_option_value', 'softtabstop', {})) - eq(2, nvim('get_option_value', 'shiftwidth', {})) + eq(true, api.nvim_get_option_value('expandtab', {})) + eq(2, api.nvim_get_option_value('tabstop', {})) + eq(2, api.nvim_get_option_value('softtabstop', {})) + eq(2, api.nvim_get_option_value('shiftwidth', {})) end) it('sets indentkeys correctly', function() nvim_command('filetype plugin indent on') nvim_command('setlocal filetype=shada') - funcs.setline(1, ' Replacement with timestamp ' .. epoch) + fn.setline(1, ' Replacement with timestamp ' .. epoch) nvim_feed('ggA:\027') - eq('Replacement with timestamp ' .. epoch .. ':', curbuf('get_lines', 0, 1, true)[1]) + eq('Replacement with timestamp ' .. epoch .. ':', api.nvim_buf_get_lines(0, 0, 1, true)[1]) nvim_feed('o-\027') - eq({' -'}, curbuf('get_lines', 1, 2, true)) + eq({ ' -' }, api.nvim_buf_get_lines(0, 1, 2, true)) nvim_feed('ggO+\027') - eq({'+'}, curbuf('get_lines', 0, 1, true)) + eq({ '+' }, api.nvim_buf_get_lines(0, 0, 1, true)) nvim_feed('GO*\027') - eq({' *'}, curbuf('get_lines', 2, 3, true)) + eq({ ' *' }, api.nvim_buf_get_lines(0, 2, 3, true)) nvim_feed('ggO /\027') - eq({' /'}, curbuf('get_lines', 0, 1, true)) + eq({ ' /' }, api.nvim_buf_get_lines(0, 0, 1, true)) nvim_feed('ggOx\027') - eq({'x'}, curbuf('get_lines', 0, 1, true)) + eq({ 'x' }, api.nvim_buf_get_lines(0, 0, 1, true)) end) end) @@ -2552,24 +3044,24 @@ describe('syntax/shada.vim', function() nvim_command('set laststatus&') local screen = Screen.new(60, 37) screen:set_default_attr_ids { - [1] = {bold = true, foreground = Screen.colors.Brown}; - [2] = {foreground = tonumber('0x6a0dad')}; - [3] = {foreground = Screen.colors.Fuchsia}; - [4] = {foreground = Screen.colors.Blue1}; - [5] = {bold = true, foreground = Screen.colors.SeaGreen4}; - [6] = {foreground = Screen.colors.SlateBlue}; - [7] = {bold = true, reverse = true}; - [8] = {bold = true, foreground = Screen.colors.Blue}; + [1] = { bold = true, foreground = Screen.colors.Brown }, + [2] = { foreground = tonumber('0x6a0dad') }, + [3] = { foreground = Screen.colors.Fuchsia }, + [4] = { foreground = Screen.colors.Blue1 }, + [5] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [6] = { foreground = Screen.colors.SlateBlue }, + [7] = { bold = true, reverse = true }, + [8] = { bold = true, foreground = Screen.colors.Blue }, } screen:attach() - curbuf('set_lines', 0, 1, true, { + api.nvim_buf_set_lines(0, 0, 1, true, { 'Header with timestamp ' .. epoch .. ':', ' % Key Value', ' + t "test"', 'Jump with timestamp ' .. epoch .. ':', ' % Key________ Description Value', - ' + n name \'A\'', + " + n name 'A'", ' + f file name ["foo"]', ' + l line number 2', ' + c column -200', @@ -2598,7 +3090,8 @@ describe('syntax/shada.vim', function() ' % Key Description________ Value', ' + se place cursor at end TRUE', }) - screen:expect{grid=[=[ + screen:expect { + grid = [=[ {1:^Header} with timestamp 1970{1:-}01{1:-}01{1:T}00{1::}00{1::}00: | {2: % Key Value} | {1: +} {3:t } {1:"}{3:test}{1:"} | @@ -2636,7 +3129,8 @@ describe('syntax/shada.vim', function() {8:~ }| {7:[No Name] [+] }| | - ]=]} + ]=], + } nvim_command([[ function GetSyntax() @@ -2657,15 +3151,20 @@ describe('syntax/shada.vim', function() return lines endfunction ]]) - local hname = function(s) return {{'ShaDaEntryHeader', 'ShaDaEntryName'}, - s} end - local h = function(s) return {{'ShaDaEntryHeader'}, s} end - local htsnum = function(s) return { - {'ShaDaEntryHeader', 'ShaDaEntryTimestamp', 'ShaDaEntryTimestampNumber'}, - s - } end + local hname = function(s) + return { { 'ShaDaEntryHeader', 'ShaDaEntryName' }, s } + end + local h = function(s) + return { { 'ShaDaEntryHeader' }, s } + end + local htsnum = function(s) + return { + { 'ShaDaEntryHeader', 'ShaDaEntryTimestamp', 'ShaDaEntryTimestampNumber' }, + s, + } + end local synhtssep = function(s) - return {{'ShaDaEntryHeader', 'ShaDaEntryTimestamp'}, s} + return { { 'ShaDaEntryHeader', 'ShaDaEntryTimestamp' }, s } end local synepoch = { year = htsnum(os.date('%Y', 0)), @@ -2675,255 +3174,435 @@ describe('syntax/shada.vim', function() minute = htsnum(os.date('%M', 0)), second = htsnum(os.date('%S', 0)), } - local msh = function(s) return {{'ShaDaEntryMapShort', - 'ShaDaEntryMapHeader'}, s} end - local mlh = function(s) return {{'ShaDaEntryMapLong', - 'ShaDaEntryMapHeader'}, s} end - local ah = function(s) return {{'ShaDaEntryArray', - 'ShaDaEntryArrayHeader'}, s} end + local msh = function(s) + return { + { 'ShaDaEntryMapShort', 'ShaDaEntryMapHeader' }, + s, + } + end + local mlh = function(s) + return { { 'ShaDaEntryMapLong', 'ShaDaEntryMapHeader' }, s } + end + local ah = function(s) + return { { 'ShaDaEntryArray', 'ShaDaEntryArrayHeader' }, s } + end -- luacheck: ignore - local mses = function(s) return {{'ShaDaEntryMapShort', - 'ShaDaEntryMapShortEntryStart'}, s} end - local mles = function(s) return {{'ShaDaEntryMapLong', - 'ShaDaEntryMapLongEntryStart'}, s} end - local act = funcs.GetSyntax() + local mses = function(s) + return { + { + 'ShaDaEntryMapShort', + 'ShaDaEntryMapShortEntryStart', + }, + s, + } + end + local mles = function(s) + return { + { 'ShaDaEntryMapLong', 'ShaDaEntryMapLongEntryStart' }, + s, + } + end + local act = fn.GetSyntax() local ms = function(syn) return { - {'ShaDaEntryMap' .. syn, 'ShaDaEntryMap' .. syn .. 'EntryStart'}, ' + ' + { 'ShaDaEntryMap' .. syn, 'ShaDaEntryMap' .. syn .. 'EntryStart' }, + ' + ', } end local as = function() - return {{'ShaDaEntryArray', 'ShaDaEntryArrayEntryStart'}, ' - '} + return { { 'ShaDaEntryArray', 'ShaDaEntryArrayEntryStart' }, ' - ' } + end + local ad = function(s) + return { + { 'ShaDaEntryArray', 'ShaDaEntryArrayDescription' }, + s, + } end - local ad = function(s) return {{'ShaDaEntryArray', - 'ShaDaEntryArrayDescription'}, s} end local mbas = function(syn) return { - {'ShaDaEntryMap' .. syn, 'ShaDaEntryMapBinArrayStart'}, - ' | - ' + { 'ShaDaEntryMap' .. syn, 'ShaDaEntryMapBinArrayStart' }, + ' | - ', + } + end + local msk = function(s) + return { + { 'ShaDaEntryMapShort', 'ShaDaEntryMapShortKey' }, + s, + } + end + local mlk = function(s) + return { + { 'ShaDaEntryMapLong', 'ShaDaEntryMapLongKey' }, + s, } end - local msk = function(s) return {{'ShaDaEntryMapShort', - 'ShaDaEntryMapShortKey'}, s} end - local mlk = function(s) return {{'ShaDaEntryMapLong', - 'ShaDaEntryMapLongKey'}, s} end - local mld = function(s) return {{'ShaDaEntryMapLong', - 'ShaDaEntryMapLongDescription'}, s} end - local c = function(s) return {{'ShaDaComment'}, s} end + local mld = function(s) + return { + { 'ShaDaEntryMapLong', 'ShaDaEntryMapLongDescription' }, + s, + } + end + local c = function(s) + return { { 'ShaDaComment' }, s } + end local exp = { { - hname('Header'), h(' with timestamp '), - synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'), - synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'), - synepoch.minute, synhtssep(':'), synepoch.second, h(':'), + hname('Header'), + h(' with timestamp '), + synepoch.year, + synhtssep('-'), + synepoch.month, + synhtssep('-'), + synepoch.day, + synhtssep('T'), + synepoch.hour, + synhtssep(':'), + synepoch.minute, + synhtssep(':'), + synepoch.second, + h(':'), }, { msh(' % Key Value'), }, { - ms('Short'), msk('t '), - {{'ShaDaEntryMapShort', 'ShaDaMsgpackBinaryString', - 'ShaDaMsgpackStringQuotes'}, '"'}, - {{'ShaDaEntryMapShort', 'ShaDaMsgpackBinaryString'}, 'test'}, - {{'ShaDaEntryMapShort', 'ShaDaMsgpackStringQuotes'}, '"'}, + ms('Short'), + msk('t '), + { + { 'ShaDaEntryMapShort', 'ShaDaMsgpackBinaryString', 'ShaDaMsgpackStringQuotes' }, + '"', + }, + { { 'ShaDaEntryMapShort', 'ShaDaMsgpackBinaryString' }, 'test' }, + { { 'ShaDaEntryMapShort', 'ShaDaMsgpackStringQuotes' }, '"' }, }, { - hname('Jump'), h(' with timestamp '), - synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'), - synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'), - synepoch.minute, synhtssep(':'), synepoch.second, h(':'), + hname('Jump'), + h(' with timestamp '), + synepoch.year, + synhtssep('-'), + synepoch.month, + synhtssep('-'), + synepoch.day, + synhtssep('T'), + synepoch.hour, + synhtssep(':'), + synepoch.minute, + synhtssep(':'), + synepoch.second, + h(':'), }, { mlh(' % Key________ Description Value'), }, { - ms('Long'), mlk('n '), mld('name '), - {{'ShaDaEntryMapLong', 'ShaDaMsgpackCharacter'}, '\'A\''}, + ms('Long'), + mlk('n '), + mld('name '), + { { 'ShaDaEntryMapLong', 'ShaDaMsgpackCharacter' }, "'A'" }, }, { - ms('Long'), mlk('f '), mld('file name '), - {{'ShaDaEntryMapLong', 'ShaDaMsgpackArray', - 'ShaDaMsgpackArrayBraces'}, '['}, - {{'ShaDaEntryMapLong', 'ShaDaMsgpackArray', 'ShaDaMsgpackBinaryString', - 'ShaDaMsgpackStringQuotes'}, '"'}, - {{'ShaDaEntryMapLong', 'ShaDaMsgpackArray', 'ShaDaMsgpackBinaryString'}, - 'foo'}, - {{'ShaDaEntryMapLong', 'ShaDaMsgpackArray', 'ShaDaMsgpackStringQuotes'}, - '"'}, - {{'ShaDaEntryMapLong', 'ShaDaMsgpackArrayBraces'}, ']'}, + ms('Long'), + mlk('f '), + mld('file name '), + { { 'ShaDaEntryMapLong', 'ShaDaMsgpackArray', 'ShaDaMsgpackArrayBraces' }, '[' }, + { + { + 'ShaDaEntryMapLong', + 'ShaDaMsgpackArray', + 'ShaDaMsgpackBinaryString', + 'ShaDaMsgpackStringQuotes', + }, + '"', + }, + { { 'ShaDaEntryMapLong', 'ShaDaMsgpackArray', 'ShaDaMsgpackBinaryString' }, 'foo' }, + { { 'ShaDaEntryMapLong', 'ShaDaMsgpackArray', 'ShaDaMsgpackStringQuotes' }, '"' }, + { { 'ShaDaEntryMapLong', 'ShaDaMsgpackArrayBraces' }, ']' }, }, { - ms('Long'), mlk('l '), mld('line number '), - {{'ShaDaEntryMapLong', 'ShaDaMsgpackInteger'}, '2'}, + ms('Long'), + mlk('l '), + mld('line number '), + { { 'ShaDaEntryMapLong', 'ShaDaMsgpackInteger' }, '2' }, }, { - ms('Long'), mlk('c '), mld('column '), - {{'ShaDaEntryMapLong', 'ShaDaMsgpackInteger'}, '-200'}, + ms('Long'), + mlk('c '), + mld('column '), + { { 'ShaDaEntryMapLong', 'ShaDaMsgpackInteger' }, '-200' }, }, { - hname('Register'), h(' with timestamp '), - synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'), - synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'), - synepoch.minute, synhtssep(':'), synepoch.second, h(':'), + hname('Register'), + h(' with timestamp '), + synepoch.year, + synhtssep('-'), + synepoch.month, + synhtssep('-'), + synepoch.day, + synhtssep('T'), + synepoch.hour, + synhtssep(':'), + synepoch.minute, + synhtssep(':'), + synepoch.second, + h(':'), }, { mlh(' % Key Description Value'), }, { - ms('Long'), mlk('rc '), mld('contents '), - {{'ShaDaEntryMapLong', 'ShaDaMsgpackMultilineArray'}, '@'}, + ms('Long'), + mlk('rc '), + mld('contents '), + { { 'ShaDaEntryMapLong', 'ShaDaMsgpackMultilineArray' }, '@' }, }, { mbas('Long'), - {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackMapBraces'}, - '{'}, - {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString', - 'ShaDaMsgpackStringQuotes'}, '"'}, - {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString'}, - 'abcdefghijklmnopqrstuvwxyz'}, - {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackStringQuotes'}, - '"'}, - {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackColon'}, ':'}, - {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap'}, ' '}, - {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackFloat'}, '1.0'}, - {{'ShaDaEntryMapLong', 'ShaDaMsgpackMapBraces'}, '}'}, + { { 'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackMapBraces' }, '{' }, + { + { + 'ShaDaEntryMapLong', + 'ShaDaMsgpackMap', + 'ShaDaMsgpackBinaryString', + 'ShaDaMsgpackStringQuotes', + }, + '"', + }, + { + { 'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString' }, + 'abcdefghijklmnopqrstuvwxyz', + }, + { { 'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackStringQuotes' }, '"' }, + { { 'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackColon' }, ':' }, + { { 'ShaDaEntryMapLong', 'ShaDaMsgpackMap' }, ' ' }, + { { 'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackFloat' }, '1.0' }, + { { 'ShaDaEntryMapLong', 'ShaDaMsgpackMapBraces' }, '}' }, }, { - ms('Long'), mlk('rt '), mld('type '), - {{'ShaDaEntryMapLong', 'ShaDaMsgpackShaDaKeyword'}, 'CHARACTERWISE'}, + ms('Long'), + mlk('rt '), + mld('type '), + { { 'ShaDaEntryMapLong', 'ShaDaMsgpackShaDaKeyword' }, 'CHARACTERWISE' }, }, { - ms('Long'), mlk('rt '), mld('type '), - {{'ShaDaEntryMapLong', 'ShaDaMsgpackShaDaKeyword'}, 'LINEWISE'}, + ms('Long'), + mlk('rt '), + mld('type '), + { { 'ShaDaEntryMapLong', 'ShaDaMsgpackShaDaKeyword' }, 'LINEWISE' }, }, { - ms('Long'), mlk('rt '), mld('type '), - {{'ShaDaEntryMapLong', 'ShaDaMsgpackShaDaKeyword'}, 'BLOCKWISE'}, + ms('Long'), + mlk('rt '), + mld('type '), + { { 'ShaDaEntryMapLong', 'ShaDaMsgpackShaDaKeyword' }, 'BLOCKWISE' }, }, { - hname('Replacement string'), h(' with timestamp '), - synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'), - synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'), - synepoch.minute, synhtssep(':'), synepoch.second, h(':'), + hname('Replacement string'), + h(' with timestamp '), + synepoch.year, + synhtssep('-'), + synepoch.month, + synhtssep('-'), + synepoch.day, + synhtssep('T'), + synepoch.hour, + synhtssep(':'), + synepoch.minute, + synhtssep(':'), + synepoch.second, + h(':'), }, { ah(' @ Description__________ Value'), }, { - as(), ad(':s replacement string '), - {{'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword'}, 'CMD'}, + as(), + ad(':s replacement string '), + { { 'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword' }, 'CMD' }, }, { - as(), ad(':s replacement string '), - {{'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword'}, 'SEARCH'}, + as(), + ad(':s replacement string '), + { { 'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword' }, 'SEARCH' }, }, { - as(), ad(':s replacement string '), - {{'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword'}, 'EXPR'}, + as(), + ad(':s replacement string '), + { { 'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword' }, 'EXPR' }, }, { - as(), ad(':s replacement string '), - {{'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword'}, 'INPUT'}, + as(), + ad(':s replacement string '), + { { 'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword' }, 'INPUT' }, }, { - as(), ad(':s replacement string '), - {{'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword'}, 'DEBUG'}, + as(), + ad(':s replacement string '), + { { 'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword' }, 'DEBUG' }, }, { - hname('Buffer list'), h(' with timestamp '), - synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'), - synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'), - synepoch.minute, synhtssep(':'), synepoch.second, h(':'), + hname('Buffer list'), + h(' with timestamp '), + synepoch.year, + synhtssep('-'), + synepoch.month, + synhtssep('-'), + synepoch.day, + synhtssep('T'), + synepoch.hour, + synhtssep(':'), + synepoch.minute, + synhtssep(':'), + synepoch.second, + h(':'), }, { c(' # Expected array of maps'), }, { - {{'ShaDaEntryRawMsgpack'}, ' = '}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackArrayBraces'}, '['}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackMapBraces'}, - '{'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackString'}, '='}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString', - 'ShaDaMsgpackStringQuotes'}, '"'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString'}, - 'a'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackStringQuotes'}, - '"'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackColon'}, ':'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap'}, ' '}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackExt'}, '+('}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackExt', - 'ShaDaMsgpackExtType'}, '10'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackExt'}, ')'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString', - 'ShaDaMsgpackStringQuotes'}, '"'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString'}, - 'ac'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString', - 'ShaDaMsgpackBinaryStringEscape'}, - '\\0'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString'}, - 'df'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString', - 'ShaDaMsgpackBinaryStringEscape'}, - '\\n'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString'}, - 'gi'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString', - 'ShaDaMsgpackBinaryStringEscape'}, - '\\"'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString'}, - 'tt\\.'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackStringQuotes'}, - '"'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackComma'}, ','}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap'}, ' '}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackKeyword'}, - 'TRUE'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackColon'}, ':'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap'}, ' '}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackKeyword'}, - 'FALSE'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackMapBraces'}, '}'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackComma'}, ','}, - {{'ShaDaMsgpackArray'}, ' '}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackArrayBraces'}, - '['}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackKeyword'}, - 'NIL'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackComma'}, ','}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray'}, ' '}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackExt'}, '+('}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackExt', - 'ShaDaMsgpackExtType'}, '-10'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackExt'}, ')'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackBinaryString', - 'ShaDaMsgpackStringQuotes'}, '"'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackStringQuotes'}, - '"'}, - {{'ShaDaMsgpackArray', 'ShaDaMsgpackArrayBraces'}, ']'}, - {{'ShaDaMsgpackArrayBraces'}, ']'}, + { { 'ShaDaEntryRawMsgpack' }, ' = ' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackArrayBraces' }, '[' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackMapBraces' }, '{' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackString' }, '=' }, + { + { + 'ShaDaMsgpackArray', + 'ShaDaMsgpackMap', + 'ShaDaMsgpackBinaryString', + 'ShaDaMsgpackStringQuotes', + }, + '"', + }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString' }, 'a' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackStringQuotes' }, '"' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackColon' }, ':' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap' }, ' ' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackExt' }, '+(' }, + { + { + 'ShaDaMsgpackArray', + 'ShaDaMsgpackMap', + 'ShaDaMsgpackExt', + 'ShaDaMsgpackExtType', + }, + '10', + }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackExt' }, ')' }, + { + { + 'ShaDaMsgpackArray', + 'ShaDaMsgpackMap', + 'ShaDaMsgpackBinaryString', + 'ShaDaMsgpackStringQuotes', + }, + '"', + }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString' }, 'ac' }, + { + { + 'ShaDaMsgpackArray', + 'ShaDaMsgpackMap', + 'ShaDaMsgpackBinaryString', + 'ShaDaMsgpackBinaryStringEscape', + }, + '\\0', + }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString' }, 'df' }, + { + { + 'ShaDaMsgpackArray', + 'ShaDaMsgpackMap', + 'ShaDaMsgpackBinaryString', + 'ShaDaMsgpackBinaryStringEscape', + }, + '\\n', + }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString' }, 'gi' }, + { + { + 'ShaDaMsgpackArray', + 'ShaDaMsgpackMap', + 'ShaDaMsgpackBinaryString', + 'ShaDaMsgpackBinaryStringEscape', + }, + '\\"', + }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString' }, 'tt\\.' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackStringQuotes' }, '"' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackComma' }, ',' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap' }, ' ' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackKeyword' }, 'TRUE' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackColon' }, ':' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap' }, ' ' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackKeyword' }, 'FALSE' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackMapBraces' }, '}' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackComma' }, ',' }, + { { 'ShaDaMsgpackArray' }, ' ' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackArrayBraces' }, '[' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackKeyword' }, 'NIL' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackComma' }, ',' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackArray' }, ' ' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackExt' }, '+(' }, + { + { + 'ShaDaMsgpackArray', + 'ShaDaMsgpackArray', + 'ShaDaMsgpackExt', + 'ShaDaMsgpackExtType', + }, + '-10', + }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackExt' }, ')' }, + { + { + 'ShaDaMsgpackArray', + 'ShaDaMsgpackArray', + 'ShaDaMsgpackBinaryString', + 'ShaDaMsgpackStringQuotes', + }, + '"', + }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackStringQuotes' }, '"' }, + { { 'ShaDaMsgpackArray', 'ShaDaMsgpackArrayBraces' }, ']' }, + { { 'ShaDaMsgpackArrayBraces' }, ']' }, }, { - hname('Buffer list'), h(' with timestamp '), - synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'), - synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'), - synepoch.minute, synhtssep(':'), synepoch.second, h(':'), + hname('Buffer list'), + h(' with timestamp '), + synepoch.year, + synhtssep('-'), + synepoch.month, + synhtssep('-'), + synepoch.day, + synhtssep('T'), + synepoch.hour, + synhtssep(':'), + synepoch.minute, + synhtssep(':'), + synepoch.second, + h(':'), }, { mlh(' % Key Description Value'), }, - { - }, + {}, { mlh(' % Key Description Value'), }, { - hname('Header'), h(' with timestamp '), - synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'), - synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'), - synepoch.minute, synhtssep(':'), synepoch.second, h(':'), + hname('Header'), + h(' with timestamp '), + synepoch.year, + synhtssep('-'), + synepoch.month, + synhtssep('-'), + synepoch.day, + synhtssep('T'), + synepoch.hour, + synhtssep(':'), + synepoch.minute, + synhtssep(':'), + synepoch.second, + h(':'), }, { mlh(' % Key Description________ Value'), @@ -2932,7 +3611,7 @@ describe('syntax/shada.vim', function() mles(' + '), mlk('se '), mld('place cursor at end '), - {{'ShaDaEntryMapLong', 'ShaDaMsgpackKeyword'}, 'TRUE'}, + { { 'ShaDaEntryMapLong', 'ShaDaMsgpackKeyword' }, 'TRUE' }, }, } eq(exp, act) diff --git a/test/functional/plugin/tohtml_spec.lua b/test/functional/plugin/tohtml_spec.lua new file mode 100644 index 0000000000..2ac0fe1fa3 --- /dev/null +++ b/test/functional/plugin/tohtml_spec.lua @@ -0,0 +1,372 @@ +local Screen = require('test.functional.ui.screen') +local helpers = require('test.functional.helpers')(after_each) + +local clear = helpers.clear +local exec = helpers.exec +local exec_lua = helpers.exec_lua +local eq = helpers.eq +local fn = helpers.fn +local api = helpers.api +local insert = helpers.insert + +local function html_syntax_match() + local styles = + vim.split(api.nvim_exec2([[/<style>/+,/<\/style>/-p]], { output = true }).output, '\n') + local attrnames = { + ['font%-weight: bold'] = 'bold', + ['text%-decoration%-line: [^;]*underline'] = 'underline', + ['font%-style: italic'] = 'italic', + ['text%-decoration%-line: [^;]*line%-through'] = 'strikethrough', + } + local hls = {} + for _, style in ipairs(styles) do + local attr = {} + for match, attrname in pairs(attrnames) do + if style:find(match) then + ---@type boolean + attr[attrname] = true + end + end + if style:find('text%-decoration%-style: wavy') and attr.underline then + ---@type boolean + attr.underline = nil + attr.undercurl = true + end + attr.bg = style:match('background%-color: #(%x+)') + if attr.bg then + attr.bg = tonumber(attr.bg, 16) + end + attr.fg = style:match('[^%-]color: #(%x+)') + if attr.fg then + attr.fg = tonumber(attr.fg, 16) + end + if style:match('^%.(%w+)') then + ---@type table + hls[style:match('^%.(%w+)')] = attr + end + end + local whitelist = { + 'fg', + 'bg', + --'sp', + --'blend', + 'bold', + --'standout', + 'underline', + 'undercurl', + --'underdouble', + --'underdotted', + --'underdashed', + 'strikethrough', + 'italic', + --'reverse', + --'nocombine', + } + for name, attrs_old in + pairs(api.nvim_get_hl(0, { link = true }) --[[@as table<string,table>]]) + do + ---@type table + local other = hls[name:gsub('%.', '-'):gsub('@', '-')] + if other then + local attrs = {} + for _, attrname in ipairs(whitelist) do + ---@type table + attrs[attrname] = attrs_old[attrname] + end + eq(attrs, other) + end + end + return hls +end + +local function html_to_extmarks() + local buf = api.nvim_get_current_buf() + local ns = api.nvim_create_namespace 'test-namespace' + api.nvim_buf_clear_namespace(buf, ns, 0, -1) + exec 'silent! norm! ggd/^<pre>$\rddG3dk' + local stack = {} + exec [[set filetype=]] + exec [[silent! %s/</¤/g]] + exec [[silent! %s/"/"/g]] + exec [[silent! %s/&/\&/g]] + exec [[silent! %s/>/>/g]] + exec [[silent! %s/</</g]] + for _, match in + ipairs( + fn.matchbufline(buf, [[¤span class="\([^"]\+\)">\|¤/span>]], 1, '$', { submatches = true }) --[[@as (table[])]] + ) + do + if match.text == '¤/span>' then + local val = table.remove(stack) + api.nvim_buf_set_extmark(buf, ns, val.lnum - 1, val.byteidx, { + hl_group = val.submatches[1], + end_row = match.lnum - 1, + end_col = match.byteidx, + }) + else + table.insert(stack, match) + end + end + exec [[silent! %s/¤\/span>//g]] + exec [[silent! %s/¤span[^>]*>//g]] +end + +---@param screen test.functional.ui.screen +---@param func function? +local function run_tohtml_and_assert(screen, func) + exec('norm! ggO-;') + screen:expect({ any = vim.pesc('-^;') }) + exec('norm! :\rh') + screen:expect({ any = vim.pesc('^-;') }) + local expected = screen:get_snapshot() + do + (func or exec)('TOhtml') + end + exec('only') + html_syntax_match() + html_to_extmarks() + exec('norm! gg0f;') + screen:expect({ any = vim.pesc('-^;') }) + exec('norm! :\rh') + screen:expect({ grid = expected.grid, attr_ids = expected.attr_ids }) +end + +describe(':TOhtml', function() + --- @type test.functional.ui.screen + local screen + before_each(function() + clear({ args = { '--clean' } }) + screen = Screen.new(80, 80) + screen:attach({ term_name = 'xterm' }) + exec('colorscheme default') + end) + + it('expected internal html generated', function() + insert([[line]]) + exec('set termguicolors') + local bg = fn.synIDattr(fn.hlID('Normal'), 'bg#', 'gui') + local fg = fn.synIDattr(fn.hlID('Normal'), 'fg#', 'gui') + exec_lua [[ + local outfile = vim.fn.tempname() .. '.html' + local html = require('tohtml').tohtml(0,{title="title",font="dumyfont"}) + vim.fn.writefile(html, outfile) + vim.cmd.split(outfile) + ]] + local out_file = api.nvim_buf_get_name(api.nvim_get_current_buf()) + eq({ + '<!DOCTYPE html>', + '<html>', + '<head>', + '<meta charset="UTF-8">', + '<title>title</title>', + ('<meta name="colorscheme" content="%s"></meta>'):format(api.nvim_get_var('colors_name')), + '<style>', + '* {font-family: dumyfont,monospace}', + ('body {background-color: %s; color: %s}'):format(bg, fg), + '</style>', + '</head>', + '<body style="display: flex">', + '<pre>', + 'line', + '', + '</pre>', + '</body>', + '</html>', + }, fn.readfile(out_file)) + end) + + it('highlight attributes generated', function() + --Make sure to uncomment the attribute in `html_syntax_match()` + exec('hi LINE gui=' .. table.concat({ + 'bold', + 'underline', + 'italic', + 'strikethrough', + }, ',')) + exec('hi UNDERCURL gui=undercurl') + exec('syn keyword LINE line') + exec('syn keyword UNDERCURL undercurl') + insert('line\nundercurl') + run_tohtml_and_assert(screen) + end) + + it('syntax', function() + insert [[ + function main() + print("hello world") + end + ]] + exec('set termguicolors') + exec('syntax enable') + exec('setf lua') + run_tohtml_and_assert(screen) + end) + + it('diff', function() + exec('set diffopt=') + insert [[ + diffadd + nochage + diffchange1 + ]] + exec('new') + insert [[ + nochage + diffchange2 + diffremove + ]] + exec('set diff') + exec('close') + exec('set diff') + run_tohtml_and_assert(screen) + end) + + it('treesitter', function() + insert [[ + function main() + print("hello world") + end + ]] + exec('setf lua') + exec_lua('vim.treesitter.start()') + run_tohtml_and_assert(screen) + end) + + it('matchadd', function() + insert [[ + line + ]] + fn.matchadd('Visual', 'line') + run_tohtml_and_assert(screen) + end) + + describe('conceallevel', function() + local function run(level) + insert([[ + line0 + line1 + line2 + line3 + ]]) + local ns = api.nvim_create_namespace '' + fn.matchadd('Conceal', 'line1', 3, 5, { conceal = 'a' }) + api.nvim_buf_set_extmark(0, ns, 2, 0, { conceal = 'a', end_col = 5 }) + exec(':syntax match Conceal "line3" conceal cchar=a') + exec('set conceallevel=' .. level) + run_tohtml_and_assert(screen) + end + it('conceallevel=0', function() + run(0) + end) + it('conceallevel=1', function() + run(1) + end) + it('conceallevel=2', function() + run(2) + end) + it('conceallevel=3', function() + run(3) + end) + end) + + describe('extmarks', function() + it('virt_text', function() + insert [[ + line1 + line2 + line3 + line4 + ]] + local ns = api.nvim_create_namespace '' + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = { { 'foo' } } }) + api.nvim_buf_set_extmark( + 0, + ns, + 1, + 0, + { virt_text = { { 'foo' } }, virt_text_pos = 'overlay' } + ) + api.nvim_buf_set_extmark(0, ns, 2, 0, { virt_text = { { 'foo' } }, virt_text_pos = 'inline' }) + --api.nvim_buf_set_extmark(0,ns,3,0,{virt_text={{'foo'}},virt_text_pos='right_align'}) + run_tohtml_and_assert(screen) + end) + it('highlight', function() + insert [[ + line1 + ]] + local ns = api.nvim_create_namespace '' + api.nvim_buf_set_extmark(0, ns, 0, 0, { end_col = 2, hl_group = 'Visual' }) + run_tohtml_and_assert(screen) + end) + it('virt_line', function() + insert [[ + line1 + line2 + ]] + local ns = api.nvim_create_namespace '' + api.nvim_buf_set_extmark(0, ns, 1, 0, { end_col = 2, virt_lines = { { { 'foo' } } } }) + run_tohtml_and_assert(screen) + end) + end) + + it('listchars', function() + exec('setlocal list') + exec( + 'setlocal listchars=eol:$,tab:<->,space:-,multispace:++,lead:_,leadmultispace:##,trail:&,nbsp:%' + ) + fn.setline(1, '\tfoo\t') + fn.setline(2, ' foo foo ') + fn.setline(3, ' foo foo ') + fn.setline(4, 'foo\194\160 \226\128\175foo') + run_tohtml_and_assert(screen) + exec('new|only') + fn.setline(1, '\tfoo\t') + exec('setlocal list') + exec('setlocal listchars=tab:a-') + run_tohtml_and_assert(screen) + end) + + it('folds', function() + insert([[ + line1 + line2 + ]]) + exec('set foldtext=foldtext()') + exec('%fo') + run_tohtml_and_assert(screen) + end) + + it('statuscol', function() + local function run() + local buf = api.nvim_get_current_buf() + run_tohtml_and_assert(screen, function() + exec_lua [[ + local outfile = vim.fn.tempname() .. '.html' + local html = require('tohtml').tohtml(0,{number_lines=true}) + vim.fn.writefile(html, outfile) + vim.cmd.split(outfile) + ]] + end) + api.nvim_set_current_buf(buf) + end + insert([[ + line1 + line2 + ]]) + exec('setlocal relativenumber') + run() + exec('setlocal norelativenumber') + exec('setlocal number') + run() + exec('setlocal relativenumber') + run() + exec('setlocal signcolumn=yes:2') + run() + exec('setlocal foldcolumn=2') + run() + exec('setlocal norelativenumber') + run() + exec('setlocal signcolumn=no') + run() + end) +end) diff --git a/test/functional/plugin/tutor_spec.lua b/test/functional/plugin/tutor_spec.lua index bd214e9c03..99538e1db0 100644 --- a/test/functional/plugin/tutor_spec.lua +++ b/test/functional/plugin/tutor_spec.lua @@ -25,7 +25,8 @@ describe(':Tutor', function() end) it('applies {unix:…,win:…} transform', function() - local expected = is_os('win') and [[ + local expected = is_os('win') + and [[ {0: }^ | {0: } 3. To verify that a file was retrieved, cursor back and notice that there | {0: } are now two copies of Lesson 5.3, the original and the retrieved version. | @@ -56,7 +57,8 @@ describe(':Tutor', function() {0: } 5. {2::r !dir} reads the output of the dir command and | {0: } puts it below the cursor position. | {0: } | - ]] or [[ + ]] + or [[ {0: }^ | {0: } 3. To verify that a file was retrieved, cursor back and notice that there | {0: } are now two copies of Lesson 5.3, the original and the retrieved version. | diff --git a/test/functional/plugin/vim_syntax_spec.lua b/test/functional/plugin/vim_syntax_spec.lua new file mode 100644 index 0000000000..9396bbce5c --- /dev/null +++ b/test/functional/plugin/vim_syntax_spec.lua @@ -0,0 +1,40 @@ +local helpers = require('test.functional.helpers')(after_each) +local Screen = require('test.functional.ui.screen') +local clear = helpers.clear +local exec = helpers.exec +local api = helpers.api + +describe('Vimscript syntax highlighting', function() + local screen + + before_each(function() + clear() + helpers.add_builddir_to_rtp() + exec([[ + setfiletype vim + syntax on + ]]) + screen = Screen.new() + screen:set_default_attr_ids({ + [0] = { foreground = Screen.colors.Blue, bold = true }, + [1] = { foreground = Screen.colors.Brown, bold = true }, + [2] = { foreground = tonumber('0x6a0dad') }, + }) + screen:attach() + end) + + it('prefixed boolean options are highlighted properly', function() + api.nvim_buf_set_lines(0, 0, -1, true, { + 'set number incsearch hlsearch', + 'set nonumber noincsearch nohlsearch', + 'set invnumber invincsearch invhlsearch', + }) + screen:expect([[ + {1:^set} {2:number} {2:incsearch} {2:hlsearch} | + {1:set} {2:nonumber} {2:noincsearch} {2:nohlsearch} | + {1:set} {2:invnumber} {2:invincsearch} {2:invhlsearch} | + {0:~ }|*10 + | + ]]) + end) +end) diff --git a/test/functional/preload.lua b/test/functional/preload.lua index 6a5a2e907e..49f1eff0da 100644 --- a/test/functional/preload.lua +++ b/test/functional/preload.lua @@ -3,12 +3,12 @@ -- for more information about this. local helpers = require('test.functional.helpers')(nil) require('test.functional.ui.screen') -local busted = require("busted") +local busted = require('busted') local is_os = helpers.is_os if is_os('win') then local ffi = require('ffi') - ffi.cdef[[ + ffi.cdef [[ typedef int errno_t; errno_t _set_fmode(int mode); ]] @@ -17,10 +17,10 @@ end local testid = (function() local id = 0 - return (function() + return function() id = id + 1 return id - end) + end end)() -- Global before_each. https://github.com/Olivine-Labs/busted/issues/613 @@ -29,13 +29,11 @@ local function before_each(_element, _parent) _G._nvim_test_id = id return nil, true end -busted.subscribe({ 'test', 'start' }, - before_each, - { - -- Ensure our --helper is handled before --output (see busted/runner.lua). - priority = 1, - -- Don't generate a test-id for skipped tests. /shrug - predicate = function (element, _, status) - return not ((element.descriptor == 'pending' or status == 'pending')) - end - }) +busted.subscribe({ 'test', 'start' }, before_each, { + -- Ensure our --helper is handled before --output (see busted/runner.lua). + priority = 1, + -- Don't generate a test-id for skipped tests. /shrug + predicate = function(element, _, status) + return not (element.descriptor == 'pending' or status == 'pending') + end, +}) diff --git a/test/functional/provider/clipboard_spec.lua b/test/functional/provider/clipboard_spec.lua index 0099183302..0c4fd7aaa0 100644 --- a/test/functional/provider/clipboard_spec.lua +++ b/test/functional/provider/clipboard_spec.lua @@ -3,12 +3,13 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert -local feed_command, expect, eq, eval, source = helpers.feed_command, helpers.expect, helpers.eq, helpers.eval, helpers.source +local feed_command, expect, eq, eval, source = + helpers.feed_command, helpers.expect, helpers.eq, helpers.eval, helpers.source local command = helpers.command -local meths = helpers.meths +local api = helpers.api local function basic_register_test(noblock) - insert("some words") + insert('some words') feed('^dwP') expect('some words') @@ -81,9 +82,9 @@ local function basic_register_test(noblock) -- pasting in visual does unnamed delete of visual selection feed('ggdG') - insert("one and two and three") + insert('one and two and three') feed('"ayiwbbviw"ap^viwp$viw"-p') - expect("two and three and one") + expect('two and three and one') end describe('clipboard', function() @@ -93,10 +94,10 @@ describe('clipboard', function() clear() screen = Screen.new(72, 4) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, - [1] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [2] = {bold = true, foreground = Screen.colors.SeaGreen4}, - [3] = {bold = true, reverse = true}; + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [2] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [3] = { bold = true, reverse = true }, }) screen:attach() end) @@ -112,15 +113,13 @@ describe('clipboard', function() feed('"+yl') screen:expect([[ ^a | - {0:~ }| - {0:~ }| + {0:~ }|*2 clipboard: No provider. Try ":checkhealth" or ":h clipboard". | ]]) feed('"+p') screen:expect([[ a^a | - {0:~ }| - {0:~ }| + {0:~ }|*2 clipboard: No provider. Try ":checkhealth" or ":h clipboard". | ]]) end) @@ -132,22 +131,19 @@ describe('clipboard', function() feed('yl') screen:expect([[ ^a | - {0:~ }| - {0:~ }| + {0:~ }|*2 clipboard: No provider. Try ":checkhealth" or ":h clipboard". | ]]) feed(':<CR>') screen:expect([[ ^a | - {0:~ }| - {0:~ }| + {0:~ }|*2 : | ]]) feed('p') screen:expect([[ a^a | - {0:~ }| - {0:~ }| + {0:~ }|*2 : | ]]) end) @@ -157,8 +153,7 @@ describe('clipboard', function() feed_command('redir @+> | :silent echo system("cat CONTRIBUTING.md") | redir END') screen:expect([[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 clipboard: No provider. Try ":checkhealth" or ":h clipboard". | ]]) end) @@ -166,12 +161,14 @@ describe('clipboard', function() it('`:redir @+>|bogus_cmd|redir END` + invalid g:clipboard must not recurse #7184', function() command("let g:clipboard = 'bogus'") feed_command('redir @+> | bogus_cmd | redir END') - screen:expect{grid=[[ + screen:expect { + grid = [[ {3: }| clipboard: No provider. Try ":checkhealth" or ":h clipboard". | {1:E492: Not an editor command: bogus_cmd | redir END} | {2:Press ENTER or type command to continue}^ | - ]]} + ]], + } end) it('invalid g:clipboard shows hint if :redir is not active', function() @@ -184,15 +181,14 @@ describe('clipboard', function() feed_command('let @+="foo"') screen:expect([[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 clipboard: No provider. Try ":checkhealth" or ":h clipboard". | ]]) end) it('valid g:clipboard', function() -- provider#clipboard#Executable() only checks the structure. - meths.set_var('clipboard', { + api.nvim_set_var('clipboard', { ['name'] = 'clippy!', ['copy'] = { ['+'] = 'any command', ['*'] = 'some other' }, ['paste'] = { ['+'] = 'any command', ['*'] = 'some other' }, @@ -238,11 +234,11 @@ describe('clipboard', function() eq('plus', eval("getreg('+')")) command('call setreg("*", "star", "v")') - eq({{'star'}, 'v'}, eval("g:dummy_clipboard_star")) + eq({ { 'star' }, 'v' }, eval('g:dummy_clipboard_star')) command('call setreg("*", "star", "V")') - eq({{'star', ''}, 'V'}, eval("g:dummy_clipboard_star")) + eq({ { 'star', '' }, 'V' }, eval('g:dummy_clipboard_star')) command('call setreg("*", "star", "b")') - eq({{'star', ''}, 'b'}, eval("g:dummy_clipboard_star")) + eq({ { 'star', '' }, 'b' }, eval('g:dummy_clipboard_star')) end) describe('g:clipboard[paste] Vimscript function', function() @@ -310,43 +306,41 @@ describe('clipboard (with fake clipboard.vim)', function() end) it('`:redir @+>` invokes clipboard once-per-message', function() - eq(0, eval("g:clip_called_set")) + eq(0, eval('g:clip_called_set')) feed_command('redir @+> | :silent echo system("cat CONTRIBUTING.md") | redir END') -- Assuming CONTRIBUTING.md has >100 lines. - assert(eval("g:clip_called_set") > 100) + assert(eval('g:clip_called_set') > 100) end) it('`:redir @">` does NOT invoke clipboard', function() -- :redir to a non-clipboard register, with `:set clipboard=unnamed` does -- NOT propagate to the clipboard. This is consistent with Vim. - command("set clipboard=unnamedplus") - eq(0, eval("g:clip_called_set")) + command('set clipboard=unnamedplus') + eq(0, eval('g:clip_called_set')) feed_command('redir @"> | :silent echo system("cat CONTRIBUTING.md") | redir END') - eq(0, eval("g:clip_called_set")) + eq(0, eval('g:clip_called_set')) end) - it('`:redir @+>|bogus_cmd|redir END` must not recurse #7184', - function() + it('`:redir @+>|bogus_cmd|redir END` must not recurse #7184', function() local screen = Screen.new(72, 4) screen:attach() screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, - [1] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, }) feed_command('redir @+> | bogus_cmd | redir END') screen:expect([[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {1:E492: Not an editor command: bogus_cmd | redir END} | ]]) end) it('has independent "* and unnamed registers by default', function() - insert("some words") + insert('some words') feed('^"*dwdw"*P') expect('some ') - eq({{'some '}, 'v'}, eval("g:test_clip['*']")) + eq({ { 'some ' }, 'v' }, eval("g:test_clip['*']")) eq('words', eval("getreg('\"', 1)")) end) @@ -364,31 +358,31 @@ describe('clipboard (with fake clipboard.vim)', function() second line first line]]) -- linewise selection should be encoded as an extra newline - eq({{'third line', ''}, 'V'}, eval("g:test_clip['+']")) - eq({{'second line', ''}, 'V'}, eval("g:test_clip['*']")) + eq({ { 'third line', '' }, 'V' }, eval("g:test_clip['+']")) + eq({ { 'second line', '' }, 'V' }, eval("g:test_clip['*']")) end) it('handles null bytes when pasting and in getreg', function() - insert("some\022000text\n\022000very binary\022000") + insert('some\022000text\n\022000very binary\022000') feed('"*y-+"*p') - eq({{'some\ntext', '\nvery binary\n',''}, 'V'}, eval("g:test_clip['*']")) - expect("some\00text\n\00very binary\00\nsome\00text\n\00very binary\00") + eq({ { 'some\ntext', '\nvery binary\n', '' }, 'V' }, eval("g:test_clip['*']")) + expect('some\00text\n\00very binary\00\nsome\00text\n\00very binary\00') -- test getreg/getregtype eq('some\ntext\n\nvery binary\n\n', eval("getreg('*', 1)")) - eq("V", eval("getregtype('*')")) + eq('V', eval("getregtype('*')")) -- getreg supports three arguments eq('some\ntext\n\nvery binary\n\n', eval("getreg('*', 1, 0)")) - eq({'some\ntext', '\nvery binary\n'}, eval("getreg('*', 1, 1)")) + eq({ 'some\ntext', '\nvery binary\n' }, eval("getreg('*', 1, 1)")) end) it('autodetects regtype', function() feed_command("let g:test_clip['*'] = ['linewise stuff','']") feed_command("let g:test_clip['+'] = ['charwise','stuff']") - eq("V", eval("getregtype('*')")) - eq("v", eval("getregtype('+')")) - insert("just some text") + eq('V', eval("getregtype('*')")) + eq('v', eval("getregtype('+')")) + insert('just some text') feed('"*p"+p') expect([[ just some text @@ -405,12 +399,12 @@ describe('clipboard (with fake clipboard.vim)', function() expect([[ very much blocktext]]) - eq("\0225", eval("getregtype('*')")) + eq('\0225', eval("getregtype('*')")) feed('gg4l<c-v>j4l"+ygg"+P') expect([[ muchvery much ktextblocktext]]) - eq({{' much', 'ktext', ''}, 'b'}, eval("g:test_clip['+']")) + eq({ { ' much', 'ktext', '' }, 'b' }, eval("g:test_clip['+']")) end) it('supports setreg()', function() @@ -434,8 +428,8 @@ describe('clipboard (with fake clipboard.vim)', function() it('supports :let @+ (issue #1427)', function() feed_command("let @+ = 'some'") feed_command("let @* = ' other stuff'") - eq({{'some'}, 'v'}, eval("g:test_clip['+']")) - eq({{' other stuff'}, 'v'}, eval("g:test_clip['*']")) + eq({ { 'some' }, 'v' }, eval("g:test_clip['+']")) + eq({ { ' other stuff' }, 'v' }, eval("g:test_clip['*']")) feed('"+p"*p') expect('some other stuff') feed_command("let @+ .= ' more'") @@ -446,14 +440,13 @@ describe('clipboard (with fake clipboard.vim)', function() it('pastes unnamed register if the provider fails', function() insert('the text') feed('yy') - feed_command("let g:cliperror = 1") + feed_command('let g:cliperror = 1') feed('"*p') expect([[ the text the text]]) end) - describe('with clipboard=unnamed', function() -- the basic behavior of unnamed register should be the same -- even when handled by clipboard provider @@ -466,20 +459,20 @@ describe('clipboard (with fake clipboard.vim)', function() end) it('works with pure text clipboard', function() - feed_command("let g:cliplossy = 1") + feed_command('let g:cliplossy = 1') -- expect failure for block mode basic_register_test(true) end) it('links the "* and unnamed registers', function() -- with cb=unnamed, "* and unnamed will be the same register - insert("some words") + insert('some words') feed('^"*dwdw"*P') expect('words') - eq({{'words'}, 'v'}, eval("g:test_clip['*']")) + eq({ { 'words' }, 'v' }, eval("g:test_clip['*']")) -- "+ shouldn't have changed - eq({''}, eval("g:test_clip['+']")) + eq({ '' }, eval("g:test_clip['+']")) feed_command("let g:test_clip['*'] = ['linewise stuff','']") feed('p') @@ -508,23 +501,23 @@ describe('clipboard (with fake clipboard.vim)', function() end) it('yanks visual selection when pasting', function() - insert("indeed visual") + insert('indeed visual') feed_command("let g:test_clip['*'] = [['clipboard'], 'c']") - feed("viwp") - eq({{'visual'}, 'v'}, eval("g:test_clip['*']")) - expect("indeed clipboard") + feed('viwp') + eq({ { 'visual' }, 'v' }, eval("g:test_clip['*']")) + expect('indeed clipboard') -- explicit "* should do the same feed_command("let g:test_clip['*'] = [['star'], 'c']") feed('viw"*p') - eq({{'clipboard'}, 'v'}, eval("g:test_clip['*']")) - expect("indeed star") + eq({ { 'clipboard' }, 'v' }, eval("g:test_clip['*']")) + expect('indeed star') end) it('unnamed operations work even if the provider fails', function() insert('the text') feed('yy') - feed_command("let g:cliperror = 1") + feed_command('let g:cliperror = 1') feed('p') expect([[ the text @@ -549,10 +542,10 @@ describe('clipboard (with fake clipboard.vim)', function() it('works in the cmdline window', function() feed('q:itext<esc>yy') - eq({{'text', ''}, 'V'}, eval("g:test_clip['*']")) + eq({ { 'text', '' }, 'V' }, eval("g:test_clip['*']")) command("let g:test_clip['*'] = [['star'], 'c']") feed('p') - eq('textstar', meths.get_current_line()) + eq('textstar', api.nvim_get_current_line()) end) it('Block paste works correctly', function() @@ -577,13 +570,13 @@ describe('clipboard (with fake clipboard.vim)', function() it('links the "+ and unnamed registers', function() eq('+', eval('v:register')) - insert("one two") + insert('one two') feed('^"+dwdw"+P') expect('two') - eq({{'two'}, 'v'}, eval("g:test_clip['+']")) + eq({ { 'two' }, 'v' }, eval("g:test_clip['+']")) -- "* shouldn't have changed - eq({''}, eval("g:test_clip['*']")) + eq({ '' }, eval("g:test_clip['*']")) feed_command("let g:test_clip['+'] = ['three']") feed('p') @@ -600,14 +593,14 @@ describe('clipboard (with fake clipboard.vim)', function() text really unnamed really unnamed]]) - eq({{'really unnamed', ''}, 'V'}, eval("g:test_clip['+']")) - eq({{'really unnamed', ''}, 'V'}, eval("g:test_clip['*']")) + eq({ { 'really unnamed', '' }, 'V' }, eval("g:test_clip['+']")) + eq({ { 'really unnamed', '' }, 'V' }, eval("g:test_clip['*']")) -- unnamedplus takes precedence when pasting eq('+', eval('v:register')) feed_command("let g:test_clip['+'] = ['the plus','']") feed_command("let g:test_clip['*'] = ['the star','']") - feed("p") + feed('p') expect([[ text really unnamed @@ -640,14 +633,14 @@ describe('clipboard (with fake clipboard.vim)', function() end) it('supports :put', function() - insert("a line") + insert('a line') feed_command("let g:test_clip['*'] = ['some text']") feed_command("let g:test_clip['+'] = ['more', 'text', '']") - feed_command(":put *") + feed_command(':put *') expect([[ a line some text]]) - feed_command(":put +") + feed_command(':put +') expect([[ a line some text @@ -660,11 +653,11 @@ describe('clipboard (with fake clipboard.vim)', function() screen:attach() feed_command("let g:test_clip['*'] = ['some', 'star data','']") feed_command("let g:test_clip['+'] = ['such', 'plus', 'stuff']") - feed_command("registers") - screen:expect([[ + feed_command('registers') + screen:expect( + [[ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {4: }| :registers | {1:Type Name Content} | @@ -672,12 +665,15 @@ describe('clipboard (with fake clipboard.vim)', function() c "+ such{2:^J}plus{2:^J}stuff | c ": let g:test_clip['+'] = ['such', 'plus', 'stuff'] | {3:Press ENTER or type command to continue}^ | - ]], { - [0] = {bold = true, foreground = Screen.colors.Blue}, - [1] = {bold = true, foreground = Screen.colors.Fuchsia}, - [2] = {foreground = Screen.colors.Blue}, - [3] = {bold = true, foreground = Screen.colors.SeaGreen}, - [4] = {bold = true, reverse = true}}) + ]], + { + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { bold = true, foreground = Screen.colors.Fuchsia }, + [2] = { foreground = Screen.colors.Blue }, + [3] = { bold = true, foreground = Screen.colors.SeaGreen }, + [4] = { bold = true, reverse = true }, + } + ) feed('<cr>') -- clear out of Press ENTER screen end) @@ -694,22 +690,28 @@ describe('clipboard (with fake clipboard.vim)', function() feed_command("let g:test_clip['*'] = ['stuff']") feed_command('redir @*>') -- it is made empty - eq({{''}, 'v'}, eval("g:test_clip['*']")) + eq({ { '' }, 'v' }, eval("g:test_clip['*']")) feed_command('let g:test = doesnotexist') feed('<cr>') - eq({{ - '', - '', - 'E121: Undefined variable: doesnotexist', - }, 'v'}, eval("g:test_clip['*']")) + eq( + { { + '', + '', + 'E121: Undefined variable: doesnotexist', + }, 'v' }, + eval("g:test_clip['*']") + ) feed_command(':echo "Howdy!"') - eq({{ - '', - '', - 'E121: Undefined variable: doesnotexist', - '', - 'Howdy!', - }, 'v'}, eval("g:test_clip['*']")) + eq({ + { + '', + '', + 'E121: Undefined variable: doesnotexist', + '', + 'Howdy!', + }, + 'v', + }, eval("g:test_clip['*']")) end) it('handles middleclick correctly', function() @@ -717,7 +719,7 @@ describe('clipboard (with fake clipboard.vim)', function() local screen = Screen.new(30, 5) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, + [0] = { bold = true, foreground = Screen.colors.Blue }, }) screen:attach() insert([[ @@ -728,8 +730,7 @@ describe('clipboard (with fake clipboard.vim)', function() screen:expect([[ the ^source | a target | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) @@ -739,7 +740,7 @@ describe('clipboard (with fake clipboard.vim)', function() the a target]]) -- on error, fall back to unnamed register - feed_command("let g:cliperror = 1") + feed_command('let g:cliperror = 1') feed('<MiddleMouse><6,1>') expect([[ the source @@ -762,4 +763,11 @@ describe('clipboard (with fake clipboard.vim)', function() expect('some some') eq('some', eval('getreg("*")')) end) + + it('does not fall back to unnamed register with getreg() #24257', function() + eval('setreg("", "wrong")') + command('let g:cliperror = 1') + eq('', eval('getreg("*")')) + eq('', eval('getreg("+")')) + end) end) diff --git a/test/functional/provider/define_spec.lua b/test/functional/provider/define_spec.lua index 12efbec326..657f1a0d8a 100644 --- a/test/functional/provider/define_spec.lua +++ b/test/functional/provider/define_spec.lua @@ -1,7 +1,8 @@ local helpers = require('test.functional.helpers')(after_each) -local eval, command, nvim = helpers.eval, helpers.command, helpers.nvim +local eval, command = helpers.eval, helpers.command local eq, run, stop = helpers.eq, helpers.run, helpers.stop local clear = helpers.clear +local api = helpers.api local function get_prefix(sync) if sync then @@ -11,7 +12,7 @@ local function get_prefix(sync) end local function call(fn, arguments) - command('call '..fn..'('..arguments..')') + command('call ' .. fn .. '(' .. arguments .. ')') end local function clear_and_init(init) @@ -44,24 +45,24 @@ end local function command_specs_for(fn, sync, first_arg_factory, init) local prefix = get_prefix(sync) - describe(prefix..' command created by', function() + describe(prefix .. ' command created by', function() before_each(clear_and_init(init)) describe(fn, function() local args before_each(function() - args = first_arg_factory()..', "test-handler", ' + args = first_arg_factory() .. ', "test-handler", ' if sync then args = args .. '1' else args = args .. '0' end - args = args..', "RpcCommand"' + args = args .. ', "RpcCommand"' end) it('without options', function() - call(fn, args..', {}') + call(fn, args .. ', {}') local function on_setup() command('RpcCommand') end @@ -75,14 +76,14 @@ local function command_specs_for(fn, sync, first_arg_factory, init) end) it('with nargs', function() - call(fn, args..', {"nargs": "*"}') + call(fn, args .. ', {"nargs": "*"}') local function on_setup() command('RpcCommand arg1 arg2 arg3') end local function handler(method, arguments) eq('test-handler', method) - eq({'arg1', 'arg2', 'arg3'}, arguments[1]) + eq({ 'arg1', 'arg2', 'arg3' }, arguments[1]) return '' end @@ -90,14 +91,14 @@ local function command_specs_for(fn, sync, first_arg_factory, init) end) it('with nargs/double-quote', function() - call(fn, args..', {"nargs": "*"}') + call(fn, args .. ', {"nargs": "*"}') local function on_setup() command('RpcCommand "arg1" "arg2" "arg3"') end local function handler(method, arguments) eq('test-handler', method) - eq({'"arg1"', '"arg2"', '"arg3"'}, arguments[1]) + eq({ '"arg1"', '"arg2"', '"arg3"' }, arguments[1]) return '' end @@ -105,14 +106,14 @@ local function command_specs_for(fn, sync, first_arg_factory, init) end) it('with range', function() - call(fn,args..', {"range": ""}') + call(fn, args .. ', {"range": ""}') local function on_setup() command('1,1RpcCommand') end local function handler(method, arguments) eq('test-handler', method) - eq({1, 1}, arguments[1]) + eq({ 1, 1 }, arguments[1]) return '' end @@ -120,15 +121,15 @@ local function command_specs_for(fn, sync, first_arg_factory, init) end) it('with nargs/range', function() - call(fn, args..', {"nargs": "1", "range": ""}') + call(fn, args .. ', {"nargs": "1", "range": ""}') local function on_setup() command('1,1RpcCommand arg') end local function handler(method, arguments) eq('test-handler', method) - eq({'arg'}, arguments[1]) - eq({1, 1}, arguments[2]) + eq({ 'arg' }, arguments[1]) + eq({ 1, 1 }, arguments[2]) return '' end @@ -136,14 +137,14 @@ local function command_specs_for(fn, sync, first_arg_factory, init) end) it('with nargs/count', function() - call(fn, args..', {"nargs": "1", "count": "5"}') + call(fn, args .. ', {"nargs": "1", "count": "5"}') local function on_setup() command('5RpcCommand arg') end local function handler(method, arguments) eq('test-handler', method) - eq({'arg'}, arguments[1]) + eq({ 'arg' }, arguments[1]) eq(5, arguments[2]) return '' end @@ -152,14 +153,14 @@ local function command_specs_for(fn, sync, first_arg_factory, init) end) it('with nargs/count/bang', function() - call(fn, args..', {"nargs": "1", "count": "5", "bang": ""}') + call(fn, args .. ', {"nargs": "1", "count": "5", "bang": ""}') local function on_setup() command('5RpcCommand! arg') end local function handler(method, arguments) eq('test-handler', method) - eq({'arg'}, arguments[1]) + eq({ 'arg' }, arguments[1]) eq(5, arguments[2]) eq(1, arguments[3]) return '' @@ -169,15 +170,14 @@ local function command_specs_for(fn, sync, first_arg_factory, init) end) it('with nargs/count/bang/register', function() - call(fn, args..', {"nargs": "1", "count": "5", "bang": "",'.. - ' "register": ""}') + call(fn, args .. ', {"nargs": "1", "count": "5", "bang": "",' .. ' "register": ""}') local function on_setup() command('5RpcCommand! b arg') end local function handler(method, arguments) eq('test-handler', method) - eq({'arg'}, arguments[1]) + eq({ 'arg' }, arguments[1]) eq(5, arguments[2]) eq(1, arguments[3]) eq('b', arguments[4]) @@ -188,8 +188,12 @@ local function command_specs_for(fn, sync, first_arg_factory, init) end) it('with nargs/count/bang/register/eval', function() - call(fn, args..', {"nargs": "1", "count": "5", "bang": "",'.. - ' "register": "", "eval": "@<reg>"}') + call( + fn, + args + .. ', {"nargs": "1", "count": "5", "bang": "",' + .. ' "register": "", "eval": "@<reg>"}' + ) local function on_setup() command('let @b = "regb"') command('5RpcCommand! b arg') @@ -197,7 +201,7 @@ local function command_specs_for(fn, sync, first_arg_factory, init) local function handler(method, arguments) eq('test-handler', method) - eq({'arg'}, arguments[1]) + eq({ 'arg' }, arguments[1]) eq(5, arguments[2]) eq(1, arguments[3]) eq('b', arguments[4]) @@ -211,28 +215,27 @@ local function command_specs_for(fn, sync, first_arg_factory, init) end) end - local function autocmd_specs_for(fn, sync, first_arg_factory, init) local prefix = get_prefix(sync) - describe(prefix..' autocmd created by', function() + describe(prefix .. ' autocmd created by', function() before_each(clear_and_init(init)) describe(fn, function() local args before_each(function() - args = first_arg_factory()..', "test-handler", ' + args = first_arg_factory() .. ', "test-handler", ' if sync then args = args .. '1' else args = args .. '0' end - args = args..', "BufEnter"' + args = args .. ', "BufEnter"' end) it('without options', function() - call(fn, args..', {}') + call(fn, args .. ', {}') local function on_setup() command('doautocmd BufEnter x.c') end @@ -246,7 +249,7 @@ local function autocmd_specs_for(fn, sync, first_arg_factory, init) end) it('with eval', function() - call(fn, args..[[, {'eval': 'expand("<afile>")'}]]) + call(fn, args .. [[, {'eval': 'expand("<afile>")'}]]) local function on_setup() command('doautocmd BufEnter x.c') end @@ -263,28 +266,27 @@ local function autocmd_specs_for(fn, sync, first_arg_factory, init) end) end - local function function_specs_for(fn, sync, first_arg_factory, init) local prefix = get_prefix(sync) - describe(prefix..' function created by', function() + describe(prefix .. ' function created by', function() before_each(clear_and_init(init)) describe(fn, function() local args before_each(function() - args = first_arg_factory()..', "test-handler", ' + args = first_arg_factory() .. ', "test-handler", ' if sync then args = args .. '1' else args = args .. '0' end - args = args..', "TestFunction"' + args = args .. ', "TestFunction"' end) it('without options', function() - call(fn, args..', {}') + call(fn, args .. ', {}') local function on_setup() if sync then eq('rv', eval('TestFunction(1, "a", ["b", "c"])')) @@ -295,7 +297,7 @@ local function function_specs_for(fn, sync, first_arg_factory, init) local function handler(method, arguments) eq('test-handler', method) - eq({{1, 'a', {'b', 'c'}}}, arguments) + eq({ { 1, 'a', { 'b', 'c' } } }, arguments) return 'rv' end @@ -303,7 +305,7 @@ local function function_specs_for(fn, sync, first_arg_factory, init) end) it('with eval', function() - call(fn, args..[[, {'eval': '2 + 2'}]]) + call(fn, args .. [[, {'eval': '2 + 2'}]]) local function on_setup() if sync then eq('rv', eval('TestFunction(1, "a", ["b", "c"])')) @@ -314,7 +316,7 @@ local function function_specs_for(fn, sync, first_arg_factory, init) local function handler(method, arguments) eq('test-handler', method) - eq({{1, 'a', {'b', 'c'}}, 4}, arguments) + eq({ { 1, 'a', { 'b', 'c' } }, 4 }, arguments) return 'rv' end @@ -327,14 +329,14 @@ local function function_specs_for(fn, sync, first_arg_factory, init) bar baz zub]]) - call(fn, args..[[, {'range': ''}]]) + call(fn, args .. [[, {'range': ''}]]) local function on_setup() command('2,3call TestFunction(1, "a", ["b", "c"])') end local function handler(method, arguments) eq('test-handler', method) - eq({{1, 'a', {'b', 'c'}}, {2, 3}}, arguments) + eq({ { 1, 'a', { 'b', 'c' } }, { 2, 3 } }, arguments) return 'rv' end @@ -342,14 +344,14 @@ local function function_specs_for(fn, sync, first_arg_factory, init) end) it('with eval/range', function() - call(fn, args..[[, {'eval': '4', 'range': ''}]]) + call(fn, args .. [[, {'eval': '4', 'range': ''}]]) local function on_setup() command('%call TestFunction(1, "a", ["b", "c"])') end local function handler(method, arguments) eq('test-handler', method) - eq({{1, 'a', {'b', 'c'}}, {1, 1}, 4}, arguments) + eq({ { 1, 'a', { 'b', 'c' } }, { 1, 1 }, 4 }, arguments) return 'rv' end @@ -360,7 +362,7 @@ local function function_specs_for(fn, sync, first_arg_factory, init) end local function channel() - return nvim('get_api_info')[1] + return api.nvim_get_chan_info(0).id end local function host() @@ -368,7 +370,7 @@ local function host() end local function register() - eval('remote#host#Register("busted", "busted", '..channel()..')') + eval('remote#host#Register("busted", "busted", ' .. channel() .. ')') end command_specs_for('remote#define#CommandOnChannel', true, channel) diff --git a/test/functional/provider/nodejs_spec.lua b/test/functional/provider/nodejs_spec.lua index 187f1c0412..1769239cb0 100644 --- a/test/functional/provider/nodejs_spec.lua +++ b/test/functional/provider/nodejs_spec.lua @@ -10,7 +10,10 @@ do clear() local reason = missing_provider('node') if reason then - pending(string.format("Missing nodejs host, or nodejs version is too old (%s)", reason), function() end) + pending( + string.format('Missing nodejs host, or nodejs version is too old (%s)', reason), + function() end + ) return end end @@ -20,24 +23,31 @@ before_each(function() end) describe('nodejs host', function() - teardown(function () + teardown(function() os.remove('Xtest-nodejs-hello.js') os.remove('Xtest-nodejs-hello-plugin.js') end) it('works', function() local fname = 'Xtest-nodejs-hello.js' - write_file(fname, [[ + write_file( + fname, + [[ const neovim = require('neovim'); const nvim = neovim.attach({socket: process.env.NVIM}); nvim.command('let g:job_out = "hello"'); - ]]) - command('let g:job_id = jobstart(["node", "'..fname..'"])') - retry(nil, 3000, function() eq('hello', eval('g:job_out')) end) + ]] + ) + command('let g:job_id = jobstart(["node", "' .. fname .. '"])') + retry(nil, 3000, function() + eq('hello', eval('g:job_out')) + end) end) it('plugin works', function() local fname = 'Xtest-nodejs-hello-plugin.js' - write_file(fname, [[ + write_file( + fname, + [[ const neovim = require('neovim'); const nvim = neovim.attach({socket: process.env.NVIM}); @@ -49,8 +59,11 @@ describe('nodejs host', function() const PluginClass = neovim.Plugin(TestPlugin); const plugin = new neovim.NvimPlugin(null, PluginClass, nvim); plugin.instance.hello(); - ]]) - command('let g:job_id = jobstart(["node", "'..fname..'"])') - retry(nil, 3000, function() eq('hello-plugin', eval('g:job_out')) end) + ]] + ) + command('let g:job_id = jobstart(["node", "' .. fname .. '"])') + retry(nil, 3000, function() + eq('hello-plugin', eval('g:job_out')) + end) end) end) diff --git a/test/functional/provider/perl_spec.lua b/test/functional/provider/perl_spec.lua index 8049f0f3e2..e9a031eb07 100644 --- a/test/functional/provider/perl_spec.lua +++ b/test/functional/provider/perl_spec.lua @@ -5,7 +5,7 @@ local command = helpers.command local write_file = helpers.write_file local eval = helpers.eval local retry = helpers.retry -local meths = helpers.meths +local api = helpers.api local insert = helpers.insert local expect = helpers.expect local feed = helpers.feed @@ -14,7 +14,10 @@ do clear() local reason = missing_provider('perl') if reason then - pending(string.format("Missing perl host, or perl version is too old (%s)", reason), function() end) + pending( + string.format('Missing perl host, or perl version is too old (%s)', reason), + function() end + ) return end end @@ -30,7 +33,7 @@ describe('legacy perl provider', function() it(':perl command', function() command('perl $vim->vars->{set_by_perl} = [100, 0];') - eq({100, 0}, eval('g:set_by_perl')) + eq({ 100, 0 }, eval('g:set_by_perl')) end) it(':perlfile command', function() @@ -45,7 +48,7 @@ describe('legacy perl provider', function() -- :perldo 1; doesn't change $_, -- the buffer should not be changed command('normal :perldo 1;') - eq(false, meths.get_option_value('modified', {})) + eq(false, api.nvim_get_option_value('modified', {})) -- insert some text insert('abc\ndef\nghi') expect([[ @@ -61,19 +64,21 @@ describe('legacy perl provider', function() end) it('perleval()', function() - eq({1, 2, {['key'] = 'val'}}, eval([[perleval('[1, 2, {"key" => "val"}]')]])) + eq({ 1, 2, { ['key'] = 'val' } }, eval([[perleval('[1, 2, {"key" => "val"}]')]])) end) end) describe('perl provider', function() - teardown(function () + teardown(function() os.remove('Xtest-perl-hello.pl') os.remove('Xtest-perl-hello-plugin.pl') end) it('works', function() local fname = 'Xtest-perl-hello.pl' - write_file(fname, [[ + write_file( + fname, + [[ package main; use strict; use warnings; @@ -84,14 +89,19 @@ describe('perl provider', function() my $nvim = Neovim::Ext::from_session($session); $nvim->command('let g:job_out = "hello"'); 1; - ]]) - command('let g:job_id = jobstart(["perl", "'..fname..'"])') - retry(nil, 3000, function() eq('hello', eval('g:job_out')) end) + ]] + ) + command('let g:job_id = jobstart(["perl", "' .. fname .. '"])') + retry(nil, 3000, function() + eq('hello', eval('g:job_out')) + end) end) it('plugin works', function() local fname = 'Xtest-perl-hello-plugin.pl' - write_file(fname, [[ + write_file( + fname, + [[ package TestPlugin; use strict; use warnings; @@ -118,8 +128,11 @@ describe('perl provider', function() my $plugin = TestPlugin->new($nvim); $plugin->test_command(); 1; - ]]) - command('let g:job_id = jobstart(["perl", "'..fname..'"])') - retry(nil, 3000, function() eq('hello-plugin', eval('g:job_out')) end) + ]] + ) + command('let g:job_id = jobstart(["perl", "' .. fname .. '"])') + retry(nil, 3000, function() + eq('hello-plugin', eval('g:job_out')) + end) end) end) diff --git a/test/functional/provider/provider_spec.lua b/test/functional/provider/provider_spec.lua index b1c326d04c..cccd1a1184 100644 --- a/test/functional/provider/provider_spec.lua +++ b/test/functional/provider/provider_spec.lua @@ -1,4 +1,3 @@ - local helpers = require('test.functional.helpers')(after_each) local clear, eval = helpers.clear, helpers.eval local command = helpers.command @@ -14,14 +13,18 @@ describe('providers', function() command('set loadplugins') -- Using test-fixture with broken impl: -- test/functional/fixtures/autoload/provider/python.vim - eq('Vim:provider: python3: missing required variable g:loaded_python3_provider', - pcall_err(eval, "has('python3')")) + eq( + 'Vim:provider: python3: missing required variable g:loaded_python3_provider', + pcall_err(eval, "has('python3')") + ) end) it('with g:loaded_xx_provider, missing #Call()', function() -- Using test-fixture with broken impl: -- test/functional/fixtures/autoload/provider/ruby.vim - eq('Vim:provider: ruby: g:loaded_ruby_provider=2 but provider#ruby#Call is not defined', - pcall_err(eval, "has('ruby')")) + eq( + 'Vim:provider: ruby: g:loaded_ruby_provider=2 but provider#ruby#Call is not defined', + pcall_err(eval, "has('ruby')") + ) end) end) diff --git a/test/functional/provider/python3_spec.lua b/test/functional/provider/python3_spec.lua index d9c44c3315..80b3552e82 100644 --- a/test/functional/provider/python3_spec.lua +++ b/test/functional/provider/python3_spec.lua @@ -8,19 +8,28 @@ local source = helpers.source local missing_provider = helpers.missing_provider local matches = helpers.matches local pcall_err = helpers.pcall_err -local funcs = helpers.funcs +local fn = helpers.fn local dedent = helpers.dedent do clear() - local reason = missing_provider('python3') + local reason = missing_provider('python') if reason then it(':python3 reports E319 if provider is missing', function() local expected = [[Vim%(py3.*%):E319: No "python3" provider found.*]] matches(expected, pcall_err(command, 'py3 print("foo")')) matches(expected, pcall_err(command, 'py3file foo')) end) - pending(string.format('Python 3 (or the pynvim module) is broken/missing (%s)', reason), function() end) + it('feature test when Python 3 provider is missing', function() + eq(0, eval('has("python3")')) + eq(0, eval('has("python3_compiled")')) + eq(0, eval('has("python3_dynamic")')) + eq(0, eval('has("pythonx")')) + end) + pending( + string.format('Python 3 (or the pynvim module) is broken/missing (%s)', reason), + function() end + ) return end end @@ -35,31 +44,40 @@ describe('python3 provider', function() eq(1, eval('has("python3")')) eq(1, eval('has("python3_compiled")')) eq(1, eval('has("python3_dynamic")')) + eq(1, eval('has("pythonx")')) eq(0, eval('has("python3_dynamic_")')) eq(0, eval('has("python3_")')) end) it('python3_execute', function() command('python3 vim.vars["set_by_python3"] = [100, 0]') - eq({100, 0}, eval('g:set_by_python3')) + eq({ 100, 0 }, eval('g:set_by_python3')) end) it('does not truncate error message <1 MB', function() -- XXX: Python limits the error name to 200 chars, so this test is -- mostly bogus. local very_long_symbol = string.rep('a', 1200) - feed_command(':silent! py3 print('..very_long_symbol..' b)') + feed_command(':silent! py3 print(' .. very_long_symbol .. ' b)') -- Error message will contain this (last) line. - matches(string.format(dedent([[ + matches( + string.format( + dedent([[ ^Error invoking 'python_execute' on channel 3 %%(python3%%-script%%-host%%): File "<string>", line 1 print%%(%s b%%) %%C* - SyntaxError: invalid syntax%%C*$]]), very_long_symbol), eval('v:errmsg')) + SyntaxError: invalid syntax%%C*$]]), + very_long_symbol + ), + eval('v:errmsg') + ) end) it('python3_execute with nested commands', function() - command([[python3 vim.command('python3 vim.command("python3 vim.command(\'let set_by_nested_python3 = 555\')")')]]) + command( + [[python3 vim.command('python3 vim.command("python3 vim.command(\'let set_by_nested_python3 = 555\')")')]] + ) eq(555, eval('g:set_by_nested_python3')) end) @@ -70,7 +88,7 @@ describe('python3 provider', function() line3 line4]]) feed('ggjvj:python3 vim.vars["range"] = vim.current.range[:]<CR>') - eq({'line2', 'line3'}, eval('g:range')) + eq({ 'line2', 'line3' }, eval('g:range')) end) it('py3file', function() @@ -102,7 +120,7 @@ describe('python3 provider', function() describe('py3eval()', function() it('works', function() - eq({1, 2, {['key'] = 'val'}}, funcs.py3eval('[1, 2, {"key": "val"}]')) + eq({ 1, 2, { ['key'] = 'val' } }, fn.py3eval('[1, 2, {"key": "val"}]')) end) it('errors out when given non-string', function() @@ -131,7 +149,7 @@ describe('python3 provider', function() command 'set pyxversion=3' -- no error eq('Vim(set):E474: Invalid argument: pyxversion=2', pcall_err(command, 'set pyxversion=2')) command 'set pyxversion=0' -- allowed, but equivalent to pyxversion=3 - eq(3, eval'&pyxversion') + eq(3, eval '&pyxversion') end) it('RPC call to expand("<afile>") during BufDelete #5245 #5617', function() @@ -146,7 +164,7 @@ describe('python3 provider', function() autocmd BufDelete * python3 foo() autocmd BufUnload * python3 foo()]=]) feed_command("exe 'split' tempname()") - feed_command("bwipeout!") + feed_command('bwipeout!') feed_command('help help') assert_alive() end) @@ -155,11 +173,11 @@ end) describe('python2 feature test', function() -- python2 is not supported, so correct behaviour is to return 0 it('works', function() - eq(0, funcs.has('python2')) - eq(0, funcs.has('python')) - eq(0, funcs.has('python_compiled')) - eq(0, funcs.has('python_dynamic')) - eq(0, funcs.has('python_dynamic_')) - eq(0, funcs.has('python_')) + eq(0, fn.has('python2')) + eq(0, fn.has('python')) + eq(0, fn.has('python_compiled')) + eq(0, fn.has('python_dynamic')) + eq(0, fn.has('python_dynamic_')) + eq(0, fn.has('python_')) end) end) diff --git a/test/functional/provider/ruby_spec.lua b/test/functional/provider/ruby_spec.lua index d3b967dfbe..9b2531a23c 100644 --- a/test/functional/provider/ruby_spec.lua +++ b/test/functional/provider/ruby_spec.lua @@ -8,9 +8,9 @@ local exc_exec = helpers.exc_exec local expect = helpers.expect local feed = helpers.feed local feed_command = helpers.feed_command -local funcs = helpers.funcs +local fn = helpers.fn local insert = helpers.insert -local meths = helpers.meths +local api = helpers.api local missing_provider = helpers.missing_provider local matches = helpers.matches local write_file = helpers.write_file @@ -36,19 +36,19 @@ end) describe('ruby feature test', function() it('works', function() - eq(1, funcs.has('ruby')) + eq(1, fn.has('ruby')) end) end) describe(':ruby command', function() it('evaluates ruby', function() command('ruby VIM.command("let g:set_by_ruby = [100, 0]")') - eq({100, 0}, meths.get_var('set_by_ruby')) + eq({ 100, 0 }, api.nvim_get_var('set_by_ruby')) end) it('supports nesting', function() command([[ruby VIM.command('ruby VIM.command("let set_by_nested_ruby = 555")')]]) - eq(555, meths.get_var('set_by_nested_ruby')) + eq(555, api.nvim_get_var('set_by_nested_ruby')) end) end) @@ -57,7 +57,7 @@ describe(':rubyfile command', function() local fname = 'rubyfile.rb' write_file(fname, 'VIM.command("let set_by_rubyfile = 123")') command('rubyfile rubyfile.rb') - eq(123, meths.get_var('set_by_rubyfile')) + eq(123, api.nvim_get_var('set_by_rubyfile')) os.remove(fname) end) end) @@ -97,7 +97,7 @@ describe(':rubydo command', function() it('does not modify the buffer if no changes are made', function() command('normal :rubydo 42') - eq(false, meths.get_option_value('modified', {})) + eq(false, api.nvim_get_option_value('modified', {})) end) end) @@ -112,11 +112,11 @@ end) describe('rubyeval()', function() it('evaluates ruby objects', function() - eq({1, 2, {['key'] = 'val'}}, funcs.rubyeval('[1, 2, {key: "val"}]')) + eq({ 1, 2, { ['key'] = 'val' } }, fn.rubyeval('[1, 2, {key: "val"}]')) end) it('returns nil for empty strings', function() - eq(helpers.NIL, funcs.rubyeval('')) + eq(vim.NIL, fn.rubyeval('')) end) it('errors out when given non-string', function() diff --git a/test/functional/script/luacats_grammar_spec.lua b/test/functional/script/luacats_grammar_spec.lua new file mode 100644 index 0000000000..c3ac9fe722 --- /dev/null +++ b/test/functional/script/luacats_grammar_spec.lua @@ -0,0 +1,154 @@ +local helpers = require('test.functional.helpers')(after_each) +local eq = helpers.eq + +local grammar = require('scripts/luacats_grammar') + +describe('luacats grammar', function() + --- @param text string + --- @param exp table<string,string> + local function test(text, exp) + it(string.format('can parse %q', text), function() + eq(exp, grammar:match(text)) + end) + end + + test('@param hello vim.type', { + kind = 'param', + name = 'hello', + type = 'vim.type', + }) + + test('@param hello vim.type this is a description', { + kind = 'param', + name = 'hello', + type = 'vim.type', + desc = 'this is a description', + }) + + test('@param hello vim.type|string this is a description', { + kind = 'param', + name = 'hello', + type = 'vim.type|string', + desc = 'this is a description', + }) + + test('@param hello vim.type?|string? this is a description', { + kind = 'param', + name = 'hello', + type = 'vim.type?|string?', + desc = 'this is a description', + }) + + test('@return string hello this is a description', { + kind = 'return', + { + name = 'hello', + type = 'string', + }, + desc = 'this is a description', + }) + + test('@return fun() hello this is a description', { + kind = 'return', + { + name = 'hello', + type = 'fun()', + }, + desc = 'this is a description', + }) + + test('@return fun(a: string[]): string hello this is a description', { + kind = 'return', + { + name = 'hello', + type = 'fun(a: string[]): string', + }, + desc = 'this is a description', + }) + + test('@return fun(a: table<string,any>): string hello this is a description', { + kind = 'return', + { + name = 'hello', + type = 'fun(a: table<string,any>): string', + }, + desc = 'this is a description', + }) + + test('@param ... string desc', { + kind = 'param', + name = '...', + type = 'string', + desc = 'desc', + }) + + test('@param level (integer|string) desc', { + kind = 'param', + name = 'level', + type = 'integer|string', + desc = 'desc', + }) + + test('@return (string command) the command and arguments', { + kind = 'return', + { + name = 'command', + type = 'string', + }, + desc = 'the command and arguments', + }) + + test('@return (string command, string[] args) the command and arguments', { + kind = 'return', + { + name = 'command', + type = 'string', + }, + { + name = 'args', + type = 'string[]', + }, + desc = 'the command and arguments', + }) + + test('@param rfc "rfc2396" | "rfc2732" | "rfc3986" | nil', { + kind = 'param', + name = 'rfc', + type = '"rfc2396" | "rfc2732" | "rfc3986" | nil', + }) + + test('@param offset_encoding "utf-8" | "utf-16" | "utf-32" | nil', { + kind = 'param', + name = 'offset_encoding', + type = '"utf-8" | "utf-16" | "utf-32" | nil', + }) + + -- handle a : after the param type + test('@param a b: desc', { + kind = 'param', + name = 'a', + type = 'b', + desc = 'desc', + }) + + test( + '@field prefix? string|table|(fun(diagnostic:vim.Diagnostic,i:integer,total:integer): string, string)', + { + kind = 'field', + name = 'prefix?', + type = 'string|table|(fun(diagnostic:vim.Diagnostic,i:integer,total:integer): string, string)', + } + ) + + test('@field [integer] integer', { + kind = 'field', + name = '[integer]', + type = 'integer', + }) + + test('@field [1] integer', { + kind = 'field', + name = '[1]', + type = 'integer', + }) +end) diff --git a/test/functional/script/luacats_parser_spec.lua b/test/functional/script/luacats_parser_spec.lua new file mode 100644 index 0000000000..e10aa81003 --- /dev/null +++ b/test/functional/script/luacats_parser_spec.lua @@ -0,0 +1,106 @@ +local helpers = require('test.functional.helpers')(after_each) +local eq = helpers.eq + +local parser = require('scripts/luacats_parser') + +--- @param name string +--- @param text string +--- @param exp table<string,string> +local function test(name, text, exp) + exp = vim.deepcopy(exp, true) + it(name, function() + eq(exp, parser.parse_str(text, 'myfile.lua')) + end) +end + +describe('luacats parser', function() + local exp = { + myclass = { + kind = 'class', + module = 'myfile.lua', + name = 'myclass', + fields = { + { kind = 'field', name = 'myclass', type = 'integer' }, + }, + }, + } + + test( + 'basic class', + [[ + --- @class myclass + --- @field myclass integer + ]], + exp + ) + + exp.myclass.inlinedoc = true + + test( + 'class with @inlinedoc (1)', + [[ + --- @class myclass + --- @inlinedoc + --- @field myclass integer + ]], + exp + ) + + test( + 'class with @inlinedoc (2)', + [[ + --- @inlinedoc + --- @class myclass + --- @field myclass integer + ]], + exp + ) + + exp.myclass.inlinedoc = nil + exp.myclass.nodoc = true + + test( + 'class with @nodoc', + [[ + --- @nodoc + --- @class myclass + --- @field myclass integer + ]], + exp + ) + + exp.myclass.nodoc = nil + exp.myclass.access = 'private' + + test( + 'class with (private)', + [[ + --- @class (private) myclass + --- @field myclass integer + ]], + exp + ) + + exp.myclass.fields[1].desc = 'Field\ndocumentation' + + test( + 'class with field doc above', + [[ + --- @class (private) myclass + --- Field + --- documentation + --- @field myclass integer + ]], + exp + ) + + exp.myclass.fields[1].desc = 'Field documentation' + test( + 'class with field doc inline', + [[ + --- @class (private) myclass + --- @field myclass integer Field documentation + ]], + exp + ) +end) diff --git a/test/functional/script/text_utils_spec.lua b/test/functional/script/text_utils_spec.lua new file mode 100644 index 0000000000..190c617e1d --- /dev/null +++ b/test/functional/script/text_utils_spec.lua @@ -0,0 +1,60 @@ +local helpers = require('test.functional.helpers')(after_each) +local exec_lua = helpers.exec_lua +local eq = helpers.eq + +local function md_to_vimdoc(text, start_indent, indent, text_width) + return exec_lua( + [[ + local text, start_indent, indent, text_width = ... + start_indent = start_indent or 0 + indent = indent or 0 + text_width = text_width or 70 + local text_utils = require('scripts/text_utils') + return text_utils.md_to_vimdoc(table.concat(text, '\n'), start_indent, indent, text_width) + ]], + text, + start_indent, + indent, + text_width + ) +end + +local function test(what, act, exp, ...) + local argc, args = select('#', ...), { ... } + it(what, function() + eq(table.concat(exp, '\n'), md_to_vimdoc(act, unpack(args, 1, argc))) + end) +end + +describe('md_to_vimdoc', function() + before_each(function() + helpers.clear() + end) + + test('can render para after fenced code', { + '- Para1', + ' ```', + ' code', + ' ```', + ' Para2', + }, { + '• Para1 >', + ' code', + '<', + ' Para2', + '', + }) + + test('start_indent only applies to first line', { + 'para1', + '', + 'para2', + }, { + 'para1', + '', + ' para2', + '', + }, 0, 10, 78) + + test('inline 1', { '(`string`)' }, { '(`string`)', '' }) +end) diff --git a/test/functional/shada/buffers_spec.lua b/test/functional/shada/buffers_spec.lua index b1c4ded541..9fead98fed 100644 --- a/test/functional/shada/buffers_spec.lua +++ b/test/functional/shada/buffers_spec.lua @@ -1,7 +1,6 @@ -- shada buffer list saving/reading support local helpers = require('test.functional.helpers')(after_each) -local nvim_command, funcs, eq, curbufmeths, meths = - helpers.command, helpers.funcs, helpers.eq, helpers.curbufmeths, helpers.meths +local nvim_command, fn, eq, api = helpers.command, helpers.fn, helpers.eq, helpers.api local expect_exit = helpers.expect_exit local shada_helpers = require('test.functional.shada.helpers') @@ -18,10 +17,10 @@ describe('shada support code', function() nvim_command('edit ' .. testfilename_2) expect_exit(nvim_command, 'qall') reset('set shada+=%') - eq(3, funcs.bufnr('$')) - eq('', funcs.bufname(1)) - eq(testfilename, funcs.bufname(2)) - eq(testfilename_2, funcs.bufname(3)) + eq(3, fn.bufnr('$')) + eq('', fn.bufname(1)) + eq(testfilename, fn.bufname(2)) + eq(testfilename_2, fn.bufname(3)) end) it('does not restore buffer list without % in &shada', function() @@ -30,8 +29,8 @@ describe('shada support code', function() nvim_command('edit ' .. testfilename_2) expect_exit(nvim_command, 'qall') reset() - eq(1, funcs.bufnr('$')) - eq('', funcs.bufname(1)) + eq(1, fn.bufnr('$')) + eq('', fn.bufname(1)) end) it('does not dump buffer list without % in &shada', function() @@ -40,44 +39,44 @@ describe('shada support code', function() nvim_command('edit ' .. testfilename_2) expect_exit(nvim_command, 'qall') reset('set shada+=%') - eq(1, funcs.bufnr('$')) - eq('', funcs.bufname(1)) + eq(1, fn.bufnr('$')) + eq('', fn.bufname(1)) end) it('does not dump unlisted buffer', function() reset('set shada+=%') nvim_command('edit ' .. testfilename) nvim_command('edit ' .. testfilename_2) - meths.set_option_value('buflisted', false, {}) + api.nvim_set_option_value('buflisted', false, {}) expect_exit(nvim_command, 'qall') reset('set shada+=%') - eq(2, funcs.bufnr('$')) - eq('', funcs.bufname(1)) - eq(testfilename, funcs.bufname(2)) + eq(2, fn.bufnr('$')) + eq('', fn.bufname(1)) + eq(testfilename, fn.bufname(2)) end) it('does not dump quickfix buffer', function() reset('set shada+=%') nvim_command('edit ' .. testfilename) nvim_command('edit ' .. testfilename_2) - meths.set_option_value('buftype', 'quickfix', {}) + api.nvim_set_option_value('buftype', 'quickfix', {}) expect_exit(nvim_command, 'qall') reset('set shada+=%') - eq(2, funcs.bufnr('$')) - eq('', funcs.bufname(1)) - eq(testfilename, funcs.bufname(2)) + eq(2, fn.bufnr('$')) + eq('', fn.bufname(1)) + eq(testfilename, fn.bufname(2)) end) it('does not dump unnamed buffers', function() reset('set shada+=% hidden') - curbufmeths.set_lines(0, 1, true, {'foo'}) + api.nvim_buf_set_lines(0, 0, 1, true, { 'foo' }) nvim_command('enew') - curbufmeths.set_lines(0, 1, true, {'bar'}) - eq(2, funcs.bufnr('$')) + api.nvim_buf_set_lines(0, 0, 1, true, { 'bar' }) + eq(2, fn.bufnr('$')) expect_exit(nvim_command, 'qall!') reset('set shada+=% hidden') - eq(1, funcs.bufnr('$')) - eq('', funcs.bufname(1)) + eq(1, fn.bufnr('$')) + eq('', fn.bufname(1)) end) it('restores 1 buffer with %1 in &shada, #5759', function() @@ -86,8 +85,8 @@ describe('shada support code', function() nvim_command('edit ' .. testfilename_2) expect_exit(nvim_command, 'qall') reset('set shada+=%1') - eq(2, funcs.bufnr('$')) - eq('', funcs.bufname(1)) - eq(testfilename, funcs.bufname(2)) + eq(2, fn.bufnr('$')) + eq('', fn.bufname(1)) + eq(testfilename, fn.bufname(2)) end) end) diff --git a/test/functional/shada/compatibility_spec.lua b/test/functional/shada/compatibility_spec.lua index fb656735dd..bc4e9675c6 100644 --- a/test/functional/shada/compatibility_spec.lua +++ b/test/functional/shada/compatibility_spec.lua @@ -1,11 +1,11 @@ -- ShaDa compatibility support local helpers = require('test.functional.helpers')(after_each) -local nvim_command, funcs, eq = helpers.command, helpers.funcs, helpers.eq +local nvim_command, fn, eq = helpers.command, helpers.fn, helpers.eq local exc_exec = helpers.exc_exec local shada_helpers = require('test.functional.shada.helpers') -local reset, clear, get_shada_rw = shada_helpers.reset, shada_helpers.clear, - shada_helpers.get_shada_rw +local reset, clear, get_shada_rw = + shada_helpers.reset, shada_helpers.clear, shada_helpers.get_shada_rw local read_shada_file = shada_helpers.read_shada_file local wshada, sdrcmd, shada_fname = get_shada_rw('Xtest-functional-shada-compatibility.shada') @@ -49,11 +49,11 @@ describe('ShaDa forward compatibility support code', function() end end eq(true, found) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) nvim_command('rshada! ' .. shada_fname) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) end) it('works with s/search pattern item with BOOL unknown (sX) key value', function() @@ -81,11 +81,11 @@ describe('ShaDa forward compatibility support code', function() end end eq(true, found) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) nvim_command('rshada!' .. shada_fname) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) end) it('works with replacement item with BOOL additional value in list', function() @@ -114,22 +114,32 @@ describe('ShaDa forward compatibility support code', function() end end eq(true, found) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) nvim_command('rshada!' .. shada_fname) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) end) - for _, v in ipairs({{name='global mark', mpack='\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161nA'}, - {name='jump', mpack='\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002'}, - {name='local mark', mpack='\010\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161na'}, - {name='change', mpack='\011\001\015\130\162mX\195\161f\196\006' .. mock_file_path .. 'c'}, - }) do + for _, v in ipairs({ + { + name = 'global mark', + mpack = '\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161nA', + }, + { + name = 'jump', + mpack = '\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002', + }, + { + name = 'local mark', + mpack = '\010\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161na', + }, + { name = 'change', mpack = '\011\001\015\130\162mX\195\161f\196\006' .. mock_file_path .. 'c' }, + }) do it('works with ' .. v.name .. ' item with BOOL unknown (mX) key value', function() nvim_command('silent noautocmd edit ' .. mock_file_path .. 'c') - eq('' .. mock_file_path .. 'c', funcs.bufname('%')) - funcs.setline('.', {'1', '2', '3'}) + eq('' .. mock_file_path .. 'c', fn.bufname('%')) + fn.setline('.', { '1', '2', '3' }) wshada(v.mpack) eq(0, exc_exec(sdrcmd(true))) os.remove(shada_fname) @@ -145,7 +155,7 @@ describe('ShaDa forward compatibility support code', function() eq(true, found) eq(0, exc_exec(sdrcmd())) nvim_command('bwipeout!') - funcs.setpos('\'A', {0, 1, 1, 0}) + fn.setpos("'A", { 0, 1, 1, 0 }) os.remove(shada_fname) nvim_command('wshada ' .. shada_fname) found = false @@ -157,21 +167,25 @@ describe('ShaDa forward compatibility support code', function() end end eq(false, found) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) nvim_command('rshada!' .. shada_fname) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) end) if v.name == 'global mark' or v.name == 'local mark' then it('works with ' .. v.name .. ' item with <C-a> name', function() nvim_command('silent noautocmd edit ' .. mock_file_path .. 'c') - eq('' .. mock_file_path .. 'c', funcs.bufname('%')) - funcs.setline('.', {'1', '2', '3'}) - wshada(v.mpack:gsub('n.$', 'n\001') - .. v.mpack:gsub('n.$', 'n\002') - .. v.mpack:gsub('n.$', 'n\003'):gsub('' .. mock_file_path .. 'c', '' .. mock_file_path2 .. 'f')) + eq('' .. mock_file_path .. 'c', fn.bufname('%')) + fn.setline('.', { '1', '2', '3' }) + wshada( + v.mpack:gsub('n.$', 'n\001') + .. v.mpack:gsub('n.$', 'n\002') + .. v.mpack + :gsub('n.$', 'n\003') + :gsub('' .. mock_file_path .. 'c', '' .. mock_file_path2 .. 'f') + ) eq(0, exc_exec(sdrcmd(true))) nvim_command('wshada ' .. shada_fname) local found = 0 @@ -199,11 +213,11 @@ describe('ShaDa forward compatibility support code', function() end end eq(0, found) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) nvim_command('rshada!' .. shada_fname) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) end) end end @@ -231,11 +245,11 @@ describe('ShaDa forward compatibility support code', function() end end eq(false, found) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) nvim_command('rshada!' .. shada_fname) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) end) it('works with register item with <C-a> name', function() @@ -267,18 +281,18 @@ describe('ShaDa forward compatibility support code', function() end end eq(0, found) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) nvim_command('rshada!' .. shada_fname) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) end) it('works with register item with type 10', function() wshada('\005\001\019\132\161na\162rX\194\162rc\145\196\001-\162rt\010') eq(0, exc_exec(sdrcmd(true))) - eq({}, funcs.getreg('a', 1, 1)) - eq('', funcs.getregtype('a')) + eq({}, fn.getreg('a', 1, 1)) + eq('', fn.getregtype('a')) nvim_command('wshada ' .. shada_fname) local found = 0 for i, v in ipairs(read_shada_file(shada_fname)) do @@ -305,19 +319,19 @@ describe('ShaDa forward compatibility support code', function() end end eq(0, found) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) nvim_command('rshada!' .. shada_fname) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) end) it('works with buffer list item with BOOL unknown (bX) key', function() nvim_command('set shada+=%') wshada('\009\000\016\145\130\161f\196\006' .. mock_file_path .. 'c\162bX\195') eq(0, exc_exec(sdrcmd())) - eq(2, funcs.bufnr('$')) - eq('' .. mock_file_path .. 'c', funcs.bufname(2)) + eq(2, fn.bufnr('$')) + eq('' .. mock_file_path .. 'c', fn.bufname(2)) os.remove(shada_fname) nvim_command('wshada ' .. shada_fname) local found = false @@ -340,11 +354,11 @@ describe('ShaDa forward compatibility support code', function() end eq(false, found) nvim_command('bwipeout!') - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) nvim_command('rshada!' .. shada_fname) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) end) it('works with history item with BOOL additional value in list', function() @@ -363,8 +377,8 @@ describe('ShaDa forward compatibility support code', function() eq(true, found) eq(0, exc_exec(sdrcmd())) os.remove(shada_fname) - funcs.histadd(':', '--') - funcs.histadd(':', '-') + fn.histadd(':', '--') + fn.histadd(':', '-') nvim_command('wshada ' .. shada_fname) found = false for _, v in ipairs(read_shada_file(shada_fname)) do @@ -374,11 +388,11 @@ describe('ShaDa forward compatibility support code', function() end end eq(true, found) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) nvim_command('rshada!' .. shada_fname) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) end) it('works with history item with type 10', function() @@ -411,11 +425,11 @@ describe('ShaDa forward compatibility support code', function() end end eq(0, found) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) nvim_command('rshada!' .. shada_fname) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) end) it('works with item with 100 type', function() @@ -448,10 +462,10 @@ describe('ShaDa forward compatibility support code', function() end end eq(0, found) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) nvim_command('rshada!' .. shada_fname) - funcs.garbagecollect(1) - funcs.garbagecollect(1) + fn.garbagecollect(1) + fn.garbagecollect(1) end) end) diff --git a/test/functional/shada/errors_spec.lua b/test/functional/shada/errors_spec.lua index ebfd73cf85..233f03e5c0 100644 --- a/test/functional/shada/errors_spec.lua +++ b/test/functional/shada/errors_spec.lua @@ -1,14 +1,12 @@ -- ShaDa errors handling support local helpers = require('test.functional.helpers')(after_each) -local nvim_command, eq, exc_exec = - helpers.command, helpers.eq, helpers.exc_exec +local nvim_command, eq, exc_exec = helpers.command, helpers.eq, helpers.exc_exec local shada_helpers = require('test.functional.shada.helpers') local reset, clear, get_shada_rw = shada_helpers.reset, shada_helpers.clear, shada_helpers.get_shada_rw -local wshada, sdrcmd, shada_fname, clean = - get_shada_rw('Xtest-functional-shada-errors.shada') +local wshada, sdrcmd, shada_fname, clean = get_shada_rw('Xtest-functional-shada-errors.shada') describe('ShaDa error handling', function() before_each(reset) @@ -29,17 +27,26 @@ describe('ShaDa error handling', function() it('fails on zero', function() wshada('\000') - eq('Vim(rshada):E576: Error while reading ShaDa file: expected positive integer at position 0, but got nothing', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E576: Error while reading ShaDa file: expected positive integer at position 0, but got nothing', + exc_exec(sdrcmd()) + ) end) it('fails on missing item', function() wshada('\000\000\000') - eq('Vim(rshada):E576: Error while reading ShaDa file: there is an item at position 0 that must not be there: Missing items are for internal uses only', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E576: Error while reading ShaDa file: there is an item at position 0 that must not be there: Missing items are for internal uses only', + exc_exec(sdrcmd()) + ) end) it('fails on -2 type', function() wshada('\254\000\000') - eq('Vim(rshada):E576: Error while reading ShaDa file: expected positive integer at position 0', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E576: Error while reading ShaDa file: expected positive integer at position 0', + exc_exec(sdrcmd()) + ) end) it('does not fail on header with zero length', function() @@ -50,22 +57,34 @@ describe('ShaDa error handling', function() it('fails on search pattern item with zero length', function() wshada('\002\000\000') - eq('Vim(rshada):E576: Failed to parse ShaDa file: incomplete msgpack string at position 3', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E576: Failed to parse ShaDa file: incomplete msgpack string at position 3', + exc_exec(sdrcmd()) + ) end) it('fails on search pattern item with -2 timestamp', function() wshada('\002\254\000') - eq('Vim(rshada):E576: Error while reading ShaDa file: expected positive integer at position 1', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E576: Error while reading ShaDa file: expected positive integer at position 1', + exc_exec(sdrcmd()) + ) end) it('fails on search pattern item with -2 length', function() wshada('\002\000\254') - eq('Vim(rshada):E576: Error while reading ShaDa file: expected positive integer at position 2', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E576: Error while reading ShaDa file: expected positive integer at position 2', + exc_exec(sdrcmd()) + ) end) it('fails on search pattern item with length greater then file length', function() wshada('\002\000\002\000') - eq('Vim(rshada):E576: Error while reading ShaDa file: last entry specified that it occupies 2 bytes, but file ended earlier', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E576: Error while reading ShaDa file: last entry specified that it occupies 2 bytes, but file ended earlier', + exc_exec(sdrcmd()) + ) end) it('fails on search pattern item with invalid byte', function() @@ -80,334 +99,523 @@ describe('ShaDa error handling', function() -- get MSGPACK_UNPACK_PARSE_ERROR and not MSGPACK_UNPACK_CONTINUE or -- MSGPACK_UNPACK_EXTRA_BYTES. wshada('\002\000\001\193') - eq('Vim(rshada):E576: Failed to parse ShaDa file due to a msgpack parser error at position 3', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E576: Failed to parse ShaDa file due to a msgpack parser error at position 3', + exc_exec(sdrcmd()) + ) end) it('fails on search pattern item with incomplete map', function() wshada('\002\000\001\129') - eq('Vim(rshada):E576: Failed to parse ShaDa file: incomplete msgpack string at position 3', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E576: Failed to parse ShaDa file: incomplete msgpack string at position 3', + exc_exec(sdrcmd()) + ) end) it('fails on search pattern item without a pattern', function() wshada('\002\000\005\129\162sX\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has no pattern', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has no pattern', + exc_exec(sdrcmd()) + ) end) it('fails on search pattern with extra bytes', function() wshada('\002\000\002\128\000') - eq('Vim(rshada):E576: Failed to parse ShaDa file: extra bytes in msgpack string at position 3', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E576: Failed to parse ShaDa file: extra bytes in msgpack string at position 3', + exc_exec(sdrcmd()) + ) end) it('fails on search pattern item with NIL value', function() wshada('\002\000\001\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 is not a dictionary', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 is not a dictionary', + exc_exec(sdrcmd()) + ) end) -- sp entry is here because it causes an allocation. it('fails on search pattern item with BIN key', function() wshada('\002\000\014\131\162sp\196\001a\162sX\192\196\000\000') - eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has key which is not a string', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has key which is not a string', + exc_exec(sdrcmd()) + ) end) -- sp entry is here because it causes an allocation. it('fails on search pattern item with empty key', function() wshada('\002\000\013\131\162sp\196\001a\162sX\192\160\000') - eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has empty key', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has empty key', + exc_exec(sdrcmd()) + ) end) it('fails on search pattern item with NIL magic key value', function() wshada('\002\000\009\130\162sX\192\162sm\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sm key value which is not a boolean', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sm key value which is not a boolean', + exc_exec(sdrcmd()) + ) end) it('fails on search pattern item with NIL smartcase key value', function() wshada('\002\000\009\130\162sX\192\162sc\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sc key value which is not a boolean', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sc key value which is not a boolean', + exc_exec(sdrcmd()) + ) end) it('fails on search pattern item with NIL search_backward key value', function() wshada('\002\000\009\130\162sX\192\162sb\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sb key value which is not a boolean', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sb key value which is not a boolean', + exc_exec(sdrcmd()) + ) end) it('fails on search pattern item with NIL has_line_offset key value', function() wshada('\002\000\009\130\162sX\192\162sl\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sl key value which is not a boolean', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sl key value which is not a boolean', + exc_exec(sdrcmd()) + ) end) it('fails on search pattern item with NIL place_cursor_at_end key value', function() wshada('\002\000\009\130\162sX\192\162se\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has se key value which is not a boolean', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has se key value which is not a boolean', + exc_exec(sdrcmd()) + ) end) it('fails on search pattern item with NIL is_last_used key value', function() wshada('\002\000\009\130\162sX\192\162su\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has su key value which is not a boolean', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has su key value which is not a boolean', + exc_exec(sdrcmd()) + ) end) it('fails on search pattern item with NIL is_substitute_pattern key value', function() wshada('\002\000\009\130\162sX\192\162ss\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has ss key value which is not a boolean', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has ss key value which is not a boolean', + exc_exec(sdrcmd()) + ) end) it('fails on search pattern item with NIL highlighted key value', function() wshada('\002\000\009\130\162sX\192\162sh\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sh key value which is not a boolean', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sh key value which is not a boolean', + exc_exec(sdrcmd()) + ) end) it('fails on search pattern item with NIL offset key value', function() wshada('\002\000\009\130\162sX\192\162so\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has so key value which is not an integer', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has so key value which is not an integer', + exc_exec(sdrcmd()) + ) end) it('fails on search pattern item with NIL pat key value', function() wshada('\002\000\009\130\162sX\192\162sp\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sp key value which is not a binary', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sp key value which is not a binary', + exc_exec(sdrcmd()) + ) end) it('fails on search pattern item with STR pat key value', function() wshada('\002\000\011\130\162sX\192\162sp\162sp') - eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sp key value which is not a binary', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sp key value which is not a binary', + exc_exec(sdrcmd()) + ) end) - for _, v in ipairs({{name='global mark', mpack='\007'}, - {name='jump', mpack='\008'}, - {name='local mark', mpack='\010'}, - {name='change', mpack='\011'}, - }) do - local is_mark_test = ({['global mark']=true, ['local mark']=true})[v.name] + for _, v in ipairs({ + { name = 'global mark', mpack = '\007' }, + { name = 'jump', mpack = '\008' }, + { name = 'local mark', mpack = '\010' }, + { name = 'change', mpack = '\011' }, + }) do + local is_mark_test = ({ ['global mark'] = true, ['local mark'] = true })[v.name] it('fails on ' .. v.name .. ' item with NIL value', function() wshada(v.mpack .. '\000\001\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 is not a dictionary', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 is not a dictionary', + exc_exec(sdrcmd()) + ) end) -- f entry is here because it causes an allocation. it('fails on ' .. v.name .. ' item with BIN key', function() wshada(v.mpack .. '\000\013\131\161f\196\001/\162mX\192\196\000\000') - eq('Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has key which is not a string', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has key which is not a string', + exc_exec(sdrcmd()) + ) end) -- f entry is here because it causes an allocation. it('fails on ' .. v.name .. ' item with empty key', function() wshada(v.mpack .. '\000\012\131\161f\196\001/\162mX\192\160\000') - eq('Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has empty key', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has empty key', + exc_exec(sdrcmd()) + ) end) it('fails on ' .. v.name .. ' item without f key', function() wshada(v.mpack .. '\000\008\130\162mX\192\161l\001') - eq('Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 is missing file name', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 is missing file name', + exc_exec(sdrcmd()) + ) end) it('fails on ' .. v.name .. ' item with zero l key', function() wshada(v.mpack .. '\000\013\131\162mX\192\161f\196\001/\161l\000') - eq('Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has invalid line number', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has invalid line number', + exc_exec(sdrcmd()) + ) end) it('fails on ' .. v.name .. ' item with negative l key', function() wshada(v.mpack .. '\000\013\131\162mX\192\161f\196\001/\161l\255') - eq('Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has invalid line number', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has invalid line number', + exc_exec(sdrcmd()) + ) end) it('fails on ' .. v.name .. ' item with negative c key', function() wshada(v.mpack .. '\000\013\131\162mX\192\161f\196\001/\161c\255') - eq('Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has invalid column number', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has invalid column number', + exc_exec(sdrcmd()) + ) end) it('fails on ' .. v.name .. ' item with STR n key value', function() wshada(v.mpack .. '\000\011\130\162mX\192\161n\163spa') - eq(is_mark_test and 'Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has n key value which is not an unsigned integer' or 'Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has n key which is only valid for local and global mark entries', exc_exec(sdrcmd())) + eq( + is_mark_test + and 'Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has n key value which is not an unsigned integer' + or 'Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has n key which is only valid for local and global mark entries', + exc_exec(sdrcmd()) + ) end) it('fails on ' .. v.name .. ' item with STR l key value', function() wshada(v.mpack .. '\000\010\130\162mX\192\161l\162sp') - eq('Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has l key value which is not an integer', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has l key value which is not an integer', + exc_exec(sdrcmd()) + ) end) it('fails on ' .. v.name .. ' item with STR c key value', function() wshada(v.mpack .. '\000\010\130\162mX\192\161c\162sp') - eq('Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has c key value which is not an integer', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has c key value which is not an integer', + exc_exec(sdrcmd()) + ) end) it('fails on ' .. v.name .. ' item with STR f key value', function() wshada(v.mpack .. '\000\010\130\162mX\192\161f\162sp') - eq('Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has f key value which is not a binary', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: mark entry at position 0 has f key value which is not a binary', + exc_exec(sdrcmd()) + ) end) end it('fails on register item with NIL value', function() wshada('\005\000\001\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: register entry at position 0 is not a dictionary', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: register entry at position 0 is not a dictionary', + exc_exec(sdrcmd()) + ) end) -- rc entry is here because it causes an allocation it('fails on register item with BIN key', function() wshada('\005\000\015\131\162rc\145\196\001a\162rX\192\196\000\000') - eq('Vim(rshada):E575: Error while reading ShaDa file: register entry at position 0 has key which is not a string', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: register entry at position 0 has key which is not a string', + exc_exec(sdrcmd()) + ) end) -- rc entry is here because it causes an allocation it('fails on register item with BIN key', function() wshada('\005\000\014\131\162rc\145\196\001a\162rX\192\160\000') - eq('Vim(rshada):E575: Error while reading ShaDa file: register entry at position 0 has empty key', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: register entry at position 0 has empty key', + exc_exec(sdrcmd()) + ) end) it('fails on register item with NIL rt key value', function() wshada('\005\000\009\130\162rX\192\162rt\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: register entry at position 0 has rt key value which is not an unsigned integer', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: register entry at position 0 has rt key value which is not an unsigned integer', + exc_exec(sdrcmd()) + ) end) it('fails on register item with NIL rw key value', function() wshada('\005\000\009\130\162rX\192\162rw\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: register entry at position 0 has rw key value which is not an unsigned integer', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: register entry at position 0 has rw key value which is not an unsigned integer', + exc_exec(sdrcmd()) + ) end) it('fails on register item with NIL rc key value', function() wshada('\005\000\009\130\162rX\192\162rc\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: register entry at position 0 has rc key with non-array value', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: register entry at position 0 has rc key with non-array value', + exc_exec(sdrcmd()) + ) end) it('fails on register item with empty rc key value', function() wshada('\005\000\009\130\162rX\192\162rc\144') - eq('Vim(rshada):E575: Error while reading ShaDa file: register entry at position 0 has rc key with empty array', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: register entry at position 0 has rc key with empty array', + exc_exec(sdrcmd()) + ) end) it('fails on register item with NIL in rc array', function() wshada('\005\000\013\130\162rX\192\162rc\146\196\001a\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: register entry at position 0 has rc array with non-binary value', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: register entry at position 0 has rc array with non-binary value', + exc_exec(sdrcmd()) + ) end) it('fails on register item without rc array', function() wshada('\005\000\009\129\162rX\146\196\001a\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: register entry at position 0 has missing rc array', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: register entry at position 0 has missing rc array', + exc_exec(sdrcmd()) + ) end) it('fails on history item with NIL value', function() wshada('\004\000\001\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: history entry at position 0 is not an array', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: history entry at position 0 is not an array', + exc_exec(sdrcmd()) + ) end) it('fails on history item with empty value', function() wshada('\004\000\001\144') - eq('Vim(rshada):E575: Error while reading ShaDa file: history entry at position 0 does not have enough elements', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: history entry at position 0 does not have enough elements', + exc_exec(sdrcmd()) + ) end) it('fails on history item with single element value', function() wshada('\004\000\002\145\000') - eq('Vim(rshada):E575: Error while reading ShaDa file: history entry at position 0 does not have enough elements', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: history entry at position 0 does not have enough elements', + exc_exec(sdrcmd()) + ) end) it('fails on history item with NIL first item', function() wshada('\004\000\003\146\192\000') - eq('Vim(rshada):E575: Error while reading ShaDa file: history entry at position 0 has wrong history type type', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: history entry at position 0 has wrong history type type', + exc_exec(sdrcmd()) + ) end) it('fails on history item with FIXUINT second item', function() wshada('\004\000\003\146\000\000') - eq('Vim(rshada):E575: Error while reading ShaDa file: history entry at position 0 has wrong history string type', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: history entry at position 0 has wrong history string type', + exc_exec(sdrcmd()) + ) end) it('fails on history item with second item with zero byte', function() wshada('\004\000\007\146\000\196\003ab\000') - eq('Vim(rshada):E575: Error while reading ShaDa file: history entry at position 0 contains string with zero byte inside', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: history entry at position 0 contains string with zero byte inside', + exc_exec(sdrcmd()) + ) end) it('fails on search history item without third item', function() wshada('\004\000\007\146\001\196\003abc') - eq('Vim(rshada):E575: Error while reading ShaDa file: search history entry at position 0 does not have separator character', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: search history entry at position 0 does not have separator character', + exc_exec(sdrcmd()) + ) end) it('fails on search history item with NIL third item', function() wshada('\004\000\007\147\001\196\002ab\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: search history entry at position 0 has wrong history separator type', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: search history entry at position 0 has wrong history separator type', + exc_exec(sdrcmd()) + ) end) it('fails on variable item with NIL value', function() wshada('\006\000\001\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: variable entry at position 0 is not an array', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: variable entry at position 0 is not an array', + exc_exec(sdrcmd()) + ) end) it('fails on variable item with empty value', function() wshada('\006\000\001\144') - eq('Vim(rshada):E575: Error while reading ShaDa file: variable entry at position 0 does not have enough elements', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: variable entry at position 0 does not have enough elements', + exc_exec(sdrcmd()) + ) end) it('fails on variable item with single element value', function() wshada('\006\000\002\145\000') - eq('Vim(rshada):E575: Error while reading ShaDa file: variable entry at position 0 does not have enough elements', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: variable entry at position 0 does not have enough elements', + exc_exec(sdrcmd()) + ) end) it('fails on variable item with NIL first item', function() wshada('\006\000\003\146\192\000') - eq('Vim(rshada):E575: Error while reading ShaDa file: variable entry at position 0 has wrong variable name type', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: variable entry at position 0 has wrong variable name type', + exc_exec(sdrcmd()) + ) end) it('fails on variable item with BIN value and type value != VAR_TYPE_BLOB', function() wshada('\006\000\007\147\196\001\065\196\000\000') - eq('Vim(rshada):E575: Error while reading ShaDa file: variable entry at position 0 has wrong variable type', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: variable entry at position 0 has wrong variable type', + exc_exec(sdrcmd()) + ) end) it('fails on replacement item with NIL value', function() wshada('\003\000\001\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: sub string entry at position 0 is not an array', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: sub string entry at position 0 is not an array', + exc_exec(sdrcmd()) + ) end) it('fails on replacement item with empty value', function() wshada('\003\000\001\144') - eq('Vim(rshada):E575: Error while reading ShaDa file: sub string entry at position 0 does not have enough elements', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: sub string entry at position 0 does not have enough elements', + exc_exec(sdrcmd()) + ) end) it('fails on replacement item with NIL first item', function() wshada('\003\000\002\145\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: sub string entry at position 0 has wrong sub string type', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: sub string entry at position 0 has wrong sub string type', + exc_exec(sdrcmd()) + ) end) it('fails on buffer list item with NIL value', function() nvim_command('set shada+=%') wshada('\009\000\001\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: buffer list entry at position 0 is not an array', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: buffer list entry at position 0 is not an array', + exc_exec(sdrcmd()) + ) end) it('fails on buffer list item with NIL item in the array', function() nvim_command('set shada+=%') wshada('\009\000\008\146\129\161f\196\001/\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: buffer list at position 0 contains entry that is not a dictionary', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: buffer list at position 0 contains entry that is not a dictionary', + exc_exec(sdrcmd()) + ) end) it('fails on buffer list item with empty item', function() nvim_command('set shada+=%') wshada('\009\000\008\146\129\161f\196\001/\128') - eq('Vim(rshada):E575: Error while reading ShaDa file: buffer list at position 0 contains entry that does not have a file name', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: buffer list at position 0 contains entry that does not have a file name', + exc_exec(sdrcmd()) + ) end) it('fails on buffer list item with NIL l key', function() nvim_command('set shada+=%') wshada('\009\000\017\146\129\161f\196\001/\130\161f\196\002/a\161l\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: buffer list entry entry at position 0 has l key value which is not an integer', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: buffer list entry entry at position 0 has l key value which is not an integer', + exc_exec(sdrcmd()) + ) end) it('fails on buffer list item with zero l key', function() nvim_command('set shada+=%') wshada('\009\000\017\146\129\161f\196\001/\130\161f\196\002/a\161l\000') - eq('Vim(rshada):E575: Error while reading ShaDa file: buffer list at position 0 contains entry with invalid line number', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: buffer list at position 0 contains entry with invalid line number', + exc_exec(sdrcmd()) + ) end) it('fails on buffer list item with negative l key', function() nvim_command('set shada+=%') wshada('\009\000\017\146\129\161f\196\001/\130\161f\196\002/a\161l\255') - eq('Vim(rshada):E575: Error while reading ShaDa file: buffer list at position 0 contains entry with invalid line number', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: buffer list at position 0 contains entry with invalid line number', + exc_exec(sdrcmd()) + ) end) it('fails on buffer list item with negative c key', function() nvim_command('set shada+=%') wshada('\009\000\017\146\129\161f\196\001/\130\161f\196\002/a\161c\255') - eq('Vim(rshada):E575: Error while reading ShaDa file: buffer list at position 0 contains entry with invalid column number', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: buffer list at position 0 contains entry with invalid column number', + exc_exec(sdrcmd()) + ) end) it('fails on buffer list item with NIL c key', function() nvim_command('set shada+=%') wshada('\009\000\017\146\129\161f\196\001/\130\161f\196\002/a\161c\192') - eq('Vim(rshada):E575: Error while reading ShaDa file: buffer list entry entry at position 0 has c key value which is not an integer', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E575: Error while reading ShaDa file: buffer list entry entry at position 0 has c key value which is not an integer', + exc_exec(sdrcmd()) + ) end) it('fails on invalid ShaDa file (viminfo file)', function() @@ -480,40 +688,229 @@ $ + 65 0 + 65 0 ]]) - eq('Vim(rshada):E576: Failed to parse ShaDa file: extra bytes in msgpack string at position 3', exc_exec(sdrcmd())) - eq('Vim(wshada):E576: Failed to parse ShaDa file: extra bytes in msgpack string at position 3', exc_exec('wshada ' .. shada_fname)) + eq( + 'Vim(rshada):E576: Failed to parse ShaDa file: extra bytes in msgpack string at position 3', + exc_exec(sdrcmd()) + ) + eq( + 'Vim(wshada):E576: Failed to parse ShaDa file: extra bytes in msgpack string at position 3', + exc_exec('wshada ' .. shada_fname) + ) eq(0, exc_exec('wshada! ' .. shada_fname)) end) it('fails on invalid ShaDa file (wrapper script)', function() wshada('#!/bin/sh\n\npowerline "$@" 2>&1 | tee -a powerline\n') - eq('Vim(rshada):E576: Failed to parse ShaDa file: extra bytes in msgpack string at position 3', exc_exec(sdrcmd())) - eq('Vim(wshada):E576: Failed to parse ShaDa file: extra bytes in msgpack string at position 3', exc_exec('wshada ' .. shada_fname)) + eq( + 'Vim(rshada):E576: Failed to parse ShaDa file: extra bytes in msgpack string at position 3', + exc_exec(sdrcmd()) + ) + eq( + 'Vim(wshada):E576: Failed to parse ShaDa file: extra bytes in msgpack string at position 3', + exc_exec('wshada ' .. shada_fname) + ) eq(0, exc_exec('wshada! ' .. shada_fname)) end) it('fails on invalid ShaDa file (failing skip in second item)', function() wshada('\001\000\001\128#!/') - eq('Vim(rshada):E576: Error while reading ShaDa file: last entry specified that it occupies 47 bytes, but file ended earlier', exc_exec(sdrcmd())) - eq('Vim(wshada):E576: Error while reading ShaDa file: last entry specified that it occupies 47 bytes, but file ended earlier', exc_exec('wshada ' .. shada_fname)) + eq( + 'Vim(rshada):E576: Error while reading ShaDa file: last entry specified that it occupies 47 bytes, but file ended earlier', + exc_exec(sdrcmd()) + ) + eq( + 'Vim(wshada):E576: Error while reading ShaDa file: last entry specified that it occupies 47 bytes, but file ended earlier', + exc_exec('wshada ' .. shada_fname) + ) eq(0, exc_exec('wshada! ' .. shada_fname)) end) it('errors with too large items', function() wshada({ - 1, 206, 70, 90, 31, 179, 86, 133, 169, 103, 101, 110, 101, 114, 97, - 116, 111, 114, 196, 4, 145, 145, 145, 145, 145, 145, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 145, 145, 145, 145, 111, 110, 196, 25, 78, 86, 73, 77, 32, - 118, 1, 46, 50, 46, 48, 45, 51, 48, 51, 45, 103, 98, 54, 55, - 52, 102, 100, 50, 99, 169, 109, 97, 120, 95, 107, 98, 121, 116, 101, - 10, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, - 207, 207, 207, 207, 207, 207, 207, 207, 16, 8, 206, 89, 90, 30, 253, - 35, 129, 161, 102, 196, 30, 47, 100, 101, 118, 47, 115, 104, 109, 47, - 102, 117, 122, 122, 105, 110, 103, 45, 110, 118, 105, 109, 45, 115, 104, - 97, 100, 97, 47, 108, 115, 2, 206, 89, 90, 30, 251, 13, 130, 162, - 115, 112, 196, 3, 102, 111, 111, 162, 115, 99, 195, 3, 146, 10, 0, + 1, + 206, + 70, + 90, + 31, + 179, + 86, + 133, + 169, + 103, + 101, + 110, + 101, + 114, + 97, + 116, + 111, + 114, + 196, + 4, + 145, + 145, + 145, + 145, + 145, + 145, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 96, + 145, + 145, + 145, + 145, + 111, + 110, + 196, + 25, + 78, + 86, + 73, + 77, + 32, + 118, + 1, + 46, + 50, + 46, + 48, + 45, + 51, + 48, + 51, + 45, + 103, + 98, + 54, + 55, + 52, + 102, + 100, + 50, + 99, + 169, + 109, + 97, + 120, + 95, + 107, + 98, + 121, + 116, + 101, + 10, + 207, + 207, + 207, + 207, + 207, + 207, + 207, + 207, + 207, + 207, + 207, + 207, + 207, + 207, + 207, + 207, + 207, + 207, + 207, + 207, + 207, + 207, + 16, + 8, + 206, + 89, + 90, + 30, + 253, + 35, + 129, + 161, + 102, + 196, + 30, + 47, + 100, + 101, + 118, + 47, + 115, + 104, + 109, + 47, + 102, + 117, + 122, + 122, + 105, + 110, + 103, + 45, + 110, + 118, + 105, + 109, + 45, + 115, + 104, + 97, + 100, + 97, + 47, + 108, + 115, + 2, + 206, + 89, + 90, + 30, + 251, + 13, + 130, + 162, + 115, + 112, + 196, + 3, + 102, + 111, + 111, + 162, + 115, + 99, + 195, + 3, + 146, + 10, + 0, }) - eq('Vim(rshada):E576: Error while reading ShaDa file: there is an item at position 93 that is stated to be too long', exc_exec(sdrcmd())) + eq( + 'Vim(rshada):E576: Error while reading ShaDa file: there is an item at position 93 that is stated to be too long', + exc_exec(sdrcmd()) + ) end) end) diff --git a/test/functional/shada/helpers.lua b/test/functional/shada/helpers.lua index cd99d38345..baa27889f3 100644 --- a/test/functional/shada/helpers.lua +++ b/test/functional/shada/helpers.lua @@ -1,10 +1,8 @@ local helpers = require('test.functional.helpers')(nil) -local meths = helpers.meths +local api = helpers.api local write_file = helpers.write_file local concat_tables = helpers.concat_tables -local mpack = require('mpack') - local tmpname = helpers.tmpname() -- o={ @@ -17,19 +15,20 @@ local function reset(o) o = o and o or {} local args_rm = o.args_rm or {} table.insert(args_rm, '-i') - local args={ - '-i', o.shadafile or tmpname, + local args = { + '-i', + o.shadafile or tmpname, } if type(o) == 'string' then - args = concat_tables(args, {'--cmd', o}) + args = concat_tables(args, { '--cmd', o }) elseif o.args then args = concat_tables(args, o.args) end - helpers.clear{ - args_rm=args_rm, - args=args, + helpers.clear { + args_rm = args_rm, + args = args, } - meths.set_var('tmpname', tmpname) + api.nvim_set_var('tmpname', tmpname) end local clear = function() @@ -57,13 +56,13 @@ local get_shada_rw = function(fname) return wshada, sdrcmd, fname, clean end -local mpack_keys = {'type', 'timestamp', 'length', 'value'} +local mpack_keys = { 'type', 'timestamp', 'length', 'value' } local read_shada_file = function(fname) local fd = io.open(fname, 'r') local mstring = fd:read('*a') fd:close() - local unpack = mpack.Unpacker() + local unpack = vim.mpack.Unpacker() local ret = {} local cur, val local i = 0 @@ -81,8 +80,8 @@ local read_shada_file = function(fname) end return { - reset=reset, - clear=clear, - get_shada_rw=get_shada_rw, - read_shada_file=read_shada_file, + reset = reset, + clear = clear, + get_shada_rw = get_shada_rw, + read_shada_file = read_shada_file, } diff --git a/test/functional/shada/history_spec.lua b/test/functional/shada/history_spec.lua index 433db3171e..c8a19bb082 100644 --- a/test/functional/shada/history_spec.lua +++ b/test/functional/shada/history_spec.lua @@ -1,7 +1,7 @@ -- ShaDa history saving/reading support local helpers = require('test.functional.helpers')(after_each) -local nvim_command, funcs, meths, nvim_feed, eq = - helpers.command, helpers.funcs, helpers.meths, helpers.feed, helpers.eq +local nvim_command, fn, api, nvim_feed, eq = + helpers.command, helpers.fn, helpers.api, helpers.feed, helpers.eq local assert_alive = helpers.assert_alive local expect_exit = helpers.expect_exit @@ -13,134 +13,131 @@ describe('ShaDa support code', function() after_each(clear) it('is able to dump and read back command-line history', function() - nvim_command('set shada=\'0') + nvim_command("set shada='0") nvim_feed(':" Test\n') nvim_command('wshada') reset() - nvim_command('set shada=\'0') + nvim_command("set shada='0") nvim_command('rshada') - eq('" Test', funcs.histget(':', -1)) + eq('" Test', fn.histget(':', -1)) end) it('is able to dump and read back 2 items in command-line history', function() - nvim_command('set shada=\'0 history=2') + nvim_command("set shada='0 history=2") nvim_feed(':" Test\n') nvim_feed(':" Test 2\n') expect_exit(nvim_command, 'qall') reset() - nvim_command('set shada=\'0 history=2') + nvim_command("set shada='0 history=2") nvim_command('rshada') - eq('" Test 2', funcs.histget(':', -1)) - eq('" Test', funcs.histget(':', -2)) + eq('" Test 2', fn.histget(':', -1)) + eq('" Test', fn.histget(':', -2)) end) - it('respects &history when dumping', - function() - nvim_command('set shada=\'0 history=1') + it('respects &history when dumping', function() + nvim_command("set shada='0 history=1") nvim_feed(':" Test\n') nvim_feed(':" Test 2\n') nvim_command('wshada') reset() - nvim_command('set shada=\'0 history=2') + nvim_command("set shada='0 history=2") nvim_command('rshada') - eq('" Test 2', funcs.histget(':', -1)) - eq('', funcs.histget(':', -2)) + eq('" Test 2', fn.histget(':', -1)) + eq('', fn.histget(':', -2)) end) - it('respects &history when loading', - function() - nvim_command('set shada=\'0 history=2') + it('respects &history when loading', function() + nvim_command("set shada='0 history=2") nvim_feed(':" Test\n') nvim_feed(':" Test 2\n') nvim_command('wshada') reset() - nvim_command('set shada=\'0 history=1') + nvim_command("set shada='0 history=1") nvim_command('rshada') - eq('" Test 2', funcs.histget(':', -1)) - eq('', funcs.histget(':', -2)) + eq('" Test 2', fn.histget(':', -1)) + eq('', fn.histget(':', -2)) end) it('dumps only requested amount of command-line history items', function() - nvim_command('set shada=\'0,:1') + nvim_command("set shada='0,:1") nvim_feed(':" Test\n') nvim_feed(':" Test 2\n') nvim_command('wshada') -- Regression test: :wshada should not alter or free history. - eq('" Test 2', funcs.histget(':', -1)) - eq('" Test', funcs.histget(':', -2)) + eq('" Test 2', fn.histget(':', -1)) + eq('" Test', fn.histget(':', -2)) reset() - nvim_command('set shada=\'0') + nvim_command("set shada='0") nvim_command('rshada') - eq('" Test 2', funcs.histget(':', -1)) - eq('', funcs.histget(':', -2)) + eq('" Test 2', fn.histget(':', -1)) + eq('', fn.histget(':', -2)) end) it('does not respect number in &shada when loading history', function() - nvim_command('set shada=\'0') + nvim_command("set shada='0") nvim_feed(':" Test\n') nvim_feed(':" Test 2\n') nvim_command('wshada') reset() - nvim_command('set shada=\'0,:1') + nvim_command("set shada='0,:1") nvim_command('rshada') - eq('" Test 2', funcs.histget(':', -1)) - eq('" Test', funcs.histget(':', -2)) + eq('" Test 2', fn.histget(':', -1)) + eq('" Test', fn.histget(':', -2)) end) it('dumps and loads all kinds of histories', function() nvim_command('debuggreedy') - nvim_feed(':debug echo "Test"\n" Test 2\nc\n') -- Debug history. - nvim_feed(':call input("")\nTest 2\n') -- Input history. - nvim_feed('"="Test"\nyy') -- Expression history. - nvim_feed('/Test\n') -- Search history - nvim_feed(':" Test\n') -- Command-line history + nvim_feed(':debug echo "Test"\n" Test 2\nc\n') -- Debug history. + nvim_feed(':call input("")\nTest 2\n') -- Input history. + nvim_feed('"="Test"\nyy') -- Expression history. + nvim_feed('/Test\n') -- Search history + nvim_feed(':" Test\n') -- Command-line history nvim_command('0debuggreedy') nvim_command('wshada') reset() nvim_command('rshada') - eq('" Test', funcs.histget(':', -1)) - eq('Test', funcs.histget('/', -1)) - eq('"Test"', funcs.histget('=', -1)) - eq('Test 2', funcs.histget('@', -1)) - eq('c', funcs.histget('>', -1)) + eq('" Test', fn.histget(':', -1)) + eq('Test', fn.histget('/', -1)) + eq('"Test"', fn.histget('=', -1)) + eq('Test 2', fn.histget('@', -1)) + eq('c', fn.histget('>', -1)) end) it('dumps and loads last search pattern with offset', function() - meths.set_option_value('wrapscan', false, {}) - funcs.setline('.', {'foo', 'bar--'}) + api.nvim_set_option_value('wrapscan', false, {}) + fn.setline('.', { 'foo', 'bar--' }) nvim_feed('gg0/a/e+1\n') - eq({0, 2, 3, 0}, funcs.getpos('.')) + eq({ 0, 2, 3, 0 }, fn.getpos('.')) nvim_command('wshada') reset() - meths.set_option_value('wrapscan', false, {}) - funcs.setline('.', {'foo', 'bar--'}) + api.nvim_set_option_value('wrapscan', false, {}) + fn.setline('.', { 'foo', 'bar--' }) nvim_feed('gg0n') - eq({0, 2, 3, 0}, funcs.getpos('.')) - eq(1, meths.get_vvar('searchforward')) + eq({ 0, 2, 3, 0 }, fn.getpos('.')) + eq(1, api.nvim_get_vvar('searchforward')) end) - it('dumps and loads last search pattern with offset and backward direction', - function() - meths.set_option_value('wrapscan', false, {}) - funcs.setline('.', {'foo', 'bar--'}) + it('dumps and loads last search pattern with offset and backward direction', function() + api.nvim_set_option_value('wrapscan', false, {}) + fn.setline('.', { 'foo', 'bar--' }) nvim_feed('G$?a?e+1\n') - eq({0, 2, 3, 0}, funcs.getpos('.')) + eq({ 0, 2, 3, 0 }, fn.getpos('.')) nvim_command('wshada') reset() - meths.set_option_value('wrapscan', false, {}) - funcs.setline('.', {'foo', 'bar--'}) + api.nvim_set_option_value('wrapscan', false, {}) + fn.setline('.', { 'foo', 'bar--' }) nvim_feed('G$n') - eq({0, 2, 3, 0}, funcs.getpos('.')) - eq(0, meths.get_vvar('searchforward')) + eq({ 0, 2, 3, 0 }, fn.getpos('.')) + eq(0, api.nvim_get_vvar('searchforward')) end) it('saves v:hlsearch=1', function() nvim_command('set hlsearch shada-=h') nvim_feed('/test\n') - eq(1, meths.get_vvar('hlsearch')) + eq(1, api.nvim_get_vvar('hlsearch')) expect_exit(nvim_command, 'qall') reset() - eq(1, meths.get_vvar('hlsearch')) + eq(1, api.nvim_get_vvar('hlsearch')) end) it('saves v:hlsearch=0 with :nohl', function() @@ -149,27 +146,27 @@ describe('ShaDa support code', function() nvim_command('nohlsearch') expect_exit(nvim_command, 'qall') reset() - eq(0, meths.get_vvar('hlsearch')) + eq(0, api.nvim_get_vvar('hlsearch')) end) it('saves v:hlsearch=0 with default &shada', function() nvim_command('set hlsearch') nvim_feed('/test\n') - eq(1, meths.get_vvar('hlsearch')) + eq(1, api.nvim_get_vvar('hlsearch')) expect_exit(nvim_command, 'qall') reset() - eq(0, meths.get_vvar('hlsearch')) + eq(0, api.nvim_get_vvar('hlsearch')) end) it('dumps and loads last substitute pattern and replacement string', function() - funcs.setline('.', {'foo', 'bar'}) + fn.setline('.', { 'foo', 'bar' }) nvim_command('%s/f/g/g') - eq('goo', funcs.getline(1)) + eq('goo', fn.getline(1)) nvim_command('wshada') reset() - funcs.setline('.', {'foo', 'bar'}) + fn.setline('.', { 'foo', 'bar' }) nvim_command('&') - eq('goo', funcs.getline(1)) + eq('goo', fn.getline(1)) end) it('dumps and loads history with UTF-8 characters', function() @@ -177,52 +174,48 @@ describe('ShaDa support code', function() nvim_feed(':echo "«"\n') expect_exit(nvim_command, 'qall') reset() - eq('echo "«"', funcs.histget(':', -1)) + eq('echo "«"', fn.histget(':', -1)) end) - it('dumps and loads replacement with UTF-8 characters', - function() + it('dumps and loads replacement with UTF-8 characters', function() nvim_command('substitute/./«/ge') expect_exit(nvim_command, 'qall!') reset() - funcs.setline('.', {'.'}) + fn.setline('.', { '.' }) nvim_command('&') - eq('«', funcs.getline('.')) + eq('«', fn.getline('.')) end) - it('dumps and loads substitute pattern with UTF-8 characters', - function() + it('dumps and loads substitute pattern with UTF-8 characters', function() nvim_command('substitute/«/./ge') expect_exit(nvim_command, 'qall!') reset() - funcs.setline('.', {'«\171'}) + fn.setline('.', { '«\171' }) nvim_command('&') - eq('.\171', funcs.getline('.')) + eq('.\171', fn.getline('.')) end) - it('dumps and loads search pattern with UTF-8 characters', - function() + it('dumps and loads search pattern with UTF-8 characters', function() nvim_command('silent! /«/') nvim_command('set shada+=/0') expect_exit(nvim_command, 'qall!') reset() - funcs.setline('.', {'\171«'}) + fn.setline('.', { '\171«' }) nvim_command('~&') - eq('\171', funcs.getline('.')) - eq('', funcs.histget('/', -1)) + eq('\171', fn.getline('.')) + eq('', fn.histget('/', -1)) end) - it('dumps and loads search pattern with 8-bit single-byte', - function() + it('dumps and loads search pattern with 8-bit single-byte', function() -- \171 is U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK in latin1 nvim_command('silent! /\171/') nvim_command('set shada+=/0') expect_exit(nvim_command, 'qall!') reset() - funcs.setline('.', {'\171«'}) + fn.setline('.', { '\171«' }) nvim_command('~&') - eq('«', funcs.getline('.')) - eq('', funcs.histget('/', -1)) + eq('«', fn.getline('.')) + eq('', fn.histget('/', -1)) end) it('does not crash when dumping last search pattern (#10945)', function() @@ -239,12 +232,11 @@ describe('ShaDa support code', function() end) it('does not crash when number of history save to zero (#11497)', function() - nvim_command('set shada=\'10') + nvim_command("set shada='10") nvim_feed(':" Test\n') nvim_command('wshada') - nvim_command('set shada=\'10,:0') + nvim_command("set shada='10,:0") nvim_command('wshada') assert_alive() end) - end) diff --git a/test/functional/shada/marks_spec.lua b/test/functional/shada/marks_spec.lua index 7f03022ab8..3f29a02506 100644 --- a/test/functional/shada/marks_spec.lua +++ b/test/functional/shada/marks_spec.lua @@ -1,8 +1,6 @@ -- ShaDa marks saving/reading support local helpers = require('test.functional.helpers')(after_each) -local meths, curwinmeths, curbufmeths, nvim_command, funcs, eq = - helpers.meths, helpers.curwinmeths, helpers.curbufmeths, helpers.command, - helpers.funcs, helpers.eq +local api, nvim_command, fn, eq = helpers.api, helpers.command, helpers.fn, helpers.eq local feed = helpers.feed local exc_exec, exec_capture = helpers.exc_exec, helpers.exec_capture local expect_exit = helpers.expect_exit @@ -11,7 +9,7 @@ local shada_helpers = require('test.functional.shada.helpers') local reset, clear = shada_helpers.reset, shada_helpers.clear local nvim_current_line = function() - return curwinmeths.get_cursor()[1] + return api.nvim_win_get_cursor(0)[1] end describe('ShaDa support code', function() @@ -45,7 +43,7 @@ describe('ShaDa support code', function() reset() nvim_command('rshada') nvim_command('normal! `A') - eq(testfilename, funcs.fnamemodify(curbufmeths.get_name(), ':t')) + eq(testfilename, fn.fnamemodify(api.nvim_buf_get_name(0), ':t')) eq(1, nvim_current_line()) nvim_command('normal! `B') eq(2, nvim_current_line()) @@ -63,16 +61,16 @@ describe('ShaDa support code', function() eq('Vim(normal):E20: Mark not set', exc_exec('normal! `A')) end) - it('does read back global mark even with `\'0` and `f0` in shada', function() + it("does read back global mark even with `'0` and `f0` in shada", function() nvim_command('edit ' .. testfilename) nvim_command('mark A') nvim_command('2') nvim_command('kB') nvim_command('wshada') - reset('set shada=\'0,f0') + reset("set shada='0,f0") nvim_command('language C') nvim_command('normal! `A') - eq(testfilename, funcs.fnamemodify(curbufmeths.get_name(), ':t')) + eq(testfilename, fn.fnamemodify(api.nvim_buf_get_name(0), ':t')) eq(1, nvim_current_line()) end) @@ -85,7 +83,7 @@ describe('ShaDa support code', function() reset() nvim_command('edit ' .. testfilename) nvim_command('normal! `a') - eq(testfilename, funcs.fnamemodify(curbufmeths.get_name(), ':t')) + eq(testfilename, fn.fnamemodify(api.nvim_buf_get_name(0), ':t')) eq(1, nvim_current_line()) nvim_command('normal! `b') eq(2, nvim_current_line()) @@ -115,12 +113,12 @@ describe('ShaDa support code', function() it('is able to populate v:oldfiles', function() nvim_command('edit ' .. testfilename) - local tf_full = curbufmeths.get_name() + local tf_full = api.nvim_buf_get_name(0) nvim_command('edit ' .. testfilename_2) - local tf_full_2 = curbufmeths.get_name() + local tf_full_2 = api.nvim_buf_get_name(0) expect_exit(nvim_command, 'qall') reset() - local oldfiles = meths.get_vvar('oldfiles') + local oldfiles = api.nvim_get_vvar('oldfiles') table.sort(oldfiles) eq(2, #oldfiles) eq(testfilename, oldfiles[1]:sub(-#testfilename)) @@ -128,7 +126,7 @@ describe('ShaDa support code', function() eq(tf_full, oldfiles[1]) eq(tf_full_2, oldfiles[2]) nvim_command('rshada!') - oldfiles = meths.get_vvar('oldfiles') + oldfiles = api.nvim_get_vvar('oldfiles') table.sort(oldfiles) eq(2, #oldfiles) eq(testfilename, oldfiles[1]:sub(-#testfilename)) @@ -160,13 +158,12 @@ describe('ShaDa support code', function() nvim_command('wshada') nvim_command('quit') nvim_command('rshada') - nvim_command('normal! \15') -- <C-o> - eq(testfilename_2, funcs.bufname('%')) - eq({2, 0}, curwinmeths.get_cursor()) + nvim_command('normal! \15') -- <C-o> + eq(testfilename_2, fn.bufname('%')) + eq({ 2, 0 }, api.nvim_win_get_cursor(0)) end) - it('is able to dump and restore jump list with different times (slow!)', - function() + it('is able to dump and restore jump list with different times (slow!)', function() nvim_command('edit ' .. testfilename_2) nvim_command('sleep 2') nvim_command('normal! G') @@ -182,19 +179,19 @@ describe('ShaDa support code', function() reset() nvim_command('redraw') nvim_command('edit ' .. testfilename) - eq(testfilename, funcs.bufname('%')) + eq(testfilename, fn.bufname('%')) eq(1, nvim_current_line()) nvim_command('execute "normal! \\<C-o>"') - eq(testfilename, funcs.bufname('%')) + eq(testfilename, fn.bufname('%')) eq(2, nvim_current_line()) nvim_command('execute "normal! \\<C-o>"') - eq(testfilename_2, funcs.bufname('%')) + eq(testfilename_2, fn.bufname('%')) eq(1, nvim_current_line()) nvim_command('execute "normal! \\<C-o>"') - eq(testfilename_2, funcs.bufname('%')) + eq(testfilename_2, fn.bufname('%')) eq(2, nvim_current_line()) nvim_command('execute "normal! \\<C-o>"') - eq(testfilename_2, funcs.bufname('%')) + eq(testfilename_2, fn.bufname('%')) eq(2, nvim_current_line()) end) @@ -218,35 +215,41 @@ describe('ShaDa support code', function() -- -c temporary sets lnum to zero to make `+/pat` work, so calling setpcmark() -- during -c used to add item with zero lnum to jump list. - it('does not create incorrect file for non-existent buffers when writing from -c', - function() - local argv = helpers.new_argv{ - args_rm={ + it('does not create incorrect file for non-existent buffers when writing from -c', function() + local argv = helpers.new_argv { + args_rm = { '-i', - '--embed', -- no --embed + '--embed', -- no --embed + }, + args = { + '-i', + api.nvim_get_var('tmpname'), -- Use same shada file as parent. + '--cmd', + 'silent edit ' .. non_existent_testfilename, + '-c', + 'qall', }, - args={ - '-i', meths.get_var('tmpname'), -- Use same shada file as parent. - '--cmd', 'silent edit '..non_existent_testfilename, - '-c', 'qall'}, } - eq('', funcs.system(argv)) + eq('', fn.system(argv)) eq(0, exc_exec('rshada')) end) - it('does not create incorrect file for non-existent buffers opened from -c', - function() - local argv = helpers.new_argv{ - args_rm={ + it('does not create incorrect file for non-existent buffers opened from -c', function() + local argv = helpers.new_argv { + args_rm = { + '-i', + '--embed', -- no --embed + }, + args = { '-i', - '--embed', -- no --embed + api.nvim_get_var('tmpname'), -- Use same shada file as parent. + '-c', + 'silent edit ' .. non_existent_testfilename, + '-c', + 'autocmd VimEnter * qall', }, - args={ - '-i', meths.get_var('tmpname'), -- Use same shada file as parent. - '-c', 'silent edit '..non_existent_testfilename, - '-c', 'autocmd VimEnter * qall'}, } - eq('', funcs.system(argv)) + eq('', fn.system(argv)) eq(0, exc_exec('rshada')) end) diff --git a/test/functional/shada/merging_spec.lua b/test/functional/shada/merging_spec.lua index dad7aa851d..1b5c0eab5d 100644 --- a/test/functional/shada/merging_spec.lua +++ b/test/functional/shada/merging_spec.lua @@ -1,17 +1,15 @@ -- ShaDa merging data support local helpers = require('test.functional.helpers')(after_each) -local nvim_command, funcs, curbufmeths, eq = - helpers.command, helpers.funcs, - helpers.curbufmeths, helpers.eq +local nvim_command, fn, eq = helpers.command, helpers.fn, helpers.eq local exc_exec, exec_capture = helpers.exc_exec, helpers.exec_capture +local api = helpers.api local shada_helpers = require('test.functional.shada.helpers') local reset, clear, get_shada_rw = shada_helpers.reset, shada_helpers.clear, shada_helpers.get_shada_rw local read_shada_file = shada_helpers.read_shada_file -local wshada, sdrcmd, shada_fname = - get_shada_rw('Xtest-functional-shada-merging.shada') +local wshada, sdrcmd, shada_fname = get_shada_rw('Xtest-functional-shada-merging.shada') local mock_file_path = '/a/b/' if helpers.is_os('win') then @@ -25,8 +23,7 @@ describe('ShaDa history merging code', function() os.remove(shada_fname) end) - it('takes item with greater timestamp from Neovim instance when reading', - function() + it('takes item with greater timestamp from Neovim instance when reading', function() wshada('\004\001\009\147\000\196\002ab\196\001a') eq(0, exc_exec(sdrcmd())) wshada('\004\000\009\147\000\196\002ab\196\001b') @@ -44,8 +41,7 @@ describe('ShaDa history merging code', function() eq(1, found) end) - it('takes item with equal timestamp from Neovim instance when reading', - function() + it('takes item with equal timestamp from Neovim instance when reading', function() wshada('\004\000\009\147\000\196\002ab\196\001a') eq(0, exc_exec(sdrcmd())) wshada('\004\000\009\147\000\196\002ab\196\001b') @@ -63,8 +59,7 @@ describe('ShaDa history merging code', function() eq(1, found) end) - it('takes item with greater timestamp from ShaDa when reading', - function() + it('takes item with greater timestamp from ShaDa when reading', function() wshada('\004\000\009\147\000\196\002ab\196\001a') eq(0, exc_exec(sdrcmd())) wshada('\004\001\009\147\000\196\002ab\196\001b') @@ -82,8 +77,7 @@ describe('ShaDa history merging code', function() eq(1, found) end) - it('takes item with greater timestamp from Neovim instance when writing', - function() + it('takes item with greater timestamp from Neovim instance when writing', function() wshada('\004\001\009\147\000\196\002ab\196\001a') eq(0, exc_exec(sdrcmd())) wshada('\004\000\009\147\000\196\002ab\196\001b') @@ -99,8 +93,7 @@ describe('ShaDa history merging code', function() eq(1, found) end) - it('takes item with equal timestamp from Neovim instance when writing', - function() + it('takes item with equal timestamp from Neovim instance when writing', function() wshada('\004\000\009\147\000\196\002ab\196\001a') eq(0, exc_exec(sdrcmd())) wshada('\004\000\009\147\000\196\002ab\196\001b') @@ -116,8 +109,7 @@ describe('ShaDa history merging code', function() eq(1, found) end) - it('takes item with greater timestamp from ShaDa when writing', - function() + it('takes item with greater timestamp from ShaDa when writing', function() wshada('\004\000\009\147\000\196\002ab\196\001a') eq(0, exc_exec(sdrcmd())) wshada('\004\001\009\147\000\196\002ab\196\001b') @@ -133,20 +125,20 @@ describe('ShaDa history merging code', function() eq(1, found) end) - it('correctly reads history items with messed up timestamps', - function() - wshada('\004\010\009\147\000\196\002ab\196\001a' - .. '\004\010\009\147\000\196\002ac\196\001a' - .. '\004\005\009\147\000\196\002ad\196\001a' - .. '\004\100\009\147\000\196\002ae\196\001a' - .. '\004\090\009\147\000\196\002af\196\001a' - ) + it('correctly reads history items with messed up timestamps', function() + wshada( + '\004\010\009\147\000\196\002ab\196\001a' + .. '\004\010\009\147\000\196\002ac\196\001a' + .. '\004\005\009\147\000\196\002ad\196\001a' + .. '\004\100\009\147\000\196\002ae\196\001a' + .. '\004\090\009\147\000\196\002af\196\001a' + ) eq(0, exc_exec(sdrcmd())) os.remove(shada_fname) eq(0, exc_exec('wshada! ' .. shada_fname)) - local items = {'ad', 'ab', 'ac', 'af', 'ae'} + local items = { 'ad', 'ab', 'ac', 'af', 'ae' } for i, v in ipairs(items) do - eq(v, funcs.histget(':', i)) + eq(v, fn.histget(':', i)) end local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do @@ -159,16 +151,16 @@ describe('ShaDa history merging code', function() eq(#items, found) end) - it('correctly reorders history items with messed up timestamps when writing', - function() - wshada('\004\010\009\147\000\196\002ab\196\001a' - .. '\004\010\009\147\000\196\002ac\196\001a' - .. '\004\005\009\147\000\196\002ad\196\001a' - .. '\004\100\009\147\000\196\002ae\196\001a' - .. '\004\090\009\147\000\196\002af\196\001a' - ) + it('correctly reorders history items with messed up timestamps when writing', function() + wshada( + '\004\010\009\147\000\196\002ab\196\001a' + .. '\004\010\009\147\000\196\002ac\196\001a' + .. '\004\005\009\147\000\196\002ad\196\001a' + .. '\004\100\009\147\000\196\002ae\196\001a' + .. '\004\090\009\147\000\196\002af\196\001a' + ) eq(0, exc_exec('wshada ' .. shada_fname)) - local items = {'ad', 'ab', 'ac', 'af', 'ae'} + local items = { 'ad', 'ab', 'ac', 'af', 'ae' } local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do if v.type == 4 and v.value[1] == 0 then @@ -180,24 +172,24 @@ describe('ShaDa history merging code', function() eq(#items, found) end) - it('correctly merges history items with duplicate mid entry when writing', - function() + it('correctly merges history items with duplicate mid entry when writing', function() -- Regression test: ShaDa code used to crash here. -- Conditions: -- 1. Entry which is duplicate to non-last entry. -- 2. At least one more non-duplicate entry. - wshada('\004\000\009\147\000\196\002ab\196\001a' - .. '\004\001\009\147\000\196\002ac\196\001a' - .. '\004\002\009\147\000\196\002ad\196\001a' - .. '\004\003\009\147\000\196\002ac\196\001a' - .. '\004\004\009\147\000\196\002af\196\001a' - .. '\004\005\009\147\000\196\002ae\196\001a' - .. '\004\006\009\147\000\196\002ag\196\001a' - .. '\004\007\009\147\000\196\002ah\196\001a' - .. '\004\008\009\147\000\196\002ai\196\001a' - ) + wshada( + '\004\000\009\147\000\196\002ab\196\001a' + .. '\004\001\009\147\000\196\002ac\196\001a' + .. '\004\002\009\147\000\196\002ad\196\001a' + .. '\004\003\009\147\000\196\002ac\196\001a' + .. '\004\004\009\147\000\196\002af\196\001a' + .. '\004\005\009\147\000\196\002ae\196\001a' + .. '\004\006\009\147\000\196\002ag\196\001a' + .. '\004\007\009\147\000\196\002ah\196\001a' + .. '\004\008\009\147\000\196\002ai\196\001a' + ) eq(0, exc_exec('wshada ' .. shada_fname)) - local items = {'ab', 'ad', 'ac', 'af', 'ae', 'ag', 'ah', 'ai'} + local items = { 'ab', 'ad', 'ac', 'af', 'ae', 'ag', 'ah', 'ai' } local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do if v.type == 4 and v.value[1] == 0 then @@ -209,20 +201,20 @@ describe('ShaDa history merging code', function() eq(#items, found) end) - it('correctly merges history items with duplicate adj entry when writing', - function() - wshada('\004\000\009\147\000\196\002ab\196\001a' - .. '\004\001\009\147\000\196\002ac\196\001a' - .. '\004\002\009\147\000\196\002ad\196\001a' - .. '\004\003\009\147\000\196\002ad\196\001a' - .. '\004\004\009\147\000\196\002af\196\001a' - .. '\004\005\009\147\000\196\002ae\196\001a' - .. '\004\006\009\147\000\196\002ag\196\001a' - .. '\004\007\009\147\000\196\002ah\196\001a' - .. '\004\008\009\147\000\196\002ai\196\001a' - ) + it('correctly merges history items with duplicate adj entry when writing', function() + wshada( + '\004\000\009\147\000\196\002ab\196\001a' + .. '\004\001\009\147\000\196\002ac\196\001a' + .. '\004\002\009\147\000\196\002ad\196\001a' + .. '\004\003\009\147\000\196\002ad\196\001a' + .. '\004\004\009\147\000\196\002af\196\001a' + .. '\004\005\009\147\000\196\002ae\196\001a' + .. '\004\006\009\147\000\196\002ag\196\001a' + .. '\004\007\009\147\000\196\002ah\196\001a' + .. '\004\008\009\147\000\196\002ai\196\001a' + ) eq(0, exc_exec('wshada ' .. shada_fname)) - local items = {'ab', 'ac', 'ad', 'af', 'ae', 'ag', 'ah', 'ai'} + local items = { 'ab', 'ac', 'ad', 'af', 'ae', 'ag', 'ah', 'ai' } local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do if v.type == 4 and v.value[1] == 0 then @@ -242,48 +234,43 @@ describe('ShaDa search pattern support code', function() os.remove(shada_fname) end) - it('uses last search pattern with gt timestamp from instance when reading', - function() + it('uses last search pattern with gt timestamp from instance when reading', function() wshada('\002\001\011\130\162sX\194\162sp\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\002\000\011\130\162sX\194\162sp\196\001?') eq(0, exc_exec(sdrcmd())) - eq('-', funcs.getreg('/')) + eq('-', fn.getreg('/')) end) - it('uses last search pattern with gt tstamp from file when reading with bang', - function() + it('uses last search pattern with gt tstamp from file when reading with bang', function() wshada('\002\001\011\130\162sX\194\162sp\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\002\000\011\130\162sX\194\162sp\196\001?') eq(0, exc_exec(sdrcmd(true))) - eq('?', funcs.getreg('/')) + eq('?', fn.getreg('/')) end) - it('uses last search pattern with eq timestamp from instance when reading', - function() + it('uses last search pattern with eq timestamp from instance when reading', function() wshada('\002\001\011\130\162sX\194\162sp\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\002\001\011\130\162sX\194\162sp\196\001?') eq(0, exc_exec(sdrcmd())) - eq('-', funcs.getreg('/')) + eq('-', fn.getreg('/')) end) - it('uses last search pattern with gt timestamp from file when reading', - function() + it('uses last search pattern with gt timestamp from file when reading', function() wshada('\002\001\011\130\162sX\194\162sp\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\002\002\011\130\162sX\194\162sp\196\001?') eq(0, exc_exec(sdrcmd())) - eq('?', funcs.getreg('/')) + eq('?', fn.getreg('/')) end) - it('uses last search pattern with gt timestamp from instance when writing', - function() + it('uses last search pattern with gt timestamp from instance when writing', function() wshada('\002\001\011\130\162sX\194\162sp\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\002\000\011\130\162sX\194\162sp\196\001?') - eq('-', funcs.getreg('/')) + eq('-', fn.getreg('/')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do @@ -294,12 +281,11 @@ describe('ShaDa search pattern support code', function() eq(1, found) end) - it('uses last search pattern with eq timestamp from instance when writing', - function() + it('uses last search pattern with eq timestamp from instance when writing', function() wshada('\002\001\011\130\162sX\194\162sp\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\002\001\011\130\162sX\194\162sp\196\001?') - eq('-', funcs.getreg('/')) + eq('-', fn.getreg('/')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do @@ -310,12 +296,11 @@ describe('ShaDa search pattern support code', function() eq(1, found) end) - it('uses last search pattern with gt timestamp from file when writing', - function() + it('uses last search pattern with gt timestamp from file when writing', function() wshada('\002\001\011\130\162sX\194\162sp\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\002\002\011\130\162sX\194\162sp\196\001?') - eq('-', funcs.getreg('/')) + eq('-', fn.getreg('/')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do @@ -326,48 +311,43 @@ describe('ShaDa search pattern support code', function() eq(1, found) end) - it('uses last s/ pattern with gt timestamp from instance when reading', - function() + it('uses last s/ pattern with gt timestamp from instance when reading', function() wshada('\002\001\011\130\162ss\195\162sp\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\002\000\011\130\162ss\195\162sp\196\001?') eq(0, exc_exec(sdrcmd())) - eq('-', funcs.getreg('/')) + eq('-', fn.getreg('/')) end) - it('uses last s/ pattern with gt timestamp from file when reading with !', - function() + it('uses last s/ pattern with gt timestamp from file when reading with !', function() wshada('\002\001\011\130\162ss\195\162sp\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\002\000\011\130\162ss\195\162sp\196\001?') eq(0, exc_exec(sdrcmd(true))) - eq('?', funcs.getreg('/')) + eq('?', fn.getreg('/')) end) - it('uses last s/ pattern with eq timestamp from instance when reading', - function() + it('uses last s/ pattern with eq timestamp from instance when reading', function() wshada('\002\001\011\130\162ss\195\162sp\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\002\001\011\130\162ss\195\162sp\196\001?') eq(0, exc_exec(sdrcmd())) - eq('-', funcs.getreg('/')) + eq('-', fn.getreg('/')) end) - it('uses last s/ pattern with gt timestamp from file when reading', - function() + it('uses last s/ pattern with gt timestamp from file when reading', function() wshada('\002\001\011\130\162ss\195\162sp\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\002\002\011\130\162ss\195\162sp\196\001?') eq(0, exc_exec(sdrcmd())) - eq('?', funcs.getreg('/')) + eq('?', fn.getreg('/')) end) - it('uses last s/ pattern with gt timestamp from instance when writing', - function() + it('uses last s/ pattern with gt timestamp from instance when writing', function() wshada('\002\001\011\130\162ss\195\162sp\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\002\000\011\130\162ss\195\162sp\196\001?') - eq('-', funcs.getreg('/')) + eq('-', fn.getreg('/')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do @@ -378,12 +358,11 @@ describe('ShaDa search pattern support code', function() eq(1, found) end) - it('uses last s/ pattern with eq timestamp from instance when writing', - function() + it('uses last s/ pattern with eq timestamp from instance when writing', function() wshada('\002\001\011\130\162ss\195\162sp\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\002\001\011\130\162ss\195\162sp\196\001?') - eq('-', funcs.getreg('/')) + eq('-', fn.getreg('/')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do @@ -394,12 +373,11 @@ describe('ShaDa search pattern support code', function() eq(1, found) end) - it('uses last s/ pattern with gt timestamp from file when writing', - function() + it('uses last s/ pattern with gt timestamp from file when writing', function() wshada('\002\001\011\130\162ss\195\162sp\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\002\002\011\130\162ss\195\162sp\196\001?') - eq('-', funcs.getreg('/')) + eq('-', fn.getreg('/')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do @@ -418,52 +396,47 @@ describe('ShaDa replacement string support code', function() os.remove(shada_fname) end) - it('uses last replacement with gt timestamp from instance when reading', - function() + it('uses last replacement with gt timestamp from instance when reading', function() wshada('\003\001\004\145\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\003\000\004\145\196\001?') eq(0, exc_exec(sdrcmd())) nvim_command('s/.*/~') - eq('-', funcs.getline('.')) + eq('-', fn.getline('.')) nvim_command('bwipeout!') end) - it('uses last replacement with gt timestamp from file when reading with bang', - function() + it('uses last replacement with gt timestamp from file when reading with bang', function() wshada('\003\001\004\145\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\003\000\004\145\196\001?') eq(0, exc_exec(sdrcmd(true))) nvim_command('s/.*/~') - eq('?', funcs.getline('.')) + eq('?', fn.getline('.')) nvim_command('bwipeout!') end) - it('uses last replacement with eq timestamp from instance when reading', - function() + it('uses last replacement with eq timestamp from instance when reading', function() wshada('\003\001\004\145\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\003\001\004\145\196\001?') eq(0, exc_exec(sdrcmd())) nvim_command('s/.*/~') - eq('-', funcs.getline('.')) + eq('-', fn.getline('.')) nvim_command('bwipeout!') end) - it('uses last replacement with gt timestamp from file when reading', - function() + it('uses last replacement with gt timestamp from file when reading', function() wshada('\003\001\004\145\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\003\002\004\145\196\001?') eq(0, exc_exec(sdrcmd())) nvim_command('s/.*/~') - eq('?', funcs.getline('.')) + eq('?', fn.getline('.')) nvim_command('bwipeout!') end) - it('uses last replacement with gt timestamp from instance when writing', - function() + it('uses last replacement with gt timestamp from instance when writing', function() wshada('\003\001\004\145\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\003\000\004\145\196\001?') @@ -477,8 +450,7 @@ describe('ShaDa replacement string support code', function() eq(1, found) end) - it('uses last replacement with eq timestamp from instance when writing', - function() + it('uses last replacement with eq timestamp from instance when writing', function() wshada('\003\001\004\145\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\003\001\004\145\196\001?') @@ -492,8 +464,7 @@ describe('ShaDa replacement string support code', function() eq(1, found) end) - it('uses last replacement with gt timestamp from file when writing', - function() + it('uses last replacement with gt timestamp from file when writing', function() wshada('\003\001\004\145\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\003\002\004\145\196\001?') @@ -515,21 +486,20 @@ describe('ShaDa marks support code', function() os.remove(shada_fname) end) - it('uses last A mark with gt timestamp from instance when reading', - function() + it('uses last A mark with gt timestamp from instance when reading', function() wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) wshada('\007\000\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') eq(0, exc_exec(sdrcmd())) nvim_command('normal! `A') - eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t')) + eq('-', fn.fnamemodify(api.nvim_buf_get_name(0), ':t')) end) it('can merge with file with mark 9 as the only numeric mark', function() wshada('\007\001\014\130\161f\196\006' .. mock_file_path .. '-\161n9') eq(0, exc_exec(sdrcmd())) nvim_command('normal! `9oabc') - eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t')) + eq('-', fn.fnamemodify(api.nvim_buf_get_name(0), ':t')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = {} for _, v in ipairs(read_shada_file(shada_fname)) do @@ -538,37 +508,66 @@ describe('ShaDa marks support code', function() found[name] = (found[name] or 0) + 1 end end - eq({['0']=1, ['1']=1}, found) + eq({ ['0'] = 1, ['1'] = 1 }, found) end) it('removes duplicates while merging', function() - wshada('\007\001\014\130\161f\196\006' .. mock_file_path .. '-\161n9' - .. '\007\001\014\130\161f\196\006' .. mock_file_path .. '-\161n9') + wshada( + '\007\001\014\130\161f\196\006' + .. mock_file_path + .. '-\161n9' + .. '\007\001\014\130\161f\196\006' + .. mock_file_path + .. '-\161n9' + ) eq(0, exc_exec(sdrcmd())) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do if v.type == 7 and v.value.f == mock_file_path .. '-' then - print(require('test.helpers').format_luav(v)) + print(require('test.format_string').format_luav(v)) found = found + 1 end end eq(1, found) end) - it('does not leak when no append is performed due to too many marks', - function() - wshada('\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'a\161n0' - .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'b\161n1' - .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161n2' - .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161n3' - .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'e\161n4' - .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'f\161n5' - .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'g\161n6' - .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'h\161n7' - .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'i\161n8' - .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'j\161n9' - .. '\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'k\161n9') + it('does not leak when no append is performed due to too many marks', function() + wshada( + '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'a\161n0' + .. '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'b\161n1' + .. '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'c\161n2' + .. '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'd\161n3' + .. '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'e\161n4' + .. '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'f\161n5' + .. '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'g\161n6' + .. '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'h\161n7' + .. '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'i\161n8' + .. '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'j\161n9' + .. '\007\001\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'k\161n9' + ) eq(0, exc_exec(sdrcmd())) eq(0, exc_exec('wshada ' .. shada_fname)) local found = {} @@ -577,22 +576,45 @@ describe('ShaDa marks support code', function() found[#found + 1] = v.value.f:sub(#v.value.f) end end - eq({'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}, found) - end) - - it('does not leak when last mark in file removes some of the earlier ones', - function() - wshada('\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'a\161n0' - .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'b\161n1' - .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161n2' - .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161n3' - .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'e\161n4' - .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'f\161n5' - .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'g\161n6' - .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'h\161n7' - .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'i\161n8' - .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'j\161n9' - .. '\007\003\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'k\161n9') + eq({ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }, found) + end) + + it('does not leak when last mark in file removes some of the earlier ones', function() + wshada( + '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'a\161n0' + .. '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'b\161n1' + .. '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'c\161n2' + .. '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'd\161n3' + .. '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'e\161n4' + .. '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'f\161n5' + .. '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'g\161n6' + .. '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'h\161n7' + .. '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'i\161n8' + .. '\007\002\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'j\161n9' + .. '\007\003\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'k\161n9' + ) eq(0, exc_exec(sdrcmd())) eq(0, exc_exec('wshada ' .. shada_fname)) local found = {} @@ -601,46 +623,42 @@ describe('ShaDa marks support code', function() found[#found + 1] = v.value.f:sub(#v.value.f) end end - eq({'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k'}, found) + eq({ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k' }, found) end) - it('uses last A mark with gt timestamp from file when reading with !', - function() + it('uses last A mark with gt timestamp from file when reading with !', function() wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) wshada('\007\000\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') eq(0, exc_exec(sdrcmd(true))) nvim_command('normal! `A') - eq('?', funcs.fnamemodify(curbufmeths.get_name(), ':t')) + eq('?', fn.fnamemodify(api.nvim_buf_get_name(0), ':t')) end) - it('uses last A mark with eq timestamp from instance when reading', - function() + it('uses last A mark with eq timestamp from instance when reading', function() wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') eq(0, exc_exec(sdrcmd())) nvim_command('normal! `A') - eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t')) + eq('-', fn.fnamemodify(api.nvim_buf_get_name(0), ':t')) end) - it('uses last A mark with gt timestamp from file when reading', - function() + it('uses last A mark with gt timestamp from file when reading', function() wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) wshada('\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') eq(0, exc_exec(sdrcmd())) nvim_command('normal! `A') - eq('?', funcs.fnamemodify(curbufmeths.get_name(), ':t')) + eq('?', fn.fnamemodify(api.nvim_buf_get_name(0), ':t')) end) - it('uses last A mark with gt timestamp from instance when writing', - function() + it('uses last A mark with gt timestamp from instance when writing', function() wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) wshada('\007\000\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') nvim_command('normal! `A') - eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t')) + eq('-', fn.fnamemodify(api.nvim_buf_get_name(0), ':t')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = {} for _, v in ipairs(read_shada_file(shada_fname)) do @@ -649,16 +667,15 @@ describe('ShaDa marks support code', function() found[name] = (found[name] or 0) + 1 end end - eq({['0']=1, A=1}, found) + eq({ ['0'] = 1, A = 1 }, found) end) - it('uses last A mark with eq timestamp from instance when writing', - function() + it('uses last A mark with eq timestamp from instance when writing', function() wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') nvim_command('normal! `A') - eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t')) + eq('-', fn.fnamemodify(api.nvim_buf_get_name(0), ':t')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = {} for _, v in ipairs(read_shada_file(shada_fname)) do @@ -667,7 +684,7 @@ describe('ShaDa marks support code', function() found[name] = (found[name] or 0) + 1 end end - eq({['0']=1, A=1}, found) + eq({ ['0'] = 1, A = 1 }, found) end) it('uses last A mark with gt timestamp from file when writing', function() @@ -675,7 +692,7 @@ describe('ShaDa marks support code', function() eq(0, exc_exec(sdrcmd())) wshada('\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') nvim_command('normal! `A') - eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t')) + eq('-', fn.fnamemodify(api.nvim_buf_get_name(0), ':t')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = {} for _, v in ipairs(read_shada_file(shada_fname)) do @@ -686,70 +703,69 @@ describe('ShaDa marks support code', function() found[name] = t end end - eq({['0']={[mock_file_path .. '-']=1}, A={[mock_file_path .. '?']=1}}, found) + eq({ ['0'] = { [mock_file_path .. '-'] = 1 }, A = { [mock_file_path .. '?'] = 1 } }, found) end) - it('uses last a mark with gt timestamp from instance when reading', - function() + it('uses last a mark with gt timestamp from instance when reading', function() nvim_command('edit ' .. mock_file_path .. '-') - funcs.setline(1, {'-', '?'}) + fn.setline(1, { '-', '?' }) wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) wshada('\010\000\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) nvim_command('normal! `a') - eq('-', funcs.getline('.')) + eq('-', fn.getline('.')) end) - it('uses last a mark with gt timestamp from file when reading with !', - function() + it('uses last a mark with gt timestamp from file when reading with !', function() nvim_command('edit ' .. mock_file_path .. '-') - funcs.setline(1, {'-', '?'}) + fn.setline(1, { '-', '?' }) wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) wshada('\010\000\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd(true))) nvim_command('normal! `a') - eq('?', funcs.getline('.')) + eq('?', fn.getline('.')) end) - it('uses last a mark with eq timestamp from instance when reading', - function() + it('uses last a mark with eq timestamp from instance when reading', function() nvim_command('edit ' .. mock_file_path .. '-') - funcs.setline(1, {'-', '?'}) + fn.setline(1, { '-', '?' }) wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) wshada('\010\001\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) nvim_command('normal! `a') - eq('-', funcs.getline('.')) + eq('-', fn.getline('.')) end) - it('uses last a mark with gt timestamp from file when reading', - function() + it('uses last a mark with gt timestamp from file when reading', function() nvim_command('edit ' .. mock_file_path .. '-') - funcs.setline(1, {'-', '?'}) + fn.setline(1, { '-', '?' }) wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) wshada('\010\002\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) nvim_command('normal! `a') - eq('?', funcs.getline('.')) + eq('?', fn.getline('.')) end) - it('uses last a mark with gt timestamp from instance when writing', - function() + it('uses last a mark with gt timestamp from instance when writing', function() nvim_command('edit ' .. mock_file_path .. '-') - funcs.setline(1, {'-', '?'}) + fn.setline(1, { '-', '?' }) wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) wshada('\010\000\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') nvim_command('normal! `a') - eq('-', funcs.getline('.')) + eq('-', fn.getline('.')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 10 and v.value.f == '' .. mock_file_path .. '-' and v.value.n == ('a'):byte() then + if + v.type == 10 + and v.value.f == '' .. mock_file_path .. '-' + and v.value.n == ('a'):byte() + then eq(true, v.value.l == 1 or v.value.l == nil) found = found + 1 end @@ -757,19 +773,22 @@ describe('ShaDa marks support code', function() eq(1, found) end) - it('uses last a mark with eq timestamp from instance when writing', - function() + it('uses last a mark with eq timestamp from instance when writing', function() nvim_command('edit ' .. mock_file_path .. '-') - funcs.setline(1, {'-', '?'}) + fn.setline(1, { '-', '?' }) wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) wshada('\010\001\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') nvim_command('normal! `a') - eq('-', funcs.getline('.')) + eq('-', fn.getline('.')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 10 and v.value.f == '' .. mock_file_path .. '-' and v.value.n == ('a'):byte() then + if + v.type == 10 + and v.value.f == '' .. mock_file_path .. '-' + and v.value.n == ('a'):byte() + then eq(true, v.value.l == 1 or v.value.l == nil) found = found + 1 end @@ -777,19 +796,22 @@ describe('ShaDa marks support code', function() eq(1, found) end) - it('uses last a mark with gt timestamp from file when writing', - function() + it('uses last a mark with gt timestamp from file when writing', function() nvim_command('edit ' .. mock_file_path .. '-') - funcs.setline(1, {'-', '?'}) + fn.setline(1, { '-', '?' }) wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) wshada('\010\002\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') nvim_command('normal! `a') - eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t')) + eq('-', fn.fnamemodify(api.nvim_buf_get_name(0), ':t')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 10 and v.value.f == '' .. mock_file_path .. '-' and v.value.n == ('a'):byte() then + if + v.type == 10 + and v.value.f == '' .. mock_file_path .. '-' + and v.value.n == ('a'):byte() + then eq(2, v.value.l) found = found + 1 end @@ -805,87 +827,80 @@ describe('ShaDa registers support code', function() os.remove(shada_fname) end) - it('uses last a register with gt timestamp from instance when reading', - function() + it('uses last a register with gt timestamp from instance when reading', function() wshada('\005\001\015\131\161na\162rX\194\162rc\145\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\005\000\015\131\161na\162rX\194\162rc\145\196\001?') eq(0, exc_exec(sdrcmd())) - eq('-', funcs.getreg('a')) + eq('-', fn.getreg('a')) end) - it('uses last a register with gt timestamp from file when reading with !', - function() + it('uses last a register with gt timestamp from file when reading with !', function() wshada('\005\001\015\131\161na\162rX\194\162rc\145\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\005\000\015\131\161na\162rX\194\162rc\145\196\001?') eq(0, exc_exec(sdrcmd(true))) - eq('?', funcs.getreg('a')) + eq('?', fn.getreg('a')) end) - it('uses last a register with eq timestamp from instance when reading', - function() + it('uses last a register with eq timestamp from instance when reading', function() wshada('\005\001\015\131\161na\162rX\194\162rc\145\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\005\001\015\131\161na\162rX\194\162rc\145\196\001?') eq(0, exc_exec(sdrcmd())) - eq('-', funcs.getreg('a')) + eq('-', fn.getreg('a')) end) - it('uses last a register with gt timestamp from file when reading', - function() + it('uses last a register with gt timestamp from file when reading', function() wshada('\005\001\015\131\161na\162rX\194\162rc\145\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\005\002\015\131\161na\162rX\194\162rc\145\196\001?') eq(0, exc_exec(sdrcmd())) - eq('?', funcs.getreg('a')) + eq('?', fn.getreg('a')) end) - it('uses last a register with gt timestamp from instance when writing', - function() + it('uses last a register with gt timestamp from instance when writing', function() wshada('\005\001\015\131\161na\162rX\194\162rc\145\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\005\000\015\131\161na\162rX\194\162rc\145\196\001?') - eq('-', funcs.getreg('a')) + eq('-', fn.getreg('a')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do if v.type == 5 and v.value.n == ('a'):byte() then - eq({'-'}, v.value.rc) + eq({ '-' }, v.value.rc) found = found + 1 end end eq(1, found) end) - it('uses last a register with eq timestamp from instance when writing', - function() + it('uses last a register with eq timestamp from instance when writing', function() wshada('\005\001\015\131\161na\162rX\194\162rc\145\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\005\001\015\131\161na\162rX\194\162rc\145\196\001?') - eq('-', funcs.getreg('a')) + eq('-', fn.getreg('a')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do if v.type == 5 and v.value.n == ('a'):byte() then - eq({'-'}, v.value.rc) + eq({ '-' }, v.value.rc) found = found + 1 end end eq(1, found) end) - it('uses last a register with gt timestamp from file when writing', - function() + it('uses last a register with gt timestamp from file when writing', function() wshada('\005\001\015\131\161na\162rX\194\162rc\145\196\001-') eq(0, exc_exec(sdrcmd())) wshada('\005\002\015\131\161na\162rX\194\162rc\145\196\001?') - eq('-', funcs.getreg('a')) + eq('-', fn.getreg('a')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do if v.type == 5 and v.value.n == ('a'):byte() then - eq({'?'}, v.value.rc) + eq({ '?' }, v.value.rc) found = found + 1 end end @@ -901,39 +916,84 @@ describe('ShaDa jumps support code', function() end) it('merges jumps when reading', function() - wshada('\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002' - .. '\008\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161l\002' - .. '\008\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'e\161l\002') - eq(0, exc_exec(sdrcmd())) - wshada('\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002' - .. '\008\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161l\003' - .. '\008\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'f\161l\002') - eq(0, exc_exec(sdrcmd())) - eq('', curbufmeths.get_name()) - eq( ' jump line col file/text\n' - .. ' 5 2 0 ' .. mock_file_path .. 'c\n' - .. ' 4 2 0 ' .. mock_file_path .. 'd\n' - .. ' 3 3 0 ' .. mock_file_path .. 'd\n' - .. ' 2 2 0 ' .. mock_file_path .. 'e\n' - .. ' 1 2 0 ' .. mock_file_path .. 'f\n' - .. '>', exec_capture('jumps')) + wshada( + '\008\001\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'c\161l\002' + .. '\008\004\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'd\161l\002' + .. '\008\007\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'e\161l\002' + ) + eq(0, exc_exec(sdrcmd())) + wshada( + '\008\001\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'c\161l\002' + .. '\008\004\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'd\161l\003' + .. '\008\007\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'f\161l\002' + ) + eq(0, exc_exec(sdrcmd())) + eq('', api.nvim_buf_get_name(0)) + eq( + ' jump line col file/text\n' + .. ' 5 2 0 ' + .. mock_file_path + .. 'c\n' + .. ' 4 2 0 ' + .. mock_file_path + .. 'd\n' + .. ' 3 3 0 ' + .. mock_file_path + .. 'd\n' + .. ' 2 2 0 ' + .. mock_file_path + .. 'e\n' + .. ' 1 2 0 ' + .. mock_file_path + .. 'f\n' + .. '>', + exec_capture('jumps') + ) end) it('merges jumps when writing', function() - wshada('\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002' - .. '\008\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161l\002' - .. '\008\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'e\161l\002') - eq(0, exc_exec(sdrcmd())) - wshada('\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002' - .. '\008\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161l\003' - .. '\008\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'f\161l\002') + wshada( + '\008\001\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'c\161l\002' + .. '\008\004\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'd\161l\002' + .. '\008\007\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'e\161l\002' + ) + eq(0, exc_exec(sdrcmd())) + wshada( + '\008\001\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'c\161l\002' + .. '\008\004\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'd\161l\003' + .. '\008\007\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'f\161l\002' + ) eq(0, exc_exec('wshada ' .. shada_fname)) local jumps = { - {file='' .. mock_file_path .. 'c', line=2}, - {file='' .. mock_file_path .. 'd', line=2}, - {file='' .. mock_file_path .. 'd', line=3}, - {file='' .. mock_file_path .. 'e', line=2}, - {file='' .. mock_file_path .. 'f', line=2}, + { file = '' .. mock_file_path .. 'c', line = 2 }, + { file = '' .. mock_file_path .. 'd', line = 2 }, + { file = '' .. mock_file_path .. 'd', line = 3 }, + { file = '' .. mock_file_path .. 'e', line = 2 }, + { file = '' .. mock_file_path .. 'f', line = 2 }, } local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do @@ -949,25 +1009,28 @@ describe('ShaDa jumps support code', function() it('merges JUMPLISTSIZE jumps when writing', function() local jumps = {} local shada = '' - for i = 1,100 do - shada = shada .. ('\008%c\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l%c' - ):format(i, i) - jumps[i] = {file='' .. mock_file_path .. 'c', line=i} + for i = 1, 100 do + shada = shada + .. ('\008%c\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l%c'):format(i, i) + jumps[i] = { file = '' .. mock_file_path .. 'c', line = i } end wshada(shada) eq(0, exc_exec(sdrcmd())) shada = '' - for i = 1,101 do + for i = 1, 101 do local t = i * 2 - shada = shada .. ( - '\008\204%c\019\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\204%c' - ):format(t, t) - jumps[(t > #jumps + 1) and (#jumps + 1) or t] = {file='' .. mock_file_path .. 'c', line=t} + shada = shada + .. ('\008\204%c\019\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\204%c'):format( + t, + t + ) + jumps[(t > #jumps + 1) and (#jumps + 1) or t] = + { file = '' .. mock_file_path .. 'c', line = t } end wshada(shada) eq(0, exc_exec('wshada ' .. shada_fname)) local shift = #jumps - 100 - for i = 1,100 do + for i = 1, 100 do jumps[i] = jumps[i + shift] end local found = 0 @@ -992,40 +1055,75 @@ describe('ShaDa changes support code', function() it('merges changes when reading', function() nvim_command('edit ' .. mock_file_path .. 'c') nvim_command('keepjumps call setline(1, range(7))') - wshada('\011\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\001' - .. '\011\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002' - .. '\011\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\003') - eq(0, exc_exec(sdrcmd())) - wshada('\011\001\018\131\162mX\194\161f\196\006' .. mock_file_path .. 'c\161l\001' - .. '\011\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\005' - .. '\011\008\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\004') - eq(0, exc_exec(sdrcmd())) - eq( 'change line col text\n' - .. ' 5 1 0 0\n' - .. ' 4 2 0 1\n' - .. ' 3 5 0 4\n' - .. ' 2 3 0 2\n' - .. ' 1 4 0 3\n' - .. '>', exec_capture('changes')) + wshada( + '\011\001\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'c\161l\001' + .. '\011\004\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'c\161l\002' + .. '\011\007\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'c\161l\003' + ) + eq(0, exc_exec(sdrcmd())) + wshada( + '\011\001\018\131\162mX\194\161f\196\006' + .. mock_file_path + .. 'c\161l\001' + .. '\011\004\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'c\161l\005' + .. '\011\008\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'c\161l\004' + ) + eq(0, exc_exec(sdrcmd())) + eq( + 'change line col text\n' + .. ' 5 1 0 0\n' + .. ' 4 2 0 1\n' + .. ' 3 5 0 4\n' + .. ' 2 3 0 2\n' + .. ' 1 4 0 3\n' + .. '>', + exec_capture('changes') + ) end) it('merges changes when writing', function() nvim_command('edit ' .. mock_file_path .. 'c') nvim_command('keepjumps call setline(1, range(7))') - wshada('\011\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\001' - .. '\011\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002' - .. '\011\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\003') - eq(0, exc_exec(sdrcmd())) - wshada('\011\001\018\131\162mX\194\161f\196\006' .. mock_file_path .. 'c\161l\001' - .. '\011\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\005' - .. '\011\008\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\004') + wshada( + '\011\001\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'c\161l\001' + .. '\011\004\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'c\161l\002' + .. '\011\007\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'c\161l\003' + ) + eq(0, exc_exec(sdrcmd())) + wshada( + '\011\001\018\131\162mX\194\161f\196\006' + .. mock_file_path + .. 'c\161l\001' + .. '\011\004\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'c\161l\005' + .. '\011\008\018\131\162mX\195\161f\196\006' + .. mock_file_path + .. 'c\161l\004' + ) eq(0, exc_exec('wshada ' .. shada_fname)) local changes = { - {line=1}, - {line=2}, - {line=5}, - {line=3}, - {line=4}, + { line = 1 }, + { line = 2 }, + { line = 5 }, + { line = 3 }, + { line = 4 }, } local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do @@ -1042,25 +1140,27 @@ describe('ShaDa changes support code', function() nvim_command('keepjumps call setline(1, range(202))') local changes = {} local shada = '' - for i = 1,100 do - shada = shada .. ('\011%c\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l%c' - ):format(i, i) - changes[i] = {line=i} + for i = 1, 100 do + shada = shada + .. ('\011%c\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l%c'):format(i, i) + changes[i] = { line = i } end wshada(shada) eq(0, exc_exec(sdrcmd())) shada = '' - for i = 1,101 do + for i = 1, 101 do local t = i * 2 - shada = shada .. ( - '\011\204%c\019\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\204%c' - ):format(t, t) - changes[(t > #changes + 1) and (#changes + 1) or t] = {line=t} + shada = shada + .. ('\011\204%c\019\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\204%c'):format( + t, + t + ) + changes[(t > #changes + 1) and (#changes + 1) or t] = { line = t } end wshada(shada) eq(0, exc_exec('wshada ' .. shada_fname)) local shift = #changes - 100 - for i = 1,100 do + for i = 1, 100 do changes[i] = changes[i + shift] end local found = 0 @@ -1073,36 +1173,37 @@ describe('ShaDa changes support code', function() eq(found, 100) end) - it('merges JUMPLISTSIZE changes when writing, with new items between old', - function() + it('merges JUMPLISTSIZE changes when writing, with new items between old', function() nvim_command('edit ' .. mock_file_path .. 'c') nvim_command('keepjumps call setline(1, range(202))') local shada = '' - for i = 1,101 do + for i = 1, 101 do local t = i * 2 - shada = shada .. ( - '\011\204%c\019\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\204%c' - ):format(t, t) + shada = shada + .. ('\011\204%c\019\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\204%c'):format( + t, + t + ) end wshada(shada) eq(0, exc_exec(sdrcmd())) shada = '' - for i = 1,100 do - shada = shada .. ('\011%c\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l%c' - ):format(i, i) + for i = 1, 100 do + shada = shada + .. ('\011%c\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l%c'):format(i, i) end local changes = {} for i = 1, 100 do - changes[i] = {line=i} + changes[i] = { line = i } end for i = 1, 101 do local t = i * 2 - changes[(t > #changes + 1) and (#changes + 1) or t] = {line=t} + changes[(t > #changes + 1) and (#changes + 1) or t] = { line = t } end wshada(shada) eq(0, exc_exec('wshada ' .. shada_fname)) local shift = #changes - 100 - for i = 1,100 do + for i = 1, 100 do changes[i] = changes[i + shift] end local found = 0 diff --git a/test/functional/shada/registers_spec.lua b/test/functional/shada/registers_spec.lua index 6aaa54cce8..ef15ab9a05 100644 --- a/test/functional/shada/registers_spec.lua +++ b/test/functional/shada/registers_spec.lua @@ -1,6 +1,6 @@ -- ShaDa registers saving/reading support local helpers = require('test.functional.helpers')(after_each) -local nvim_command, funcs, eq = helpers.command, helpers.funcs, helpers.eq +local nvim_command, fn, eq = helpers.command, helpers.fn, helpers.eq local shada_helpers = require('test.functional.shada.helpers') local reset, clear = shada_helpers.reset, shada_helpers.clear @@ -8,15 +8,15 @@ local expect_exit = helpers.expect_exit local setreg = function(name, contents, typ) if type(contents) == 'string' then - contents = {contents} + contents = { contents } end - funcs.setreg(name, contents, typ) + fn.setreg(name, contents, typ) end local getreg = function(name) return { - funcs.getreg(name, 1, 1), - funcs.getregtype(name), + fn.getreg(name, 1, 1), + fn.getregtype(name), } end @@ -25,159 +25,154 @@ describe('ShaDa support code', function() after_each(clear) it('is able to dump and restore registers and their type', function() - setreg('c', {'d', 'e', ''}, 'c') - setreg('l', {'a', 'b', 'cde'}, 'l') - setreg('b', {'bca', 'abc', 'cba'}, 'b3') + setreg('c', { 'd', 'e', '' }, 'c') + setreg('l', { 'a', 'b', 'cde' }, 'l') + setreg('b', { 'bca', 'abc', 'cba' }, 'b3') expect_exit(nvim_command, 'qall') reset() - eq({{'d', 'e', ''}, 'v'}, getreg('c')) - eq({{'a', 'b', 'cde'}, 'V'}, getreg('l')) - eq({{'bca', 'abc', 'cba'}, '\0223'}, getreg('b')) + eq({ { 'd', 'e', '' }, 'v' }, getreg('c')) + eq({ { 'a', 'b', 'cde' }, 'V' }, getreg('l')) + eq({ { 'bca', 'abc', 'cba' }, '\0223' }, getreg('b')) end) it('does not dump registers with zero <', function() - nvim_command('set shada=\'0,<0') - setreg('c', {'d', 'e', ''}, 'c') - setreg('l', {'a', 'b', 'cde'}, 'l') - setreg('b', {'bca', 'abc', 'cba'}, 'b3') + nvim_command("set shada='0,<0") + setreg('c', { 'd', 'e', '' }, 'c') + setreg('l', { 'a', 'b', 'cde' }, 'l') + setreg('b', { 'bca', 'abc', 'cba' }, 'b3') expect_exit(nvim_command, 'qall') reset() - eq({{}, ''}, getreg('c')) - eq({{}, ''}, getreg('l')) - eq({{}, ''}, getreg('b')) + eq({ {}, '' }, getreg('c')) + eq({ {}, '' }, getreg('l')) + eq({ {}, '' }, getreg('b')) end) it('does restore registers with zero <', function() - setreg('c', {'d', 'e', ''}, 'c') - setreg('l', {'a', 'b', 'cde'}, 'l') - setreg('b', {'bca', 'abc', 'cba'}, 'b3') + setreg('c', { 'd', 'e', '' }, 'c') + setreg('l', { 'a', 'b', 'cde' }, 'l') + setreg('b', { 'bca', 'abc', 'cba' }, 'b3') expect_exit(nvim_command, 'qall') - reset('set shada=\'0,<0') - eq({{'d', 'e', ''}, 'v'}, getreg('c')) - eq({{'a', 'b', 'cde'}, 'V'}, getreg('l')) - eq({{'bca', 'abc', 'cba'}, '\0223'}, getreg('b')) + reset("set shada='0,<0") + eq({ { 'd', 'e', '' }, 'v' }, getreg('c')) + eq({ { 'a', 'b', 'cde' }, 'V' }, getreg('l')) + eq({ { 'bca', 'abc', 'cba' }, '\0223' }, getreg('b')) end) it('does not dump registers with zero "', function() nvim_command('set shada=\'0,\\"0') - setreg('c', {'d', 'e', ''}, 'c') - setreg('l', {'a', 'b', 'cde'}, 'l') - setreg('b', {'bca', 'abc', 'cba'}, 'b3') + setreg('c', { 'd', 'e', '' }, 'c') + setreg('l', { 'a', 'b', 'cde' }, 'l') + setreg('b', { 'bca', 'abc', 'cba' }, 'b3') expect_exit(nvim_command, 'qall') reset() - eq({{}, ''}, getreg('c')) - eq({{}, ''}, getreg('l')) - eq({{}, ''}, getreg('b')) + eq({ {}, '' }, getreg('c')) + eq({ {}, '' }, getreg('l')) + eq({ {}, '' }, getreg('b')) end) it('does restore registers with zero "', function() - setreg('c', {'d', 'e', ''}, 'c') - setreg('l', {'a', 'b', 'cde'}, 'l') - setreg('b', {'bca', 'abc', 'cba'}, 'b3') + setreg('c', { 'd', 'e', '' }, 'c') + setreg('l', { 'a', 'b', 'cde' }, 'l') + setreg('b', { 'bca', 'abc', 'cba' }, 'b3') expect_exit(nvim_command, 'qall') reset('set shada=\'0,\\"0') - eq({{'d', 'e', ''}, 'v'}, getreg('c')) - eq({{'a', 'b', 'cde'}, 'V'}, getreg('l')) - eq({{'bca', 'abc', 'cba'}, '\0223'}, getreg('b')) + eq({ { 'd', 'e', '' }, 'v' }, getreg('c')) + eq({ { 'a', 'b', 'cde' }, 'V' }, getreg('l')) + eq({ { 'bca', 'abc', 'cba' }, '\0223' }, getreg('b')) end) it('does dump registers with zero ", but non-zero <', function() nvim_command('set shada=\'0,\\"0,<50') - setreg('c', {'d', 'e', ''}, 'c') - setreg('l', {'a', 'b', 'cde'}, 'l') - setreg('b', {'bca', 'abc', 'cba'}, 'b3') + setreg('c', { 'd', 'e', '' }, 'c') + setreg('l', { 'a', 'b', 'cde' }, 'l') + setreg('b', { 'bca', 'abc', 'cba' }, 'b3') expect_exit(nvim_command, 'qall') reset() - eq({{'d', 'e', ''}, 'v'}, getreg('c')) - eq({{'a', 'b', 'cde'}, 'V'}, getreg('l')) - eq({{'bca', 'abc', 'cba'}, '\0223'}, getreg('b')) + eq({ { 'd', 'e', '' }, 'v' }, getreg('c')) + eq({ { 'a', 'b', 'cde' }, 'V' }, getreg('l')) + eq({ { 'bca', 'abc', 'cba' }, '\0223' }, getreg('b')) end) it('does limit number of lines according to <', function() - nvim_command('set shada=\'0,<2') - setreg('o', {'d'}, 'c') - setreg('t', {'a', 'b', 'cde'}, 'l') + nvim_command("set shada='0,<2") + setreg('o', { 'd' }, 'c') + setreg('t', { 'a', 'b', 'cde' }, 'l') expect_exit(nvim_command, 'qall') reset() - eq({{'d'}, 'v'}, getreg('o')) - eq({{}, ''}, getreg('t')) + eq({ { 'd' }, 'v' }, getreg('o')) + eq({ {}, '' }, getreg('t')) end) it('does limit number of lines according to "', function() nvim_command('set shada=\'0,\\"2') - setreg('o', {'d'}, 'c') - setreg('t', {'a', 'b', 'cde'}, 'l') + setreg('o', { 'd' }, 'c') + setreg('t', { 'a', 'b', 'cde' }, 'l') expect_exit(nvim_command, 'qall') reset() - eq({{'d'}, 'v'}, getreg('o')) - eq({{}, ''}, getreg('t')) + eq({ { 'd' }, 'v' }, getreg('o')) + eq({ {}, '' }, getreg('t')) end) it('does limit number of lines according to < rather then "', function() nvim_command('set shada=\'0,\\"2,<3') - setreg('o', {'d'}, 'c') - setreg('t', {'a', 'b', 'cde'}, 'l') - setreg('h', {'abc', 'acb', 'bac', 'bca', 'cab', 'cba'}, 'b3') + setreg('o', { 'd' }, 'c') + setreg('t', { 'a', 'b', 'cde' }, 'l') + setreg('h', { 'abc', 'acb', 'bac', 'bca', 'cab', 'cba' }, 'b3') expect_exit(nvim_command, 'qall') reset() - eq({{'d'}, 'v'}, getreg('o')) - eq({{'a', 'b', 'cde'}, 'V'}, getreg('t')) - eq({{}, ''}, getreg('h')) + eq({ { 'd' }, 'v' }, getreg('o')) + eq({ { 'a', 'b', 'cde' }, 'V' }, getreg('t')) + eq({ {}, '' }, getreg('h')) end) - it('dumps and loads register correctly with utf-8 contents', - function() + it('dumps and loads register correctly with utf-8 contents', function() reset() - setreg('e', {'«'}, 'c') + setreg('e', { '«' }, 'c') expect_exit(nvim_command, 'qall') reset() - eq({{'«'}, 'v'}, getreg('e')) + eq({ { '«' }, 'v' }, getreg('e')) end) - it('dumps and loads history correctly with 8-bit single-byte', - function() + it('dumps and loads history correctly with 8-bit single-byte', function() reset() -- \171 is U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK in latin1 - setreg('e', {'\171«'}, 'c') + setreg('e', { '\171«' }, 'c') expect_exit(nvim_command, 'qall') reset() - eq({{'\171«'}, 'v'}, getreg('e')) + eq({ { '\171«' }, 'v' }, getreg('e')) end) - it('has a blank unnamed register if it wasn\'t set and register 0 is empty', - function() - setreg('1', {'one'}, 'c') - setreg('2', {'two'}, 'c') - setreg('a', {'a'}, 'c') + it("has a blank unnamed register if it wasn't set and register 0 is empty", function() + setreg('1', { 'one' }, 'c') + setreg('2', { 'two' }, 'c') + setreg('a', { 'a' }, 'c') expect_exit(nvim_command, 'qall') reset() - eq({{}, ''}, getreg('0')) - eq({{'one'}, 'v'}, getreg('1')) - eq({{}, ''}, getreg('"')) - eq({{'a'}, 'v'}, getreg('a')) + eq({ {}, '' }, getreg('0')) + eq({ { 'one' }, 'v' }, getreg('1')) + eq({ {}, '' }, getreg('"')) + eq({ { 'a' }, 'v' }, getreg('a')) end) - it('defaults the unnamed register to register 0 if it wasn\'t set', - function() - setreg('0', {'zero'}, 'c') - setreg('1', {'one'}, 'c') - setreg('2', {'two'}, 'c') + it("defaults the unnamed register to register 0 if it wasn't set", function() + setreg('0', { 'zero' }, 'c') + setreg('1', { 'one' }, 'c') + setreg('2', { 'two' }, 'c') expect_exit(nvim_command, 'qall') reset() - eq({{'zero'}, 'v'}, getreg('0')) - eq({{'one'}, 'v'}, getreg('1')) - eq({{'zero'}, 'v'}, getreg('"')) + eq({ { 'zero' }, 'v' }, getreg('0')) + eq({ { 'one' }, 'v' }, getreg('1')) + eq({ { 'zero' }, 'v' }, getreg('"')) end) - it('remembers which register was the unnamed register when loading', - function() - setreg('0', {'zero'}, 'c') - setreg('1', {'one'}, 'cu') - setreg('2', {'two'}, 'c') + it('remembers which register was the unnamed register when loading', function() + setreg('0', { 'zero' }, 'c') + setreg('1', { 'one' }, 'cu') + setreg('2', { 'two' }, 'c') expect_exit(nvim_command, 'qall') reset() - eq({{'zero'}, 'v'}, getreg('0')) - eq({{'one'}, 'v'}, getreg('1')) - eq({{'one'}, 'v'}, getreg('"')) + eq({ { 'zero' }, 'v' }, getreg('0')) + eq({ { 'one' }, 'v' }, getreg('1')) + eq({ { 'one' }, 'v' }, getreg('"')) end) end) diff --git a/test/functional/shada/shada_spec.lua b/test/functional/shada/shada_spec.lua index 3a3238eb34..6eb318015d 100644 --- a/test/functional/shada/shada_spec.lua +++ b/test/functional/shada/shada_spec.lua @@ -1,25 +1,20 @@ -- Other ShaDa tests local helpers = require('test.functional.helpers')(after_each) -local meths, nvim_command, funcs, eq = - helpers.meths, helpers.command, helpers.funcs, helpers.eq +local api, nvim_command, fn, eq = helpers.api, helpers.command, helpers.fn, helpers.eq local write_file, spawn, set_session, nvim_prog, exc_exec = - helpers.write_file, helpers.spawn, helpers.set_session, helpers.nvim_prog, - helpers.exc_exec + helpers.write_file, helpers.spawn, helpers.set_session, helpers.nvim_prog, helpers.exc_exec local is_os = helpers.is_os local skip = helpers.skip -local luv = require('luv') -local paths = require('test.cmakeconfig.paths') - -local mpack = require('mpack') +local uv = vim.uv +local paths = helpers.paths local shada_helpers = require('test.functional.shada.helpers') local reset, clear, get_shada_rw = shada_helpers.reset, shada_helpers.clear, shada_helpers.get_shada_rw local read_shada_file = shada_helpers.read_shada_file -local wshada, _, shada_fname, clean = - get_shada_rw('Xtest-functional-shada-shada.shada') +local wshada, _, shada_fname, clean = get_shada_rw('Xtest-functional-shada-shada.shada') local dirname = 'Xtest-functional-shada-shada.d' local dirshada = dirname .. '/main.shada' @@ -29,12 +24,16 @@ describe('ShaDa support code', function() after_each(function() clear() clean() - luv.fs_rmdir(dirname) + uv.fs_rmdir(dirname) end) it('preserves `s` item size limit with unknown entries', function() - wshada('\100\000\207\000\000\000\000\000\000\004\000\218\003\253' .. ('-'):rep(1024 - 3) - .. '\100\000\207\000\000\000\000\000\000\004\001\218\003\254' .. ('-'):rep(1025 - 3)) + wshada( + '\100\000\207\000\000\000\000\000\000\004\000\218\003\253' + .. ('-'):rep(1024 - 3) + .. '\100\000\207\000\000\000\000\000\000\004\001\218\003\254' + .. ('-'):rep(1025 - 3) + ) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do @@ -58,8 +57,8 @@ describe('ShaDa support code', function() local hist1 = ('-'):rep(1024 - 5) local hist2 = ('-'):rep(1025 - 5) nvim_command('set shada-=s10 shada+=s1') - funcs.histadd(':', hist1) - funcs.histadd(':', hist2) + fn.histadd(':', hist1) + fn.histadd(':', hist2) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do @@ -73,35 +72,53 @@ describe('ShaDa support code', function() it('leaves .tmp.a in-place when there is error in original ShaDa', function() wshada('Some text file') - eq('Vim(wshada):E576: Error while reading ShaDa file: last entry specified that it occupies 109 bytes, but file ended earlier', exc_exec('wshada ' .. shada_fname)) + eq( + 'Vim(wshada):E576: Error while reading ShaDa file: last entry specified that it occupies 109 bytes, but file ended earlier', + exc_exec('wshada ' .. shada_fname) + ) eq(1, read_shada_file(shada_fname .. '.tmp.a')[1].type) end) - it('does not leave .tmp.a in-place when there is error in original ShaDa, but writing with bang', function() - wshada('Some text file') - eq(0, exc_exec('wshada! ' .. shada_fname)) - eq(1, read_shada_file(shada_fname)[1].type) - eq(nil, luv.fs_stat(shada_fname .. '.tmp.a')) - end) + it( + 'does not leave .tmp.a in-place when there is error in original ShaDa, but writing with bang', + function() + wshada('Some text file') + eq(0, exc_exec('wshada! ' .. shada_fname)) + eq(1, read_shada_file(shada_fname)[1].type) + eq(nil, uv.fs_stat(shada_fname .. '.tmp.a')) + end + ) it('leaves .tmp.b in-place when there is error in original ShaDa and it has .tmp.a', function() wshada('Some text file') - eq('Vim(wshada):E576: Error while reading ShaDa file: last entry specified that it occupies 109 bytes, but file ended earlier', exc_exec('wshada ' .. shada_fname)) - eq('Vim(wshada):E576: Error while reading ShaDa file: last entry specified that it occupies 109 bytes, but file ended earlier', exc_exec('wshada ' .. shada_fname)) + eq( + 'Vim(wshada):E576: Error while reading ShaDa file: last entry specified that it occupies 109 bytes, but file ended earlier', + exc_exec('wshada ' .. shada_fname) + ) + eq( + 'Vim(wshada):E576: Error while reading ShaDa file: last entry specified that it occupies 109 bytes, but file ended earlier', + exc_exec('wshada ' .. shada_fname) + ) eq(1, read_shada_file(shada_fname .. '.tmp.a')[1].type) eq(1, read_shada_file(shada_fname .. '.tmp.b')[1].type) end) - it('leaves .tmp.z in-place when there is error in original ShaDa and it has .tmp.a … .tmp.x', function() - wshada('Some text file') - local i = ('a'):byte() - while i < ('z'):byte() do - write_file(shada_fname .. ('.tmp.%c'):format(i), 'Some text file', true) - i = i + 1 + it( + 'leaves .tmp.z in-place when there is error in original ShaDa and it has .tmp.a … .tmp.x', + function() + wshada('Some text file') + local i = ('a'):byte() + while i < ('z'):byte() do + write_file(shada_fname .. ('.tmp.%c'):format(i), 'Some text file', true) + i = i + 1 + end + eq( + 'Vim(wshada):E576: Error while reading ShaDa file: last entry specified that it occupies 109 bytes, but file ended earlier', + exc_exec('wshada ' .. shada_fname) + ) + eq(1, read_shada_file(shada_fname .. '.tmp.z')[1].type) end - eq('Vim(wshada):E576: Error while reading ShaDa file: last entry specified that it occupies 109 bytes, but file ended earlier', exc_exec('wshada ' .. shada_fname)) - eq(1, read_shada_file(shada_fname .. '.tmp.z')[1].type) - end) + ) it('errors out when there are .tmp.a … .tmp.z ShaDa files', function() wshada('') @@ -110,33 +127,36 @@ describe('ShaDa support code', function() write_file(shada_fname .. ('.tmp.%c'):format(i), '', true) i = i + 1 end - eq('Vim(wshada):E138: All Xtest-functional-shada-shada.shada.tmp.X files exist, cannot write ShaDa file!', exc_exec('wshada ' .. shada_fname)) + eq( + 'Vim(wshada):E138: All Xtest-functional-shada-shada.shada.tmp.X files exist, cannot write ShaDa file!', + exc_exec('wshada ' .. shada_fname) + ) end) it('reads correctly various timestamps', function() local msgpack = { - '\100', -- Positive fixnum 100 - '\204\255', -- uint 8 255 - '\205\010\003', -- uint 16 2563 - '\206\255\010\030\004', -- uint 32 4278853124 - '\207\005\100\060\250\255\010\030\004', -- uint 64 388502516579048964 + '\100', -- Positive fixnum 100 + '\204\255', -- uint 8 255 + '\205\010\003', -- uint 16 2563 + '\206\255\010\030\004', -- uint 32 4278853124 + '\207\005\100\060\250\255\010\030\004', -- uint 64 388502516579048964 } local s = '\100' local e = '\001\192' wshada(s .. table.concat(msgpack, e .. s) .. e) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 - local typ = mpack.decode(s) + local typ = vim.mpack.decode(s) for _, v in ipairs(read_shada_file(shada_fname)) do if v.type == typ then found = found + 1 - eq(mpack.decode(msgpack[found]), v.timestamp) + eq(vim.mpack.decode(msgpack[found]), v.timestamp) end end eq(#msgpack, found) end) - local marklike = {[7]=true, [8]=true, [10]=true, [11]=true} + local marklike = { [7] = true, [8] = true, [10] = true, [11] = true } local find_file = function(fname) local found = {} for _, v in ipairs(read_shada_file(shada_fname)) do @@ -155,7 +175,7 @@ describe('ShaDa support code', function() it('correctly uses shada-r option', function() nvim_command('set shellslash') - meths.set_var('__home', paths.test_source_path) + api.nvim_set_var('__home', paths.test_source_path) nvim_command('let $HOME = __home') nvim_command('unlet __home') nvim_command('edit ~/README.md') @@ -163,104 +183,107 @@ describe('ShaDa support code', function() nvim_command('undo') nvim_command('set shada+=%') nvim_command('wshada! ' .. shada_fname) - local readme_fname = funcs.resolve(paths.test_source_path) .. '/README.md' - eq({[7]=2, [8]=2, [9]=1, [10]=4, [11]=1}, find_file(readme_fname)) + local readme_fname = fn.resolve(paths.test_source_path) .. '/README.md' + eq({ [7] = 2, [8] = 2, [9] = 1, [10] = 4, [11] = 1 }, find_file(readme_fname)) nvim_command('set shada+=r~') nvim_command('wshada! ' .. shada_fname) eq({}, find_file(readme_fname)) nvim_command('set shada-=r~') nvim_command('wshada! ' .. shada_fname) - eq({[7]=2, [8]=2, [9]=1, [10]=4, [11]=1}, find_file(readme_fname)) - nvim_command('set shada+=r' .. funcs.escape( - funcs.escape(paths.test_source_path, '$~'), ' "\\,')) + eq({ [7] = 2, [8] = 2, [9] = 1, [10] = 4, [11] = 1 }, find_file(readme_fname)) + nvim_command('set shada+=r' .. fn.escape(fn.escape(paths.test_source_path, '$~'), ' "\\,')) nvim_command('wshada! ' .. shada_fname) eq({}, find_file(readme_fname)) end) it('correctly ignores case with shada-r option', function() nvim_command('set shellslash') - local pwd = funcs.getcwd() + local pwd = fn.getcwd() local relfname = 'абв/test' local fname = pwd .. '/' .. relfname - meths.set_var('__fname', fname) + api.nvim_set_var('__fname', fname) nvim_command('silent! edit `=__fname`') - funcs.setline(1, {'a', 'b', 'c', 'd'}) + fn.setline(1, { 'a', 'b', 'c', 'd' }) nvim_command('normal! GmAggmaAabc') nvim_command('undo') nvim_command('set shada+=%') nvim_command('wshada! ' .. shada_fname) - eq({[7]=2, [8]=2, [9]=1, [10]=4, [11]=2}, find_file(fname)) + eq({ [7] = 2, [8] = 2, [9] = 1, [10] = 4, [11] = 2 }, find_file(fname)) nvim_command('set shada+=r' .. pwd .. '/АБВ') nvim_command('wshada! ' .. shada_fname) eq({}, find_file(fname)) end) it('is able to set &shada after &viminfo', function() - meths.set_option_value('viminfo', '\'10', {}) - eq('\'10', meths.get_option_value('viminfo', {})) - eq('\'10', meths.get_option_value('shada', {})) - meths.set_option_value('shada', '', {}) - eq('', meths.get_option_value('viminfo', {})) - eq('', meths.get_option_value('shada', {})) + api.nvim_set_option_value('viminfo', "'10", {}) + eq("'10", api.nvim_get_option_value('viminfo', {})) + eq("'10", api.nvim_get_option_value('shada', {})) + api.nvim_set_option_value('shada', '', {}) + eq('', api.nvim_get_option_value('viminfo', {})) + eq('', api.nvim_get_option_value('shada', {})) end) it('is able to set all& after setting &shada', function() - meths.set_option_value('shada', '\'10', {}) - eq('\'10', meths.get_option_value('viminfo', {})) - eq('\'10', meths.get_option_value('shada', {})) + api.nvim_set_option_value('shada', "'10", {}) + eq("'10", api.nvim_get_option_value('viminfo', {})) + eq("'10", api.nvim_get_option_value('shada', {})) nvim_command('set all&') - eq('!,\'100,<50,s10,h', meths.get_option_value('viminfo', {})) - eq('!,\'100,<50,s10,h', meths.get_option_value('shada', {})) + eq("!,'100,<50,s10,h", api.nvim_get_option_value('viminfo', {})) + eq("!,'100,<50,s10,h", api.nvim_get_option_value('shada', {})) end) it('is able to set &shada after &viminfo using :set', function() - nvim_command('set viminfo=\'10') - eq('\'10', meths.get_option_value('viminfo', {})) - eq('\'10', meths.get_option_value('shada', {})) + nvim_command("set viminfo='10") + eq("'10", api.nvim_get_option_value('viminfo', {})) + eq("'10", api.nvim_get_option_value('shada', {})) nvim_command('set shada=') - eq('', meths.get_option_value('viminfo', {})) - eq('', meths.get_option_value('shada', {})) + eq('', api.nvim_get_option_value('viminfo', {})) + eq('', api.nvim_get_option_value('shada', {})) end) it('setting &shada gives proper error message on missing number', function() - eq([[Vim(set):E526: Missing number after <">: shada="]], - exc_exec([[set shada=\"]])) - for _, c in ipairs({"'", "/", ":", "<", "@", "s"}) do - eq(([[Vim(set):E526: Missing number after <%s>: shada=%s]]):format(c, c), - exc_exec(([[set shada=%s]]):format(c))) + eq([[Vim(set):E526: Missing number after <">: shada="]], exc_exec([[set shada=\"]])) + for _, c in ipairs({ "'", '/', ':', '<', '@', 's' }) do + eq( + ([[Vim(set):E526: Missing number after <%s>: shada=%s]]):format(c, c), + exc_exec(([[set shada=%s]]):format(c)) + ) end end) it('does not crash when ShaDa file directory is not writable', function() skip(is_os('win')) - funcs.mkdir(dirname, '', 0) - eq(0, funcs.filewritable(dirname)) - reset{shadafile=dirshada, args={'--cmd', 'set shada='}} - meths.set_option_value('shada', '\'10', {}) - eq('Vim(wshada):E886: System error while opening ShaDa file ' - .. 'Xtest-functional-shada-shada.d/main.shada for reading to merge ' - .. 'before writing it: permission denied', - exc_exec('wshada')) - meths.set_option_value('shada', '', {}) + fn.mkdir(dirname, '', 0) + eq(0, fn.filewritable(dirname)) + reset { shadafile = dirshada, args = { '--cmd', 'set shada=' } } + api.nvim_set_option_value('shada', "'10", {}) + eq( + 'Vim(wshada):E886: System error while opening ShaDa file ' + .. 'Xtest-functional-shada-shada.d/main.shada for reading to merge ' + .. 'before writing it: permission denied', + exc_exec('wshada') + ) + api.nvim_set_option_value('shada', '', {}) end) end) describe('ShaDa support code', function() it('does not write NONE file', function() - local session = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed', - '--headless', '--cmd', 'qall'}, true) + local session = spawn( + { nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed', '--headless', '--cmd', 'qall' }, + true + ) session:close() - eq(nil, luv.fs_stat('NONE')) - eq(nil, luv.fs_stat('NONE.tmp.a')) + eq(nil, uv.fs_stat('NONE')) + eq(nil, uv.fs_stat('NONE.tmp.a')) end) it('does not read NONE file', function() write_file('NONE', '\005\001\015\131\161na\162rX\194\162rc\145\196\001-') - local session = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed', - '--headless'}, true) + local session = spawn({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed', '--headless' }, true) set_session(session) - eq('', funcs.getreg('a')) + eq('', fn.getreg('a')) session:close() os.remove('NONE') end) diff --git a/test/functional/shada/variables_spec.lua b/test/functional/shada/variables_spec.lua index a91b7eb193..d70f5deded 100644 --- a/test/functional/shada/variables_spec.lua +++ b/test/functional/shada/variables_spec.lua @@ -1,7 +1,7 @@ -- ShaDa variables saving/reading support local helpers = require('test.functional.helpers')(after_each) -local meths, funcs, nvim_command, eq, eval = - helpers.meths, helpers.funcs, helpers.command, helpers.eq, helpers.eval +local api, fn, nvim_command, eq, eval = + helpers.api, helpers.fn, helpers.command, helpers.eq, helpers.eval local expect_exit = helpers.expect_exit local shada_helpers = require('test.functional.shada.helpers') @@ -12,24 +12,23 @@ describe('ShaDa support code', function() after_each(clear) it('is able to dump and read back string variable', function() - meths.set_var('STRVAR', 'foo') + api.nvim_set_var('STRVAR', 'foo') nvim_command('set shada+=!') nvim_command('wshada') reset() nvim_command('set shada+=!') nvim_command('rshada') - eq('foo', meths.get_var('STRVAR')) + eq('foo', api.nvim_get_var('STRVAR')) end) local autotest = function(tname, varname, varval, val_is_expr) - it('is able to dump and read back ' .. tname .. ' variable automatically', - function() + it('is able to dump and read back ' .. tname .. ' variable automatically', function() reset('set shada+=!') if val_is_expr then nvim_command('let g:' .. varname .. ' = ' .. varval) - varval = meths.get_var(varname) + varval = api.nvim_get_var(varname) else - meths.set_var(varname, varval) + api.nvim_set_var(varname, varval) end local vartype = eval('type(g:' .. varname .. ')') -- Exit during `reset` is not a regular exit: it does not write shada @@ -37,15 +36,15 @@ describe('ShaDa support code', function() expect_exit(nvim_command, 'qall') reset('set shada+=!') eq(vartype, eval('type(g:' .. varname .. ')')) - eq(varval, meths.get_var(varname)) + eq(varval, api.nvim_get_var(varname)) end) end autotest('string', 'STRVAR', 'foo') autotest('number', 'NUMVAR', 42) autotest('float', 'FLTVAR', 42.5) - autotest('dictionary', 'DCTVAR', {a=10}) - autotest('list', 'LSTVAR', {{a=10}, {b=10.5}, {c='str'}}) + autotest('dictionary', 'DCTVAR', { a = 10 }) + autotest('list', 'LSTVAR', { { a = 10 }, { b = 10.5 }, { c = 'str' } }) autotest('true', 'TRUEVAR', true) autotest('false', 'FALSEVAR', false) autotest('null', 'NULLVAR', 'v:null', true) @@ -54,111 +53,110 @@ describe('ShaDa support code', function() autotest('blob (with NULs)', 'BLOBVARNULS', '0z004e554c7300', true) it('does not read back variables without `!` in &shada', function() - meths.set_var('STRVAR', 'foo') + api.nvim_set_var('STRVAR', 'foo') nvim_command('set shada+=!') nvim_command('wshada') reset('set shada-=!') nvim_command('rshada') - eq(0, funcs.exists('g:STRVAR')) + eq(0, fn.exists('g:STRVAR')) end) it('does not dump variables without `!` in &shada', function() nvim_command('set shada-=!') - meths.set_var('STRVAR', 'foo') + api.nvim_set_var('STRVAR', 'foo') nvim_command('wshada') reset() nvim_command('set shada+=!') nvim_command('rshada') - eq(0, funcs.exists('g:STRVAR')) + eq(0, fn.exists('g:STRVAR')) end) it('does not dump session variables', function() nvim_command('set shada+=!') - meths.set_var('StrVar', 'foo') + api.nvim_set_var('StrVar', 'foo') nvim_command('wshada') reset() nvim_command('set shada+=!') nvim_command('rshada') - eq(0, funcs.exists('g:StrVar')) + eq(0, fn.exists('g:StrVar')) end) it('does not dump regular variables', function() nvim_command('set shada+=!') - meths.set_var('str_var', 'foo') + api.nvim_set_var('str_var', 'foo') nvim_command('wshada') reset() nvim_command('set shada+=!') nvim_command('rshada') - eq(0, funcs.exists('g:str_var')) + eq(0, fn.exists('g:str_var')) end) - it('dumps and loads variables correctly with utf-8 strings', - function() + it('dumps and loads variables correctly with utf-8 strings', function() reset() - meths.set_var('STRVAR', '«') - meths.set_var('LSTVAR', {'«'}) - meths.set_var('DCTVAR', {['«']='«'}) - meths.set_var('NESTEDVAR', {['«']={{'«'}, {['«']='«'}, {a='Test'}}}) + api.nvim_set_var('STRVAR', '«') + api.nvim_set_var('LSTVAR', { '«' }) + api.nvim_set_var('DCTVAR', { ['«'] = '«' }) + api.nvim_set_var('NESTEDVAR', { ['«'] = { { '«' }, { ['«'] = '«' }, { a = 'Test' } } }) expect_exit(nvim_command, 'qall') reset() - eq('«', meths.get_var('STRVAR')) - eq({'«'}, meths.get_var('LSTVAR')) - eq({['«']='«'}, meths.get_var('DCTVAR')) - eq({['«']={{'«'}, {['«']='«'}, {a='Test'}}}, meths.get_var('NESTEDVAR')) + eq('«', api.nvim_get_var('STRVAR')) + eq({ '«' }, api.nvim_get_var('LSTVAR')) + eq({ ['«'] = '«' }, api.nvim_get_var('DCTVAR')) + eq({ ['«'] = { { '«' }, { ['«'] = '«' }, { a = 'Test' } } }, api.nvim_get_var('NESTEDVAR')) end) - it('dumps and loads variables correctly with 8-bit strings', - function() + it('dumps and loads variables correctly with 8-bit strings', function() reset() -- \171 is U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK in latin1 -- This is invalid unicode, but we should still dump and restore it. - meths.set_var('STRVAR', '\171') - meths.set_var('LSTVAR', {'\171'}) - meths.set_var('DCTVAR', {['«\171']='«\171'}) - meths.set_var('NESTEDVAR', {['\171']={{'\171«'}, {['\171']='\171'}, - {a='Test'}}}) + api.nvim_set_var('STRVAR', '\171') + api.nvim_set_var('LSTVAR', { '\171' }) + api.nvim_set_var('DCTVAR', { ['«\171'] = '«\171' }) + api.nvim_set_var( + 'NESTEDVAR', + { ['\171'] = { { '\171«' }, { ['\171'] = '\171' }, { a = 'Test' } } } + ) expect_exit(nvim_command, 'qall') reset() - eq('\171', meths.get_var('STRVAR')) - eq({'\171'}, meths.get_var('LSTVAR')) - eq({['«\171']='«\171'}, meths.get_var('DCTVAR')) - eq({['\171']={{'\171«'}, {['\171']='\171'}, {a='Test'}}}, - meths.get_var('NESTEDVAR')) + eq('\171', api.nvim_get_var('STRVAR')) + eq({ '\171' }, api.nvim_get_var('LSTVAR')) + eq({ ['«\171'] = '«\171' }, api.nvim_get_var('DCTVAR')) + eq( + { ['\171'] = { { '\171«' }, { ['\171'] = '\171' }, { a = 'Test' } } }, + api.nvim_get_var('NESTEDVAR') + ) end) - it('ignore when a funcref is stored in a variable', - function() + it('ignore when a funcref is stored in a variable', function() nvim_command('let F = function("tr")') - meths.set_var('U', '10') + api.nvim_set_var('U', '10') nvim_command('set shada+=!') nvim_command('wshada') reset() nvim_command('set shada+=!') nvim_command('rshada') - eq('10', meths.get_var('U')) + eq('10', api.nvim_get_var('U')) end) - it('ignore when a partial is stored in a variable', - function() + it('ignore when a partial is stored in a variable', function() nvim_command('let P = { -> 1 }') - meths.set_var('U', '10') + api.nvim_set_var('U', '10') nvim_command('set shada+=!') nvim_command('wshada') reset() nvim_command('set shada+=!') nvim_command('rshada') - eq('10', meths.get_var('U')) + eq('10', api.nvim_get_var('U')) end) - it('ignore when a self-referencing list is stored in a variable', - function() - meths.set_var('L', {}) + it('ignore when a self-referencing list is stored in a variable', function() + api.nvim_set_var('L', {}) nvim_command('call add(L, L)') - meths.set_var('U', '10') + api.nvim_set_var('U', '10') nvim_command('set shada+=!') nvim_command('wshada') reset() nvim_command('rshada') - eq('10', meths.get_var('U')) + eq('10', api.nvim_get_var('U')) end) end) diff --git a/test/functional/terminal/altscreen_spec.lua b/test/functional/terminal/altscreen_spec.lua index cbe5e06005..c3be9ec6ca 100644 --- a/test/functional/terminal/altscreen_spec.lua +++ b/test/functional/terminal/altscreen_spec.lua @@ -1,12 +1,14 @@ local helpers = require('test.functional.helpers')(after_each) local thelpers = require('test.functional.terminal.helpers') -local clear, eq, curbuf = helpers.clear, helpers.eq, helpers.curbuf +local clear, eq, api = helpers.clear, helpers.eq, helpers.api local feed = helpers.feed local feed_data = thelpers.feed_data local enter_altscreen = thelpers.enter_altscreen local exit_altscreen = thelpers.exit_altscreen -if helpers.skip(helpers.is_os('win')) then return end +if helpers.skip(helpers.is_os('win')) then + return +end describe(':terminal altscreen', function() local screen @@ -14,8 +16,17 @@ describe(':terminal altscreen', function() before_each(function() clear() screen = thelpers.screen_setup() - feed_data({'line1', 'line2', 'line3', 'line4', 'line5', 'line6', - 'line7', 'line8', ''}) + feed_data({ + 'line1', + 'line2', + 'line3', + 'line4', + 'line5', + 'line6', + 'line7', + 'line8', + '', + }) screen:expect([[ line4 | line5 | @@ -27,15 +38,11 @@ describe(':terminal altscreen', function() ]]) enter_altscreen() screen:expect([[ - | - | - | - | - | + |*5 {1: } | {3:-- TERMINAL --} | ]]) - eq(10, curbuf('line_count')) + eq(10, api.nvim_buf_line_count(0)) end) it('wont clear lines already in the scrollback', function() @@ -45,9 +52,7 @@ describe(':terminal altscreen', function() line1 | line2 | line3 | - | - | - | + |*3 ]]) end) @@ -79,8 +84,17 @@ describe(':terminal altscreen', function() describe('with lines printed after the screen height limit', function() before_each(function() - feed_data({'line9', 'line10', 'line11', 'line12', 'line13', - 'line14', 'line15', 'line16', ''}) + feed_data({ + 'line9', + 'line10', + 'line11', + 'line12', + 'line13', + 'line14', + 'line15', + 'line16', + '', + }) screen:expect([[ line12 | line13 | @@ -93,7 +107,7 @@ describe(':terminal altscreen', function() end) it('wont modify line count', function() - eq(10, curbuf('line_count')) + eq(10, api.nvim_buf_line_count(0)) end) it('wont modify lines in the scrollback', function() @@ -114,8 +128,7 @@ describe(':terminal altscreen', function() local function wait_removal() screen:try_resize(screen._width, screen._height - 2) screen:expect([[ - | - | + |*2 rows: 4, cols: 50 | {1: } | {3:-- TERMINAL --} | @@ -127,12 +140,11 @@ describe(':terminal altscreen', function() feed('<c-\\><c-n>4k') screen:expect([[ ^ | - | - | + |*2 rows: 4, cols: 50 | | ]]) - eq(9, curbuf('line_count')) + eq(9, api.nvim_buf_line_count(0)) end) describe('and after exit', function() diff --git a/test/functional/terminal/api_spec.lua b/test/functional/terminal/api_spec.lua index 93641fc576..79cc5016da 100644 --- a/test/functional/terminal/api_spec.lua +++ b/test/functional/terminal/api_spec.lua @@ -2,67 +2,70 @@ local helpers = require('test.functional.helpers')(after_each) local child_session = require('test.functional.terminal.helpers') local ok = helpers.ok -if helpers.skip(helpers.is_os('win')) then return end +if helpers.skip(helpers.is_os('win')) then + return +end describe('api', function() local screen - local socket_name = "./Xtest_functional_api.sock" + local socket_name = './Xtest_functional_api.sock' before_each(function() helpers.clear() os.remove(socket_name) - screen = child_session.screen_setup(0, '["'..helpers.nvim_prog - ..'", "-u", "NONE", "-i", "NONE", "--cmd", "'..helpers.nvim_set..'"]') + screen = child_session.setup_child_nvim({ + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + 'colorscheme vim', + '--cmd', + helpers.nvim_set .. ' notermguicolors', + }) end) after_each(function() os.remove(socket_name) end) - it("qa! RPC request during insert-mode", function() - screen:expect{grid=[[ + it('qa! RPC request during insert-mode', function() + screen:expect { + grid = [[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*4 | {3:-- TERMINAL --} | - ]]} + ]], + } -- Start the socket from the child nvim. - child_session.feed_data(":echo serverstart('"..socket_name.."')\n") + child_session.feed_data(":echo serverstart('" .. socket_name .. "')\n") -- Wait for socket creation. screen:expect([[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| - ]]..socket_name..[[ | + {4:~ }|*4 + ]] .. socket_name .. [[ | {3:-- TERMINAL --} | ]]) local socket_session1 = helpers.connect(socket_name) local socket_session2 = helpers.connect(socket_name) - child_session.feed_data("i[tui] insert-mode") + child_session.feed_data('i[tui] insert-mode') -- Wait for stdin to be processed. screen:expect([[ [tui] insert-mode{1: } | - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*4 {3:-- INSERT --} | {3:-- TERMINAL --} | ]]) - ok((socket_session1:request("nvim_ui_attach", 42, 6, {rgb=true}))) - ok((socket_session2:request("nvim_ui_attach", 25, 30, {rgb=true}))) + ok((socket_session1:request('nvim_ui_attach', 42, 6, { rgb = true }))) + ok((socket_session2:request('nvim_ui_attach', 25, 30, { rgb = true }))) - socket_session1:notify("nvim_input", "\n[socket 1] this is more than 25 columns") - socket_session2:notify("nvim_input", "\n[socket 2] input") + socket_session1:notify('nvim_input', '\n[socket 1] this is more than 25 columns') + socket_session2:notify('nvim_input', '\n[socket 2] input') screen:expect([[ [tui] insert-mode | @@ -74,6 +77,6 @@ describe('api', function() {3:-- TERMINAL --} | ]]) - socket_session1:request("nvim_command", "qa!") + socket_session1:request('nvim_command', 'qa!') end) end) diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua index 6fcd029a5b..376b7b849e 100644 --- a/test/functional/terminal/buffer_spec.lua +++ b/test/functional/terminal/buffer_spec.lua @@ -1,23 +1,24 @@ local helpers = require('test.functional.helpers')(after_each) +local Screen = require('test.functional.ui.screen') local thelpers = require('test.functional.terminal.helpers') local assert_alive = helpers.assert_alive -local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim +local feed, clear = helpers.feed, helpers.clear local poke_eventloop = helpers.poke_eventloop +local nvim_prog = helpers.nvim_prog local eval, feed_command, source = helpers.eval, helpers.feed_command, helpers.source local pcall_err = helpers.pcall_err local eq, neq = helpers.eq, helpers.neq -local meths = helpers.meths +local api = helpers.api local retry = helpers.retry local write_file = helpers.write_file local command = helpers.command local exc_exec = helpers.exc_exec local matches = helpers.matches local exec_lua = helpers.exec_lua -local sleep = helpers.sleep -local funcs = helpers.funcs +local sleep = vim.uv.sleep +local fn = helpers.fn local is_os = helpers.is_os local skip = helpers.skip -local nvim_prog = helpers.nvim_prog describe(':terminal buffer', function() local screen @@ -31,13 +32,19 @@ describe(':terminal buffer', function() it('terminal-mode forces various options', function() feed([[<C-\><C-N>]]) command('setlocal cursorline cursorlineopt=both cursorcolumn scrolloff=4 sidescrolloff=7') - eq({ 'both', 1, 1, 4, 7 }, eval('[&l:cursorlineopt, &l:cursorline, &l:cursorcolumn, &l:scrolloff, &l:sidescrolloff]')) + eq( + { 'both', 1, 1, 4, 7 }, + eval('[&l:cursorlineopt, &l:cursorline, &l:cursorcolumn, &l:scrolloff, &l:sidescrolloff]') + ) eq('nt', eval('mode(1)')) -- Enter terminal-mode ("insert" mode in :terminal). feed('i') eq('t', eval('mode(1)')) - eq({ 'number', 1, 0, 0, 0 }, eval('[&l:cursorlineopt, &l:cursorline, &l:cursorcolumn, &l:scrolloff, &l:sidescrolloff]')) + eq( + { 'number', 1, 0, 0, 0 }, + eval('[&l:cursorlineopt, &l:cursorline, &l:cursorcolumn, &l:scrolloff, &l:sidescrolloff]') + ) end) it('terminal-mode does not change cursorlineopt if cursorline is disabled', function() @@ -59,11 +66,7 @@ describe(':terminal buffer', function() feed('<c-\\><c-n>:set bufhidden=wipe<cr>:enew<cr>') screen:expect([[ ^ | - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*5 :enew | ]]) end) @@ -72,11 +75,7 @@ describe(':terminal buffer', function() feed(':bnext:l<esc>') screen:expect([[ ^ | - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*5 | ]]) end) @@ -88,21 +87,17 @@ describe(':terminal buffer', function() screen:expect([[ tty ready | {2:^ } | - | - | - | - | - | + |*5 ]]) end) it('does not create swap files', function() - local swapfile = nvim('exec', 'swapname', true):gsub('\n', '') + local swapfile = api.nvim_exec('swapname', true):gsub('\n', '') eq(nil, io.open(swapfile)) end) it('does not create undofiles files', function() - local undofile = nvim('eval', 'undofile(bufname("%"))') + local undofile = api.nvim_eval('undofile(bufname("%"))') eq(nil, io.open(undofile)) end) end) @@ -112,10 +107,7 @@ describe(':terminal buffer', function() screen:expect([[ tty ready | {2:^ } | - | - | - | - | + |*4 {8:E21: Cannot make changes, 'modifiable' is off} | ]]) end) @@ -126,22 +118,16 @@ describe(':terminal buffer', function() feed('"ap"ap') screen:expect([[ ^tty ready | - appended tty ready | - appended tty ready | + appended tty ready |*2 {2: } | - | - | + |*2 :let @a = "appended " . @a | ]]) -- operator count is also taken into consideration feed('3"ap') screen:expect([[ ^tty ready | - appended tty ready | - appended tty ready | - appended tty ready | - appended tty ready | - appended tty ready | + appended tty ready |*5 :let @a = "appended " . @a | ]]) end) @@ -154,17 +140,14 @@ describe(':terminal buffer', function() ^tty ready | appended tty ready | {2: } | - | - | - | + |*3 :put a | ]]) -- line argument is only used to move the cursor feed_command('6put a') screen:expect([[ tty ready | - appended tty ready | - appended tty ready | + appended tty ready |*2 {2: } | | ^ | @@ -176,34 +159,24 @@ describe(':terminal buffer', function() feed('<c-\\><c-n>:bd!<cr>') screen:expect([[ ^ | - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*5 :bd! | ]]) feed_command('bnext') screen:expect([[ ^ | - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*5 :bnext | ]]) end) it('handles loss of focus gracefully', function() -- Change the statusline to avoid printing the file name, which varies. - nvim('set_option_value', 'statusline', '==========', {}) + api.nvim_set_option_value('statusline', '==========', {}) -- Save the buffer number of the terminal for later testing. local tbuf = eval('bufnr("%")') - local exitcmd = is_os('win') - and "['cmd', '/c', 'exit']" - or "['sh', '-c', 'exit']" + local exitcmd = is_os('win') and "['cmd', '/c', 'exit']" or "['sh', '-c', 'exit']" source([[ function! SplitWindow(id, data, event) new @@ -211,7 +184,7 @@ describe(':terminal buffer', function() endfunction startinsert - call jobstart(]]..exitcmd..[[, {'on_exit': function("SplitWindow")}) + call jobstart(]] .. exitcmd .. [[, {'on_exit': function("SplitWindow")}) call feedkeys("\<C-\>", 't') " vim will expect <C-n>, but be exited out of " the terminal before it can be entered. ]]) @@ -228,7 +201,7 @@ describe(':terminal buffer', function() ]]) neq(tbuf, eval('bufnr("%")')) - feed_command('quit!') -- Should exit the new window, not the terminal. + feed_command('quit!') -- Should exit the new window, not the terminal. eq(tbuf, eval('bufnr("%")')) end) @@ -243,46 +216,46 @@ describe(':terminal buffer', function() feed_command('terminal') feed('<c-\\><c-n>') feed_command('confirm bdelete') - screen:expect{any='Close "term://'} + screen:expect { any = 'Close "term://' } end) it('with &confirm', function() feed_command('terminal') feed('<c-\\><c-n>') feed_command('bdelete') - screen:expect{any='E89'} + screen:expect { any = 'E89' } feed('<cr>') eq('terminal', eval('&buftype')) feed_command('set confirm | bdelete') - screen:expect{any='Close "term://'} + screen:expect { any = 'Close "term://' } feed('y') neq('terminal', eval('&buftype')) end) end) it('it works with set rightleft #11438', function() - skip(is_os('win')) local columns = eval('&columns') feed(string.rep('a', columns)) command('set rightleft') screen:expect([[ ydaer ytt| {1:a}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - | - | - | - | + |*4 {3:-- TERMINAL --} | ]]) command('bdelete!') end) it('requires bang (!) to close a running job #15402', function() - skip(is_os('win'), "Test freezes the CI and makes it time out") + skip(is_os('win'), 'Test freezes the CI and makes it time out') eq('Vim(wqall):E948: Job still running', exc_exec('wqall')) for _, cmd in ipairs({ 'bdelete', '%bdelete', 'bwipeout', 'bunload' }) do - matches('^Vim%('..cmd:gsub('%%', '')..'%):E89: term://.*tty%-test.* will be killed %(add %! to override%)$', - exc_exec(cmd)) + matches( + '^Vim%(' + .. cmd:gsub('%%', '') + .. '%):E89: term://.*tty%-test.* will be killed %(add %! to override%)$', + exc_exec(cmd) + ) end command('call jobstop(&channel)') assert(0 >= eval('jobwait([&channel], 1000)[0]')) @@ -299,51 +272,97 @@ describe(':terminal buffer', function() it('does not segfault when pasting empty register #13955', function() feed('<c-\\><c-n>') - feed_command('put a') -- register a is empty + feed_command('put a') -- register a is empty helpers.assert_alive() end) it([[can use temporary normal mode <c-\><c-o>]], function() - eq('t', funcs.mode(1)) + eq('t', fn.mode(1)) feed [[<c-\><c-o>]] - screen:expect{grid=[[ + screen:expect { + grid = [[ tty ready | {2:^ } | - | - | - | - | + |*4 {3:-- (terminal) --} | - ]]} - eq('ntT', funcs.mode(1)) + ]], + } + eq('ntT', fn.mode(1)) feed [[:let g:x = 17]] - screen:expect{grid=[[ + screen:expect { + grid = [[ tty ready | {2: } | - | - | - | - | + |*4 :let g:x = 17^ | - ]]} + ]], + } feed [[<cr>]] - screen:expect{grid=[[ + screen:expect { + grid = [[ tty ready | {1: } | - | - | - | - | + |*4 {3:-- TERMINAL --} | - ]]} - eq('t', funcs.mode(1)) + ]], + } + eq('t', fn.mode(1)) end) it('writing to an existing file with :w fails #13549', function() - eq('Vim(write):E13: File exists (add ! to override)', - pcall_err(command, 'write test/functional/fixtures/tty-test.c')) + eq( + 'Vim(write):E13: File exists (add ! to override)', + pcall_err(command, 'write test/functional/fixtures/tty-test.c') + ) + end) + + it('emits TermRequest events #26972', function() + command('new') + local term = api.nvim_open_term(0, {}) + local termbuf = api.nvim_get_current_buf() + + -- Test that autocommand buffer is associated with the terminal buffer, not the current buffer + command('au TermRequest * let g:termbuf = +expand("<abuf>")') + command('wincmd p') + + -- cwd will be inserted in a file URI, which cannot contain backs + local cwd = fn.getcwd():gsub('\\', '/') + local parent = cwd:match('^(.+/)') + local expected = '\027]7;file://host' .. parent + api.nvim_chan_send(term, string.format('%s\027\\', expected)) + eq(expected, eval('v:termrequest')) + eq(termbuf, eval('g:termbuf')) + end) + + it('TermReqeust synchronization #27572', function() + command('new') + command('autocmd! nvim_terminal TermRequest') + local term = exec_lua([[ + _G.input = {} + local term = vim.api.nvim_open_term(0, { + on_input = function(_, _, _, data) + table.insert(_G.input, data) + end, + force_crlf = false, + }) + vim.api.nvim_create_autocmd('TermRequest', { + callback = function(args) + if args.data == '\027]11;?' then + table.insert(_G.input, '\027]11;rgb:0000/0000/0000\027\\') + end + end + }) + return term + ]]) + api.nvim_chan_send(term, '\027]11;?\007\027[5n\027]11;?\007\027[5n') + eq({ + '\027]11;rgb:0000/0000/0000\027\\', + '\027[0n', + '\027]11;rgb:0000/0000/0000\027\\', + '\027[0n', + }, exec_lua('return _G.input')) end) end) @@ -351,7 +370,7 @@ describe('No heap-buffer-overflow when using', function() local testfilename = 'Xtestfile-functional-terminal-buffers_spec' before_each(function() - write_file(testfilename, "aaaaaaaaaaaaaaaaaaaaaaaaaaaa") + write_file(testfilename, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaa') end) after_each(function() @@ -414,10 +433,12 @@ end) it('terminal truncates number of composing characters to 5', function() clear() - local chan = meths.open_term(0, {}) + local chan = api.nvim_open_term(0, {}) local composing = ('a̳'):sub(2) - meths.chan_send(chan, 'a' .. composing:rep(8)) - retry(nil, nil, function() eq('a' .. composing:rep(5), meths.get_current_line()) end) + api.nvim_chan_send(chan, 'a' .. composing:rep(8)) + retry(nil, nil, function() + eq('a' .. composing:rep(5), api.nvim_get_current_line()) + end) end) describe('terminal input', function() @@ -447,31 +468,80 @@ end) describe('terminal input', function() it('sends various special keys with modifiers', function() clear() - local screen = thelpers.screen_setup(0, - string.format([=[["%s", "-u", "NONE", "-i", "NONE", "--cmd", "startinsert"]]=], nvim_prog)) - screen:expect{grid=[[ + local screen = thelpers.setup_child_nvim({ + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + 'colorscheme vim', + '--cmd', + 'set notermguicolors', + '--cmd', + 'startinsert', + }) + screen:expect { + grid = [[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] 0,1 All}| {3:-- INSERT --} | {3:-- TERMINAL --} | - ]]} + ]], + } for _, key in ipairs({ - '<M-Tab>', '<M-CR>', '<M-Esc>', - '<BS>', '<S-Tab>', '<Insert>', '<Del>', '<PageUp>', '<PageDown>', - '<S-Up>', '<C-Up>', '<Up>', '<S-Down>', '<C-Down>', '<Down>', - '<S-Left>', '<C-Left>', '<Left>', '<S-Right>', '<C-Right>', '<Right>', - '<S-Home>', '<C-Home>', '<Home>', '<S-End>', '<C-End>', '<End>', - '<C-LeftMouse>', '<C-LeftRelease>', '<2-LeftMouse>', '<2-LeftRelease>', - '<S-RightMouse>', '<S-RightRelease>', '<2-RightMouse>', '<2-RightRelease>', - '<M-MiddleMouse>', '<M-MiddleRelease>', '<2-MiddleMouse>', '<2-MiddleRelease>', - '<S-ScrollWheelUp>', '<S-ScrollWheelDown>', '<ScrollWheelUp>', '<ScrollWheelDown>', - '<S-ScrollWheelLeft>', '<S-ScrollWheelRight>', '<ScrollWheelLeft>', '<ScrollWheelRight>', + '<M-Tab>', + '<M-CR>', + '<M-Esc>', + '<BS>', + '<S-Tab>', + '<Insert>', + '<Del>', + '<PageUp>', + '<PageDown>', + '<S-Up>', + '<C-Up>', + '<Up>', + '<S-Down>', + '<C-Down>', + '<Down>', + '<S-Left>', + '<C-Left>', + '<Left>', + '<S-Right>', + '<C-Right>', + '<Right>', + '<S-Home>', + '<C-Home>', + '<Home>', + '<S-End>', + '<C-End>', + '<End>', + '<C-LeftMouse>', + '<C-LeftRelease>', + '<2-LeftMouse>', + '<2-LeftRelease>', + '<S-RightMouse>', + '<S-RightRelease>', + '<2-RightMouse>', + '<2-RightRelease>', + '<M-MiddleMouse>', + '<M-MiddleRelease>', + '<2-MiddleMouse>', + '<2-MiddleRelease>', + '<S-ScrollWheelUp>', + '<S-ScrollWheelDown>', + '<ScrollWheelUp>', + '<ScrollWheelDown>', + '<S-ScrollWheelLeft>', + '<S-ScrollWheelRight>', + '<ScrollWheelLeft>', + '<ScrollWheelRight>', }) do feed('<CR><C-V>' .. key) - retry(nil, nil, function() eq(key, meths.get_current_line()) end) + retry(nil, nil, function() + eq(key, api.nvim_get_current_line()) + end) end end) end) @@ -484,7 +554,7 @@ if is_os('win') then clear() feed_command('set modifiable swapfile undolevels=20') poke_eventloop() - local cmd = '["cmd.exe","/K","PROMPT=$g$s"]' + local cmd = { 'cmd.exe', '/K', 'PROMPT=$g$s' } screen = thelpers.screen_setup(nil, cmd) end) @@ -549,11 +619,70 @@ describe('termopen()', function() it('disallowed when textlocked and in cmdwin buffer', function() command("autocmd TextYankPost <buffer> ++once call termopen('foo')") - matches("Vim%(call%):E565: Not allowed to change text or change window$", - pcall_err(command, "normal! yy")) + matches( + 'Vim%(call%):E565: Not allowed to change text or change window$', + pcall_err(command, 'normal! yy') + ) + + feed('q:') + eq( + 'Vim:E11: Invalid in command-line window; <CR> executes, CTRL-C quits', + pcall_err(fn.termopen, 'bar') + ) + end) + + describe('$COLORTERM value', function() + if skip(is_os('win'), 'Not applicable for Windows') then + return + end - feed("q:") - eq("Vim:E11: Invalid in command-line window; <CR> executes, CTRL-C quits", - pcall_err(funcs.termopen, "bar")) + before_each(function() + -- Outer value should never be propagated to :terminal + fn.setenv('COLORTERM', 'wrongvalue') + end) + + local function test_term_colorterm(expected, opts) + local screen = Screen.new(50, 4) + screen:attach() + fn.termopen({ + nvim_prog, + '-u', + 'NONE', + '-i', + 'NONE', + '--headless', + '-c', + 'echo $COLORTERM | quit', + }, opts) + screen:expect(([[ + ^%s{MATCH:%%s+}| + [Process exited 0] | + |*2 + ]]):format(expected)) + end + + describe("with 'notermguicolors'", function() + before_each(function() + command('set notermguicolors') + end) + it('is empty by default', function() + test_term_colorterm('') + end) + it('can be overridden', function() + test_term_colorterm('expectedvalue', { env = { COLORTERM = 'expectedvalue' } }) + end) + end) + + describe("with 'termguicolors'", function() + before_each(function() + command('set termguicolors') + end) + it('is "truecolor" by default', function() + test_term_colorterm('truecolor') + end) + it('can be overridden', function() + test_term_colorterm('expectedvalue', { env = { COLORTERM = 'expectedvalue' } }) + end) + end) end) end) diff --git a/test/functional/terminal/channel_spec.lua b/test/functional/terminal/channel_spec.lua index 8510df5347..9615534c87 100644 --- a/test/functional/terminal/channel_spec.lua +++ b/test/functional/terminal/channel_spec.lua @@ -8,7 +8,7 @@ local pcall_err = helpers.pcall_err local feed = helpers.feed local poke_eventloop = helpers.poke_eventloop local is_os = helpers.is_os -local meths = helpers.meths +local api = helpers.api local async_meths = helpers.async_meths local testprg = helpers.testprg local assert_alive = helpers.assert_alive @@ -26,9 +26,11 @@ describe('terminal channel is closed and later released if', function() command([[let id = nvim_open_term(0, {})]]) local chans = eval('len(nvim_list_chans())') -- channel hasn't been released yet - eq("Vim(call):Can't send data to closed stream", - pcall_err(command, [[bdelete! | call chansend(id, 'test')]])) - feed('<Ignore>') -- add input to separate two RPC requests + eq( + "Vim(call):Can't send data to closed stream", + pcall_err(command, [[bdelete! | call chansend(id, 'test')]]) + ) + feed('<Ignore>') -- add input to separate two RPC requests -- channel has been released after one main loop iteration eq(chans - 1, eval('len(nvim_list_chans())')) end) @@ -37,15 +39,17 @@ describe('terminal channel is closed and later released if', function() command('let id = nvim_open_term(0, {})') local chans = eval('len(nvim_list_chans())') -- channel has been closed but not released - eq("Vim(call):Can't send data to closed stream", - pcall_err(command, [[call chanclose(id) | call chansend(id, 'test')]])) - screen:expect({any='%[Terminal closed%]'}) + eq( + "Vim(call):Can't send data to closed stream", + pcall_err(command, [[call chanclose(id) | call chansend(id, 'test')]]) + ) + screen:expect({ any = '%[Terminal closed%]' }) eq(chans, eval('len(nvim_list_chans())')) -- delete terminal feed('i<CR>') -- need to first process input poke_eventloop() - feed('<Ignore>') -- add input to separate two RPC requests + feed('<Ignore>') -- add input to separate two RPC requests -- channel has been released after another main loop iteration eq(chans - 1, eval('len(nvim_list_chans())')) end) @@ -54,14 +58,18 @@ describe('terminal channel is closed and later released if', function() command('let id = nvim_open_term(0, {})') local chans = eval('len(nvim_list_chans())') -- channel has been closed but not released - eq("Vim(call):Can't send data to closed stream", - pcall_err(command, [[call chanclose(id) | call chansend(id, 'test')]])) - screen:expect({any='%[Terminal closed%]'}) + eq( + "Vim(call):Can't send data to closed stream", + pcall_err(command, [[call chanclose(id) | call chansend(id, 'test')]]) + ) + screen:expect({ any = '%[Terminal closed%]' }) eq(chans, eval('len(nvim_list_chans())')) -- channel still hasn't been released yet - eq("Vim(call):Can't send data to closed stream", - pcall_err(command, [[bdelete | call chansend(id, 'test')]])) - feed('<Ignore>') -- add input to separate two RPC requests + eq( + "Vim(call):Can't send data to closed stream", + pcall_err(command, [[bdelete | call chansend(id, 'test')]]) + ) + feed('<Ignore>') -- add input to separate two RPC requests -- channel has been released after one main loop iteration eq(chans - 1, eval('len(nvim_list_chans())')) end) @@ -70,16 +78,18 @@ describe('terminal channel is closed and later released if', function() command([[let id = termopen('echo')]]) local chans = eval('len(nvim_list_chans())') -- wait for process to exit - screen:expect({any='%[Process exited 0%]'}) + screen:expect({ any = '%[Process exited 0%]' }) -- process has exited but channel has't been released - eq("Vim(call):Can't send data to closed stream", - pcall_err(command, [[call chansend(id, 'test')]])) + eq( + "Vim(call):Can't send data to closed stream", + pcall_err(command, [[call chansend(id, 'test')]]) + ) eq(chans, eval('len(nvim_list_chans())')) -- delete terminal feed('i<CR>') -- need to first process input poke_eventloop() - feed('<Ignore>') -- add input to separate two RPC requests + feed('<Ignore>') -- add input to separate two RPC requests -- channel has been released after another main loop iteration eq(chans - 1, eval('len(nvim_list_chans())')) end) @@ -89,34 +99,38 @@ describe('terminal channel is closed and later released if', function() command([[let id = termopen('echo')]]) local chans = eval('len(nvim_list_chans())') -- wait for process to exit - screen:expect({any='%[Process exited 0%]'}) + screen:expect({ any = '%[Process exited 0%]' }) -- process has exited but channel hasn't been released - eq("Vim(call):Can't send data to closed stream", - pcall_err(command, [[call chansend(id, 'test')]])) + eq( + "Vim(call):Can't send data to closed stream", + pcall_err(command, [[call chansend(id, 'test')]]) + ) eq(chans, eval('len(nvim_list_chans())')) -- channel still hasn't been released yet - eq("Vim(call):Can't send data to closed stream", - pcall_err(command, [[bdelete | call chansend(id, 'test')]])) - feed('<Ignore>') -- add input to separate two RPC requests + eq( + "Vim(call):Can't send data to closed stream", + pcall_err(command, [[bdelete | call chansend(id, 'test')]]) + ) + feed('<Ignore>') -- add input to separate two RPC requests -- channel has been released after one main loop iteration eq(chans - 1, eval('len(nvim_list_chans())')) end) end) it('chansend sends lines to terminal channel in proper order', function() - clear({args = {'--cmd', 'set laststatus=2'}}) + clear({ args = { '--cmd', 'set laststatus=2' } }) local screen = Screen.new(100, 20) screen:attach() - local shells = is_os('win') and {'cmd.exe', 'pwsh.exe -nop', 'powershell.exe -nop'} or {'sh'} + local shells = is_os('win') and { 'cmd.exe', 'pwsh.exe -nop', 'powershell.exe -nop' } or { 'sh' } for _, sh in ipairs(shells) do command([[let id = termopen(']] .. sh .. [[')]]) command([[call chansend(id, ['echo "hello"', 'echo "world"', ''])]]) - screen:expect{ - any=[[echo "hello".*echo "world"]] + screen:expect { + any = [[echo "hello".*echo "world"]], } command('bdelete!') - screen:expect{ - any='%[No Name%]' + screen:expect { + any = '%[No Name%]', } end end) @@ -126,76 +140,139 @@ describe('no crash when TermOpen autocommand', function() before_each(function() clear() - meths.set_option_value('shell', testprg('shell-test'), {}) + api.nvim_set_option_value('shell', testprg('shell-test'), {}) command('set shellcmdflag=EXE shellredir= shellpipe= shellquote= shellxquote=') screen = Screen.new(60, 4) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}; + [0] = { bold = true, foreground = Screen.colors.Blue }, }) screen:attach() end) it('processes job exit event when using termopen()', function() command([[autocmd TermOpen * call input('')]]) - async_meths.command('terminal foobar') - screen:expect{grid=[[ + async_meths.nvim_command('terminal foobar') + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| + {0:~ }|*2 ^ | - ]]} + ]], + } feed('<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ready $ foobar | | [Process exited 0] | | - ]]} + ]], + } feed('i<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]]} + ]], + } assert_alive() end) it('wipes buffer and processes events when using termopen()', function() command([[autocmd TermOpen * bwipe! | call input('')]]) - async_meths.command('terminal foobar') - screen:expect{grid=[[ + async_meths.nvim_command('terminal foobar') + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| + {0:~ }|*2 ^ | - ]]} + ]], + } feed('<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]]} + ]], + } assert_alive() end) it('wipes buffer and processes events when using nvim_open_term()', function() command([[autocmd TermOpen * bwipe! | call input('')]]) - async_meths.open_term(0, {}) - screen:expect{grid=[[ + async_meths.nvim_open_term(0, {}) + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| + {0:~ }|*2 ^ | - ]]} + ]], + } feed('<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]]} + ]], + } assert_alive() end) end) + +describe('nvim_open_term', function() + local screen + + before_each(function() + clear() + screen = Screen.new(8, 10) + screen:attach() + end) + + it('with force_crlf=true converts newlines', function() + local win = api.nvim_get_current_win() + local buf = api.nvim_create_buf(false, true) + local term = api.nvim_open_term(buf, { force_crlf = true }) + api.nvim_win_set_buf(win, buf) + api.nvim_chan_send(term, 'here\nthere\nfoo\r\nbar\n\ntest') + screen:expect { + grid = [[ + ^here | + there | + foo | + bar | + | + test | + |*4 + ]], + } + api.nvim_chan_send(term, '\nfirst') + screen:expect { + grid = [[ + ^here | + there | + foo | + bar | + | + test | + first | + |*3 + ]], + } + end) + + it('with force_crlf=false does not convert newlines', function() + local win = api.nvim_get_current_win() + local buf = api.nvim_create_buf(false, true) + local term = api.nvim_open_term(buf, { force_crlf = false }) + api.nvim_win_set_buf(win, buf) + api.nvim_chan_send(term, 'here\nthere') + screen:expect { grid = [[ + ^here | + there | + |*8 + ]] } + end) +end) diff --git a/test/functional/terminal/cursor_spec.lua b/test/functional/terminal/cursor_spec.lua index 8285bcc26e..73fd97203e 100644 --- a/test/functional/terminal/cursor_spec.lua +++ b/test/functional/terminal/cursor_spec.lua @@ -1,9 +1,8 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local thelpers = require('test.functional.terminal.helpers') -local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim +local feed, clear = helpers.feed, helpers.clear local testprg, command = helpers.testprg, helpers.command -local nvim_prog = helpers.nvim_prog local eq, eval = helpers.eq, helpers.eval local matches = helpers.matches local poke_eventloop = helpers.poke_eventloop @@ -20,16 +19,12 @@ describe(':terminal cursor', function() screen = thelpers.screen_setup() end) - it('moves the screen cursor when focused', function() thelpers.feed_data('testing cursor') screen:expect([[ tty ready | testing cursor{1: } | - | - | - | - | + |*4 {3:-- TERMINAL --} | ]]) end) @@ -39,11 +34,7 @@ describe(':terminal cursor', function() screen:expect([[ tty ready | {2:^ } | - | - | - | - | - | + |*5 ]]) end) @@ -94,21 +85,14 @@ describe(':terminal cursor', function() hide_cursor() screen:expect([[ tty ready | - | - | - | - | - | + |*5 {3:-- TERMINAL --} | ]]) show_cursor() screen:expect([[ tty ready | {1: } | - | - | - | - | + |*4 {3:-- TERMINAL --} | ]]) -- same for when the terminal is unfocused @@ -117,42 +101,33 @@ describe(':terminal cursor', function() screen:expect([[ tty ready | ^ | - | - | - | - | - | + |*5 ]]) show_cursor() screen:expect([[ tty ready | {2:^ } | - | - | - | - | - | + |*5 ]]) end) end) end) - describe('cursor with customized highlighting', function() local screen before_each(function() clear() - nvim('command', 'highlight TermCursor ctermfg=45 ctermbg=46 cterm=NONE') - nvim('command', 'highlight TermCursorNC ctermfg=55 ctermbg=56 cterm=NONE') + command('highlight TermCursor ctermfg=45 ctermbg=46 cterm=NONE') + command('highlight TermCursorNC ctermfg=55 ctermbg=56 cterm=NONE') screen = Screen.new(50, 7) screen:set_default_attr_ids({ - [1] = {foreground = 45, background = 46}, - [2] = {foreground = 55, background = 56}, - [3] = {bold = true}, + [1] = { foreground = 45, background = 46 }, + [2] = { foreground = 55, background = 56 }, + [3] = { bold = true }, }) - screen:attach({rgb=false}) - command('call termopen(["'..testprg('tty-test')..'"])') + screen:attach({ rgb = false }) + command('call termopen(["' .. testprg('tty-test') .. '"])') feed('i') poke_eventloop() end) @@ -161,21 +136,14 @@ describe('cursor with customized highlighting', function() screen:expect([[ tty ready | {1: } | - | - | - | - | + |*4 {3:-- TERMINAL --} | ]]) feed('<c-\\><c-n>') screen:expect([[ tty ready | {2:^ } | - | - | - | - | - | + |*5 ]]) end) end) @@ -184,20 +152,37 @@ describe('buffer cursor position is correct in terminal without number column', local screen local function setup_ex_register(str) - screen = thelpers.screen_setup(0, '["'..nvim_prog - ..[[", "-u", "NONE", "-i", "NONE", "-E", "--cmd", "let @r = ']]..str..[['", ]] + screen = thelpers.setup_child_nvim({ + '-u', + 'NONE', + '-i', + 'NONE', + '-E', + '--cmd', + string.format('let @r = "%s"', str), -- <Left> and <Right> don't always work - ..[["--cmd", "cnoremap <C-X> <Left>", "--cmd", "cnoremap <C-O> <Right>"]]..']', 70) + '--cmd', + 'cnoremap <C-X> <Left>', + '--cmd', + 'cnoremap <C-O> <Right>', + '--cmd', + 'set notermguicolors', + }, { + cols = 70, + }) + screen:set_default_attr_ids({ + [1] = { foreground = 253, background = 11 }, + [2] = { reverse = true }, + [3] = { bold = true }, + [4] = { background = 11 }, + }) -- Also check for real cursor position, as it is used for stuff like input methods screen._handle_busy_start = function() end screen._handle_busy_stop = function() end screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :{1:^ } | + :{2:^ } | {3:-- TERMINAL --} | ]]) end @@ -212,76 +197,58 @@ describe('buffer cursor position is correct in terminal without number column', it('at the end', function() feed('<C-R>r') screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :aaaaaaaa{1:^ } | + :aaaaaaaa{2:^ } | {3:-- TERMINAL --} | ]]) - eq({6, 9}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 9 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :aaaaaaa^a{2: } | + :aaaaaaa^a{4: } | | ]]) - eq({6, 8}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 8 }, eval('nvim_win_get_cursor(0)')) end) it('near the end', function() feed('<C-R>r<C-X><C-X>') screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :aaaaaa{1:^a}a | + :aaaaaa{2:^a}a | {3:-- TERMINAL --} | ]]) - eq({6, 7}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 7 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :aaaaa^a{2:a}a | + :aaaaa^a{4:a}a | | ]]) - eq({6, 6}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 6 }, eval('nvim_win_get_cursor(0)')) end) it('near the start', function() feed('<C-R>r<C-B><C-O>') screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :a{1:^a}aaaaaa | + :a{2:^a}aaaaaa | {3:-- TERMINAL --} | ]]) - eq({6, 2}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 2 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :^a{2:a}aaaaaa | + :^a{4:a}aaaaaa | | ]]) - eq({6, 1}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 1 }, eval('nvim_win_get_cursor(0)')) end) end) @@ -293,164 +260,135 @@ describe('buffer cursor position is correct in terminal without number column', it('at the end', function() feed('<C-R>r') screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :µµµµµµµµ{1:^ } | + :µµµµµµµµ{2:^ } | {3:-- TERMINAL --} | ]]) - eq({6, 17}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 17 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :µµµµµµµ^µ{2: } | + :µµµµµµµ^µ{4: } | | ]]) - eq({6, 15}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 15 }, eval('nvim_win_get_cursor(0)')) end) it('near the end', function() feed('<C-R>r<C-X><C-X>') screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :µµµµµµ{1:^µ}µ | + :µµµµµµ{2:^µ}µ | {3:-- TERMINAL --} | ]]) - eq({6, 13}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 13 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :µµµµµ^µ{2:µ}µ | + :µµµµµ^µ{4:µ}µ | | ]]) - eq({6, 11}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 11 }, eval('nvim_win_get_cursor(0)')) end) it('near the start', function() feed('<C-R>r<C-B><C-O>') screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :µ{1:^µ}µµµµµµ | + :µ{2:^µ}µµµµµµ | {3:-- TERMINAL --} | ]]) - eq({6, 3}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 3 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :^µ{2:µ}µµµµµµ | + :^µ{4:µ}µµµµµµ | | ]]) - eq({6, 1}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 1 }, eval('nvim_win_get_cursor(0)')) end) end) - describe('in a line with single-cell composed multibyte characters and no trailing spaces,', function() - if skip(is_os('win'), "Encoding problem?") then return end - - before_each(function() - setup_ex_register('µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳') - end) - - it('at the end', function() - feed('<C-R>r') - screen:expect([[ - | - | - | - | + describe( + 'in a line with single-cell composed multibyte characters and no trailing spaces,', + function() + if skip(is_os('win'), 'Encoding problem?') then + return + end + + before_each(function() + setup_ex_register('µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳') + end) + + it('at the end', function() + feed('<C-R>r') + screen:expect([[ + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳{1:^ } | + :µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳{2:^ } | {3:-- TERMINAL --} | ]]) - eq({6, 33}, eval('nvim_win_get_cursor(0)')) - feed([[<C-\><C-N>]]) - screen:expect([[ - | - | - | - | + eq({ 6, 33 }, eval('nvim_win_get_cursor(0)')) + feed([[<C-\><C-N>]]) + screen:expect([[ + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :µ̳µ̳µ̳µ̳µ̳µ̳µ̳^µ̳{2: } | + :µ̳µ̳µ̳µ̳µ̳µ̳µ̳^µ̳{4: } | | ]]) - eq({6, 29}, eval('nvim_win_get_cursor(0)')) - end) + eq({ 6, 29 }, eval('nvim_win_get_cursor(0)')) + end) - it('near the end', function() - feed('<C-R>r<C-X><C-X>') - screen:expect([[ - | - | - | - | + it('near the end', function() + feed('<C-R>r<C-X><C-X>') + screen:expect([[ + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :µ̳µ̳µ̳µ̳µ̳µ̳{1:^µ̳}µ̳ | + :µ̳µ̳µ̳µ̳µ̳µ̳{2:^µ̳}µ̳ | {3:-- TERMINAL --} | ]]) - eq({6, 25}, eval('nvim_win_get_cursor(0)')) - feed([[<C-\><C-N>]]) - screen:expect([[ - | - | - | - | + eq({ 6, 25 }, eval('nvim_win_get_cursor(0)')) + feed([[<C-\><C-N>]]) + screen:expect([[ + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :µ̳µ̳µ̳µ̳µ̳^µ̳{2:µ̳}µ̳ | + :µ̳µ̳µ̳µ̳µ̳^µ̳{4:µ̳}µ̳ | | ]]) - eq({6, 21}, eval('nvim_win_get_cursor(0)')) - end) + eq({ 6, 21 }, eval('nvim_win_get_cursor(0)')) + end) - it('near the start', function() - feed('<C-R>r<C-B><C-O>') - screen:expect([[ - | - | - | - | + it('near the start', function() + feed('<C-R>r<C-B><C-O>') + screen:expect([[ + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :µ̳{1:^µ̳}µ̳µ̳µ̳µ̳µ̳µ̳ | + :µ̳{2:^µ̳}µ̳µ̳µ̳µ̳µ̳µ̳ | {3:-- TERMINAL --} | ]]) - eq({6, 5}, eval('nvim_win_get_cursor(0)')) - feed([[<C-\><C-N>]]) - screen:expect([[ - | - | - | - | + eq({ 6, 5 }, eval('nvim_win_get_cursor(0)')) + feed([[<C-\><C-N>]]) + screen:expect([[ + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :^µ̳{2:µ̳}µ̳µ̳µ̳µ̳µ̳µ̳ | + :^µ̳{4:µ̳}µ̳µ̳µ̳µ̳µ̳µ̳ | | ]]) - eq({6, 1}, eval('nvim_win_get_cursor(0)')) - end) - end) + eq({ 6, 1 }, eval('nvim_win_get_cursor(0)')) + end) + end + ) describe('in a line with double-cell multibyte characters and no trailing spaces,', function() - if skip(is_os('win'), "Encoding problem?") then return end + if skip(is_os('win'), 'Encoding problem?') then + return + end before_each(function() setup_ex_register('哦哦哦哦哦哦哦哦') @@ -459,76 +397,58 @@ describe('buffer cursor position is correct in terminal without number column', it('at the end', function() feed('<C-R>r') screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :哦哦哦哦哦哦哦哦{1:^ } | + :哦哦哦哦哦哦哦哦{2:^ } | {3:-- TERMINAL --} | ]]) - eq({6, 25}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 25 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :哦哦哦哦哦哦哦^哦{2: } | + :哦哦哦哦哦哦哦^哦{4: } | | ]]) - eq({6, 22}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 22 }, eval('nvim_win_get_cursor(0)')) end) it('near the end', function() feed('<C-R>r<C-X><C-X>') screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :哦哦哦哦哦哦{1:^哦}哦 | + :哦哦哦哦哦哦{2:^哦}哦 | {3:-- TERMINAL --} | ]]) - eq({6, 19}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 19 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :哦哦哦哦哦^哦{2:哦}哦 | + :哦哦哦哦哦^哦{4:哦}哦 | | ]]) - eq({6, 16}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 16 }, eval('nvim_win_get_cursor(0)')) end) it('near the start', function() feed('<C-R>r<C-B><C-O>') screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :哦{1:^哦}哦哦哦哦哦哦 | + :哦{2:^哦}哦哦哦哦哦哦 | {3:-- TERMINAL --} | ]]) - eq({6, 4}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 4 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :^哦{2:哦}哦哦哦哦哦哦 | + :^哦{4:哦}哦哦哦哦哦哦 | | ]]) - eq({6, 1}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 1 }, eval('nvim_win_get_cursor(0)')) end) end) @@ -536,27 +456,21 @@ describe('buffer cursor position is correct in terminal without number column', setup_ex_register('aaaaaaaa ') feed('<C-R>r') screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :aaaaaaaa {1:^ } | + :aaaaaaaa {2:^ } | {3:-- TERMINAL --} | ]]) matches('^:aaaaaaaa [ ]*$', eval('nvim_get_current_line()')) - eq({6, 13}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 13 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ - | - | - | - | + |*4 Entering Ex mode. Type "visual" to go to Normal mode. | - :aaaaaaaa ^ {2: } | + :aaaaaaaa ^ {4: } | | ]]) - eq({6, 12}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 12 }, eval('nvim_win_get_cursor(0)')) end) end) @@ -564,10 +478,31 @@ describe('buffer cursor position is correct in terminal with number column', fun local screen local function setup_ex_register(str) - screen = thelpers.screen_setup(0, '["'..nvim_prog - ..[[", "-u", "NONE", "-i", "NONE", "-E", "--cmd", "let @r = ']]..str..[['", ]] + screen = thelpers.setup_child_nvim({ + '-u', + 'NONE', + '-i', + 'NONE', + '-E', + '--cmd', + string.format('let @r = "%s"', str), -- <Left> and <Right> don't always work - ..[["--cmd", "cnoremap <C-X> <Left>", "--cmd", "cnoremap <C-O> <Right>"]]..']', 70) + '--cmd', + 'cnoremap <C-X> <Left>', + '--cmd', + 'cnoremap <C-O> <Right>', + '--cmd', + 'set notermguicolors', + }, { + cols = 70, + }) + screen:set_default_attr_ids({ + [1] = { foreground = 253, background = 11 }, + [2] = { reverse = true }, + [3] = { bold = true }, + [4] = { background = 11 }, + [7] = { foreground = 130 }, + }) -- Also check for real cursor position, as it is used for stuff like input methods screen._handle_busy_start = function() end screen._handle_busy_stop = function() end @@ -577,7 +512,7 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:{1:^ } | + {7: 6 }:{2:^ } | {3:-- TERMINAL --} | ]]) end @@ -600,10 +535,10 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:aaaaaaaa{1:^ } | + {7: 6 }:aaaaaaaa{2:^ } | {3:-- TERMINAL --} | ]]) - eq({6, 9}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 9 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ {7: 1 } | @@ -611,10 +546,10 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:aaaaaaa^a{2: } | + {7: 6 }:aaaaaaa^a{4: } | | ]]) - eq({6, 8}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 8 }, eval('nvim_win_get_cursor(0)')) end) it('near the end', function() @@ -625,10 +560,10 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:aaaaaa{1:^a}a | + {7: 6 }:aaaaaa{2:^a}a | {3:-- TERMINAL --} | ]]) - eq({6, 7}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 7 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ {7: 1 } | @@ -636,10 +571,10 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:aaaaa^a{2:a}a | + {7: 6 }:aaaaa^a{4:a}a | | ]]) - eq({6, 6}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 6 }, eval('nvim_win_get_cursor(0)')) end) it('near the start', function() @@ -650,10 +585,10 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:a{1:^a}aaaaaa | + {7: 6 }:a{2:^a}aaaaaa | {3:-- TERMINAL --} | ]]) - eq({6, 2}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 2 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ {7: 1 } | @@ -661,10 +596,10 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:^a{2:a}aaaaaa | + {7: 6 }:^a{4:a}aaaaaa | | ]]) - eq({6, 1}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 1 }, eval('nvim_win_get_cursor(0)')) end) end) @@ -681,10 +616,10 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:µµµµµµµµ{1:^ } | + {7: 6 }:µµµµµµµµ{2:^ } | {3:-- TERMINAL --} | ]]) - eq({6, 17}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 17 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ {7: 1 } | @@ -692,10 +627,10 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:µµµµµµµ^µ{2: } | + {7: 6 }:µµµµµµµ^µ{4: } | | ]]) - eq({6, 15}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 15 }, eval('nvim_win_get_cursor(0)')) end) it('near the end', function() @@ -706,10 +641,10 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:µµµµµµ{1:^µ}µ | + {7: 6 }:µµµµµµ{2:^µ}µ | {3:-- TERMINAL --} | ]]) - eq({6, 13}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 13 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ {7: 1 } | @@ -717,10 +652,10 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:µµµµµ^µ{2:µ}µ | + {7: 6 }:µµµµµ^µ{4:µ}µ | | ]]) - eq({6, 11}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 11 }, eval('nvim_win_get_cursor(0)')) end) it('near the start', function() @@ -731,10 +666,10 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:µ{1:^µ}µµµµµµ | + {7: 6 }:µ{2:^µ}µµµµµµ | {3:-- TERMINAL --} | ]]) - eq({6, 3}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 3 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ {7: 1 } | @@ -742,98 +677,105 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:^µ{2:µ}µµµµµµ | + {7: 6 }:^µ{4:µ}µµµµµµ | | ]]) - eq({6, 1}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 1 }, eval('nvim_win_get_cursor(0)')) end) end) - describe('in a line with single-cell composed multibyte characters and no trailing spaces,', function() - if skip(is_os('win'), "Encoding problem?") then return end + describe( + 'in a line with single-cell composed multibyte characters and no trailing spaces,', + function() + if skip(is_os('win'), 'Encoding problem?') then + return + end - before_each(function() - setup_ex_register('µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳') - end) + before_each(function() + setup_ex_register('µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳') + end) - it('at the end', function() - feed('<C-R>r') - screen:expect([[ + it('at the end', function() + feed('<C-R>r') + screen:expect([[ {7: 1 } | {7: 2 } | {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳{1:^ } | + {7: 6 }:µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳{2:^ } | {3:-- TERMINAL --} | ]]) - eq({6, 33}, eval('nvim_win_get_cursor(0)')) - feed([[<C-\><C-N>]]) - screen:expect([[ + eq({ 6, 33 }, eval('nvim_win_get_cursor(0)')) + feed([[<C-\><C-N>]]) + screen:expect([[ {7: 1 } | {7: 2 } | {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:µ̳µ̳µ̳µ̳µ̳µ̳µ̳^µ̳{2: } | + {7: 6 }:µ̳µ̳µ̳µ̳µ̳µ̳µ̳^µ̳{4: } | | ]]) - eq({6, 29}, eval('nvim_win_get_cursor(0)')) - end) + eq({ 6, 29 }, eval('nvim_win_get_cursor(0)')) + end) - it('near the end', function() - feed('<C-R>r<C-X><C-X>') - screen:expect([[ + it('near the end', function() + feed('<C-R>r<C-X><C-X>') + screen:expect([[ {7: 1 } | {7: 2 } | {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:µ̳µ̳µ̳µ̳µ̳µ̳{1:^µ̳}µ̳ | + {7: 6 }:µ̳µ̳µ̳µ̳µ̳µ̳{2:^µ̳}µ̳ | {3:-- TERMINAL --} | ]]) - eq({6, 25}, eval('nvim_win_get_cursor(0)')) - feed([[<C-\><C-N>]]) - screen:expect([[ + eq({ 6, 25 }, eval('nvim_win_get_cursor(0)')) + feed([[<C-\><C-N>]]) + screen:expect([[ {7: 1 } | {7: 2 } | {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:µ̳µ̳µ̳µ̳µ̳^µ̳{2:µ̳}µ̳ | + {7: 6 }:µ̳µ̳µ̳µ̳µ̳^µ̳{4:µ̳}µ̳ | | ]]) - eq({6, 21}, eval('nvim_win_get_cursor(0)')) - end) + eq({ 6, 21 }, eval('nvim_win_get_cursor(0)')) + end) - it('near the start', function() - feed('<C-R>r<C-B><C-O>') - screen:expect([[ + it('near the start', function() + feed('<C-R>r<C-B><C-O>') + screen:expect([[ {7: 1 } | {7: 2 } | {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:µ̳{1:^µ̳}µ̳µ̳µ̳µ̳µ̳µ̳ | + {7: 6 }:µ̳{2:^µ̳}µ̳µ̳µ̳µ̳µ̳µ̳ | {3:-- TERMINAL --} | ]]) - eq({6, 5}, eval('nvim_win_get_cursor(0)')) - feed([[<C-\><C-N>]]) - screen:expect([[ + eq({ 6, 5 }, eval('nvim_win_get_cursor(0)')) + feed([[<C-\><C-N>]]) + screen:expect([[ {7: 1 } | {7: 2 } | {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:^µ̳{2:µ̳}µ̳µ̳µ̳µ̳µ̳µ̳ | + {7: 6 }:^µ̳{4:µ̳}µ̳µ̳µ̳µ̳µ̳µ̳ | | ]]) - eq({6, 1}, eval('nvim_win_get_cursor(0)')) - end) - end) + eq({ 6, 1 }, eval('nvim_win_get_cursor(0)')) + end) + end + ) describe('in a line with double-cell multibyte characters and no trailing spaces,', function() - if skip(is_os('win'), "Encoding problem?") then return end + if skip(is_os('win'), 'Encoding problem?') then + return + end before_each(function() setup_ex_register('哦哦哦哦哦哦哦哦') @@ -847,10 +789,10 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:哦哦哦哦哦哦哦哦{1:^ } | + {7: 6 }:哦哦哦哦哦哦哦哦{2:^ } | {3:-- TERMINAL --} | ]]) - eq({6, 25}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 25 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ {7: 1 } | @@ -858,10 +800,10 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:哦哦哦哦哦哦哦^哦{2: } | + {7: 6 }:哦哦哦哦哦哦哦^哦{4: } | | ]]) - eq({6, 22}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 22 }, eval('nvim_win_get_cursor(0)')) end) it('near the end', function() @@ -872,10 +814,10 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:哦哦哦哦哦哦{1:^哦}哦 | + {7: 6 }:哦哦哦哦哦哦{2:^哦}哦 | {3:-- TERMINAL --} | ]]) - eq({6, 19}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 19 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ {7: 1 } | @@ -883,10 +825,10 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:哦哦哦哦哦^哦{2:哦}哦 | + {7: 6 }:哦哦哦哦哦^哦{4:哦}哦 | | ]]) - eq({6, 16}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 16 }, eval('nvim_win_get_cursor(0)')) end) it('near the start', function() @@ -897,10 +839,10 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:哦{1:^哦}哦哦哦哦哦哦 | + {7: 6 }:哦{2:^哦}哦哦哦哦哦哦 | {3:-- TERMINAL --} | ]]) - eq({6, 4}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 4 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ {7: 1 } | @@ -908,10 +850,10 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:^哦{2:哦}哦哦哦哦哦哦 | + {7: 6 }:^哦{4:哦}哦哦哦哦哦哦 | | ]]) - eq({6, 1}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 1 }, eval('nvim_win_get_cursor(0)')) end) end) @@ -924,11 +866,11 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:aaaaaaaa {1:^ } | + {7: 6 }:aaaaaaaa {2:^ } | {3:-- TERMINAL --} | ]]) matches('^:aaaaaaaa [ ]*$', eval('nvim_get_current_line()')) - eq({6, 13}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 13 }, eval('nvim_win_get_cursor(0)')) feed([[<C-\><C-N>]]) screen:expect([[ {7: 1 } | @@ -936,9 +878,9 @@ describe('buffer cursor position is correct in terminal with number column', fun {7: 3 } | {7: 4 } | {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. | - {7: 6 }:aaaaaaaa ^ {2: } | + {7: 6 }:aaaaaaaa ^ {4: } | | ]]) - eq({6, 12}, eval('nvim_win_get_cursor(0)')) + eq({ 6, 12 }, eval('nvim_win_get_cursor(0)')) end) end) diff --git a/test/functional/terminal/edit_spec.lua b/test/functional/terminal/edit_spec.lua index 29361bc0fa..f7ceb0a68b 100644 --- a/test/functional/terminal/edit_spec.lua +++ b/test/functional/terminal/edit_spec.lua @@ -1,72 +1,68 @@ local helpers = require('test.functional.helpers')(after_each) local screen = require('test.functional.ui.screen') -local curbufmeths = helpers.curbufmeths -local curwinmeths = helpers.curwinmeths local testprg = helpers.testprg local command = helpers.command -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local clear = helpers.clear local eq = helpers.eq local matches = helpers.matches -local pesc = helpers.pesc +local pesc = vim.pesc describe(':edit term://*', function() local get_screen = function(columns, lines) local scr = screen.new(columns, lines) - scr:attach({rgb=false}) + scr:attach({ rgb = false }) return scr end before_each(function() clear() - meths.set_option_value('shell', testprg('shell-test'), {}) - meths.set_option_value('shellcmdflag', 'EXE', {}) + api.nvim_set_option_value('shell', testprg('shell-test'), {}) + api.nvim_set_option_value('shellcmdflag', 'EXE', {}) end) it('runs TermOpen event', function() - meths.set_var('termopen_runs', {}) + api.nvim_set_var('termopen_runs', {}) command('autocmd TermOpen * :call add(g:termopen_runs, expand("<amatch>"))') command('edit term://') - local termopen_runs = meths.get_var('termopen_runs') + local termopen_runs = api.nvim_get_var('termopen_runs') eq(1, #termopen_runs) - local cwd = funcs.fnamemodify('.', ':p:~'):gsub([[[\/]*$]], '') - matches('^term://'..pesc(cwd)..'//%d+:$', termopen_runs[1]) + local cwd = fn.fnamemodify('.', ':p:~'):gsub([[[\/]*$]], '') + matches('^term://' .. pesc(cwd) .. '//%d+:$', termopen_runs[1]) end) it("runs TermOpen early enough to set buffer-local 'scrollback'", function() local columns, lines = 20, 4 local scr = get_screen(columns, lines) local rep = 97 - meths.set_option_value('shellcmdflag', 'REP ' .. rep, {}) - command('set shellxquote=') -- win: avoid extra quotes + api.nvim_set_option_value('shellcmdflag', 'REP ' .. rep, {}) + command('set shellxquote=') -- win: avoid extra quotes local sb = 10 - command('autocmd TermOpen * :setlocal scrollback='..tostring(sb) - ..'|call feedkeys("G", "n")') + command( + 'autocmd TermOpen * :setlocal scrollback=' .. tostring(sb) .. '|call feedkeys("G", "n")' + ) command('edit term://foobar') local bufcontents = {} - local winheight = curwinmeths.get_height() + local winheight = api.nvim_win_get_height(0) local buf_cont_start = rep - sb - winheight + 2 - for i = buf_cont_start,(rep - 1) do + for i = buf_cont_start, (rep - 1) do bufcontents[#bufcontents + 1] = ('%d: foobar'):format(i) end bufcontents[#bufcontents + 1] = '' bufcontents[#bufcontents + 1] = '[Process exited 0]' local exp_screen = '\n' - for i = 1,(winheight - 1) do + for i = 1, (winheight - 1) do local line = bufcontents[#bufcontents - winheight + i] - exp_screen = (exp_screen - .. line - .. (' '):rep(columns - #line) - .. '|\n') + exp_screen = (exp_screen .. line .. (' '):rep(columns - #line) .. '|\n') end - exp_screen = exp_screen..'^[Process exited 0] |\n' + exp_screen = exp_screen .. '^[Process exited 0] |\n' - exp_screen = exp_screen..(' '):rep(columns)..'|\n' + exp_screen = exp_screen .. (' '):rep(columns) .. '|\n' scr:expect(exp_screen) - eq(bufcontents, curbufmeths.get_lines(0, -1, true)) + eq(bufcontents, api.nvim_buf_get_lines(0, 0, -1, true)) end) end) diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua index f628e261a2..92d37fc04a 100644 --- a/test/functional/terminal/ex_terminal_spec.lua +++ b/test/functional/terminal/ex_terminal_spec.lua @@ -1,11 +1,12 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local assert_alive = helpers.assert_alive -local clear, poke_eventloop, nvim = helpers.clear, helpers.poke_eventloop, helpers.nvim +local clear, poke_eventloop = helpers.clear, helpers.poke_eventloop local testprg, source, eq = helpers.testprg, helpers.source, helpers.eq local feed = helpers.feed local feed_command, eval = helpers.feed_command, helpers.eval -local funcs = helpers.funcs +local fn = helpers.fn +local api = helpers.api local retry = helpers.retry local ok = helpers.ok local command = helpers.command @@ -19,10 +20,10 @@ describe(':terminal', function() before_each(function() clear() screen = Screen.new(50, 4) - screen:attach({rgb=false}) + screen:attach({ rgb = false }) end) - it("does not interrupt Press-ENTER prompt #2748", function() + it('does not interrupt Press-ENTER prompt #2748', function() -- Ensure that :messages shows Press-ENTER. source([[ echomsg "msg1" @@ -30,14 +31,14 @@ describe(':terminal', function() echomsg "msg3" ]]) -- Invoke a command that emits frequent terminal activity. - feed([[:terminal "]]..testprg('shell-test')..[[" REP 9999 !terminal_output!<cr>]]) + feed([[:terminal "]] .. testprg('shell-test') .. [[" REP 9999 !terminal_output!<cr>]]) feed([[<C-\><C-N>]]) poke_eventloop() -- Wait for some terminal activity. retry(nil, 4000, function() - ok(funcs.line('$') > 6) + ok(fn.line('$') > 6) end) - feed_command("messages") + feed_command('messages') screen:expect([[ msg1 | msg2 | @@ -46,36 +47,40 @@ describe(':terminal', function() ]]) end) - it("reads output buffer on terminal reporting #4151", function() + it('reads output buffer on terminal reporting #4151', function() skip(is_ci('cirrus') or is_os('win')) if is_os('win') then - feed_command([[terminal powershell -NoProfile -NoLogo -Command Write-Host -NoNewline "\"$([char]27)[6n\""; Start-Sleep -Milliseconds 500 ]]) + feed_command( + [[terminal powershell -NoProfile -NoLogo -Command Write-Host -NoNewline "\"$([char]27)[6n\""; Start-Sleep -Milliseconds 500 ]] + ) else feed_command([[terminal printf '\e[6n'; sleep 0.5 ]]) end - screen:expect{any='%^%[%[1;1R'} + screen:expect { any = '%^%[%[1;1R' } end) - it("in normal-mode :split does not move cursor", function() + it('in normal-mode :split does not move cursor', function() if is_os('win') then - feed_command([[terminal for /L \\%I in (1,0,2) do ( echo foo & ping -w 100 -n 1 127.0.0.1 > nul )]]) + feed_command( + [[terminal for /L \\%I in (1,0,2) do ( echo foo & ping -w 100 -n 1 127.0.0.1 > nul )]] + ) else feed_command([[terminal while true; do echo foo; sleep .1; done]]) end - feed([[<C-\><C-N>M]]) -- move cursor away from last line + feed([[<C-\><C-N>M]]) -- move cursor away from last line poke_eventloop() - eq(3, eval("line('$')")) -- window height - eq(2, eval("line('.')")) -- cursor is in the middle + eq(3, eval("line('$')")) -- window height + eq(2, eval("line('.')")) -- cursor is in the middle feed_command('vsplit') - eq(2, eval("line('.')")) -- cursor stays where we put it + eq(2, eval("line('.')")) -- cursor stays where we put it feed_command('split') - eq(2, eval("line('.')")) -- cursor stays where we put it + eq(2, eval("line('.')")) -- cursor stays where we put it end) it('Enter/Leave does not increment jumplist #3723', function() feed_command('terminal') local function enter_and_leave() - local lines_before = funcs.line('$') + local lines_before = fn.line('$') -- Create a new line (in the shell). For a normal buffer this -- increments the jumplist; for a terminal-buffer it should not. #3723 feed('i') @@ -86,44 +91,44 @@ describe(':terminal', function() poke_eventloop() -- Wait for >=1 lines to be created. retry(nil, 4000, function() - ok(funcs.line('$') > lines_before) + ok(fn.line('$') > lines_before) end) end enter_and_leave() enter_and_leave() enter_and_leave() - ok(funcs.line('$') > 6) -- Verify assumption. - local jumps = funcs.split(funcs.execute('jumps'), '\n') + ok(fn.line('$') > 6) -- Verify assumption. + local jumps = fn.split(fn.execute('jumps'), '\n') eq(' jump line col file/text', jumps[1]) eq(3, #jumps) end) it('nvim_get_mode() in :terminal', function() command('terminal') - eq({ blocking=false, mode='nt' }, nvim('get_mode')) + eq({ blocking = false, mode = 'nt' }, api.nvim_get_mode()) feed('i') - eq({ blocking=false, mode='t' }, nvim('get_mode')) + eq({ blocking = false, mode = 't' }, api.nvim_get_mode()) feed([[<C-\><C-N>]]) - eq({ blocking=false, mode='nt' }, nvim('get_mode')) + eq({ blocking = false, mode = 'nt' }, api.nvim_get_mode()) end) it(':stopinsert RPC request exits terminal-mode #7807', function() command('terminal') feed('i[tui] insert-mode') - eq({ blocking=false, mode='t' }, nvim('get_mode')) + eq({ blocking = false, mode = 't' }, api.nvim_get_mode()) command('stopinsert') - feed('<Ignore>') -- Add input to separate two RPC requests - eq({ blocking=false, mode='nt' }, nvim('get_mode')) + feed('<Ignore>') -- Add input to separate two RPC requests + eq({ blocking = false, mode = 'nt' }, api.nvim_get_mode()) end) - it(':stopinsert in normal mode doesn\'t break insert mode #9889', function() + it(":stopinsert in normal mode doesn't break insert mode #9889", function() command('terminal') - eq({ blocking=false, mode='nt' }, nvim('get_mode')) + eq({ blocking = false, mode = 'nt' }, api.nvim_get_mode()) command('stopinsert') - feed('<Ignore>') -- Add input to separate two RPC requests - eq({ blocking=false, mode='nt' }, nvim('get_mode')) + feed('<Ignore>') -- Add input to separate two RPC requests + eq({ blocking = false, mode = 'nt' }, api.nvim_get_mode()) feed('a') - eq({ blocking=false, mode='t' }, nvim('get_mode')) + eq({ blocking = false, mode = 't' }, api.nvim_get_mode()) end) it('switching to terminal buffer in Insert mode goes to Terminal mode #7164', function() @@ -134,77 +139,73 @@ describe(':terminal', function() command('autocmd InsertLeave * let g:events += ["InsertLeave"]') command('autocmd TermEnter * let g:events += ["TermEnter"]') command('inoremap <F2> <Cmd>wincmd p<CR>') - eq({ blocking=false, mode='i' }, nvim('get_mode')) + eq({ blocking = false, mode = 'i' }, api.nvim_get_mode()) feed('<F2>') - eq({ blocking=false, mode='t' }, nvim('get_mode')) - eq({'InsertLeave', 'TermEnter'}, eval('g:events')) + eq({ blocking = false, mode = 't' }, api.nvim_get_mode()) + eq({ 'InsertLeave', 'TermEnter' }, eval('g:events')) + end) + + it('switching to terminal buffer immediately after :stopinsert #27031', function() + command('terminal') + command('vnew') + feed('i') + eq({ blocking = false, mode = 'i' }, api.nvim_get_mode()) + command('stopinsert | wincmd p') + eq({ blocking = false, mode = 'nt' }, api.nvim_get_mode()) end) end) -describe(':terminal (with fake shell)', function() +local function test_terminal_with_fake_shell(backslash) + -- shell-test.c is a fake shell that prints its arguments and exits. + local shell_path = testprg('shell-test') + if backslash then + shell_path = shell_path:gsub('/', [[\]]) + end + local screen before_each(function() clear() screen = Screen.new(50, 4) - screen:attach({rgb=false}) - -- shell-test.c is a fake shell that prints its arguments and exits. - nvim('set_option_value', 'shell', testprg('shell-test'), {}) - nvim('set_option_value', 'shellcmdflag', 'EXE', {}) - nvim('set_option_value', 'shellxquote', '', {}) + screen:attach({ rgb = false }) + api.nvim_set_option_value('shell', shell_path, {}) + api.nvim_set_option_value('shellcmdflag', 'EXE', {}) + api.nvim_set_option_value('shellxquote', '', {}) -- win: avoid extra quotes end) - -- Invokes `:terminal {cmd}` using a fake shell (shell-test.c) which prints - -- the {cmd} and exits immediately. - -- When no argument is given and the exit code is zero, the terminal buffer - -- closes automatically. - local function terminal_with_fake_shell(cmd) - feed_command("terminal "..(cmd and cmd or "")) - end - it('with no argument, acts like termopen()', function() - skip(is_os('win')) - -- Use the EXIT subcommand to end the process with a non-zero exit code to - -- prevent the buffer from closing automatically - nvim('set_option_value', 'shellcmdflag', 'EXIT', {}) - terminal_with_fake_shell(1) - retry(nil, 4 * screen.timeout, function() + command('autocmd! nvim_terminal TermClose') + feed_command('terminal') screen:expect([[ - ^ | - [Process exited 1] | + ^ready $ | + [Process exited 0] | | - :terminal 1 | + :terminal | ]]) - end) end) it("with no argument, and 'shell' is set to empty string", function() - nvim('set_option_value', 'shell', '', {}) - terminal_with_fake_shell() + api.nvim_set_option_value('shell', '', {}) + feed_command('terminal') screen:expect([[ ^ | - ~ | - ~ | + ~ |*2 E91: 'shell' option is empty | ]]) end) it("with no argument, but 'shell' has arguments, acts like termopen()", function() - skip(is_os('win')) - nvim('set_option_value', 'shell', testprg('shell-test')..' -t jeff', {}) - terminal_with_fake_shell() + api.nvim_set_option_value('shell', shell_path .. ' INTERACT', {}) + feed_command('terminal') screen:expect([[ - ^jeff $ | - [Process exited 0] | - | + ^interact $ | + |*2 :terminal | ]]) end) it('executes a given command through the shell', function() - skip(is_os('win')) - command('set shellxquote=') -- win: avoid extra quotes - terminal_with_fake_shell('echo hi') + feed_command('terminal echo hi') screen:expect([[ ^ready $ echo hi | | @@ -214,10 +215,8 @@ describe(':terminal (with fake shell)', function() end) it("executes a given command through the shell, when 'shell' has arguments", function() - skip(is_os('win')) - nvim('set_option_value', 'shell', testprg('shell-test')..' -t jeff', {}) - command('set shellxquote=') -- win: avoid extra quotes - terminal_with_fake_shell('echo hi') + api.nvim_set_option_value('shell', shell_path .. ' -t jeff', {}) + feed_command('terminal echo hi') screen:expect([[ ^jeff $ echo hi | | @@ -227,9 +226,7 @@ describe(':terminal (with fake shell)', function() end) it('allows quotes and slashes', function() - skip(is_os('win')) - command('set shellxquote=') -- win: avoid extra quotes - terminal_with_fake_shell([[echo 'hello' \ "world"]]) + feed_command([[terminal echo 'hello' \ "world"]]) screen:expect([[ ^ready $ echo 'hello' \ "world" | | @@ -242,38 +239,39 @@ describe(':terminal (with fake shell)', function() source([[ autocmd BufNew * set shell=foo terminal]]) - -- Verify that BufNew actually fired (else the test is invalid). + -- Verify that BufNew actually fired (else the test is invalid). eq('foo', eval('&shell')) end) it('ignores writes if the backing stream closes', function() - terminal_with_fake_shell() - feed('iiXXXXXXX') - poke_eventloop() - -- Race: Though the shell exited (and streams were closed by SIGCHLD - -- handler), :terminal cleanup is pending on the main-loop. - -- This write should be ignored (not crash, #5445). - feed('iiYYYYYYY') - assert_alive() + command('autocmd! nvim_terminal TermClose') + feed_command('terminal') + feed('iiXXXXXXX') + poke_eventloop() + -- Race: Though the shell exited (and streams were closed by SIGCHLD + -- handler), :terminal cleanup is pending on the main-loop. + -- This write should be ignored (not crash, #5445). + feed('iiYYYYYYY') + assert_alive() end) it('works with findfile()', function() + command('autocmd! nvim_terminal TermClose') feed_command('terminal') - eq('term://', string.match(eval('bufname("%")'), "^term://")) + eq('term://', string.match(eval('bufname("%")'), '^term://')) eq('scripts/shadacat.py', eval('findfile("scripts/shadacat.py", ".")')) end) it('works with :find', function() - skip(is_os('win')) - nvim('set_option_value', 'shellcmdflag', 'EXIT', {}) - terminal_with_fake_shell(1) + command('autocmd! nvim_terminal TermClose') + feed_command('terminal') screen:expect([[ - ^ | - [Process exited 1] | + ^ready $ | + [Process exited 0] | | - :terminal 1 | + :terminal | ]]) - eq('term://', string.match(eval('bufname("%")'), "^term://")) + eq('term://', string.match(eval('bufname("%")'), '^term://')) feed([[<C-\><C-N>]]) feed_command([[find */shadacat.py]]) if is_os('win') then @@ -284,19 +282,15 @@ describe(':terminal (with fake shell)', function() end) it('works with gf', function() - skip(is_os('win')) - command('set shellxquote=') -- win: avoid extra quotes - terminal_with_fake_shell([[echo "scripts/shadacat.py"]]) - retry(nil, 4 * screen.timeout, function() + feed_command([[terminal echo "scripts/shadacat.py"]]) screen:expect([[ ^ready $ echo "scripts/shadacat.py" | | [Process exited 0] | :terminal echo "scripts/shadacat.py" | ]]) - end) feed([[<C-\><C-N>]]) - eq('term://', string.match(eval('bufname("%")'), "^term://")) + eq('term://', string.match(eval('bufname("%")'), '^term://')) feed([[ggf"lgf]]) eq('scripts/shadacat.py', eval('bufname("%")')) end) @@ -311,4 +305,29 @@ describe(':terminal (with fake shell)', function() terminal]]) end end) + + describe('exit does not have long delay #27615', function() + for _, ut in ipairs({ 5, 50, 500, 5000, 50000, 500000 }) do + it(('with updatetime=%d'):format(ut), function() + api.nvim_set_option_value('updatetime', ut, {}) + api.nvim_set_option_value('shellcmdflag', 'EXIT', {}) + feed_command('terminal 42') + screen:expect([[ + ^ | + [Process exited 42] | + | + :terminal 42 | + ]]) + end) + end + end) +end + +describe(':terminal (with fake shell)', function() + test_terminal_with_fake_shell(false) + if is_os('win') then + describe("when 'shell' uses backslashes", function() + test_terminal_with_fake_shell(true) + end) + end end) diff --git a/test/functional/terminal/helpers.lua b/test/functional/terminal/helpers.lua index 62d3dd67a3..05db1b3c8c 100644 --- a/test/functional/terminal/helpers.lua +++ b/test/functional/terminal/helpers.lua @@ -5,11 +5,12 @@ local helpers = require('test.functional.helpers')(nil) local Screen = require('test.functional.ui.screen') local testprg = helpers.testprg local exec_lua = helpers.exec_lua -local nvim = helpers.nvim +local api = helpers.api +local nvim_prog = helpers.nvim_prog local function feed_data(data) if type(data) == 'table' then - data = table.concat(data, '\n') + data = table.concat(data, '\n') end exec_lua('vim.api.nvim_chan_send(vim.b.terminal_job_id, ...)', data) end @@ -20,7 +21,7 @@ end local function make_lua_executor(session) return function(code, ...) - local status, rv = session:request('nvim_exec_lua', code, {...}) + local status, rv = session:request('nvim_exec_lua', code, { ... }) if not status then session:stop() error(rv[2]) @@ -32,76 +33,108 @@ end -- some helpers for controlling the terminal. the codes were taken from -- infocmp xterm-256color which is less what libvterm understands -- civis/cnorm -local function hide_cursor() feed_termcode('[?25l') end -local function show_cursor() feed_termcode('[?25h') end +local function hide_cursor() + feed_termcode('[?25l') +end +local function show_cursor() + feed_termcode('[?25h') +end -- smcup/rmcup -local function enter_altscreen() feed_termcode('[?1049h') end -local function exit_altscreen() feed_termcode('[?1049l') end +local function enter_altscreen() + feed_termcode('[?1049h') +end +local function exit_altscreen() + feed_termcode('[?1049l') +end -- character attributes -local function set_fg(num) feed_termcode('[38;5;'..num..'m') end -local function set_bg(num) feed_termcode('[48;5;'..num..'m') end -local function set_bold() feed_termcode('[1m') end -local function set_italic() feed_termcode('[3m') end -local function set_underline() feed_termcode('[4m') end -local function set_underdouble() feed_termcode('[4:2m') end -local function set_undercurl() feed_termcode('[4:3m') end -local function set_strikethrough() feed_termcode('[9m') end -local function clear_attrs() feed_termcode('[0;10m') end +local function set_fg(num) + feed_termcode('[38;5;' .. num .. 'm') +end +local function set_bg(num) + feed_termcode('[48;5;' .. num .. 'm') +end +local function set_bold() + feed_termcode('[1m') +end +local function set_italic() + feed_termcode('[3m') +end +local function set_underline() + feed_termcode('[4m') +end +local function set_underdouble() + feed_termcode('[4:2m') +end +local function set_undercurl() + feed_termcode('[4:3m') +end +local function set_strikethrough() + feed_termcode('[9m') +end +local function clear_attrs() + feed_termcode('[0;10m') +end -- mouse -local function enable_mouse() feed_termcode('[?1002h') end -local function disable_mouse() feed_termcode('[?1002l') end +local function enable_mouse() + feed_termcode('[?1002h') +end +local function disable_mouse() + feed_termcode('[?1002l') +end -local default_command = '["'..testprg('tty-test')..'"]' +local default_command = { testprg('tty-test') } -local function screen_setup(extra_rows, command, cols, opts) +local function screen_setup(extra_rows, command, cols, env, screen_opts) extra_rows = extra_rows and extra_rows or 0 command = command and command or default_command cols = cols and cols or 50 - nvim('command', 'highlight TermCursor cterm=reverse') - nvim('command', 'highlight TermCursorNC ctermbg=11') + api.nvim_command('highlight TermCursor cterm=reverse') + api.nvim_command('highlight TermCursorNC ctermbg=11') local screen = Screen.new(cols, 7 + extra_rows) screen:set_default_attr_ids({ - [1] = {reverse = true}, -- focused cursor - [2] = {background = 11}, -- unfocused cursor - [3] = {bold = true}, - [4] = {foreground = 12}, - [5] = {bold = true, reverse = true}, - -- 6 was a duplicate item - [7] = {foreground = 130}, - [8] = {foreground = 15, background = 1}, -- error message - [9] = {foreground = 4}, - [10] = {foreground = 121}, -- "Press ENTER" in embedded :terminal session. - [11] = {foreground = tonumber('0x00000b')}, - [12] = {underline = true}, - [13] = {underline = true, reverse = true}, - [14] = {underline = true, reverse = true, bold = true}, - [15] = {underline = true, foreground = 12}, + [1] = { reverse = true }, -- focused cursor + [2] = { background = 11 }, -- unfocused cursor + [3] = { bold = true }, + [4] = { foreground = 12 }, -- NonText in :terminal session + [5] = { bold = true, reverse = true }, + [6] = { foreground = 81 }, -- SpecialKey in :terminal session + [7] = { foreground = 130 }, -- LineNr in host session + [8] = { foreground = 15, background = 1 }, -- ErrorMsg in :terminal session + [9] = { foreground = 4 }, + [10] = { foreground = 121 }, -- MoreMsg in :terminal session + [11] = { foreground = 11 }, -- LineNr in :terminal session + [12] = { underline = true }, + [13] = { underline = true, reverse = true }, + [14] = { underline = true, reverse = true, bold = true }, + [15] = { underline = true, foreground = 12 }, + [16] = { background = 248, foreground = 0 }, -- Visual in :terminal session }) - screen:attach(opts or {rgb=false}) + screen:attach(screen_opts or { rgb = false }) - nvim('command', 'enew | call termopen('..command..')') - nvim('input', '<CR>') - local vim_errmsg = nvim('eval', 'v:errmsg') - if vim_errmsg and "" ~= vim_errmsg then + api.nvim_command('enew') + api.nvim_call_function('termopen', { command, env and { env = env } or nil }) + api.nvim_input('<CR>') + local vim_errmsg = api.nvim_eval('v:errmsg') + if vim_errmsg and '' ~= vim_errmsg then error(vim_errmsg) end - nvim('command', 'setlocal scrollback=10') - nvim('command', 'startinsert') - nvim('input', '<Ignore>') -- Add input to separate two RPC requests + api.nvim_command('setlocal scrollback=10') + api.nvim_command('startinsert') + api.nvim_input('<Ignore>') -- Add input to separate two RPC requests -- tty-test puts the terminal into raw mode and echoes input. Tests work by -- feeding termcodes to control the display and asserting by screen:expect. - if command == default_command and opts == nil then + if command == default_command and screen_opts == nil then -- Wait for "tty ready" to be printed before each test or the terminal may -- still be in canonical mode (will echo characters for example). local empty_line = (' '):rep(cols) local expected = { - 'tty ready'..(' '):rep(cols - 9), - '{1: }' ..(' '):rep(cols - 1), + 'tty ready' .. (' '):rep(cols - 9), + '{1: }' .. (' '):rep(cols - 1), empty_line, empty_line, empty_line, @@ -112,16 +145,28 @@ local function screen_setup(extra_rows, command, cols, opts) end table.insert(expected, '{3:-- TERMINAL --}' .. ((' '):rep(cols - 14))) - screen:expect(table.concat(expected, '|\n')..'|') + screen:expect(table.concat(expected, '|\n') .. '|') else -- This eval also acts as a poke_eventloop(). - if 0 == nvim('eval', "exists('b:terminal_job_id')") then - error("terminal job failed to start") + if 0 == api.nvim_eval("exists('b:terminal_job_id')") then + error('terminal job failed to start') end end return screen end +local function setup_child_nvim(args, opts) + opts = opts or {} + local argv = { nvim_prog, unpack(args) } + + local env = opts.env or {} + if not env.VIMRUNTIME then + env.VIMRUNTIME = os.getenv('VIMRUNTIME') + end + + return screen_setup(0, argv, opts.cols, env) +end + return { feed_data = feed_data, feed_termcode = feed_termcode, @@ -141,5 +186,6 @@ return { clear_attrs = clear_attrs, enable_mouse = enable_mouse, disable_mouse = disable_mouse, - screen_setup = screen_setup + screen_setup = screen_setup, + setup_child_nvim = setup_child_nvim, } diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua index 2ac45771d4..ec057c6766 100644 --- a/test/functional/terminal/highlight_spec.lua +++ b/test/functional/terminal/highlight_spec.lua @@ -1,11 +1,12 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local thelpers = require('test.functional.terminal.helpers') -local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim +local feed, clear = helpers.feed, helpers.clear +local api = helpers.api local testprg, command = helpers.testprg, helpers.command local nvim_prog_abs = helpers.nvim_prog_abs local eq, eval = helpers.eq, helpers.eval -local funcs = helpers.funcs +local fn = helpers.fn local nvim_set = helpers.nvim_set local is_os = helpers.is_os local skip = helpers.skip @@ -17,30 +18,27 @@ describe(':terminal highlight', function() clear() screen = Screen.new(50, 7) screen:set_default_attr_ids({ - [1] = {foreground = 45}, - [2] = {background = 46}, - [3] = {foreground = 45, background = 46}, - [4] = {bold = true, italic = true, underline = true, strikethrough = true}, - [5] = {bold = true}, - [6] = {foreground = 12}, - [7] = {bold = true, reverse = true}, - [8] = {background = 11}, - [9] = {foreground = 130}, - [10] = {reverse = true}, - [11] = {background = 11}, - [12] = {bold = true, underdouble = true}, - [13] = {italic = true, undercurl = true}, + [1] = { foreground = 45 }, + [2] = { background = 46 }, + [3] = { foreground = 45, background = 46 }, + [4] = { bold = true, italic = true, underline = true, strikethrough = true }, + [5] = { bold = true }, + [6] = { foreground = 12 }, + [7] = { bold = true, reverse = true }, + [8] = { background = 11 }, + [9] = { foreground = 130 }, + [10] = { reverse = true }, + [11] = { background = 11 }, + [12] = { bold = true, underdouble = true }, + [13] = { italic = true, undercurl = true }, }) - screen:attach({rgb=false}) + screen:attach({ rgb = false }) command(("enew | call termopen(['%s'])"):format(testprg('tty-test'))) feed('i') screen:expect([[ tty ready | {10: } | - | - | - | - | + |*4 {5:-- TERMINAL --} | ]]) end) @@ -64,10 +62,7 @@ describe(':terminal highlight', function() screen:expect(sub([[ tty ready | {NUM:text}text{10: } | - | - | - | - | + |*4 {5:-- TERMINAL --} | ]])) end @@ -79,7 +74,7 @@ describe(':terminal highlight', function() pass_attrs() local lines = {} for i = 1, 8 do - table.insert(lines, 'line'..tostring(i)) + table.insert(lines, 'line' .. tostring(i)) end table.insert(lines, '') thelpers.feed_data(lines) @@ -106,8 +101,12 @@ describe(':terminal highlight', function() end) end - descr('foreground', 1, function() thelpers.set_fg(45) end) - descr('background', 2, function() thelpers.set_bg(46) end) + descr('foreground', 1, function() + thelpers.set_fg(45) + end) + descr('background', 2, function() + thelpers.set_bg(46) + end) descr('foreground and background', 3, function() thelpers.set_fg(45) thelpers.set_bg(46) @@ -133,20 +132,41 @@ it(':terminal highlight has lower precedence than editor #9964', function() local screen = Screen.new(30, 4) screen:set_default_attr_ids({ -- "Normal" highlight emitted by the child nvim process. - N_child = {foreground = tonumber('0x4040ff'), background = tonumber('0xffff40'), fg_indexed=true, bg_indexed=true}, + N_child = { + foreground = tonumber('0x4040ff'), + background = tonumber('0xffff40'), + fg_indexed = true, + bg_indexed = true, + }, -- "Search" highlight in the parent nvim process. - S = {background = Screen.colors.Green, italic = true, foreground = Screen.colors.Red}, + S = { background = Screen.colors.Green, italic = true, foreground = Screen.colors.Red }, -- "Question" highlight in the parent nvim process. -- note: bg is indexed as it comes from the (cterm) child, while fg isn't as it comes from (rgb) parent - Q = {background = tonumber('0xffff40'), bold = true, foreground = Screen.colors.SeaGreen4, bg_indexed=true}, + Q = { + background = tonumber('0xffff40'), + bold = true, + foreground = Screen.colors.SeaGreen4, + bg_indexed = true, + }, }) - screen:attach({rgb=true}) + screen:attach({ rgb = true }) -- Child nvim process in :terminal (with cterm colors). - funcs.termopen({ - nvim_prog_abs(), '-n', '-u', 'NORC', '-i', 'NONE', '--cmd', nvim_set, + fn.termopen({ + nvim_prog_abs(), + '-n', + '-u', + 'NORC', + '-i', + 'NONE', + '--cmd', + nvim_set .. ' notermguicolors', '+hi Normal ctermfg=Blue ctermbg=Yellow', '+norm! ichild nvim', '+norm! oline 2', + }, { + env = { + VIMRUNTIME = os.getenv('VIMRUNTIME'), + }, }) screen:expect([[ {N_child:^child nvim }| @@ -179,10 +199,10 @@ describe(':terminal highlight forwarding', function() screen = Screen.new(50, 7) screen:set_rgb_cterm(true) screen:set_default_attr_ids({ - [1] = {{reverse = true}, {reverse = true}}, - [2] = {{bold = true}, {bold = true}}, - [3] = {{fg_indexed = true, foreground = tonumber('0xe0e000')}, {foreground = 3}}, - [4] = {{foreground = tonumber('0xff8000')}, {}}, + [1] = { { reverse = true }, { reverse = true } }, + [2] = { { bold = true }, { bold = true } }, + [3] = { { fg_indexed = true, foreground = tonumber('0xe0e000') }, { foreground = 3 } }, + [4] = { { foreground = tonumber('0xff8000') }, {} }, }) screen:attach() command(("enew | call termopen(['%s'])"):format(testprg('tty-test'))) @@ -190,10 +210,7 @@ describe(':terminal highlight forwarding', function() screen:expect([[ tty ready | {1: } | - | - | - | - | + |*4 {2:-- TERMINAL --} | ]]) end) @@ -206,19 +223,17 @@ describe(':terminal highlight forwarding', function() thelpers.feed_data('color') thelpers.clear_attrs() thelpers.feed_data('text') - screen:expect{grid=[[ + screen:expect { + grid = [[ tty ready | {3:text}{4:color}text{1: } | - | - | - | - | + |*4 {2:-- TERMINAL --} | - ]]} + ]], + } end) end) - describe(':terminal highlight with custom palette', function() local screen @@ -226,26 +241,23 @@ describe(':terminal highlight with custom palette', function() clear() screen = Screen.new(50, 7) screen:set_default_attr_ids({ - [1] = {foreground = tonumber('0x123456')}, -- no fg_indexed when overridden - [2] = {foreground = 12}, - [3] = {bold = true, reverse = true}, - [5] = {background = 11}, - [6] = {foreground = 130}, - [7] = {reverse = true}, - [8] = {background = 11}, - [9] = {bold = true}, + [1] = { foreground = tonumber('0x123456') }, -- no fg_indexed when overridden + [2] = { foreground = 12 }, + [3] = { bold = true, reverse = true }, + [5] = { background = 11 }, + [6] = { foreground = 130 }, + [7] = { reverse = true }, + [8] = { background = 11 }, + [9] = { bold = true }, }) - screen:attach({rgb=true}) - nvim('set_var', 'terminal_color_3', '#123456') + screen:attach({ rgb = true }) + api.nvim_set_var('terminal_color_3', '#123456') command(("enew | call termopen(['%s'])"):format(testprg('tty-test'))) feed('i') screen:expect([[ tty ready | {7: } | - | - | - | - | + |*4 {9:-- TERMINAL --} | ]]) end) @@ -259,10 +271,7 @@ describe(':terminal highlight with custom palette', function() screen:expect([[ tty ready | {1:text}text{7: } | - | - | - | - | + |*4 {9:-- TERMINAL --} | ]]) end) @@ -275,35 +284,37 @@ describe('synIDattr()', function() screen = Screen.new(50, 7) command('highlight Normal ctermfg=252 guifg=#ff0000 guibg=Black') -- Salmon #fa8072 Maroon #800000 - command('highlight Keyword ctermfg=79 guifg=Salmon guisp=Maroon cterm=strikethrough gui=strikethrough') + command( + 'highlight Keyword ctermfg=79 guifg=Salmon guisp=Maroon cterm=strikethrough gui=strikethrough' + ) end) it('returns cterm-color if RGB-capable UI is _not_ attached', function() eq('252', eval('synIDattr(hlID("Normal"), "fg")')) eq('252', eval('synIDattr(hlID("Normal"), "fg#")')) - eq('', eval('synIDattr(hlID("Normal"), "bg")')) - eq('', eval('synIDattr(hlID("Normal"), "bg#")')) - eq('79', eval('synIDattr(hlID("Keyword"), "fg")')) - eq('79', eval('synIDattr(hlID("Keyword"), "fg#")')) - eq('', eval('synIDattr(hlID("Keyword"), "sp")')) - eq('', eval('synIDattr(hlID("Keyword"), "sp#")')) + eq('', eval('synIDattr(hlID("Normal"), "bg")')) + eq('', eval('synIDattr(hlID("Normal"), "bg#")')) + eq('79', eval('synIDattr(hlID("Keyword"), "fg")')) + eq('79', eval('synIDattr(hlID("Keyword"), "fg#")')) + eq('', eval('synIDattr(hlID("Keyword"), "sp")')) + eq('', eval('synIDattr(hlID("Keyword"), "sp#")')) end) it('returns gui-color if "gui" arg is passed', function() - eq('Black', eval('synIDattr(hlID("Normal"), "bg", "gui")')) + eq('Black', eval('synIDattr(hlID("Normal"), "bg", "gui")')) eq('Maroon', eval('synIDattr(hlID("Keyword"), "sp", "gui")')) end) it('returns gui-color if RGB-capable UI is attached', function() - screen:attach({rgb=true}) + screen:attach({ rgb = true }) eq('#ff0000', eval('synIDattr(hlID("Normal"), "fg")')) - eq('Black', eval('synIDattr(hlID("Normal"), "bg")')) - eq('Salmon', eval('synIDattr(hlID("Keyword"), "fg")')) - eq('Maroon', eval('synIDattr(hlID("Keyword"), "sp")')) + eq('Black', eval('synIDattr(hlID("Normal"), "bg")')) + eq('Salmon', eval('synIDattr(hlID("Keyword"), "fg")')) + eq('Maroon', eval('synIDattr(hlID("Keyword"), "sp")')) end) it('returns #RRGGBB value for fg#/bg#/sp#', function() - screen:attach({rgb=true}) + screen:attach({ rgb = true }) eq('#ff0000', eval('synIDattr(hlID("Normal"), "fg#")')) eq('#000000', eval('synIDattr(hlID("Normal"), "bg#")')) eq('#fa8072', eval('synIDattr(hlID("Keyword"), "fg#")')) @@ -311,19 +322,24 @@ describe('synIDattr()', function() end) it('returns color number if non-GUI', function() - screen:attach({rgb=false}) + screen:attach({ rgb = false }) eq('252', eval('synIDattr(hlID("Normal"), "fg")')) eq('79', eval('synIDattr(hlID("Keyword"), "fg")')) end) it('returns "1" if group has given highlight attribute', function() local hl_attrs = { - 'underline', 'undercurl', 'underdouble', 'underdotted', 'underdashed', 'strikethrough' + 'underline', + 'undercurl', + 'underdouble', + 'underdotted', + 'underdashed', + 'strikethrough', } - for _,hl_attr in ipairs(hl_attrs) do + for _, hl_attr in ipairs(hl_attrs) do local context = 'using ' .. hl_attr .. ' attr' command('highlight Keyword cterm=' .. hl_attr .. ' gui=' .. hl_attr) - eq('', eval('synIDattr(hlID("Normal"), "'.. hl_attr .. '")'), context) + eq('', eval('synIDattr(hlID("Normal"), "' .. hl_attr .. '")'), context) eq('1', eval('synIDattr(hlID("Keyword"), "' .. hl_attr .. '")'), context) eq('1', eval('synIDattr(hlID("Keyword"), "' .. hl_attr .. '", "gui")'), context) end @@ -340,14 +356,10 @@ describe('fg/bg special colors', function() end) it('resolve to "Normal" values', function() - eq(eval('synIDattr(hlID("Normal"), "bg")'), - eval('synIDattr(hlID("Visual"), "fg")')) - eq(eval('synIDattr(hlID("Normal"), "bg#")'), - eval('synIDattr(hlID("Visual"), "fg#")')) - eq(eval('synIDattr(hlID("Normal"), "fg")'), - eval('synIDattr(hlID("Visual"), "bg")')) - eq(eval('synIDattr(hlID("Normal"), "fg#")'), - eval('synIDattr(hlID("Visual"), "bg#")')) + eq(eval('synIDattr(hlID("Normal"), "bg")'), eval('synIDattr(hlID("Visual"), "fg")')) + eq(eval('synIDattr(hlID("Normal"), "bg#")'), eval('synIDattr(hlID("Visual"), "fg#")')) + eq(eval('synIDattr(hlID("Normal"), "fg")'), eval('synIDattr(hlID("Visual"), "bg")')) + eq(eval('synIDattr(hlID("Normal"), "fg#")'), eval('synIDattr(hlID("Visual"), "bg#")')) eq('bg', eval('synIDattr(hlID("Visual"), "fg", "gui")')) eq('bg', eval('synIDattr(hlID("Visual"), "fg#", "gui")')) eq('fg', eval('synIDattr(hlID("Visual"), "bg", "gui")')) @@ -357,23 +369,20 @@ describe('fg/bg special colors', function() end) it('resolve to "Normal" values in RGB-capable UI', function() - screen:attach({rgb=true}) + screen:attach({ rgb = true }) eq('bg', eval('synIDattr(hlID("Visual"), "fg")')) - eq(eval('synIDattr(hlID("Normal"), "bg#")'), - eval('synIDattr(hlID("Visual"), "fg#")')) + eq(eval('synIDattr(hlID("Normal"), "bg#")'), eval('synIDattr(hlID("Visual"), "fg#")')) eq('fg', eval('synIDattr(hlID("Visual"), "bg")')) - eq(eval('synIDattr(hlID("Normal"), "fg#")'), - eval('synIDattr(hlID("Visual"), "bg#")')) + eq(eval('synIDattr(hlID("Normal"), "fg#")'), eval('synIDattr(hlID("Visual"), "bg#")')) eq('bg', eval('synIDattr(hlID("Visual"), "sp")')) - eq(eval('synIDattr(hlID("Normal"), "bg#")'), - eval('synIDattr(hlID("Visual"), "sp#")')) + eq(eval('synIDattr(hlID("Normal"), "bg#")'), eval('synIDattr(hlID("Visual"), "sp#")')) end) it('resolve after the "Normal" group is modified', function() - screen:attach({rgb=true}) + screen:attach({ rgb = true }) local new_guibg = '#282c34' local new_guifg = '#abb2bf' - command('highlight Normal guifg='..new_guifg..' guibg='..new_guibg) + command('highlight Normal guifg=' .. new_guifg .. ' guibg=' .. new_guibg) eq(new_guibg, eval('synIDattr(hlID("Visual"), "fg#")')) eq(new_guifg, eval('synIDattr(hlID("Visual"), "bg#")')) eq(new_guibg, eval('synIDattr(hlID("Visual"), "sp#")')) diff --git a/test/functional/terminal/mouse_spec.lua b/test/functional/terminal/mouse_spec.lua index 3291a38e03..0395d5ee16 100644 --- a/test/functional/terminal/mouse_spec.lua +++ b/test/functional/terminal/mouse_spec.lua @@ -1,7 +1,7 @@ local helpers = require('test.functional.helpers')(after_each) local thelpers = require('test.functional.terminal.helpers') local clear, eq, eval = helpers.clear, helpers.eq, helpers.eval -local feed, nvim, command = helpers.feed, helpers.nvim, helpers.command +local feed, api, command = helpers.feed, helpers.api, helpers.command local feed_data = thelpers.feed_data local is_os = helpers.is_os local skip = helpers.skip @@ -11,14 +11,14 @@ describe(':terminal mouse', function() before_each(function() clear() - nvim('set_option_value', 'statusline', '==========', {}) + api.nvim_set_option_value('statusline', '==========', {}) command('highlight StatusLine cterm=NONE') command('highlight StatusLineNC cterm=NONE') command('highlight VertSplit cterm=NONE') screen = thelpers.screen_setup() local lines = {} for i = 1, 30 do - table.insert(lines, 'line'..tostring(i)) + table.insert(lines, 'line' .. tostring(i)) end table.insert(lines, '') feed_data(lines) @@ -243,6 +243,134 @@ describe(':terminal mouse', function() {3:-- TERMINAL --} | ]]) end) + + it('will lose focus if statusline is clicked', function() + command('set laststatus=2') + screen:expect([[ + line29 | + line30 | + mouse enabled | + rows: 5, cols: 50 | + {1: } | + ========== | + {3:-- TERMINAL --} | + ]]) + feed('<LeftMouse><0,5>') + screen:expect([[ + line29 | + line30 | + mouse enabled | + rows: 5, cols: 50 | + {2:^ } | + ========== | + | + ]]) + feed('<LeftDrag><0,4>') + screen:expect([[ + mouse enabled | + rows: 5, cols: 50 | + rows: 4, cols: 50 | + {2:^ } | + ========== | + |*2 + ]]) + end) + + it('will lose focus if right separator is clicked', function() + command('rightbelow vnew | wincmd p | startinsert') + screen:expect([[ + line29 │ | + line30 │{4:~ }| + mouse enabled │{4:~ }| + rows: 5, cols: 24 │{4:~ }| + {1: } │{4:~ }| + ========== ========== | + {3:-- TERMINAL --} | + ]]) + feed('<LeftMouse><24,0>') + screen:expect([[ + line29 │ | + line30 │{4:~ }| + mouse enabled │{4:~ }| + rows: 5, cols: 24 │{4:~ }| + {2:^ } │{4:~ }| + ========== ========== | + | + ]]) + feed('<LeftDrag><23,0>') + screen:expect([[ + line30 │ | + mouse enabled │{4:~ }| + rows: 5, cols: 24 │{4:~ }| + rows: 5, cols: 23 │{4:~ }| + {2:^ } │{4:~ }| + ========== ========== | + | + ]]) + end) + + it('will lose focus if winbar/tabline is clicked', function() + command('setlocal winbar=WINBAR') + screen:expect([[ + {3:WINBAR }| + line29 | + line30 | + mouse enabled | + rows: 5, cols: 50 | + {1: } | + {3:-- TERMINAL --} | + ]]) + feed('<LeftMouse><0,0>') + screen:expect([[ + {3:WINBAR }| + line29 | + line30 | + mouse enabled | + rows: 5, cols: 50 | + {2:^ } | + | + ]]) + command('set showtabline=2 tabline=TABLINE | startinsert') + screen:expect([[ + {1:TABLINE }| + {3:WINBAR }| + mouse enabled | + rows: 5, cols: 50 | + rows: 4, cols: 50 | + {1: } | + {3:-- TERMINAL --} | + ]]) + feed('<LeftMouse><0,0>') + screen:expect([[ + {1:TABLINE }| + {3:WINBAR }| + mouse enabled | + rows: 5, cols: 50 | + rows: 4, cols: 50 | + {2:^ } | + | + ]]) + command('setlocal winbar= | startinsert') + screen:expect([[ + {1:TABLINE }| + mouse enabled | + rows: 5, cols: 50 | + rows: 4, cols: 50 | + rows: 5, cols: 50 | + {1: } | + {3:-- TERMINAL --} | + ]]) + feed('<LeftMouse><0,0>') + screen:expect([[ + {1:TABLINE }| + mouse enabled | + rows: 5, cols: 50 | + rows: 4, cols: 50 | + rows: 5, cols: 50 | + {2:^ } | + | + ]]) + end) end) describe('with a split window and other buffer', function() @@ -386,7 +514,7 @@ describe(':terminal mouse', function() end) it('handles terminal size when switching buffers', function() - nvim('set_option_value', 'hidden', true, {}) + api.nvim_set_option_value('hidden', true, {}) feed('<c-\\><c-n><c-w><c-w>') screen:expect([[ {7: 27 }line │line30 | diff --git a/test/functional/terminal/scrollback_spec.lua b/test/functional/terminal/scrollback_spec.lua index 1e278e4cff..858e23984d 100644 --- a/test/functional/terminal/scrollback_spec.lua +++ b/test/functional/terminal/scrollback_spec.lua @@ -1,14 +1,13 @@ local Screen = require('test.functional.ui.screen') local helpers = require('test.functional.helpers')(after_each) local thelpers = require('test.functional.terminal.helpers') -local clear, eq, curbuf = helpers.clear, helpers.eq, helpers.curbuf +local clear, eq = helpers.clear, helpers.eq local feed, testprg = helpers.feed, helpers.testprg local eval = helpers.eval local command = helpers.command local poke_eventloop = helpers.poke_eventloop local retry = helpers.retry -local meths = helpers.meths -local nvim = helpers.nvim +local api = helpers.api local feed_data = thelpers.feed_data local pcall_err = helpers.pcall_err local exec_lua = helpers.exec_lua @@ -28,7 +27,7 @@ describe(':terminal scrollback', function() before_each(function() local lines = {} for i = 1, 30 do - table.insert(lines, 'line'..tostring(i)) + table.insert(lines, 'line' .. tostring(i)) end table.insert(lines, '') feed_data(lines) @@ -59,7 +58,7 @@ describe(':terminal scrollback', function() describe('with cursor at last row', function() before_each(function() - feed_data({'line1', 'line2', 'line3', 'line4', ''}) + feed_data({ 'line1', 'line2', 'line3', 'line4', '' }) screen:expect([[ tty ready | line1 | @@ -72,7 +71,9 @@ describe(':terminal scrollback', function() end) describe('and 1 line is printed', function() - before_each(function() feed_data({'line5', ''}) end) + before_each(function() + feed_data({ 'line5', '' }) + end) it('will hide the top line', function() screen:expect([[ @@ -84,11 +85,13 @@ describe(':terminal scrollback', function() {1: } | {3:-- TERMINAL --} | ]]) - eq(7, curbuf('line_count')) + eq(7, api.nvim_buf_line_count(0)) end) describe('and then 3 more lines are printed', function() - before_each(function() feed_data({'line6', 'line7', 'line8'}) end) + before_each(function() + feed_data({ 'line6', 'line7', 'line8' }) + end) it('will hide the top 4 lines', function() screen:expect([[ @@ -137,7 +140,6 @@ describe(':terminal scrollback', function() end) end) - describe('and height decreased by 1', function() local function will_hide_top_line() feed([[<C-\><C-N>]]) @@ -167,7 +169,7 @@ describe(':terminal scrollback', function() {2:^ } | | ]]) - eq(8, curbuf('line_count')) + eq(8, api.nvim_buf_line_count(0)) feed([[3k]]) screen:expect([[ ^line4 | @@ -184,7 +186,9 @@ describe(':terminal scrollback', function() -- XXX: Can't test this reliably on Windows unless the cursor is _moved_ -- by the resize. http://docs.libuv.org/en/v1.x/signal.html -- See also: https://github.com/rprichard/winpty/issues/110 - if skip(is_os('win')) then return end + if skip(is_os('win')) then + return + end describe('and the height is decreased by 2', function() before_each(function() @@ -199,7 +203,7 @@ describe(':terminal scrollback', function() | {3:-- TERMINAL --} | ]]) - eq(4, curbuf('line_count')) + eq(4, api.nvim_buf_line_count(0)) end it('will delete the last two empty lines', will_delete_last_two_lines) @@ -217,7 +221,7 @@ describe(':terminal scrollback', function() {1: } | {3:-- TERMINAL --} | ]]) - eq(4, curbuf('line_count')) + eq(4, api.nvim_buf_line_count(0)) feed('<c-\\><c-n>gg') screen:expect([[ ^tty ready | @@ -239,7 +243,7 @@ describe(':terminal scrollback', function() describe('with 4 lines hidden in the scrollback', function() before_each(function() - feed_data({'line1', 'line2', 'line3', 'line4', ''}) + feed_data({ 'line1', 'line2', 'line3', 'line4', '' }) screen:expect([[ tty ready | line1 | @@ -256,14 +260,16 @@ describe(':terminal scrollback', function() {1: } | {3:-- TERMINAL --} | ]]) - eq(7, curbuf('line_count')) + eq(7, api.nvim_buf_line_count(0)) end) describe('and the height is increased by 1', function() -- XXX: Can't test this reliably on Windows unless the cursor is _moved_ -- by the resize. http://docs.libuv.org/en/v1.x/signal.html -- See also: https://github.com/rprichard/winpty/issues/110 - if skip(is_os('win')) then return end + if skip(is_os('win')) then + return + end local function pop_then_push() screen:try_resize(screen._width, screen._height + 1) screen:expect([[ @@ -280,7 +286,7 @@ describe(':terminal scrollback', function() describe('and then by 3', function() before_each(function() pop_then_push() - eq(8, curbuf('line_count')) + eq(8, api.nvim_buf_line_count(0)) screen:try_resize(screen._width, screen._height + 3) end) @@ -295,7 +301,7 @@ describe(':terminal scrollback', function() {1: } | {3:-- TERMINAL --} | ]]) - eq(9, curbuf('line_count')) + eq(9, api.nvim_buf_line_count(0)) feed('<c-\\><c-n>gg') screen:expect([[ ^tty ready | @@ -335,7 +341,7 @@ describe(':terminal scrollback', function() ]]) -- since there's an empty line after the cursor, the buffer line -- count equals the terminal screen height - eq(11, curbuf('line_count')) + eq(11, api.nvim_buf_line_count(0)) end) end) end) @@ -347,7 +353,7 @@ describe(':terminal prints more lines than the screen height and exits', functio it('will push extra lines to scrollback', function() clear() local screen = Screen.new(30, 7) - screen:attach({rgb=false}) + screen:attach({ rgb = false }) command(("call termopen(['%s', '10']) | startinsert"):format(testprg('tty-test'))) screen:expect([[ line6 | @@ -362,11 +368,7 @@ describe(':terminal prints more lines than the screen height and exits', functio -- closes the buffer correctly after pressing a key screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*5 | ]]) end) @@ -378,62 +380,71 @@ describe("'scrollback' option", function() end) local function set_fake_shell() - nvim('set_option_value', 'shell', string.format('"%s" INTERACT', testprg('shell-test')), {}) + api.nvim_set_option_value('shell', string.format('"%s" INTERACT', testprg('shell-test')), {}) end local function expect_lines(expected, epsilon) local ep = epsilon and epsilon or 0 local actual = eval("line('$')") if expected > actual + ep and expected < actual - ep then - error('expected (+/- '..ep..'): '..expected..', actual: '..tostring(actual)) + error('expected (+/- ' .. ep .. '): ' .. expected .. ', actual: ' .. tostring(actual)) end end it('set to 0 behaves as 1', function() local screen if is_os('win') then - screen = thelpers.screen_setup(nil, "['cmd.exe']", 30) + screen = thelpers.screen_setup(nil, { 'cmd.exe' }, 30) else - screen = thelpers.screen_setup(nil, "['sh']", 30) + screen = thelpers.screen_setup(nil, { 'sh' }, 30) end - meths.set_option_value('scrollback', 0, {}) + api.nvim_set_option_value('scrollback', 0, {}) feed_data(('%s REP 31 line%s'):format(testprg('shell-test'), is_os('win') and '\r' or '\n')) - screen:expect{any='30: line '} - retry(nil, nil, function() expect_lines(7) end) + screen:expect { any = '30: line ' } + retry(nil, nil, function() + expect_lines(7) + end) end) it('deletes lines (only) if necessary', function() local screen if is_os('win') then command([[let $PROMPT='$$']]) - screen = thelpers.screen_setup(nil, "['cmd.exe']", 30) + screen = thelpers.screen_setup(nil, { 'cmd.exe' }, 30) else command('let $PS1 = "$"') - screen = thelpers.screen_setup(nil, "['sh']", 30) + screen = thelpers.screen_setup(nil, { 'sh' }, 30) end - meths.set_option_value('scrollback', 200, {}) + api.nvim_set_option_value('scrollback', 200, {}) -- Wait for prompt. - screen:expect{any='%$'} + screen:expect { any = '%$' } feed_data(('%s REP 31 line%s'):format(testprg('shell-test'), is_os('win') and '\r' or '\n')) - screen:expect{any='30: line '} + screen:expect { any = '30: line ' } - retry(nil, nil, function() expect_lines(33, 2) end) - meths.set_option_value('scrollback', 10, {}) + retry(nil, nil, function() + expect_lines(33, 2) + end) + api.nvim_set_option_value('scrollback', 10, {}) poke_eventloop() - retry(nil, nil, function() expect_lines(16) end) - meths.set_option_value('scrollback', 10000, {}) - retry(nil, nil, function() expect_lines(16) end) + retry(nil, nil, function() + expect_lines(16) + end) + api.nvim_set_option_value('scrollback', 10000, {}) + retry(nil, nil, function() + expect_lines(16) + end) -- Terminal job data is received asynchronously, may happen before the -- 'scrollback' option is synchronized with the internal sb_buffer. command('sleep 100m') feed_data(('%s REP 41 line%s'):format(testprg('shell-test'), is_os('win') and '\r' or '\n')) if is_os('win') then - screen:expect{grid=[[ + screen:expect { + grid = [[ 37: line | 38: line | 39: line | @@ -441,9 +452,11 @@ describe("'scrollback' option", function() | ${1: } | {3:-- TERMINAL --} | - ]]} + ]], + } else - screen:expect{grid=[[ + screen:expect { + grid = [[ 36: line | 37: line | 38: line | @@ -451,7 +464,8 @@ describe("'scrollback' option", function() 40: line | {MATCH:.*}| {3:-- TERMINAL --} | - ]]} + ]], + } end expect_lines(58) @@ -465,11 +479,11 @@ describe("'scrollback' option", function() local screen = thelpers.screen_setup(nil, nil, 30) local lines = {} for i = 1, 30 do - table.insert(lines, 'line'..tostring(i)) + table.insert(lines, 'line' .. tostring(i)) end table.insert(lines, '') feed_data(lines) - screen:expect([[ + screen:expect([[ line26 | line27 | line28 | @@ -478,32 +492,33 @@ describe("'scrollback' option", function() {1: } | {3:-- TERMINAL --} | ]]) - local term_height = 6 -- Actual terminal screen height, not the scrollback + local term_height = 6 -- Actual terminal screen height, not the scrollback -- Initial - local scrollback = meths.get_option_value('scrollback', {}) + local scrollback = api.nvim_get_option_value('scrollback', {}) eq(scrollback + term_height, eval('line("$")')) -- Reduction scrollback = scrollback - 2 - meths.set_option_value('scrollback', scrollback, {}) + api.nvim_set_option_value('scrollback', scrollback, {}) eq(scrollback + term_height, eval('line("$")')) end) it('defaults to 10000 in :terminal buffers', function() set_fake_shell() command('terminal') - eq(10000, meths.get_option_value('scrollback', {})) + eq(10000, api.nvim_get_option_value('scrollback', {})) end) it('error if set to invalid value', function() - eq('Vim(set):E474: Invalid argument: scrollback=-2', - pcall_err(command, 'set scrollback=-2')) - eq('Vim(set):E474: Invalid argument: scrollback=100001', - pcall_err(command, 'set scrollback=100001')) + eq('Vim(set):E474: Invalid argument: scrollback=-2', pcall_err(command, 'set scrollback=-2')) + eq( + 'Vim(set):E474: Invalid argument: scrollback=100001', + pcall_err(command, 'set scrollback=100001') + ) end) it('defaults to -1 on normal buffers', function() command('new') - eq(-1, meths.get_option_value('scrollback', {})) + eq(-1, api.nvim_get_option_value('scrollback', {})) end) it(':setlocal in a :terminal buffer', function() @@ -512,50 +527,49 @@ describe("'scrollback' option", function() -- _Global_ scrollback=-1 defaults :terminal to 10_000. command('setglobal scrollback=-1') command('terminal') - eq(10000, meths.get_option_value('scrollback', {})) + eq(10000, api.nvim_get_option_value('scrollback', {})) -- _Local_ scrollback=-1 in :terminal forces the _maximum_. command('setlocal scrollback=-1') - retry(nil, nil, function() -- Fixup happens on refresh, not immediately. - eq(100000, meths.get_option_value('scrollback', {})) + retry(nil, nil, function() -- Fixup happens on refresh, not immediately. + eq(100000, api.nvim_get_option_value('scrollback', {})) end) -- _Local_ scrollback=-1 during TermOpen forces the maximum. #9605 command('setglobal scrollback=-1') command('autocmd TermOpen * setlocal scrollback=-1') command('terminal') - eq(100000, meths.get_option_value('scrollback', {})) + eq(100000, api.nvim_get_option_value('scrollback', {})) end) it(':setlocal in a normal buffer', function() command('new') -- :setlocal to -1. command('setlocal scrollback=-1') - eq(-1, meths.get_option_value('scrollback', {})) + eq(-1, api.nvim_get_option_value('scrollback', {})) -- :setlocal to anything except -1. Currently, this just has no effect. command('setlocal scrollback=42') - eq(42, meths.get_option_value('scrollback', {})) + eq(42, api.nvim_get_option_value('scrollback', {})) end) it(':set updates local value and global default', function() set_fake_shell() - command('set scrollback=42') -- set global value - eq(42, meths.get_option_value('scrollback', {})) + command('set scrollback=42') -- set global value + eq(42, api.nvim_get_option_value('scrollback', {})) command('terminal') - eq(42, meths.get_option_value('scrollback', {})) -- inherits global default + eq(42, api.nvim_get_option_value('scrollback', {})) -- inherits global default command('setlocal scrollback=99') - eq(99, meths.get_option_value('scrollback', {})) - command('set scrollback<') -- reset to global default - eq(42, meths.get_option_value('scrollback', {})) - command('setglobal scrollback=734') -- new global default - eq(42, meths.get_option_value('scrollback', {})) -- local value did not change + eq(99, api.nvim_get_option_value('scrollback', {})) + command('set scrollback<') -- reset to global default + eq(42, api.nvim_get_option_value('scrollback', {})) + command('setglobal scrollback=734') -- new global default + eq(42, api.nvim_get_option_value('scrollback', {})) -- local value did not change command('terminal') - eq(734, meths.get_option_value('scrollback', {})) + eq(734, api.nvim_get_option_value('scrollback', {})) end) - end) -describe("pending scrollback line handling", function() +describe('pending scrollback line handling', function() local screen before_each(function() @@ -563,9 +577,9 @@ describe("pending scrollback line handling", function() screen = Screen.new(30, 7) screen:attach() screen:set_default_attr_ids { - [1] = {foreground = Screen.colors.Brown}, - [2] = {reverse = true}, - [3] = {bold = true}, + [1] = { foreground = Screen.colors.Brown }, + [2] = { reverse = true }, + [3] = { bold = true }, } end) @@ -580,41 +594,42 @@ describe("pending scrollback line handling", function() ]] screen:expect [[ {1: 1 }^a | - {1: 2 } a | - {1: 3 } a | - {1: 4 } a | - {1: 5 } a | - {1: 6 } a | + {1: 2 }a | + {1: 3 }a | + {1: 4 }a | + {1: 5 }a | + {1: 6 }a | | ]] feed('G') screen:expect [[ - {1: 7 } a | - {1: 8 } a | - {1: 9 } a | - {1: 10 } a | - {1: 11 } a | - {1: 12 } ^a | + {1: 7 }a | + {1: 8 }a | + {1: 9 }a | + {1: 10 }a | + {1: 11 }a | + {1: 12 }^a | | ]] assert_alive() end) - it("does not crash after nvim_buf_call #14891", function() - skip(is_os('win')) - exec_lua [[ + it('does not crash after nvim_buf_call #14891', function() + exec_lua( + [[ local bufnr = vim.api.nvim_create_buf(false, true) + local args = ... vim.api.nvim_buf_call(bufnr, function() - vim.fn.termopen({"echo", ("hi\n"):rep(11)}) + vim.fn.termopen(args) end) vim.api.nvim_win_set_buf(0, bufnr) - vim.cmd("startinsert") - ]] + vim.cmd('startinsert') + ]], + is_os('win') and { 'cmd.exe', '/c', 'for /L %I in (1,1,12) do @echo hi' } + or { 'printf', ('hi\n'):rep(12) } + ) screen:expect [[ - hi | - hi | - hi | - | + hi |*4 | [Process exited 0]{2: } | {3:-- TERMINAL --} | diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index b17eed00f9..94690524d3 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -20,16 +20,19 @@ local nvim_prog = helpers.nvim_prog local nvim_set = helpers.nvim_set local ok = helpers.ok local read_file = helpers.read_file -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local is_ci = helpers.is_ci local is_os = helpers.is_os local new_pipename = helpers.new_pipename local spawn_argv = helpers.spawn_argv local set_session = helpers.set_session local write_file = helpers.write_file +local eval = helpers.eval -if helpers.skip(is_os('win')) then return end +if helpers.skip(is_os('win')) then + return +end describe('TUI', function() local screen @@ -39,14 +42,21 @@ describe('TUI', function() before_each(function() clear() local child_server = new_pipename() - screen = thelpers.screen_setup(0, - string.format([=[["%s", "--listen", "%s", "-u", "NONE", "-i", "NONE", "--cmd", "%s laststatus=2 background=dark"]]=], - nvim_prog, child_server, nvim_set)) + screen = thelpers.setup_child_nvim({ + '--listen', + child_server, + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + nvim_set .. ' notermguicolors laststatus=2 background=dark', + '--cmd', + 'colorscheme vim', + }) screen:expect([[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| | {3:-- TERMINAL --} | @@ -75,7 +85,7 @@ describe('TUI', function() it('rapid resize #7572 #7628', function() helpers.skip(helpers.is_asan(), 'Test extra unstable with ASAN. See #23762') -- Need buffer rows to provoke the behavior. - feed_data(":edit test/functional/fixtures/bigfile.txt\n") + feed_data(':edit test/functional/fixtures/bigfile.txt\n') screen:expect([[ {1:0}000;<control>;Cc;0;BN;;;;;N;NULL;;;; | 0001;<control>;Cc;0;BN;;;;;N;START OF HEADING;;;; | @@ -102,21 +112,26 @@ describe('TUI', function() screen:try_resize(57, 17) command('call jobresize(b:terminal_job_id, 57, 17)') retry(nil, nil, function() - eq({true, 57}, {child_session:request('nvim_win_get_width', 0)}) + eq({ true, 57 }, { child_session:request('nvim_win_get_width', 0) }) end) end) it('accepts resize while pager is active', function() - child_session:request('nvim_exec2', [[ + child_session:request( + 'nvim_exec2', + [[ set more func! ManyErr() for i in range(20) echoerr "FAIL ".i endfor endfunc - ]], {}) + ]], + {} + ) feed_data(':call ManyErr()\r') - screen:expect{grid=[[ + screen:expect { + grid = [[ {8:Error detected while processing function ManyErr:} | {11:line 2:} | {8:FAIL 0} | @@ -124,24 +139,27 @@ describe('TUI', function() {8:FAIL 2} | {10:-- More --}{1: } | {3:-- TERMINAL --} | - ]]} + ]], + } - screen:try_resize(50,10) - screen:expect{grid=[[ + screen:try_resize(50, 10) + screen:expect { + grid = [[ :call ManyErr() | {8:Error detected while processing function ManyErr:} | {11:line 2:} | {8:FAIL 0} | {8:FAIL 1} | {8:FAIL 2} | - | - | + |*2 {10:-- More --}{1: } | {3:-- TERMINAL --} | - ]]} + ]], + } feed_data('j') - screen:expect{grid=[[ + screen:expect { + grid = [[ {8:Error detected while processing function ManyErr:} | {11:line 2:} | {8:FAIL 0} | @@ -152,10 +170,12 @@ describe('TUI', function() {8:FAIL 5} | {10:-- More --}{1: } | {3:-- TERMINAL --} | - ]]} + ]], + } - screen:try_resize(50,7) - screen:expect{grid=[[ + screen:try_resize(50, 7) + screen:expect { + grid = [[ {8:FAIL 1} | {8:FAIL 2} | {8:FAIL 3} | @@ -163,28 +183,34 @@ describe('TUI', function() {8:FAIL 5} | {10:-- More --}{1: } | {3:-- TERMINAL --} | - ]]} + ]], + } - screen:try_resize(50,5) - screen:expect{grid=[[ + screen:try_resize(50, 5) + screen:expect { + grid = [[ {8:FAIL 3} | {8:FAIL 4} | {8:FAIL 5} | {10:-- More --}{1: } | {3:-- TERMINAL --} | - ]]} + ]], + } feed_data('g') - screen:expect{grid=[[ + screen:expect { + grid = [[ :call ManyErr() | {8:Error detected while processing function ManyErr:} | {11:line 2:} | {10:-- More --}{1: } | {3:-- TERMINAL --} | - ]]} + ]], + } - screen:try_resize(50,10) - screen:expect{grid=[[ + screen:try_resize(50, 10) + screen:expect { + grid = [[ :call ManyErr() | {8:Error detected while processing function ManyErr:} | {11:line 2:} | @@ -195,21 +221,19 @@ describe('TUI', function() {8:FAIL 4} | {10:-- More --}{1: } | {3:-- TERMINAL --} | - ]]} + ]], + } feed_data('\003') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*6 {5:[No Name] }| | {3:-- TERMINAL --} | - ]]} + ]], + } end) it('accepts basic utf-8 input', function() @@ -238,8 +262,8 @@ describe('TUI', function() it('interprets leading <Esc> byte as ALT modifier in normal-mode', function() local keys = 'dfghjkl' for c in keys:gmatch('.') do - feed_data(':nnoremap <a-'..c..'> ialt-'..c..'<cr><esc>\r') - feed_data('\027'..c) + feed_data(':nnoremap <a-' .. c .. '> ialt-' .. c .. '<cr><esc>\r') + feed_data('\027' .. c) end screen:expect([[ alt-j | @@ -268,9 +292,7 @@ describe('TUI', function() feed_data('i\022\027j') screen:expect([[ <M-j>{1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] [+] }| {3:-- INSERT --} | {3:-- TERMINAL --} | @@ -278,17 +300,19 @@ describe('TUI', function() end) it('interprets <Esc>[27u as <Esc>', function() - child_session:request('nvim_exec2', [[ + child_session:request( + 'nvim_exec2', + [[ nnoremap <M-;> <Nop> nnoremap <Esc> AESC<Esc> nnoremap ; Asemicolon<Esc> - ]], {}) + ]], + {} + ) feed_data('\027[27u;') screen:expect([[ ESCsemicolo{1:n} | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] [+] }| | {3:-- TERMINAL --} | @@ -302,9 +326,7 @@ describe('TUI', function() feed_data('i\022\027\000') screen:expect([[ <M-C-Space>{1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] [+] }| {3:-- INSERT --} | {3:-- TERMINAL --} | @@ -316,25 +338,25 @@ describe('TUI', function() feed_data('\022\007') -- ctrl+g feed_data('\022\022') -- ctrl+v feed_data('\022\013') -- ctrl+m - local attrs = screen:get_default_attr_ids() - attrs[11] = {foreground = 81} screen:expect([[ - {11:^G^V^M}{1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {6:^G^V^M}{1: } | + {4:~ }|*3 {5:[No Name] [+] }| {3:-- INSERT --} | {3:-- TERMINAL --} | - ]], attrs) + ]]) end) local function test_mouse_wheel(esc) - child_session:request('nvim_exec2', [[ + child_session:request( + 'nvim_exec2', + [[ set number nostartofline nowrap mousescroll=hor:1,ver:1 call setline(1, repeat([join(range(10), '----')], 10)) vsplit - ]], {}) + ]], + {} + ) screen:expect([[ {11: 1 }{1:0}----1----2----3----4│{11: 1 }0----1----2----3----| {11: 2 }0----1----2----3----4│{11: 2 }0----1----2----3----| @@ -348,7 +370,7 @@ describe('TUI', function() if esc then feed_data('\027[<65;8;1M') else - meths.input_mouse('wheel', 'down', '', 0, 0, 7) + api.nvim_input_mouse('wheel', 'down', '', 0, 0, 7) end screen:expect([[ {11: 2 }{1:0}----1----2----3----4│{11: 1 }0----1----2----3----| @@ -363,7 +385,7 @@ describe('TUI', function() if esc then feed_data('\027[<65;48;1M') else - meths.input_mouse('wheel', 'down', '', 0, 0, 47) + api.nvim_input_mouse('wheel', 'down', '', 0, 0, 47) end screen:expect([[ {11: 2 }{1:0}----1----2----3----4│{11: 2 }0----1----2----3----| @@ -378,7 +400,7 @@ describe('TUI', function() if esc then feed_data('\027[<67;8;1M') else - meths.input_mouse('wheel', 'right', '', 0, 0, 7) + api.nvim_input_mouse('wheel', 'right', '', 0, 0, 7) end screen:expect([[ {11: 2 }{1:-}---1----2----3----4-│{11: 2 }0----1----2----3----| @@ -393,7 +415,7 @@ describe('TUI', function() if esc then feed_data('\027[<67;48;1M') else - meths.input_mouse('wheel', 'right', '', 0, 0, 47) + api.nvim_input_mouse('wheel', 'right', '', 0, 0, 47) end screen:expect([[ {11: 2 }{1:-}---1----2----3----4-│{11: 2 }----1----2----3----4| @@ -408,7 +430,7 @@ describe('TUI', function() if esc then feed_data('\027[<69;8;1M') else - meths.input_mouse('wheel', 'down', 'S', 0, 0, 7) + api.nvim_input_mouse('wheel', 'down', 'S', 0, 0, 7) end screen:expect([[ {11: 5 }{1:-}---1----2----3----4-│{11: 2 }----1----2----3----4| @@ -423,7 +445,7 @@ describe('TUI', function() if esc then feed_data('\027[<69;48;1M') else - meths.input_mouse('wheel', 'down', 'S', 0, 0, 47) + api.nvim_input_mouse('wheel', 'down', 'S', 0, 0, 47) end screen:expect([[ {11: 5 }{1:-}---1----2----3----4-│{11: 5 }----1----2----3----4| @@ -438,7 +460,7 @@ describe('TUI', function() if esc then feed_data('\027[<71;8;1M') else - meths.input_mouse('wheel', 'right', 'S', 0, 0, 7) + api.nvim_input_mouse('wheel', 'right', 'S', 0, 0, 7) end screen:expect([[ {11: 5 }{1:-}---6----7----8----9 │{11: 5 }----1----2----3----4| @@ -453,7 +475,7 @@ describe('TUI', function() if esc then feed_data('\027[<71;48;1M') else - meths.input_mouse('wheel', 'right', 'S', 0, 0, 47) + api.nvim_input_mouse('wheel', 'right', 'S', 0, 0, 47) end screen:expect([[ {11: 5 }{1:-}---6----7----8----9 │{11: 5 }5----6----7----8----| @@ -468,7 +490,7 @@ describe('TUI', function() if esc then feed_data('\027[<64;8;1M') else - meths.input_mouse('wheel', 'up', '', 0, 0, 7) + api.nvim_input_mouse('wheel', 'up', '', 0, 0, 7) end screen:expect([[ {11: 4 }----6----7----8----9 │{11: 5 }5----6----7----8----| @@ -483,7 +505,7 @@ describe('TUI', function() if esc then feed_data('\027[<64;48;1M') else - meths.input_mouse('wheel', 'up', '', 0, 0, 47) + api.nvim_input_mouse('wheel', 'up', '', 0, 0, 47) end screen:expect([[ {11: 4 }----6----7----8----9 │{11: 4 }5----6----7----8----| @@ -498,7 +520,7 @@ describe('TUI', function() if esc then feed_data('\027[<66;8;1M') else - meths.input_mouse('wheel', 'left', '', 0, 0, 7) + api.nvim_input_mouse('wheel', 'left', '', 0, 0, 7) end screen:expect([[ {11: 4 }5----6----7----8----9│{11: 4 }5----6----7----8----| @@ -513,7 +535,7 @@ describe('TUI', function() if esc then feed_data('\027[<66;48;1M') else - meths.input_mouse('wheel', 'left', '', 0, 0, 47) + api.nvim_input_mouse('wheel', 'left', '', 0, 0, 47) end screen:expect([[ {11: 4 }5----6----7----8----9│{11: 4 }-5----6----7----8---| @@ -528,7 +550,7 @@ describe('TUI', function() if esc then feed_data('\027[<68;8;1M') else - meths.input_mouse('wheel', 'up', 'S', 0, 0, 7) + api.nvim_input_mouse('wheel', 'up', 'S', 0, 0, 7) end screen:expect([[ {11: 1 }5----6----7----8----9│{11: 4 }-5----6----7----8---| @@ -543,7 +565,7 @@ describe('TUI', function() if esc then feed_data('\027[<68;48;1M') else - meths.input_mouse('wheel', 'up', 'S', 0, 0, 47) + api.nvim_input_mouse('wheel', 'up', 'S', 0, 0, 47) end screen:expect([[ {11: 1 }5----6----7----8----9│{11: 1 }-5----6----7----8---| @@ -558,7 +580,7 @@ describe('TUI', function() if esc then feed_data('\027[<70;8;1M') else - meths.input_mouse('wheel', 'left', 'S', 0, 0, 7) + api.nvim_input_mouse('wheel', 'left', 'S', 0, 0, 7) end screen:expect([[ {11: 1 }0----1----2----3----4│{11: 1 }-5----6----7----8---| @@ -573,7 +595,7 @@ describe('TUI', function() if esc then feed_data('\027[<70;48;1M') else - meths.input_mouse('wheel', 'left', 'S', 0, 0, 47) + api.nvim_input_mouse('wheel', 'left', 'S', 0, 0, 47) end screen:expect([[ {11: 1 }0----1----2----3----4│{11: 1 }0----1----2----3----| @@ -597,7 +619,9 @@ describe('TUI', function() end) local function test_mouse_popup(esc) - child_session:request('nvim_exec2', [[ + child_session:request( + 'nvim_exec2', + [[ call setline(1, 'popup menu test') set mouse=a mousemodel=popup @@ -607,11 +631,13 @@ describe('TUI', function() menu PopUp.baz :let g:menustr = 'baz'<CR> highlight Pmenu ctermbg=NONE ctermfg=NONE cterm=underline,reverse highlight PmenuSel ctermbg=NONE ctermfg=NONE cterm=underline,reverse,bold - ]], {}) + ]], + {} + ) if esc then feed_data('\027[<2;5;1M') else - meths.input_mouse('right', 'press', '', 0, 0, 4) + api.nvim_input_mouse('right', 'press', '', 0, 0, 4) end screen:expect([[ {1:p}opup menu test | @@ -625,13 +651,27 @@ describe('TUI', function() if esc then feed_data('\027[<2;5;1m') else - meths.input_mouse('right', 'release', '', 0, 0, 4) + api.nvim_input_mouse('right', 'release', '', 0, 0, 4) end screen:expect_unchanged() if esc then + feed_data('\027[<64;5;1M') + else + api.nvim_input_mouse('wheel', 'up', '', 0, 0, 4) + end + screen:expect([[ + {1:p}opup menu test | + {4:~ }{14: foo }{4: }| + {4:~ }{13: bar }{4: }| + {4:~ }{13: baz }{4: }| + {5:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]) + if esc then feed_data('\027[<35;7;4M') else - meths.input_mouse('move', '', '', 0, 3, 6) + api.nvim_input_mouse('move', '', '', 0, 3, 6) end screen:expect([[ {1:p}opup menu test | @@ -643,15 +683,27 @@ describe('TUI', function() {3:-- TERMINAL --} | ]]) if esc then + feed_data('\027[<65;7;4M') + else + api.nvim_input_mouse('wheel', 'down', '', 0, 3, 6) + end + screen:expect([[ + {1:p}opup menu test | + {4:~ }{13: foo }{4: }| + {4:~ }{14: bar }{4: }| + {4:~ }{13: baz }{4: }| + {5:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]) + if esc then feed_data('\027[<0;7;3M') else - meths.input_mouse('left', 'press', '', 0, 2, 6) + api.nvim_input_mouse('left', 'press', '', 0, 2, 6) end screen:expect([[ {1:p}opup menu test | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] [+] }| :let g:menustr = 'bar' | {3:-- TERMINAL --} | @@ -659,18 +711,17 @@ describe('TUI', function() if esc then feed_data('\027[<0;7;3m') else - meths.input_mouse('left', 'release', '', 0, 2, 6) + api.nvim_input_mouse('left', 'release', '', 0, 2, 6) end screen:expect_unchanged() if esc then feed_data('\027[<2;45;3M') else - meths.input_mouse('right', 'press', '', 0, 2, 44) + api.nvim_input_mouse('right', 'press', '', 0, 2, 44) end screen:expect([[ {1:p}opup menu test | - {4:~ }| - {4:~ }| + {4:~ }|*2 {4:~ }{13: foo }{4: }| {5:[No Name] [+] }{13: bar }{5: }| :let g:menustr = 'bar' {13: baz } | @@ -679,12 +730,11 @@ describe('TUI', function() if esc then feed_data('\027[<34;48;6M') else - meths.input_mouse('right', 'drag', '', 0, 5, 47) + api.nvim_input_mouse('right', 'drag', '', 0, 5, 47) end screen:expect([[ {1:p}opup menu test | - {4:~ }| - {4:~ }| + {4:~ }|*2 {4:~ }{13: foo }{4: }| {5:[No Name] [+] }{13: bar }{5: }| :let g:menustr = 'bar' {14: baz } | @@ -693,13 +743,11 @@ describe('TUI', function() if esc then feed_data('\027[<2;48;6m') else - meths.input_mouse('right', 'release', '', 0, 5, 47) + api.nvim_input_mouse('right', 'release', '', 0, 5, 47) end screen:expect([[ {1:p}opup menu test | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] [+] }| :let g:menustr = 'baz' | {3:-- TERMINAL --} | @@ -718,78 +766,72 @@ describe('TUI', function() it('accepts keypad keys from kitty keyboard protocol #19180', function() feed_data('i') - feed_data(funcs.nr2char(57399)) -- KP_0 - feed_data(funcs.nr2char(57400)) -- KP_1 - feed_data(funcs.nr2char(57401)) -- KP_2 - feed_data(funcs.nr2char(57402)) -- KP_3 - feed_data(funcs.nr2char(57403)) -- KP_4 - feed_data(funcs.nr2char(57404)) -- KP_5 - feed_data(funcs.nr2char(57405)) -- KP_6 - feed_data(funcs.nr2char(57406)) -- KP_7 - feed_data(funcs.nr2char(57407)) -- KP_8 - feed_data(funcs.nr2char(57408)) -- KP_9 - feed_data(funcs.nr2char(57409)) -- KP_DECIMAL - feed_data(funcs.nr2char(57410)) -- KP_DIVIDE - feed_data(funcs.nr2char(57411)) -- KP_MULTIPLY - feed_data(funcs.nr2char(57412)) -- KP_SUBTRACT - feed_data(funcs.nr2char(57413)) -- KP_ADD - feed_data(funcs.nr2char(57414)) -- KP_ENTER - feed_data(funcs.nr2char(57415)) -- KP_EQUAL + feed_data(fn.nr2char(57399)) -- KP_0 + feed_data(fn.nr2char(57400)) -- KP_1 + feed_data(fn.nr2char(57401)) -- KP_2 + feed_data(fn.nr2char(57402)) -- KP_3 + feed_data(fn.nr2char(57403)) -- KP_4 + feed_data(fn.nr2char(57404)) -- KP_5 + feed_data(fn.nr2char(57405)) -- KP_6 + feed_data(fn.nr2char(57406)) -- KP_7 + feed_data(fn.nr2char(57407)) -- KP_8 + feed_data(fn.nr2char(57408)) -- KP_9 + feed_data(fn.nr2char(57409)) -- KP_DECIMAL + feed_data(fn.nr2char(57410)) -- KP_DIVIDE + feed_data(fn.nr2char(57411)) -- KP_MULTIPLY + feed_data(fn.nr2char(57412)) -- KP_SUBTRACT + feed_data(fn.nr2char(57413)) -- KP_ADD + feed_data(fn.nr2char(57414)) -- KP_ENTER + feed_data(fn.nr2char(57415)) -- KP_EQUAL screen:expect([[ 0123456789./*-+ | ={1: } | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] [+] }| {3:-- INSERT --} | {3:-- TERMINAL --} | ]]) - feed_data(funcs.nr2char(57417)) -- KP_LEFT + feed_data(fn.nr2char(57417)) -- KP_LEFT screen:expect([[ 0123456789./*-+ | {1:=} | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] [+] }| {3:-- INSERT --} | {3:-- TERMINAL --} | ]]) - feed_data(funcs.nr2char(57418)) -- KP_RIGHT + feed_data(fn.nr2char(57418)) -- KP_RIGHT screen:expect([[ 0123456789./*-+ | ={1: } | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] [+] }| {3:-- INSERT --} | {3:-- TERMINAL --} | ]]) - feed_data(funcs.nr2char(57419)) -- KP_UP + feed_data(fn.nr2char(57419)) -- KP_UP screen:expect([[ 0{1:1}23456789./*-+ | = | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] [+] }| {3:-- INSERT --} | {3:-- TERMINAL --} | ]]) - feed_data(funcs.nr2char(57420)) -- KP_DOWN + feed_data(fn.nr2char(57420)) -- KP_DOWN screen:expect([[ 0123456789./*-+ | ={1: } | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] [+] }| {3:-- INSERT --} | {3:-- TERMINAL --} | ]]) - feed_data(funcs.nr2char(57425)) -- KP_INSERT + feed_data(fn.nr2char(57425)) -- KP_INSERT screen:expect([[ 0123456789./*-+ | ={1: } | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] [+] }| {3:-- REPLACE --} | {3:-- TERMINAL --} | @@ -798,8 +840,7 @@ describe('TUI', function() screen:expect([[ 0123456789./*-+ | {1:=} | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] [+] }| | {3:-- TERMINAL --} | @@ -808,8 +849,7 @@ describe('TUI', function() screen:expect([[ {1:0}123456789./*-+ | = | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] [+] }| | {3:-- TERMINAL --} | @@ -818,52 +858,51 @@ describe('TUI', function() screen:expect([[ 0123456789{1:.}/*-+ | = | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] [+] }| | {3:-- TERMINAL --} | ]]) - feed_data(funcs.nr2char(57426)) -- KP_DELETE + feed_data(fn.nr2char(57426)) -- KP_DELETE screen:expect([[ 0123456789{1:/}*-+ | = | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] [+] }| | {3:-- TERMINAL --} | ]]) - feed_data(funcs.nr2char(57423)) -- KP_HOME + feed_data(fn.nr2char(57423)) -- KP_HOME screen:expect([[ {1:0}123456789/*-+ | = | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] [+] }| | {3:-- TERMINAL --} | ]]) - feed_data(funcs.nr2char(57424)) -- KP_END + feed_data(fn.nr2char(57424)) -- KP_END screen:expect([[ 0123456789/*-{1:+} | = | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] [+] }| | {3:-- TERMINAL --} | ]]) - child_session:request('nvim_exec2', [[ + child_session:request( + 'nvim_exec2', + [[ tab split tabnew highlight Tabline ctermbg=NONE ctermfg=NONE cterm=underline - ]], {}) + ]], + {} + ) screen:expect([[ {12: + [No Name] + [No Name] }{3: [No Name] }{1: }{12:X}| {1: } | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] }| | {3:-- TERMINAL --} | @@ -882,8 +921,7 @@ describe('TUI', function() screen:expect([[ {12: + [No Name] + [No Name] }{3: [No Name] }{1: }{12:X}| {1: } | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] }| | {3:-- TERMINAL --} | @@ -892,20 +930,19 @@ describe('TUI', function() it('supports Super and Meta modifiers', function() feed_data('i') - feed_data('\022\027[106;9u') -- Super + j - feed_data('\022\027[107;33u') -- Meta + k - feed_data('\022\027[13;41u') -- Super + Meta + Enter - feed_data('\022\027[127;48u') -- Shift + Alt + Ctrl + Super + Meta + Backspace + feed_data('\022\027[106;9u') -- Super + j + feed_data('\022\027[107;33u') -- Meta + k + feed_data('\022\027[13;41u') -- Super + Meta + Enter + feed_data('\022\027[127;48u') -- Shift + Alt + Ctrl + Super + Meta + Backspace feed_data('\n') - feed_data('\022\027[57376;9u') -- Super + F13 - feed_data('\022\027[57377;33u') -- Meta + F14 - feed_data('\022\027[57378;41u') -- Super + Meta + F15 - feed_data('\022\027[57379;48u') -- Shift + Alt + Ctrl + Super + Meta + F16 + feed_data('\022\027[57376;9u') -- Super + F13 + feed_data('\022\027[57377;33u') -- Meta + F14 + feed_data('\022\027[57378;41u') -- Super + Meta + F15 + feed_data('\022\027[57379;48u') -- Shift + Alt + Ctrl + Super + Meta + F16 screen:expect([[ <D-j><T-k><T-D-CR><M-T-C-S-D-BS> | <D-F13><T-F14><T-D-F15><M-T-C-S-D-F16>{1: } | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] [+] }| {3:-- INSERT --} | {3:-- TERMINAL --} | @@ -917,61 +954,54 @@ describe('TUI', function() feed_data('i""\027i\027[200~') screen:expect([[ "{1:"} | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] [+] }| {3:-- INSERT --} | {3:-- TERMINAL --} | ]]) feed_data('pasted from terminal') - expect_child_buf_lines({'"pasted from terminal"'}) + expect_child_buf_lines({ '"pasted from terminal"' }) screen:expect([[ "pasted from terminal{1:"} | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] [+] }| {3:-- INSERT --} | {3:-- TERMINAL --} | ]]) - feed_data('\027[201~') -- End paste. - feed_data('\027[27u') -- ESC: go to Normal mode. + feed_data('\027[201~') -- End paste. + feed_data('\027[27u') -- ESC: go to Normal mode. wait_for_mode('n') screen:expect([[ "pasted from termina{1:l}" | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] [+] }| | {3:-- TERMINAL --} | ]]) -- Dot-repeat/redo. feed_data('2.') - expect_child_buf_lines({'"pasted from terminapasted from terminalpasted from terminall"'}) + expect_child_buf_lines({ '"pasted from terminapasted from terminalpasted from terminall"' }) screen:expect([[ "pasted from terminapasted from terminalpasted fro| m termina{1:l}l" | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] [+] }| | {3:-- TERMINAL --} | ]]) -- Undo. feed_data('u') - expect_child_buf_lines({'"pasted from terminal"'}) + expect_child_buf_lines({ '"pasted from terminal"' }) feed_data('u') - expect_child_buf_lines({'""'}) + expect_child_buf_lines({ '""' }) feed_data('u') - expect_child_buf_lines({''}) + expect_child_buf_lines({ '' }) end) it('paste: select-mode', function() feed_data('ithis is line 1\nthis is line 2\nline 3 is here\n\027') wait_for_mode('n') - screen:expect{grid=[[ + screen:expect([[ this is line 1 | this is line 2 | line 3 is here | @@ -979,33 +1009,40 @@ describe('TUI', function() {5:[No Name] [+] }| | {3:-- TERMINAL --} | - ]]} + ]]) -- Select-mode. Use <C-n> to move down. feed_data('gg04lgh\14\14') - wait_for_mode('s') + screen:expect([[ + this{16: is line 1} | + {16:this is line 2} | + {16:line}{1: }3 is here | + | + {5:[No Name] [+] }| + {3:-- SELECT --} | + {3:-- TERMINAL --} | + ]]) feed_data('\027[200~') feed_data('just paste it™') feed_data('\027[201~') - screen:expect{grid=[[ + screen:expect([[ thisjust paste it{1:™}3 is here | | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] [+] }| | {3:-- TERMINAL --} | - ]]} + ]]) -- Undo. feed_data('u') - expect_child_buf_lines{ + expect_child_buf_lines { 'this is line 1', 'this is line 2', 'line 3 is here', '', } -- Redo. - feed_data('\18') -- <C-r> - expect_child_buf_lines{ + feed_data('\18') -- <C-r> + expect_child_buf_lines { 'thisjust paste it™3 is here', '', } @@ -1013,32 +1050,28 @@ describe('TUI', function() it('paste: terminal mode', function() if is_ci('github') then - pending("tty-test complains about not owning the terminal -- actions/runner#241") + pending('tty-test complains about not owning the terminal -- actions/runner#241') end child_exec_lua('vim.o.statusline="^^^^^^^"') child_exec_lua('vim.cmd.terminal(...)', testprg('tty-test')) feed_data('i') - screen:expect{grid=[[ + screen:expect([[ tty ready | {1: } | - | - | + |*2 {5:^^^^^^^ }| - {3:-- TERMINAL --} | - {3:-- TERMINAL --} | - ]]} + {3:-- TERMINAL --} |*2 + ]]) feed_data('\027[200~') feed_data('hallo') feed_data('\027[201~') - screen:expect{grid=[[ + screen:expect([[ tty ready | hallo{1: } | - | - | + |*2 {5:^^^^^^^ }| - {3:-- TERMINAL --} | - {3:-- TERMINAL --} | - ]]} + {3:-- TERMINAL --} |*2 + ]]) end) it('paste: normal-mode (+CRLF #10872)', function() @@ -1046,99 +1079,98 @@ describe('TUI', function() wait_for_mode('c') feed_data('\n') wait_for_mode('n') - local expected_lf = {'line 1', 'ESC:\027 / CR: \rx'} - local expected_crlf = {'line 1', 'ESC:\027 / CR: ', 'x'} + local expected_lf = { 'line 1', 'ESC:\027 / CR: \rx' } + local expected_crlf = { 'line 1', 'ESC:\027 / CR: ', 'x' } local expected_grid1 = [[ line 1 | - ESC:{11:^[} / CR: | + ESC:{6:^[} / CR: | {1:x} | {4:~ }| {5:[No Name] [+] 3,1 All}| | {3:-- TERMINAL --} | ]] - local expected_attr = { - [1] = {reverse = true}, - [3] = {bold = true}, - [4] = {foreground = tonumber('0x00000c')}, - [5] = {bold = true, reverse = true}, - [11] = {foreground = tonumber('0x000051')}, - [12] = {reverse = true, foreground = tonumber('0x000051')}, - } -- "bracketed paste" - feed_data('\027[200~'..table.concat(expected_lf,'\n')..'\027[201~') - screen:expect{grid=expected_grid1, attr_ids=expected_attr} + feed_data('\027[200~' .. table.concat(expected_lf, '\n') .. '\027[201~') + screen:expect(expected_grid1) -- Dot-repeat/redo. feed_data('.') - screen:expect{grid=[[ - ESC:{11:^[} / CR: | + screen:expect([[ + ESC:{6:^[} / CR: | xline 1 | - ESC:{11:^[} / CR: | + ESC:{6:^[} / CR: | {1:x} | {5:[No Name] [+] 5,1 Bot}| | {3:-- TERMINAL --} | - ]], attr_ids=expected_attr} + ]]) -- Undo. feed_data('u') expect_child_buf_lines(expected_crlf) feed_data('u') - expect_child_buf_lines({''}) + expect_child_buf_lines({ '' }) feed_data(':echo') wait_for_mode('c') feed_data('\n') wait_for_mode('n') -- CRLF input - feed_data('\027[200~'..table.concat(expected_lf,'\r\n')..'\027[201~') - screen:expect{grid=expected_grid1, attr_ids=expected_attr} + feed_data('\027[200~' .. table.concat(expected_lf, '\r\n') .. '\027[201~') + screen:expect(expected_grid1) expect_child_buf_lines(expected_crlf) end) it('paste: cmdline-mode inserts 1 line', function() - feed_data('ifoo\n') -- Insert some text (for dot-repeat later). - feed_data('\027:""') -- Enter Cmdline-mode. - feed_data('\027[D') -- <Left> to place cursor between quotes. + feed_data('ifoo\n') -- Insert some text (for dot-repeat later). + feed_data('\027:""') -- Enter Cmdline-mode. + feed_data('\027[D') -- <Left> to place cursor between quotes. wait_for_mode('c') + screen:expect([[ + foo | + | + {4:~ }|*2 + {5:[No Name] [+] }| + :"{1:"} | + {3:-- TERMINAL --} | + ]]) -- "bracketed paste" feed_data('\027[200~line 1\nline 2\n') wait_for_mode('c') feed_data('line 3\nline 4\n\027[201~') wait_for_mode('c') - screen:expect{grid=[[ + screen:expect([[ foo | | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] [+] }| :"line 1{1:"} | {3:-- TERMINAL --} | - ]]} + ]]) -- Dot-repeat/redo. feed_data('\027[27u') wait_for_mode('n') feed_data('.') - screen:expect{grid=[[ - foo | - foo | + screen:expect([[ + foo |*2 {1: } | {4:~ }| {5:[No Name] [+] }| | {3:-- TERMINAL --} | - ]]} + ]]) end) it('paste: cmdline-mode collects chunks of unfinished line', function() local function expect_cmdline(expected) retry(nil, nil, function() - local _, cmdline = child_session:request( - 'nvim_call_function', 'getcmdline', {}) + local _, cmdline = child_session:request('nvim_call_function', 'getcmdline', {}) eq(expected, cmdline) + local _, pos = child_session:request('nvim_call_function', 'getcmdpos', {}) + eq(#expected, pos) -- Cursor is just before the last char. end) end - feed_data('\027:""') -- Enter Cmdline-mode. - feed_data('\027[D') -- <Left> to place cursor between quotes. - wait_for_mode('c') + feed_data('\027:""') -- Enter Cmdline-mode. + feed_data('\027[D') -- <Left> to place cursor between quotes. + expect_cmdline('""') feed_data('\027[200~stuff 1 ') expect_cmdline('"stuff 1 "') -- Discards everything after the first line. @@ -1153,27 +1185,30 @@ describe('TUI', function() end) it('paste: recovers from vim.paste() failure', function() - child_session:request('nvim_exec_lua', [[ + child_session:request( + 'nvim_exec_lua', + [[ _G.save_paste_fn = vim.paste -- Stack traces for this test are non-deterministic, so disable them _G.debug.traceback = function(msg) return msg end vim.paste = function(lines, phase) error("fake fail") end - ]], {}) + ]], + {} + ) -- Prepare something for dot-repeat/redo. feed_data('ifoo\n\027[27u') wait_for_mode('n') - screen:expect{grid=[[ + screen:expect([[ foo | {1: } | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] [+] }| | {3:-- TERMINAL --} | - ]]} + ]]) -- Start pasting... feed_data('\027[200~line 1\nline 2\n') - screen:expect{grid=[[ + screen:expect([[ foo | | {5: }| @@ -1181,44 +1216,39 @@ describe('TUI', function() {8:ake fail} | {10:Press ENTER or type command to continue}{1: } | {3:-- TERMINAL --} | - ]]} + ]]) -- Remaining chunks are discarded after vim.paste() failure. feed_data('line 3\nline 4\n') feed_data('line 5\nline 6\n') feed_data('line 7\nline 8\n') -- Stop paste. feed_data('\027[201~') - feed_data('\n') -- <CR> - expect_child_buf_lines({'foo',''}) - --Dot-repeat/redo is not modified by failed paste. + feed_data('\n') -- <CR> to dismiss hit-enter prompt + expect_child_buf_lines({ 'foo', '' }) + -- Dot-repeat/redo is not modified by failed paste. feed_data('.') - screen:expect{grid=[[ - foo | - foo | + screen:expect([[ + foo |*2 {1: } | {4:~ }| {5:[No Name] [+] }| | {3:-- TERMINAL --} | - ]]} + ]]) -- Editor should still work after failed/drained paste. feed_data('ityped input...\027[27u') - screen:expect{grid=[[ - foo | - foo | + screen:expect([[ + foo |*2 typed input..{1:.} | {4:~ }| {5:[No Name] [+] }| | {3:-- TERMINAL --} | - ]]} + ]]) -- Paste works if vim.paste() succeeds. - child_session:request('nvim_exec_lua', [[ - vim.paste = _G.save_paste_fn - ]], {}) + child_session:request('nvim_exec_lua', [[vim.paste = _G.save_paste_fn]], {}) feed_data('\027[200~line A\nline B\n\027[201~') - feed_data('\n') -- <CR> - screen:expect{grid=[[ + screen:expect([[ foo | typed input...line A | line B | @@ -1226,28 +1256,36 @@ describe('TUI', function() {5:[No Name] [+] }| | {3:-- TERMINAL --} | - ]]} + ]]) end) it('paste: vim.paste() cancel (retval=false) #10865', function() -- This test only exercises the "cancel" case. Use-case would be "dangling -- paste", but that is not implemented yet. #10865 - child_session:request('nvim_exec_lua', [[ + child_session:request( + 'nvim_exec_lua', + [[ vim.paste = function(lines, phase) return false end - ]], {}) + ]], + {} + ) feed_data('\027[200~line A\nline B\n\027[201~') feed_data('ifoo\n\027[27u') - expect_child_buf_lines({'foo',''}) + expect_child_buf_lines({ 'foo', '' }) end) it("paste: 'nomodifiable' buffer", function() child_session:request('nvim_command', 'set nomodifiable') - child_session:request('nvim_exec_lua', [[ + child_session:request( + 'nvim_exec_lua', + [[ -- Truncate the error message to hide the line number _G.debug.traceback = function(msg) return msg:sub(-49) end - ]], {}) + ]], + {} + ) feed_data('\027[200~fail 1\nfail 2\n\027[201~') - screen:expect{grid=[[ + screen:expect([[ | {4:~ }| {5: }| @@ -1255,11 +1293,11 @@ describe('TUI', function() {8:hanges, 'modifiable' is off} | {10:Press ENTER or type command to continue}{1: } | {3:-- TERMINAL --} | - ]]} - feed_data('\n') -- <Enter> + ]]) + feed_data('\n') -- <Enter> to dismiss hit-enter prompt child_session:request('nvim_command', 'set modifiable') feed_data('\027[200~success 1\nsuccess 2\n\027[201~') - screen:expect{grid=[[ + screen:expect([[ success 1 | success 2 | {1: } | @@ -1267,7 +1305,7 @@ describe('TUI', function() {5:[No Name] [+] }| | {3:-- TERMINAL --} | - ]]} + ]]) end) it('paste: exactly 64 bytes #10311', function() @@ -1275,20 +1313,19 @@ describe('TUI', function() feed_data('i') wait_for_mode('i') -- "bracketed paste" - feed_data('\027[200~'..expected..'\027[201~') - expect_child_buf_lines({expected}) + feed_data('\027[200~' .. expected .. '\027[201~') + expect_child_buf_lines({ expected }) feed_data(' end') - expected = expected..' end' + expected = expected .. ' end' screen:expect([[ zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz| zzzzzzzzzzzzzz end{1: } | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5:[No Name] [+] }| {3:-- INSERT --} | {3:-- TERMINAL --} | ]]) - expect_child_buf_lines({expected}) + expect_child_buf_lines({ expected }) end) it('paste: less-than sign in cmdline #11088', function() @@ -1296,16 +1333,14 @@ describe('TUI', function() feed_data(':') wait_for_mode('c') -- "bracketed paste" - feed_data('\027[200~'..expected..'\027[201~') - screen:expect{grid=[[ + feed_data('\027[200~' .. expected .. '\027[201~') + screen:expect([[ | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| :<{1: } | {3:-- TERMINAL --} | - ]]} + ]]) end) it('paste: big burst of input', function() @@ -1317,7 +1352,7 @@ describe('TUI', function() feed_data('i') wait_for_mode('i') -- "bracketed paste" - feed_data('\027[200~'..table.concat(t, '\n')..'\027[201~') + feed_data('\027[200~' .. table.concat(t, '\n') .. '\027[201~') expect_child_buf_lines(t) feed_data(' end') screen:expect([[ @@ -1329,7 +1364,7 @@ describe('TUI', function() {3:-- INSERT --} | {3:-- TERMINAL --} | ]]) - feed_data('\027[27u') -- ESC: go to Normal mode. + feed_data('\027[27u') -- ESC: go to Normal mode. wait_for_mode('n') -- Dot-repeat/redo. feed_data('.') @@ -1347,9 +1382,10 @@ describe('TUI', function() it('paste: forwards spurious "start paste" code', function() -- If multiple "start paste" sequences are sent without a corresponding -- "stop paste" sequence, only the first occurrence should be consumed. - + feed_data('i') + wait_for_mode('i') -- Send the "start paste" sequence. - feed_data('i\027[200~') + feed_data('\027[200~') feed_data('\npasted from terminal (1)\n') -- Send spurious "start paste" sequence. feed_data('\027[200~') @@ -1357,7 +1393,7 @@ describe('TUI', function() -- Send the "stop paste" sequence. feed_data('\027[201~') - screen:expect{grid=[[ + screen:expect([[ | pasted from terminal (1) | {6:^[}[200~ | @@ -1365,27 +1401,19 @@ describe('TUI', function() {5:[No Name] [+] }| {3:-- INSERT --} | {3:-- TERMINAL --} | - ]], attr_ids={ - [1] = {reverse = true}, - [2] = {background = tonumber('0x00000b')}, - [3] = {bold = true}, - [4] = {foreground = tonumber('0x00000c')}, - [5] = {bold = true, reverse = true}, - [6] = {foreground = tonumber('0x000051')}, - }} + ]]) end) it('paste: ignores spurious "stop paste" code', function() -- If "stop paste" sequence is received without a preceding "start paste" -- sequence, it should be ignored. feed_data('i') + wait_for_mode('i') -- Send "stop paste" sequence. feed_data('\027[201~') screen:expect([[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| {3:-- INSERT --} | {3:-- TERMINAL --} | @@ -1394,23 +1422,13 @@ describe('TUI', function() it('paste: split "start paste" code', function() feed_data('i') - screen:expect{grid=[[ - {1: } | - {4:~ }| - {4:~ }| - {4:~ }| - {5:[No Name] }| - {3:-- INSERT --} | - {3:-- TERMINAL --} | - ]]} + wait_for_mode('i') -- Send split "start paste" sequence. feed_data('\027[2') feed_data('00~pasted from terminal\027[201~') screen:expect([[ pasted from terminal{1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] [+] }| {3:-- INSERT --} | {3:-- TERMINAL --} | @@ -1419,23 +1437,13 @@ describe('TUI', function() it('paste: split "stop paste" code', function() feed_data('i') - screen:expect{grid=[[ - {1: } | - {4:~ }| - {4:~ }| - {4:~ }| - {5:[No Name] }| - {3:-- INSERT --} | - {3:-- TERMINAL --} | - ]]} + wait_for_mode('i') -- Send split "stop paste" sequence. feed_data('\027[200~pasted from terminal\027[20') feed_data('1~') screen:expect([[ pasted from terminal{1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] [+] }| {3:-- INSERT --} | {3:-- TERMINAL --} | @@ -1443,7 +1451,9 @@ describe('TUI', function() end) it('paste: streamed paste with isolated "stop paste" code', function() - child_session:request('nvim_exec_lua', [[ + child_session:request( + 'nvim_exec_lua', + [[ _G.paste_phases = {} vim.paste = (function(overridden) return function(lines, phase) @@ -1451,57 +1461,47 @@ describe('TUI', function() overridden(lines, phase) end end)(vim.paste) - ]], {}) + ]], + {} + ) feed_data('i') - screen:expect{grid=[[ - {1: } | - {4:~ }| - {4:~ }| - {4:~ }| - {5:[No Name] }| - {3:-- INSERT --} | - {3:-- TERMINAL --} | - ]]} - feed_data('\027[200~pasted') -- phase 1 + wait_for_mode('i') + feed_data('\027[200~pasted') -- phase 1 screen:expect([[ pasted{1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] [+] }| {3:-- INSERT --} | {3:-- TERMINAL --} | ]]) - feed_data(' from terminal') -- phase 2 + feed_data(' from terminal') -- phase 2 screen:expect([[ pasted from terminal{1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] [+] }| {3:-- INSERT --} | {3:-- TERMINAL --} | ]]) -- Send isolated "stop paste" sequence. - feed_data('\027[201~') -- phase 3 + feed_data('\027[201~') -- phase 3 screen:expect_unchanged() local _, rv = child_session:request('nvim_exec_lua', [[return _G.paste_phases]], {}) - eq({1, 2, 3}, rv) + eq({ 1, 2, 3 }, rv) end) it('allows termguicolors to be set at runtime', function() screen:set_option('rgb', true) screen:set_default_attr_ids({ - [1] = {reverse = true}, - [2] = {foreground = tonumber('0x4040ff'), fg_indexed=true}, - [3] = {bold = true, reverse = true}, - [4] = {bold = true}, - [5] = {reverse = true, foreground = tonumber('0xe0e000'), fg_indexed=true}, - [6] = {foreground = tonumber('0xe0e000'), fg_indexed=true}, - [7] = {reverse = true, foreground = Screen.colors.SeaGreen4}, - [8] = {foreground = Screen.colors.SeaGreen4}, - [9] = {bold = true, foreground = Screen.colors.Blue1}, - [10] = {foreground = Screen.colors.Blue}, + [1] = { reverse = true }, + [2] = { foreground = tonumber('0x4040ff'), fg_indexed = true }, + [3] = { bold = true, reverse = true }, + [4] = { bold = true }, + [5] = { reverse = true, foreground = tonumber('0xe0e000'), fg_indexed = true }, + [6] = { foreground = tonumber('0xe0e000'), fg_indexed = true }, + [7] = { reverse = true, foreground = Screen.colors.SeaGreen4 }, + [8] = { foreground = Screen.colors.SeaGreen4 }, + [9] = { bold = true, foreground = Screen.colors.Blue1 }, + [10] = { foreground = Screen.colors.Blue }, }) feed_data(':hi SpecialKey ctermfg=3 guifg=SeaGreen\n') @@ -1511,9 +1511,7 @@ describe('TUI', function() feed_data(':set termguicolors?\n') screen:expect([[ {5:^}{6:G} | - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 {3:[No Name] [+] }| notermguicolors | {4:-- TERMINAL --} | @@ -1522,9 +1520,7 @@ describe('TUI', function() feed_data(':set termguicolors\n') screen:expect([[ {7:^}{8:G} | - {9:~}{10: }| - {9:~}{10: }| - {9:~}{10: }| + {9:~}{10: }|*3 {3:[No Name] [+] }| :set termguicolors | {4:-- TERMINAL --} | @@ -1533,9 +1529,7 @@ describe('TUI', function() feed_data(':set notermguicolors\n') screen:expect([[ {5:^}{6:G} | - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 {3:[No Name] [+] }| :set notermguicolors | {4:-- TERMINAL --} | @@ -1544,50 +1538,54 @@ describe('TUI', function() it('forwards :term palette colors with termguicolors', function() if is_ci('github') then - pending("tty-test complains about not owning the terminal -- actions/runner#241") + pending('tty-test complains about not owning the terminal -- actions/runner#241') end screen:set_rgb_cterm(true) screen:set_default_attr_ids({ - [1] = {{reverse = true}, {reverse = true}}, - [2] = {{bold = true, reverse = true}, {bold = true, reverse = true}}, - [3] = {{bold = true}, {bold = true}}, - [4] = {{fg_indexed = true, foreground = tonumber('0xe0e000')}, {foreground = 3}}, - [5] = {{foreground = tonumber('0xff8000')}, {}}, + [1] = { { reverse = true }, { reverse = true } }, + [2] = { { bold = true, reverse = true }, { bold = true, reverse = true } }, + [3] = { { bold = true }, { bold = true } }, + [4] = { { fg_indexed = true, foreground = tonumber('0xe0e000') }, { foreground = 3 } }, + [5] = { { foreground = tonumber('0xff8000') }, {} }, }) child_exec_lua('vim.o.statusline="^^^^^^^"') child_exec_lua('vim.o.termguicolors=true') child_exec_lua('vim.cmd.terminal(...)', testprg('tty-test')) - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:t}ty ready | - | - | - | + |*3 {2:^^^^^^^ }| | {3:-- TERMINAL --} | - ]]} - feed_data(':call chansend(&channel, "\\033[38;5;3mtext\\033[38:2:255:128:0mcolor\\033[0;10mtext")\n') - screen:expect{grid=[[ + ]], + } + feed_data( + ':call chansend(&channel, "\\033[38;5;3mtext\\033[38:2:255:128:0mcolor\\033[0;10mtext")\n' + ) + screen:expect { + grid = [[ {1:t}ty ready | {4:text}{5:color}text | - | - | + |*2 {2:^^^^^^^ }| | {3:-- TERMINAL --} | - ]]} + ]], + } feed_data(':set notermguicolors\n') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:t}ty ready | {4:text}colortext | - | - | + |*2 {2:^^^^^^^ }| :set notermguicolors | {3:-- TERMINAL --} | - ]]} + ]], + } end) it('in nvim_list_uis()', function() @@ -1613,7 +1611,7 @@ describe('TUI', function() term_background = '', term_colors = 256, term_name = exp_term, - width = 50 + width = 50, }, } local _, rv = child_session:request('nvim_list_uis') @@ -1621,10 +1619,17 @@ describe('TUI', function() end) it('allows grid to assume wider ambiguous-width characters than host terminal #19686', function() - child_session:request('nvim_buf_set_lines', 0, 0, -1, true, { ('℃'):rep(60), ('℃'):rep(60) }) + child_session:request( + 'nvim_buf_set_lines', + 0, + 0, + -1, + true, + { ('℃'):rep(60), ('℃'):rep(60) } + ) child_session:request('nvim_set_option_value', 'cursorline', true, {}) child_session:request('nvim_set_option_value', 'list', true, {}) - child_session:request('nvim_set_option_value', 'listchars', 'eol:$', {win=0}) + child_session:request('nvim_set_option_value', 'listchars', 'eol:$', { win = 0 }) feed_data('gg') local singlewidth_screen = [[ {13:℃}{12:℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃}| @@ -1651,9 +1656,9 @@ describe('TUI', function() screen:expect(doublewidth_screen) child_session:request('nvim_set_option_value', 'ambiwidth', 'single', {}) screen:expect(singlewidth_screen) - child_session:request('nvim_call_function', 'setcellwidths', {{{0x2103, 0x2103, 2}}}) + child_session:request('nvim_call_function', 'setcellwidths', { { { 0x2103, 0x2103, 2 } } }) screen:expect(doublewidth_screen) - child_session:request('nvim_call_function', 'setcellwidths', {{{0x2103, 0x2103, 1}}}) + child_session:request('nvim_call_function', 'setcellwidths', { { { 0x2103, 0x2103, 1 } } }) screen:expect(singlewidth_screen) end) @@ -1661,92 +1666,106 @@ describe('TUI', function() helpers.skip(is_os('mac'), 'FIXME: crashes/errors on macOS') screen:try_resize(77, 855) retry(nil, nil, function() - eq({true, 852}, {child_session:request('nvim_win_get_height', 0)}) + eq({ true, 852 }, { child_session:request('nvim_win_get_height', 0) }) end) -- Use full screen message so that redrawing afterwards is more deterministic. child_session:notify('nvim_command', 'intro') - screen:expect({any = 'Nvim'}) + screen:expect({ any = 'Nvim' }) -- Going to top-left corner needs 3 bytes. -- Setting underline attribute needs 9 bytes. - -- The whole line needs 3 + 9 + 65515 + 3 = 65530 bytes. + -- The whole line needs 3 + 9 + 65513 + 3 = 65528 bytes. -- The cursor_address that comes after will overflow the 65535-byte buffer. - local line = ('a'):rep(65515) .. '℃' - child_session:notify('nvim_exec_lua', [[ + local line = ('a'):rep(65513) .. '℃' + child_session:notify( + 'nvim_exec_lua', + [[ vim.api.nvim_buf_set_lines(0, 0, -1, true, {...}) vim.o.cursorline = true - ]], {line, 'b'}) + ]], + { line, 'b' } + ) -- Close the :intro message and redraw the lines. feed_data('\n') screen:expect( - '{13:a}{12:' .. ('a'):rep(76) .. '}|\n' - .. ('{12:' .. ('a'):rep(77) .. '}|\n'):rep(849) - .. '{12:' .. ('a'):rep(65) .. '℃' .. (' '):rep(11) .. '}|\n' .. dedent([[ + '{13:a}{12:' + .. ('a'):rep(76) + .. '}|\n' + .. ('{12:' .. ('a'):rep(77) .. '}|\n'):rep(849) + .. '{12:' + .. ('a'):rep(63) + .. '℃' + .. (' '):rep(13) + .. '}|\n' + .. dedent([[ b | {5:[No Name] [+] }| | - {3:-- TERMINAL --} |]])) + {3:-- TERMINAL --} |]]) + ) end) it('visual bell (padding) does not crash #21610', function() feed_data ':set visualbell\n' - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| :set visualbell | {3:-- TERMINAL --} | - ]]} + ]], + } -- move left is enough to invoke the bell feed_data 'h' -- visual change to show we process events after this feed_data 'i' - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| {3:-- INSERT --} | {3:-- TERMINAL --} | - ]]} + ]], + } end) it('no assert failure on deadly signal #21896', function() exec_lua([[vim.uv.kill(vim.fn.jobpid(vim.bo.channel), 'sigterm')]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ Vim: Caught deadly signal 'SIGTERM' | - | - | + |*2 [Process exited 1]{1: } | - | - | + |*2 {3:-- TERMINAL --} | - ]]} + ]], + } end) it('no stack-use-after-scope with cursor color #22432', function() screen:set_option('rgb', true) command('set termguicolors') - child_session:request('nvim_exec2', [[ + child_session:request( + 'nvim_exec2', + [[ set tgc hi Cursor guifg=Red guibg=Green set guicursor=n:block-Cursor/lCursor - ]], {}) + ]], + {} + ) screen:set_default_attr_ids({ - [1] = {reverse = true}, - [2] = {bold = true, foreground = Screen.colors.Blue}, - [3] = {foreground = Screen.colors.Blue}, - [4] = {reverse = true, bold = true}, - [5] = {bold = true}, + [1] = { reverse = true }, + [2] = { bold = true, foreground = Screen.colors.Blue }, + [3] = { foreground = Screen.colors.Blue }, + [4] = { reverse = true, bold = true }, + [5] = { bold = true }, }) screen:expect([[ {1: } | - {2:~}{3: }| - {2:~}{3: }| - {2:~}{3: }| + {2:~}{3: }|*3 {4:[No Name] }| | {5:-- TERMINAL --} | @@ -1754,9 +1773,7 @@ describe('TUI', function() feed_data('i') screen:expect([[ {1: } | - {2:~}{3: }| - {2:~}{3: }| - {2:~}{3: }| + {2:~}{3: }|*3 {4:[No Name] }| {5:-- INSERT --} | {5:-- TERMINAL --} | @@ -1764,12 +1781,10 @@ describe('TUI', function() end) it('redraws on SIGWINCH even if terminal size is unchanged #23411', function() - child_session:request('nvim_echo', {{'foo'}}, false, {}) + child_session:request('nvim_echo', { { 'foo' } }, false, {}) screen:expect([[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| foo | {3:-- TERMINAL --} | @@ -1777,9 +1792,7 @@ describe('TUI', function() exec_lua([[vim.uv.kill(vim.fn.jobpid(vim.bo.channel), 'sigwinch')]]) screen:expect([[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| | {3:-- TERMINAL --} | @@ -1787,14 +1800,14 @@ describe('TUI', function() end) it('supports hiding cursor', function() - child_session:request('nvim_command', - "let g:id = jobstart([v:progpath, '--clean', '--headless'])") + child_session:request( + 'nvim_command', + "let g:id = jobstart([v:progpath, '--clean', '--headless'])" + ) feed_data(':call jobwait([g:id])\n') screen:expect([[ | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| :call jobwait([g:id]) | {3:-- TERMINAL --} | @@ -1802,14 +1815,73 @@ describe('TUI', function() feed_data('\003') screen:expect([[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| Type :qa and press <Enter> to exit Nvim | {3:-- TERMINAL --} | ]]) end) + + it('cursor is not hidden on incsearch with no match', function() + feed_data('ifoo\027') + feed_data('/foo') + screen:expect([[ + {1:foo} | + {4:~ }|*3 + {5:[No Name] [+] }| + /foo{1: } | + {3:-- TERMINAL --} | + ]]) + screen:sleep(10) + feed_data('b') + screen:expect([[ + foo | + {4:~ }|*3 + {5:[No Name] [+] }| + /foob{1: } | + {3:-- TERMINAL --} | + ]]) + screen:sleep(10) + feed_data('a') + screen:expect([[ + foo | + {4:~ }|*3 + {5:[No Name] [+] }| + /fooba{1: } | + {3:-- TERMINAL --} | + ]]) + end) + + it('emits hyperlinks with OSC 8', function() + exec_lua([[ + local buf = vim.api.nvim_get_current_buf() + _G.urls = {} + vim.api.nvim_create_autocmd('TermRequest', { + buffer = buf, + callback = function(args) + local req = args.data + if not req then + return + end + local url = req:match('\027]8;;(.*)$') + if url ~= nil then + table.insert(_G.urls, url) + end + end, + }) + ]]) + child_exec_lua([[ + vim.api.nvim_buf_set_lines(0, 0, 0, true, {'Hello'}) + local ns = vim.api.nvim_create_namespace('test') + vim.api.nvim_buf_set_extmark(0, ns, 0, 1, { + end_col = 3, + url = 'https://example.com', + }) + ]]) + retry(nil, 1000, function() + eq({ 'https://example.com', '' }, exec_lua([[return _G.urls]])) + end) + end) end) describe('TUI', function() @@ -1818,25 +1890,34 @@ describe('TUI', function() it('resize at startup #17285 #15044 #11330', function() local screen = Screen.new(50, 10) screen:set_default_attr_ids({ - [1] = {reverse = true}, - [2] = {bold = true, foreground = Screen.colors.Blue}, - [3] = {bold = true}, - [4] = {foreground = tonumber('0x4040ff'), fg_indexed = true}, - [5] = {bold = true, reverse = true}, + [1] = { reverse = true }, + [2] = { bold = true, foreground = Screen.colors.Blue }, + [3] = { bold = true }, + [4] = { foreground = tonumber('0x4040ff'), fg_indexed = true }, + [5] = { bold = true, reverse = true }, }) screen:attach() + fn.termopen({ + nvim_prog, + '--clean', + '--cmd', + 'colorscheme vim', + '--cmd', + 'set notermguicolors', + '--cmd', + 'let start = reltime() | while v:true | if reltimefloat(reltime(start)) > 2 | break | endif | endwhile', + }, { + env = { + VIMRUNTIME = os.getenv('VIMRUNTIME'), + }, + }) exec([[ - call termopen([v:progpath, '--clean', '--cmd', 'let start = reltime() | while v:true | if reltimefloat(reltime(start)) > 2 | break | endif | endwhile']) sleep 500m vs new ]]) screen:expect([[ ^ │ | - {2:~ }│{4:~ }| - {2:~ }│{4:~ }| - {2:~ }│{4:~ }| - {2:~ }│{4:~ }| - {2:~ }│{4:~ }| + {2:~ }│{4:~ }|*5 {2:~ }│{5:[No Name] 0,0-1 All}| {2:~ }│ | {5:new }{1:{MATCH:<.*[/\]nvim }}| @@ -1849,43 +1930,53 @@ describe('TUI', function() pending('missing LuaJIT FFI') end local script_file = 'Xargv0.lua' - write_file(script_file, [=[ + write_file( + script_file, + [=[ local ffi = require('ffi') ffi.cdef([[int execl(const char *, const char *, ...);]]) - ffi.C.execl(vim.v.progpath, 'Xargv0nvim', '--clean') - ]=]) + ffi.C.execl(vim.v.progpath, 'Xargv0nvim', '--clean', nil) + ]=] + ) finally(function() os.remove(script_file) end) - local screen = thelpers.screen_setup(0, string.format([=[["%s", "--clean", "-l", "%s"]]=], - nvim_prog, script_file)) - screen:expect{grid=[[ + local screen = thelpers.setup_child_nvim({ '--clean', '-l', script_file }) + screen:expect { + grid = [[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| - {5:[No Name] 0,0-1 All}| + ~ |*3 + [No Name] 0,0-1 All| | {3:-- TERMINAL --} | - ]]} + ]], + } feed_data(':put =v:argv + [v:progname]\n') - screen:expect{grid=[[ + screen:expect { + grid = [[ Xargv0nvim | --embed | --clean | {1:X}argv0nvim | - {5:[No Name] [+] 5,1 Bot}| + [No Name] [+] 5,1 Bot| 4 more lines | {3:-- TERMINAL --} | - ]]} + ]], + } end) it('with non-tty (pipe) stdout/stderr', function() finally(function() os.remove('testF') end) - local screen = thelpers.screen_setup(0, '"'..nvim_prog - ..' -u NONE -i NONE --cmd \'set noswapfile noshowcmd noruler\' --cmd \'normal iabc\' > /dev/null 2>&1 && cat testF && rm testF"') + local screen = thelpers.screen_setup( + 0, + ('"%s" -u NONE -i NONE --cmd "set noswapfile noshowcmd noruler" --cmd "normal iabc" > /dev/null 2>&1 && cat testF && rm testF'):format( + nvim_prog + ), + nil, + { VIMRUNTIME = os.getenv('VIMRUNTIME') } + ) feed_data(':w testF\n:q\n') screen:expect([[ :w testF | @@ -1899,24 +1990,32 @@ describe('TUI', function() end) it('<C-h> #10134', function() - local screen = thelpers.screen_setup(0, '["'..nvim_prog - ..[[", "-u", "NONE", "-i", "NONE", "--cmd", "set noruler", "--cmd", ':nnoremap <C-h> :echomsg "\<C-h\>"<CR>']]..']') - screen:expect{grid=[[ + local screen = thelpers.setup_child_nvim({ + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + 'colorscheme vim', + '--cmd', + 'set noruler notermguicolors', + '--cmd', + ':nnoremap <C-h> :echomsg "\\<C-h\\>"<CR>', + }) + screen:expect { + grid = [[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| | {3:-- TERMINAL --} | - ]]} + ]], + } command([[call chansend(b:terminal_job_id, "\<C-h>")]]) screen:expect([[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| <C-h> | {3:-- TERMINAL --} | @@ -1924,19 +2023,31 @@ describe('TUI', function() end) it('draws line with many trailing spaces correctly #24955', function() - local screen = thelpers.screen_setup(0, '["'..nvim_prog..[[", "-u", "NONE", "-i", "NONE"]] - ..[[, "--cmd", "call setline(1, ['1st line' .. repeat(' ', 153), '2nd line'])"]]..']', 80) - screen:expect{grid=[[ + local screen = thelpers.setup_child_nvim({ + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + 'set notermguicolors', + '--cmd', + 'colorscheme vim', + '--cmd', + 'call setline(1, ["1st line" .. repeat(" ", 153), "2nd line"])', + }, { cols = 80 }) + screen:expect { + grid = [[ {1:1}st line | - | - | + |*2 2nd line | {5:[No Name] [+] 1,1 All}| | {3:-- TERMINAL --} | - ]]} + ]], + } feed_data('$') - screen:expect{grid=[[ + screen:expect { + grid = [[ 1st line | | {1: } | @@ -1944,41 +2055,93 @@ describe('TUI', function() {5:[No Name] [+] 1,161 All}| | {3:-- TERMINAL --} | - ]]} + ]], + } + end) + + it('no heap-buffer-overflow when changing &columns', function() + -- Set a different bg colour and change $TERM to something dumber so the `print_spaces()` + -- codepath in `clear_region()` is hit. + local screen = thelpers.setup_child_nvim({ + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + 'set notermguicolors | highlight Normal ctermbg=red', + '--cmd', + 'call setline(1, ["a"->repeat(&columns)])', + }, { env = { TERM = 'ansi' } }) + + screen:expect { + grid = [[ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + ~ |*3 + [No Name] [+] 1,1 All| + | + -- TERMINAL -- | + ]], + attr_ids = {}, + } + + feed_data(':set columns=12\n') + screen:expect { + grid = [[ + aaaaaaaaaaaa |*4 + < [+] 1,1 | + | + -- TERMINAL -- | + ]], + attr_ids = {}, + } + + -- Wider than TUI, so screen state will look weird. + -- Wait for the statusline to redraw to confirm that the TUI lives and ASAN is happy. + feed_data(':set columns=99|set stl=redrawn%m\n') + screen:expect({ any = 'redrawn%[%+%]' }) end) end) describe('TUI UIEnter/UILeave', function() it('fires exactly once, after VimEnter', function() clear() - local screen = thelpers.screen_setup(0, - '["'..nvim_prog..'", "-u", "NONE", "-i", "NONE"' - ..[[, "--cmd", "set noswapfile noshowcmd noruler"]] - ..[[, "--cmd", "let g:evs = []"]] - ..[[, "--cmd", "autocmd UIEnter * :call add(g:evs, 'UIEnter')"]] - ..[[, "--cmd", "autocmd UILeave * :call add(g:evs, 'UILeave')"]] - ..[[, "--cmd", "autocmd VimEnter * :call add(g:evs, 'VimEnter')"]] - ..']' - ) - screen:expect{grid=[[ + local screen = thelpers.setup_child_nvim({ + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + 'colorscheme vim', + '--cmd', + 'set noswapfile noshowcmd noruler notermguicolors', + '--cmd', + 'let g:evs = []', + '--cmd', + 'autocmd UIEnter * :call add(g:evs, "UIEnter")', + '--cmd', + 'autocmd UILeave * :call add(g:evs, "UILeave")', + '--cmd', + 'autocmd VimEnter * :call add(g:evs, "VimEnter")', + }) + screen:expect { + grid = [[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| | {3:-- TERMINAL --} | - ]]} - feed_data(":echo g:evs\n") - screen:expect{grid=[[ + ]], + } + feed_data(':echo g:evs\n') + screen:expect { + grid = [[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| ['VimEnter', 'UIEnter'] | {3:-- TERMINAL --} | - ]]} + ]], + } end) end) @@ -1989,25 +2152,36 @@ describe('TUI FocusGained/FocusLost', function() before_each(function() clear() local child_server = new_pipename() - screen = thelpers.screen_setup(0, - string.format( - [=[["%s", "--listen", "%s", "-u", "NONE", "-i", "NONE", "--cmd", "set noswapfile noshowcmd noruler"]]=], - nvim_prog, child_server)) + screen = thelpers.setup_child_nvim({ + '--listen', + child_server, + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + 'colorscheme vim', + '--cmd', + 'set noswapfile noshowcmd noruler notermguicolors background=dark', + }) + screen:expect([[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| | {3:-- TERMINAL --} | ]]) child_session = helpers.connect(child_server) - child_session:request('nvim_exec2', [[ + child_session:request( + 'nvim_exec2', + [[ autocmd FocusGained * echo 'gained' autocmd FocusLost * echo 'lost' - ]], {}) - feed_data("\034\016") -- CTRL-\ CTRL-N + ]], + {} + ) + feed_data('\034\016') -- CTRL-\ CTRL-N end) it('in normal-mode', function() @@ -2015,9 +2189,7 @@ describe('TUI FocusGained/FocusLost', function() feed_data('\027[I') screen:expect([[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| gained | {3:-- TERMINAL --} | @@ -2026,9 +2198,7 @@ describe('TUI FocusGained/FocusLost', function() feed_data('\027[O') screen:expect([[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| lost | {3:-- TERMINAL --} | @@ -2039,22 +2209,20 @@ describe('TUI FocusGained/FocusLost', function() it('in insert-mode', function() feed_data(':set noshowmode\r') feed_data('i') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| :set noshowmode | {3:-- TERMINAL --} | - ]]} + ]], + } retry(2, 3 * screen.timeout, function() feed_data('\027[I') screen:expect([[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| gained | {3:-- TERMINAL --} | @@ -2062,9 +2230,7 @@ describe('TUI FocusGained/FocusLost', function() feed_data('\027[O') screen:expect([[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| lost | {3:-- TERMINAL --} | @@ -2079,34 +2245,37 @@ describe('TUI FocusGained/FocusLost', function() feed_data('\027[I') screen:expect([[ | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| :{1: } | {3:-- TERMINAL --} | ]]) feed_data('\027[O') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| :{1: } | {3:-- TERMINAL --} | - ]], unchanged=true} + ]], + unchanged = true, + } end) it('in cmdline-mode', function() -- Set up autocmds that modify the buffer, instead of just calling :echo. -- This is how we can test handling of focus gained/lost during cmdline-mode. -- See commit: 5cc87d4dabd02167117be7a978b5c8faaa975419. - child_session:request('nvim_exec2', [[ + child_session:request( + 'nvim_exec2', + [[ autocmd! autocmd FocusLost * call append(line('$'), 'lost') autocmd FocusGained * call append(line('$'), 'gained') - ]], {}) + ]], + {} + ) retry(2, 3 * screen.timeout, function() -- Enter cmdline-mode. feed_data(':') @@ -2118,44 +2287,46 @@ describe('TUI FocusGained/FocusLost', function() -- Exit cmdline-mode. Redraws from timers/events are blocked during -- cmdline-mode, so the buffer won't be updated until we exit cmdline-mode. feed_data('\n') - screen:expect{any='lost'..(' '):rep(46)..'|\ngained'} + screen:expect { any = 'lost' .. (' '):rep(46) .. '|\ngained' } end) end) it('in terminal-mode', function() - feed_data(':set shell='..testprg('shell-test')..' shellcmdflag=EXE\n') + feed_data(':set shell=' .. testprg('shell-test') .. ' shellcmdflag=EXE\n') feed_data(':set noshowmode laststatus=0\n') feed_data(':terminal zia\n') -- Wait for terminal to be ready. - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:r}eady $ zia | | [Process exited 0] | - | - | + |*2 :terminal zia | {3:-- TERMINAL --} | - ]]} + ]], + } feed_data('\027[I') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:r}eady $ zia | | [Process exited 0] | - | - | + |*2 gained | {3:-- TERMINAL --} | - ]], timeout=(4 * screen.timeout)} + ]], + timeout = (4 * screen.timeout), + } feed_data('\027[O') screen:expect([[ {1:r}eady $ zia | | [Process exited 0] | - | - | + |*2 lost | {3:-- TERMINAL --} | ]]) @@ -2164,8 +2335,9 @@ describe('TUI FocusGained/FocusLost', function() it('in press-enter prompt', function() feed_data(":echom 'msg1'|echom 'msg2'|echom 'msg3'|echom 'msg4'|echom 'msg5'\n") -- Execute :messages to provoke the press-enter prompt. - feed_data(":messages\n") - screen:expect{grid=[[ + feed_data(':messages\n') + screen:expect { + grid = [[ msg1 | msg2 | msg3 | @@ -2173,10 +2345,12 @@ describe('TUI FocusGained/FocusLost', function() msg5 | {10:Press ENTER or type command to continue}{1: } | {3:-- TERMINAL --} | - ]]} + ]], + } feed_data('\027[I') feed_data('\027[I') - screen:expect{grid=[[ + screen:expect { + grid = [[ msg1 | msg2 | msg3 | @@ -2184,7 +2358,9 @@ describe('TUI FocusGained/FocusLost', function() msg5 | {10:Press ENTER or type command to continue}{1: } | {3:-- TERMINAL --} | - ]], unchanged=true} + ]], + unchanged = true, + } end) end) @@ -2194,97 +2370,108 @@ describe("TUI 't_Co' (terminal colors)", function() local screen local function assert_term_colors(term, colorterm, maxcolors) - clear({env={TERM=term}, args={}}) - -- This is ugly because :term/termopen() forces TERM=xterm-256color. - -- TODO: Revisit this after jobstart/termopen accept `env` dict. - screen = thelpers.screen_setup(0, string.format( - [=[['sh', '-c', 'LANG=C TERM=%s %s %s -u NONE -i NONE --cmd "%s"']]=], - term or "", - (colorterm ~= nil and "COLORTERM="..colorterm or ""), - nvim_prog, - nvim_set)) + clear({ env = { TERM = term }, args = {} }) + screen = thelpers.setup_child_nvim({ + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + 'colorscheme vim', + '--cmd', + nvim_set .. ' notermguicolors', + }, { + env = { + LANG = 'C', + TERM = term or '', + COLORTERM = colorterm or '', + }, + }) local tline - if maxcolors == 8 or maxcolors == 16 then - tline = "~ " + if maxcolors == 8 then + tline = '{9:~ }' + elseif maxcolors == 16 then + tline = '~ ' else - tline = "{4:~ }" + tline = '{4:~ }' end - screen:expect(string.format([[ + screen:expect(string.format( + [[ {1: } | - %s| - %s| - %s| - %s| + %s|*4 | {3:-- TERMINAL --} | - ]], tline, tline, tline, tline)) + ]], + tline + )) - feed_data(":echo &t_Co\n") - screen:expect(string.format([[ + feed_data(':echo &t_Co\n') + screen:expect(string.format( + [[ {1: } | - %s| - %s| - %s| - %s| + %s|*4 %-3s | {3:-- TERMINAL --} | - ]], tline, tline, tline, tline, tostring(maxcolors and maxcolors or ""))) + ]], + tline, + tostring(maxcolors and maxcolors or '') + )) end -- ansi and no terminal type at all: - it("no TERM uses 8 colors", function() + it('no TERM uses 8 colors', function() assert_term_colors(nil, nil, 8) end) - it("TERM=ansi no COLORTERM uses 8 colors", function() - assert_term_colors("ansi", nil, 8) + it('TERM=ansi no COLORTERM uses 8 colors', function() + assert_term_colors('ansi', nil, 8) end) - it("TERM=ansi with COLORTERM=anything-no-number uses 16 colors", function() - assert_term_colors("ansi", "yet-another-term", 16) + it('TERM=ansi with COLORTERM=anything-no-number uses 16 colors', function() + assert_term_colors('ansi', 'yet-another-term', 16) end) - it("unknown TERM COLORTERM with 256 in name uses 256 colors", function() - assert_term_colors("ansi", "yet-another-term-256color", 256) + it('unknown TERM COLORTERM with 256 in name uses 256 colors', function() + assert_term_colors('ansi', 'yet-another-term-256color', 256) end) - it("TERM=ansi-256color sets 256 colours", function() - assert_term_colors("ansi-256color", nil, 256) + it('TERM=ansi-256color sets 256 colours', function() + assert_term_colors('ansi-256color', nil, 256) end) -- Unknown terminal types: - it("unknown TERM no COLORTERM sets 8 colours", function() - assert_term_colors("yet-another-term", nil, 8) + it('unknown TERM no COLORTERM sets 8 colours', function() + assert_term_colors('yet-another-term', nil, 8) end) - it("unknown TERM with COLORTERM=anything-no-number uses 16 colors", function() - assert_term_colors("yet-another-term", "yet-another-term", 16) + it('unknown TERM with COLORTERM=anything-no-number uses 16 colors', function() + assert_term_colors('yet-another-term', 'yet-another-term', 16) end) - it("unknown TERM with 256 in name sets 256 colours", function() - assert_term_colors("yet-another-term-256color", nil, 256) + it('unknown TERM with 256 in name sets 256 colours', function() + assert_term_colors('yet-another-term-256color', nil, 256) end) - it("unknown TERM COLORTERM with 256 in name uses 256 colors", function() - assert_term_colors("yet-another-term", "yet-another-term-256color", 256) + it('unknown TERM COLORTERM with 256 in name uses 256 colors', function() + assert_term_colors('yet-another-term', 'yet-another-term-256color', 256) end) -- Linux kernel terminal emulator: - it("TERM=linux uses 256 colors", function() - assert_term_colors("linux", nil, 256) + it('TERM=linux uses 256 colors', function() + assert_term_colors('linux', nil, 256) end) - it("TERM=linux-16color uses 256 colors", function() - assert_term_colors("linux-16color", nil, 256) + it('TERM=linux-16color uses 256 colors', function() + assert_term_colors('linux-16color', nil, 256) end) - it("TERM=linux-256color uses 256 colors", function() - assert_term_colors("linux-256color", nil, 256) + it('TERM=linux-256color uses 256 colors', function() + assert_term_colors('linux-256color', nil, 256) end) -- screen: @@ -2293,28 +2480,28 @@ describe("TUI 't_Co' (terminal colors)", function() -- Linux and MacOS have a screen entry in external terminfo with 8 colours, -- which is raised to 16 by COLORTERM. - it("TERM=screen no COLORTERM uses 8/256 colors", function() + it('TERM=screen no COLORTERM uses 8/256 colors', function() if is_os('freebsd') then - assert_term_colors("screen", nil, 256) + assert_term_colors('screen', nil, 256) else - assert_term_colors("screen", nil, 8) + assert_term_colors('screen', nil, 8) end end) - it("TERM=screen COLORTERM=screen uses 16/256 colors", function() + it('TERM=screen COLORTERM=screen uses 16/256 colors', function() if is_os('freebsd') then - assert_term_colors("screen", "screen", 256) + assert_term_colors('screen', 'screen', 256) else - assert_term_colors("screen", "screen", 16) + assert_term_colors('screen', 'screen', 16) end end) - it("TERM=screen COLORTERM=screen-256color uses 256 colors", function() - assert_term_colors("screen", "screen-256color", 256) + it('TERM=screen COLORTERM=screen-256color uses 256 colors', function() + assert_term_colors('screen', 'screen-256color', 256) end) - it("TERM=screen-256color no COLORTERM uses 256 colors", function() - assert_term_colors("screen-256color", nil, 256) + it('TERM=screen-256color no COLORTERM uses 256 colors', function() + assert_term_colors('screen-256color', nil, 256) end) -- tmux: @@ -2323,38 +2510,38 @@ describe("TUI 't_Co' (terminal colors)", function() -- Linux has a tmux entry in external terminfo with 8 colours, -- which is raised to 256. - it("TERM=tmux no COLORTERM uses 256 colors", function() - assert_term_colors("tmux", nil, 256) + it('TERM=tmux no COLORTERM uses 256 colors', function() + assert_term_colors('tmux', nil, 256) end) - it("TERM=tmux COLORTERM=tmux uses 256 colors", function() - assert_term_colors("tmux", "tmux", 256) + it('TERM=tmux COLORTERM=tmux uses 256 colors', function() + assert_term_colors('tmux', 'tmux', 256) end) - it("TERM=tmux COLORTERM=tmux-256color uses 256 colors", function() - assert_term_colors("tmux", "tmux-256color", 256) + it('TERM=tmux COLORTERM=tmux-256color uses 256 colors', function() + assert_term_colors('tmux', 'tmux-256color', 256) end) - it("TERM=tmux-256color no COLORTERM uses 256 colors", function() - assert_term_colors("tmux-256color", nil, 256) + it('TERM=tmux-256color no COLORTERM uses 256 colors', function() + assert_term_colors('tmux-256color', nil, 256) end) -- xterm and imitators: - it("TERM=xterm uses 256 colors", function() - assert_term_colors("xterm", nil, 256) + it('TERM=xterm uses 256 colors', function() + assert_term_colors('xterm', nil, 256) end) - it("TERM=xterm COLORTERM=gnome-terminal uses 256 colors", function() - assert_term_colors("xterm", "gnome-terminal", 256) + it('TERM=xterm COLORTERM=gnome-terminal uses 256 colors', function() + assert_term_colors('xterm', 'gnome-terminal', 256) end) - it("TERM=xterm COLORTERM=mate-terminal uses 256 colors", function() - assert_term_colors("xterm", "mate-terminal", 256) + it('TERM=xterm COLORTERM=mate-terminal uses 256 colors', function() + assert_term_colors('xterm', 'mate-terminal', 256) end) - it("TERM=xterm-256color uses 256 colors", function() - assert_term_colors("xterm-256color", nil, 256) + it('TERM=xterm-256color uses 256 colors', function() + assert_term_colors('xterm-256color', nil, 256) end) -- rxvt and stterm: @@ -2364,44 +2551,44 @@ describe("TUI 't_Co' (terminal colors)", function() -- Linux has an rxvt, an st, and an st-16color entry in external terminfo -- with 8, 8, and 16 colours respectively, which are raised to 256. - it("TERM=rxvt no COLORTERM uses 256 colors", function() - assert_term_colors("rxvt", nil, 256) + it('TERM=rxvt no COLORTERM uses 256 colors', function() + assert_term_colors('rxvt', nil, 256) end) - it("TERM=rxvt COLORTERM=rxvt uses 256 colors", function() - assert_term_colors("rxvt", "rxvt", 256) + it('TERM=rxvt COLORTERM=rxvt uses 256 colors', function() + assert_term_colors('rxvt', 'rxvt', 256) end) - it("TERM=rxvt-256color uses 256 colors", function() - assert_term_colors("rxvt-256color", nil, 256) + it('TERM=rxvt-256color uses 256 colors', function() + assert_term_colors('rxvt-256color', nil, 256) end) - it("TERM=st no COLORTERM uses 256 colors", function() - assert_term_colors("st", nil, 256) + it('TERM=st no COLORTERM uses 256 colors', function() + assert_term_colors('st', nil, 256) end) - it("TERM=st COLORTERM=st uses 256 colors", function() - assert_term_colors("st", "st", 256) + it('TERM=st COLORTERM=st uses 256 colors', function() + assert_term_colors('st', 'st', 256) end) - it("TERM=st COLORTERM=st-256color uses 256 colors", function() - assert_term_colors("st", "st-256color", 256) + it('TERM=st COLORTERM=st-256color uses 256 colors', function() + assert_term_colors('st', 'st-256color', 256) end) - it("TERM=st-16color no COLORTERM uses 8/256 colors", function() - assert_term_colors("st", nil, 256) + it('TERM=st-16color no COLORTERM uses 8/256 colors', function() + assert_term_colors('st', nil, 256) end) - it("TERM=st-16color COLORTERM=st uses 16/256 colors", function() - assert_term_colors("st", "st", 256) + it('TERM=st-16color COLORTERM=st uses 16/256 colors', function() + assert_term_colors('st', 'st', 256) end) - it("TERM=st-16color COLORTERM=st-256color uses 256 colors", function() - assert_term_colors("st", "st-256color", 256) + it('TERM=st-16color COLORTERM=st-256color uses 256 colors', function() + assert_term_colors('st', 'st-256color', 256) end) - it("TERM=st-256color uses 256 colors", function() - assert_term_colors("st-256color", nil, 256) + it('TERM=st-256color uses 256 colors', function() + assert_term_colors('st-256color', nil, 256) end) -- gnome and vte: @@ -2411,54 +2598,53 @@ describe("TUI 't_Co' (terminal colors)", function() -- external terminfo with 8, 8, 256, and 256 colours respectively, which are -- raised to 256. - it("TERM=gnome no COLORTERM uses 256 colors", function() - assert_term_colors("gnome", nil, 256) + it('TERM=gnome no COLORTERM uses 256 colors', function() + assert_term_colors('gnome', nil, 256) end) - it("TERM=gnome COLORTERM=gnome uses 256 colors", function() - assert_term_colors("gnome", "gnome", 256) + it('TERM=gnome COLORTERM=gnome uses 256 colors', function() + assert_term_colors('gnome', 'gnome', 256) end) - it("TERM=gnome COLORTERM=gnome-256color uses 256 colors", function() - assert_term_colors("gnome", "gnome-256color", 256) + it('TERM=gnome COLORTERM=gnome-256color uses 256 colors', function() + assert_term_colors('gnome', 'gnome-256color', 256) end) - it("TERM=gnome-256color uses 256 colors", function() - assert_term_colors("gnome-256color", nil, 256) + it('TERM=gnome-256color uses 256 colors', function() + assert_term_colors('gnome-256color', nil, 256) end) - it("TERM=vte no COLORTERM uses 256 colors", function() - assert_term_colors("vte", nil, 256) + it('TERM=vte no COLORTERM uses 256 colors', function() + assert_term_colors('vte', nil, 256) end) - it("TERM=vte COLORTERM=vte uses 256 colors", function() - assert_term_colors("vte", "vte", 256) + it('TERM=vte COLORTERM=vte uses 256 colors', function() + assert_term_colors('vte', 'vte', 256) end) - it("TERM=vte COLORTERM=vte-256color uses 256 colors", function() - assert_term_colors("vte", "vte-256color", 256) + it('TERM=vte COLORTERM=vte-256color uses 256 colors', function() + assert_term_colors('vte', 'vte-256color', 256) end) - it("TERM=vte-256color uses 256 colors", function() - assert_term_colors("vte-256color", nil, 256) + it('TERM=vte-256color uses 256 colors', function() + assert_term_colors('vte-256color', nil, 256) end) -- others: -- TODO(blueyed): this is made pending, since it causes failure + later hang -- when using non-compatible libvterm (#9494/#10179). - pending("TERM=interix uses 8 colors", function() - assert_term_colors("interix", nil, 8) + pending('TERM=interix uses 8 colors', function() + assert_term_colors('interix', nil, 8) end) - it("TERM=iTerm.app uses 256 colors", function() - assert_term_colors("iTerm.app", nil, 256) + it('TERM=iTerm.app uses 256 colors', function() + assert_term_colors('iTerm.app', nil, 256) end) - it("TERM=iterm uses 256 colors", function() - assert_term_colors("iterm", nil, 256) + it('TERM=iterm uses 256 colors', function() + assert_term_colors('iterm', nil, 256) end) - end) -- These tests require `thelpers` because --headless/--embed @@ -2468,39 +2654,43 @@ describe("TUI 'term' option", function() local function assert_term(term_envvar, term_expected) clear() - -- This is ugly because :term/termopen() forces TERM=xterm-256color. - -- TODO: Revisit this after jobstart/termopen accept `env` dict. - local cmd = string.format( - [=[['sh', '-c', 'LANG=C TERM=%s %s -u NONE -i NONE --cmd "%s"']]=], - term_envvar or "", - nvim_prog, - nvim_set) - screen = thelpers.screen_setup(0, cmd) + screen = thelpers.setup_child_nvim({ + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + nvim_set .. ' notermguicolors', + }, { + env = { + LANG = 'C', + TERM = term_envvar or '', + }, + }) local full_timeout = screen.timeout - screen.timeout = 250 -- We want screen:expect() to fail quickly. - retry(nil, 2 * full_timeout, function() -- Wait for TUI thread to set 'term'. + retry(nil, 2 * full_timeout, function() -- Wait for TUI thread to set 'term'. feed_data(":echo 'term='.(&term)\n") - screen:expect{any='term='..term_expected} + screen:expect { any = 'term=' .. term_expected, timeout = 250 } end) end it('gets builtin term if $TERM is invalid', function() - assert_term("foo", "builtin_ansi") + assert_term('foo', 'builtin_ansi') end) it('gets system-provided term if $TERM is valid', function() if is_os('openbsd') then - assert_term("xterm", "xterm") - elseif is_os('bsd') then -- BSD lacks terminfo, builtin is always used. - assert_term("xterm", "builtin_xterm") + assert_term('xterm', 'xterm') + elseif is_os('bsd') then -- BSD lacks terminfo, builtin is always used. + assert_term('xterm', 'builtin_xterm') elseif is_os('mac') then - local status, _ = pcall(assert_term, "xterm", "xterm") + local status, _ = pcall(assert_term, 'xterm', 'xterm') if not status then - pending("macOS: unibilium could not find terminfo") + pending('macOS: unibilium could not find terminfo') end else - assert_term("xterm", "xterm") + assert_term('xterm', 'xterm') end end) @@ -2510,12 +2700,11 @@ describe("TUI 'term' option", function() assert_term('conemu', 'builtin_conemu') assert_term('vtpcon', 'builtin_vtpcon') end) - end) -- These tests require `thelpers` because --headless/--embed -- does not initialize the TUI. -describe("TUI", function() +describe('TUI', function() local screen local logfile = 'Xtest_tui_verbose_log' after_each(function() @@ -2525,284 +2714,398 @@ describe("TUI", function() -- Runs (child) `nvim` in a TTY (:terminal), to start the builtin TUI. local function nvim_tui(extra_args) clear() - -- This is ugly because :term/termopen() forces TERM=xterm-256color. - -- TODO: Revisit this after jobstart/termopen accept `env` dict. - local cmd = string.format( - [=[['sh', '-c', 'LANG=C %s -u NONE -i NONE %s --cmd "%s"']]=], - nvim_prog, - extra_args or "", - nvim_set) - screen = thelpers.screen_setup(0, cmd) + screen = thelpers.setup_child_nvim({ + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + 'colorscheme vim', + '--cmd', + nvim_set .. ' notermguicolors', + extra_args, + }, { + env = { + LANG = 'C', + }, + }) end it('-V3log logs terminfo values', function() - nvim_tui('-V3'..logfile) + nvim_tui('-V3' .. logfile) -- Wait for TUI to start. feed_data('Gitext') screen:expect([[ text{1: } | - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*4 {3:-- INSERT --} | {3:-- TERMINAL --} | ]]) - retry(nil, 3000, function() -- Wait for log file to be flushed. + retry(nil, 3000, function() -- Wait for log file to be flushed. local log = read_file('Xtest_tui_verbose_log') or '' eq('--- Terminal info --- {{{\n', string.match(log, '%-%-%- Terminal.-\n')) -- }}} ok(#log > 50) end) end) -end) - --- See test/unit/tui_spec.lua for unit tests. -describe('TUI bg color', function() - local screen - - local function setup_bg_test() - clear() - screen = thelpers.screen_setup(0, '["'..nvim_prog - ..'", "-u", "NONE", "-i", "NONE", "--cmd", "set noswapfile", ' - ..'"-c", "autocmd OptionSet background echo \\"did OptionSet, yay!\\""]') - end - - before_each(setup_bg_test) + it('does not crash on large inputs #26099', function() + nvim_tui() - it('triggers OptionSet event on unsplit terminal-response', function() screen:expect([[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| - {5:[No Name] 0,0-1 All}| + {4:~ }|*4 | {3:-- TERMINAL --} | ]]) - feed_data('\027]11;rgb:ffff/ffff/ffff\027\\') - screen:expect{any='did OptionSet, yay!'} - feed_data(':echo "new_bg=".&background\n') - screen:expect{any='new_bg=light'} + feed_data(string.format('\027]52;c;%s\027\\', string.rep('A', 8192))) - setup_bg_test() - screen:expect([[ + screen:expect { + grid = [[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| - {5:[No Name] 0,0-1 All}| + {4:~ }|*4 | {3:-- TERMINAL --} | + ]], + unchanged = true, + } + end) + + it('queries the terminal for truecolor support', function() + clear() + exec_lua([[ + vim.api.nvim_create_autocmd('TermRequest', { + callback = function(args) + local req = args.data + local payload = req:match('^\027P%+q([%x;]+)$') + if payload then + local t = {} + for cap in vim.gsplit(payload, ';') do + local resp = string.format('\027P1+r%s\027\\', payload) + vim.api.nvim_chan_send(vim.bo[args.buf].channel, resp) + t[vim.text.hexdecode(cap)] = true + end + vim.g.xtgettcap = t + return true + end + end, + }) ]]) - feed_data('\027]11;rgba:ffff/ffff/ffff/8000\027\\') - screen:expect{any='did OptionSet, yay!'} - feed_data(':echo "new_bg=".&background\n') - screen:expect{any='new_bg=light'} + local child_server = new_pipename() + screen = thelpers.setup_child_nvim({ + '--listen', + child_server, + '-u', + 'NONE', + '-i', + 'NONE', + }, { + env = { + VIMRUNTIME = os.getenv('VIMRUNTIME'), + + -- Force COLORTERM to be unset and use a TERM that does not contain Tc or RGB in terminfo. + -- This will force the nested nvim instance to query with XTGETTCAP + COLORTERM = '', + TERM = 'xterm-256colors', + }, + }) + + screen:expect({ any = '%[No Name%]' }) + + local child_session = helpers.connect(child_server) + retry(nil, 1000, function() + eq({ + Tc = true, + RGB = true, + setrgbf = true, + setrgbb = true, + }, eval("get(g:, 'xtgettcap', '')")) + eq({ true, 1 }, { child_session:request('nvim_eval', '&termguicolors') }) + end) end) - it('triggers OptionSet event with split terminal-response', function() - screen:expect([[ - {1: } | - {4:~ }| - {4:~ }| - {4:~ }| - {5:[No Name] 0,0-1 All}| - | - {3:-- TERMINAL --} | + it('queries the terminal for OSC 52 support', function() + clear() + exec_lua([[ + vim.api.nvim_create_autocmd('TermRequest', { + callback = function(args) + local req = args.data + local payload = req:match('^\027P%+q([%x;]+)$') + if payload and vim.text.hexdecode(payload) == 'Ms' then + vim.g.xtgettcap = 'Ms' + local resp = string.format('\027P1+r%s=%s\027\\', payload, vim.text.hexencode('\027]52;;\027\\')) + vim.api.nvim_chan_send(vim.bo[args.buf].channel, resp) + return true + end + end, + }) ]]) - -- Send a background response with the OSC command part split. - feed_data('\027]11;rgb') - feed_data(':ffff/ffff/ffff\027\\') - screen:expect{any='did OptionSet, yay!'} - feed_data(':echo "new_bg=".&background\n') - screen:expect{any='new_bg=light'} + local child_server = new_pipename() + screen = thelpers.setup_child_nvim({ + '--listen', + child_server, + -- Use --clean instead of -u NONE to load the osc52 plugin + '--clean', + }, { + env = { + VIMRUNTIME = os.getenv('VIMRUNTIME'), + + -- Only queries when SSH_TTY is set + SSH_TTY = '/dev/pts/1', + }, + }) - setup_bg_test() - screen:expect([[ - {1: } | - {4:~ }| - {4:~ }| - {4:~ }| - {5:[No Name] 0,0-1 All}| - | - {3:-- TERMINAL --} | - ]]) - -- Send a background response with the Pt portion split. - feed_data('\027]11;rgba:ffff/fff') - feed_data('f/ffff/8000\027\\') - screen:expect{any='did OptionSet, yay!'} + screen:expect({ any = '%[No Name%]' }) - feed_data(':echo "new_bg=".&background\n') - screen:expect{any='new_bg=light'} + local child_session = helpers.connect(child_server) + retry(nil, 1000, function() + eq('Ms', eval("get(g:, 'xtgettcap', '')")) + eq({ true, 'OSC 52' }, { child_session:request('nvim_eval', 'g:clipboard.name') }) + end) end) +end) - it('not triggers OptionSet event with invalid terminal-response', function() - screen:expect([[ - {1: } | - {4:~ }| - {4:~ }| - {4:~ }| - {5:[No Name] 0,0-1 All}| - | - {3:-- TERMINAL --} | - ]]) - feed_data('\027]11;rgb:ffff/ffff/ffff/8000\027\\') - screen:expect_unchanged() +describe('TUI bg color', function() + before_each(clear) + + it('is properly set in a nested Nvim instance when background=dark', function() + command('highlight clear Normal') + command('set background=dark') -- set outer Nvim background + local child_server = new_pipename() + local screen = thelpers.setup_child_nvim({ + '--listen', + child_server, + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + 'colorscheme vim', + '--cmd', + 'set noswapfile', + }) + screen:expect({ any = '%[No Name%]' }) + local child_session = helpers.connect(child_server) + retry(nil, nil, function() + eq({ true, 'dark' }, { child_session:request('nvim_eval', '&background') }) + end) + end) - feed_data(':echo "new_bg=".&background\n') - screen:expect{any='new_bg=dark'} + it('is properly set in a nested Nvim instance when background=light', function() + command('highlight clear Normal') + command('set background=light') -- set outer Nvim background + local child_server = new_pipename() + local screen = thelpers.setup_child_nvim({ + '--listen', + child_server, + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + 'colorscheme vim', + '--cmd', + 'set noswapfile', + }) + screen:expect({ any = '%[No Name%]' }) + local child_session = helpers.connect(child_server) + retry(nil, nil, function() + eq({ true, 'light' }, { child_session:request('nvim_eval', '&background') }) + end) + end) + + it('queries the terminal for background color', function() + exec_lua([[ + vim.api.nvim_create_autocmd('TermRequest', { + callback = function(args) + local req = args.data + if req == '\027]11;?' then + vim.g.oscrequest = true + return true + end + end, + }) + ]]) + thelpers.setup_child_nvim({ + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + 'colorscheme vim', + '--cmd', + 'set noswapfile', + }) + retry(nil, 1000, function() + eq(true, eval("get(g:, 'oscrequest', v:false)")) + end) + end) - setup_bg_test() + it('triggers OptionSet from automatic background processing', function() + local screen = thelpers.setup_child_nvim({ + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + 'colorscheme vim', + '--cmd', + 'set noswapfile', + '-c', + 'autocmd OptionSet background echo "did OptionSet, yay!"', + }) screen:expect([[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {3:~} |*3 {5:[No Name] 0,0-1 All}| - | + did OptionSet, yay! | {3:-- TERMINAL --} | ]]) - feed_data('\027]11;rgba:ffff/foo/ffff/8000\027\\') - screen:expect_unchanged() - - feed_data(':echo "new_bg=".&background\n') - screen:expect{any='new_bg=dark'} end) end) -- These tests require `thelpers` because --headless/--embed -- does not initialize the TUI. -describe("TUI as a client", function() - - it("connects to remote instance (with its own TUI)", function() +describe('TUI as a client', function() + it('connects to remote instance (with its own TUI)', function() local server_super = spawn_argv(false) -- equivalent to clear() local client_super = spawn_argv(true) set_session(server_super) local server_pipe = new_pipename() - local screen_server = thelpers.screen_setup(0, - string.format([=[["%s", "--listen", "%s", "-u", "NONE", "-i", "NONE", "--cmd", "%s laststatus=2 background=dark"]]=], - nvim_prog, server_pipe, nvim_set)) + local screen_server = thelpers.setup_child_nvim({ + '--listen', + server_pipe, + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + 'colorscheme vim', + '--cmd', + nvim_set .. ' notermguicolors laststatus=2 background=dark', + }) - feed_data("iHello, World") - screen_server:expect{grid=[[ + feed_data('iHello, World') + screen_server:expect { + grid = [[ Hello, World{1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] [+] }| {3:-- INSERT --} | {3:-- TERMINAL --} | - ]]} - feed_data("\027") - screen_server:expect{grid=[[ + ]], + } + feed_data('\027') + screen_server:expect { + grid = [[ Hello, Worl{1:d} | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] [+] }| | {3:-- TERMINAL --} | - ]]} + ]], + } set_session(client_super) - local screen_client = thelpers.screen_setup(0, - string.format([=[["%s", "--server", "%s", "--remote-ui"]]=], - nvim_prog, server_pipe)) + local screen_client = thelpers.setup_child_nvim({ + '--server', + server_pipe, + '--remote-ui', + }) - screen_client:expect{grid=[[ + screen_client:expect { + grid = [[ Hello, Worl{1:d} | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] [+] }| | {3:-- TERMINAL --} | - ]]} + ]], + } -- grid smaller than containing terminal window is cleared properly feed_data(":call setline(1,['a'->repeat(&columns)]->repeat(&lines))\n") - feed_data("0:set lines=3\n") - screen_server:expect{grid=[[ + feed_data('0:set lines=3\n') + screen_server:expect { + grid = [[ {1:a}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| {5:[No Name] [+] }| - | - | - | - | + |*4 {3:-- TERMINAL --} | - ]]} + ]], + } - feed_data(":q!\n") + feed_data(':q!\n') server_super:close() client_super:close() end) - it("connects to remote instance (--headless)", function() + it('connects to remote instance (--headless)', function() local server = spawn_argv(false) -- equivalent to clear() local client_super = spawn_argv(true) set_session(server) - local server_pipe = meths.get_vvar('servername') + local server_pipe = api.nvim_get_vvar('servername') server:request('nvim_input', 'iHalloj!<Esc>') + server:request('nvim_command', 'set notermguicolors') set_session(client_super) - local screen_client = thelpers.screen_setup(0, - string.format([=[["%s", "--server", "%s", "--remote-ui"]]=], - nvim_prog, server_pipe)) + local screen_client = thelpers.setup_child_nvim({ + '--server', + server_pipe, + '--remote-ui', + }) - screen_client:expect{grid=[[ + screen_client:expect { + grid = [[ Halloj{1:!} | - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*4 | {3:-- TERMINAL --} | - ]]} + ]], + } -- No heap-use-after-free when receiving UI events after deadly signal #22184 server:request('nvim_input', ('a'):rep(1000)) exec_lua([[vim.uv.kill(vim.fn.jobpid(vim.bo.channel), 'sigterm')]]) - screen_client:expect{grid=[[ + screen_client:expect { + grid = [[ Vim: Caught deadly signal 'SIGTERM' | - | - | + |*2 [Process exited 1]{1: } | - | - | + |*2 {3:-- TERMINAL --} | - ]]} + ]], + } - eq(0, meths.get_vvar('shell_error')) + eq(0, api.nvim_get_vvar('shell_error')) -- exits on input eof #22244 - funcs.system({nvim_prog, '--server', server_pipe, '--remote-ui'}) - eq(1, meths.get_vvar('shell_error')) + fn.system({ nvim_prog, '--server', server_pipe, '--remote-ui' }) + eq(1, api.nvim_get_vvar('shell_error')) client_super:close() server:close() end) - it("throws error when no server exists", function() + it('throws error when no server exists', function() clear() - local screen = thelpers.screen_setup(0, - string.format([=[["%s", "--server", "127.0.0.1:2436546", "--remote-ui"]]=], - nvim_prog), 60) + local screen = thelpers.setup_child_nvim({ + '--server', + '127.0.0.1:2436546', + '--remote-ui', + }, { cols = 60 }) screen:expect([[ Remote ui failed to start: {MATCH:.*}| | [Process exited 1]{1: } | - | - | - | + |*3 {3:-- TERMINAL --} | ]]) end) @@ -2813,89 +3116,98 @@ describe("TUI as a client", function() set_session(server_super) local server_pipe = new_pipename() - local screen_server = thelpers.screen_setup(0, - string.format([=[["%s", "--listen", "%s", "-u", "NONE", "-i", "NONE", "--cmd", "%s laststatus=2 background=dark"]]=], - nvim_prog, server_pipe, nvim_set)) - screen_server:expect{grid=[[ + local screen_server = thelpers.setup_child_nvim({ + '--listen', + server_pipe, + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + 'colorscheme vim', + '--cmd', + nvim_set .. ' notermguicolors laststatus=2 background=dark', + }) + screen_server:expect { + grid = [[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] }| | {3:-- TERMINAL --} | - ]]} + ]], + } - feed_data("iHello, World") - screen_server:expect{grid=[[ + feed_data('iHello, World') + screen_server:expect { + grid = [[ Hello, World{1: } | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] [+] }| {3:-- INSERT --} | {3:-- TERMINAL --} | - ]]} - feed_data("\027") - screen_server:expect{grid=[[ + ]], + } + feed_data('\027') + screen_server:expect { + grid = [[ Hello, Worl{1:d} | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] [+] }| | {3:-- TERMINAL --} | - ]]} + ]], + } set_session(client_super) - local screen_client = thelpers.screen_setup(0, - string.format([=[["%s", "--server", "%s", "--remote-ui"]]=], - nvim_prog, server_pipe)) + local screen_client = thelpers.setup_child_nvim({ + '--server', + server_pipe, + '--remote-ui', + }) - screen_client:expect{grid=[[ + screen_client:expect { + grid = [[ Hello, Worl{1:d} | - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*3 {5:[No Name] [+] }| | {3:-- TERMINAL --} | - ]]} + ]], + } -- quitting the server set_session(server_super) - feed_data(status and ':' .. status .. 'cquit!\n' or ":quit!\n") + feed_data(status and ':' .. status .. 'cquit!\n' or ':quit!\n') status = status and status or 0 - screen_server:expect{grid=[[ + screen_server:expect { + grid = [[ | [Process exited ]] .. status .. [[]{1: }{MATCH:%s+}| - | - | - | - | + |*4 {3:-- TERMINAL --} | - ]]} + ]], + } -- assert that client has exited - screen_client:expect{grid=[[ + screen_client:expect { + grid = [[ | [Process exited ]] .. status .. [[]{1: }{MATCH:%s+}| - | - | - | - | + |*4 {3:-- TERMINAL --} | - ]]} + ]], + } server_super:close() client_super:close() end - describe("exits when server quits", function() - it("with :quit", function() + describe('exits when server quits', function() + it('with :quit', function() test_remote_tui_quit() end) - it("with :cquit", function() + it('with :cquit', function() test_remote_tui_quit(42) end) end) diff --git a/test/functional/terminal/window_spec.lua b/test/functional/terminal/window_spec.lua index 39fc2c2562..3781933cad 100644 --- a/test/functional/terminal/window_spec.lua +++ b/test/functional/terminal/window_spec.lua @@ -22,13 +22,15 @@ describe(':terminal window', function() skip(is_os('win')) -- Test has hardcoded assumptions of dimensions. eq(7, eval('&lines')) - feed_data('\n\n\n') -- Add blank lines. + feed_data('\n\n\n') -- Add blank lines. -- Terminal/shell contents must exceed the height of this window. command('topleft 1split') eq('terminal', eval('&buftype')) feed([[i<cr>]]) -- Check topline _while_ in terminal-mode. - retry(nil, nil, function() eq(6, eval('winsaveview()["topline"]')) end) + retry(nil, nil, function() + eq(6, eval('winsaveview()["topline"]')) + end) end) describe("with 'number'", function() @@ -121,11 +123,7 @@ describe(':terminal window', function() screen:expect([[ tty ready | {2:^ } | - | - | - | - | - | + |*5 ]]) feed(':set colorcolumn=20<CR>i') end) @@ -134,10 +132,7 @@ describe(':terminal window', function() screen:expect([[ tty ready | {1: } | - | - | - | - | + |*4 {3:-- TERMINAL --} | ]]) end) @@ -146,7 +141,7 @@ describe(':terminal window', function() describe('with fold set', function() before_each(function() feed([[<C-\><C-N>:set foldenable foldmethod=manual<CR>i]]) - feed_data({'line1', 'line2', 'line3', 'line4', ''}) + feed_data({ 'line1', 'line2', 'line3', 'line4', '' }) screen:expect([[ tty ready | line1 | @@ -179,54 +174,35 @@ describe(':terminal with multigrid', function() before_each(function() clear() - screen = thelpers.screen_setup(0,nil,50,{ext_multigrid=true}) + screen = thelpers.screen_setup(0, nil, 50, nil, { ext_multigrid = true }) end) it('resizes to requested size', function() screen:expect([[ ## grid 1 - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| + [2:--------------------------------------------------]|*6 [3:--------------------------------------------------]| ## grid 2 tty ready | {1: } | - | - | - | - | + |*4 ## grid 3 {3:-- TERMINAL --} | ]]) screen:try_resize_grid(2, 20, 10) if is_os('win') then - screen:expect{any="rows: 10, cols: 20"} + screen:expect { any = 'rows: 10, cols: 20' } else screen:expect([[ ## grid 1 - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| + [2:--------------------------------------------------]|*6 [3:--------------------------------------------------]| ## grid 2 tty ready | rows: 10, cols: 20 | {1: } | - | - | - | - | - | - | - | + |*7 ## grid 3 {3:-- TERMINAL --} | ]]) @@ -234,16 +210,11 @@ describe(':terminal with multigrid', function() screen:try_resize_grid(2, 70, 3) if is_os('win') then - screen:expect{any="rows: 3, cols: 70"} + screen:expect { any = 'rows: 3, cols: 70' } else screen:expect([[ ## grid 1 - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| + [2:--------------------------------------------------]|*6 [3:--------------------------------------------------]| ## grid 2 rows: 10, cols: 20 | @@ -256,16 +227,11 @@ describe(':terminal with multigrid', function() screen:try_resize_grid(2, 0, 0) if is_os('win') then - screen:expect{any="rows: 6, cols: 50"} + screen:expect { any = 'rows: 6, cols: 50' } else screen:expect([[ ## grid 1 - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| + [2:--------------------------------------------------]|*6 [3:--------------------------------------------------]| ## grid 2 tty ready | diff --git a/test/functional/terminal/window_split_tab_spec.lua b/test/functional/terminal/window_split_tab_spec.lua index da14531fa2..17411e2724 100644 --- a/test/functional/terminal/window_split_tab_spec.lua +++ b/test/functional/terminal/window_split_tab_spec.lua @@ -7,8 +7,8 @@ local feed_command = helpers.feed_command local command = helpers.command local eq = helpers.eq local eval = helpers.eval -local meths = helpers.meths -local sleep = helpers.sleep +local api = helpers.api +local sleep = vim.uv.sleep local retry = helpers.retry local is_os = helpers.is_os @@ -19,7 +19,7 @@ describe(':terminal', function() clear() -- set the statusline to a constant value because of variables like pid -- and current directory and to improve visibility of splits - meths.set_option_value('statusline', '==========', {}) + api.nvim_set_option_value('statusline', '==========', {}) command('highlight StatusLine cterm=NONE') command('highlight StatusLineNC cterm=NONE') command('highlight VertSplit cterm=NONE') @@ -35,7 +35,7 @@ describe(':terminal', function() command('terminal') command('vsplit foo') eq(3, eval("winnr('$')")) - feed('ZQ') -- Close split, should not crash. #7538 + feed('ZQ') -- Close split, should not crash. #7538 assert_alive() end) @@ -50,8 +50,7 @@ describe(':terminal', function() tty ready | rows: 5, cols: 50 | {2: } | - | - | + |*2 ========== | :2split | ]]) @@ -63,31 +62,23 @@ describe(':terminal', function() ^tty ready | rows: 5, cols: 50 | {2: } | - | - | + |*2 ========== | :wincmd p | ]]) end) it('does not change size if updated when not visible in any window #19665', function() - local channel = meths.get_option_value('channel', {}) + local channel = api.nvim_get_option_value('channel', {}) command('enew') sleep(100) - meths.chan_send(channel, 'foo') + api.nvim_chan_send(channel, 'foo') sleep(100) command('bprevious') screen:expect([[ tty ready | ^foo{2: } | - | - | - | - | - | - | - | - | + |*8 ]]) end) @@ -100,9 +91,9 @@ describe(':terminal', function() -- win: SIGWINCH is unreliable, use a weaker test. #7506 retry(3, 30000, function() screen:try_resize(w1, h1) - screen:expect{any='rows: 7, cols: 47'} + screen:expect { any = 'rows: 7, cols: 47' } screen:try_resize(w2, h2) - screen:expect{any='rows: 4, cols: 41'} + screen:expect { any = 'rows: 4, cols: 41' } end) return end @@ -112,9 +103,7 @@ describe(':terminal', function() tty ready | rows: 7, cols: 47 | {2: } | - | - | - | + |*3 ^ | | ]]) @@ -133,8 +122,7 @@ describe(':terminal', function() command('split') command('terminal') feed('a<Cmd>wincmd j<CR>') - eq(2, eval("winnr()")) + eq(2, eval('winnr()')) eq('t', eval('mode(1)')) end) - end) diff --git a/test/functional/treesitter/fold_spec.lua b/test/functional/treesitter/fold_spec.lua index a8abbc002b..9428432f66 100644 --- a/test/functional/treesitter/fold_spec.lua +++ b/test/functional/treesitter/fold_spec.lua @@ -5,6 +5,7 @@ local insert = helpers.insert local exec_lua = helpers.exec_lua local command = helpers.command local feed = helpers.feed +local poke_eventloop = helpers.poke_eventloop local Screen = require('test.functional.ui.screen') before_each(clear) @@ -12,6 +13,11 @@ before_each(clear) describe('treesitter foldexpr', function() clear() + before_each(function() + -- open folds to avoid deleting entire folded region + exec_lua([[vim.opt.foldlevel = 9]]) + end) + local test_text = [[ void ui_refresh(void) { @@ -33,6 +39,12 @@ void ui_refresh(void) } }]] + local function parse(lang) + exec_lua( + ([[vim.treesitter.get_parser(0, %s):parse()]]):format(lang and '"' .. lang .. '"' or 'nil') + ) + end + local function get_fold_levels() return exec_lua([[ local res = {} @@ -43,10 +55,10 @@ void ui_refresh(void) ]]) end - it("can compute fold levels", function() + it('can compute fold levels', function() insert(test_text) - exec_lua([[vim.treesitter.get_parser(0, "c")]]) + parse('c') eq({ [1] = '>1', @@ -67,16 +79,17 @@ void ui_refresh(void) [16] = '3', [17] = '3', [18] = '2', - [19] = '1' }, get_fold_levels()) - + [19] = '1', + }, get_fold_levels()) end) - it("recomputes fold levels after lines are added/removed", function() + it('recomputes fold levels after lines are added/removed', function() insert(test_text) - exec_lua([[vim.treesitter.get_parser(0, "c")]]) + parse('c') command('1,2d') + poke_eventloop() eq({ [1] = '0', @@ -95,9 +108,11 @@ void ui_refresh(void) [14] = '2', [15] = '2', [16] = '1', - [17] = '0' }, get_fold_levels()) + [17] = '0', + }, get_fold_levels()) command('1put!') + poke_eventloop() eq({ [1] = '>1', @@ -118,26 +133,295 @@ void ui_refresh(void) [16] = '3', [17] = '3', [18] = '2', - [19] = '1' }, get_fold_levels()) + [19] = '1', + }, get_fold_levels()) + end) + + it('handles changes close to start/end of folds', function() + insert([[ +# h1 +t1 +# h2 +t2]]) + + exec_lua([[vim.treesitter.query.set('markdown', 'folds', '(section) @fold')]]) + parse('markdown') + + eq({ + [1] = '>1', + [2] = '1', + [3] = '>1', + [4] = '1', + }, get_fold_levels()) + + feed('2ggo<Esc>') + poke_eventloop() + + eq({ + [1] = '>1', + [2] = '1', + [3] = '1', + [4] = '>1', + [5] = '1', + }, get_fold_levels()) + + feed('dd') + poke_eventloop() + + eq({ + [1] = '>1', + [2] = '1', + [3] = '>1', + [4] = '1', + }, get_fold_levels()) + + feed('2ggdd') + poke_eventloop() + + eq({ + [1] = '0', + [2] = '>1', + [3] = '1', + }, get_fold_levels()) + + feed('u') + poke_eventloop() + + eq({ + [1] = '>1', + [2] = '1', + [3] = '>1', + [4] = '1', + }, get_fold_levels()) + + feed('3ggdd') + poke_eventloop() + + eq({ + [1] = '>1', + [2] = '1', + [3] = '1', + }, get_fold_levels()) + + feed('u') + poke_eventloop() + + eq({ + [1] = '>1', + [2] = '1', + [3] = '>1', + [4] = '1', + }, get_fold_levels()) + + feed('3ggI#<Esc>') + parse() + poke_eventloop() + + eq({ + [1] = '>1', + [2] = '1', + [3] = '>2', + [4] = '2', + }, get_fold_levels()) + + feed('x') + parse() + poke_eventloop() + + eq({ + [1] = '>1', + [2] = '1', + [3] = '>1', + [4] = '1', + }, get_fold_levels()) end) - it("updates folds in all windows", function() + it('handles changes that trigger multiple on_bytes', function() + insert([[ +function f() + asdf() + asdf() +end +-- comment]]) + + exec_lua( + [[vim.treesitter.query.set('lua', 'folds', '[(function_declaration) (parameters) (arguments)] @fold')]] + ) + parse('lua') + + eq({ + [1] = '>1', + [2] = '1', + [3] = '1', + [4] = '1', + [5] = '0', + }, get_fold_levels()) + + command('1,4join') + poke_eventloop() + + eq({ + [1] = '0', + [2] = '0', + }, get_fold_levels()) + + feed('u') + poke_eventloop() + + eq({ + [1] = '>1', + [2] = '1', + [3] = '1', + [4] = '1', + [5] = '0', + }, get_fold_levels()) + end) + + it('handles multiple folds that overlap at the end and start', function() + insert([[ +function f() + g( + function() + asdf() + end, function() + end + ) +end]]) + + exec_lua( + [[vim.treesitter.query.set('lua', 'folds', '[(function_declaration) (function_definition) (parameters) (arguments)] @fold')]] + ) + parse('lua') + + -- If fold1.stop = fold2.start, then move fold1's stop up so that fold2.start gets proper level. + eq({ + [1] = '>1', + [2] = '>2', + [3] = '>3', + [4] = '3', + [5] = '>3', + [6] = '3', + [7] = '2', + [8] = '1', + }, get_fold_levels()) + + command('1,8join') + feed('u') + poke_eventloop() + + eq({ + [1] = '>1', + [2] = '>2', + [3] = '>3', + [4] = '3', + [5] = '>3', + [6] = '3', + [7] = '2', + [8] = '1', + }, get_fold_levels()) + end) + + it('handles multiple folds that start at the same line', function() + insert([[ +function f(a) + if #(g({ + k = v, + })) > 0 then + return + end +end]]) + + exec_lua( + [[vim.treesitter.query.set('lua', 'folds', '[(if_statement) (function_declaration) (parameters) (arguments) (table_constructor)] @fold')]] + ) + parse('lua') + + eq({ + [1] = '>1', + [2] = '>3', + [3] = '3', + [4] = '3', + [5] = '2', + [6] = '2', + [7] = '1', + }, get_fold_levels()) + + command('2,6join') + poke_eventloop() + + eq({ + [1] = '>1', + [2] = '1', + [3] = '1', + }, get_fold_levels()) + + feed('u') + poke_eventloop() + + eq({ + [1] = '>1', + [2] = '>3', + [3] = '3', + [4] = '3', + [5] = '2', + [6] = '2', + [7] = '1', + }, get_fold_levels()) + end) + + it('takes account of relevant options', function() + insert([[ +# h1 +t1 +## h2 +t2 +### h3 +t3]]) + + exec_lua([[vim.treesitter.query.set('markdown', 'folds', '(section) @fold')]]) + parse('markdown') + + command([[set foldminlines=2]]) + + eq({ + [1] = '>1', + [2] = '1', + [3] = '>2', + [4] = '2', + [5] = '2', + [6] = '2', + }, get_fold_levels()) + + command([[set foldminlines=1 foldnestmax=1]]) + + eq({ + [1] = '>1', + [2] = '1', + [3] = '1', + [4] = '1', + [5] = '1', + [6] = '1', + }, get_fold_levels()) + end) + + it('updates folds in all windows', function() local screen = Screen.new(60, 48) screen:attach() screen:set_default_attr_ids({ - [1] = {background = Screen.colors.Grey, foreground = Screen.colors.DarkBlue}; - [2] = {bold = true, foreground = Screen.colors.Blue1}; - [3] = {bold = true, reverse = true}; - [4] = {reverse = true}; + [1] = { background = Screen.colors.Grey, foreground = Screen.colors.DarkBlue }, + [2] = { bold = true, foreground = Screen.colors.Blue1 }, + [3] = { bold = true, reverse = true }, + [4] = { reverse = true }, }) - exec_lua([[vim.treesitter.get_parser(0, "c")]]) - command([[set foldmethod=expr foldexpr=v:lua.vim.treesitter.foldexpr() foldcolumn=1 foldlevel=9]]) + parse('c') + command([[set foldmethod=expr foldexpr=v:lua.vim.treesitter.foldexpr() foldcolumn=1]]) command('split') insert(test_text) - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:-}void ui_refresh(void) | {1:│}{ | {1:│} int width = INT_MAX, height = INT_MAX; | @@ -157,10 +441,7 @@ void ui_refresh(void) {1:3} } | {1:2} } | {1:│}^} | - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*4 {3:[No Name] [+] }| {1:-}void ui_refresh(void) | {1:│}{ | @@ -181,16 +462,16 @@ void ui_refresh(void) {1:3} } | {1:2} } | {1:│}} | - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 {4:[No Name] [+] }| | - ]]} + ]], + } command('1,2d') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: } ^int width = INT_MAX, height = INT_MAX; | {1: } bool ext_widgets[kUIExtCount]; | {1:-} for (UIExtension i = 0; (int)i < kUIExtCount; i++) { | @@ -208,12 +489,7 @@ void ui_refresh(void) {1:2} } | {1:│} } | {1: }} | - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*6 {3:[No Name] [+] }| {1: } int width = INT_MAX, height = INT_MAX; | {1: } bool ext_widgets[kUIExtCount]; | @@ -232,19 +508,16 @@ void ui_refresh(void) {1:2} } | {1:│} } | {1: }} | - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*5 {4:[No Name] [+] }| | - ]]} - + ]], + } feed([[O<C-u><C-r>"<BS><Esc>]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:-}void ui_refresh(void) | {1:│}^{ | {1:│} int width = INT_MAX, height = INT_MAX; | @@ -264,10 +537,7 @@ void ui_refresh(void) {1:3} } | {1:2} } | {1:│}} | - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*4 {3:[No Name] [+] }| {1:-}void ui_refresh(void) | {1:│}{ | @@ -288,21 +558,21 @@ void ui_refresh(void) {1:3} } | {1:2} } | {1:│}} | - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 {4:[No Name] [+] }| | - ]]} - + ]], + } end) it("doesn't open folds in diff mode", function() local screen = Screen.new(60, 36) screen:attach() - exec_lua([[vim.treesitter.get_parser(0, "c")]]) - command([[set foldmethod=expr foldexpr=v:lua.vim.treesitter.foldexpr() foldcolumn=1 foldlevel=9]]) + parse('c') + command( + [[set foldmethod=expr foldexpr=v:lua.vim.treesitter.foldexpr() foldcolumn=1 foldlevel=9]] + ) insert(test_text) command('16d') @@ -312,7 +582,8 @@ void ui_refresh(void) command('windo diffthis') feed('do') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:+ }{2:+-- 9 lines: void ui_refresh(void)·······················}| {1: } for (size_t i = 0; i < ui_count; i++) { | {1: } UI *ui = uis[i]; | @@ -324,12 +595,7 @@ void ui_refresh(void) {1: } } | {1: } } | {1: }} | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*6 {4:[No Name] [+] }| {1:+ }{2:+-- 9 lines: void ui_refresh(void)·······················}| {1: } for (size_t i = 0; i < ui_count; i++) { | @@ -342,133 +608,70 @@ void ui_refresh(void) {1: } ^} | {1: } } | {1: }} | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*5 {5:[No Name] [+] }| | - ]], attr_ids={ - [1] = {background = Screen.colors.Grey, foreground = Screen.colors.Blue4}; - [2] = {background = Screen.colors.LightGrey, foreground = Screen.colors.Blue4}; - [3] = {foreground = Screen.colors.Blue, bold = true}; - [4] = {reverse = true}; - [5] = {reverse = true, bold = true}; - }} - end) - -end) - -describe('treesitter foldtext', function() - local test_text = [[ -void qsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *)) -{ - int width = INT_MAX, height = INT_MAX; - bool ext_widgets[kUIExtCount]; - for (UIExtension i = 0; (int)i < kUIExtCount; i++) { - ext_widgets[i] = true; - } - - bool inclusive = ui_override(); - for (size_t i = 0; i < ui_count; i++) { - UI *ui = uis[i]; - width = MIN(ui->width, width); - height = MIN(ui->height, height); - foo = BAR(ui->bazaar, bazaar); - for (UIExtension j = 0; (int)j < kUIExtCount; j++) { - ext_widgets[j] &= (ui->ui_ext[j] || inclusive); + ]], + attr_ids = { + [1] = { background = Screen.colors.Grey, foreground = Screen.colors.Blue4 }, + [2] = { background = Screen.colors.LightGrey, foreground = Screen.colors.Blue4 }, + [3] = { foreground = Screen.colors.Blue, bold = true }, + [4] = { reverse = true }, + [5] = { reverse = true, bold = true }, + }, } - } -}]] - local screen + end) - before_each(function() - screen = Screen.new(60, 5) + it("doesn't open folds that are not touched", function() + local screen = Screen.new(40, 8) screen:set_default_attr_ids({ - [0] = {foreground = Screen.colors.Blue, bold = true}, - [1] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGray}; - [2] = {bold = true, background = Screen.colors.LightGray, foreground = Screen.colors.SeaGreen}; - [3] = {foreground = Screen.colors.DarkCyan, background = Screen.colors.LightGray}; - [4] = {foreground = Screen.colors.SlateBlue, background = Screen.colors.LightGray}; - [5] = {bold = true, background = Screen.colors.LightGray, foreground = Screen.colors.Brown}; - [6] = {background = Screen.colors.Red1}; - [7] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.Red}; - [8] = {foreground = Screen.colors.Brown, bold = true, background = Screen.colors.Red}; - [9] = {foreground = Screen.colors.SlateBlue, background = Screen.colors.Red}; - [10] = {bold = true}; + [1] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.Gray }, + [2] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGray }, + [3] = { foreground = Screen.colors.Blue1, bold = true }, + [4] = { bold = true }, }) screen:attach() - end) - it('displays highlighted content', function() - command([[set foldmethod=manual foldtext=v:lua.vim.treesitter.foldtext() updatetime=50]]) - insert(test_text) - exec_lua([[vim.treesitter.get_parser(0, "c")]]) - - feed('ggVGzf') - screen:expect{grid=[[ - {2:^void}{1: }{3:qsort}{4:(}{2:void}{1: }{5:*}{3:base}{4:,}{1: }{2:size_t}{1: }{3:nel}{4:,}{1: }{2:size_t}{1: }{3:width}{4:,}{1: }{2:int}{1: }{4:(}{5:*}{3:compa}| - {0:~ }| - {0:~ }| - {0:~ }| - | - ]]} - end) - - it('handles deep nested captures', function() - command([[set foldmethod=manual foldtext=v:lua.vim.treesitter.foldtext() updatetime=50]]) insert([[ -function FoldInfo.new() - return setmetatable({ - start_counts = {}, - stop_counts = {}, - levels0 = {}, - levels = {}, - }, FoldInfo) -end]]) - exec_lua([[vim.treesitter.get_parser(0, "lua")]]) - - feed('ggjVGkzfgg') - screen:expect{grid=[[ - ^function FoldInfo.new() | - {1: }{5:return}{1: }{4:setmetatable({}{1:·····································}| - end | - {0:~ }| - | - ]]} - - command('hi! Visual guibg=Red') - feed('GVgg') - screen:expect{grid=[[ - ^f{6:unction FoldInfo.new()} | - {7: }{8:return}{7: }{9:setmetatable({}{7:·····································}| - {6:end} | - {0:~ }| - {10:-- VISUAL LINE --} | - ]]} - - feed('10l<C-V>') - screen:expect{grid=[[ - {6:function F}^oldInfo.new() | - {7: }{8:return}{7: }{9:se}{4:tmetatable({}{1:·····································}| - {6:end} | - {0:~ }| - {10:-- VISUAL BLOCK --} | - ]]} - end) - - it('falls back to default', function() - command([[set foldmethod=manual foldtext=v:lua.vim.treesitter.foldtext()]]) - insert(test_text) +# h1 +t1 +# h2 +t2]]) + exec_lua([[vim.treesitter.query.set('markdown', 'folds', '(section) @fold')]]) + parse('markdown') + command( + [[set foldmethod=expr foldexpr=v:lua.vim.treesitter.foldexpr() foldcolumn=1 foldlevel=0]] + ) + + feed('ggzojo') + poke_eventloop() + + screen:expect { + grid = [[ + {1:-}# h1 | + {1:│}t1 | + {1:│}^ | + {1:+}{2:+-- 2 lines: # h2·····················}| + {3:~ }|*3 + {4:-- INSERT --} | + ]], + } - feed('ggVGzf') - screen:expect{grid=[[ - {1:^+-- 19 lines: void qsort(void *base, size_t nel, size_t widt}| - {0:~ }| - {0:~ }| - {0:~ }| - | - ]]} + feed('<Esc>u') + -- TODO(tomtomjhj): `u` spuriously opens the fold (#26499). + feed('zMggzo') + + feed('dd') + poke_eventloop() + + screen:expect { + grid = [[ + {1:-}^t1 | + {1:-}# h2 | + {1:│}t2 | + {3:~ }|*4 + 1 line less; before #2 {MATCH:.*}| + ]], + } end) end) diff --git a/test/functional/treesitter/highlight_spec.lua b/test/functional/treesitter/highlight_spec.lua index e037c9e215..2bf230fe69 100644 --- a/test/functional/treesitter/highlight_spec.lua +++ b/test/functional/treesitter/highlight_spec.lua @@ -6,7 +6,7 @@ local insert = helpers.insert local exec_lua = helpers.exec_lua local feed = helpers.feed local command = helpers.command -local meths = helpers.meths +local api = helpers.api local eq = helpers.eq before_each(clear) @@ -100,17 +100,7 @@ local injection_grid_c = [[ return 42; \ | } | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 | ]] @@ -121,17 +111,7 @@ local injection_grid_expected_c = [[ {4:return} {5:42}; \ | } | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 | ]] @@ -142,17 +122,17 @@ describe('treesitter highlighting (C)', function() screen = Screen.new(65, 18) screen:attach() screen:set_default_attr_ids { - [1] = {bold = true, foreground = Screen.colors.Blue1}; - [2] = {foreground = Screen.colors.Blue1}; - [3] = {bold = true, foreground = Screen.colors.SeaGreen4}; - [4] = {bold = true, foreground = Screen.colors.Brown}; - [5] = {foreground = Screen.colors.Magenta}; - [6] = {foreground = Screen.colors.Red}; - [7] = {bold = true, foreground = Screen.colors.SlateBlue}; - [8] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}; - [9] = {foreground = Screen.colors.Magenta, background = Screen.colors.Red}; - [10] = {foreground = Screen.colors.Red, background = Screen.colors.Red}; - [11] = {foreground = Screen.colors.Cyan4}; + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.Blue1 }, + [3] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [4] = { bold = true, foreground = Screen.colors.Brown }, + [5] = { foreground = Screen.colors.Magenta }, + [6] = { foreground = Screen.colors.Red }, + [7] = { bold = true, foreground = Screen.colors.SlateBlue }, + [8] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [9] = { foreground = Screen.colors.Magenta, background = Screen.colors.Red }, + [10] = { foreground = Screen.colors.Red, background = Screen.colors.Red }, + [11] = { foreground = Screen.colors.Cyan4 }, } exec_lua([[ hl_query = ... ]], hl_query_c) @@ -162,7 +142,8 @@ describe('treesitter highlighting (C)', function() it('is updated with edits', function() insert(hl_text_c) - screen:expect{grid=[[ + screen:expect { + grid = [[ /// Schedule Lua callback on main loop's event queue | static int nlua_schedule(lua_State *const lstate) | { | @@ -178,17 +159,18 @@ describe('treesitter highlighting (C)', function() 1, (void *)(ptrdiff_t)cb); | return 0; | ^} | - {1:~ }| - {1:~ }| + {1:~ }|*2 | - ]]} + ]], + } exec_lua [[ local parser = vim.treesitter.get_parser(0, "c") local highlighter = vim.treesitter.highlighter test_hl = highlighter.new(parser, {queries = {c = hl_query}}) ]] - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:/// Schedule Lua callback on main loop's event queue} | {3:static} {3:int} {11:nlua_schedule}({3:lua_State} *{3:const} lstate) | { | @@ -204,14 +186,15 @@ describe('treesitter highlighting (C)', function() {5:1}, ({3:void} *)({3:ptrdiff_t})cb); | {4:return} {5:0}; | ^} | - {1:~ }| - {1:~ }| + {1:~ }|*2 | - ]]} + ]], + } - feed("5Goc<esc>dd") + feed('5Goc<esc>dd') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:/// Schedule Lua callback on main loop's event queue} | {3:static} {3:int} {11:nlua_schedule}({3:lua_State} *{3:const} lstate) | { | @@ -227,13 +210,14 @@ describe('treesitter highlighting (C)', function() {5:1}, ({3:void} *)({3:ptrdiff_t})cb); | {4:return} {5:0}; | } | - {1:~ }| - {1:~ }| + {1:~ }|*2 | - ]]} + ]], + } feed('7Go*/<esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:/// Schedule Lua callback on main loop's event queue} | {3:static} {3:int} {11:nlua_schedule}({3:lua_State} *{3:const} lstate) | { | @@ -252,10 +236,12 @@ describe('treesitter highlighting (C)', function() } | {1:~ }| | - ]]} + ]], + } feed('3Go/*<esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:/// Schedule Lua callback on main loop's event queue} | {3:static} {3:int} {11:nlua_schedule}({3:lua_State} *{3:const} lstate) | { | @@ -274,11 +260,13 @@ describe('treesitter highlighting (C)', function() {4:return} {5:0}; | {8:}} | | - ]]} + ]], + } - feed("gg$") - feed("~") - screen:expect{grid=[[ + feed('gg$') + feed('~') + screen:expect { + grid = [[ {2:/// Schedule Lua callback on main loop's event queu^E} | {3:static} {3:int} {11:nlua_schedule}({3:lua_State} *{3:const} lstate) | { | @@ -297,11 +285,12 @@ describe('treesitter highlighting (C)', function() {4:return} {5:0}; | {8:}} | | - ]]} - + ]], + } - feed("re") - screen:expect{grid=[[ + feed('re') + screen:expect { + grid = [[ {2:/// Schedule Lua callback on main loop's event queu^e} | {3:static} {3:int} {11:nlua_schedule}({3:lua_State} *{3:const} lstate) | { | @@ -320,7 +309,8 @@ describe('treesitter highlighting (C)', function() {4:return} {5:0}; | {8:}} | | - ]]} + ]], + } end) it('is updated with :sort', function() @@ -329,7 +319,8 @@ describe('treesitter highlighting (C)', function() local parser = vim.treesitter.get_parser(0, "c") test_hl = vim.treesitter.highlighter.new(parser, {queries = {c = hl_query}}) ]] - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:int} width = {5:INT_MAX}, height = {5:INT_MAX}; | {3:bool} ext_widgets[kUIExtCount]; | {4:for} ({3:UIExtension} i = {5:0}; ({3:int})i < kUIExtCount; i++) { | @@ -348,10 +339,12 @@ describe('treesitter highlighting (C)', function() } | ^} | | - ]]} + ]], + } - feed ":sort<cr>" - screen:expect{grid=[[ + feed ':sort<cr>' + screen:expect { + grid = [[ ^ | ext_widgets[j] &= (ui->ui_ext[j] || inclusive); | {3:UI} *ui = uis[i]; | @@ -366,15 +359,16 @@ describe('treesitter highlighting (C)', function() {4:for} ({3:UIExtension} i = {5:0}; ({3:int})i < kUIExtCount; i++) { | {4:for} ({3:size_t} i = {5:0}; i < ui_count; i++) { | {3:int} width = {5:INT_MAX}, height = {5:INT_MAX}; | - } | - } | + } |*2 {3:void} ui_refresh({3:void}) | :sort | - ]]} + ]], + } - feed "u" + feed 'u' - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:int} width = {5:INT_MAX}, height = {5:INT_MAX}; | {3:bool} ext_widgets[kUIExtCount]; | {4:for} ({3:UIExtension} i = {5:0}; ({3:int})i < kUIExtCount; i++) { | @@ -393,17 +387,19 @@ describe('treesitter highlighting (C)', function() } | ^} | 19 changes; before #2 {MATCH:.*}| - ]]} + ]], + } end) - it("supports with custom parser", function() + it('supports with custom parser', function() screen:set_default_attr_ids { - [1] = {bold = true, foreground = Screen.colors.SeaGreen4}; + [1] = { bold = true, foreground = Screen.colors.SeaGreen4 }, } insert(test_text_c) - screen:expect{ grid= [[ + screen:expect { + grid = [[ int width = INT_MAX, height = INT_MAX; | bool ext_widgets[kUIExtCount]; | for (UIExtension i = 0; (int)i < kUIExtCount; i++) { | @@ -422,7 +418,8 @@ describe('treesitter highlighting (C)', function() } | ^} | | - ]] } + ]], + } exec_lua [[ parser = vim.treesitter.get_parser(0, "c") @@ -438,7 +435,8 @@ describe('treesitter highlighting (C)', function() local hl = vim.treesitter.highlighter.new(parser, {queries = {c = "(identifier) @type"}}) ]] - screen:expect{ grid = [[ + screen:expect { + grid = [[ int {1:width} = {1:INT_MAX}, {1:height} = {1:INT_MAX}; | bool {1:ext_widgets}[{1:kUIExtCount}]; | for (UIExtension {1:i} = 0; (int)i < kUIExtCount; i++) { | @@ -457,13 +455,14 @@ describe('treesitter highlighting (C)', function() } | ^} | | - ]] } + ]], + } end) - it("supports injected languages", function() + it('supports injected languages', function() insert(injection_text_c) - screen:expect{grid=injection_grid_c} + screen:expect { grid = injection_grid_c } exec_lua [[ local parser = vim.treesitter.get_parser(0, "c", { @@ -473,13 +472,13 @@ describe('treesitter highlighting (C)', function() test_hl = highlighter.new(parser, {queries = {c = hl_query}}) ]] - screen:expect{grid=injection_grid_expected_c} + screen:expect { grid = injection_grid_expected_c } end) it("supports injecting by ft name in metadata['injection.language']", function() insert(injection_text_c) - screen:expect{grid=injection_grid_c} + screen:expect { grid = injection_grid_c } exec_lua [[ vim.treesitter.language.register("c", "foo") @@ -490,10 +489,10 @@ describe('treesitter highlighting (C)', function() test_hl = highlighter.new(parser, {queries = {c = hl_query}}) ]] - screen:expect{grid=injection_grid_expected_c} + screen:expect { grid = injection_grid_expected_c } end) - it("supports overriding queries, like ", function() + it('supports overriding queries, like ', function() insert([[ int x = INT_MAX; #define READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) @@ -510,29 +509,21 @@ describe('treesitter highlighting (C)', function() vim.treesitter.highlighter.new(vim.treesitter.get_parser(0, "c")) ]] - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:int} x = {5:INT_MAX}; | #define {5:READ_STRING}(x, y) ({3:char} *)read_string((x), ({3:size_t})(y)) | #define foo {3:void} main() { \ | {4:return} {5:42}; \ | } | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 | - ]]} + ]], + } end) - it("supports highlighting with custom highlight groups", function() + it('supports highlighting with custom highlight groups', function() insert(hl_text_c) exec_lua [[ @@ -540,7 +531,8 @@ describe('treesitter highlighting (C)', function() test_hl = vim.treesitter.highlighter.new(parser, {queries = {c = hl_query}}) ]] - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:/// Schedule Lua callback on main loop's event queue} | {3:static} {3:int} {11:nlua_schedule}({3:lua_State} *{3:const} lstate) | { | @@ -556,15 +548,16 @@ describe('treesitter highlighting (C)', function() {5:1}, ({3:void} *)({3:ptrdiff_t})cb); | {4:return} {5:0}; | ^} | - {1:~ }| - {1:~ }| + {1:~ }|*2 | - ]]} + ]], + } -- This will change ONLY the literal strings to look like comments -- The only literal string is the "vim.schedule: expected function" in this test. exec_lua [[vim.cmd("highlight link @string.nonexistent_specializer comment")]] - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:/// Schedule Lua callback on main loop's event queue} | {3:static} {3:int} {11:nlua_schedule}({3:lua_State} *{3:const} lstate) | { | @@ -580,14 +573,14 @@ describe('treesitter highlighting (C)', function() {5:1}, ({3:void} *)({3:ptrdiff_t})cb); | {4:return} {5:0}; | ^} | - {1:~ }| - {1:~ }| + {1:~ }|*2 | - ]]} - screen:expect{ unchanged=true } + ]], + } + screen:expect { unchanged = true } end) - it("supports highlighting with priority", function() + it('supports highlighting with priority', function() insert([[ int x = INT_MAX; #define READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) @@ -601,120 +594,80 @@ describe('treesitter highlighting (C)', function() test_hl = vim.treesitter.highlighter.new(parser, {queries = {c = hl_query..'\n((translation_unit) @constant (#set! "priority" 101))\n'}}) ]] -- expect everything to have Constant highlight - screen:expect{grid=[[ + screen:expect { + grid = [[ {12:int}{8: x = INT_MAX;} | {8:#define READ_STRING(x, y) (}{12:char}{8: *)read_string((x), (}{12:size_t}{8:)(y))} | {8:#define foo }{12:void}{8: main() { \} | {8: }{12:return}{8: 42; \} | {8: }} | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - | - ]], attr_ids={ - [1] = {bold = true, foreground = Screen.colors.Blue1}; - [8] = {foreground = Screen.colors.Magenta1}; - -- bold will not be overwritten at the moment - [12] = {bold = true, foreground = Screen.colors.Magenta1}; - }} + {1:~ }|*11 + | + ]], + attr_ids = { + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [8] = { foreground = Screen.colors.Magenta1 }, + -- bold will not be overwritten at the moment + [12] = { bold = true, foreground = Screen.colors.Magenta1 }, + }, + } eq({ - {capture='constant', metadata = { priority='101' }, lang='c' }; - {capture='type', metadata = { }, lang='c' }; + { capture = 'constant', metadata = { priority = '101' }, lang = 'c' }, + { capture = 'type', metadata = {}, lang = 'c' }, }, exec_lua [[ return vim.treesitter.get_captures_at_pos(0, 0, 2) ]]) - end) + end) - it("allows to use captures with dots (don't use fallback when specialization of foo exists)", function() - insert([[ + it( + "allows to use captures with dots (don't use fallback when specialization of foo exists)", + function() + insert([[ char* x = "Will somebody ever read this?"; ]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ char* x = "Will somebody ever read this?"; | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*15 | - ]]} + ]], + } - command [[ + command [[ hi link @foo.bar Type hi link @foo String ]] - exec_lua [[ + exec_lua [[ local parser = vim.treesitter.get_parser(0, "c", {}) local highlighter = vim.treesitter.highlighter test_hl = highlighter.new(parser, {queries = {c = "(primitive_type) @foo.bar (string_literal) @foo"}}) ]] - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:char}* x = {5:"Will somebody ever read this?"}; | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*15 | - ]]} + ]], + } - -- clearing specialization reactivates fallback - command [[ hi clear @foo.bar ]] - screen:expect{grid=[[ + -- clearing specialization reactivates fallback + command [[ hi clear @foo.bar ]] + screen:expect { + grid = [[ {5:char}* x = {5:"Will somebody ever read this?"}; | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*15 | - ]]} - end) + ]], + } + end + ) - it("supports conceal attribute", function() + it('supports conceal attribute', function() insert(hl_text_c) -- conceal can be empty or a single cchar. @@ -723,15 +676,16 @@ describe('treesitter highlighting (C)', function() local parser = vim.treesitter.get_parser(0, "c") test_hl = vim.treesitter.highlighter.new(parser, {queries = {c = [[ ("static" @keyword - (set! conceal "R")) + (#set! conceal "R")) ((identifier) @Identifier - (set! conceal "") - (eq? @Identifier "lstate")) + (#set! conceal "") + (#eq? @Identifier "lstate")) ]]}}) ]=] - screen:expect{grid=[[ + screen:expect { + grid = [[ /// Schedule Lua callback on main loop's event queue | {4:R} int nlua_schedule(lua_State *const ) | { | @@ -747,33 +701,60 @@ describe('treesitter highlighting (C)', function() 1, (void *)(ptrdiff_t)cb); | return 0; | ^} | - {1:~ }| - {1:~ }| + {1:~ }|*2 | - ]]} + ]], + } end) - it("@foo.bar groups has the correct fallback behavior", function() - local get_hl = function(name) return meths.get_hl_by_name(name,1).foreground end - meths.set_hl(0, "@foo", {fg = 1}) - meths.set_hl(0, "@foo.bar", {fg = 2}) - meths.set_hl(0, "@foo.bar.baz", {fg = 3}) - - eq(1, get_hl"@foo") - eq(1, get_hl"@foo.a.b.c.d") - eq(2, get_hl"@foo.bar") - eq(2, get_hl"@foo.bar.a.b.c.d") - eq(3, get_hl"@foo.bar.baz") - eq(3, get_hl"@foo.bar.baz.d") + it('@foo.bar groups has the correct fallback behavior', function() + local get_hl = function(name) + return api.nvim_get_hl_by_name(name, 1).foreground + end + api.nvim_set_hl(0, '@foo', { fg = 1 }) + api.nvim_set_hl(0, '@foo.bar', { fg = 2 }) + api.nvim_set_hl(0, '@foo.bar.baz', { fg = 3 }) + + eq(1, get_hl '@foo') + eq(1, get_hl '@foo.a.b.c.d') + eq(2, get_hl '@foo.bar') + eq(2, get_hl '@foo.bar.a.b.c.d') + eq(3, get_hl '@foo.bar.baz') + eq(3, get_hl '@foo.bar.baz.d') -- lookup is case insensitive - eq(2, get_hl"@FOO.BAR.SPAM") + eq(2, get_hl '@FOO.BAR.SPAM') + + api.nvim_set_hl(0, '@foo.missing.exists', { fg = 3 }) + eq(1, get_hl '@foo.missing') + eq(3, get_hl '@foo.missing.exists') + eq(3, get_hl '@foo.missing.exists.bar') + eq(nil, get_hl '@total.nonsense.but.a.lot.of.dots') + end) - meths.set_hl(0, "@foo.missing.exists", {fg = 3}) - eq(1, get_hl"@foo.missing") - eq(3, get_hl"@foo.missing.exists") - eq(3, get_hl"@foo.missing.exists.bar") - eq(nil, get_hl"@total.nonsense.but.a.lot.of.dots") + it('supports multiple nodes assigned to the same capture #17060', function() + insert([[ + int x = 4; + int y = 5; + int z = 6; + ]]) + + exec_lua([[ + local query = '((declaration)+ @string)' + vim.treesitter.query.set('c', 'highlights', query) + vim.treesitter.highlighter.new(vim.treesitter.get_parser(0, 'c')) + ]]) + + screen:expect { + grid = [[ + {5:int x = 4;} | + {5:int y = 5;} | + {5:int z = 6;} | + ^ | + {1:~ }|*13 + | + ]], + } end) end) @@ -784,16 +765,16 @@ describe('treesitter highlighting (help)', function() screen = Screen.new(40, 6) screen:attach() screen:set_default_attr_ids { - [1] = {foreground = Screen.colors.Blue1}; - [2] = {bold = true, foreground = Screen.colors.Blue1}; - [3] = {bold = true, foreground = Screen.colors.Brown}; - [4] = {foreground = Screen.colors.Cyan4}; - [5] = {foreground = Screen.colors.Magenta1}; + [1] = { foreground = Screen.colors.Blue1 }, + [2] = { bold = true, foreground = Screen.colors.Blue1 }, + [3] = { bold = true, foreground = Screen.colors.Brown }, + [4] = { foreground = Screen.colors.Cyan4 }, + [5] = { foreground = Screen.colors.Magenta1 }, } end) - it("correctly redraws added/removed injections", function() - insert[[ + it('correctly redraws added/removed injections', function() + insert [[ >ruby -- comment local this_is = 'actually_lua' @@ -805,38 +786,43 @@ describe('treesitter highlighting (help)', function() vim.treesitter.start() ]] - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:>ruby} | {1: -- comment} | {1: local this_is = 'actually_lua'} | - < | + {1:<} | ^ | | - ]]} + ]], + } - helpers.curbufmeths.set_text(0, 1, 0, 5, {'lua'}) + helpers.api.nvim_buf_set_text(0, 0, 1, 0, 5, { 'lua' }) - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:>lua} | {1: -- comment} | {1: }{3:local}{1: }{4:this_is}{1: }{3:=}{1: }{5:'actually_lua'} | - < | + {1:<} | ^ | | - ]]} + ]], + } - helpers.curbufmeths.set_text(0, 1, 0, 4, {'ruby'}) + helpers.api.nvim_buf_set_text(0, 0, 1, 0, 4, { 'ruby' }) - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:>ruby} | {1: -- comment} | {1: local this_is = 'actually_lua'} | - < | + {1:<} | ^ | | - ]]} + ]], + } end) - end) describe('treesitter highlighting (nested injections)', function() @@ -846,15 +832,15 @@ describe('treesitter highlighting (nested injections)', function() screen = Screen.new(80, 7) screen:attach() screen:set_default_attr_ids { - [1] = {foreground = Screen.colors.SlateBlue}; - [2] = {bold = true, foreground = Screen.colors.Brown}; - [3] = {foreground = Screen.colors.Cyan4}; - [4] = {foreground = Screen.colors.Fuchsia}; + [1] = { foreground = Screen.colors.SlateBlue }, + [2] = { bold = true, foreground = Screen.colors.Brown }, + [3] = { foreground = Screen.colors.Cyan4 }, + [4] = { foreground = Screen.colors.Fuchsia }, } end) - it("correctly redraws nested injections (GitHub #25252)", function() - insert[=[ + it('correctly redraws nested injections (GitHub #25252)', function() + insert [=[ function foo() print("Lua!") end local lorem = { @@ -875,9 +861,10 @@ vim.cmd([[ ]] -- invalidate the language tree - feed("ggi--[[<ESC>04x") + feed('ggi--[[<ESC>04x') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:^function} {3:foo}{1:()} {1:print(}{4:"Lua!"}{1:)} {2:end} | | {2:local} {3:lorem} {2:=} {1:{} | @@ -885,12 +872,14 @@ vim.cmd([[ {3:bar} {2:=} {1:{},} | {1:}} | | - ]]} + ]], + } -- spam newline insert/delete to invalidate Lua > Vim > Lua region - feed("3jo<ESC>ddko<ESC>ddko<ESC>ddko<ESC>ddk0") + feed('3jo<ESC>ddko<ESC>ddko<ESC>ddko<ESC>ddk0') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:function} {3:foo}{1:()} {1:print(}{4:"Lua!"}{1:)} {2:end} | | {2:local} {3:lorem} {2:=} {1:{} | @@ -898,7 +887,7 @@ vim.cmd([[ {3:bar} {2:=} {1:{},} | {1:}} | | - ]]} + ]], + } end) - end) diff --git a/test/functional/treesitter/inspect_tree_spec.lua b/test/functional/treesitter/inspect_tree_spec.lua new file mode 100644 index 0000000000..a3d44ff906 --- /dev/null +++ b/test/functional/treesitter/inspect_tree_spec.lua @@ -0,0 +1,115 @@ +local helpers = require('test.functional.helpers')(after_each) +local clear = helpers.clear +local insert = helpers.insert +local dedent = helpers.dedent +local eq = helpers.eq +local exec_lua = helpers.exec_lua +local feed = helpers.feed + +describe('vim.treesitter.inspect_tree', function() + before_each(clear) + + local expect_tree = function(x) + local expected = vim.split(vim.trim(dedent(x)), '\n') + local actual = helpers.buf_lines(0) ---@type string[] + eq(expected, actual) + end + + it('working', function() + insert([[ + print() + ]]) + + exec_lua([[ + vim.treesitter.start(0, 'lua') + vim.treesitter.inspect_tree() + ]]) + + expect_tree [[ + (chunk ; [0, 0] - [2, 0] + (function_call ; [0, 0] - [0, 7] + name: (identifier) ; [0, 0] - [0, 5] + arguments: (arguments))) ; [0, 5] - [0, 7] + ]] + end) + + it('can toggle to show anonymous nodes', function() + insert([[ + print() + ]]) + + exec_lua([[ + vim.treesitter.start(0, 'lua') + vim.treesitter.inspect_tree() + ]]) + feed('a') + + expect_tree [[ + (chunk ; [0, 0] - [2, 0] + (function_call ; [0, 0] - [0, 7] + name: (identifier) ; [0, 0] - [0, 5] + arguments: (arguments ; [0, 5] - [0, 7] + "(" ; [0, 5] - [0, 6] + ")"))) ; [0, 6] - [0, 7] + ]] + end) + + it('works for injected trees', function() + insert([[ + ```lua + return + ``` + ]]) + + exec_lua([[ + vim.treesitter.start(0, 'markdown') + vim.treesitter.get_parser():parse() + vim.treesitter.inspect_tree() + ]]) + + expect_tree [[ + (document ; [0, 0] - [4, 0] + (section ; [0, 0] - [4, 0] + (fenced_code_block ; [0, 0] - [3, 0] + (fenced_code_block_delimiter) ; [0, 0] - [0, 3] + (info_string ; [0, 3] - [0, 6] + (language)) ; [0, 3] - [0, 6] + (block_continuation) ; [1, 0] - [1, 0] + (code_fence_content ; [1, 0] - [2, 0] + (chunk ; [1, 0] - [2, 0] + (return_statement)) ; [1, 0] - [1, 6] + (block_continuation)) ; [2, 0] - [2, 0] + (fenced_code_block_delimiter)))) ; [2, 0] - [2, 3] + ]] + end) + + it('can toggle to show languages', function() + insert([[ + ```lua + return + ``` + ]]) + + exec_lua([[ + vim.treesitter.start(0, 'markdown') + vim.treesitter.get_parser():parse() + vim.treesitter.inspect_tree() + ]]) + feed('I') + + expect_tree [[ + (document ; [0, 0] - [4, 0] markdown + (section ; [0, 0] - [4, 0] markdown + (fenced_code_block ; [0, 0] - [3, 0] markdown + (fenced_code_block_delimiter) ; [0, 0] - [0, 3] markdown + (info_string ; [0, 3] - [0, 6] markdown + (language)) ; [0, 3] - [0, 6] markdown + (block_continuation) ; [1, 0] - [1, 0] markdown + (code_fence_content ; [1, 0] - [2, 0] markdown + (chunk ; [1, 0] - [2, 0] lua + (return_statement)) ; [1, 0] - [1, 6] lua + (block_continuation)) ; [2, 0] - [2, 0] markdown + (fenced_code_block_delimiter)))) ; [2, 0] - [2, 3] markdown + ]] + end) +end) diff --git a/test/functional/treesitter/language_spec.lua b/test/functional/treesitter/language_spec.lua index 9b871a72fb..65d9e0e81c 100644 --- a/test/functional/treesitter/language_spec.lua +++ b/test/functional/treesitter/language_spec.lua @@ -13,27 +13,43 @@ before_each(clear) describe('treesitter language API', function() -- error tests not requiring a parser library it('handles missing language', function() - eq(".../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers", - pcall_err(exec_lua, "parser = vim.treesitter.get_parser(0, 'borklang')")) + eq( + ".../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers", + pcall_err(exec_lua, "parser = vim.treesitter.get_parser(0, 'borklang')") + ) -- actual message depends on platform - matches("Failed to load parser for language 'borklang': uv_dlopen: .+", - pcall_err(exec_lua, "parser = vim.treesitter.language.add('borklang', { path = 'borkbork.so' })")) + matches( + "Failed to load parser for language 'borklang': uv_dlopen: .+", + pcall_err( + exec_lua, + "parser = vim.treesitter.language.add('borklang', { path = 'borkbork.so' })" + ) + ) eq(false, exec_lua("return pcall(vim.treesitter.language.add, 'borklang')")) - eq(false, exec_lua("return pcall(vim.treesitter.language.add, 'borklang', { path = 'borkbork.so' })")) + eq( + false, + exec_lua("return pcall(vim.treesitter.language.add, 'borklang', { path = 'borkbork.so' })") + ) - eq(".../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers", - pcall_err(exec_lua, "parser = vim.treesitter.language.inspect('borklang')")) + eq( + ".../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers", + pcall_err(exec_lua, "parser = vim.treesitter.language.inspect('borklang')") + ) - matches("Failed to load parser: uv_dlsym: .+", - pcall_err(exec_lua, 'vim.treesitter.language.add("c", { symbol_name = "borklang" })')) + matches( + 'Failed to load parser: uv_dlsym: .+', + pcall_err(exec_lua, 'vim.treesitter.language.add("c", { symbol_name = "borklang" })') + ) end) it('shows error for invalid language name', function() - eq(".../language.lua:0: '/foo/' is not a valid language name", - pcall_err(exec_lua, 'vim.treesitter.language.add("/foo/")')) + eq( + ".../language.lua:0: '/foo/' is not a valid language name", + pcall_err(exec_lua, 'vim.treesitter.language.add("/foo/")') + ) end) it('inspects language', function() @@ -52,40 +68,45 @@ describe('treesitter language API', function() return {keys, lang.fields, symbols} ]])) - eq({fields=true, symbols=true, _abi_version=true}, keys) + eq({ fields = true, symbols = true, _abi_version = true }, keys) local fset = {} - for _,f in pairs(fields) do - eq("string", type(f)) + for _, f in pairs(fields) do + eq('string', type(f)) fset[f] = true end - eq(true, fset["directive"]) - eq(true, fset["initializer"]) + eq(true, fset['directive']) + eq(true, fset['initializer']) local has_named, has_anonymous - for _,s in pairs(symbols) do - eq("string", type(s[1])) - eq("boolean", type(s[2])) - if s[1] == "for_statement" and s[2] == true then + for _, s in pairs(symbols) do + eq('string', type(s[1])) + eq('boolean', type(s[2])) + if s[1] == 'for_statement' and s[2] == true then has_named = true - elseif s[1] == "|=" and s[2] == false then + elseif s[1] == '|=' and s[2] == false then has_anonymous = true end end - eq({true,true}, {has_named,has_anonymous}) + eq({ true, true }, { has_named, has_anonymous }) end) - it('checks if vim.treesitter.get_parser tries to create a new parser on filetype change', function () - command("set filetype=c") - -- Should not throw an error when filetype is c - eq('c', exec_lua("return vim.treesitter.get_parser(0):lang()")) - command("set filetype=borklang") - -- Should throw an error when filetype changes to borklang - eq(".../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers", - pcall_err(exec_lua, "new_parser = vim.treesitter.get_parser(0, 'borklang')")) - end) + it( + 'checks if vim.treesitter.get_parser tries to create a new parser on filetype change', + function() + command('set filetype=c') + -- Should not throw an error when filetype is c + eq('c', exec_lua('return vim.treesitter.get_parser(0):lang()')) + command('set filetype=borklang') + -- Should throw an error when filetype changes to borklang + eq( + ".../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers", + pcall_err(exec_lua, "new_parser = vim.treesitter.get_parser(0, 'borklang')") + ) + end + ) - it('retrieve the tree given a range', function () + it('retrieve the tree given a range', function() insert([[ int main() { int x = 3; @@ -99,7 +120,7 @@ describe('treesitter language API', function() eq('<node translation_unit>', exec_lua('return tostring(tree:root())')) end) - it('retrieve the node given a range', function () + it('retrieve the node given a range', function() insert([[ int main() { int x = 3; @@ -113,4 +134,3 @@ describe('treesitter language API', function() eq('<node primitive_type>', exec_lua('return tostring(node)')) end) end) - diff --git a/test/functional/treesitter/node_spec.lua b/test/functional/treesitter/node_spec.lua index eef75d0e91..f114d36823 100644 --- a/test/functional/treesitter/node_spec.lua +++ b/test/functional/treesitter/node_spec.lua @@ -9,7 +9,7 @@ local assert_alive = helpers.assert_alive before_each(clear) local function lua_eval(lua_expr) - return exec_lua("return " .. lua_expr) + return exec_lua('return ' .. lua_expr) end describe('treesitter node API', function() @@ -40,6 +40,20 @@ describe('treesitter node API', function() assert_alive() end) + it('get_node() with lang given', function() + -- this buffer doesn't have filetype set! + insert('local foo = function() end') + exec_lua([[ + node = vim.treesitter.get_node({ + bufnr = 0, + pos = { 0, 6 }, -- on "foo" + lang = 'lua', + }) + ]]) + eq('foo', lua_eval('vim.treesitter.get_node_text(node, 0)')) + eq('identifier', lua_eval('node:type()')) + end) + it('can move between siblings', function() insert([[ int main(int x, int y, int z) { @@ -48,14 +62,13 @@ describe('treesitter node API', function() ]]) exec_lua([[ - query = require"vim.treesitter.query" parser = vim.treesitter.get_parser(0, "c") tree = parser:parse()[1] root = tree:root() lang = vim.treesitter.language.inspect('c') function node_text(node) - return query.get_node_text(node, 0) + return vim.treesitter.get_node_text(node, 0) end ]]) diff --git a/test/functional/treesitter/parser_spec.lua b/test/functional/treesitter/parser_spec.lua index 6f386115ae..875b772fec 100644 --- a/test/functional/treesitter/parser_spec.lua +++ b/test/functional/treesitter/parser_spec.lua @@ -8,11 +8,13 @@ local exec_lua = helpers.exec_lua local pcall_err = helpers.pcall_err local feed = helpers.feed local is_os = helpers.is_os +local api = helpers.api +local fn = helpers.fn describe('treesitter parser API', function() before_each(function() clear() - exec_lua[[ + exec_lua [[ vim.g.__ts_debug = 1 ]] end) @@ -30,59 +32,62 @@ describe('treesitter parser API', function() lang = vim.treesitter.language.inspect('c') ]]) - eq("<tree>", exec_lua("return tostring(tree)")) - eq("<node translation_unit>", exec_lua("return tostring(root)")) - eq({0,0,3,0}, exec_lua("return {root:range()}")) - - eq(1, exec_lua("return root:child_count()")) - exec_lua("child = root:child(0)") - eq("<node function_definition>", exec_lua("return tostring(child)")) - eq({0,0,2,1}, exec_lua("return {child:range()}")) - - eq("function_definition", exec_lua("return child:type()")) - eq(true, exec_lua("return child:named()")) - eq("number", type(exec_lua("return child:symbol()"))) - eq({'function_definition', true}, exec_lua("return lang.symbols[child:symbol()]")) - - exec_lua("anon = root:descendant_for_range(0,8,0,9)") - eq("(", exec_lua("return anon:type()")) - eq(false, exec_lua("return anon:named()")) - eq("number", type(exec_lua("return anon:symbol()"))) - eq({'(', false}, exec_lua("return lang.symbols[anon:symbol()]")) - - exec_lua("descendant = root:descendant_for_range(1,2,1,12)") - eq("<node declaration>", exec_lua("return tostring(descendant)")) - eq({1,2,1,12}, exec_lua("return {descendant:range()}")) - eq("(declaration type: (primitive_type) declarator: (init_declarator declarator: (identifier) value: (number_literal)))", exec_lua("return descendant:sexpr()")) - - feed("2G7|ay") + eq('<tree>', exec_lua('return tostring(tree)')) + eq('<node translation_unit>', exec_lua('return tostring(root)')) + eq({ 0, 0, 3, 0 }, exec_lua('return {root:range()}')) + + eq(1, exec_lua('return root:child_count()')) + exec_lua('child = root:child(0)') + eq('<node function_definition>', exec_lua('return tostring(child)')) + eq({ 0, 0, 2, 1 }, exec_lua('return {child:range()}')) + + eq('function_definition', exec_lua('return child:type()')) + eq(true, exec_lua('return child:named()')) + eq('number', type(exec_lua('return child:symbol()'))) + eq({ 'function_definition', true }, exec_lua('return lang.symbols[child:symbol()]')) + + exec_lua('anon = root:descendant_for_range(0,8,0,9)') + eq('(', exec_lua('return anon:type()')) + eq(false, exec_lua('return anon:named()')) + eq('number', type(exec_lua('return anon:symbol()'))) + eq({ '(', false }, exec_lua('return lang.symbols[anon:symbol()]')) + + exec_lua('descendant = root:descendant_for_range(1,2,1,12)') + eq('<node declaration>', exec_lua('return tostring(descendant)')) + eq({ 1, 2, 1, 12 }, exec_lua('return {descendant:range()}')) + eq( + '(declaration type: (primitive_type) declarator: (init_declarator declarator: (identifier) value: (number_literal)))', + exec_lua('return descendant:sexpr()') + ) + + feed('2G7|ay') exec_lua([[ tree2 = parser:parse()[1] root2 = tree2:root() descendant2 = root2:descendant_for_range(1,2,1,13) ]]) - eq(false, exec_lua("return tree2 == tree1")) - eq(false, exec_lua("return root2 == root")) - eq("<node declaration>", exec_lua("return tostring(descendant2)")) - eq({1,2,1,13}, exec_lua("return {descendant2:range()}")) + eq(false, exec_lua('return tree2 == tree1')) + eq(false, exec_lua('return root2 == root')) + eq('<node declaration>', exec_lua('return tostring(descendant2)')) + eq({ 1, 2, 1, 13 }, exec_lua('return {descendant2:range()}')) - eq(true, exec_lua("return child == child")) + eq(true, exec_lua('return child == child')) -- separate lua object, but represents same node - eq(true, exec_lua("return child == root:child(0)")) - eq(false, exec_lua("return child == descendant2")) - eq(false, exec_lua("return child == nil")) - eq(false, exec_lua("return child == tree")) + eq(true, exec_lua('return child == root:child(0)')) + eq(false, exec_lua('return child == descendant2')) + eq(false, exec_lua('return child == nil')) + eq(false, exec_lua('return child == tree')) - eq("string", exec_lua("return type(child:id())")) - eq(true, exec_lua("return child:id() == child:id()")) + eq('string', exec_lua('return type(child:id())')) + eq(true, exec_lua('return child:id() == child:id()')) -- separate lua object, but represents same node - eq(true, exec_lua("return child:id() == root:child(0):id()")) - eq(false, exec_lua("return child:id() == descendant2:id()")) - eq(false, exec_lua("return child:id() == nil")) - eq(false, exec_lua("return child:id() == tree")) + eq(true, exec_lua('return child:id() == root:child(0):id()')) + eq(false, exec_lua('return child:id() == descendant2:id()')) + eq(false, exec_lua('return child:id() == nil')) + eq(false, exec_lua('return child:id() == tree')) -- unchanged buffer: return the same tree - eq(true, exec_lua("return parser:parse()[1] == tree2")) + eq(true, exec_lua('return parser:parse()[1] == tree2')) end) local test_text = [[ @@ -107,7 +112,7 @@ void ui_refresh(void) }]] it('allows to iterate over nodes children', function() - insert(test_text); + insert(test_text) local res = exec_lua([[ parser = vim.treesitter.get_parser(0, "c") @@ -122,26 +127,28 @@ void ui_refresh(void) ]]) eq({ - {"primitive_type", "type"}, - {"function_declarator", "declarator"}, - {"compound_statement", "body"} + { 'primitive_type', 'type' }, + { 'function_declarator', 'declarator' }, + { 'compound_statement', 'body' }, }, res) end) it('does not get parser for empty filetype', function() - insert(test_text); + insert(test_text) - eq('.../treesitter.lua:0: There is no parser available for buffer 1 and one' - .. ' could not be created because lang could not be determined. Either' - .. ' pass lang or set the buffer filetype', - pcall_err(exec_lua, 'vim.treesitter.get_parser(0)')) + eq( + '.../treesitter.lua:0: There is no parser available for buffer 1 and one' + .. ' could not be created because lang could not be determined. Either' + .. ' pass lang or set the buffer filetype', + pcall_err(exec_lua, 'vim.treesitter.get_parser(0)') + ) -- Must provide language for buffers with an empty filetype exec_lua("vim.treesitter.get_parser(0, 'c')") end) it('allows to get a child by field', function() - insert(test_text); + insert(test_text) local res = exec_lua([[ parser = vim.treesitter.get_parser(0, "c") @@ -155,7 +162,7 @@ void ui_refresh(void) return res ]]) - eq({{ "primitive_type", 0, 0, 0, 4 }}, res) + eq({ { 'primitive_type', 0, 0, 0, 4 } }, res) local res_fail = exec_lua([[ parser = vim.treesitter.get_parser(0, "c") @@ -166,14 +173,14 @@ void ui_refresh(void) assert(res_fail) end) - local query = [[ - ((call_expression function: (identifier) @minfunc (argument_list (identifier) @min_id)) (eq? @minfunc "MIN")) + local test_query = [[ + ((call_expression function: (identifier) @minfunc (argument_list (identifier) @min_id)) (#eq? @minfunc "MIN")) "for" @keyword (primitive_type) @type (field_expression argument: (identifier) @fieldarg) ]] - it("supports runtime queries", function() + it('supports runtime queries', function() local ret = exec_lua [[ return vim.treesitter.query.get("c", "highlights").captures[1] ]] @@ -181,10 +188,11 @@ void ui_refresh(void) eq('variable', ret) end) - it("supports caching queries", function() - local long_query = query:rep(100) + it('supports caching queries', function() + local long_query = test_query:rep(100) local function q(n) - return exec_lua ([[ + return exec_lua( + [[ local query, n = ... local before = vim.uv.hrtime() for i=1,n,1 do @@ -192,7 +200,10 @@ void ui_refresh(void) end local after = vim.uv.hrtime() return after - before - ]], long_query, n) + ]], + long_query, + n + ) end local firstrun = q(1) @@ -200,13 +211,17 @@ void ui_refresh(void) -- First run should be at least 200x slower than an 100 subsequent runs. local factor = is_os('win') and 100 or 200 - assert(factor * manyruns < firstrun, ('firstrun: %f ms, manyruns: %f ms'):format(firstrun / 1e6, manyruns / 1e6)) + assert( + factor * manyruns < firstrun, + ('firstrun: %f ms, manyruns: %f ms'):format(firstrun / 1e6, manyruns / 1e6) + ) end) it('support query and iter by capture', function() insert(test_text) - local res = exec_lua([[ + local res = exec_lua( + [[ cquery = vim.treesitter.query.parse("c", ...) parser = vim.treesitter.get_parser(0, "c") tree = parser:parse()[1] @@ -216,50 +231,124 @@ void ui_refresh(void) table.insert(res, {cquery.captures[cid], node:type(), node:range()}) end return res - ]], query) + ]], + test_query + ) eq({ - { "type", "primitive_type", 8, 2, 8, 6 }, - { "keyword", "for", 9, 2, 9, 5 }, - { "type", "primitive_type", 9, 7, 9, 13 }, - { "minfunc", "identifier", 11, 12, 11, 15 }, - { "fieldarg", "identifier", 11, 16, 11, 18 }, - { "min_id", "identifier", 11, 27, 11, 32 }, - { "minfunc", "identifier", 12, 13, 12, 16 }, - { "fieldarg", "identifier", 12, 17, 12, 19 }, - { "min_id", "identifier", 12, 29, 12, 35 }, - { "fieldarg", "identifier", 13, 14, 13, 16 } + { 'type', 'primitive_type', 8, 2, 8, 6 }, + { 'keyword', 'for', 9, 2, 9, 5 }, + { 'type', 'primitive_type', 9, 7, 9, 13 }, + { 'minfunc', 'identifier', 11, 12, 11, 15 }, + { 'fieldarg', 'identifier', 11, 16, 11, 18 }, + { 'min_id', 'identifier', 11, 27, 11, 32 }, + { 'minfunc', 'identifier', 12, 13, 12, 16 }, + { 'fieldarg', 'identifier', 12, 17, 12, 19 }, + { 'min_id', 'identifier', 12, 29, 12, 35 }, + { 'fieldarg', 'identifier', 13, 14, 13, 16 }, }, res) end) it('support query and iter by match', function() insert(test_text) - local res = exec_lua([[ + local res = exec_lua( + [[ cquery = vim.treesitter.query.parse("c", ...) parser = vim.treesitter.get_parser(0, "c") tree = parser:parse()[1] res = {} - for pattern, match in cquery:iter_matches(tree:root(), 0, 7, 14) do + for pattern, match in cquery:iter_matches(tree:root(), 0, 7, 14, { all = true }) do -- can't transmit node over RPC. just check the name and range local mrepr = {} - for cid,node in pairs(match) do - table.insert(mrepr, {cquery.captures[cid], node:type(), node:range()}) + for cid, nodes in pairs(match) do + for _, node in ipairs(nodes) do + table.insert(mrepr, {cquery.captures[cid], node:type(), node:range()}) + end end table.insert(res, {pattern, mrepr}) end return res - ]], query) + ]], + test_query + ) + + eq({ + { 3, { { 'type', 'primitive_type', 8, 2, 8, 6 } } }, + { 2, { { 'keyword', 'for', 9, 2, 9, 5 } } }, + { 3, { { 'type', 'primitive_type', 9, 7, 9, 13 } } }, + { 4, { { 'fieldarg', 'identifier', 11, 16, 11, 18 } } }, + { + 1, + { { 'minfunc', 'identifier', 11, 12, 11, 15 }, { 'min_id', 'identifier', 11, 27, 11, 32 } }, + }, + { 4, { { 'fieldarg', 'identifier', 12, 17, 12, 19 } } }, + { + 1, + { { 'minfunc', 'identifier', 12, 13, 12, 16 }, { 'min_id', 'identifier', 12, 29, 12, 35 } }, + }, + { 4, { { 'fieldarg', 'identifier', 13, 14, 13, 16 } } }, + }, res) + end) + + it('support query and iter by capture for quantifiers', function() + insert(test_text) + + local res = exec_lua( + [[ + cquery = vim.treesitter.query.parse("c", ...) + parser = vim.treesitter.get_parser(0, "c") + tree = parser:parse()[1] + res = {} + for cid, node in cquery:iter_captures(tree:root(), 0, 7, 14) do + -- can't transmit node over RPC. just check the name and range + table.insert(res, {cquery.captures[cid], node:type(), node:range()}) + end + return res + ]], + '(expression_statement (assignment_expression (call_expression)))+ @funccall' + ) eq({ - { 3, { { "type", "primitive_type", 8, 2, 8, 6 } } }, - { 2, { { "keyword", "for", 9, 2, 9, 5 } } }, - { 3, { { "type", "primitive_type", 9, 7, 9, 13 } } }, - { 4, { { "fieldarg", "identifier", 11, 16, 11, 18 } } }, - { 1, { { "minfunc", "identifier", 11, 12, 11, 15 }, { "min_id", "identifier", 11, 27, 11, 32 } } }, - { 4, { { "fieldarg", "identifier", 12, 17, 12, 19 } } }, - { 1, { { "minfunc", "identifier", 12, 13, 12, 16 }, { "min_id", "identifier", 12, 29, 12, 35 } } }, - { 4, { { "fieldarg", "identifier", 13, 14, 13, 16 } } } + { 'funccall', 'expression_statement', 11, 4, 11, 34 }, + { 'funccall', 'expression_statement', 12, 4, 12, 37 }, + { 'funccall', 'expression_statement', 13, 4, 13, 34 }, + }, res) + end) + + it('support query and iter by match for quantifiers', function() + insert(test_text) + + local res = exec_lua( + [[ + cquery = vim.treesitter.query.parse("c", ...) + parser = vim.treesitter.get_parser(0, "c") + tree = parser:parse()[1] + res = {} + for pattern, match in cquery:iter_matches(tree:root(), 0, 7, 14, { all = true }) do + -- can't transmit node over RPC. just check the name and range + local mrepr = {} + for cid, nodes in pairs(match) do + for _, node in ipairs(nodes) do + table.insert(mrepr, {cquery.captures[cid], node:type(), node:range()}) + end + end + table.insert(res, {pattern, mrepr}) + end + return res + ]], + '(expression_statement (assignment_expression (call_expression)))+ @funccall' + ) + + eq({ + { + 1, + { + { 'funccall', 'expression_statement', 11, 4, 11, 34 }, + { 'funccall', 'expression_statement', 12, 4, 12, 37 }, + { 'funccall', 'expression_statement', 13, 4, 13, 34 }, + }, + }, }, res) end) @@ -286,7 +375,9 @@ def run a = <<~E end]] insert(text) - eq('', exec_lua[[ + eq( + '', + exec_lua [[ local fake_node = {} function fake_node:start() return 3, 0, 23 @@ -301,7 +392,8 @@ end]] return 3, 0, 3, 0 end return vim.treesitter.get_node_text(fake_node, 0) - ]]) + ]] + ) end) it('support getting empty text if node range is zero width', function() @@ -338,11 +430,13 @@ end]] parser = vim.treesitter.get_parser(0, "c") tree = parser:parse()[1] res = {} - for pattern, match in cquery:iter_matches(tree:root(), 0) do + for pattern, match in cquery:iter_matches(tree:root(), 0, 0, -1, { all = true }) do -- can't transmit node over RPC. just check the name and range local mrepr = {} - for cid,node in pairs(match) do - table.insert(mrepr, {cquery.captures[cid], node:type(), node:range()}) + for cid, nodes in pairs(match) do + for _, node in ipairs(nodes) do + table.insert(mrepr, {cquery.captures[cid], node:type(), node:range()}) + end end table.insert(res, {pattern, mrepr}) end @@ -350,12 +444,12 @@ end]] ]]) eq({ - { 2, { { "times", '*', 0, 4, 0, 5 } } }, - { 5, { { "string", 'string_literal', 0, 16, 0, 20 } } }, - { 4, { { "escape", 'escape_sequence', 0, 17, 0, 19 } } }, - { 3, { { "paren", '(', 0, 22, 0, 23 } } }, - { 1, { { "plus", '+', 0, 25, 0, 26 } } }, - { 2, { { "times", '*', 0, 30, 0, 31 } } }, + { 2, { { 'times', '*', 0, 4, 0, 5 } } }, + { 5, { { 'string', 'string_literal', 0, 16, 0, 20 } } }, + { 4, { { 'escape', 'escape_sequence', 0, 17, 0, 19 } } }, + { 3, { { 'paren', '(', 0, 22, 0, 23 } } }, + { 1, { { 'plus', '+', 0, 25, 0, 26 } } }, + { 2, { { 'times', '*', 0, 30, 0, 31 } } }, }, res) end) @@ -394,54 +488,63 @@ end]] end ]]) - local res0 = exec_lua([[return get_query_result(...)]], - [[((primitive_type) @c-keyword (#any-of? @c-keyword "int" "float"))]]) + local res0 = exec_lua( + [[return get_query_result(...)]], + [[((primitive_type) @c-keyword (#any-of? @c-keyword "int" "float"))]] + ) eq({ - { "c-keyword", "primitive_type", { 2, 2, 2, 5 }, "int" }, - { "c-keyword", "primitive_type", { 3, 4, 3, 7 }, "int" }, + { 'c-keyword', 'primitive_type', { 2, 2, 2, 5 }, 'int' }, + { 'c-keyword', 'primitive_type', { 3, 4, 3, 7 }, 'int' }, }, res0) - local res1 = exec_lua([[return get_query_result(...)]], + local res1 = exec_lua( + [[return get_query_result(...)]], [[ ((string_literal) @fizzbuzz-strings (#any-of? @fizzbuzz-strings "\"number= %d FizzBuzz\\n\"" "\"number= %d Fizz\\n\"" "\"number= %d Buzz\\n\"" )) - ]]) + ]] + ) eq({ - { "fizzbuzz-strings", "string_literal", { 6, 15, 6, 38 }, "\"number= %d FizzBuzz\\n\""}, - { "fizzbuzz-strings", "string_literal", { 8, 15, 8, 34 }, "\"number= %d Fizz\\n\""}, - { "fizzbuzz-strings", "string_literal", { 10, 15, 10, 34 }, "\"number= %d Buzz\\n\""}, + { 'fizzbuzz-strings', 'string_literal', { 6, 15, 6, 38 }, '"number= %d FizzBuzz\\n"' }, + { 'fizzbuzz-strings', 'string_literal', { 8, 15, 8, 34 }, '"number= %d Fizz\\n"' }, + { 'fizzbuzz-strings', 'string_literal', { 10, 15, 10, 34 }, '"number= %d Buzz\\n"' }, }, res1) end) - it('allow loading query with escaped quotes and capture them with `lua-match?` and `vim-match?`', function() - insert('char* astring = "Hello World!";') + it( + 'allow loading query with escaped quotes and capture them with `lua-match?` and `vim-match?`', + function() + insert('char* astring = "Hello World!";') - local res = exec_lua([[ + local res = exec_lua([[ cquery = vim.treesitter.query.parse("c", '([_] @quote (#vim-match? @quote "^\\"$")) ([_] @quote (#lua-match? @quote "^\\"$"))') parser = vim.treesitter.get_parser(0, "c") tree = parser:parse()[1] res = {} - for pattern, match in cquery:iter_matches(tree:root(), 0) do + for pattern, match in cquery:iter_matches(tree:root(), 0, 0, -1, { all = true }) do -- can't transmit node over RPC. just check the name and range local mrepr = {} - for cid,node in pairs(match) do - table.insert(mrepr, {cquery.captures[cid], node:type(), node:range()}) + for cid, nodes in pairs(match) do + for _, node in ipairs(nodes) do + table.insert(mrepr, {cquery.captures[cid], node:type(), node:range()}) + end end table.insert(res, {pattern, mrepr}) end return res ]]) - eq({ - { 1, { { "quote", '"', 0, 16, 0, 17 } } }, - { 2, { { "quote", '"', 0, 16, 0, 17 } } }, - { 1, { { "quote", '"', 0, 29, 0, 30 } } }, - { 2, { { "quote", '"', 0, 29, 0, 30 } } }, - }, res) - end) + eq({ + { 1, { { 'quote', '"', 0, 16, 0, 17 } } }, + { 2, { { 'quote', '"', 0, 16, 0, 17 } } }, + { 1, { { 'quote', '"', 0, 29, 0, 30 } } }, + { 2, { { 'quote', '"', 0, 29, 0, 30 } } }, + }, res) + end + ) it('allows to add predicates', function() insert([[ @@ -450,44 +553,250 @@ end]] } ]]) - local custom_query = "((identifier) @main (#is-main? @main))" + local custom_query = '((identifier) @main (#is-main? @main))' - local res = exec_lua([[ - local query = vim.treesitter.query + do + local res = exec_lua( + [[ + local query = vim.treesitter.query + + local function is_main(match, pattern, bufnr, predicate) + local nodes = match[ predicate[2] ] + for _, node in ipairs(nodes) do + if vim.treesitter.get_node_text(node, bufnr) == 'main' then + return true + end + end + return false + end + + local parser = vim.treesitter.get_parser(0, "c") - local function is_main(match, pattern, bufnr, predicate) - local node = match[ predicate[2] ] + -- Time bomb: update this in 0.12 + if vim.fn.has('nvim-0.12') == 1 then + return 'Update this test to remove this message and { all = true } from add_predicate' + end + query.add_predicate("is-main?", is_main, { all = true }) + + local query = query.parse("c", ...) + + local nodes = {} + for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do + table.insert(nodes, {node:range()}) + end + + return nodes + ]], + custom_query + ) - return query.get_node_text(node, bufnr) + eq({ { 0, 4, 0, 8 } }, res) end - local parser = vim.treesitter.get_parser(0, "c") + -- Once with the old API. Remove this whole 'do' block in 0.12 + do + local res = exec_lua( + [[ + local query = vim.treesitter.query - query.add_predicate("is-main?", is_main) + local function is_main(match, pattern, bufnr, predicate) + local node = match[ predicate[2] ] - local query = query.parse("c", ...) + return vim.treesitter.get_node_text(node, bufnr) == 'main' + end - local nodes = {} - for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do - table.insert(nodes, {node:range()}) + local parser = vim.treesitter.get_parser(0, "c") + + query.add_predicate("is-main?", is_main, true) + + local query = query.parse("c", ...) + + local nodes = {} + for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do + table.insert(nodes, {node:range()}) + end + + return nodes + ]], + custom_query + ) + + -- Remove this 'do' block in 0.12 + eq(0, fn.has('nvim-0.12')) + eq({ { 0, 4, 0, 8 } }, res) end - return nodes - ]], custom_query) + do + local res = exec_lua [[ + local query = vim.treesitter.query - eq({{0, 4, 0, 8}}, res) + local t = {} + for _, v in ipairs(query.list_predicates()) do + t[v] = true + end - local res_list = exec_lua[[ - local query = vim.treesitter.query + return t + ]] - local list = query.list_predicates() + eq(true, res['is-main?']) + end + end) - table.sort(list) + it('supports "all" and "any" semantics for predicates on quantified captures #24738', function() + local query_all = [[ + (((comment (comment_content))+) @bar + (#lua-match? @bar "Yes")) + ]] + + local query_any = [[ + (((comment (comment_content))+) @bar + (#any-lua-match? @bar "Yes")) + ]] + + local function test(input, query) + api.nvim_buf_set_lines(0, 0, -1, true, vim.split(dedent(input), '\n')) + return exec_lua( + [[ + local parser = vim.treesitter.get_parser(0, "lua") + local query = vim.treesitter.query.parse("lua", ...) + local nodes = {} + for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do + nodes[#nodes+1] = { node:range() } + end + return nodes + ]], + query + ) + end + + eq( + {}, + test( + [[ + -- Yes + -- No + -- Yes + ]], + query_all + ) + ) + + eq( + { + { 0, 2, 0, 8 }, + { 1, 2, 1, 8 }, + { 2, 2, 2, 8 }, + }, + test( + [[ + -- Yes + -- Yes + -- Yes + ]], + query_all + ) + ) + + eq( + {}, + test( + [[ + -- No + -- No + -- No + ]], + query_any + ) + ) + + eq( + { + { 0, 2, 0, 7 }, + { 1, 2, 1, 8 }, + { 2, 2, 2, 7 }, + }, + test( + [[ + -- No + -- Yes + -- No + ]], + query_any + ) + ) + end) + + it('supports any- prefix to match any capture when using quantifiers #24738', function() + insert([[ + -- Comment + -- Comment + -- Comment + ]]) - return list + local query = [[ + (((comment (comment_content))+) @bar + (#lua-match? @bar "Comment")) ]] - eq({ 'any-of?', 'contains?', 'eq?', 'has-ancestor?', 'has-parent?', 'is-main?', 'lua-match?', 'match?', 'vim-match?' }, res_list) + local result = exec_lua( + [[ + local parser = vim.treesitter.get_parser(0, "lua") + local query = vim.treesitter.query.parse("lua", ...) + local nodes = {} + for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do + nodes[#nodes+1] = { node:range() } + end + return nodes + ]], + query + ) + + eq({ + { 0, 2, 0, 12 }, + { 1, 2, 1, 12 }, + { 2, 2, 2, 12 }, + }, result) + end) + + it('supports the old broken version of iter_matches #24738', function() + -- Delete this test in 0.12 when iter_matches is removed + eq(0, fn.has('nvim-0.12')) + + insert(test_text) + local res = exec_lua( + [[ + cquery = vim.treesitter.query.parse("c", ...) + parser = vim.treesitter.get_parser(0, "c") + tree = parser:parse()[1] + res = {} + for pattern, match in cquery:iter_matches(tree:root(), 0, 7, 14) do + local mrepr = {} + for cid, node in pairs(match) do + table.insert(mrepr, {cquery.captures[cid], node:type(), node:range()}) + end + table.insert(res, {pattern, mrepr}) + end + return res + ]], + test_query + ) + + eq({ + { 3, { { 'type', 'primitive_type', 8, 2, 8, 6 } } }, + { 2, { { 'keyword', 'for', 9, 2, 9, 5 } } }, + { 3, { { 'type', 'primitive_type', 9, 7, 9, 13 } } }, + { 4, { { 'fieldarg', 'identifier', 11, 16, 11, 18 } } }, + { + 1, + { { 'minfunc', 'identifier', 11, 12, 11, 15 }, { 'min_id', 'identifier', 11, 27, 11, 32 } }, + }, + { 4, { { 'fieldarg', 'identifier', 12, 17, 12, 19 } } }, + { + 1, + { { 'minfunc', 'identifier', 12, 13, 12, 16 }, { 'min_id', 'identifier', 12, 29, 12, 35 } }, + }, + { 4, { { 'fieldarg', 'identifier', 13, 14, 13, 16 } } }, + }, res) end) it('allows to set simple ranges', function() @@ -498,7 +807,7 @@ end]] return { parser:parse()[1]:root():range() } ]] - eq({0, 0, 19, 0}, res) + eq({ 0, 0, 19, 0 }, res) -- The following sets the included ranges for the current parser -- As stated here, this only includes the function (thus the whole buffer, without the last line) @@ -509,7 +818,7 @@ end]] return { parser:parse(true)[1]:root():range() } ]] - eq({0, 0, 18, 1}, res2) + eq({ 0, 0, 18, 1 }, res2) eq({ { { 0, 0, 0, 18, 1, 512 } } }, exec_lua [[ return parser:included_regions() ]]) @@ -522,7 +831,7 @@ end]] eq(range_tbl, { { { 0, 0, 0, 17, 1, 508 } } }) end) - it("allows to set complex ranges", function() + it('allows to set complex ranges', function() insert(test_text) local res = exec_lua [[ @@ -552,10 +861,11 @@ end]] { 8, 2, 8, 33 }, { 9, 7, 9, 20 }, { 10, 4, 10, 20 }, - { 14, 9, 14, 27 } }, res) + { 14, 9, 14, 27 }, + }, res) end) - it("allows to create string parsers", function() + it('allows to create string parsers', function() local ret = exec_lua [[ local parser = vim.treesitter.get_string_parser("int foo = 42;", "c") return { parser:parse()[1]:root():range() } @@ -564,35 +874,39 @@ end]] eq({ 0, 0, 0, 13 }, ret) end) - it("allows to run queries with string parsers", function() + it('allows to run queries with string parsers', function() local txt = [[ int foo = 42; int bar = 13; ]] - local ret = exec_lua([[ + local ret = exec_lua( + [[ local str = ... local parser = vim.treesitter.get_string_parser(str, "c") local nodes = {} - local query = vim.treesitter.query.parse("c", '((identifier) @id (eq? @id "foo"))') + local query = vim.treesitter.query.parse("c", '((identifier) @id (#eq? @id "foo"))') for _, node in query:iter_captures(parser:parse()[1]:root(), str) do table.insert(nodes, { node:range() }) end - return nodes]], txt) + return nodes]], + txt + ) - eq({ {0, 10, 0, 13} }, ret) + eq({ { 0, 10, 0, 13 } }, ret) end) - it("should use node range when omitted", function() + it('should use node range when omitted', function() local txt = [[ int foo = 42; int bar = 13; ]] - local ret = exec_lua([[ + local ret = exec_lua( + [[ local str = ... local parser = vim.treesitter.get_string_parser(str, "c") @@ -604,12 +918,14 @@ end]] table.insert(nodes, { node:range() }) end - return nodes]], txt) + return nodes]], + txt + ) - eq({ {1, 10, 1, 13} }, ret) + eq({ { 1, 10, 1, 13 } }, ret) end) - describe("when creating a language tree", function() + describe('when creating a language tree', function() local function get_ranges() return exec_lua([[ local result = {} @@ -629,8 +945,8 @@ int x = INT_MAX; ]]) end) - describe("when parsing regions independently", function() - it("should inject a language", function() + describe('when parsing regions independently', function() + it('should inject a language', function() exec_lua([[ parser = vim.treesitter.get_parser(0, "c", { injections = { @@ -638,32 +954,32 @@ int x = INT_MAX; parser:parse(true) ]]) - eq("table", exec_lua("return type(parser:children().c)")) - eq(5, exec_lua("return #parser:children().c:trees()")) + eq('table', exec_lua('return type(parser:children().c)')) + eq(5, exec_lua('return #parser:children().c:trees()')) eq({ - {0, 0, 7, 0}, -- root tree - {3, 14, 3, 17}, -- VALUE 123 - {4, 15, 4, 18}, -- VALUE1 123 - {5, 15, 5, 18}, -- VALUE2 123 - {1, 26, 1, 63}, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) - {2, 29, 2, 66} -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) + { 0, 0, 7, 0 }, -- root tree + { 3, 14, 3, 17 }, -- VALUE 123 + { 4, 15, 4, 18 }, -- VALUE1 123 + { 5, 15, 5, 18 }, -- VALUE2 123 + { 1, 26, 1, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) + { 2, 29, 2, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) }, get_ranges()) helpers.feed('ggo<esc>') - eq(5, exec_lua("return #parser:children().c:trees()")) + eq(5, exec_lua('return #parser:children().c:trees()')) eq({ - {0, 0, 8, 0}, -- root tree - {4, 14, 4, 17}, -- VALUE 123 - {5, 15, 5, 18}, -- VALUE1 123 - {6, 15, 6, 18}, -- VALUE2 123 - {2, 26, 2, 63}, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) - {3, 29, 3, 66} -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) + { 0, 0, 8, 0 }, -- root tree + { 4, 14, 4, 17 }, -- VALUE 123 + { 5, 15, 5, 18 }, -- VALUE1 123 + { 6, 15, 6, 18 }, -- VALUE2 123 + { 2, 26, 2, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) + { 3, 29, 3, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) }, get_ranges()) end) end) - describe("when parsing regions combined", function() - it("should inject a language", function() + describe('when parsing regions combined', function() + it('should inject a language', function() exec_lua([[ parser = vim.treesitter.get_parser(0, "c", { injections = { @@ -671,33 +987,45 @@ int x = INT_MAX; parser:parse(true) ]]) - eq("table", exec_lua("return type(parser:children().c)")) - eq(2, exec_lua("return #parser:children().c:trees()")) + eq('table', exec_lua('return type(parser:children().c)')) + eq(2, exec_lua('return #parser:children().c:trees()')) eq({ - {0, 0, 7, 0}, -- root tree - {3, 14, 5, 18}, -- VALUE 123 - -- VALUE1 123 - -- VALUE2 123 - {1, 26, 2, 66} -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) - -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) + { 0, 0, 7, 0 }, -- root tree + { 3, 14, 5, 18 }, -- VALUE 123 + -- VALUE1 123 + -- VALUE2 123 + { 1, 26, 2, 66 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) + -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) }, get_ranges()) helpers.feed('ggo<esc>') - eq("table", exec_lua("return type(parser:children().c)")) - eq(2, exec_lua("return #parser:children().c:trees()")) + eq('table', exec_lua('return type(parser:children().c)')) + eq(2, exec_lua('return #parser:children().c:trees()')) eq({ - {0, 0, 8, 0}, -- root tree - {4, 14, 6, 18}, -- VALUE 123 - -- VALUE1 123 - -- VALUE2 123 - {2, 26, 3, 66} -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) - -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) + { 0, 0, 8, 0 }, -- root tree + { 4, 14, 6, 18 }, -- VALUE 123 + -- VALUE1 123 + -- VALUE2 123 + { 2, 26, 3, 66 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) + -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) + }, get_ranges()) + + helpers.feed('7ggI//<esc>') + exec_lua([[parser:parse({6, 7})]]) + eq('table', exec_lua('return type(parser:children().c)')) + eq(2, exec_lua('return #parser:children().c:trees()')) + eq({ + { 0, 0, 8, 0 }, -- root tree + { 4, 14, 5, 18 }, -- VALUE 123 + -- VALUE1 123 + { 2, 26, 3, 66 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) + -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) }, get_ranges()) end) end) - describe("when using injection.self", function() - it("should inject the source language", function() + describe('when using injection.self', function() + it('should inject the source language', function() exec_lua([[ parser = vim.treesitter.get_parser(0, "c", { injections = { @@ -705,32 +1033,32 @@ int x = INT_MAX; parser:parse(true) ]]) - eq("table", exec_lua("return type(parser:children().c)")) - eq(5, exec_lua("return #parser:children().c:trees()")) + eq('table', exec_lua('return type(parser:children().c)')) + eq(5, exec_lua('return #parser:children().c:trees()')) eq({ - {0, 0, 7, 0}, -- root tree - {3, 14, 3, 17}, -- VALUE 123 - {4, 15, 4, 18}, -- VALUE1 123 - {5, 15, 5, 18}, -- VALUE2 123 - {1, 26, 1, 63}, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) - {2, 29, 2, 66} -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) + { 0, 0, 7, 0 }, -- root tree + { 3, 14, 3, 17 }, -- VALUE 123 + { 4, 15, 4, 18 }, -- VALUE1 123 + { 5, 15, 5, 18 }, -- VALUE2 123 + { 1, 26, 1, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) + { 2, 29, 2, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) }, get_ranges()) helpers.feed('ggo<esc>') - eq(5, exec_lua("return #parser:children().c:trees()")) + eq(5, exec_lua('return #parser:children().c:trees()')) eq({ - {0, 0, 8, 0}, -- root tree - {4, 14, 4, 17}, -- VALUE 123 - {5, 15, 5, 18}, -- VALUE1 123 - {6, 15, 6, 18}, -- VALUE2 123 - {2, 26, 2, 63}, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) - {3, 29, 3, 66} -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) + { 0, 0, 8, 0 }, -- root tree + { 4, 14, 4, 17 }, -- VALUE 123 + { 5, 15, 5, 18 }, -- VALUE1 123 + { 6, 15, 6, 18 }, -- VALUE2 123 + { 2, 26, 2, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) + { 3, 29, 3, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) }, get_ranges()) end) end) - describe("when using the offset directive", function() - it("should shift the range by the directive amount", function() + describe('when using the offset directive', function() + it('should shift the range by the directive amount', function() exec_lua([[ parser = vim.treesitter.get_parser(0, "c", { injections = { @@ -738,18 +1066,18 @@ int x = INT_MAX; parser:parse(true) ]]) - eq("table", exec_lua("return type(parser:children().c)")) + eq('table', exec_lua('return type(parser:children().c)')) eq({ - {0, 0, 7, 0}, -- root tree - {3, 16, 3, 16}, -- VALUE 123 - {4, 17, 4, 17}, -- VALUE1 123 - {5, 17, 5, 17}, -- VALUE2 123 - {1, 26, 1, 63}, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) - {2, 29, 2, 66} -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) + { 0, 0, 7, 0 }, -- root tree + { 3, 16, 3, 16 }, -- VALUE 123 + { 4, 17, 4, 17 }, -- VALUE1 123 + { 5, 17, 5, 17 }, -- VALUE2 123 + { 1, 26, 1, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) + { 2, 29, 2, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) }, get_ranges()) end) - it("should list all directives", function() - local res_list = exec_lua[[ + it('should list all directives', function() + local res_list = exec_lua [[ local query = vim.treesitter.query local list = query.list_directives() @@ -764,7 +1092,7 @@ int x = INT_MAX; end) end) - describe("when getting the language for a range", function() + describe('when getting the language for a range', function() before_each(function() insert([[ int x = INT_MAX; @@ -772,7 +1100,7 @@ int x = INT_MAX; ]]) end) - it("should return the correct language tree", function() + it('should return the correct language tree', function() local result = exec_lua([[ parser = vim.treesitter.get_parser(0, "c", { injections = { c = '(preproc_def (preproc_arg) @injection.content (#set! injection.language "c"))'}}) @@ -787,9 +1115,9 @@ int x = INT_MAX; end) end) - describe("when getting/setting match data", function() - describe("when setting for the whole match", function() - it("should set/get the data correctly", function() + describe('when getting/setting match data', function() + describe('when setting for the whole match', function() + it('should set/get the data correctly', function() insert([[ int x = 3; ]]) @@ -800,18 +1128,18 @@ int x = INT_MAX; query = vim.treesitter.query.parse("c", '((number_literal) @number (#set! "key" "value"))') parser = vim.treesitter.get_parser(0, "c") - for pattern, match, metadata in query:iter_matches(parser:parse()[1]:root(), 0) do + for pattern, match, metadata in query:iter_matches(parser:parse()[1]:root(), 0, 0, -1, { all = true }) do result = metadata.key end return result ]]) - eq(result, "value") + eq(result, 'value') end) - describe("when setting a key on a capture", function() - it("it should create the nested table", function() + describe('when setting a key on a capture', function() + it('it should create the nested table', function() insert([[ int x = 3; ]]) @@ -823,17 +1151,17 @@ int x = INT_MAX; query = vim.treesitter.query.parse("c", '((number_literal) @number (#set! @number "key" "value"))') parser = vim.treesitter.get_parser(0, "c") - for pattern, match, metadata in query:iter_matches(parser:parse()[1]:root(), 0) do + for pattern, match, metadata in query:iter_matches(parser:parse()[1]:root(), 0, 0, -1, { all = true }) do for _, nested_tbl in pairs(metadata) do return nested_tbl.key end end ]]) - eq(result, "value") + eq(result, 'value') end) - it("it should not overwrite the nested table", function() + it('it should not overwrite the nested table', function() insert([[ int x = 3; ]]) @@ -845,15 +1173,15 @@ int x = INT_MAX; query = vim.treesitter.query.parse("c", '((number_literal) @number (#set! @number "key" "value") (#set! @number "key2" "value2"))') parser = vim.treesitter.get_parser(0, "c") - for pattern, match, metadata in query:iter_matches(parser:parse()[1]:root(), 0) do + for pattern, match, metadata in query:iter_matches(parser:parse()[1]:root(), 0, 0, -1, { all = true }) do for _, nested_tbl in pairs(metadata) do return nested_tbl end end ]]) local expected = { - ["key"] = "value", - ["key2"] = "value2", + ['key'] = 'value', + ['key2'] = 'value2', } eq(expected, result) @@ -878,7 +1206,8 @@ int x = INT_MAX; ]]) local function run_query() - return exec_lua([[ + return exec_lua( + [[ local query = vim.treesitter.query.parse("c", ...) parser = vim.treesitter.get_parser() tree = parser:parse()[1] @@ -887,23 +1216,24 @@ int x = INT_MAX; table.insert(res, {query.captures[id], node:range()}) end return res - ]], query0) + ]], + query0 + ) end eq({ { 'function', 0, 0, 2, 1 }, - { 'declaration', 1, 2, 1, 12 } + { 'declaration', 1, 2, 1, 12 }, }, run_query()) - helpers.command'normal ggO' + helpers.command 'normal ggO' insert('int a;') eq({ { 'declaration', 0, 0, 0, 6 }, { 'function', 1, 0, 3, 1 }, - { 'declaration', 2, 2, 2, 12 } + { 'declaration', 2, 2, 2, 12 }, }, run_query()) - end) it('handles ranges when source is a multiline string (#20419)', function() @@ -926,7 +1256,8 @@ int x = INT_MAX; ]] ]==] - local r = exec_lua([[ + local r = exec_lua( + [[ local parser = vim.treesitter.get_string_parser(..., 'lua') parser:parse(true) local ranges = {} @@ -934,19 +1265,22 @@ int x = INT_MAX; ranges[tree:lang()] = { tstree:root():range(true) } end) return ranges - ]], source) + ]], + source + ) eq({ lua = { 0, 6, 6, 16, 4, 438 }, query = { 6, 20, 113, 15, 6, 431 }, - vim = { 1, 0, 16, 4, 6, 89 } + vim = { 1, 0, 16, 4, 6, 89 }, }, r) -- The above ranges are provided directly from treesitter, however query directives may mutate -- the ranges but only provide a Range4. Strip the byte entries from the ranges and make sure -- add_bytes() produces the same result. - local rb = exec_lua([[ + local rb = exec_lua( + [[ local r, source = ... local add_bytes = require('vim.treesitter._range').add_bytes for lang, range in pairs(r) do @@ -954,13 +1288,15 @@ int x = INT_MAX; r[lang] = add_bytes(source, r[lang]) end return r - ]], r, source) + ]], + r, + source + ) eq(rb, r) - end) - it("does not produce empty injection ranges (#23409)", function() + it('does not produce empty injection ranges (#23409)', function() insert [[ Examples: >lua local a = {} @@ -977,7 +1313,7 @@ int x = INT_MAX; parser1:parse(true) ]] - eq(0, exec_lua("return #vim.tbl_keys(parser1:children())")) + eq(0, exec_lua('return #vim.tbl_keys(parser1:children())')) exec_lua [[ parser2 = require('vim.treesitter.languagetree').new(0, "vimdoc", { @@ -988,13 +1324,12 @@ int x = INT_MAX; parser2:parse(true) ]] - eq(1, exec_lua("return #vim.tbl_keys(parser2:children())")) - eq( { { { 1, 0, 21, 2, 0, 42 } } }, exec_lua("return parser2:children().lua:included_regions()")) - + eq(1, exec_lua('return #vim.tbl_keys(parser2:children())')) + eq({ { { 1, 0, 21, 2, 0, 42 } } }, exec_lua('return parser2:children().lua:included_regions()')) end) - it("parsers injections incrementally", function() - insert(dedent[[ + it('parsers injections incrementally', function() + insert(dedent [[ >lua local a = {} < @@ -1033,26 +1368,38 @@ int x = INT_MAX; ]] --- Do not parse injections by default - eq(0, exec_lua [[ + eq( + 0, + exec_lua [[ parser:parse() return #vim.tbl_keys(parser:children()) - ]]) + ]] + ) --- Only parse injections between lines 0, 2 - eq(1, exec_lua [[ + eq( + 1, + exec_lua [[ parser:parse({0, 2}) return #parser:children().lua:trees() - ]]) + ]] + ) - eq(2, exec_lua [[ + eq( + 2, + exec_lua [[ parser:parse({2, 6}) return #parser:children().lua:trees() - ]]) + ]] + ) - eq(7, exec_lua [[ + eq( + 7, + exec_lua [[ parser:parse(true) return #parser:children().lua:trees() - ]]) + ]] + ) end) it('fails to load queries', function() @@ -1062,43 +1409,48 @@ int x = INT_MAX; -- Invalid node type test( - '.../query.lua:0: Query error at 1:2. Invalid node type "dentifier":\n'.. - '(dentifier) @variable\n'.. - ' ^', - '(dentifier) @variable') + '.../query.lua:0: Query error at 1:2. Invalid node type "dentifier":\n' + .. '(dentifier) @variable\n' + .. ' ^', + '(dentifier) @variable' + ) -- Impossible pattern test( - '.../query.lua:0: Query error at 1:13. Impossible pattern:\n'.. - '(identifier (identifier) @variable)\n'.. - ' ^', - '(identifier (identifier) @variable)') + '.../query.lua:0: Query error at 1:13. Impossible pattern:\n' + .. '(identifier (identifier) @variable)\n' + .. ' ^', + '(identifier (identifier) @variable)' + ) -- Invalid syntax test( - '.../query.lua:0: Query error at 1:13. Invalid syntax:\n'.. - '(identifier @variable\n'.. - ' ^', - '(identifier @variable') + '.../query.lua:0: Query error at 1:13. Invalid syntax:\n' + .. '(identifier @variable\n' + .. ' ^', + '(identifier @variable' + ) -- Invalid field name test( - '.../query.lua:0: Query error at 1:15. Invalid field name "invalid_field":\n'.. - '((identifier) invalid_field: (identifier))\n'.. - ' ^', - '((identifier) invalid_field: (identifier))') + '.../query.lua:0: Query error at 1:15. Invalid field name "invalid_field":\n' + .. '((identifier) invalid_field: (identifier))\n' + .. ' ^', + '((identifier) invalid_field: (identifier))' + ) -- Invalid capture name test( - '.../query.lua:0: Query error at 3:2. Invalid capture name "ok.capture":\n'.. - '@ok.capture\n'.. - ' ^', - '((identifier) @id \n(#eq? @id\n@ok.capture\n))') + '.../query.lua:0: Query error at 3:2. Invalid capture name "ok.capture":\n' + .. '@ok.capture\n' + .. ' ^', + '((identifier) @id \n(#eq? @id\n@ok.capture\n))' + ) end) describe('is_valid()', function() before_each(function() - insert(dedent[[ + insert(dedent [[ Treesitter integration *treesitter* Nvim integrates the `tree-sitter` library for incremental parsing of buffers: @@ -1137,7 +1489,7 @@ int x = INT_MAX; describe('when adding content with injections', function() before_each(function() feed('G') - insert(dedent[[ + insert(dedent [[ >lua local a = {} < @@ -1156,23 +1508,29 @@ int x = INT_MAX; eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()')) end) - it('is fully valid after a range parse that leads to parsing not parsed injections', function() - exec_lua('vim.treesitter.get_parser():parse({5, 7})') - eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)')) - eq(true, exec_lua('return vim.treesitter.get_parser():is_valid()')) - end) - - it('is valid excluding, invalid including children after a range parse that does not lead to parsing not parsed injections', function() - exec_lua('vim.treesitter.get_parser():parse({2, 4})') - eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)')) - eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()')) - end) + it( + 'is fully valid after a range parse that leads to parsing not parsed injections', + function() + exec_lua('vim.treesitter.get_parser():parse({5, 7})') + eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)')) + eq(true, exec_lua('return vim.treesitter.get_parser():is_valid()')) + end + ) + + it( + 'is valid excluding, invalid including children after a range parse that does not lead to parsing not parsed injections', + function() + exec_lua('vim.treesitter.get_parser():parse({2, 4})') + eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)')) + eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()')) + end + ) end) describe('when removing content with injections', function() before_each(function() feed('G') - insert(dedent[[ + insert(dedent [[ >lua local a = {} < @@ -1205,11 +1563,14 @@ int x = INT_MAX; eq(true, exec_lua('return vim.treesitter.get_parser():is_valid()')) end) - it('is valid excluding, invalid including children after a range parse that does not lead to parsing modified child tree', function() - exec_lua('vim.treesitter.get_parser():parse({2, 4})') - eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)')) - eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()')) - end) + it( + 'is valid excluding, invalid including children after a range parse that does not lead to parsing modified child tree', + function() + exec_lua('vim.treesitter.get_parser():parse({2, 4})') + eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)')) + eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()')) + end + ) end) end) end) diff --git a/test/functional/treesitter/utils_spec.lua b/test/functional/treesitter/utils_spec.lua index 9c07959098..2734c22499 100644 --- a/test/functional/treesitter/utils_spec.lua +++ b/test/functional/treesitter/utils_spec.lua @@ -11,7 +11,6 @@ describe('treesitter utils', function() before_each(clear) it('can find an ancestor', function() - insert([[ int main() { int x = 3; diff --git a/test/functional/ui/bufhl_spec.lua b/test/functional/ui/bufhl_spec.lua index 81e514c9aa..896f75a681 100644 --- a/test/functional/ui/bufhl_spec.lua +++ b/test/functional/ui/bufhl_spec.lua @@ -3,9 +3,10 @@ local Screen = require('test.functional.ui.screen') local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert local command, neq = helpers.command, helpers.neq -local meths = helpers.meths -local curbufmeths, eq = helpers.curbufmeths, helpers.eq +local api = helpers.api +local eq = helpers.eq local pcall_err = helpers.pcall_err +local set_virtual_text = api.nvim_buf_set_virtual_text describe('Buffer highlighting', function() local screen @@ -16,31 +17,31 @@ describe('Buffer highlighting', function() screen = Screen.new(40, 8) screen:attach() screen:set_default_attr_ids({ - [1] = {bold=true, foreground=Screen.colors.Blue}, - [2] = {foreground = Screen.colors.Fuchsia}, -- String - [3] = {foreground = Screen.colors.Brown, bold = true}, -- Statement - [4] = {foreground = Screen.colors.SlateBlue}, -- Special - [5] = {bold = true, foreground = Screen.colors.SlateBlue}, - [6] = {foreground = Screen.colors.DarkCyan}, -- Identifier - [7] = {bold = true}, - [8] = {underline = true, bold = true, foreground = Screen.colors.SlateBlue}, - [9] = {foreground = Screen.colors.SlateBlue, underline = true}, - [10] = {foreground = Screen.colors.Red}, - [11] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [12] = {foreground = Screen.colors.Blue1}, - [13] = {background = Screen.colors.LightGrey}, - [14] = {background = Screen.colors.Gray90}, - [15] = {background = Screen.colors.Gray90, bold = true, foreground = Screen.colors.Brown}, - [16] = {foreground = Screen.colors.Magenta, background = Screen.colors.Gray90}, - [17] = {foreground = Screen.colors.Magenta, background = Screen.colors.LightRed}, - [18] = {background = Screen.colors.LightRed}, - [19] = {foreground = Screen.colors.Blue1, background = Screen.colors.LightRed}, - [20] = {underline = true, bold = true, foreground = Screen.colors.Cyan4}, + [1] = { bold = true, foreground = Screen.colors.Blue }, + [2] = { foreground = Screen.colors.Fuchsia }, -- String + [3] = { foreground = Screen.colors.Brown, bold = true }, -- Statement + [4] = { foreground = Screen.colors.SlateBlue }, -- Special + [5] = { bold = true, foreground = Screen.colors.SlateBlue }, + [6] = { foreground = Screen.colors.DarkCyan }, -- Identifier + [7] = { bold = true }, + [8] = { underline = true, bold = true, foreground = Screen.colors.SlateBlue }, + [9] = { foreground = Screen.colors.SlateBlue, underline = true }, + [10] = { foreground = Screen.colors.Red }, + [11] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [12] = { foreground = Screen.colors.Blue1 }, + [13] = { foreground = Screen.colors.Black, background = Screen.colors.LightGrey }, + [14] = { background = Screen.colors.Gray90 }, + [15] = { background = Screen.colors.Gray90, bold = true, foreground = Screen.colors.Brown }, + [16] = { foreground = Screen.colors.Magenta, background = Screen.colors.Gray90 }, + [17] = { foreground = Screen.colors.Magenta, background = Screen.colors.LightRed }, + [18] = { background = Screen.colors.LightRed }, + [19] = { foreground = Screen.colors.Blue1, background = Screen.colors.LightRed }, + [20] = { underline = true, bold = true, foreground = Screen.colors.Cyan4 }, }) end) - local add_highlight = curbufmeths.add_highlight - local clear_namespace = curbufmeths.clear_namespace + local add_highlight = api.nvim_buf_add_highlight + local clear_namespace = api.nvim_buf_clear_namespace it('works', function() insert([[ @@ -51,49 +52,35 @@ describe('Buffer highlighting', function() screen:expect([[ these are some lines | with colorful tex^t | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | ]]) - add_highlight(-1, "String", 0 , 10, 14) - add_highlight(-1, "Statement", 1 , 5, -1) + add_highlight(0, -1, 'String', 0, 10, 14) + add_highlight(0, -1, 'Statement', 1, 5, -1) screen:expect([[ these are {2:some} lines | with {3:colorful tex^t} | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | ]]) - feed("ggo<esc>") + feed('ggo<esc>') screen:expect([[ these are {2:some} lines | ^ | with {3:colorful text} | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]) - clear_namespace(-1, 0, -1) + clear_namespace(0, -1, 0, -1) screen:expect([[ these are some lines | ^ | with colorful text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]) end) @@ -107,89 +94,79 @@ describe('Buffer highlighting', function() combining highlights from different sources]]) - command("hi ImportantWord gui=bold cterm=bold") - id1 = add_highlight(0, "ImportantWord", 0, 2, 8) - add_highlight(id1, "ImportantWord", 1, 12, -1) - add_highlight(id1, "ImportantWord", 2, 0, 9) - add_highlight(id1, "ImportantWord", 3, 5, 14) + command('hi ImportantWord gui=bold cterm=bold') + id1 = add_highlight(0, 0, 'ImportantWord', 0, 2, 8) + add_highlight(0, id1, 'ImportantWord', 1, 12, -1) + add_highlight(0, id1, 'ImportantWord', 2, 0, 9) + add_highlight(0, id1, 'ImportantWord', 3, 5, 14) -- add_highlight can be called like this to get a new source -- without adding any highlight - id2 = add_highlight(0, "", 0, 0, 0) + id2 = add_highlight(0, 0, '', 0, 0, 0) neq(id1, id2) - add_highlight(id2, "Special", 0, 2, 8) - add_highlight(id2, "Identifier", 1, 3, 8) - add_highlight(id2, "Special", 1, 14, 20) - add_highlight(id2, "Underlined", 2, 6, 12) - add_highlight(id2, "Underlined", 3, 0, 9) + add_highlight(0, id2, 'Special', 0, 2, 8) + add_highlight(0, id2, 'Identifier', 1, 3, 8) + add_highlight(0, id2, 'Special', 1, 14, 20) + add_highlight(0, id2, 'Underlined', 2, 6, 12) + add_highlight(0, id2, 'Underlined', 3, 0, 9) screen:expect([[ a {5:longer} example | in {6:order} to {7:de}{5:monstr}{7:ate} | {7:combin}{8:ing}{9: hi}ghlights | {9:from }{8:diff}{7:erent} source^s | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]) end) it('and clearing the first added', function() - clear_namespace(id1, 0, -1) + clear_namespace(0, id1, 0, -1) screen:expect([[ a {4:longer} example | in {6:order} to de{4:monstr}ate | combin{9:ing hi}ghlights | {9:from diff}erent source^s | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]) end) it('and clearing using deprecated name', function() - curbufmeths.clear_highlight(id1, 0, -1) + api.nvim_buf_clear_highlight(0, id1, 0, -1) screen:expect([[ a {4:longer} example | in {6:order} to de{4:monstr}ate | combin{9:ing hi}ghlights | {9:from diff}erent source^s | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]) end) it('and clearing the second added', function() - clear_namespace(id2, 0, -1) + clear_namespace(0, id2, 0, -1) screen:expect([[ a {7:longer} example | in order to {7:demonstrate} | {7:combining} highlights | from {7:different} source^s | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]) end) it('and clearing line ranges', function() - clear_namespace(-1, 0, 1) - clear_namespace(id1, 1, 2) - clear_namespace(id2, 2, -1) + clear_namespace(0, -1, 0, 1) + clear_namespace(0, id1, 1, 2) + clear_namespace(0, id2, 2, -1) screen:expect([[ a longer example | in {6:order} to de{4:monstr}ate | {7:combining} highlights | from {7:different} source^s | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]) end) @@ -201,9 +178,7 @@ describe('Buffer highlighting', function() ^ | in {6:order} to {7:de}{5:monstr}{7:ate} | {9:from }{8:diff}{7:erent} sources | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]) @@ -211,231 +186,229 @@ describe('Buffer highlighting', function() -- the deleted line wrapping around. we should invalidate -- highlights when they are completely inside deleted text command('3move 4') - screen:expect{grid=[[ + screen:expect { + grid = [[ a {5:longer} example | | {8:from different sources} | {8:^in }{20:order}{8: to demonstrate} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]]} + ]], + } --screen:expect([[ -- a {5:longer} example | -- | -- {9:from }{8:diff}{7:erent} sources | -- ^in {6:order} to {7:de}{5:monstr}{7:ate} | - -- {1:~ }| - -- {1:~ }| - -- {1:~ }| + -- {1:~ }|*3 -- | --]]) command('undo') - screen:expect{grid=[[ + screen:expect { + grid = [[ a {5:longer} example | ^ | in {6:order} to {7:de}{5:monstr}{7:ate} | {9:from }{8:diff}{7:erent} sources | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 1 change; before #4 {MATCH:.*}| - ]]} + ]], + } command('undo') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^a {5:longer} example | in {6:order} to {7:de}{5:monstr}{7:ate} | {9:from }{8:diff}{7:erent} sources | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 1 line less; before #3 {MATCH:.*}| - ]]} + ]], + } command('undo') - screen:expect{grid=[[ + screen:expect { + grid = [[ a {5:longer} example | in {6:order} to {7:de}{5:monstr}{7:ate} | {7:^combin}{8:ing}{9: hi}ghlights | {9:from }{8:diff}{7:erent} sources | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 1 more line; before #2 {MATCH:.*}| - ]]} + ]], + } end) it('and moving lines around', function() command('2move 3') - screen:expect{grid=[[ + screen:expect { + grid = [[ a {5:longer} example | {7:combin}{8:ing}{9: hi}ghlights | ^in {6:order} to {7:de}{5:monstr}{7:ate} | {9:from }{8:diff}{7:erent} sources | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]]} + ]], + } command('1,2move 4') - screen:expect{grid=[[ + screen:expect { + grid = [[ in {6:order} to {7:de}{5:monstr}{7:ate} | {9:from }{8:diff}{7:erent} sources | a {5:longer} example | {7:^combin}{8:ing}{9: hi}ghlights | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]]} + ]], + } command('undo') - screen:expect{grid=[[ + screen:expect { + grid = [[ a {5:longer} example | {7:combin}{8:ing}{9: hi}ghlights | ^in {6:order} to {7:de}{5:monstr}{7:ate} | {9:from }{8:diff}{7:erent} sources | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 2 changes; before #3 {MATCH:.*}| - ]]} + ]], + } command('undo') - screen:expect{grid=[[ + screen:expect { + grid = [[ a {5:longer} example | ^in {6:order} to {7:de}{5:monstr}{7:ate} | {7:combin}{8:ing}{9: hi}ghlights | {9:from }{8:diff}{7:erent} sources | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 1 change; before #2 {MATCH:.*}| - ]]} + ]], + } end) it('and adjusting columns', function() -- insert before feed('ggiquite <esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ quite^ a {5:longer} example | in {6:order} to {7:de}{5:monstr}{7:ate} | {7:combin}{8:ing}{9: hi}ghlights | {9:from }{8:diff}{7:erent} sources | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]]} + ]], + } feed('u') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^a {5:longer} example | in {6:order} to {7:de}{5:monstr}{7:ate} | {7:combin}{8:ing}{9: hi}ghlights | {9:from }{8:diff}{7:erent} sources | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 1 change; before #2 {MATCH:.*}| - ]]} + ]], + } -- change/insert in the middle feed('+fesAAAA') - screen:expect{grid=[[ + screen:expect { + grid = [[ a {5:longer} example | in {6:ordAAAA^r} to {7:de}{5:monstr}{7:ate} | {7:combin}{8:ing}{9: hi}ghlights | {9:from }{8:diff}{7:erent} sources | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {7:-- INSERT --} | - ]]} + ]], + } feed('<esc>tdD') - screen:expect{grid=[[ + screen:expect { + grid = [[ a {5:longer} example | in {6:ordAAAAr} t^o | {7:combin}{8:ing}{9: hi}ghlights | {9:from }{8:diff}{7:erent} sources | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]]} + ]], + } feed('u') - screen:expect{grid=[[ + screen:expect { + grid = [[ a {5:longer} example | in {6:ordAAAAr} to^ {7:de}{5:monstr}{7:ate} | {7:combin}{8:ing}{9: hi}ghlights | {9:from }{8:diff}{7:erent} sources | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 1 change; before #4 {MATCH:.*}| - ]]} + ]], + } feed('u') - screen:expect{grid=[[ + screen:expect { + grid = [[ a {5:longer} example | in {6:ord^er} to {7:de}{5:monstr}{7:ate} | {7:combin}{8:ing}{9: hi}ghlights | {9:from }{8:diff}{7:erent} sources | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 1 change; before #3 {MATCH:.*}| - ]]} + ]], + } end) it('and joining lines', function() feed('ggJJJ') - screen:expect{grid=[[ + screen:expect { + grid = [[ a {5:longer} example in {6:order} to {7:de}{5:monstr}{7:ate}| {7:combin}{8:ing}{9: hi}ghlights^ {9:from }{8:diff}{7:erent} sou| rces | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | - ]]} + ]], + } feed('uuu') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^a {5:longer} example | in {6:order} to {7:de}{5:monstr}{7:ate} | {7:combin}{8:ing}{9: hi}ghlights | {9:from }{8:diff}{7:erent} sources | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 1 more line; before #2 {MATCH:.*}| - ]]} + ]], + } end) it('and splitting lines', function() feed('2Gtti<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ a {5:longer} example | in {6:order} | ^ to {7:de}{5:monstr}{7:ate} | {7:combin}{8:ing}{9: hi}ghlights | {9:from }{8:diff}{7:erent} sources | - {1:~ }| - {1:~ }| + {1:~ }|*2 {7:-- INSERT --} | - ]]} + ]], + } feed('<esc>tsi<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ a {5:longer} example | in {6:order} | to {7:de}{5:mo} | @@ -444,61 +417,53 @@ describe('Buffer highlighting', function() {9:from }{8:diff}{7:erent} sources | {1:~ }| {7:-- INSERT --} | - ]]} + ]], + } feed('<esc>u') - screen:expect{grid=[[ + screen:expect { + grid = [[ a {5:longer} example | in {6:order} | to {7:de}{5:mo^nstr}{7:ate} | {7:combin}{8:ing}{9: hi}ghlights | {9:from }{8:diff}{7:erent} sources | - {1:~ }| - {1:~ }| + {1:~ }|*2 1 line less; before #3 {MATCH:.*}| - ]]} + ]], + } feed('<esc>u') - screen:expect{grid=[[ + screen:expect { + grid = [[ a {5:longer} example | in {6:order}^ to {7:de}{5:monstr}{7:ate} | {7:combin}{8:ing}{9: hi}ghlights | {9:from }{8:diff}{7:erent} sources | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 1 line less; before #2 {MATCH:.*}| - ]]} + ]], + } end) end) pending('prioritizes latest added highlight', function() insert([[ three overlapping colors]]) - add_highlight(0, "Identifier", 0, 6, 17) - add_highlight(0, "String", 0, 14, 23) - local id = add_highlight(0, "Special", 0, 0, 9) + add_highlight(0, 0, 'Identifier', 0, 6, 17) + add_highlight(0, 0, 'String', 0, 14, 23) + local id = add_highlight(0, 0, 'Special', 0, 0, 9) screen:expect([[ {4:three ove}{6:rlapp}{2:ing color}^s | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | ]]) - clear_namespace(id, 0, 1) + clear_namespace(0, id, 0, 1) screen:expect([[ three {6:overlapp}{2:ing color}^s | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | ]]) end) @@ -506,96 +471,76 @@ describe('Buffer highlighting', function() it('prioritizes earlier highlight groups (TEMP)', function() insert([[ three overlapping colors]]) - add_highlight(0, "Identifier", 0, 6, 17) - add_highlight(0, "String", 0, 14, 23) - local id = add_highlight(0, "Special", 0, 0, 9) + add_highlight(0, 0, 'Identifier', 0, 6, 17) + add_highlight(0, 0, 'String', 0, 14, 23) + local id = add_highlight(0, 0, 'Special', 0, 0, 9) - screen:expect{grid=[[ + screen:expect { + grid = [[ {4:three }{6:overlapp}{2:ing color}^s | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | - ]]} + ]], + } - clear_namespace(id, 0, 1) - screen:expect{grid=[[ + clear_namespace(0, id, 0, 1) + screen:expect { + grid = [[ three {6:overlapp}{2:ing color}^s | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | - ]]} + ]], + } end) it('respects priority', function() - local set_extmark = curbufmeths.set_extmark - local id = meths.create_namespace('') + local id = api.nvim_create_namespace('') insert [[foobar]] - set_extmark(id, 0, 0, { + api.nvim_buf_set_extmark(0, id, 0, 0, { end_line = 0, end_col = 5, - hl_group = "Statement", - priority = 100 + hl_group = 'Statement', + priority = 100, }) - set_extmark(id, 0, 0, { + api.nvim_buf_set_extmark(0, id, 0, 0, { end_line = 0, end_col = 6, - hl_group = "String", - priority = 1 + hl_group = 'String', + priority = 1, }) screen:expect [[ {3:fooba}{2:^r} | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | ]] - clear_namespace(id, 0, -1) - screen:expect{grid=[[ + clear_namespace(0, id, 0, -1) + screen:expect { + grid = [[ fooba^r | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | - ]]} + ]], + } - set_extmark(id, 0, 0, { + api.nvim_buf_set_extmark(0, id, 0, 0, { end_line = 0, end_col = 6, - hl_group = "String", - priority = 1 + hl_group = 'String', + priority = 1, }) - set_extmark(id, 0, 0, { + api.nvim_buf_set_extmark(0, id, 0, 0, { end_line = 0, end_col = 5, - hl_group = "Statement", - priority = 100 + hl_group = 'Statement', + priority = 100, }) screen:expect [[ {3:fooba}{2:^r} | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | ]] end) @@ -603,17 +548,12 @@ describe('Buffer highlighting', function() it('works with multibyte text', function() insert([[ Ta båten över sjön!]]) - add_highlight(-1, "Identifier", 0, 3, 9) - add_highlight(-1, "String", 0, 16, 21) + add_highlight(0, -1, 'Identifier', 0, 3, 9) + add_highlight(0, -1, 'String', 0, 16, 21) screen:expect([[ Ta {6:båten} över {2:sjön}^! | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | ]]) end) @@ -621,33 +561,22 @@ describe('Buffer highlighting', function() it('works with new syntax groups', function() insert([[ fancy code in a new fancy language]]) - add_highlight(-1, "FancyLangItem", 0, 0, 5) + add_highlight(0, -1, 'FancyLangItem', 0, 0, 5) screen:expect([[ fancy code in a new fancy languag^e | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | ]]) command('hi FancyLangItem guifg=red') screen:expect([[ {10:fancy} code in a new fancy languag^e | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | ]]) end) describe('virtual text decorations', function() - local set_virtual_text = curbufmeths.set_virtual_text local id1, id2 before_each(function() insert([[ @@ -661,16 +590,18 @@ describe('Buffer highlighting', function() 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5| , 5, 5, 5, 5, 5, 5, | x = 4 | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) - id1 = set_virtual_text(0, 0, {{"=", "Statement"}, {" 3", "Number"}}, {}) - set_virtual_text(id1, 1, {{"ERROR:", "ErrorMsg"}, {" invalid syntax"}}, {}) - id2 = set_virtual_text(0, 2, {{"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."}}, {}) + id1 = set_virtual_text(0, 0, 0, { { '=', 'Statement' }, { ' 3', 'Number' } }, {}) + set_virtual_text(0, id1, 1, { { 'ERROR:', 'ErrorMsg' }, { ' invalid syntax' } }, {}) + id2 = set_virtual_text(0, 0, 2, { + { + 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', + }, + }, {}) neq(id2, id1) - end) it('works', function() @@ -680,278 +611,298 @@ describe('Buffer highlighting', function() 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5| , 5, 5, 5, 5, 5, 5, Lorem ipsum dolor s| x = 4 | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) - clear_namespace(id1, 0, -1) + clear_namespace(0, id1, 0, -1) screen:expect([[ ^1 + 2 | 3 + | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5| , 5, 5, 5, 5, 5, 5, Lorem ipsum dolor s| x = 4 | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) -- Handles doublewidth chars, leaving a space if truncating -- in the middle of a char - eq(-1, set_virtual_text(-1, 1, {{"暗x事zz速野谷質結育副住新覚丸活解終事", "Comment"}}, {})) + eq( + -1, + set_virtual_text( + 0, + -1, + 1, + { { '暗x事zz速野谷質結育副住新覚丸活解終事', 'Comment' } }, + {} + ) + ) screen:expect([[ ^1 + 2 | 3 + {12:暗x事zz速野谷質結育副住新覚丸活解終 }| 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5| , 5, 5, 5, 5, 5, 5, Lorem ipsum dolor s| x = 4 | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) - feed("2Gx") + feed('2Gx') screen:expect([[ 1 + 2 | ^ + {12:暗x事zz速野谷質結育副住新覚丸活解終事}| 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5| , 5, 5, 5, 5, 5, 5, Lorem ipsum dolor s| x = 4 | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) - feed("2Gdd") + feed('2Gdd') -- TODO(bfredl): currently decorations get moved from a deleted line -- to the next one. We might want to add "invalidation" when deleting -- over a decoration. - screen:expect{grid=[[ + screen:expect { + grid = [[ 1 + 2 | ^5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5| , 5, 5, 5, 5, 5, 5, {12:暗x事zz速野谷質結育}| x = 4 | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]]} + ]], + } --screen:expect([[ -- 1 + 2 | -- ^5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5| -- , 5, 5, 5, 5, 5, 5, Lorem ipsum dolor s| -- x = 4 | - -- {1:~ }| - -- {1:~ }| - -- {1:~ }| + -- {1:~ }|*3 -- | --]]) end) it('validates contents', function() -- this used to leak memory - eq("Invalid 'chunk': expected Array, got String", pcall_err(set_virtual_text, id1, 0, {"texty"}, {})) - eq("Invalid 'chunk': expected Array, got String", pcall_err(set_virtual_text, id1, 0, {{"very"}, "texty"}, {})) + eq( + "Invalid 'chunk': expected Array, got String", + pcall_err(set_virtual_text, 0, id1, 0, { 'texty' }, {}) + ) + eq( + "Invalid 'chunk': expected Array, got String", + pcall_err(set_virtual_text, 0, id1, 0, { { 'very' }, 'texty' }, {}) + ) end) it('can be retrieved', function() - local get_extmarks = curbufmeths.get_extmarks - local line_count = curbufmeths.line_count - - local s1 = {{'Köttbullar', 'Comment'}, {'Kräuterbutter'}} - local s2 = {{'こんにちは', 'Comment'}} - - set_virtual_text(id1, 0, s1, {}) - eq({{1, 0, 0, { - ns_id = 1, - priority = 0, - virt_text = s1, - -- other details - right_gravity = true, - virt_text_pos = 'eol', - virt_text_hide = false, - }}}, get_extmarks(id1, {0,0}, {0, -1}, {details=true})) - - local lastline = line_count() - set_virtual_text(id1, line_count(), s2, {}) - eq({{3, lastline, 0, { - ns_id = 1, - priority = 0, - virt_text = s2, - -- other details - right_gravity = true, - virt_text_pos = 'eol', - virt_text_hide = false, - }}}, get_extmarks(id1, {lastline,0}, {lastline, -1}, {details=true})) - - eq({}, get_extmarks(id1, {lastline+9000,0}, {lastline+9000, -1}, {})) + local get_extmarks = api.nvim_buf_get_extmarks + local line_count = api.nvim_buf_line_count + + local s1 = { { 'Köttbullar', 'Comment' }, { 'Kräuterbutter' } } + local s2 = { { 'こんにちは', 'Comment' } } + + set_virtual_text(0, id1, 0, s1, {}) + eq({ + { + 1, + 0, + 0, + { + ns_id = 1, + priority = 0, + virt_text = s1, + -- other details + right_gravity = true, + virt_text_repeat_linebreak = false, + virt_text_pos = 'eol', + virt_text_hide = false, + }, + }, + }, get_extmarks(0, id1, { 0, 0 }, { 0, -1 }, { details = true })) + + local lastline = line_count(0) + set_virtual_text(0, id1, line_count(0), s2, {}) + eq({ + { + 3, + lastline, + 0, + { + ns_id = 1, + priority = 0, + virt_text = s2, + -- other details + right_gravity = true, + virt_text_repeat_linebreak = false, + virt_text_pos = 'eol', + virt_text_hide = false, + }, + }, + }, get_extmarks(0, id1, { lastline, 0 }, { lastline, -1 }, { details = true })) + + eq({}, get_extmarks(0, id1, { lastline + 9000, 0 }, { lastline + 9000, -1 }, {})) end) it('is not highlighted by visual selection', function() - feed("ggVG") + feed('ggVG') screen:expect([[ {13:1 + 2} {3:=}{2: 3} | {13:3 +} {11:ERROR:} invalid syntax | {13:5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}| {13:, 5, 5, 5, 5, 5, 5, } Lorem ipsum dolor s| ^x{13: = 4} | - {1:~ }| - {1:~ }| + {1:~ }|*2 {7:-- VISUAL LINE --} | ]]) - feed("<esc>") + feed('<esc>') screen:expect([[ 1 + 2 {3:=}{2: 3} | 3 + {11:ERROR:} invalid syntax | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5| , 5, 5, 5, 5, 5, 5, Lorem ipsum dolor s| ^x = 4 | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) -- special case: empty line has extra eol highlight - feed("ggd$") + feed('ggd$') screen:expect([[ ^ {3:=}{2: 3} | 3 + {11:ERROR:} invalid syntax | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5| , 5, 5, 5, 5, 5, 5, Lorem ipsum dolor s| x = 4 | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) - feed("jvk") + feed('jvk') screen:expect([[ ^ {3:=}{2: 3} | {13:3} + {11:ERROR:} invalid syntax | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5| , 5, 5, 5, 5, 5, 5, Lorem ipsum dolor s| x = 4 | - {1:~ }| - {1:~ }| + {1:~ }|*2 {7:-- VISUAL --} | ]]) - feed("o") + feed('o') screen:expect([[ {13: }{3:=}{2: 3} | ^3 + {11:ERROR:} invalid syntax | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5| , 5, 5, 5, 5, 5, 5, Lorem ipsum dolor s| x = 4 | - {1:~ }| - {1:~ }| + {1:~ }|*2 {7:-- VISUAL --} | ]]) end) - it('works with listchars', function() - command("set list listchars+=eol:$") + command('set list listchars+=eol:$') screen:expect([[ ^1 + 2{1:$}{3:=}{2: 3} | 3 +{1:$}{11:ERROR:} invalid syntax | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5| , 5, 5, 5, 5, 5, 5,{1:-$}Lorem ipsum dolor s| x = 4{1:$} | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) - clear_namespace(-1, 0, -1) + clear_namespace(0, -1, 0, -1) screen:expect([[ ^1 + 2{1:$} | 3 +{1:$} | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5| , 5, 5, 5, 5, 5, 5,{1:-$} | x = 4{1:$} | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) end) it('works with cursorline', function() - command("set cursorline") + command('set cursorline') - screen:expect{grid=[[ + screen:expect { + grid = [[ {14:^1 + 2 }{3:=}{2: 3}{14: }| 3 + {11:ERROR:} invalid syntax | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5| , 5, 5, 5, 5, 5, 5, Lorem ipsum dolor s| x = 4 | - {1:~ }| - {1:~ }| + {1:~ }|*2 | - ]]} + ]], + } feed('j') - screen:expect{grid=[[ + screen:expect { + grid = [[ 1 + 2 {3:=}{2: 3} | {14:^3 + }{11:ERROR:} invalid syntax{14: }| 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5| , 5, 5, 5, 5, 5, 5, Lorem ipsum dolor s| x = 4 | - {1:~ }| - {1:~ }| + {1:~ }|*2 | - ]]} - + ]], + } feed('j') - screen:expect{grid=[[ + screen:expect { + grid = [[ 1 + 2 {3:=}{2: 3} | 3 + {11:ERROR:} invalid syntax | {14:^5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}| {14:, 5, 5, 5, 5, 5, 5, }Lorem ipsum dolor s| x = 4 | - {1:~ }| - {1:~ }| + {1:~ }|*2 | - ]]} + ]], + } end) it('works with color column', function() - eq(-1, set_virtual_text(-1, 3, {{"暗x事", "Comment"}}, {})) - screen:expect{grid=[[ + eq(-1, set_virtual_text(0, -1, 3, { { '暗x事', 'Comment' } }, {})) + screen:expect { + grid = [[ ^1 + 2 {3:=}{2: 3} | 3 + {11:ERROR:} invalid syntax | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5| , 5, 5, 5, 5, 5, 5, Lorem ipsum dolor s| x = 4 {12:暗x事} | - {1:~ }| - {1:~ }| + {1:~ }|*2 | - ]]} + ]], + } - command("set colorcolumn=9") - screen:expect{grid=[[ + command('set colorcolumn=9') + screen:expect { + grid = [[ ^1 + 2 {3:=}{2: 3} | 3 + {11:ERROR:} invalid syntax | 5, 5, 5,{18: }5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5| , 5, 5, 5, 5, 5, 5, Lorem ipsum dolor s| x = 4 {12:暗x事} | - {1:~ }| - {1:~ }| + {1:~ }|*2 | - ]]} + ]], + } end) end) it('and virtual text use the same namespace counter', function() - local set_virtual_text = curbufmeths.set_virtual_text - eq(1, add_highlight(0, "String", 0 , 0, -1)) - eq(2, set_virtual_text(0, 0, {{"= text", "Comment"}}, {})) - eq(3, meths.create_namespace("my-ns")) - eq(4, add_highlight(0, "String", 0 , 0, -1)) - eq(5, set_virtual_text(0, 0, {{"= text", "Comment"}}, {})) - eq(6, meths.create_namespace("other-ns")) + eq(1, add_highlight(0, 0, 'String', 0, 0, -1)) + eq(2, set_virtual_text(0, 0, 0, { { '= text', 'Comment' } }, {})) + eq(3, api.nvim_create_namespace('my-ns')) + eq(4, add_highlight(0, 0, 'String', 0, 0, -1)) + eq(5, set_virtual_text(0, 0, 0, { { '= text', 'Comment' } }, {})) + eq(6, api.nvim_create_namespace('other-ns')) end) end) diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua index e4766103c2..6c4000ba41 100644 --- a/test/functional/ui/cmdline_highlight_spec.lua +++ b/test/functional/ui/cmdline_highlight_spec.lua @@ -4,13 +4,12 @@ local Screen = require('test.functional.ui.screen') local eq = helpers.eq local feed = helpers.feed local clear = helpers.clear -local meths = helpers.meths -local funcs = helpers.funcs +local api = helpers.api +local fn = helpers.fn local source = helpers.source local exec_capture = helpers.exec_capture local dedent = helpers.dedent local command = helpers.command -local curbufmeths = helpers.curbufmeths local screen @@ -138,36 +137,35 @@ before_each(function() endfunction ]]) screen:set_default_attr_ids({ - RBP1={background = Screen.colors.Red}, - RBP2={background = Screen.colors.Yellow}, - RBP3={background = Screen.colors.Green}, - RBP4={background = Screen.colors.Blue}, - EOB={bold = true, foreground = Screen.colors.Blue1}, - ERR={foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - SK={foreground = Screen.colors.Blue}, - PE={bold = true, foreground = Screen.colors.SeaGreen4}, - NUM={foreground = Screen.colors.Blue2}, - NPAR={foreground = Screen.colors.Yellow}, - SQ={foreground = Screen.colors.Blue3}, - SB={foreground = Screen.colors.Blue4}, - E={foreground = Screen.colors.Red, background = Screen.colors.Blue}, - M={bold = true}, - MSEP={bold = true, reverse = true}; + RBP1 = { background = Screen.colors.Red }, + RBP2 = { background = Screen.colors.Yellow }, + RBP3 = { background = Screen.colors.Green }, + RBP4 = { background = Screen.colors.Blue }, + EOB = { bold = true, foreground = Screen.colors.Blue1 }, + ERR = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + SK = { foreground = Screen.colors.Blue }, + PE = { bold = true, foreground = Screen.colors.SeaGreen4 }, + NUM = { foreground = Screen.colors.Blue2 }, + NPAR = { foreground = Screen.colors.Yellow }, + SQ = { foreground = Screen.colors.Blue3 }, + SB = { foreground = Screen.colors.Blue4 }, + E = { foreground = Screen.colors.Red, background = Screen.colors.Blue }, + M = { bold = true }, + MSEP = { bold = true, reverse = true }, }) end) local function set_color_cb(funcname, callback_return, id) - meths.set_var('id', id or '') - if id and id ~= '' and funcs.exists('*' .. funcname .. 'N') then - command(('let g:Nvim_color_input%s = {cmdline -> %sN(%s, cmdline)}'):format( - id, funcname, id)) + api.nvim_set_var('id', id or '') + if id and id ~= '' and fn.exists('*' .. funcname .. 'N') then + command(('let g:Nvim_color_input%s = {cmdline -> %sN(%s, cmdline)}'):format(id, funcname, id)) if callback_return then - meths.set_var('callback_return' .. id, callback_return) + api.nvim_set_var('callback_return' .. id, callback_return) end else - meths.set_var('Nvim_color_input', funcname) + api.nvim_set_var('Nvim_color_input', funcname) if callback_return then - meths.set_var('callback_return', callback_return) + api.nvim_set_var('callback_return', callback_return) end end end @@ -178,142 +176,94 @@ end describe('Command-line coloring', function() it('works', function() set_color_cb('RainBowParens') - meths.set_option_value('more', false, {}) + api.nvim_set_option_value('more', false, {}) start_prompt() screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :^ | ]]) feed('e') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :e^ | ]]) feed('cho ') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :echo ^ | ]]) feed('(') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :echo {RBP1:(}^ | ]]) feed('(') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :echo {RBP1:(}{RBP2:(}^ | ]]) feed('42') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :echo {RBP1:(}{RBP2:(}42^ | ]]) feed('))') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :echo {RBP1:(}{RBP2:(}42{RBP2:)}{RBP1:)}^ | ]]) feed('<BS>') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :echo {RBP1:(}{RBP2:(}42{RBP2:)}^ | ]]) redraw_input() - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :echo {RBP1:(}{RBP2:(}42{RBP2:)}^ | - ]], reset=true} + ]], + reset = true, + } end) - for _, func_part in ipairs({'', 'n', 'msg'}) do + for _, func_part in ipairs({ '', 'n', 'msg' }) do it('disables :echo' .. func_part .. ' messages', function() set_color_cb('Echo' .. func_part .. 'ing') start_prompt('echo') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :echo^ | ]]) end) end - it('does the right thing when hl start appears to split multibyte char', - function() + it('does the right thing when hl start appears to split multibyte char', function() set_color_cb('SplitMultibyteStart') start_prompt('echo "«') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*2 {MSEP: }| :echo " | {ERR:E5405: Chunk 0 start 7 splits multibyte }| {ERR:character} | :echo "«^ | - ]]} + ]], + } feed('»') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*2 {MSEP: }| :echo " | {ERR:E5405: Chunk 0 start 7 splits multibyte }| @@ -321,14 +271,12 @@ describe('Command-line coloring', function() :echo "«»^ | ]]) end) - it('does the right thing when hl end appears to split multibyte char', - function() + it('does the right thing when hl end appears to split multibyte char', function() set_color_cb('SplitMultibyteEnd') start_prompt('echo "«') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*2 {MSEP: }| :echo " | {ERR:E5406: Chunk 0 end 7 splits multibyte ch}| @@ -355,12 +303,7 @@ describe('Command-line coloring', function() start_prompt('e') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :e^ | ]]) eq('', exec_capture('messages')) @@ -370,12 +313,7 @@ describe('Command-line coloring', function() start_prompt('e') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :e^ | ]]) eq('', exec_capture('messages')) @@ -385,12 +323,7 @@ describe('Command-line coloring', function() start_prompt('e') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :e^ | ]]) eq('', exec_capture('messages')) @@ -414,8 +347,7 @@ describe('Command-line coloring', function() start_prompt('let x = "«»«»«»«»«»"') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*2 {MSEP: }| :let x = " | {ERR:E5405: Chunk 0 start 10 splits multibyte}| @@ -425,38 +357,27 @@ describe('Command-line coloring', function() feed('\n') screen:expect([[ ^ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 | ]]) feed('\n') - eq('let x = "«»«»«»«»«»"', meths.get_var('out')) + eq('let x = "«»«»«»«»«»"', api.nvim_get_var('out')) local msg = '\nE5405: Chunk 0 start 10 splits multibyte character' - eq(msg:rep(1), funcs.execute('messages')) + eq(msg:rep(1), fn.execute('messages')) end) it('allows interrupting callback with <C-c>', function() set_color_cb('Halting') start_prompt('echo 42') screen:expect([[ ^ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 | ]]) screen:sleep(500) feed('<C-c>') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*2 {MSEP: }| : | {ERR:E5407: Callback has thrown an exception:}| @@ -466,36 +387,21 @@ describe('Command-line coloring', function() redraw_input() screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :echo 42^ | ]]) feed('\n') screen:expect([[ ^ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :echo 42 | ]]) feed('\n') - eq('echo 42', meths.get_var('out')) + eq('echo 42', api.nvim_get_var('out')) feed('<C-c>') screen:expect([[ ^ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 Type :qa and pre...nter> to exit Nvim | ]]) end) @@ -504,12 +410,7 @@ describe('Command-line coloring', function() start_prompt('echo ("<C-v><CR><C-v><Nul><C-v><NL>")') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :echo {RBP1:(}"{SK:^M^@^@}"{RBP1:)}^ | ]]) end) @@ -519,9 +420,7 @@ describe('Command-line coloring', function() start_prompt('#') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {MSEP: }| : | {ERR:E5400: Callback should return list} | @@ -529,13 +428,11 @@ describe('Command-line coloring', function() ]]) feed('<CR><CR><CR>') - set_color_cb('ReturningGlobal', {{0, 1, 'Normal'}, 42}) + set_color_cb('ReturningGlobal', { { 0, 1, 'Normal' }, 42 }) start_prompt('#') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {MSEP: }| : | {ERR:E5401: List item 1 is not a List} | @@ -543,12 +440,11 @@ describe('Command-line coloring', function() ]]) feed('<CR><CR><CR>') - set_color_cb('ReturningGlobal2', {{0, 1, 'Normal'}, {1}}) + set_color_cb('ReturningGlobal2', { { 0, 1, 'Normal' }, { 1 } }) start_prompt('+') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*2 {MSEP: }| :+ | {ERR:E5402: List item 1 has incorrect length:}| @@ -557,12 +453,11 @@ describe('Command-line coloring', function() ]]) feed('<CR><CR><CR>') - set_color_cb('ReturningGlobal2', {{0, 1, 'Normal'}, {2, 3, 'Normal'}}) + set_color_cb('ReturningGlobal2', { { 0, 1, 'Normal' }, { 2, 3, 'Normal' } }) start_prompt('+') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*2 {MSEP: }| :+ | {ERR:E5403: Chunk 1 start 2 not in range [1, }| @@ -571,13 +466,11 @@ describe('Command-line coloring', function() ]]) feed('<CR><CR><CR>') - set_color_cb('ReturningGlobal2', {{0, 1, 'Normal'}, {1, 3, 'Normal'}}) + set_color_cb('ReturningGlobal2', { { 0, 1, 'Normal' }, { 1, 3, 'Normal' } }) start_prompt('+') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {MSEP: }| :+ | {ERR:E5404: Chunk 1 end 3 not in range (1, 2]}| @@ -585,7 +478,7 @@ describe('Command-line coloring', function() ]]) end) it('does not error out when called from a errorred out cycle', function() - set_color_cb('ReturningGlobal', {{0, 1, 'Normal'}}) + set_color_cb('ReturningGlobal', { { 0, 1, 'Normal' } }) feed(dedent([[ :set regexpengine=2 :for pat in [' \ze*', ' \zs*'] @@ -607,117 +500,79 @@ describe('Command-line coloring', function() : : ]])) - eq({'', ':', 'E888 detected for \\ze*', ':', 'E888 detected for \\zs*'}, - curbufmeths.get_lines(0, -1, false)) - eq('', funcs.execute('messages')) + eq( + { '', ':', 'E888 detected for \\ze*', ':', 'E888 detected for \\zs*' }, + api.nvim_buf_get_lines(0, 0, -1, false) + ) + eq('', fn.execute('messages')) end) it('allows nesting input()s', function() - set_color_cb('ReturningGlobal', {{0, 1, 'RBP1'}}, '') + set_color_cb('ReturningGlobal', { { 0, 1, 'RBP1' } }, '') start_prompt('1') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :{RBP1:1}^ | ]]) - set_color_cb('ReturningGlobal', {{0, 1, 'RBP2'}}, '1') + set_color_cb('ReturningGlobal', { { 0, 1, 'RBP2' } }, '1') start_prompt('2') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :{RBP2:2}^ | ]]) - set_color_cb('ReturningGlobal', {{0, 1, 'RBP3'}}, '2') + set_color_cb('ReturningGlobal', { { 0, 1, 'RBP3' } }, '2') start_prompt('3') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :{RBP3:3}^ | ]]) - set_color_cb('ReturningGlobal', {{0, 1, 'RBP4'}}, '3') + set_color_cb('ReturningGlobal', { { 0, 1, 'RBP4' } }, '3') start_prompt('4') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :{RBP4:4}^ | ]]) feed('<CR>') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :{RBP3:3}4^ | ]]) feed('<CR>') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :{RBP2:2}34^ | ]]) feed('<CR>') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :{RBP1:1}234^ | ]]) feed('<CR><CR><C-l>') screen:expect([[ ^ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 | ]]) - eq('1234', meths.get_var('out')) - eq('234', meths.get_var('out1')) - eq('34', meths.get_var('out2')) - eq('4', meths.get_var('out3')) - eq(0, funcs.exists('g:out4')) + eq('1234', api.nvim_get_var('out')) + eq('234', api.nvim_get_var('out1')) + eq('34', api.nvim_get_var('out2')) + eq('4', api.nvim_get_var('out3')) + eq(0, fn.exists('g:out4')) end) it('runs callback with the same data only once', function() local function new_recording_calls(...) - eq({...}, meths.get_var('recording_calls')) - meths.set_var('recording_calls', {}) + eq({ ... }, api.nvim_get_var('recording_calls')) + api.nvim_set_var('recording_calls', {}) end set_color_cb('Recording') start_prompt('') @@ -726,22 +581,21 @@ describe('Command-line coloring', function() -- new_recording_calls(expected_result) -- (actual_before_fix) -- feed('a') - new_recording_calls('a') -- ('a', 'a') + new_recording_calls('a') -- ('a', 'a') feed('b') new_recording_calls('ab') -- ('a', 'ab', 'ab') feed('c') - new_recording_calls('abc') -- ('ab', 'abc', 'abc') + new_recording_calls('abc') -- ('ab', 'abc', 'abc') feed('<BS>') - new_recording_calls('ab') -- ('abc', 'ab', 'ab') + new_recording_calls('ab') -- ('abc', 'ab', 'ab') feed('<BS>') - new_recording_calls('a') -- ('ab', 'a', 'a') + new_recording_calls('a') -- ('ab', 'a', 'a') feed('<BS>') - new_recording_calls() -- ('a') + new_recording_calls() -- ('a') feed('<CR><CR>') - eq('', meths.get_var('out')) + eq('', api.nvim_get_var('out')) end) - it('does not crash when callback has caught not-a-editor-command exception', - function() + it('does not crash when callback has caught not-a-editor-command exception', function() source([[ function CaughtExc(cmdline) abort try @@ -754,30 +608,25 @@ describe('Command-line coloring', function() ]]) set_color_cb('CaughtExc') start_prompt('1') - eq(1, meths.eval('1')) + eq(1, api.nvim_eval('1')) end) end) describe('Ex commands coloring', function() it('works', function() - meths.set_var('Nvim_color_cmdline', 'RainBowParens') + api.nvim_set_var('Nvim_color_cmdline', 'RainBowParens') feed(':echo (((1)))') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :echo {RBP1:(}{RBP2:(}{RBP3:(}1{RBP3:)}{RBP2:)}{RBP1:)}^ | ]]) end) it('still executes command-line even if errored out', function() - meths.set_var('Nvim_color_cmdline', 'SplitMultibyteStart') + api.nvim_set_var('Nvim_color_cmdline', 'SplitMultibyteStart') feed(':let x = "«"\n') - eq('«', meths.get_var('x')) + eq('«', api.nvim_get_var('x')) local msg = 'E5405: Chunk 0 start 10 splits multibyte character' - eq('\n'..msg, funcs.execute('messages')) + eq('\n' .. msg, fn.execute('messages')) end) it('does not error out when called from a errorred out cycle', function() -- Apparently when there is a cycle in which one of the commands errors out @@ -794,16 +643,17 @@ describe('Ex commands coloring', function() : endtry :endfor ]])) - eq({'', 'E888 detected for \\ze*', 'E888 detected for \\zs*'}, - curbufmeths.get_lines(0, -1, false)) - eq('', funcs.execute('messages')) + eq( + { '', 'E888 detected for \\ze*', 'E888 detected for \\zs*' }, + api.nvim_buf_get_lines(0, 0, -1, false) + ) + eq('', fn.execute('messages')) end) it('does not crash when using `n` in debug mode', function() feed(':debug execute "echo 1"\n') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*2 {MSEP: }| Entering Debug mode. Type "cont" to con| tinue. | @@ -824,12 +674,7 @@ describe('Ex commands coloring', function() feed('\n') screen:expect([[ ^ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 | ]]) end) @@ -838,8 +683,7 @@ describe('Ex commands coloring', function() feed(':#x') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*2 {MSEP: }| :# | {ERR:Error detected while processing :} | @@ -858,11 +702,13 @@ describe('Ex commands coloring', function() {PE:Press ENTER or type command to continue}^ | ]]) feed('<CR>') - eq('Error detected while processing :\nE605: Exception not caught: 42\nE749: Empty buffer', - exec_capture('messages')) + eq( + 'Error detected while processing :\nE605: Exception not caught: 42\nE749: Empty buffer', + exec_capture('messages') + ) end) it('errors out when failing to get callback', function() - meths.set_var('Nvim_color_cmdline', 42) + api.nvim_set_var('Nvim_color_cmdline', 42) feed(':#') screen:expect([[ | @@ -878,77 +724,52 @@ describe('Ex commands coloring', function() end) describe('Expressions coloring support', function() it('works', function() - meths.command('hi clear NvimNumber') - meths.command('hi clear NvimNestingParenthesis') - meths.command('hi NvimNumber guifg=Blue2') - meths.command('hi NvimNestingParenthesis guifg=Yellow') + command('hi clear NvimNumber') + command('hi clear NvimNestingParenthesis') + command('hi NvimNumber guifg=Blue2') + command('hi NvimNestingParenthesis guifg=Yellow') feed(':echo <C-r>=(((1)))') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 ={NPAR:(((}{NUM:1}{NPAR:)))}^ | ]]) end) it('does not use Nvim_color_expr', function() - meths.set_var('Nvim_color_expr', 42) + api.nvim_set_var('Nvim_color_expr', 42) -- Used to error out due to failing to get callback. - meths.command('hi clear NvimNumber') - meths.command('hi NvimNumber guifg=Blue2') + command('hi clear NvimNumber') + command('hi NvimNumber guifg=Blue2') feed(':<C-r>=1') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 ={NUM:1}^ | ]]) end) it('works correctly with non-ASCII and control characters', function() - meths.command('hi clear NvimStringBody') - meths.command('hi clear NvimStringQuote') - meths.command('hi clear NvimInvalid') - meths.command('hi NvimStringQuote guifg=Blue3') - meths.command('hi NvimStringBody guifg=Blue4') - meths.command('hi NvimInvalid guifg=Red guibg=Blue') + command('hi clear NvimStringBody') + command('hi clear NvimStringQuote') + command('hi clear NvimInvalid') + command('hi NvimStringQuote guifg=Blue3') + command('hi NvimStringBody guifg=Blue4') + command('hi NvimInvalid guifg=Red guibg=Blue') feed('i<C-r>="«»"«»') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 ={SQ:"}{SB:«»}{SQ:"}{E:«»}^ | ]]) feed('<C-c>') screen:expect([[ ^ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 {M:-- INSERT --} | ]]) feed('<Esc>') screen:expect([[ ^ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 | ]]) feed(':<C-\\>e"<C-v><C-x>"<C-v><C-x>') @@ -956,35 +777,20 @@ describe('Expressions coloring support', function() -- highlighting. screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 ={SQ:"}{SB:^X}{SQ:"}{ERR:^X}^ | ]]) feed('<C-c>') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 :^ | ]]) - funcs.setreg('a', {'\192'}) + fn.setreg('a', { '\192' }) feed('<C-r>="<C-r><C-r>a"<C-r><C-r>a"foo"') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*6 ={SQ:"}{SB:<c0>}{SQ:"}{E:<c0>"}{SB:foo}{E:"}^ | ]]) end) diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua index 188b9ee87b..0eb5770819 100644 --- a/test/functional/ui/cmdline_spec.lua +++ b/test/functional/ui/cmdline_spec.lua @@ -9,22 +9,22 @@ local exec = helpers.exec local eval = helpers.eval local eq = helpers.eq local is_os = helpers.is_os -local meths = helpers.meths +local api = helpers.api local function new_screen(opt) local screen = Screen.new(25, 5) screen:attach(opt) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {reverse = true}, - [3] = {bold = true, reverse = true}, - [4] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [5] = {bold = true, foreground = Screen.colors.SeaGreen4}, - [6] = {foreground = Screen.colors.Magenta}, - [7] = {bold = true, foreground = Screen.colors.Brown}, - [8] = {background = Screen.colors.LightGrey}, - [9] = {bold = true}, - [10] = {background = Screen.colors.Yellow1}; + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { reverse = true }, + [3] = { bold = true, reverse = true }, + [4] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [5] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [6] = { foreground = Screen.colors.Magenta }, + [7] = { bold = true, foreground = Screen.colors.Brown }, + [8] = { foreground = Screen.colors.Black, background = Screen.colors.LightGrey }, + [9] = { bold = true }, + [10] = { background = Screen.colors.Yellow1 }, }) return screen end @@ -34,370 +34,445 @@ local function test_cmdline(linegrid) before_each(function() clear() - screen = new_screen({rgb=true, ext_cmdline=true, ext_linegrid=linegrid}) + screen = new_screen({ rgb = true, ext_cmdline = true, ext_linegrid = linegrid }) end) it('works', function() feed(':') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{""}}, - pos = 0, - }}} + ]], + cmdline = { { + firstc = ':', + content = { { '' } }, + pos = 0, + } }, + } feed('sign') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{"sign"}}, - pos = 4, - }}} + ]], + cmdline = { + { + firstc = ':', + content = { { 'sign' } }, + pos = 4, + }, + }, + } feed('<Left>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{"sign"}}, - pos = 3, - }}} + ]], + cmdline = { + { + firstc = ':', + content = { { 'sign' } }, + pos = 3, + }, + }, + } feed('<bs>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{"sin"}}, - pos = 2, - }}} + ]], + cmdline = { + { + firstc = ':', + content = { { 'sin' } }, + pos = 2, + }, + }, + } feed('<Esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]]} + ]], + } end) - it("works with input()", function() + it('works with input()', function() feed(':call input("input", "default")<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - prompt = "input", - content = {{"default"}}, - pos = 7, - }}} + ]], + cmdline = { + { + prompt = 'input', + content = { { 'default' } }, + pos = 7, + }, + }, + } feed('<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]]} + ]], + } end) - it("works with special chars and nested cmdline", function() + it('works with special chars and nested cmdline', function() feed(':xx<c-r>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{"xx"}}, - pos = 2, - special = {'"', true}, - }}} + ]], + cmdline = { + { + firstc = ':', + content = { { 'xx' } }, + pos = 2, + special = { '"', true }, + }, + }, + } feed('=') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{"xx"}}, - pos = 2, - special = {'"', true}, - }, { - firstc = "=", - content = {{""}}, - pos = 0, - }}} + ]], + cmdline = { + { + firstc = ':', + content = { { 'xx' } }, + pos = 2, + special = { '"', true }, + }, + { + firstc = '=', + content = { { '' } }, + pos = 0, + }, + }, + } feed('1+2') - local expectation = {{ - firstc = ":", - content = {{"xx"}}, - pos = 2, - special = {'"', true}, - }, { - firstc = "=", - content = {{"1", 6}, {"+", 7}, {"2", 6}}, - pos = 3, - }} - - screen:expect{grid=[[ + local expectation = { + { + firstc = ':', + content = { { 'xx' } }, + pos = 2, + special = { '"', true }, + }, + { + firstc = '=', + content = { { '1', 6 }, { '+', 7 }, { '2', 6 } }, + pos = 3, + }, + } + + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline=expectation} + ]], + cmdline = expectation, + } -- erase information, so we check if it is retransmitted - command("mode") - screen:expect{grid=[[ + command('mode') + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline=expectation, reset=true} - + ]], + cmdline = expectation, + reset = true, + } feed('<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{"xx3"}}, - pos = 3, - }}} + ]], + cmdline = { + { + firstc = ':', + content = { { 'xx3' } }, + pos = 3, + }, + }, + } feed('<esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]]} + ]], + } end) - it("works with function definitions", function() + it('works with function definitions', function() feed(':function Foo()<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - indent = 2, - firstc = ":", - content = {{""}}, - pos = 0, - }}, cmdline_block = { - {{'function Foo()'}}, - }} + ]], + cmdline = { + { + indent = 2, + firstc = ':', + content = { { '' } }, + pos = 0, + }, + }, + cmdline_block = { + { { 'function Foo()' } }, + }, + } feed('line1<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - indent = 2, - firstc = ":", - content = {{""}}, - pos = 0, - }}, cmdline_block = { - {{'function Foo()'}}, - {{' line1'}}, - }} - - command("mode") - screen:expect{grid=[[ + ]], + cmdline = { + { + indent = 2, + firstc = ':', + content = { { '' } }, + pos = 0, + }, + }, + cmdline_block = { + { { 'function Foo()' } }, + { { ' line1' } }, + }, + } + + command('mode') + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - indent = 2, - firstc = ":", - content = {{""}}, - pos = 0, - }}, cmdline_block = { - {{'function Foo()'}}, - {{' line1'}}, - }, reset=true} + ]], + cmdline = { + { + indent = 2, + firstc = ':', + content = { { '' } }, + pos = 0, + }, + }, + cmdline_block = { + { { 'function Foo()' } }, + { { ' line1' } }, + }, + reset = true, + } feed('endfunction<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]]} + ]], + } -- Try once more, to check buffer is reinitialized. #8007 feed(':function Bar()<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - indent = 2, - firstc = ":", - content = {{""}}, - pos = 0, - }}, cmdline_block = { - {{'function Bar()'}}, - }} + ]], + cmdline = { + { + indent = 2, + firstc = ':', + content = { { '' } }, + pos = 0, + }, + }, + cmdline_block = { + { { 'function Bar()' } }, + }, + } feed('endfunction<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]]} - + ]], + } end) - it("works with cmdline window", function() + it('works with cmdline window', function() feed(':make') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{"make"}}, - pos = 4, - }}} + ]], + cmdline = { + { + firstc = ':', + content = { { 'make' } }, + pos = 4, + }, + }, + } feed('<c-f>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | {2:[No Name] }| {1::}mak^e | {3:[Command Line] }| | - ]]} + ]], + } -- nested cmdline feed(':yank') - screen:expect{grid=[[ + screen:expect { + grid = [[ | {2:[No Name] }| {1::}mak^e | {3:[Command Line] }| | - ]], cmdline={nil, { - firstc = ":", - content = {{"yank"}}, - pos = 4, - }}} - - command("mode") - screen:expect{grid=[[ + ]], + cmdline = { + nil, + { + firstc = ':', + content = { { 'yank' } }, + pos = 4, + }, + }, + } + + command('mode') + screen:expect { + grid = [[ | {2:[No Name] }| {1::}mak^e | {3:[Command Line] }| | - ]], cmdline={nil, { - firstc = ":", - content = {{"yank"}}, - pos = 4, - }}, reset=true} - - feed("<c-c>") - screen:expect{grid=[[ + ]], + cmdline = { + nil, + { + firstc = ':', + content = { { 'yank' } }, + pos = 4, + }, + }, + reset = true, + } + + feed('<c-c>') + screen:expect { + grid = [[ | {2:[No Name] }| {1::}mak^e | {3:[Command Line] }| | - ]]} + ]], + } - feed("<c-c>") - screen:expect{grid=[[ + feed('<c-c>') + screen:expect { + grid = [[ ^ | {2:[No Name] }| {1::}make | {3:[Command Line] }| | - ]], cmdline={{ - firstc = ":", - content = {{"make"}}, - pos = 4, - }}} - - command("redraw!") - screen:expect{grid=[[ + ]], + cmdline = { + { + firstc = ':', + content = { { 'make' } }, + pos = 4, + }, + }, + } + + command('redraw!') + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{"make"}}, - pos = 4, - }}} + ]], + cmdline = { + { + firstc = ':', + content = { { 'make' } }, + pos = 4, + }, + }, + } end) it('works with inputsecret()', function() feed(":call inputsecret('secret:')<cr>abc123") - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - prompt = "secret:", - content = {{"******"}}, - pos = 6, - }}} + ]], + cmdline = { + { + prompt = 'secret:', + content = { { '******' } }, + pos = 6, + }, + }, + } end) it('works with highlighted cmdline', function() @@ -427,23 +502,33 @@ local function test_cmdline(linegrid) "map <f5> :let x = input({'prompt':'>'})<cr> ]]) screen:set_default_attr_ids({ - RBP1={background = Screen.colors.Red}, - RBP2={background = Screen.colors.Yellow}, - EOB={bold = true, foreground = Screen.colors.Blue1}, + RBP1 = { background = Screen.colors.Red }, + RBP2 = { background = Screen.colors.Yellow }, + EOB = { bold = true, foreground = Screen.colors.Blue1 }, }) feed('<f5>(a(b)a)') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 | - ]], cmdline={{ - prompt = '>', - content = {{'(', 'RBP1'}, {'a'}, {'(', 'RBP2'}, {'b'}, - { ')', 'RBP2'}, {'a'}, {')', 'RBP1'}}, - pos = 7, - }}} + ]], + cmdline = { + { + prompt = '>', + content = { + { '(', 'RBP1' }, + { 'a' }, + { '(', 'RBP2' }, + { 'b' }, + { ')', 'RBP2' }, + { 'a' }, + { ')', 'RBP1' }, + }, + pos = 7, + }, + }, + } end) it('works together with ext_wildmenu', function() @@ -461,79 +546,102 @@ local function test_cmdline(linegrid) screen:set_option('ext_wildmenu', true) feed(':sign <tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{"sign define"}}, - pos = 11, - }}, wildmenu_items=expected, wildmenu_pos=0} + ]], + cmdline = { + { + firstc = ':', + content = { { 'sign define' } }, + pos = 11, + }, + }, + wildmenu_items = expected, + wildmenu_pos = 0, + } feed('<tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{"sign jump"}}, - pos = 9, - }}, wildmenu_items=expected, wildmenu_pos=1} + ]], + cmdline = { + { + firstc = ':', + content = { { 'sign jump' } }, + pos = 9, + }, + }, + wildmenu_items = expected, + wildmenu_pos = 1, + } feed('<left><left>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{"sign "}}, - pos = 5, - }}, wildmenu_items=expected, wildmenu_pos=-1} + ]], + cmdline = { + { + firstc = ':', + content = { { 'sign ' } }, + pos = 5, + }, + }, + wildmenu_items = expected, + wildmenu_pos = -1, + } feed('<right>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{"sign define"}}, - pos = 11, - }}, wildmenu_items=expected, wildmenu_pos=0} + ]], + cmdline = { + { + firstc = ':', + content = { { 'sign define' } }, + pos = 11, + }, + }, + wildmenu_items = expected, + wildmenu_pos = 0, + } feed('a') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{"sign definea"}}, - pos = 12, - }}} + ]], + cmdline = { + { + firstc = ':', + content = { { 'sign definea' } }, + pos = 12, + }, + }, + } end) it('works together with ext_popupmenu', function() local expected = { - {'define', '', '', ''}, - {'jump', '', '', ''}, - {'list', '', '', ''}, - {'place', '', '', ''}, - {'undefine', '', '', ''}, - {'unplace', '', '', ''}, + { 'define', '', '', '' }, + { 'jump', '', '', '' }, + { 'list', '', '', '' }, + { 'place', '', '', '' }, + { 'undefine', '', '', '' }, + { 'unplace', '', '', '' }, } command('set wildmode=full') @@ -541,90 +649,115 @@ local function test_cmdline(linegrid) screen:set_option('ext_popupmenu', true) feed(':sign <tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{"sign define"}}, - pos = 11, - }}, popupmenu={items=expected, pos=0, anchor={-1, 0, 5}}} + ]], + cmdline = { + { + firstc = ':', + content = { { 'sign define' } }, + pos = 11, + }, + }, + popupmenu = { items = expected, pos = 0, anchor = { -1, 0, 5 } }, + } feed('<tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{"sign jump"}}, - pos = 9, - }}, popupmenu={items=expected, pos=1, anchor={-1, 0, 5}}} + ]], + cmdline = { + { + firstc = ':', + content = { { 'sign jump' } }, + pos = 9, + }, + }, + popupmenu = { items = expected, pos = 1, anchor = { -1, 0, 5 } }, + } feed('<left><left>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{"sign "}}, - pos = 5, - }}, popupmenu={items=expected, pos=-1, anchor={-1, 0, 5}}} + ]], + cmdline = { + { + firstc = ':', + content = { { 'sign ' } }, + pos = 5, + }, + }, + popupmenu = { items = expected, pos = -1, anchor = { -1, 0, 5 } }, + } feed('<right>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{"sign define"}}, - pos = 11, - }}, popupmenu={items=expected, pos=0, anchor={-1, 0, 5}}} + ]], + cmdline = { + { + firstc = ':', + content = { { 'sign define' } }, + pos = 11, + }, + }, + popupmenu = { items = expected, pos = 0, anchor = { -1, 0, 5 } }, + } feed('a') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{"sign definea"}}, - pos = 12, - }}} + ]], + cmdline = { + { + firstc = ':', + content = { { 'sign definea' } }, + pos = 12, + }, + }, + } feed('<esc>') -- check positioning with multibyte char in pattern - command("e långfile1") - command("sp långfile2") + command('e långfile1') + command('sp långfile2') feed(':b lå<tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | {3:långfile2 }| | {2:långfile1 }| | - ]], popupmenu={ - anchor = { -1, 0, 2 }, - items = {{ "långfile1", "", "", "" }, { "långfile2", "", "", "" }}, - pos = 0 - }, cmdline={{ - content = {{ "b långfile1" }}, - firstc = ":", - pos = 12 - }}} + ]], + popupmenu = { + anchor = { -1, 0, 2 }, + items = { { 'långfile1', '', '', '' }, { 'långfile2', '', '', '' } }, + pos = 0, + }, + cmdline = { + { + content = { { 'b långfile1' } }, + firstc = ':', + pos = 12, + }, + }, + } end) it('ext_wildmenu takes precedence over ext_popupmenu', function() @@ -643,17 +776,22 @@ local function test_cmdline(linegrid) screen:set_option('ext_popupmenu', true) feed(':sign <tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - firstc = ":", - content = {{"sign define"}}, - pos = 11, - }}, wildmenu_items=expected, wildmenu_pos=0} + ]], + cmdline = { + { + firstc = ':', + content = { { 'sign define' } }, + pos = 11, + }, + }, + wildmenu_items = expected, + wildmenu_pos = 0, + } end) it("doesn't send invalid events when aborting mapping #10000", function() @@ -661,85 +799,100 @@ local function test_cmdline(linegrid) command('cnoremap ab c') feed(':xa') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], cmdline={{ - content = { { "x" } }, - firstc = ":", - pos = 1, - special = { "a", false } - }}} + ]], + cmdline = { + { + content = { { 'x' } }, + firstc = ':', + pos = 1, + special = { 'a', false }, + }, + }, + } -- This used to send an invalid event where pos where larger than the total -- length of content. Checked in _handle_cmdline_show. feed('<esc>') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]) end) - end -- the representation of cmdline and cmdline_block contents changed with ext_linegrid -- (which uses indexed highlights) so make sure to test both -describe('ui/ext_cmdline', function() test_cmdline(true) end) -describe('ui/ext_cmdline (legacy highlights)', function() test_cmdline(false) end) +describe('ui/ext_cmdline', function() + test_cmdline(true) +end) +describe('ui/ext_cmdline (legacy highlights)', function() + test_cmdline(false) +end) describe('cmdline redraw', function() local screen before_each(function() clear() - screen = new_screen({rgb=true}) + screen = new_screen({ rgb = true }) end) it('with timer', function() feed(':012345678901234567890123456789') - screen:expect{grid=[[ + screen:expect { + grid = [[ | {1:~ }| {3: }| :012345678901234567890123| 456789^ | - ]]} + ]], + } command('call timer_start(0, {-> 1})') - screen:expect{grid=[[ + screen:expect { + grid = [[ | {1:~ }| {3: }| :012345678901234567890123| 456789^ | - ]], unchanged=true, timeout=100} + ]], + unchanged = true, + timeout = 100, + } end) it('with <Cmd>', function() if is_os('bsd') then pending('FIXME #10804') end - command('cmap a <Cmd>call sin(0)<CR>') -- no-op + command('cmap a <Cmd>call sin(0)<CR>') -- no-op feed(':012345678901234567890123456789') - screen:expect{grid=[[ + screen:expect { + grid = [[ | {1:~ }| {3: }| :012345678901234567890123| 456789^ | - ]]} + ]], + } feed('a') - screen:expect{grid=[[ + screen:expect { + grid = [[ | {1:~ }| {3: }| :012345678901234567890123| 456789^ | - ]], unchanged=true} + ]], + unchanged = true, + } end) it('after pressing Ctrl-C in cmdwin in Visual mode #18967', function() @@ -748,26 +901,20 @@ describe('cmdline redraw', function() feed('q:iabc<Esc>vhh') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2:[No Name] }| {1::}^a{8:bc} | - {1:~ }| - {1:~ }| + {1:~ }|*2 {3:[Command Line] }| {9:-- VISUAL --} | ]]) feed('<C-C>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2:[No Name] }| {1::}a{8:bc} | - {1:~ }| - {1:~ }| + {1:~ }|*2 {3:[Command Line] }| :^abc | ]]) @@ -775,80 +922,80 @@ describe('cmdline redraw', function() it('with rightleftcmd', function() command('set rightleft rightleftcmd=search shortmess+=s') - meths.buf_set_lines(0, 0, -1, true, {"let's rock!"}) - screen:expect{grid=[[ + api.nvim_buf_set_lines(0, 0, -1, true, { "let's rock!" }) + screen:expect { + grid = [[ !kcor s'te^l| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*3 | - ]]} + ]], + } feed '/' - screen:expect{grid=[[ + screen:expect { + grid = [[ !kcor s'tel| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*3 ^ /| - ]]} + ]], + } feed "let's" -- note: cursor looks off but looks alright in real use -- when rendered as a block so it touches the end of the text - screen:expect{grid=[[ + screen:expect { + grid = [[ !kcor {2:s'tel}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*3 ^ s'tel/| - ]]} + ]], + } -- cursor movement - feed "<space>" - screen:expect{grid=[[ + feed '<space>' + screen:expect { + grid = [[ !kcor{2: s'tel}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*3 ^ s'tel/| - ]]} + ]], + } - feed "rock" - screen:expect{grid=[[ + feed 'rock' + screen:expect { + grid = [[ !{2:kcor s'tel}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*3 ^ kcor s'tel/| - ]]} + ]], + } - feed "<right>" - screen:expect{grid=[[ + feed '<right>' + screen:expect { + grid = [[ !{2:kcor s'tel}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*3 ^kcor s'tel/| - ]]} + ]], + } - feed "<left>" - screen:expect{grid=[[ + feed '<left>' + screen:expect { + grid = [[ !{2:kcor s'tel}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*3 ^ kcor s'tel/| - ]]} + ]], + } - feed "<cr>" - screen:expect{grid=[[ + feed '<cr>' + screen:expect { + grid = [[ !{10:kcor s'te^l}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*3 kcor s'tel/ | - ]]} + ]], + } end) end) @@ -863,48 +1010,52 @@ describe('statusline is redrawn on entering cmdline', function() it('from normal mode', function() command('set statusline=%{mode()}') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {3:n }| | - ]]} + ]], + } feed(':') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {3:c }| :^ | - ]]} + ]], + } end) it('from normal mode when : is mapped', function() command('set statusline=%{mode()}') command('nnoremap ; :') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {3:n }| | - ]]} + ]], + } feed(';') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {3:c }| :^ | - ]]} + ]], + } end) it('with scrolled messages', function() - screen:try_resize(35,14) + screen:try_resize(35, 14) exec([[ let g:count = 0 autocmd CmdlineEnter * let g:count += 1 @@ -914,30 +1065,28 @@ describe('statusline is redrawn on entering cmdline', function() setlocal winbar=%{mode()}%{g:count} ]]) feed(':echoerr doesnotexist<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {9:c1 }| | {3:c1 }| | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {3: }| {4:E121: Undefined variable: doesnotex}| {4:ist} | {5:Press ENTER or type command to cont}| {5:inue}^ | - ]]} + ]], + } feed(':echoerr doesnotexist<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {9:c2 }| | {3:c2 }| | - {1:~ }| - {1:~ }| + {1:~ }|*2 {3: }| {4:E121: Undefined variable: doesnotex}| {4:ist} | @@ -946,10 +1095,12 @@ describe('statusline is redrawn on entering cmdline', function() {4:ist} | {5:Press ENTER or type command to cont}| {5:inue}^ | - ]]} + ]], + } feed(':echoerr doesnotexist<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {9:c3 }| | {3:c3 }| @@ -964,61 +1115,60 @@ describe('statusline is redrawn on entering cmdline', function() {4:ist} | {5:Press ENTER or type command to cont}| {5:inue}^ | - ]]} + ]], + } feed('<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {9:n3 }| ^ | {3:n3 }| | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 {2:[No Name] }| | - ]]} + ]], + } end) describe('if custom statusline is set by', function() before_each(function() command('set statusline=') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {3:[No Name] }| | - ]]} + ]], + } end) it('CmdlineEnter autocommand', function() command('autocmd CmdlineEnter * set statusline=command') feed(':') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {3:command }| :^ | - ]]} + ]], + } end) it('ModeChanged autocommand', function() command('autocmd ModeChanged *:c set statusline=command') feed(':') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {3:command }| :^ | - ]]} + ]], + } end) end) end) @@ -1027,9 +1177,9 @@ it('tabline is not redrawn in Ex mode #24122', function() clear() local screen = Screen.new(60, 5) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {bold = true, reverse = true}, -- MsgSeparator - [2] = {reverse = true}, -- TabLineFill + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { bold = true, reverse = true }, -- MsgSeparator + [2] = { reverse = true }, -- TabLineFill }) screen:attach() @@ -1044,28 +1194,32 @@ it('tabline is not redrawn in Ex mode #24122', function() ]]) feed('gQ') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:foo }| | {1: }| Entering Ex mode. Type "visual" to go to Normal mode. | :^ | - ]]} + ]], + } feed('echo 1<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: }| Entering Ex mode. Type "visual" to go to Normal mode. | :echo 1 | 1 | :^ | - ]]} + ]], + } end) -describe("cmdline height", function() +describe('cmdline height', function() before_each(clear) - it("does not crash resized screen #14263", function() + it('does not crash resized screen #14263', function() local screen = Screen.new(25, 10) screen:attach() command('set cmdheight=9999') @@ -1089,329 +1243,341 @@ describe('cmdheight=0', function() clear() screen = Screen.new(25, 5) screen:set_default_attr_ids { - [1] = {bold = true, foreground = Screen.colors.Blue}; - [2] = {bold = true, reverse = true}; - [3] = {bold = true}; - [4] = {foreground = Screen.colors.White, background = Screen.colors.Red}; - [5] = {foreground = Screen.colors.SeaGreen4, bold = true}; - [6] = {reverse = true}; - [7] = {background = Screen.colors.Yellow}; + [1] = { bold = true, foreground = Screen.colors.Blue }, + [2] = { bold = true, reverse = true }, + [3] = { bold = true }, + [4] = { foreground = Screen.colors.White, background = Screen.colors.Red }, + [5] = { foreground = Screen.colors.SeaGreen4, bold = true }, + [6] = { reverse = true }, + [7] = { background = Screen.colors.Yellow }, } screen:attach() end) - it("with redrawdebug=invalid resize -1", function() - command("set redrawdebug=invalid cmdheight=0 noruler laststatus=0") - screen:expect{grid=[[ + it('with redrawdebug=invalid resize -1', function() + command('set redrawdebug=invalid cmdheight=0 noruler laststatus=0') + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]]} - feed(":resize -1<CR>") - screen:expect{grid=[[ + {1:~ }|*4 + ]], + } + feed(':resize -1<CR>') + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]]} + ]], + } assert_alive() end) - it("with cmdheight=1 noruler laststatus=2", function() - command("set cmdheight=1 noruler laststatus=2") - screen:expect{grid=[[ + it('with cmdheight=1 noruler laststatus=2', function() + command('set cmdheight=1 noruler laststatus=2') + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:[No Name] }| | - ]]} + ]], + } end) - it("with cmdheight=0 noruler laststatus=2", function() - command("set cmdheight=0 noruler laststatus=2") - screen:expect{grid=[[ + it('with cmdheight=0 noruler laststatus=2', function() + command('set cmdheight=0 noruler laststatus=2') + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2:[No Name] }| - ]]} + ]], + } end) - it("with cmdheight=0 ruler laststatus=0", function() - command("set cmdheight=0 ruler laststatus=0") - screen:expect{grid=[[ + it('with cmdheight=0 ruler laststatus=0', function() + command('set cmdheight=0 ruler laststatus=0') + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]]} + {1:~ }|*4 + ]], + } end) - it("with cmdheight=0 ruler laststatus=0", function() - command("set cmdheight=0 noruler laststatus=0 showmode") + it('with cmdheight=0 ruler laststatus=0', function() + command('set cmdheight=0 noruler laststatus=0 showmode') feed('i') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], showmode={}} + {1:~ }|*4 + ]], + showmode = {}, + } feed('<Esc>') eq(0, eval('&cmdheight')) end) - it("with cmdheight=0 ruler rulerformat laststatus=0", function() - command("set cmdheight=0 noruler laststatus=0 rulerformat=%l,%c%= showmode") + it('with cmdheight=0 ruler rulerformat laststatus=0', function() + command('set cmdheight=0 noruler laststatus=0 rulerformat=%l,%c%= showmode') feed('i') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], showmode={}} + {1:~ }|*4 + ]], + showmode = {}, + } feed('<Esc>') eq(0, eval('&cmdheight')) end) - it("with showmode", function() - command("set cmdheight=1 noruler laststatus=0 showmode") + it('with showmode', function() + command('set cmdheight=1 noruler laststatus=0 showmode') feed('i') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {3:-- INSERT --} | - ]]} + ]], + } feed('<Esc>') eq(1, eval('&cmdheight')) end) - it("when using command line", function() - command("set cmdheight=0 noruler laststatus=0") + it('when using command line', function() + command('set cmdheight=0 noruler laststatus=0') feed(':') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 :^ | - ]]} + ]], + } eq(0, eval('&cmdheight')) feed('<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], showmode={}} + {1:~ }|*4 + ]], + showmode = {}, + } eq(0, eval('&cmdheight')) end) - it("when using input()", function() - command("set cmdheight=0 noruler laststatus=0") + it('when using input()', function() + command('set cmdheight=0 noruler laststatus=0') feed(':call input("foo >")<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | {1:~ }| {2: }| :call input("foo >") | foo >^ | - ]]} + ]], + } eq(0, eval('&cmdheight')) feed('<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], showmode={}} + {1:~ }|*4 + ]], + showmode = {}, + } eq(0, eval('&cmdheight')) end) - it("with winbar and splits", function() - command("set cmdheight=0 noruler laststatus=3 winbar=foo") + it('with winbar and splits', function() + command('set cmdheight=0 noruler laststatus=3 winbar=foo') feed(':split<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2: }| :split | {4:E36: Not enough room} | {5:Press ENTER or type comma}| {5:nd to continue}^ | - ]]} + ]], + } feed('<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:foo }| ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:[No Name] }| - ]]} + ]], + } feed(':') - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:foo }| | - {1:~ }| - {1:~ }| + {1:~ }|*2 :^ | - ]]} + ]], + } feed('<Esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:foo }| ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:[No Name] }| - ]], showmode={}} + ]], + showmode = {}, + } eq(0, eval('&cmdheight')) assert_alive() end) - it("when macro with lastline", function() - command("set cmdheight=0 display=lastline") + it('when macro with lastline', function() + command('set cmdheight=0 display=lastline') feed('qq') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]]} + {1:~ }|*4 + ]], + } feed('q') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], unchanged=true} + {1:~ }|*4 + ]], + unchanged = true, + } end) - it("when substitute text", function() - command("set cmdheight=0 noruler laststatus=3") + it('when substitute text', function() + command('set cmdheight=0 noruler laststatus=3') feed('ifoo<ESC>') - screen:expect{grid=[[ + screen:expect { + grid = [[ fo^o | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2:[No Name] [+] }| - ]]} + ]], + } feed(':%s/foo/bar/gc<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {6:foo} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {5:replace wi...q/l/^E/^Y)?}^ | - ]]} + ]], + } feed('y') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^bar | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2:[No Name] [+] }| - ]]} + ]], + } assert_alive() end) - it("when window resize", function() - command("set cmdheight=0") + it('when window resize', function() + command('set cmdheight=0') feed('<C-w>+') eq(0, eval('&cmdheight')) end) - it("with non-silent mappings with cmdline", function() - command("set cmdheight=0") - command("map <f3> :nohlsearch<cr>") + it('with non-silent mappings with cmdline', function() + command('set cmdheight=0') + command('map <f3> :nohlsearch<cr>') feed('iaabbaa<esc>/aa<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {7:^aa}bb{7:aa} | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]]} + {1:~ }|*4 + ]], + } feed('<f3>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^aabbaa | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]]} + {1:~ }|*4 + ]], + } end) it('with silent! at startup', function() - clear{args={'-c', 'set cmdheight=0', '-c', 'autocmd VimEnter * silent! call Foo()'}} + clear { args = { '-c', 'set cmdheight=0', '-c', 'autocmd VimEnter * silent! call Foo()' } } screen:attach() -- doesn't crash while not displaying silent! error message - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]]} + {1:~ }|*4 + ]], + } end) it('with multigrid', function() - clear{args={'--cmd', 'set cmdheight=0'}} - screen:attach{ext_multigrid=true} - meths.buf_set_lines(0, 0, -1, true, {'p'}) - screen:expect{grid=[[ + clear { args = { '--cmd', 'set cmdheight=0' } } + screen:attach { ext_multigrid = true } + api.nvim_buf_set_lines(0, 0, -1, true, { 'p' }) + screen:expect { + grid = [[ ## grid 1 - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| + [2:-------------------------]|*5 ## grid 2 ^p | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 - ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - }} + ]], + win_viewport = { + [2] = { + win = 1000, + topline = 0, + botline = 2, + curline = 0, + curcol = 0, + linecount = 1, + sum_scroll_delta = 0, + }, + }, + } feed '/p' - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| + [2:-------------------------]|*4 [3:-------------------------]| ## grid 2 {6:p} | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 /p^ | - ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - }} + ]], + win_viewport = { + [2] = { + win = 1000, + topline = 0, + botline = 2, + curline = 0, + curcol = 0, + linecount = 1, + sum_scroll_delta = 0, + }, + }, + } end) it('winbar is redrawn on entering cmdline and :redrawstatus #20336', function() @@ -1423,8 +1589,7 @@ describe('cmdheight=0', function() screen:expect([[ {3:c :}| | - {1:~ }| - {1:~ }| + {1:~ }|*2 :^ | ]]) feed('echo') @@ -1432,16 +1597,14 @@ describe('cmdheight=0', function() screen:expect([[ {3:c :}| | - {1:~ }| - {1:~ }| + {1:~ }|*2 :echo^ | ]]) command('redrawstatus') screen:expect([[ {3:c :echo}| | - {1:~ }| - {1:~ }| + {1:~ }|*2 :echo^ | ]]) end) @@ -1452,28 +1615,17 @@ describe('cmdheight=0', function() command('vsplit') screen:expect([[ ^ │ | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*8 ]]) feed(':') command('split') feed('<Esc>') screen:expect([[ ^ │ | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*3 {2:[No Name] }│{1:~ }| │{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*3 ]]) command('resize 2') screen:expect([[ @@ -1481,25 +1633,17 @@ describe('cmdheight=0', function() {1:~ }│{1:~ }| {2:[No Name] }│{1:~ }| │{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*5 ]]) feed(':') command('wincmd =') feed('<Esc>') screen:expect([[ ^ │ | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*3 {2:[No Name] }│{1:~ }| │{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*3 ]]) end) @@ -1508,10 +1652,7 @@ describe('cmdheight=0', function() feed('d') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ]]) assert_alive() end) @@ -1521,52 +1662,48 @@ describe('cmdheight=0', function() command('resize +1') screen:expect([[ ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:[No Name] }| | ]]) command('set cmdheight=0') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2:[No Name] }| - ]]} + ]], + } command('resize -1') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:[No Name] }| | - ]]} + ]], + } command('resize +1') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2:[No Name] }| ]]) end) - it("cannot be resized at all with external messages", function() + it('cannot be resized at all with external messages', function() clear() - screen = new_screen({rgb=true, ext_messages=true}) + screen = new_screen({ rgb = true, ext_messages = true }) command('set laststatus=2 mouse=a') command('resize -1') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {3:[No Name] }| ]]) - meths.input_mouse('left', 'press', '', 0, 6, 10) + api.nvim_input_mouse('left', 'press', '', 0, 6, 10) poke_eventloop() - meths.input_mouse('left', 'drag', '', 0, 5, 10) + api.nvim_input_mouse('left', 'drag', '', 0, 5, 10) screen:expect_unchanged() end) end) diff --git a/test/functional/ui/cursor_spec.lua b/test/functional/ui/cursor_spec.lua index 05057ca080..871e9a0790 100644 --- a/test/functional/ui/cursor_spec.lua +++ b/test/functional/ui/cursor_spec.lua @@ -1,6 +1,6 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local clear, meths = helpers.clear, helpers.meths +local clear, api = helpers.clear, helpers.api local eq = helpers.eq local command = helpers.command @@ -27,7 +27,8 @@ describe('ui/cursor', function() attr = {}, attr_lm = {}, mouse_shape = 0, - short_name = 'n' }, + short_name = 'n', + }, [2] = { blinkoff = 0, blinkon = 0, @@ -40,7 +41,8 @@ describe('ui/cursor', function() attr = {}, attr_lm = {}, mouse_shape = 0, - short_name = 'v' }, + short_name = 'v', + }, [3] = { blinkoff = 0, blinkon = 0, @@ -53,7 +55,8 @@ describe('ui/cursor', function() attr = {}, attr_lm = {}, mouse_shape = 0, - short_name = 'i' }, + short_name = 'i', + }, [4] = { blinkoff = 0, blinkon = 0, @@ -66,7 +69,8 @@ describe('ui/cursor', function() attr = {}, attr_lm = {}, mouse_shape = 0, - short_name = 'r' }, + short_name = 'r', + }, [5] = { blinkoff = 0, blinkon = 0, @@ -79,7 +83,8 @@ describe('ui/cursor', function() attr = {}, attr_lm = {}, mouse_shape = 0, - short_name = 'c' }, + short_name = 'c', + }, [6] = { blinkoff = 0, blinkon = 0, @@ -92,7 +97,8 @@ describe('ui/cursor', function() attr = {}, attr_lm = {}, mouse_shape = 0, - short_name = 'ci' }, + short_name = 'ci', + }, [7] = { blinkoff = 0, blinkon = 0, @@ -105,7 +111,8 @@ describe('ui/cursor', function() attr = {}, attr_lm = {}, mouse_shape = 0, - short_name = 'cr' }, + short_name = 'cr', + }, [8] = { blinkoff = 0, blinkon = 0, @@ -118,7 +125,8 @@ describe('ui/cursor', function() attr = {}, attr_lm = {}, mouse_shape = 0, - short_name = 'o' }, + short_name = 'o', + }, [9] = { blinkoff = 0, blinkon = 0, @@ -131,35 +139,43 @@ describe('ui/cursor', function() attr = {}, attr_lm = {}, mouse_shape = 0, - short_name = 've' }, + short_name = 've', + }, [10] = { name = 'cmdline_hover', mouse_shape = 0, - short_name = 'e' }, + short_name = 'e', + }, [11] = { name = 'statusline_hover', mouse_shape = 0, - short_name = 's' }, + short_name = 's', + }, [12] = { name = 'statusline_drag', mouse_shape = 0, - short_name = 'sd' }, + short_name = 'sd', + }, [13] = { name = 'vsep_hover', mouse_shape = 0, - short_name = 'vs' }, + short_name = 'vs', + }, [14] = { name = 'vsep_drag', mouse_shape = 0, - short_name = 'vd' }, + short_name = 'vd', + }, [15] = { name = 'more', mouse_shape = 0, - short_name = 'm' }, + short_name = 'm', + }, [16] = { name = 'more_lastline', mouse_shape = 0, - short_name = 'ml' }, + short_name = 'ml', + }, [17] = { blinkoff = 0, blinkon = 0, @@ -171,8 +187,9 @@ describe('ui/cursor', function() id_lm = 0, attr = {}, attr_lm = {}, - short_name = 'sm' }, - } + short_name = 'sm', + }, + } screen:expect(function() -- Default 'guicursor', published on startup. @@ -184,38 +201,55 @@ describe('ui/cursor', function() -- Event is published ONLY if the cursor style changed. screen._mode_info = nil command("echo 'test'") - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - ~ | - ~ | - ~ | + ~ |*3 test | - ]], condition=function() - eq(nil, screen._mode_info) - end} + ]], + condition = function() + eq(nil, screen._mode_info) + end, + } -- Change the cursor style. helpers.command('hi Cursor guibg=DarkGray') - helpers.command('set guicursor=n-v-c:block,i-ci-ve:ver25,r-cr-o:hor20' - ..',a:blinkwait700-blinkoff400-blinkon250-Cursor/lCursor' - ..',sm:block-blinkwait175-blinkoff150-blinkon175') + helpers.command( + 'set guicursor=n-v-c:block,i-ci-ve:ver25,r-cr-o:hor20' + .. ',a:blinkwait700-blinkoff400-blinkon250-Cursor/lCursor' + .. ',sm:block-blinkwait175-blinkoff150-blinkon175' + ) -- Update the expected values. for _, m in ipairs(expected_mode_info) do if m.name == 'showmatch' then - if m.blinkon then m.blinkon = 175 end - if m.blinkoff then m.blinkoff = 150 end - if m.blinkwait then m.blinkwait = 175 end + if m.blinkon then + m.blinkon = 175 + end + if m.blinkoff then + m.blinkoff = 150 + end + if m.blinkwait then + m.blinkwait = 175 + end else - if m.blinkon then m.blinkon = 250 end - if m.blinkoff then m.blinkoff = 400 end - if m.blinkwait then m.blinkwait = 700 end + if m.blinkon then + m.blinkon = 250 + end + if m.blinkoff then + m.blinkoff = 400 + end + if m.blinkwait then + m.blinkwait = 700 + end end if m.hl_id then - m.hl_id = 64 - m.attr = {background = Screen.colors.DarkGray} + m.hl_id = 64 + m.attr = { background = Screen.colors.DarkGray } + end + if m.id_lm then + m.id_lm = 69 end - if m.id_lm then m.id_lm = 67 end end -- Assert the new expectation. @@ -232,10 +266,10 @@ describe('ui/cursor', function() -- Update the expected values. for _, m in ipairs(expected_mode_info) do if m.hl_id then - m.attr = {background = Screen.colors.Red} + m.attr = { background = Screen.colors.Red } end if m.id_lm then - m.attr_lm = {background = Screen.colors.Green} + m.attr_lm = { background = Screen.colors.Green } end end -- Assert the new expectation. @@ -250,23 +284,27 @@ describe('ui/cursor', function() for _, m in ipairs(expected_mode_info) do if m.hl_id then - m.attr = {background = Screen.colors.Red, blend = 100} + m.attr = { background = Screen.colors.Red, blend = 100 } end end - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - ~ | - ~ | - ~ | + ~ |*3 test | - ]], condition=function() - eq(expected_mode_info, screen._mode_info) - end + ]], + condition = function() + eq(expected_mode_info, screen._mode_info) + end, } -- Another cursor style. - meths.set_option_value('guicursor', 'n-v-c:ver35-blinkwait171-blinkoff172-blinkon173' - ..',ve:hor35,o:ver50,i-ci:block,r-cr:hor90,sm:ver42', {}) + api.nvim_set_option_value( + 'guicursor', + 'n-v-c:ver35-blinkwait171-blinkoff172-blinkon173' + .. ',ve:hor35,o:ver50,i-ci:block,r-cr:hor90,sm:ver42', + {} + ) screen:expect(function() local named = {} for _, m in ipairs(screen._mode_info) do @@ -288,9 +326,13 @@ describe('ui/cursor', function() end) -- If there is no setting for guicursor, it becomes the default setting. - meths.set_option_value('guicursor', 'n:ver35-blinkwait171-blinkoff172-blinkon173-Cursor/lCursor', {}) + api.nvim_set_option_value( + 'guicursor', + 'n:ver35-blinkwait171-blinkoff172-blinkon173-Cursor/lCursor', + {} + ) screen:expect(function() - for _,m in ipairs(screen._mode_info) do + for _, m in ipairs(screen._mode_info) do if m.name ~= 'normal' then eq('block', m.cursor_shape or 'block') eq(0, m.blinkon or 0) @@ -304,7 +346,7 @@ describe('ui/cursor', function() end) it("empty 'guicursor' sets cursor_shape=block in all modes", function() - meths.set_option_value('guicursor', '', {}) + api.nvim_set_option_value('guicursor', '', {}) screen:expect(function() -- Empty 'guicursor' sets enabled=false. eq(false, screen._cursor_style_enabled) @@ -318,5 +360,4 @@ describe('ui/cursor', function() end end) end) - end) diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index e8fcfc46fc..e57e719192 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -7,9 +7,8 @@ local insert = helpers.insert local exec_lua = helpers.exec_lua local exec = helpers.exec local expect_events = helpers.expect_events -local meths = helpers.meths -local funcs = helpers.funcs -local curbufmeths = helpers.curbufmeths +local api = helpers.api +local fn = helpers.fn local command = helpers.command local eq = helpers.eq local assert_alive = helpers.assert_alive @@ -40,6 +39,7 @@ describe('decorations providers', function() [16] = {special = Screen.colors.Red, undercurl = true}, [17] = {foreground = Screen.colors.Red}, [18] = {bold = true, foreground = Screen.colors.SeaGreen}; + [19] = {bold = true}; } end) @@ -212,9 +212,7 @@ describe('decorations providers', function() {15:i} am not capitalized. | I am a {16:speling} {16:mistakke}. | | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]} @@ -227,9 +225,7 @@ describe('decorations providers', function() {15:^i} am not capitalized. | I am a {16:speling} {16:mistakke}. | | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]} @@ -242,24 +238,20 @@ describe('decorations providers', function() {15:i} am not capitalized. | I am a {16:^speling} {16:mistakke}. | | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]} -- spell=false with higher priority does disable spell - local ns = meths.create_namespace "spell" - local id = curbufmeths.set_extmark(ns, 0, 0, { priority = 30, end_row = 2, end_col = 23, spell = false }) + local ns = api.nvim_create_namespace "spell" + local id = api.nvim_buf_set_extmark(0, ns, 0, 0, { priority = 30, end_row = 2, end_col = 23, spell = false }) screen:expect{grid=[[ I am well written text. | i am not capitalized. | I am a ^speling mistakke. | | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]} @@ -269,24 +261,20 @@ describe('decorations providers', function() i am not capitalized. | I am a ^speling mistakke. | | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {17:search hit BOTTOM, continuing at TOP} | ]]} command('echo ""') -- spell=false with lower priority doesn't disable spell - curbufmeths.set_extmark(ns, 0, 0, { id = id, priority = 10, end_row = 2, end_col = 23, spell = false }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { id = id, priority = 10, end_row = 2, end_col = 23, spell = false }) screen:expect{grid=[[ I am well written text. | {15:i} am not capitalized. | I am a {16:^speling} {16:mistakke}. | | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]} @@ -296,9 +284,7 @@ describe('decorations providers', function() {15:i} am not capitalized. | I am a {16:speling} {16:^mistakke}. | | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]} @@ -320,7 +306,7 @@ describe('decorations providers', function() LineNr = {italic=true, bg="Magenta"}; Comment = {fg="#FF0000", bg = 80*256+40}; CursorLine = {link="ErrorMsg"}; - } do meths.set_hl(ns1, k, v) end + } do api.nvim_set_hl(ns1, k, v) end screen:expect{grid=[[ {3: 1 }{4:// just to see if there was an accid}| @@ -341,7 +327,7 @@ describe('decorations providers', function() | ]]} - meths.set_hl_ns(ns1) + api.nvim_set_hl_ns(ns1) screen:expect{grid=[[ {10: 1 }{11:// just to see if there was an accid}| {10: }{11:ent} | @@ -401,7 +387,7 @@ describe('decorations providers', function() highlight link LinkGroup OriginalGroup ]] - meths.buf_set_virtual_text(0, 0, 2, {{'- not red', 'LinkGroup'}}, {}) + api.nvim_buf_set_virtual_text(0, 0, 2, {{'- not red', 'LinkGroup'}}, {}) screen:expect{grid=[[ // just to see if there was an accident | // on Mulholland Drive | @@ -413,8 +399,8 @@ describe('decorations providers', function() | ]]} - meths.set_hl(ns1, 'LinkGroup', {fg = 'Blue'}) - meths.set_hl_ns(ns1) + api.nvim_set_hl(ns1, 'LinkGroup', {fg = 'Blue'}) + api.nvim_set_hl_ns(ns1) screen:expect{grid=[[ // just to see if there was an accident | @@ -437,7 +423,7 @@ describe('decorations providers', function() highlight link LinkGroup OriginalGroup ]] - meths.buf_set_virtual_text(0, 0, 2, {{'- not red', 'LinkGroup'}}, {}) + api.nvim_buf_set_virtual_text(0, 0, 2, {{'- not red', 'LinkGroup'}}, {}) screen:expect{grid=[[ // just to see if there was an accident | // on Mulholland Drive | @@ -449,8 +435,8 @@ describe('decorations providers', function() | ]]} - meths.set_hl(ns1, 'LinkGroup', {fg = 'Blue', default=true}) - meths.set_hl_ns(ns1) + api.nvim_set_hl(ns1, 'LinkGroup', {fg = 'Blue', default=true}) + api.nvim_set_hl_ns(ns1) feed 'k' screen:expect{grid=[[ @@ -629,9 +615,9 @@ describe('decorations providers', function() vim.api.nvim_buf_set_lines(0, 0, -1, false, lines) ]]) setup_provider([[ - local function on_do(kind, winid, bufnr, topline, botline_guess) + local function on_do(kind, winid, bufnr, topline, botline) if kind == 'win' then - if topline < 100 and botline_guess > 100 then + if topline < 100 and botline > 100 then api.nvim_buf_set_extmark(bufnr, ns1, 99, -1, { sign_text = 'X' }) else api.nvim_buf_clear_namespace(bufnr, ns1, 0, -1) @@ -640,7 +626,7 @@ describe('decorations providers', function() end ]]) command([[autocmd CursorMoved * call line('w$')]]) - meths.win_set_cursor(0, {100, 0}) + api.nvim_win_set_cursor(0, {100, 0}) screen:expect([[ {14: }hello97 | {14: }hello98 | @@ -651,7 +637,7 @@ describe('decorations providers', function() {14: }hello103 | | ]]) - meths.win_set_cursor(0, {1, 0}) + api.nvim_win_set_cursor(0, {1, 0}) screen:expect([[ ^hello1 | hello2 | @@ -669,7 +655,7 @@ describe('decorations providers', function() eok = true ]]) setup_provider([[ - local function on_do(kind, winid, bufnr, topline, botline_guess) + local function on_do(kind, winid, bufnr, topline, botline) if kind == 'line' then api.nvim_buf_set_extmark(bufnr, ns1, 1, -1, { sign_text = 'X' }) eok = pcall(api.nvim_buf_clear_namespace, bufnr, ns1, 0, -1) @@ -701,6 +687,77 @@ describe('decorations providers', function() {18:Press ENTER or type command to continue}^ | ]]} end) + + it('can add new providers during redraw #26652', function() + setup_provider [[ + local ns = api.nvim_create_namespace('test_no_add') + function on_do(...) + api.nvim_set_decoration_provider(ns, {}) + end + ]] + + helpers.assert_alive() + end) + + it('supports subpriorities (order of definitions in a query file #27131)', function() + insert(mulholland) + setup_provider [[ + local test_ns = api.nvim_create_namespace('mulholland') + function on_do(event, ...) + if event == "line" then + local win, buf, line = ... + api.nvim_buf_set_extmark(buf, test_ns, line, 0, { + end_row = line + 1, + hl_eol = true, + hl_group = 'Comment', + ephemeral = true, + priority = 100, + _subpriority = 20, + }) + + -- This extmark is set last but has a lower subpriority, so the first extmark "wins" + api.nvim_buf_set_extmark(buf, test_ns, line, 0, { + end_row = line + 1, + hl_eol = true, + hl_group = 'String', + ephemeral = true, + priority = 100, + _subpriority = 10, + }) + end + end + ]] + + screen:expect{grid=[[ + {4:// just to see if there was an accident }| + {4:// on Mulholland Drive }| + {4:try_start(); }| + {4:bufref_T save_buf; }| + {4:switch_buffer(&save_buf, buf); }| + {4:posp = getmark(mark, false); }| + {4:restore_buffer(&save_buf);^ }| + | + ]]} + end) + + it('is not invoked repeatedly in Visual mode with vim.schedule() #20235', function() + exec_lua([[_G.cnt = 0]]) + setup_provider([[ + function on_do(event, ...) + if event == 'win' then + vim.schedule(function() end) + _G.cnt = _G.cnt + 1 + end + end + ]]) + feed('v') + screen:expect([[ + ^ | + {1:~ }|*6 + {19:-- VISUAL --} | + ]]) + eq(2, exec_lua([[return _G.cnt]])) + end) end) local example_text = [[ @@ -749,14 +806,14 @@ describe('extmark decorations', function() [23] = {foreground = Screen.colors.Magenta1, background = Screen.colors.LightGrey}; [24] = {bold = true}; [25] = {background = Screen.colors.LightRed}; - [26] = {background=Screen.colors.DarkGrey, foreground=Screen.colors.LightGrey}; - [27] = {background = Screen.colors.Plum1}; + [26] = {background = Screen.colors.DarkGrey, foreground = Screen.colors.LightGrey}; + [27] = {background = Screen.colors.LightGrey, foreground = Screen.colors.Black}; [28] = {underline = true, foreground = Screen.colors.SlateBlue}; - [29] = {foreground = Screen.colors.SlateBlue, background = Screen.colors.LightGray, underline = true}; - [30] = {foreground = Screen.colors.DarkCyan, background = Screen.colors.LightGray, underline = true}; + [29] = {foreground = Screen.colors.SlateBlue, background = Screen.colors.LightGrey, underline = true}; + [30] = {foreground = Screen.colors.DarkCyan, background = Screen.colors.LightGrey, underline = true}; [31] = {underline = true, foreground = Screen.colors.DarkCyan}; [32] = {underline = true}; - [33] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGray}; + [33] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey}; [34] = {background = Screen.colors.Yellow}; [35] = {background = Screen.colors.Yellow, bold = true, foreground = Screen.colors.Blue}; [36] = {foreground = Screen.colors.Blue1, bold = true, background = Screen.colors.Red}; @@ -765,9 +822,12 @@ describe('extmark decorations', function() [39] = {foreground = Screen.colors.Blue1, background = Screen.colors.LightCyan1, bold = true}; [40] = {reverse = true}; [41] = {bold = true, reverse = true}; + [42] = {undercurl = true, special = Screen.colors.Red}; + [43] = {background = Screen.colors.Yellow, undercurl = true, special = Screen.colors.Red}; + [44] = {background = Screen.colors.LightMagenta}; } - ns = meths.create_namespace 'test' + ns = api.nvim_create_namespace 'test' end) it('empty virtual text at eol should not break colorcolumn #17860', function() @@ -787,11 +847,10 @@ describe('extmark decorations', function() colpos = colpos+1 {25: } | end {25: } | end {25: } | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) - meths.buf_set_extmark(0, ns, 4, 0, { virt_text={{''}}, virt_text_pos='eol'}) + api.nvim_buf_set_extmark(0, ns, 4, 0, { virt_text={{''}}, virt_text_pos='eol'}) screen:expect_unchanged() end) @@ -800,19 +859,19 @@ describe('extmark decorations', function() feed 'gg' for i = 1,9 do - meths.buf_set_extmark(0, ns, i, 0, { virt_text={{'|', 'LineNr'}}, virt_text_pos='overlay'}) + api.nvim_buf_set_extmark(0, ns, i, 0, { virt_text={{'|', 'LineNr'}}, virt_text_pos='overlay'}) if i == 3 or (i >= 6 and i <= 9) then - meths.buf_set_extmark(0, ns, i, 4, { virt_text={{'|', 'NonText'}}, virt_text_pos='overlay'}) + api.nvim_buf_set_extmark(0, ns, i, 4, { virt_text={{'|', 'NonText'}}, virt_text_pos='overlay'}) end end - meths.buf_set_extmark(0, ns, 9, 10, { virt_text={{'foo'}, {'bar', 'MoreMsg'}, {'!!', 'ErrorMsg'}}, virt_text_pos='overlay'}) + api.nvim_buf_set_extmark(0, ns, 9, 10, { virt_text={{'foo'}, {'bar', 'MoreMsg'}, {'!!', 'ErrorMsg'}}, virt_text_pos='overlay'}) -- can "float" beyond end of line - meths.buf_set_extmark(0, ns, 5, 28, { virt_text={{'loopy', 'ErrorMsg'}}, virt_text_pos='overlay'}) + api.nvim_buf_set_extmark(0, ns, 5, 28, { virt_text={{'loopy', 'ErrorMsg'}}, virt_text_pos='overlay'}) -- bound check: right edge of window - meths.buf_set_extmark(0, ns, 2, 26, { virt_text={{'bork bork bork'}, {(' bork'):rep(10), 'ErrorMsg'}}, virt_text_pos='overlay'}) + api.nvim_buf_set_extmark(0, ns, 2, 26, { virt_text={{'bork bork bork'}, {(' bork'):rep(10), 'ErrorMsg'}}, virt_text_pos='overlay'}) -- empty virt_text should not change anything - meths.buf_set_extmark(0, ns, 6, 16, { virt_text={{''}}, virt_text_pos='overlay'}) + api.nvim_buf_set_extmark(0, ns, 6, 16, { virt_text={{''}}, virt_text_pos='overlay'}) screen:expect{grid=[[ ^for _,item in ipairs(items) do | @@ -827,8 +886,7 @@ describe('extmark decorations', function() {2:|} {1:|} cofoo{3:bar}{4:!!}olpos+1 | end | end | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} @@ -857,18 +915,17 @@ describe('extmark decorations', function() s+1 | end | end | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} -- truncating in the middle of a char leaves a space - meths.buf_set_lines(0, 0, 1, true, {'for _,item in ipairs(items) do -- 古古古'}) - meths.buf_set_lines(0, 10, 12, true, {' end -- ??????????', 'end -- ?古古古古?古古'}) - meths.buf_set_extmark(0, ns, 0, 35, { virt_text={{'A', 'ErrorMsg'}, {'AA'}}, virt_text_pos='overlay'}) - meths.buf_set_extmark(0, ns, 10, 19, { virt_text={{'口口口', 'ErrorMsg'}}, virt_text_pos='overlay'}) - meths.buf_set_extmark(0, ns, 11, 21, { virt_text={{'口口口', 'ErrorMsg'}}, virt_text_pos='overlay'}) - meths.buf_set_extmark(0, ns, 11, 8, { virt_text={{'口口', 'ErrorMsg'}}, virt_text_pos='overlay'}) + api.nvim_buf_set_lines(0, 0, 1, true, {'for _,item in ipairs(items) do -- 古古古'}) + api.nvim_buf_set_lines(0, 10, 12, true, {' end -- ??????????', 'end -- ?古古古古?古古'}) + api.nvim_buf_set_extmark(0, ns, 0, 35, { virt_text={{'A', 'ErrorMsg'}, {'AA'}}, virt_text_pos='overlay'}) + api.nvim_buf_set_extmark(0, ns, 10, 19, { virt_text={{'口口口', 'ErrorMsg'}}, virt_text_pos='overlay'}) + api.nvim_buf_set_extmark(0, ns, 11, 21, { virt_text={{'口口口', 'ErrorMsg'}}, virt_text_pos='overlay'}) + api.nvim_buf_set_extmark(0, ns, 11, 8, { virt_text={{'口口', 'ErrorMsg'}}, virt_text_pos='overlay'}) screen:expect{grid=[[ ^for _,item in ipairs(i| tems) do -- {4:A}AA 古 | @@ -892,8 +949,7 @@ describe('extmark decorations', function() s+1 | end -- ???????{4:口 }| end -- {4:口口} 古古{4:口口 }| - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} @@ -914,7 +970,7 @@ describe('extmark decorations', function() | ]]} - meths.buf_clear_namespace(0, ns, 0, -1) + api.nvim_buf_clear_namespace(0, ns, 0, -1) screen:expect{grid=[[ ^for _,item in ipairs(items) do -- 古古古 | local text, hl_id_cell, count = unpack(item) | @@ -936,8 +992,8 @@ describe('extmark decorations', function() screen:try_resize(50, 6) insert(('ab'):rep(100)) for i = 0, 9 do - meths.buf_set_extmark(0, ns, 0, 42 + i, { virt_text={{tostring(i), 'ErrorMsg'}}, virt_text_pos='overlay'}) - meths.buf_set_extmark(0, ns, 0, 91 + i, { virt_text={{tostring(i), 'ErrorMsg'}}, virt_text_pos='overlay', virt_text_hide=true}) + api.nvim_buf_set_extmark(0, ns, 0, 42 + i, { virt_text={{tostring(i), 'ErrorMsg'}}, virt_text_pos='overlay'}) + api.nvim_buf_set_extmark(0, ns, 0, 91 + i, { virt_text={{tostring(i), 'ErrorMsg'}}, virt_text_pos='overlay', virt_text_hide=true}) end screen:expect{grid=[[ ababababababababababababababababababababab{4:01234567}| @@ -962,7 +1018,7 @@ describe('extmark decorations', function() screen:expect{grid=[[ ababababababababababababababababababababab{4:01234567}| {1:++}{4:89}abababababababababababababababababababa{4:0123456}| - {1:++}^a{18:babab}ababababababababababababababababababababab| + {1:++}^a{27:babab}ababababababababababababababababababababab| {1:++}abababababababababababababababababababababababab| {1:++}ababab | {24:-- VISUAL --} | @@ -972,7 +1028,7 @@ describe('extmark decorations', function() screen:expect{grid=[[ ababababababababababababababababababababab{4:01234567}| {1:++}{4:89}abababababababababababababababababababa{4:0123456}| - {1:++}{18:ababa}^bababababababababababababababababababababab| + {1:++}{27:ababa}^bababababababababababababababababababababab| {1:++}abababababababababababababababababababababababab| {1:++}ababab | {24:-- VISUAL --} | @@ -981,8 +1037,8 @@ describe('extmark decorations', function() feed('gk') screen:expect{grid=[[ ababababababababababababababababababababab{4:01234567}| - {1:++}{4:89}aba^b{18:ababababababababababababababababababababab}| - {1:++}{18:a}{4:89}babababababababababababababababababababababab| + {1:++}{4:89}aba^b{27:ababababababababababababababababababababab}| + {1:++}{27:a}{4:89}babababababababababababababababababababababab| {1:++}abababababababababababababababababababababababab| {1:++}ababab | {24:-- VISUAL --} | @@ -991,7 +1047,7 @@ describe('extmark decorations', function() feed('o') screen:expect{grid=[[ ababababababababababababababababababababab{4:01234567}| - {1:++}{4:89}aba{18:bababababababababababababababababababababab}| + {1:++}{4:89}aba{27:bababababababababababababababababababababab}| {1:++}^a{4:89}babababababababababababababababababababababab| {1:++}abababababababababababababababababababababababab| {1:++}ababab | @@ -1033,9 +1089,9 @@ describe('extmark decorations', function() it('virt_text_hide hides overlay virtual text when extmark is off-screen', function() screen:try_resize(50, 3) command('set nowrap') - meths.buf_set_lines(0, 0, -1, true, {'-- ' .. ('…'):rep(57)}) - meths.buf_set_extmark(0, ns, 0, 0, { virt_text={{'?????', 'ErrorMsg'}}, virt_text_pos='overlay', virt_text_hide=true}) - meths.buf_set_extmark(0, ns, 0, 123, { virt_text={{'!!!!!', 'ErrorMsg'}}, virt_text_pos='overlay', virt_text_hide=true}) + api.nvim_buf_set_lines(0, 0, -1, true, {'-- ' .. ('…'):rep(57)}) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text={{'?????', 'ErrorMsg'}}, virt_text_pos='overlay', virt_text_hide=true}) + api.nvim_buf_set_extmark(0, ns, 0, 123, { virt_text={{'!!!!!', 'ErrorMsg'}}, virt_text_pos='overlay', virt_text_hide=true}) screen:expect{grid=[[ {4:^?????}……………………………………………………………………………………………………{4:!!!!!}……| {1:~ }| @@ -1088,10 +1144,10 @@ describe('extmark decorations', function() it('overlay virtual text works on and after a TAB #24022', function() screen:try_resize(40, 3) - meths.buf_set_lines(0, 0, -1, true, {'\t\tline 1'}) - meths.buf_set_extmark(0, ns, 0, 0, { virt_text = {{'AA', 'Search'}}, virt_text_pos = 'overlay', hl_mode = 'combine' }) - meths.buf_set_extmark(0, ns, 0, 1, { virt_text = {{'BB', 'Search'}}, virt_text_pos = 'overlay', hl_mode = 'combine' }) - meths.buf_set_extmark(0, ns, 0, 2, { virt_text = {{'CC', 'Search'}}, virt_text_pos = 'overlay', hl_mode = 'combine' }) + api.nvim_buf_set_lines(0, 0, -1, true, {'\t\tline 1'}) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = {{'AA', 'Search'}}, virt_text_pos = 'overlay', hl_mode = 'combine' }) + api.nvim_buf_set_extmark(0, ns, 0, 1, { virt_text = {{'BB', 'Search'}}, virt_text_pos = 'overlay', hl_mode = 'combine' }) + api.nvim_buf_set_extmark(0, ns, 0, 2, { virt_text = {{'CC', 'Search'}}, virt_text_pos = 'overlay', hl_mode = 'combine' }) screen:expect{grid=[[ {34:AA} ^ {34:BB} {34:CC}ne 1 | {1:~ }| @@ -1125,19 +1181,19 @@ describe('extmark decorations', function() colpos {5:=} colpos{5:+}{13:1} | {5:end} | {5:end} | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} command 'hi Blendy guibg=Red blend=30' - meths.buf_set_extmark(0, ns, 1, 5, { virt_text={{'blendy text - here', 'Blendy'}}, virt_text_pos='overlay', hl_mode='blend'}) - meths.buf_set_extmark(0, ns, 2, 5, { virt_text={{'combining color', 'Blendy'}}, virt_text_pos='overlay', hl_mode='combine'}) - meths.buf_set_extmark(0, ns, 3, 5, { virt_text={{'replacing color', 'Blendy'}}, virt_text_pos='overlay', hl_mode='replace'}) + command 'hi! Visual guifg=NONE guibg=LightGrey' + api.nvim_buf_set_extmark(0, ns, 1, 5, { virt_text={{'blendy text - here', 'Blendy'}}, virt_text_pos='overlay', hl_mode='blend'}) + api.nvim_buf_set_extmark(0, ns, 2, 5, { virt_text={{'combining color', 'Blendy'}}, virt_text_pos='overlay', hl_mode='combine'}) + api.nvim_buf_set_extmark(0, ns, 3, 5, { virt_text={{'replacing color', 'Blendy'}}, virt_text_pos='overlay', hl_mode='replace'}) - meths.buf_set_extmark(0, ns, 4, 5, { virt_text={{'blendy text - here', 'Blendy'}}, virt_text_pos='overlay', hl_mode='blend', virt_text_hide=true}) - meths.buf_set_extmark(0, ns, 5, 5, { virt_text={{'combining color', 'Blendy'}}, virt_text_pos='overlay', hl_mode='combine', virt_text_hide=true}) - meths.buf_set_extmark(0, ns, 6, 5, { virt_text={{'replacing color', 'Blendy'}}, virt_text_pos='overlay', hl_mode='replace', virt_text_hide=true}) + api.nvim_buf_set_extmark(0, ns, 4, 5, { virt_text={{'blendy text - here', 'Blendy'}}, virt_text_pos='overlay', hl_mode='blend', virt_text_hide=true}) + api.nvim_buf_set_extmark(0, ns, 5, 5, { virt_text={{'combining color', 'Blendy'}}, virt_text_pos='overlay', hl_mode='combine', virt_text_hide=true}) + api.nvim_buf_set_extmark(0, ns, 6, 5, { virt_text={{'replacing color', 'Blendy'}}, virt_text_pos='overlay', hl_mode='replace', virt_text_hide=true}) screen:expect{grid=[[ {5:^for} _,item {5:in} {6:ipairs}(items) {5:do} | @@ -1152,8 +1208,7 @@ describe('extmark decorations', function() colpos {5:=} colpos{5:+}{13:1} | {5:end} | {5:end} | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} @@ -1171,8 +1226,7 @@ describe('extmark decorations', function() colpos {5:=} colpos{5:+}{13:1} | {5:end} | {5:end} | - {1:~ }| - {1:~ }| + {1:~ }|*2 {24:-- VISUAL LINE --} | ]]} @@ -1190,8 +1244,7 @@ describe('extmark decorations', function() colpos {5:=} colpos{5:+}{13:1} | {5:end} | {5:end} | - {1:~ }| - {1:~ }| + {1:~ }|*2 {24:-- VISUAL LINE --} | ]]} end) @@ -1199,17 +1252,17 @@ describe('extmark decorations', function() it('can have virtual text of right_align and fixed win_col position', function() insert(example_text) feed 'gg' - meths.buf_set_extmark(0, ns, 1, 0, { virt_text={{'Very', 'ErrorMsg'}}, virt_text_win_col=31, hl_mode='blend'}) - meths.buf_set_extmark(0, ns, 1, 0, { virt_text={{'VERY', 'ErrorMsg'}}, virt_text_pos='right_align', hl_mode='blend'}) - meths.buf_set_extmark(0, ns, 2, 10, { virt_text={{'Much', 'ErrorMsg'}}, virt_text_win_col=31, hl_mode='blend'}) - meths.buf_set_extmark(0, ns, 2, 10, { virt_text={{'MUCH', 'ErrorMsg'}}, virt_text_pos='right_align', hl_mode='blend'}) - meths.buf_set_extmark(0, ns, 3, 14, { virt_text={{'Error', 'ErrorMsg'}}, virt_text_win_col=31, hl_mode='blend'}) - meths.buf_set_extmark(0, ns, 3, 14, { virt_text={{'ERROR', 'ErrorMsg'}}, virt_text_pos='right_align', hl_mode='blend'}) - meths.buf_set_extmark(0, ns, 7, 21, { virt_text={{'-', 'NonText'}}, virt_text_win_col=4, hl_mode='blend'}) - meths.buf_set_extmark(0, ns, 7, 21, { virt_text={{'-', 'NonText'}}, virt_text_pos='right_align', hl_mode='blend'}) + api.nvim_buf_set_extmark(0, ns, 1, 0, { virt_text={{'Very', 'ErrorMsg'}}, virt_text_win_col=31, hl_mode='blend'}) + api.nvim_buf_set_extmark(0, ns, 1, 0, { virt_text={{'VERY', 'ErrorMsg'}}, virt_text_pos='right_align', hl_mode='blend'}) + api.nvim_buf_set_extmark(0, ns, 2, 10, { virt_text={{'Much', 'ErrorMsg'}}, virt_text_win_col=31, hl_mode='blend'}) + api.nvim_buf_set_extmark(0, ns, 2, 10, { virt_text={{'MUCH', 'ErrorMsg'}}, virt_text_pos='right_align', hl_mode='blend'}) + api.nvim_buf_set_extmark(0, ns, 3, 14, { virt_text={{'Error', 'ErrorMsg'}}, virt_text_win_col=31, hl_mode='blend'}) + api.nvim_buf_set_extmark(0, ns, 3, 14, { virt_text={{'ERROR', 'ErrorMsg'}}, virt_text_pos='right_align', hl_mode='blend'}) + api.nvim_buf_set_extmark(0, ns, 7, 21, { virt_text={{'-', 'NonText'}}, virt_text_win_col=4, hl_mode='blend'}) + api.nvim_buf_set_extmark(0, ns, 7, 21, { virt_text={{'-', 'NonText'}}, virt_text_pos='right_align', hl_mode='blend'}) -- empty virt_text should not change anything - meths.buf_set_extmark(0, ns, 8, 0, { virt_text={{''}}, virt_text_win_col=14, hl_mode='blend'}) - meths.buf_set_extmark(0, ns, 8, 0, { virt_text={{''}}, virt_text_pos='right_align', hl_mode='blend'}) + api.nvim_buf_set_extmark(0, ns, 8, 0, { virt_text={{''}}, virt_text_win_col=14, hl_mode='blend'}) + api.nvim_buf_set_extmark(0, ns, 8, 0, { virt_text={{''}}, virt_text_pos='right_align', hl_mode='blend'}) screen:expect{grid=[[ ^for _,item in ipairs(items) do | @@ -1224,8 +1277,7 @@ describe('extmark decorations', function() colpos = colpos+1 | end | end | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} @@ -1262,8 +1314,7 @@ describe('extmark decorations', function() colpos = colpos+1 | end | end | - {1:~ }| - {1:~ }| + {1:~ }|*2 : | ]]} @@ -1305,7 +1356,7 @@ describe('extmark decorations', function() | ]]} - meths.buf_set_extmark(0, ns, 4, 50, { virt_text={{'EOL', 'NonText'}} }) + api.nvim_buf_set_extmark(0, ns, 4, 50, { virt_text={{'EOL', 'NonText'}} }) screen:expect{grid=[[ for _,item in ipairs(items) do | local text, hl_id_cell, cou{4:Very} unpack(ite{4:VERY}| @@ -1461,17 +1512,16 @@ describe('extmark decorations', function() it('virtual text win_col out of window does not break display #25645', function() screen:try_resize(51, 6) command('vnew') - meths.buf_set_lines(0, 0, -1, false, { string.rep('a', 50) }) + api.nvim_buf_set_lines(0, 0, -1, false, { string.rep('a', 50) }) screen:expect{grid=[[ ^aaaaaaaaaaaaaaaaaaaaaaaaa│ | aaaaaaaaaaaaaaaaaaaaaaaaa│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*2 {41:[No Name] [+] }{40:[No Name] }| | ]]} local extmark_opts = { virt_text_win_col = 35, virt_text = { { ' ', 'Comment' } } } - meths.buf_set_extmark(0, ns, 0, 0, extmark_opts) + api.nvim_buf_set_extmark(0, ns, 0, 0, extmark_opts) screen:expect_unchanged() assert_alive() end) @@ -1487,9 +1537,9 @@ describe('extmark decorations', function() -- XXX: the behavior of overlay virtual text at non-zero column is strange: -- 1. With 'wrap' it is never shown. -- 2. With 'nowrap' it is shown only if the extmark is hidden before leftcol. - meths.buf_set_extmark(0, ns, 0, 0, { virt_text = {{'AA', 'Underlined'}}, hl_mode = 'combine', virt_text_pos = 'overlay' }) - meths.buf_set_extmark(0, ns, 0, 5, { virt_text = {{'BB', 'Underlined'}}, hl_mode = 'combine', virt_text_win_col = 10 }) - meths.buf_set_extmark(0, ns, 0, 2, { virt_text = {{'CC', 'Underlined'}}, hl_mode = 'combine', virt_text_pos = 'right_align' }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = {{'AA', 'Underlined'}}, hl_mode = 'combine', virt_text_pos = 'overlay' }) + api.nvim_buf_set_extmark(0, ns, 0, 5, { virt_text = {{'BB', 'Underlined'}}, hl_mode = 'combine', virt_text_win_col = 10 }) + api.nvim_buf_set_extmark(0, ns, 0, 2, { virt_text = {{'CC', 'Underlined'}}, hl_mode = 'combine', virt_text_pos = 'right_align' }) screen:expect{grid=[[ {29:AA}{33:- 2 lin}{29:BB}{33:: 11111·····························}{29:CC}| 3333^3 | @@ -1532,9 +1582,9 @@ describe('extmark decorations', function() ddddd eeeee]]) command('windo diffthis') - meths.buf_set_extmark(0, ns, 0, 0, { virt_text = {{'AA', 'Underlined'}}, virt_text_pos = 'overlay' }) - meths.buf_set_extmark(0, ns, 0, 0, { virt_text = {{'BB', 'Underlined'}}, virt_text_win_col = 10 }) - meths.buf_set_extmark(0, ns, 0, 0, { virt_text = {{'CC', 'Underlined'}}, virt_text_pos = 'right_align' }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = {{'AA', 'Underlined'}}, virt_text_pos = 'overlay' }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = {{'BB', 'Underlined'}}, virt_text_win_col = 10 }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = {{'CC', 'Underlined'}}, virt_text_pos = 'right_align' }) screen:expect{grid=[[ {37: }{38:aaaaa }│{37: }{39:------------------------}| {37: }bbbbb │{37: }{28:AA}bbb {28:BB} {28:CC}| @@ -1577,14 +1627,13 @@ describe('extmark decorations', function() {'d', {'BgTwo', 'FgZwei'}}; {'X', {'BgTwo', 'FgZwei', 'VeryBold'}}; } - meths.buf_set_extmark(0, ns, 0, 0, { virt_text = vt, virt_text_pos = 'eol' }) - meths.buf_set_extmark(0, ns, 0, 0, { virt_text = vt, virt_text_pos = 'right_align' }) - meths.buf_set_extmark(0, ns, 0, 0, { virt_text = vt, virt_text_pos = 'inline' }) - meths.buf_set_extmark(0, ns, 0, 0, { virt_lines = { vt, vt } }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = vt, virt_text_pos = 'eol' }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = vt, virt_text_pos = 'right_align' }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = vt, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_lines = { vt, vt } }) screen:expect{grid=[[ {2:a}{3:b}{4:c}{5:d}{6:X}#^# {2:a}{3:b}{4:c}{5:d}{6:X} {2:a}{3:b}{4:c}{5:d}{6:X}| - {2:a}{3:b}{4:c}{5:d}{6:X} | - {2:a}{3:b}{4:c}{5:d}{6:X} | + {2:a}{3:b}{4:c}{5:d}{6:X} |*2 {1:~ }| | ]]} @@ -1597,19 +1646,7 @@ describe('extmark decorations', function() ]] screen:expect{grid=[[ ^ a | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*13 | ]]} @@ -1619,19 +1656,7 @@ describe('extmark decorations', function() ]] screen:expect{grid=[[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*13 | ]]} assert_alive() @@ -1640,43 +1665,40 @@ describe('extmark decorations', function() it('conceal with conceal char #19007', function() screen:try_resize(50, 5) insert('foo\n') - meths.buf_set_extmark(0, ns, 0, 0, {end_col=0, end_row=2, conceal='X'}) + api.nvim_buf_set_extmark(0, ns, 0, 0, {end_col=0, end_row=2, conceal='X'}) command('set conceallevel=2') screen:expect([[ {26:X} | ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) command('set conceallevel=1') screen:expect_unchanged() - eq("conceal char has to be printable", pcall_err(meths.buf_set_extmark, 0, ns, 0, 0, {end_col=0, end_row=2, conceal='\255'})) + eq("conceal char has to be printable", pcall_err(api.nvim_buf_set_extmark, 0, ns, 0, 0, {end_col=0, end_row=2, conceal='\255'})) end) it('conceal with composed conceal char', function() screen:try_resize(50, 5) insert('foo\n') - meths.buf_set_extmark(0, ns, 0, 0, {end_col=0, end_row=2, conceal='ẍ̲'}) + api.nvim_buf_set_extmark(0, ns, 0, 0, {end_col=0, end_row=2, conceal='ẍ̲'}) command('set conceallevel=2') screen:expect([[ {26:ẍ̲} | ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) command('set conceallevel=1') screen:expect_unchanged() -- this is rare, but could happen. Save at least the first codepoint - meths._invalidate_glyph_cache() + api.nvim__invalidate_glyph_cache() screen:expect{grid=[[ {26:x} | ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} end) @@ -1684,30 +1706,28 @@ describe('extmark decorations', function() it('conceal without conceal char #24782', function() screen:try_resize(50, 5) insert('foobar\n') - meths.buf_set_extmark(0, ns, 0, 0, {end_col=3, conceal=''}) + api.nvim_buf_set_extmark(0, ns, 0, 0, {end_col=3, conceal=''}) command('set listchars=conceal:?') command('let &conceallevel=1') screen:expect([[ {26:?}bar | ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) command('let &conceallevel=2') screen:expect([[ bar | ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) end) it('conceal works just before truncated double-width char #21486', function() screen:try_resize(40, 4) - meths.buf_set_lines(0, 0, -1, true, {'', ('a'):rep(37) .. '<>古'}) - meths.buf_set_extmark(0, ns, 1, 37, {end_col=39, conceal=''}) + api.nvim_buf_set_lines(0, 0, -1, true, {'', ('a'):rep(37) .. '<>古'}) + api.nvim_buf_set_extmark(0, ns, 1, 37, {end_col=39, conceal=''}) command('setlocal conceallevel=2') screen:expect{grid=[[ ^ | @@ -1724,6 +1744,35 @@ describe('extmark decorations', function() ]]} end) + it('redraws properly when adding/removing conceal on non-current line', function() + screen:try_resize(50, 5) + api.nvim_buf_set_lines(0, 0, -1, true, {'abcd', 'efgh','ijkl', 'mnop'}) + command('setlocal conceallevel=2') + screen:expect{grid=[[ + ^abcd | + efgh | + ijkl | + mnop | + | + ]]} + api.nvim_buf_set_extmark(0, ns, 2, 1, {end_col=3, conceal=''}) + screen:expect{grid=[[ + ^abcd | + efgh | + il | + mnop | + | + ]]} + api.nvim_buf_clear_namespace(0, ns, 0, -1) + screen:expect{grid=[[ + ^abcd | + efgh | + ijkl | + mnop | + | + ]]} + end) + it('avoids redraw issue #20651', function() exec_lua[[ vim.cmd.normal'10oXXX' @@ -1748,25 +1797,16 @@ describe('extmark decorations', function() ]] for _ = 1, 3 do - helpers.sleep(10) + vim.uv.sleep(10) feed 'j' end screen:expect{grid=[[ - {27: } | - XXX | - XXX | + {44: } | + XXX |*2 ^XXX HELLO | - XXX | - XXX | - XXX | - XXX | - XXX | - XXX | - XXX | - {1:~ }| - {1:~ }| - {1:~ }| + XXX |*7 + {1:~ }|*3 | ]]} @@ -1790,32 +1830,32 @@ describe('extmark decorations', function() [6] = {bold = true, undercurl = true, special = Screen.colors.Red}; }) - meths.buf_set_extmark(0, ns, 0, 0, { end_col = 9, hl_group = 'TestUL', priority = 20 }) - meths.buf_set_extmark(0, ns, 0, 3, { end_col = 6, hl_group = 'TestUC', priority = 30 }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { end_col = 9, hl_group = 'TestUL', priority = 20 }) + api.nvim_buf_set_extmark(0, ns, 0, 3, { end_col = 6, hl_group = 'TestUC', priority = 30 }) screen:expect([[ {1:aaa}{4:bbb}{1:aa^a} | {0:~ }| | ]]) - meths.buf_clear_namespace(0, ns, 0, -1) - meths.buf_set_extmark(0, ns, 0, 0, { end_col = 9, hl_group = 'TestUC', priority = 20 }) - meths.buf_set_extmark(0, ns, 0, 3, { end_col = 6, hl_group = 'TestUL', priority = 30 }) + api.nvim_buf_clear_namespace(0, ns, 0, -1) + api.nvim_buf_set_extmark(0, ns, 0, 0, { end_col = 9, hl_group = 'TestUC', priority = 20 }) + api.nvim_buf_set_extmark(0, ns, 0, 3, { end_col = 6, hl_group = 'TestUL', priority = 30 }) screen:expect([[ {2:aaa}{3:bbb}{2:aa^a} | {0:~ }| | ]]) - meths.buf_clear_namespace(0, ns, 0, -1) - meths.buf_set_extmark(0, ns, 0, 0, { end_col = 9, hl_group = 'TestUL', priority = 30 }) - meths.buf_set_extmark(0, ns, 0, 3, { end_col = 6, hl_group = 'TestUC', priority = 20 }) + api.nvim_buf_clear_namespace(0, ns, 0, -1) + api.nvim_buf_set_extmark(0, ns, 0, 0, { end_col = 9, hl_group = 'TestUL', priority = 30 }) + api.nvim_buf_set_extmark(0, ns, 0, 3, { end_col = 6, hl_group = 'TestUC', priority = 20 }) screen:expect([[ {1:aaa}{3:bbb}{1:aa^a} | {0:~ }| | ]]) - meths.buf_clear_namespace(0, ns, 0, -1) - meths.buf_set_extmark(0, ns, 0, 0, { end_col = 9, hl_group = 'TestUC', priority = 30 }) - meths.buf_set_extmark(0, ns, 0, 3, { end_col = 6, hl_group = 'TestUL', priority = 20 }) + api.nvim_buf_clear_namespace(0, ns, 0, -1) + api.nvim_buf_set_extmark(0, ns, 0, 0, { end_col = 9, hl_group = 'TestUC', priority = 30 }) + api.nvim_buf_set_extmark(0, ns, 0, 3, { end_col = 6, hl_group = 'TestUL', priority = 20 }) screen:expect([[ {2:aaa}{4:bbb}{2:aa^a} | {0:~ }| @@ -1824,14 +1864,14 @@ describe('extmark decorations', function() -- When only one highlight group has an underline attribute, it should always take effect. for _, d in ipairs({-5, 5}) do - meths.buf_clear_namespace(0, ns, 0, -1) + api.nvim_buf_clear_namespace(0, ns, 0, -1) screen:expect([[ aaabbbaa^a | {0:~ }| | ]]) - meths.buf_set_extmark(0, ns, 0, 0, { end_col = 9, hl_group = 'TestUL', priority = 25 + d }) - meths.buf_set_extmark(0, ns, 0, 3, { end_col = 6, hl_group = 'TestBold', priority = 25 - d }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { end_col = 9, hl_group = 'TestUL', priority = 25 + d }) + api.nvim_buf_set_extmark(0, ns, 0, 3, { end_col = 6, hl_group = 'TestBold', priority = 25 - d }) screen:expect([[ {1:aaa}{5:bbb}{1:aa^a} | {0:~ }| @@ -1839,14 +1879,14 @@ describe('extmark decorations', function() ]]) end for _, d in ipairs({-5, 5}) do - meths.buf_clear_namespace(0, ns, 0, -1) + api.nvim_buf_clear_namespace(0, ns, 0, -1) screen:expect([[ aaabbbaa^a | {0:~ }| | ]]) - meths.buf_set_extmark(0, ns, 0, 0, { end_col = 9, hl_group = 'TestUC', priority = 25 + d }) - meths.buf_set_extmark(0, ns, 0, 3, { end_col = 6, hl_group = 'TestBold', priority = 25 - d }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { end_col = 9, hl_group = 'TestUC', priority = 25 + d }) + api.nvim_buf_set_extmark(0, ns, 0, 3, { end_col = 6, hl_group = 'TestBold', priority = 25 - d }) screen:expect([[ {2:aaa}{6:bbb}{2:aa^a} | {0:~ }| @@ -1863,10 +1903,11 @@ describe('extmark decorations', function() feed('gg') command('set ft=lua') command('syntax on') - meths.buf_set_extmark(0, ns, 0, 0, { end_col = 3, hl_mode = 'combine', hl_group = 'Visual' }) + command('hi default MyMark guibg=LightGrey') + api.nvim_buf_set_extmark(0, ns, 0, 0, { end_col = 3, hl_mode = 'combine', hl_group = 'MyMark' }) command('hi default MyLine gui=underline') command('sign define CurrentLine linehl=MyLine') - funcs.sign_place(6, 'Test', 'CurrentLine', '', { lnum = 1 }) + fn.sign_place(6, 'Test', 'CurrentLine', '', { lnum = 1 }) screen:expect{grid=[[ {30:^fun}{31:ction}{32: Func() }| {6:end} | @@ -1877,8 +1918,8 @@ describe('extmark decorations', function() it('highlight works after TAB with sidescroll #14201', function() screen:try_resize(50, 3) command('set nowrap') - meths.buf_set_lines(0, 0, -1, true, {'\tword word word word'}) - meths.buf_set_extmark(0, ns, 0, 1, { end_col = 3, hl_group = 'ErrorMsg' }) + api.nvim_buf_set_lines(0, 0, -1, true, {'\tword word word word'}) + api.nvim_buf_set_extmark(0, ns, 0, 1, { end_col = 3, hl_group = 'ErrorMsg' }) screen:expect{grid=[[ ^ {4:wo}rd word word word | {1:~ }| @@ -1906,16 +1947,16 @@ describe('extmark decorations', function() it('highlights the beginning of a TAB char correctly #23734', function() screen:try_resize(50, 3) - meths.buf_set_lines(0, 0, -1, true, {'this is the\ttab'}) - meths.buf_set_extmark(0, ns, 0, 11, { end_col = 15, hl_group = 'ErrorMsg' }) + api.nvim_buf_set_lines(0, 0, -1, true, {'this is the\ttab'}) + api.nvim_buf_set_extmark(0, ns, 0, 11, { end_col = 15, hl_group = 'ErrorMsg' }) screen:expect{grid=[[ ^this is the{4: tab} | {1:~ }| | ]]} - meths.buf_clear_namespace(0, ns, 0, -1) - meths.buf_set_extmark(0, ns, 0, 12, { end_col = 15, hl_group = 'ErrorMsg' }) + api.nvim_buf_clear_namespace(0, ns, 0, -1) + api.nvim_buf_set_extmark(0, ns, 0, 12, { end_col = 15, hl_group = 'ErrorMsg' }) screen:expect{grid=[[ ^this is the {4:tab} | {1:~ }| @@ -1925,50 +1966,62 @@ describe('extmark decorations', function() it('highlight applies to a full TAB on line with matches #20885', function() screen:try_resize(50, 3) - meths.buf_set_lines(0, 0, -1, true, {'\t-- match1', ' -- match2'}) - funcs.matchadd('Underlined', 'match') - meths.buf_set_extmark(0, ns, 0, 0, { end_row = 1, end_col = 0, hl_group = 'Visual' }) - meths.buf_set_extmark(0, ns, 1, 0, { end_row = 2, end_col = 0, hl_group = 'Visual' }) + api.nvim_buf_set_lines(0, 0, -1, true, {'\t-- match1', ' -- match2'}) + fn.matchadd('NonText', 'match') + api.nvim_buf_set_extmark(0, ns, 0, 0, { end_row = 1, end_col = 0, hl_group = 'Search' }) + api.nvim_buf_set_extmark(0, ns, 1, 0, { end_row = 2, end_col = 0, hl_group = 'Search' }) screen:expect{grid=[[ - {18: ^ -- }{29:match}{18:1} | - {18: -- }{29:match}{18:2} | + {34: ^ -- }{35:match}{34:1} | + {34: -- }{35:match}{34:2} | | ]]} end) pending('highlight applies to a full TAB in visual block mode', function() screen:try_resize(50, 8) - meths.buf_set_lines(0, 0, -1, true, {'asdf', '\tasdf', '\tasdf', '\tasdf', 'asdf'}) - meths.buf_set_extmark(0, ns, 0, 0, {end_row = 5, end_col = 0, hl_group = 'Underlined'}) + command('hi! Visual guifg=NONE guibg=LightGrey') + api.nvim_buf_set_lines(0, 0, -1, true, {'asdf', '\tasdf', '\tasdf', '\tasdf', 'asdf'}) + api.nvim_buf_set_extmark(0, ns, 0, 0, {end_row = 5, end_col = 0, hl_group = 'Underlined'}) screen:expect([[ {28:^asdf} | - {28: asdf} | - {28: asdf} | - {28: asdf} | + {28: asdf} |*3 {28:asdf} | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) feed('<C-V>Gll') screen:expect([[ {29:asd}{28:f} | - {29: }{28: asdf} | - {29: }{28: asdf} | - {29: }{28: asdf} | + {29: }{28: asdf} |*3 {29:as}{28:^df} | - {1:~ }| - {1:~ }| + {1:~ }|*2 {24:-- VISUAL BLOCK --} | ]]) end) + it('highlight works properly with multibyte text and spell #26771', function() + insert('口口\n') + screen:try_resize(50, 3) + api.nvim_buf_set_extmark(0, ns, 0, 0, { end_col = 3, hl_group = 'Search' }) + screen:expect([[ + {34:口}口 | + ^ | + | + ]]) + command('setlocal spell') + screen:expect([[ + {43:口}{42:口} | + ^ | + | + ]]) + end) + it('supports multiline highlights', function() insert(example_text) feed 'gg' for _,i in ipairs {1,2,3,5,6,7} do for _,j in ipairs {2,5,10,15} do - meths.buf_set_extmark(0, ns, i, j, { end_col=j+2, hl_group = 'NonText'}) + api.nvim_buf_set_extmark(0, ns, i, j, { end_col=j+2, hl_group = 'NonText'}) end end screen:expect{grid=[[ @@ -1984,8 +2037,7 @@ describe('extmark decorations', function() colpos = colpos+1 | end | end | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} feed'5<c-e>' @@ -1997,17 +2049,11 @@ describe('extmark decorations', function() colpos = colpos+1 | end | end | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*7 | ]]} - meths.buf_set_extmark(0, ns, 1, 0, { end_line=8, end_col=10, hl_group = 'ErrorMsg'}) + api.nvim_buf_set_extmark(0, ns, 1, 0, { end_line=8, end_col=10, hl_group = 'ErrorMsg'}) screen:expect{grid=[[ {4:^ }{36: }{4:f}{36:or}{4: _ }{36:= }{4:1, }{36:(c}{4:ount or 1) do} | {4: }{36: }{4: }{36: }{4: lo}{36:ca}{4:l c}{36:el}{4:l = line[colpos]} | @@ -2016,13 +2062,7 @@ describe('extmark decorations', function() colpos = colpos+1 | end | end | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*7 | ]]} end) @@ -2031,7 +2071,7 @@ describe('extmark decorations', function() screen:try_resize(50, 5) insert(example_text) feed'gg' - meths.buf_set_extmark(0, ns, 0, 6, { end_col=13, hl_group = 'NonText', undo_restore=val}) + api.nvim_buf_set_extmark(0, ns, 0, 6, { end_col=13, hl_group = 'NonText', undo_restore=val}) screen:expect{grid=[[ ^for _,{1:item in} ipairs(items) do | local text, hl_id_cell, count = unpack(item) | @@ -2040,7 +2080,7 @@ describe('extmark decorations', function() | ]]} - meths.buf_set_text(0, 0, 4, 0, 8, {''}) + api.nvim_buf_set_text(0, 0, 4, 0, 8, {''}) screen:expect{grid=[[ ^for {1:em in} ipairs(items) do | local text, hl_id_cell, count = unpack(item) | @@ -2078,7 +2118,7 @@ describe('extmark decorations', function() eq({ { 1, 0, 8, { end_col = 13, end_right_gravity = false, end_row = 0, hl_eol = false, hl_group = "NonText", undo_restore = false, ns_id = 1, priority = 4096, right_gravity = true } } }, - meths.buf_get_extmarks(0, ns, {0,0}, {0, -1}, {details=true})) + api.nvim_buf_get_extmarks(0, ns, {0,0}, {0, -1}, {details=true})) end) it('virtual text works with rightleft', function() @@ -2086,10 +2126,10 @@ describe('extmark decorations', function() insert('abcdefghijklmn') feed('0') command('set rightleft') - meths.buf_set_extmark(0, ns, 0, 0, { virt_text = {{'EOL', 'Underlined'}}}) - meths.buf_set_extmark(0, ns, 0, 0, { virt_text = {{'right_align', 'Underlined'}}, virt_text_pos = 'right_align' }) - meths.buf_set_extmark(0, ns, 0, 0, { virt_text = {{'win_col', 'Underlined'}}, virt_text_win_col = 20 }) - meths.buf_set_extmark(0, ns, 0, 2, { virt_text = {{'overlayed', 'Underlined'}}, virt_text_pos = 'overlay' }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = {{'EOL', 'Underlined'}}}) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = {{'right_align', 'Underlined'}}, virt_text_pos = 'right_align' }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = {{'win_col', 'Underlined'}}, virt_text_win_col = 20 }) + api.nvim_buf_set_extmark(0, ns, 0, 2, { virt_text = {{'overlayed', 'Underlined'}}, virt_text_pos = 'overlay' }) screen:expect{grid=[[ {28:ngila_thgir} {28:loc_niw} {28:LOE} nml{28:deyalrevo}b^a| {1: ~}| @@ -2135,7 +2175,74 @@ describe('extmark decorations', function() ]]} end) - it('works with double width char and rightleft', function() + it('virtual text overwrites double-width char properly', function() + screen:try_resize(50, 3) + insert('abcdefghij口klmnopqrstu口vwx口yz') + feed('0') + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = {{'!!!!!', 'Underlined'}}, virt_text_win_col = 11 }) + screen:expect{grid=[[ + ^abcdefghij {28:!!!!!}opqrstu口vwx口yz | + {1:~ }| + | + ]]} + feed('8x') + screen:expect{grid=[[ + ^ij口klmnopq{28:!!!!!} vwx口yz | + {1:~ }| + | + ]]} + feed('3l5x') + screen:expect{grid=[[ + ij口^pqrstu {28:!!!!!} yz | + {1:~ }| + | + ]]} + feed('5x') + screen:expect{grid=[[ + ij口^u口vwx {28:!!!!!} | + {1:~ }| + | + ]]} + end) + + it('virtual text blending space does not overwrite double-width char', function() + screen:try_resize(50, 3) + insert('abcdefghij口klmnopqrstu口vwx口yz') + feed('0') + command('hi Blendy guibg=Red blend=30') + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = {{' ! ! ', 'Blendy'}}, virt_text_win_col = 8, hl_mode = 'blend' }) + screen:expect{grid=[[ + ^abcdefgh{10:i}{7:!}{10:口}{7:!}{10:l}mnopqrstu口vwx口yz | + {1:~ }| + | + ]]} + feed('x') + screen:expect{grid=[[ + ^bcdefghi{10:j}{7:!}{10: k}{7:!}{10:m}nopqrstu口vwx口yz | + {1:~ }| + | + ]]} + feed('x') + screen:expect{grid=[[ + ^cdefghij{10: }{7:!}{10:kl}{7:!}{10:n}opqrstu口vwx口yz | + {1:~ }| + | + ]]} + feed('x') + screen:expect{grid=[[ + ^defghij口{7:!}{10:lm}{7:!}{10:o}pqrstu口vwx口yz | + {1:~ }| + | + ]]} + feed('7x') + screen:expect{grid=[[ + ^口klmnop{10:q}{7:!}{10:st}{7:!}{10:口}vwx口yz | + {1:~ }| + | + ]]} + end) + + it('virtual text works with double-width char and rightleft', function() screen:try_resize(50, 3) insert('abcdefghij口klmnopqrstu口vwx口yz') feed('0') @@ -2145,10 +2252,10 @@ describe('extmark decorations', function() {1: ~}| | ]]} - meths.buf_set_extmark(0, ns, 0, 2, { virt_text = {{'overlayed', 'Underlined'}}, virt_text_pos = 'overlay' }) - meths.buf_set_extmark(0, ns, 0, 14, { virt_text = {{'古', 'Underlined'}}, virt_text_pos = 'overlay' }) - meths.buf_set_extmark(0, ns, 0, 20, { virt_text = {{'\t', 'Underlined'}}, virt_text_pos = 'overlay' }) - meths.buf_set_extmark(0, ns, 0, 29, { virt_text = {{'古', 'Underlined'}}, virt_text_pos = 'overlay' }) + api.nvim_buf_set_extmark(0, ns, 0, 2, { virt_text = {{'overlayed', 'Underlined'}}, virt_text_pos = 'overlay' }) + api.nvim_buf_set_extmark(0, ns, 0, 14, { virt_text = {{'古', 'Underlined'}}, virt_text_pos = 'overlay' }) + api.nvim_buf_set_extmark(0, ns, 0, 20, { virt_text = {{'\t', 'Underlined'}}, virt_text_pos = 'overlay' }) + api.nvim_buf_set_extmark(0, ns, 0, 29, { virt_text = {{'古', 'Underlined'}}, virt_text_pos = 'overlay' }) screen:expect{grid=[[ zy {28:古}wv {28: }qpon{28:古}k {28:deyalrevo}b^a| {1: ~}| @@ -2156,16 +2263,231 @@ describe('extmark decorations', function() ]]} end) + it('virtual text is drawn correctly after delete and undo #27368', function() + insert('aaa\nbbb\nccc\nddd\neee') + command('vsplit') + api.nvim_buf_set_extmark(0, ns, 2, 0, { virt_text = {{'EOL'}} }) + feed('3gg') + screen:expect{grid=[[ + aaa │aaa | + bbb │bbb | + ^ccc EOL │ccc EOL | + ddd │ddd | + eee │eee | + {1:~ }│{1:~ }|*8 + {41:[No Name] [+] }{40:[No Name] [+] }| + | + ]]} + feed('dd') + screen:expect{grid=[[ + aaa │aaa | + bbb │bbb | + ^ddd EOL │ddd EOL | + eee │eee | + {1:~ }│{1:~ }|*9 + {41:[No Name] [+] }{40:[No Name] [+] }| + | + ]]} + command('silent undo') + screen:expect{grid=[[ + aaa │aaa | + bbb │bbb | + ^ccc EOL │ccc EOL | + ddd │ddd | + eee │eee | + {1:~ }│{1:~ }|*8 + {41:[No Name] [+] }{40:[No Name] [+] }| + | + ]]} + end) + it('works with both hl_group and sign_hl_group', function() screen:try_resize(screen._width, 3) insert('abcdefghijklmn') - meths.buf_set_extmark(0, ns, 0, 0, {sign_text='S', sign_hl_group='NonText', hl_group='Error', end_col=14}) + api.nvim_buf_set_extmark(0, ns, 0, 0, {sign_text='S', sign_hl_group='NonText', hl_group='Error', end_col=14}) screen:expect{grid=[[ {1:S }{4:abcdefghijklm^n} | {1:~ }| | ]]} end) + + it('virt_text_repeat_linebreak repeats virtual text on wrapped lines', function() + screen:try_resize(40, 5) + api.nvim_set_option_value('breakindent', true, {}) + insert(example_text) + api.nvim_buf_set_extmark(0, ns, 1, 0, { virt_text = {{'│', 'NonText'}}, virt_text_pos = 'overlay', virt_text_repeat_linebreak = true }) + api.nvim_buf_set_extmark(0, ns, 1, 3, { virt_text = {{'│', 'NonText'}}, virt_text_pos = 'overlay', virt_text_repeat_linebreak = true }) + command('norm gg') + screen:expect{grid=[[ + ^for _,item in ipairs(items) do | + {1:│} {1:│}local text, hl_id_cell, count = unpa| + {1:│} {1:│}ck(item) | + if hl_id_cell ~= nil then | + | + ]]} + api.nvim_buf_clear_namespace(0, ns, 0, -1) + api.nvim_buf_set_extmark(0, ns, 1, 0, { virt_text = {{'│', 'NonText'}}, virt_text_repeat_linebreak = true, virt_text_win_col = 0 }) + api.nvim_buf_set_extmark(0, ns, 1, 0, { virt_text = {{'│', 'NonText'}}, virt_text_repeat_linebreak = true, virt_text_win_col = 2 }) + screen:expect{grid=[[ + ^for _,item in ipairs(items) do | + {1:│} {1:│} local text, hl_id_cell, count = unpa| + {1:│} {1:│} ck(item) | + if hl_id_cell ~= nil then | + | + ]]} + end) + + it('supports URLs', function() + insert(example_text) + + local url = 'https://example.com' + + screen:set_default_attr_ids({ + e = { bold = true, foreground = Screen.colors.Blue }, + u = { url = url }, + }) + + api.nvim_buf_set_extmark(0, ns, 1, 4, { + end_col = 14, + url = url, + }) + + screen:expect{grid=[[ + for _,item in ipairs(items) do | + {u:local text}, hl_id_cell, count = unpack(item) | + if hl_id_cell ~= nil then | + hl_id = hl_id_cell | + end | + for _ = 1, (count or 1) do | + local cell = line[colpos] | + cell.text = text | + cell.hl_id = hl_id | + colpos = colpos+1 | + end | + en^d | + {e:~ }| + {e:~ }| + | + ]]} + end) + + it('can replace marks in place with different decorations #27211', function() + local mark = api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_lines = {{{"foo", "ErrorMsg"}}}, }) + screen:expect{grid=[[ + ^ | + {4:foo} | + {1:~ }|*12 + | + ]]} + + api.nvim_buf_set_extmark(0, ns, 0, 0, { + id = mark, + virt_text = { { "testing", "NonText" } }, + virt_text_pos = "inline", + }) + screen:expect{grid=[[ + {1:^testing} | + {1:~ }|*13 + | + ]]} + + api.nvim_buf_del_extmark(0, ns, mark) + screen:expect{grid=[[ + ^ | + {1:~ }|*13 + | + ]]} + + helpers.assert_alive() + end) + + it('priority ordering of overlay or win_col virtual text at same position', function() + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = {{'A'}}, virt_text_pos = 'overlay', priority = 100 }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = {{'A'}}, virt_text_win_col = 30, priority = 100 }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = {{'BB'}}, virt_text_pos = 'overlay', priority = 90 }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = {{'BB'}}, virt_text_win_col = 30, priority = 90 }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = {{'CCC'}}, virt_text_pos = 'overlay', priority = 80 }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = {{'CCC'}}, virt_text_win_col = 30, priority = 80 }) + screen:expect([[ + ^ABC ABC | + {1:~ }|*13 + | + ]]) + end) + + it('priority ordering of inline and non-inline virtual text at same char', function() + insert(('?'):rep(40) .. ('!'):rep(30)) + api.nvim_buf_set_extmark(0, ns, 0, 40, { virt_text = {{'A'}}, virt_text_pos = 'overlay', priority = 10 }) + api.nvim_buf_set_extmark(0, ns, 0, 40, { virt_text = {{'a'}}, virt_text_win_col = 15, priority = 10 }) + api.nvim_buf_set_extmark(0, ns, 0, 40, { virt_text = {{'BBBB'}}, virt_text_pos = 'inline', priority = 15 }) + api.nvim_buf_set_extmark(0, ns, 0, 40, { virt_text = {{'C'}}, virt_text_pos = 'overlay', priority = 20 }) + api.nvim_buf_set_extmark(0, ns, 0, 40, { virt_text = {{'c'}}, virt_text_win_col = 17, priority = 20 }) + api.nvim_buf_set_extmark(0, ns, 0, 40, { virt_text = {{'DDDD'}}, virt_text_pos = 'inline', priority = 25 }) + api.nvim_buf_set_extmark(0, ns, 0, 40, { virt_text = {{'E'}}, virt_text_pos = 'overlay', priority = 30 }) + api.nvim_buf_set_extmark(0, ns, 0, 40, { virt_text = {{'e'}}, virt_text_win_col = 19, priority = 30 }) + api.nvim_buf_set_extmark(0, ns, 0, 40, { virt_text = {{'FFFF'}}, virt_text_pos = 'inline', priority = 35 }) + api.nvim_buf_set_extmark(0, ns, 0, 40, { virt_text = {{'G'}}, virt_text_pos = 'overlay', priority = 40 }) + api.nvim_buf_set_extmark(0, ns, 0, 40, { virt_text = {{'g'}}, virt_text_win_col = 21, priority = 40 }) + api.nvim_buf_set_extmark(0, ns, 0, 40, { virt_text = {{'HHHH'}}, virt_text_pos = 'inline', priority = 45 }) + api.nvim_buf_set_extmark(0, ns, 0, 40, { virt_text = {{'I'}}, virt_text_pos = 'overlay', priority = 50 }) + api.nvim_buf_set_extmark(0, ns, 0, 40, { virt_text = {{'i'}}, virt_text_win_col = 23, priority = 50 }) + api.nvim_buf_set_extmark(0, ns, 0, 40, { virt_text = {{'JJJJ'}}, virt_text_pos = 'inline', priority = 55 }) + api.nvim_buf_set_extmark(0, ns, 0, 40, { virt_text = {{'K'}}, virt_text_pos = 'overlay', priority = 60 }) + api.nvim_buf_set_extmark(0, ns, 0, 40, { virt_text = {{'k'}}, virt_text_win_col = 25, priority = 60 }) + screen:expect([[ + ???????????????a?c?e????????????????????ABBBCDDDEF| + FFGHHHIJJJK!!!!!!!!!!g!i!k!!!!!!!!!!!!!^! | + {1:~ }|*12 + | + ]]) + feed('02x$') + screen:expect([[ + ???????????????a?c?e??????????????????ABBBCDDDEFFF| + GHHHIJJJK!!!!!!!!!!!!g!i!k!!!!!!!!!!!^! | + {1:~ }|*12 + | + ]]) + feed('02x$') + screen:expect([[ + ???????????????a?c?e?g??????????????ABBBCDDDEFFFGH| + HHIJJJK!!!!!!!!!!!!!!!!i!k!!!!!!!!!^! | + {1:~ }|*12 + | + ]]) + feed('02x$') + screen:expect([[ + ???????????????a?c?e?g????????????ABBBCDDDEFFFGHHH| + IJJJK!!!!!!!!!!!!!!!!!!i!k!!!!!!!^! | + {1:~ }|*12 + | + ]]) + command('set nowrap') + feed('0') + screen:expect([[ + ^???????????????a?c?e?g?i?k????????ABBBCDDDEFFFGHHH| + {1:~ }|*13 + | + ]]) + feed('2x') + screen:expect([[ + ^???????????????a?c?e?g?i?k??????ABBBCDDDEFFFGHHHIJ| + {1:~ }|*13 + | + ]]) + feed('2x') + screen:expect([[ + ^???????????????a?c?e?g?i?k????ABBBCDDDEFFFGHHHIJJJ| + {1:~ }|*13 + | + ]]) + feed('2x') + screen:expect([[ + ^???????????????a?c?e?g?i?k??ABBBCDDDEFFFGHHHIJJJK!| + {1:~ }|*13 + | + ]]) + end) end) describe('decorations: inline virtual text', function() @@ -2181,7 +2503,7 @@ describe('decorations: inline virtual text', function() [4] = {background = Screen.colors.Red1, foreground = Screen.colors.Gray100}; [5] = {background = Screen.colors.Red1, bold = true}; [6] = {foreground = Screen.colors.DarkCyan}; - [7] = {background = Screen.colors.LightGrey}; + [7] = {background = Screen.colors.LightGrey, foreground = Screen.colors.Black}; [8] = {bold = true}; [9] = {background = Screen.colors.Plum1}; [10] = {foreground = Screen.colors.SlateBlue}; @@ -2198,7 +2520,7 @@ describe('decorations: inline virtual text', function() [21] = {reverse = true, foreground = Screen.colors.SlateBlue} } - ns = meths.create_namespace 'test' + ns = api.nvim_create_namespace 'test' end) @@ -2219,7 +2541,7 @@ describe('decorations: inline virtual text', function() | ]]} - meths.buf_set_extmark(0, ns, 1, 14, {virt_text={{': ', 'Special'}, {'string', 'Type'}}, virt_text_pos='inline'}) + api.nvim_buf_set_extmark(0, ns, 1, 14, {virt_text={{': ', 'Special'}, {'string', 'Type'}}, virt_text_pos='inline'}) screen:expect{grid=[[ ^for _,item in ipairs(items) do | local text{10:: }{3:string}, hl_id_cell, count = unpack| @@ -2279,9 +2601,9 @@ describe('decorations: inline virtual text', function() | ]]} - meths.buf_set_extmark(0, ns, 0, 5, {virt_text={{''}, {''}}, virt_text_pos='inline'}) - meths.buf_set_extmark(0, ns, 1, 14, {virt_text={{''}, {': ', 'Special'}}, virt_text_pos='inline'}) - meths.buf_set_extmark(0, ns, 1, 48, {virt_text={{''}, {''}}, virt_text_pos='inline'}) + api.nvim_buf_set_extmark(0, ns, 0, 5, {virt_text={{''}, {''}}, virt_text_pos='inline'}) + api.nvim_buf_set_extmark(0, ns, 1, 14, {virt_text={{''}, {': ', 'Special'}}, virt_text_pos='inline'}) + api.nvim_buf_set_extmark(0, ns, 1, 48, {virt_text={{''}, {''}}, virt_text_pos='inline'}) screen:expect{grid=[[ ^for _,item in ipairs(items) do | local text{10:: }, hl_id_cell, count = unpack(item)| @@ -2295,7 +2617,7 @@ describe('decorations: inline virtual text', function() | ]]} - meths.buf_set_extmark(0, ns, 1, 14, {virt_text={{''}, {'string', 'Type'}}, virt_text_pos='inline'}) + api.nvim_buf_set_extmark(0, ns, 1, 14, {virt_text={{''}, {'string', 'Type'}}, virt_text_pos='inline'}) feed('V') screen:expect{grid=[[ ^f{7:or _,item in ipairs(items) do} | @@ -2327,8 +2649,8 @@ describe('decorations: inline virtual text', function() it('Normal mode "gM" command works properly', function() command([[call setline(1, '123456789')]]) - meths.buf_set_extmark(0, ns, 0, 2, { virt_text = { { 'bbb', 'Special' } }, virt_text_pos = 'inline' }) - meths.buf_set_extmark(0, ns, 0, 7, { virt_text = { { 'bbb', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 2, { virt_text = { { 'bbb', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 7, { virt_text = { { 'bbb', 'Special' } }, virt_text_pos = 'inline' }) feed('gM') screen:expect{grid=[[ 12{10:bbb}34^567{10:bbb}89 | @@ -2340,8 +2662,8 @@ describe('decorations: inline virtual text', function() local function test_normal_gj_gk() screen:try_resize(60, 6) command([[call setline(1, repeat([repeat('a', 55)], 2))]]) - meths.buf_set_extmark(0, ns, 0, 40, { virt_text = { { ('b'):rep(10), 'Special' } }, virt_text_pos = 'inline' }) - meths.buf_set_extmark(0, ns, 1, 40, { virt_text = { { ('b'):rep(10), 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 40, { virt_text = { { ('b'):rep(10), 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 1, 40, { virt_text = { { ('b'):rep(10), 'Special' } }, virt_text_pos = 'inline' }) screen:expect{grid=[[ ^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa{10:bbbbbbbbbb}aaaaaaaaaa| aaaaa | @@ -2419,8 +2741,8 @@ describe('decorations: inline virtual text', function() it('cursor positions are correct with multiple inline virtual text', function() insert('12345678') - meths.buf_set_extmark(0, ns, 0, 4, { virt_text = { { ' virtual text ', 'Special' } }, virt_text_pos = 'inline' }) - meths.buf_set_extmark(0, ns, 0, 4, { virt_text = { { ' virtual text ', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 4, { virt_text = { { ' virtual text ', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 4, { virt_text = { { ' virtual text ', 'Special' } }, virt_text_pos = 'inline' }) feed '^' feed '4l' screen:expect{grid=[[ @@ -2433,7 +2755,7 @@ describe('decorations: inline virtual text', function() it('adjusts cursor location correctly when inserting around inline virtual text', function() insert('12345678') feed '$' - meths.buf_set_extmark(0, ns, 0, 4, { virt_text = { { ' virtual text ', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 4, { virt_text = { { ' virtual text ', 'Special' } }, virt_text_pos = 'inline' }) screen:expect{grid=[[ 1234{10: virtual text }567^8 | @@ -2444,7 +2766,7 @@ describe('decorations: inline virtual text', function() it('has correct highlighting with multi-byte characters', function() insert('12345678') - meths.buf_set_extmark(0, ns, 0, 4, { virt_text = { { 'múlti-byté chñröcters 修补', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 4, { virt_text = { { 'múlti-byté chñröcters 修补', 'Special' } }, virt_text_pos = 'inline' }) screen:expect{grid=[[ 1234{10:múlti-byté chñröcters 修补}567^8 | @@ -2455,7 +2777,7 @@ describe('decorations: inline virtual text', function() it('has correct cursor position when inserting around virtual text', function() insert('12345678') - meths.buf_set_extmark(0, ns, 0, 4, { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 4, { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' }) feed '^' feed '3l' feed 'a' @@ -2481,7 +2803,7 @@ describe('decorations: inline virtual text', function() end) it('has correct cursor position with virtual text on an empty line', function() - meths.buf_set_extmark(0, ns, 0, 0, { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' }) screen:expect{grid=[[ {10:^virtual text} | {1:~ }| @@ -2495,8 +2817,8 @@ describe('decorations: inline virtual text', function() call setline(1, ['', 'aaa', '', 'bbbbbb']) normal gg0 ]]) - meths.buf_set_extmark(0, ns, 0, 0, { virt_text = { { string.rep('X', 60), 'Special' } }, virt_text_pos = 'inline' }) - meths.buf_set_extmark(0, ns, 2, 0, { virt_text = { { string.rep('X', 61), 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = { { string.rep('X', 60), 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 2, 0, { virt_text = { { string.rep('X', 61), 'Special' } }, virt_text_pos = 'inline' }) feed('$') screen:expect{grid=[[ {10:^XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}| @@ -2504,8 +2826,7 @@ describe('decorations: inline virtual text', function() {10:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}| {10:X} | bbbbbb | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} feed('j') @@ -2515,8 +2836,7 @@ describe('decorations: inline virtual text', function() {10:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}| {10:X} | bbbbbb | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} feed('j') @@ -2526,8 +2846,7 @@ describe('decorations: inline virtual text', function() {10:^XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}| {10:X} | bbbbbb | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} feed('j') @@ -2537,8 +2856,7 @@ describe('decorations: inline virtual text', function() {10:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}| {10:X} | bbbbb^b | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} feed('0<C-V>2l2k') @@ -2548,8 +2866,7 @@ describe('decorations: inline virtual text', function() {10:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}| {10:X} | {7:bbb}bbb | - {1:~ }| - {1:~ }| + {1:~ }|*2 {8:-- VISUAL BLOCK --} | ]]} feed([[<Esc>/aaa\n\%V<CR>]]) @@ -2559,8 +2876,7 @@ describe('decorations: inline virtual text', function() {10:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}| {10:X} | bbbbbb | - {1:~ }| - {1:~ }| + {1:~ }|*2 {16:search hit BOTTOM, continuing at TOP} | ]]} feed('3ggic') @@ -2570,8 +2886,7 @@ describe('decorations: inline virtual text', function() c{10:^XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}| {10:XX} | bbbbbb | - {1:~ }| - {1:~ }| + {1:~ }|*2 {8:-- INSERT --} | ]]} feed([[<Esc>/aaa\nc\%V<CR>]]) @@ -2581,8 +2896,7 @@ describe('decorations: inline virtual text', function() {12:c}{10:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}| {10:XX} | bbbbbb | - {1:~ }| - {1:~ }| + {1:~ }|*2 {16:search hit BOTTOM, continuing at TOP} | ]]} end) @@ -2594,7 +2908,7 @@ describe('decorations: inline virtual text', function() feed('<TAB>') feed('test') feed('<ESC>') - meths.buf_set_extmark(0, ns, 0, 1, { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 1, { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' }) feed('0') screen:expect{grid=[[ ^ {10:virtual text} test | @@ -2635,7 +2949,7 @@ describe('decorations: inline virtual text', function() command('set linebreak') insert('one twoword') feed('0') - meths.buf_set_extmark(0, ns, 0, 3, { virt_text = { { ': virtual text', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 3, { virt_text = { { ': virtual text', 'Special' } }, virt_text_pos = 'inline' }) screen:expect{grid=[[ ^one{10:: virtual text} twoword | {1:~ }| @@ -2646,10 +2960,10 @@ describe('decorations: inline virtual text', function() it('search highlight is correct', function() insert('foo foo foo bar\nfoo foo foo bar') feed('gg0') - meths.buf_set_extmark(0, ns, 0, 9, { virt_text = { { 'AAA', 'Special' } }, virt_text_pos = 'inline' }) - meths.buf_set_extmark(0, ns, 0, 9, { virt_text = { { 'BBB', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) - meths.buf_set_extmark(0, ns, 1, 9, { virt_text = { { 'CCC', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) - meths.buf_set_extmark(0, ns, 1, 9, { virt_text = { { 'DDD', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'replace' }) + api.nvim_buf_set_extmark(0, ns, 0, 9, { virt_text = { { 'AAA', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 9, { virt_text = { { 'BBB', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) + api.nvim_buf_set_extmark(0, ns, 1, 9, { virt_text = { { 'CCC', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) + api.nvim_buf_set_extmark(0, ns, 1, 9, { virt_text = { { 'DDD', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'replace' }) screen:expect{grid=[[ ^foo foo f{10:AAABBB}oo bar | foo foo f{10:CCCDDD}oo bar | @@ -2663,7 +2977,7 @@ describe('decorations: inline virtual text', function() /foo^ | ]]} - meths.buf_set_extmark(0, ns, 0, 13, { virt_text = { { 'EEE', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) + api.nvim_buf_set_extmark(0, ns, 0, 13, { virt_text = { { 'EEE', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) feed('<C-G>') screen:expect{grid=[[ {12:foo} {12:foo} {13:f}{10:AAA}{21:BBB}{13:oo} b{10:EEE}ar | @@ -2675,10 +2989,10 @@ describe('decorations: inline virtual text', function() it('Visual select highlight is correct', function() insert('foo foo foo bar\nfoo foo foo bar') feed('gg0') - meths.buf_set_extmark(0, ns, 0, 8, { virt_text = { { 'AAA', 'Special' } }, virt_text_pos = 'inline' }) - meths.buf_set_extmark(0, ns, 0, 8, { virt_text = { { 'BBB', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) - meths.buf_set_extmark(0, ns, 1, 8, { virt_text = { { 'CCC', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) - meths.buf_set_extmark(0, ns, 1, 8, { virt_text = { { 'DDD', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'replace' }) + api.nvim_buf_set_extmark(0, ns, 0, 8, { virt_text = { { 'AAA', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 8, { virt_text = { { 'BBB', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) + api.nvim_buf_set_extmark(0, ns, 1, 8, { virt_text = { { 'CCC', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) + api.nvim_buf_set_extmark(0, ns, 1, 8, { virt_text = { { 'DDD', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'replace' }) feed('8l') screen:expect{grid=[[ foo foo {10:AAABBB}^foo bar | @@ -2694,7 +3008,7 @@ describe('decorations: inline virtual text', function() {8:-- VISUAL BLOCK --} | ]]} - meths.buf_set_extmark(0, ns, 0, 10, { virt_text = { { 'EEE', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) + api.nvim_buf_set_extmark(0, ns, 0, 10, { virt_text = { { 'EEE', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) screen:expect{grid=[[ foo fo{7:o }{10:AAA}{20:BBB}{7:f}o{10:EEE}o bar | foo fo^o{7: }{20:CCC}{10:DDD}{7:f}oo bar | @@ -2704,12 +3018,12 @@ describe('decorations: inline virtual text', function() it('inside highlight range of another extmark', function() insert('foo foo foo bar\nfoo foo foo bar') - meths.buf_set_extmark(0, ns, 0, 8, { virt_text = { { 'AAA', 'Special' } }, virt_text_pos = 'inline' }) - meths.buf_set_extmark(0, ns, 0, 8, { virt_text = { { 'BBB', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) - meths.buf_set_extmark(0, ns, 1, 8, { virt_text = { { 'CCC', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) - meths.buf_set_extmark(0, ns, 1, 8, { virt_text = { { 'DDD', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'replace' }) - meths.buf_set_extmark(0, ns, 0, 4, { end_col = 11, hl_group = 'Search' }) - meths.buf_set_extmark(0, ns, 1, 4, { end_col = 11, hl_group = 'Search' }) + api.nvim_buf_set_extmark(0, ns, 0, 8, { virt_text = { { 'AAA', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 8, { virt_text = { { 'BBB', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) + api.nvim_buf_set_extmark(0, ns, 1, 8, { virt_text = { { 'CCC', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) + api.nvim_buf_set_extmark(0, ns, 1, 8, { virt_text = { { 'DDD', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'replace' }) + api.nvim_buf_set_extmark(0, ns, 0, 4, { end_col = 11, hl_group = 'Search' }) + api.nvim_buf_set_extmark(0, ns, 1, 4, { end_col = 11, hl_group = 'Search' }) screen:expect{grid=[[ foo {12:foo }{10:AAA}{19:BBB}{12:foo} bar | foo {12:foo }{19:CCC}{10:DDD}{12:foo} ba^r | @@ -2719,10 +3033,10 @@ describe('decorations: inline virtual text', function() it('inside highlight range of syntax', function() insert('foo foo foo bar\nfoo foo foo bar') - meths.buf_set_extmark(0, ns, 0, 8, { virt_text = { { 'AAA', 'Special' } }, virt_text_pos = 'inline' }) - meths.buf_set_extmark(0, ns, 0, 8, { virt_text = { { 'BBB', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) - meths.buf_set_extmark(0, ns, 1, 8, { virt_text = { { 'CCC', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) - meths.buf_set_extmark(0, ns, 1, 8, { virt_text = { { 'DDD', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'replace' }) + api.nvim_buf_set_extmark(0, ns, 0, 8, { virt_text = { { 'AAA', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 8, { virt_text = { { 'BBB', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) + api.nvim_buf_set_extmark(0, ns, 1, 8, { virt_text = { { 'CCC', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) + api.nvim_buf_set_extmark(0, ns, 1, 8, { virt_text = { { 'DDD', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'replace' }) command([[syntax match Search 'foo \zsfoo foo\ze bar']]) screen:expect{grid=[[ foo {12:foo }{10:AAA}{19:BBB}{12:foo} bar | @@ -2734,7 +3048,7 @@ describe('decorations: inline virtual text', function() it('cursor position is correct when inserting around a virtual text with left gravity', function() screen:try_resize(27, 4) insert(('a'):rep(15)) - meths.buf_set_extmark(0, ns, 0, 8, { virt_text = { { ('>'):rep(43), 'Special' } }, virt_text_pos = 'inline', right_gravity = false }) + api.nvim_buf_set_extmark(0, ns, 0, 8, { virt_text = { { ('>'):rep(43), 'Special' } }, virt_text_pos = 'inline', right_gravity = false }) command('setlocal showbreak=+ breakindent breakindentopt=shift:2') feed('08l') screen:expect{grid=[[ @@ -2805,8 +3119,8 @@ describe('decorations: inline virtual text', function() screen:try_resize(30, 4) command('setlocal showbreak=+ breakindent breakindentopt=shift:2') insert(('a'):rep(15)) - meths.buf_set_extmark(0, ns, 0, 8, { virt_text = {{ ('>'):rep(32), 'Special' }}, virt_text_pos = 'inline', right_gravity = false }) - meths.buf_set_extmark(0, ns, 0, 8, { virt_text = {{ ('<'):rep(32), 'Special' }}, virt_text_pos = 'inline', right_gravity = true }) + api.nvim_buf_set_extmark(0, ns, 0, 8, { virt_text = {{ ('>'):rep(32), 'Special' }}, virt_text_pos = 'inline', right_gravity = false }) + api.nvim_buf_set_extmark(0, ns, 0, 8, { virt_text = {{ ('<'):rep(32), 'Special' }}, virt_text_pos = 'inline', right_gravity = true }) feed('08l') screen:expect{grid=[[ aaaaaaaa{10:>>>>>>>>>>>>>>>>>>>>>>}| @@ -2903,8 +3217,8 @@ describe('decorations: inline virtual text', function() it('draws correctly with no wrap multiple virtual text, where one is hidden', function() insert('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz') command("set nowrap") - meths.buf_set_extmark(0, ns, 0, 50, { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' }) - meths.buf_set_extmark(0, ns, 0, 2, { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 50, { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 2, { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' }) feed('$') screen:expect{grid=[[ opqrstuvwxyzabcdefghijklmnopqrstuvwx{10:virtual text}y^z| @@ -2916,7 +3230,7 @@ describe('decorations: inline virtual text', function() it('draws correctly with no wrap and a long virtual text', function() insert('abcdefghi') command("set nowrap") - meths.buf_set_extmark(0, ns, 0, 2, { virt_text = { { string.rep('X', 55), 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 2, { virt_text = { { string.rep('X', 55), 'Special' } }, virt_text_pos = 'inline' }) feed('$') screen:expect{grid=[[ {10:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}cdefgh^i| @@ -2928,7 +3242,7 @@ describe('decorations: inline virtual text', function() it('tabs are the correct length with no wrap following virtual text', function() command('set nowrap') feed('itest<TAB>a<ESC>') - meths.buf_set_extmark(0, ns, 0, 0, { virt_text = { { string.rep('a', 55), 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = { { string.rep('a', 55), 'Special' } }, virt_text_pos = 'inline' }) feed('gg$') screen:expect{grid=[[ {10:aaaaaaaaaaaaaaaaaaaaaaaaa}test ^a | @@ -2940,7 +3254,7 @@ describe('decorations: inline virtual text', function() it('highlighting does not extend with no wrap and a long virtual text', function() insert('abcdef') command("set nowrap") - meths.buf_set_extmark(0, ns, 0, 3, { virt_text = { { string.rep('X', 50), 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 3, { virt_text = { { string.rep('X', 50), 'Special' } }, virt_text_pos = 'inline' }) feed('$') screen:expect{grid=[[ {10:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}de^f| @@ -2952,7 +3266,7 @@ describe('decorations: inline virtual text', function() it('hidden virtual text does not interfere with Visual highlight', function() insert('abcdef') command('set nowrap') - meths.buf_set_extmark(0, ns, 0, 0, { virt_text = { { 'XXX', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = { { 'XXX', 'Special' } }, virt_text_pos = 'inline' }) feed('V2zl') screen:expect{grid=[[ {10:X}{7:abcde}^f | @@ -2979,7 +3293,7 @@ describe('decorations: inline virtual text', function() test test]]) command('set number') - meths.buf_set_extmark(0, ns, 0, 1, { virt_text = { { string.rep('X', 55), 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 1, { virt_text = { { string.rep('X', 55), 'Special' } }, virt_text_pos = 'inline' }) feed('gg0') screen:expect{grid=[[ {2: 1 }^t{10:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}| @@ -2992,7 +3306,7 @@ describe('decorations: inline virtual text', function() it('highlighting is correct when virtual text is proceeded with a match', function() insert([[test]]) - meths.buf_set_extmark(0, ns, 0, 2, { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 2, { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' }) feed('gg0') command('match ErrorMsg /e/') screen:expect{grid=[[ @@ -3010,7 +3324,7 @@ describe('decorations: inline virtual text', function() it('smoothscroll works correctly when virtual text wraps', function() insert('foobar') - meths.buf_set_extmark(0, ns, 0, 3, { virt_text = { { string.rep('X', 55), 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 3, { virt_text = { { string.rep('X', 55), 'Special' } }, virt_text_pos = 'inline' }) command('setlocal smoothscroll') screen:expect{grid=[[ foo{10:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}| @@ -3036,9 +3350,9 @@ describe('decorations: inline virtual text', function() ]]) insert('aaa\tbbb') command("set diff") - meths.buf_set_extmark(0, ns, 0, 1, { virt_text = { { 'test', 'Special' } }, virt_text_pos = 'inline', right_gravity = false }) - meths.buf_set_extmark(0, ns, 5, 0, { virt_text = { { '!', 'Special' } }, virt_text_pos = 'inline' }) - meths.buf_set_extmark(0, ns, 5, 3, { virt_text = { { '' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 1, { virt_text = { { 'test', 'Special' } }, virt_text_pos = 'inline', right_gravity = false }) + api.nvim_buf_set_extmark(0, ns, 5, 0, { virt_text = { { '!', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 5, 3, { virt_text = { { '' } }, virt_text_pos = 'inline' }) command("vnew") insert([[ 000 @@ -3052,13 +3366,11 @@ describe('decorations: inline virtual text', function() feed('gg0') screen:expect{grid=[[ {9:^000 }│{5:9}{14:test}{9:000 }| - {9:000 }│{9:000}{5:9}{9: }| - {9:000 }│{9:000}{5:9}{9: }| + {9:000 }│{9:000}{5:9}{9: }|*2 {9:000 }│{5:9}{9:000 }| {9:000 }│{9:000}{5:9}{9: }| {9:aaabbb }│{14:!}{9:aaa}{5: }{9:bbb }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*2 {15:[No Name] [+] }{13:[No Name] [+] }| | ]]} @@ -3066,13 +3378,11 @@ describe('decorations: inline virtual text', function() feed('zl') screen:expect{grid=[[ {9:000 }│{14:test}{9:000 }| - {9:000 }│{9:00}{5:9}{9: }| - {9:000 }│{9:00}{5:9}{9: }| + {9:000 }│{9:00}{5:9}{9: }|*2 {9:000 }│{9:000 }| {9:000 }│{9:00}{5:9}{9: }| {9:aaabbb }│{9:aaa}{5: }{9:bb^b }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*2 {13:[No Name] [+] }{15:[No Name] [+] }| | ]]} @@ -3081,8 +3391,8 @@ describe('decorations: inline virtual text', function() it('correctly draws when there are multiple overlapping virtual texts on the same line with nowrap', function() command('set nowrap') insert('a') - meths.buf_set_extmark(0, ns, 0, 0, { virt_text = { { string.rep('a', 55), 'Special' } }, virt_text_pos = 'inline' }) - meths.buf_set_extmark(0, ns, 0, 0, { virt_text = { { string.rep('b', 55), 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = { { string.rep('a', 55), 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = { { string.rep('b', 55), 'Special' } }, virt_text_pos = 'inline' }) feed('$') screen:expect{grid=[[ {10:bbbbbbbbbbbbbbbbbbbbbbbbb}^a | @@ -3094,7 +3404,7 @@ describe('decorations: inline virtual text', function() it('correctly draws when overflowing virtual text is followed by TAB with no wrap', function() command('set nowrap') feed('i<TAB>test<ESC>') - meths.buf_set_extmark( 0, ns, 0, 0, { virt_text = { { string.rep('a', 60), 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark( 0, ns, 0, 0, { virt_text = { { string.rep('a', 60), 'Special' } }, virt_text_pos = 'inline' }) feed('0') screen:expect({grid=[[ {10:aaaaaaaaaaaaaaaaaaaaaa} ^ test | @@ -3112,8 +3422,8 @@ describe('decorations: inline virtual text', function() bbbbb ccccc]]) - meths.buf_set_extmark(0, ns, 0, 0, { virt_text = {{'foo'}}, virt_text_pos = 'inline' }) - meths.buf_set_extmark(0, ns, 2, 0, { virt_text = {{'bar'}}, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = {{'foo'}}, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 2, 0, { virt_text = {{'bar'}}, virt_text_pos = 'inline' }) screen:expect{grid=[[ fooaaaaa | bbbbb | @@ -3141,44 +3451,37 @@ describe('decorations: inline virtual text', function() screen:expect{grid=[[ {18:^+-- 2 lines: aaaaa·······························································}| {17:+-- 2 lines: ccccc·······························································}| - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} feed('j') screen:expect{grid=[[ {17:+-- 2 lines: aaaaa·······························································}| {18:^+-- 2 lines: ccccc·······························································}| - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} end) it('does not crash at right edge of wide window #23848', function() screen:try_resize(82, 5) - meths.buf_set_extmark(0, ns, 0, 0, {virt_text = {{('a'):rep(82)}, {'b'}}, virt_text_pos = 'inline'}) + api.nvim_buf_set_extmark(0, ns, 0, 0, {virt_text = {{('a'):rep(82)}, {'b'}}, virt_text_pos = 'inline'}) screen:expect{grid=[[ ^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| b | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} command('set nowrap') screen:expect{grid=[[ ^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]} feed('82i0<Esc>0') screen:expect{grid=[[ ^0000000000000000000000000000000000000000000000000000000000000000000000000000000000| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]} command('set wrap') @@ -3196,7 +3499,7 @@ describe('decorations: inline virtual text', function() setlocal nowrap list listchars=extends:! call setline(1, repeat('a', 51)) ]]) - meths.buf_set_extmark(0, ns, 0, 50, { virt_text = { { 'bbb', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 50, { virt_text = { { 'bbb', 'Special' } }, virt_text_pos = 'inline' }) feed('20l') screen:expect{grid=[[ aaaaaaaaaaaaaaaaaaaa^aaaaaaaaaaaaaaaaaaaaaaaaaaaaa{1:!}| @@ -3233,7 +3536,7 @@ describe('decorations: inline virtual text', function() command('set nowrap') command('set list') command('set listchars+=extends:c') - meths.buf_set_extmark(0, ns, 0, 0, { virt_text = { { 'test', 'Special' } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_text = { { 'test', 'Special' } }, virt_text_pos = 'inline' }) insert(string.rep('a', 50)) feed('gg0') screen:expect{grid=[[ @@ -3246,8 +3549,8 @@ describe('decorations: inline virtual text', function() it('blockwise Visual highlight with double-width virtual text (replace)', function() screen:try_resize(60, 6) insert('123456789\n123456789\n123456789\n123456789') - meths.buf_set_extmark(0, ns, 1, 1, { virt_text = { { '-口-', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'replace' }) - meths.buf_set_extmark(0, ns, 2, 2, { virt_text = { { '口', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'replace' }) + api.nvim_buf_set_extmark(0, ns, 1, 1, { virt_text = { { '-口-', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'replace' }) + api.nvim_buf_set_extmark(0, ns, 2, 2, { virt_text = { { '口', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'replace' }) feed('gg0') screen:expect{grid=[[ ^123456789 | @@ -3316,8 +3619,8 @@ describe('decorations: inline virtual text', function() it('blockwise Visual highlight with double-width virtual text (combine)', function() screen:try_resize(60, 6) insert('123456789\n123456789\n123456789\n123456789') - meths.buf_set_extmark(0, ns, 1, 1, { virt_text = { { '-口-', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) - meths.buf_set_extmark(0, ns, 2, 2, { virt_text = { { '口', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) + api.nvim_buf_set_extmark(0, ns, 1, 1, { virt_text = { { '-口-', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) + api.nvim_buf_set_extmark(0, ns, 2, 2, { virt_text = { { '口', 'Special' } }, virt_text_pos = 'inline', hl_mode = 'combine' }) feed('gg0') screen:expect{grid=[[ ^123456789 | @@ -3392,7 +3695,7 @@ describe('decorations: inline virtual text', function() call setline(1, repeat('a', 28)) normal! $ ]]) - meths.buf_set_extmark(0, ns, 0, 27, { virt_text = { { ('123'):rep(23) } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 27, { virt_text = { { ('123'):rep(23) } }, virt_text_pos = 'inline' }) feed(':<CR>') -- Have a screen line that doesn't start with spaces screen:expect{grid=[[ 1 aaaaaaaaaaaaaaaaaaaaaaaaaa| @@ -3416,26 +3719,20 @@ describe('decorations: inline virtual text', function() {1:+}23123123123123123123123| {1:+}12312312312312312312312| {1:+}3^a | - {1:~ }| - {1:~ }| + {1:~ }|*2 : | ]]} feed('<C-E>') screen:expect{grid=[[ {1:+}12312312312312312312312| {1:+}3^a | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 : | ]]} feed('<C-E>') screen:expect{grid=[[ {1:+}3^a | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 : | ]]} feed('zbi') @@ -3480,26 +3777,20 @@ describe('decorations: inline virtual text', function() {1:+}31231231231231231231231| {1:+}23123123123123123123123| {1:+}^a | - {1:~ }| - {1:~ }| + {1:~ }|*2 : | ]]} feed('<C-E>') screen:expect{grid=[[ {1:+}23123123123123123123123| {1:+}^a | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 : | ]]} feed('<C-E>') screen:expect{grid=[[ {1:+}^a | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 : | ]]} feed('023x$') @@ -3516,26 +3807,20 @@ describe('decorations: inline virtual text', function() {1:+}31231231231231231231231| {1:+}23123123123123123123123| {1:+}^a | - {1:~ }| - {1:~ }| + {1:~ }|*2 : | ]]} feed('<C-E>') screen:expect{grid=[[ {1:+}23123123123123123123123| {1:+}^a | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 : | ]]} feed('<C-E>') screen:expect{grid=[[ {1:+}^a | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 : | ]]} feed('zbi') @@ -3552,8 +3837,7 @@ describe('decorations: inline virtual text', function() 1 ^12312312312312312312312312| {1:+}31231231231231231231231| {1:+}23123123123123123123a | - {1:~ }| - {1:~ }| + {1:~ }|*2 {8:-- INSERT --} | ]]} feed('<Esc>') @@ -3561,26 +3845,20 @@ describe('decorations: inline virtual text', function() 1 12312312312312312312312312| {1:+}31231231231231231231231| {1:+}23123123123123123123^a | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} feed('<C-E>') screen:expect{grid=[[ {1:+}31231231231231231231231| {1:+}23123123123123123123^a | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]} feed('<C-E>') screen:expect{grid=[[ {1:+}23123123123123123123^a | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]} feed('zbx') @@ -3588,8 +3866,7 @@ describe('decorations: inline virtual text', function() 1 ^12312312312312312312312312| {1:+}31231231231231231231231| {1:+}23123123123123123123 | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} feed('26ia<Esc>a') @@ -3631,7 +3908,7 @@ describe('decorations: inline virtual text', function() call setline(1, repeat("\t", 4) .. 'a') normal! $ ]]) - meths.buf_set_extmark(0, ns, 0, 3, { virt_text = { { ('12'):rep(32) } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 3, { virt_text = { { ('12'):rep(32) } }, virt_text_pos = 'inline' }) screen:expect{grid=[[ {1:<------><------><------>}121212| 121212121212121212121212121212| @@ -3645,26 +3922,20 @@ describe('decorations: inline virtual text', function() {1:<<<}212121212121212121212121212| 1212121212121212121212121212{1:<-}| {1:----->}^a | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} feed('<C-E>') screen:expect{grid=[[ {1:<<<}2121212121212121212121212{1:<-}| {1:----->}^a | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]} feed('<C-E>') screen:expect{grid=[[ {1:<<<-->}^a | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]} feed('zbh') @@ -3708,26 +3979,20 @@ describe('decorations: inline virtual text', function() {1:<<<}212121212121212121212121212| 1212121212121212121212121212 | ^ a | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} feed('<C-E>') screen:expect{grid=[[ {1:<<<}2121212121212121212121212 | ^ a | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]} feed('<C-E>') screen:expect{grid=[[ {1:<<<} ^ a | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]} end) @@ -3739,13 +4004,12 @@ describe('decorations: inline virtual text', function() call setline(1, repeat('a', 50) .. ' ' .. repeat('c', 45)) normal! $ ]]) - meths.buf_set_extmark(0, ns, 0, 50, { virt_text = { { ('b'):rep(10) } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 50, { virt_text = { { ('b'):rep(10) } }, virt_text_pos = 'inline' }) screen:expect{grid=[[ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| {1:+}bbbbbbbbbb | {1:+}cccccccccccccccccccccccccccccccccccccccccccc^c | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} feed('05x$') @@ -3753,8 +4017,7 @@ describe('decorations: inline virtual text', function() aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb| {1:+}bbbbb | {1:+}cccccccccccccccccccccccccccccccccccccccccccc^c | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} end) @@ -3764,7 +4027,7 @@ describe('decorations: inline virtual text', function() call setline(1, repeat('a', 40) .. '口' .. '12345') normal! $ ]]) - meths.buf_set_extmark(0, ns, 0, 40, { virt_text = { { ('b'):rep(9) } }, virt_text_pos = 'inline' }) + api.nvim_buf_set_extmark(0, ns, 0, 40, { virt_text = { { ('b'):rep(9) } }, virt_text_pos = 'inline' }) screen:expect{grid=[[ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbb{1:>}| 口1234^5 | @@ -3791,7 +4054,7 @@ describe('decorations: virtual lines', function() [9] = {foreground = Screen.colors.Brown}; } - ns = meths.create_namespace 'test' + ns = api.nvim_create_namespace 'test' end) local example_text2 = [[ @@ -3806,16 +4069,31 @@ if (h->n_buckets < new_n_buckets) { // expand it('works with one line', function() insert(example_text2) - feed 'gg' - meths.buf_set_extmark(0, ns, 1, 33, { + feed '2gg' + screen:expect{grid=[[ + if (h->n_buckets < new_n_buckets) { // expand | + ^khkey_t *new_keys = (khkey_t *)krealloc((void *)| + h->keys, new_n_buckets * sizeof(khkey_t)); | + h->keys = new_keys; | + if (kh_is_map && val_size) { | + char *new_vals = krealloc( h->vals_buf, new_n_| + buckets * val_size); | + h->vals_buf = new_vals; | + } | + } | + {1:~ }| + | + ]]} + + api.nvim_buf_set_extmark(0, ns, 1, 33, { virt_lines={ {{">> ", "NonText"}, {"krealloc", "Identifier"}, {": change the size of an allocation"}}}; virt_lines_above=true; }) screen:expect{grid=[[ - ^if (h->n_buckets < new_n_buckets) { // expand | + if (h->n_buckets < new_n_buckets) { // expand | {1:>> }{2:krealloc}: change the size of an allocation | - khkey_t *new_keys = (khkey_t *)krealloc((void *)| + ^khkey_t *new_keys = (khkey_t *)krealloc((void *)| h->keys, new_n_buckets * sizeof(khkey_t)); | h->keys = new_keys; | if (kh_is_map && val_size) { | @@ -3876,10 +4154,9 @@ if (h->n_buckets < new_n_buckets) { // expand | ]]} - meths.buf_set_extmark(0, ns, 5, 0, { + api.nvim_buf_set_extmark(0, ns, 5, 0, { virt_lines = { {{"^^ REVIEW:", "Todo"}, {" new_vals variable seems unnecessary?", "Comment"}} }; }) - -- TODO: what about the cursor?? screen:expect{grid=[[ if (h->n_buckets < new_n_buckets) { // expand | khkey_t *new_keys = (khkey_t *) | @@ -3895,8 +4172,7 @@ if (h->n_buckets < new_n_buckets) { // expand | ]]} - meths.buf_clear_namespace(0, ns, 0, -1) - -- Cursor should be drawn on the correct line. #22704 + api.nvim_buf_clear_namespace(0, ns, 0, -1) screen:expect{grid=[[ if (h->n_buckets < new_n_buckets) { // expand | khkey_t *new_keys = (khkey_t *) | @@ -3932,7 +4208,7 @@ if (h->n_buckets < new_n_buckets) { // expand | ]]} - meths.buf_set_extmark(0, ns, 0, 0, { + api.nvim_buf_set_extmark(0, ns, 0, 0, { virt_lines={ {{"refactor(khash): ", "Special"}, {"take size of values as parameter"}}; {{"Author: Dev Devsson, "}, {"Tue Aug 31 10:13:37 2021", "Comment"}}; @@ -3993,7 +4269,7 @@ if (h->n_buckets < new_n_buckets) { // expand | ]]} - local id = meths.buf_set_extmark(0, ns, 7, 0, { + local id = api.nvim_buf_set_extmark(0, ns, 7, 0, { virt_lines={{{"Grugg"}}}; right_gravity=false; }) @@ -4076,7 +4352,7 @@ if (h->n_buckets < new_n_buckets) { // expand | ]]} - meths.buf_del_extmark(0, ns, id) + api.nvim_buf_del_extmark(0, ns, id) screen:expect{grid=[[ if (h->n_buckets < new_n_buckets) { // expand | khkey_t *new_keys = (khkey_t *)krealloc((void *)| @@ -4112,7 +4388,7 @@ if (h->n_buckets < new_n_buckets) { // expand | ]]} - local id = meths.buf_set_extmark(0, ns, 8, 0, { + local id = api.nvim_buf_set_extmark(0, ns, 8, 0, { virt_lines={{{"Grugg"}}}; virt_lines_above = true, }) @@ -4158,9 +4434,7 @@ if (h->n_buckets < new_n_buckets) { // expand ^char *new_vals = krealloc( h->vals_buf, new_n_| buckets * val_size); | Grugg | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]} @@ -4168,31 +4442,14 @@ if (h->n_buckets < new_n_buckets) { // expand screen:expect{grid=[[ ^ | Grugg | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*9 --No lines in buffer-- | ]]} - meths.buf_del_extmark(0, ns, id) + api.nvim_buf_del_extmark(0, ns, id) screen:expect{grid=[[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*10 --No lines in buffer-- | ]]} end) @@ -4201,19 +4458,11 @@ if (h->n_buckets < new_n_buckets) { // expand command([[syntax region foo keepend start='^foo' end='^$']]) command('syntax sync minlines=100') insert('foo') - meths.buf_set_extmark(0, ns, 0, 0, {virt_lines = {{{'bar', 'Comment'}}}}) + api.nvim_buf_set_extmark(0, ns, 0, 0, {virt_lines = {{{'bar', 'Comment'}}}}) screen:expect([[ fo^o | {6:bar} | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*9 | ]]) end) @@ -4223,7 +4472,7 @@ if (h->n_buckets < new_n_buckets) { // expand insert("aa\nbb\ncc\ndd\nee\nff\ngg\nhh") feed 'gg' - meths.buf_set_extmark(0, ns, 6, 0, { + api.nvim_buf_set_extmark(0, ns, 6, 0, { virt_lines={ {{"they see me"}}; {{"scrolling", "Special"}}; @@ -4325,8 +4574,7 @@ if (h->n_buckets < new_n_buckets) { // expand they | {7:hatin'} | ^hh | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} @@ -4335,9 +4583,7 @@ if (h->n_buckets < new_n_buckets) { // expand they | {7:hatin'} | ^hh | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]} @@ -4345,21 +4591,14 @@ if (h->n_buckets < new_n_buckets) { // expand screen:expect{grid=[[ {7:hatin'} | ^hh | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]} feed '<c-e>' screen:expect{grid=[[ ^hh | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | ]]} end) @@ -4383,7 +4622,7 @@ if (h->n_buckets < new_n_buckets) { // expand | ]]} - local markid = meths.buf_set_extmark(0, ns, 2, 0, { + local markid = api.nvim_buf_set_extmark(0, ns, 2, 0, { virt_lines={ {{"Some special", "Special"}}; {{"remark about codes", "Comment"}}; @@ -4405,7 +4644,7 @@ if (h->n_buckets < new_n_buckets) { // expand | ]]} - meths.buf_set_extmark(0, ns, 2, 0, { + api.nvim_buf_set_extmark(0, ns, 2, 0, { virt_lines={ {{"Some special", "Special"}}; {{"remark about codes", "Comment"}}; @@ -4433,7 +4672,7 @@ if (h->n_buckets < new_n_buckets) { // expand it('works with hard TABs', function() insert(example_text2) feed 'gg' - meths.buf_set_extmark(0, ns, 1, 0, { + api.nvim_buf_set_extmark(0, ns, 1, 0, { virt_lines={ {{">>", "NonText"}, {"\tvery\ttabby", "Identifier"}, {"text\twith\ttabs"}}}; }) screen:expect{grid=[[ @@ -4507,8 +4746,8 @@ if (h->n_buckets < new_n_buckets) { // expand bbb ccc ddd]]) - meths.buf_set_extmark(0, ns, 0, 0, {end_row = 2, virt_lines = {{{'VIRT LINE 1', 'NonText'}}}}) - meths.buf_set_extmark(0, ns, 3, 0, {end_col = 2, virt_lines = {{{'VIRT LINE 2', 'NonText'}}}}) + api.nvim_buf_set_extmark(0, ns, 0, 0, {end_row = 2, virt_lines = {{{'VIRT LINE 1', 'NonText'}}}}) + api.nvim_buf_set_extmark(0, ns, 3, 0, {end_col = 2, virt_lines = {{{'VIRT LINE 2', 'NonText'}}}}) screen:expect{grid=[[ aaa | {1:VIRT LINE 1} | @@ -4529,8 +4768,8 @@ if (h->n_buckets < new_n_buckets) { // expand ccc ddd]]) command('set number rightleft') - meths.buf_set_extmark(0, ns, 0, 0, {virt_lines = {{{'VIRT LINE 1', 'NonText'}}}, virt_lines_leftcol = true}) - meths.buf_set_extmark(0, ns, 3, 0, {virt_lines = {{{'VIRT LINE 2', 'NonText'}}}}) + api.nvim_buf_set_extmark(0, ns, 0, 0, {virt_lines = {{{'VIRT LINE 1', 'NonText'}}}, virt_lines_leftcol = true}) + api.nvim_buf_set_extmark(0, ns, 3, 0, {virt_lines = {{{'VIRT LINE 2', 'NonText'}}}}) screen:expect{grid=[[ aaa{9: 1 }| {1:1 ENIL TRIV}| @@ -4550,7 +4789,7 @@ if (h->n_buckets < new_n_buckets) { // expand line3 line4 line5]]) - meths.buf_set_extmark(0, ns, 0, 0, {virt_lines={{{"foo"}}, {{"bar"}}, {{"baz"}}}}) + api.nvim_buf_set_extmark(0, ns, 0, 0, {virt_lines={{{"foo"}}, {{"bar"}}, {{"baz"}}}}) screen:expect{grid=[[ line1 | foo | @@ -4560,32 +4799,29 @@ if (h->n_buckets < new_n_buckets) { // expand line3 | line4 | line^5 | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]} feed('gg') - feed('dd') + feed('yyp') screen:expect{grid=[[ - ^line2 | + line1 | foo | bar | baz | + ^line1 | + line2 | line3 | line4 | line5 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]} - feed('yyp') + feed('dd') screen:expect{grid=[[ - line2 | + line1 | foo | bar | baz | @@ -4593,11 +4829,22 @@ if (h->n_buckets < new_n_buckets) { // expand line3 | line4 | line5 | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]} + + feed('kdd') + screen:expect([[ + ^line2 | + foo | + bar | + baz | + line3 | + line4 | + line5 | + {1:~ }|*4 + | + ]]) end) end) @@ -4612,10 +4859,11 @@ describe('decorations: signs', function() [1] = {foreground = Screen.colors.Blue4, background = Screen.colors.Grey}; [2] = {foreground = Screen.colors.Blue1, bold = true}; [3] = {background = Screen.colors.Yellow1, foreground = Screen.colors.Blue1}; + [4] = {foreground = Screen.colors.Gray100, background = Screen.colors.Red}; } - ns = meths.create_namespace 'test' - meths.set_option_value('signcolumn', 'auto:9', {}) + ns = api.nvim_create_namespace 'test' + api.nvim_set_option_value('signcolumn', 'auto:9', {}) end) local example_test3 = [[ @@ -4630,7 +4878,7 @@ l5 insert(example_test3) feed 'gg' - meths.buf_set_extmark(0, ns, 1, -1, {sign_text='S'}) + api.nvim_buf_set_extmark(0, ns, 1, -1, {sign_text='S'}) screen:expect{grid=[[ {1: }^l1 | @@ -4639,19 +4887,16 @@ l5 {1: }l4 | {1: }l5 | {1: } | - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 | ]]} - end) it('can add a single sign (with end row)', function() insert(example_test3) feed 'gg' - meths.buf_set_extmark(0, ns, 1, -1, {sign_text='S', end_row=1}) + api.nvim_buf_set_extmark(0, ns, 1, -1, {sign_text='S', end_row=1}) screen:expect{grid=[[ {1: }^l1 | @@ -4660,19 +4905,16 @@ l5 {1: }l4 | {1: }l5 | {1: } | - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 | ]]} - end) it('can add a single sign and text highlight', function() insert(example_test3) feed 'gg' - meths.buf_set_extmark(0, ns, 1, 0, {sign_text='S', hl_group='Todo', end_col=1}) + api.nvim_buf_set_extmark(0, ns, 1, 0, {sign_text='S', hl_group='Todo', end_col=1}) screen:expect{grid=[[ {1: }^l1 | S {3:l}2 | @@ -4680,20 +4922,18 @@ l5 {1: }l4 | {1: }l5 | {1: } | - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 | ]]} - meths.buf_clear_namespace(0, ns, 0, -1) + api.nvim_buf_clear_namespace(0, ns, 0, -1) end) it('can add multiple signs (single extmark)', function() insert(example_test3) feed 'gg' - meths.buf_set_extmark(0, ns, 1, -1, {sign_text='S', end_row = 2}) + api.nvim_buf_set_extmark(0, ns, 1, -1, {sign_text='S', end_row = 2}) screen:expect{grid=[[ {1: }^l1 | @@ -4702,20 +4942,17 @@ l5 {1: }l4 | {1: }l5 | {1: } | - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 | ]]} - end) it('can add multiple signs (multiple extmarks)', function() insert(example_test3) feed'gg' - meths.buf_set_extmark(0, ns, 1, -1, {sign_text='S1'}) - meths.buf_set_extmark(0, ns, 3, -1, {sign_text='S2', end_row = 4}) + api.nvim_buf_set_extmark(0, ns, 1, -1, {sign_text='S1'}) + api.nvim_buf_set_extmark(0, ns, 3, -1, {sign_text='S2', end_row = 4}) screen:expect{grid=[[ {1: }^l1 | @@ -4724,9 +4961,7 @@ l5 S2l4 | S2l5 | {1: } | - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 | ]]} end) @@ -4735,8 +4970,8 @@ l5 insert(example_test3) feed 'gg' - meths.buf_set_extmark(0, ns, 3, -1, {sign_text='S1'}) - meths.buf_set_extmark(0, ns, 1, -1, {sign_text='S2', end_row = 3}) + api.nvim_buf_set_extmark(0, ns, 3, -1, {sign_text='S1'}) + api.nvim_buf_set_extmark(0, ns, 1, -1, {sign_text='S2', end_row = 3}) screen:expect{grid=[[ {1: }^l1 | S2{1: }l2 | @@ -4744,9 +4979,7 @@ l5 S1S2l4 | {1: }l5 | {1: } | - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 | ]]} end) @@ -4756,8 +4989,8 @@ l5 insert(example_test3) feed 'gg' - meths.buf_set_extmark(0, ns, 1, -1, {sign_text='S1', end_row=2}) - meths.buf_set_extmark(0, ns, 2, -1, {sign_text='S2', end_row=3}) + api.nvim_buf_set_extmark(0, ns, 1, -1, {sign_text='S1', end_row=2}) + api.nvim_buf_set_extmark(0, ns, 2, -1, {sign_text='S2', end_row=3}) screen:expect{grid=[[ {1: }^l1 | @@ -4766,9 +4999,7 @@ l5 S2{1: }l4 | {1: }l5 | {1: } | - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 | ]]} end) @@ -4777,8 +5008,8 @@ l5 insert(example_test3) feed 'gg' - meths.buf_set_extmark(0, ns, 0, -1, {sign_text='S1', end_row=0}) - meths.buf_set_extmark(0, ns, 1, -1, {sign_text='S2', end_row=1}) + api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S1', end_row=0}) + api.nvim_buf_set_extmark(0, ns, 1, -1, {sign_text='S2', end_row=1}) screen:expect{grid=[[ S1^l1 | @@ -4787,9 +5018,7 @@ l5 {1: }l4 | {1: }l5 | {1: } | - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 | ]]} end) @@ -4801,10 +5030,10 @@ l5 helpers.command('sign define Oldsign text=x') helpers.command([[exe 'sign place 42 line=2 name=Oldsign buffer=' . bufnr('')]]) - meths.buf_set_extmark(0, ns, 0, -1, {sign_text='S1'}) - meths.buf_set_extmark(0, ns, 1, -1, {sign_text='S2'}) - meths.buf_set_extmark(0, ns, 0, -1, {sign_text='S4'}) - meths.buf_set_extmark(0, ns, 2, -1, {sign_text='S5'}) + api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S1'}) + api.nvim_buf_set_extmark(0, ns, 1, -1, {sign_text='S2'}) + api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S4'}) + api.nvim_buf_set_extmark(0, ns, 2, -1, {sign_text='S5'}) screen:expect{grid=[[ S1S4^l1 | @@ -4813,9 +5042,7 @@ l5 {1: }l4 | {1: }l5 | {1: } | - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 | ]]} end) @@ -4827,11 +5054,11 @@ l5 helpers.command('sign define Oldsign text=x') helpers.command([[exe 'sign place 42 line=2 name=Oldsign buffer=' . bufnr('')]]) - meths.buf_set_extmark(0, ns, 0, -1, {sign_text='S1'}) - meths.buf_set_extmark(0, ns, 1, -1, {sign_text='S2'}) - meths.buf_set_extmark(0, ns, 0, -1, {sign_text='S3', end_row = 4}) - meths.buf_set_extmark(0, ns, 0, -1, {sign_text='S4'}) - meths.buf_set_extmark(0, ns, 2, -1, {sign_text='S5'}) + api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S1'}) + api.nvim_buf_set_extmark(0, ns, 1, -1, {sign_text='S2'}) + api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S3', end_row = 4}) + api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S4'}) + api.nvim_buf_set_extmark(0, ns, 2, -1, {sign_text='S5'}) screen:expect{grid=[[ S1S3S4^l1 | @@ -4840,9 +5067,7 @@ l5 S3{1: }l4 | S3{1: }l5 | {1: } | - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 | ]]} end) @@ -4853,21 +5078,16 @@ l5 feed 'gg' feed '2<C-e>' - meths.buf_set_extmark(0, ns, 1, -1, {sign_text='X', end_row=3}) + api.nvim_buf_set_extmark(0, ns, 1, -1, {sign_text='X', end_row=3}) screen:expect{grid=[[ X {1: }^l3 | X {1: }l4 | {1: }l5 | {1: } | - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*5 | ]]} - end) it('can add lots of signs', function() @@ -4875,29 +5095,22 @@ l5 command 'normal 10oa b c d e f g h' for i = 1, 10 do - meths.buf_set_extmark(0, ns, i, 0, { end_col = 1, hl_group='Todo' }) - meths.buf_set_extmark(0, ns, i, 2, { end_col = 3, hl_group='Todo' }) - meths.buf_set_extmark(0, ns, i, 4, { end_col = 5, hl_group='Todo' }) - meths.buf_set_extmark(0, ns, i, 6, { end_col = 7, hl_group='Todo' }) - meths.buf_set_extmark(0, ns, i, 8, { end_col = 9, hl_group='Todo' }) - meths.buf_set_extmark(0, ns, i, 10, { end_col = 11, hl_group='Todo' }) - meths.buf_set_extmark(0, ns, i, 12, { end_col = 13, hl_group='Todo' }) - meths.buf_set_extmark(0, ns, i, 14, { end_col = 15, hl_group='Todo' }) - meths.buf_set_extmark(0, ns, i, -1, { sign_text='W' }) - meths.buf_set_extmark(0, ns, i, -1, { sign_text='X' }) - meths.buf_set_extmark(0, ns, i, -1, { sign_text='Y' }) - meths.buf_set_extmark(0, ns, i, -1, { sign_text='Z' }) + api.nvim_buf_set_extmark(0, ns, i, 0, { end_col = 1, hl_group='Todo' }) + api.nvim_buf_set_extmark(0, ns, i, 2, { end_col = 3, hl_group='Todo' }) + api.nvim_buf_set_extmark(0, ns, i, 4, { end_col = 5, hl_group='Todo' }) + api.nvim_buf_set_extmark(0, ns, i, 6, { end_col = 7, hl_group='Todo' }) + api.nvim_buf_set_extmark(0, ns, i, 8, { end_col = 9, hl_group='Todo' }) + api.nvim_buf_set_extmark(0, ns, i, 10, { end_col = 11, hl_group='Todo' }) + api.nvim_buf_set_extmark(0, ns, i, 12, { end_col = 13, hl_group='Todo' }) + api.nvim_buf_set_extmark(0, ns, i, 14, { end_col = 15, hl_group='Todo' }) + api.nvim_buf_set_extmark(0, ns, i, -1, { sign_text='W' }) + api.nvim_buf_set_extmark(0, ns, i, -1, { sign_text='X' }) + api.nvim_buf_set_extmark(0, ns, i, -1, { sign_text='Y' }) + api.nvim_buf_set_extmark(0, ns, i, -1, { sign_text='Z' }) end screen:expect{grid=[[ - W X Y Z {3:a} {3:b} {3:c} {3:d} {3:e} {3:f} {3:g} {3:h} | - W X Y Z {3:a} {3:b} {3:c} {3:d} {3:e} {3:f} {3:g} {3:h} | - W X Y Z {3:a} {3:b} {3:c} {3:d} {3:e} {3:f} {3:g} {3:h} | - W X Y Z {3:a} {3:b} {3:c} {3:d} {3:e} {3:f} {3:g} {3:h} | - W X Y Z {3:a} {3:b} {3:c} {3:d} {3:e} {3:f} {3:g} {3:h} | - W X Y Z {3:a} {3:b} {3:c} {3:d} {3:e} {3:f} {3:g} {3:h} | - W X Y Z {3:a} {3:b} {3:c} {3:d} {3:e} {3:f} {3:g} {3:h} | - W X Y Z {3:a} {3:b} {3:c} {3:d} {3:e} {3:f} {3:g} {3:h} | + W X Y Z {3:a} {3:b} {3:c} {3:d} {3:e} {3:f} {3:g} {3:h} |*8 W X Y Z {3:a} {3:b} {3:c} {3:d} {3:e} {3:f} {3:g} {3:^h} | | ]]} @@ -4911,10 +5124,10 @@ l5 command('sign define Oldsign text=O3') command([[exe 'sign place 42 line=1 name=Oldsign priority=10 buffer=' . bufnr('')]]) - meths.buf_set_extmark(0, ns, 0, -1, {sign_text='S4', priority=100}) - meths.buf_set_extmark(0, ns, 0, -1, {sign_text='S2', priority=5}) - meths.buf_set_extmark(0, ns, 0, -1, {sign_text='S5', priority=200}) - meths.buf_set_extmark(0, ns, 0, -1, {sign_text='S1', priority=1}) + api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S4', priority=100}) + api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S2', priority=5}) + api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S5', priority=200}) + api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S1', priority=1}) screen:expect{grid=[[ S1S2O3S4S5^l1 | @@ -4923,7 +5136,7 @@ l5 ]]} -- Check truncation works too - meths.set_option_value('signcolumn', 'auto', {}) + api.nvim_set_option_value('signcolumn', 'auto', {}) screen:expect{grid=[[ S5^l1 | @@ -4952,10 +5165,10 @@ l5 | ]]} - meths.buf_set_extmark(0, ns, 0, -1, {sign_text='S1', priority=1}) + api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S1', priority=1}) screen:expect_unchanged() - meths.buf_set_extmark(0, ns, 0, -1, {sign_text='S5', priority=200}) + api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S5', priority=200}) screen:expect{grid=[[ O3O3O3O3O3O3O3O3S5^ | {2:~ }| @@ -4967,16 +5180,237 @@ l5 it('does not set signcolumn for signs without text', function() screen:try_resize(20, 3) - meths.set_option_value('signcolumn', 'auto', {}) + api.nvim_set_option_value('signcolumn', 'auto', {}) insert(example_test3) feed 'gg' - meths.buf_set_extmark(0, ns, 0, -1, {number_hl_group='Error'}) + api.nvim_buf_set_extmark(0, ns, 0, -1, {number_hl_group='Error'}) screen:expect{grid=[[ ^l1 | l2 | | ]]} end) + + it('correct width when removing multiple signs from sentinel line', function() + screen:try_resize(20, 4) + insert(example_test3) + api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S1', end_row=3}) + api.nvim_buf_set_extmark(0, ns, 1, -1, {invalidate = true, sign_text='S2'}) + api.nvim_buf_set_extmark(0, ns, 1, -1, {invalidate = true, sign_text='S3'}) + feed('2Gdd') + + screen:expect{grid=[[ + S1l1 | + S1^l3 | + S1l4 | + | + ]]} + end) + + it('correct width with multiple overlapping signs', function() + screen:try_resize(20, 4) + insert(example_test3) + api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S1'}) + api.nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='S2', end_row=2}) + api.nvim_buf_set_extmark(0, ns, 1, -1, {sign_text='S3', end_row=2}) + feed('gg') + + local s1 = [[ + S1S2^l1 | + S2S3l2 | + S2S3l3 | + | + ]] + screen:expect{grid=s1} + -- Correct width when :move'ing a line with signs + command('move2') + screen:expect{grid=[[ + S3{1: }l2 | + S1S2S3^l1 | + {1: }l3 | + | + ]]} + command('silent undo') + screen:expect{grid=s1} + command('d') + screen:expect{grid=[[ + S1S2S3^l2 | + S2S3{1: }l3 | + {1: }l4 | + | + ]]} + command('d') + screen:expect{grid=[[ + S1S2S3^l3 | + {1: }l4 | + {1: }l5 | + | + ]]} + end) + + it('correct width when adding and removing multiple signs', function() + screen:try_resize(20, 4) + insert(example_test3) + feed('gg') + command([[ + let ns = nvim_create_namespace('') + call nvim_buf_set_extmark(0, ns, 0, 0, {'sign_text':'S1', 'end_row':3}) + let s1 = nvim_buf_set_extmark(0, ns, 2, 0, {'sign_text':'S2', 'end_row':4}) + let s2 = nvim_buf_set_extmark(0, ns, 5, 0, {'sign_text':'S3'}) + let s3 = nvim_buf_set_extmark(0, ns, 6, 0, {'sign_text':'S3'}) + let s4 = nvim_buf_set_extmark(0, ns, 5, 0, {'sign_text':'S3'}) + let s5 = nvim_buf_set_extmark(0, ns, 6, 0, {'sign_text':'S3'}) + redraw! + call nvim_buf_del_extmark(0, ns, s2) + call nvim_buf_del_extmark(0, ns, s3) + call nvim_buf_del_extmark(0, ns, s4) + call nvim_buf_del_extmark(0, ns, s5) + redraw! + call nvim_buf_del_extmark(0, ns, s1) + ]]) + screen:expect{grid=[[ + S1^l1 | + S1l2 | + S1l3 | + | + ]]} + end) + + it('correct width when deleting lines', function() + screen:try_resize(20, 4) + insert(example_test3) + feed('gg') + command([[ + let ns = nvim_create_namespace('') + call nvim_buf_set_extmark(0, ns, 4, 0, {'sign_text':'S1'}) + call nvim_buf_set_extmark(0, ns, 4, 0, {'sign_text':'S2'}) + let s3 = nvim_buf_set_extmark(0, ns, 5, 0, {'sign_text':'S3'}) + call nvim_buf_del_extmark(0, ns, s3) + norm 4Gdd + ]]) + screen:expect{grid=[[ + {1: }l3 | + S1S2l5 | + {1: }^ | + | + ]]} + end) + + it('correct width when splitting lines with signs on different columns', function() + screen:try_resize(20, 4) + insert(example_test3) + feed('gg') + api.nvim_buf_set_extmark(0, ns, 0, 0, {sign_text='S1'}) + api.nvim_buf_set_extmark(0, ns, 0, 1, {sign_text='S2'}) + feed('a<cr><esc>') + screen:expect{grid=[[ + S1l | + S2^1 | + {1: }l2 | + | + ]]} + end) + + it('correct width after wiping a buffer', function() + screen:try_resize(20, 4) + insert(example_test3) + feed('gg') + local buf = api.nvim_get_current_buf() + api.nvim_buf_set_extmark(buf, ns, 0, 0, { sign_text = 'h' }) + screen:expect{grid=[[ + h ^l1 | + {1: }l2 | + {1: }l3 | + | + ]]} + api.nvim_win_set_buf(0, api.nvim_create_buf(false, true)) + api.nvim_buf_delete(buf, {unload=true, force=true}) + api.nvim_buf_set_lines(buf, 0, -1, false, {''}) + api.nvim_win_set_buf(0, buf) + screen:expect{grid=[[ + ^ | + {2:~ }|*2 + | + ]]} + end) + + it('correct width with moved marks before undo savepos', function() + screen:try_resize(20, 4) + insert(example_test3) + feed('gg') + exec_lua([[ + local ns = vim.api.nvim_create_namespace('') + vim.api.nvim_buf_set_extmark(0, ns, 0, 0, { sign_text = 'S1' }) + vim.api.nvim_buf_set_extmark(0, ns, 1, 0, { sign_text = 'S2' }) + local s3 = vim.api.nvim_buf_set_extmark(0, ns, 2, 0, { sign_text = 'S3' }) + local s4 = vim.api.nvim_buf_set_extmark(0, ns, 2, 0, { sign_text = 'S4' }) + vim.schedule(function() + vim.cmd('silent d3') + vim.api.nvim_buf_set_extmark(0, ns, 2, 0, { id = s3, sign_text = 'S3' }) + vim.api.nvim_buf_set_extmark(0, ns, 2, 0, { id = s4, sign_text = 'S4' }) + vim.cmd('silent undo') + vim.api.nvim_buf_del_extmark(0, ns, s3) + end) + ]]) + + screen:expect{grid=[[ + S1^l1 | + S2l2 | + S4l3 | + | + ]]} + end) + + it('no crash with sign after many marks #27137', function() + screen:try_resize(20, 4) + insert('a') + for _ = 0, 104 do + api.nvim_buf_set_extmark(0, ns, 0, 0, {hl_group = 'Error', end_col = 1}) + end + api.nvim_buf_set_extmark(0, ns, 0, 0, {sign_text = 'S1'}) + + screen:expect{grid=[[ + S1{4:^a} | + {2:~ }|*2 + | + ]]} + end) + + it('correct sort order with multiple namespaces and same id', function() + local ns2 = api.nvim_create_namespace('') + api.nvim_buf_set_extmark(0, ns, 0, 0, {sign_text = 'S1', id = 1}) + api.nvim_buf_set_extmark(0, ns2, 0, 0, {sign_text = 'S2', id = 1}) + + screen:expect{grid=[[ + S1S2^ | + {2:~ }|*8 + | + ]]} + end) + + it('correct number of signs after deleting text (#27046)', function() + command('call setline(1, ["foo"]->repeat(31))') + api.nvim_buf_set_extmark(0, ns, 0, 0, {end_row = 0, sign_text = 'S1'}) + api.nvim_buf_set_extmark(0, ns, 0, 0, {end_row = 0, end_col = 3, hl_group = 'Error'}) + api.nvim_buf_set_extmark(0, ns, 9, 0, {end_row = 9, sign_text = 'S2'}) + api.nvim_buf_set_extmark(0, ns, 9, 0, {end_row = 9, end_col = 3, hl_group = 'Error'}) + api.nvim_buf_set_extmark(0, ns, 19, 0, {end_row = 19, sign_text = 'S3'}) + api.nvim_buf_set_extmark(0, ns, 19, 0, {end_row = 19, end_col = 3, hl_group = 'Error'}) + api.nvim_buf_set_extmark(0, ns, 29, 0, {end_row = 29, sign_text = 'S4'}) + api.nvim_buf_set_extmark(0, ns, 29, 0, {end_row = 29, end_col = 3, hl_group = 'Error'}) + api.nvim_buf_set_extmark(0, ns, 30, 0, {end_row = 30, sign_text = 'S5'}) + api.nvim_buf_set_extmark(0, ns, 30, 0, {end_row = 30, end_col = 3, hl_group = 'Error'}) + command('0d29') + + screen:expect{grid=[[ + S1S2S3S4{4:^foo} | + S5{1: }{4:foo} | + {2:~ }|*7 + 29 fewer lines | + ]]} + + api.nvim_buf_clear_namespace(0, ns, 0, -1) + end) end) describe('decorations: virt_text', function() @@ -5002,9 +5436,9 @@ describe('decorations: virt_text', function() command 'normal 4ohello' command 'normal aVIRTUAL' - local ns = meths.create_namespace('test') + local ns = api.nvim_create_namespace('test') - meths.buf_set_extmark(0, ns, 2, 0, { + api.nvim_buf_set_extmark(0, ns, 2, 0, { virt_text = {{"hello", "String"}}, virt_text_win_col = 20, }) @@ -5015,10 +5449,7 @@ describe('decorations: virt_text', function() {1: 2 }hello {2:hello} | {1: 1 }hello | {1:5 }helloVIRTUA^L | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*4 | ]]} @@ -5031,10 +5462,7 @@ describe('decorations: virt_text', function() {1: 1 }hello {2:hello} | {1:4 }hell^o | {1: 1 }helloVIRTUAL | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*4 | ]]} end) @@ -5044,34 +5472,379 @@ describe('decorations: virt_text', function() screen:expect{grid=[[ | - hello | - hello | - hello | - hello | + hello |*4 hell^o | - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*3 | ]]} - local ns = meths.create_namespace('ns') + local ns = api.nvim_create_namespace('ns') for row = 1, 5 do - meths.buf_set_extmark(0, ns, row, 0, { id = 1, virt_text = {{'world', 'Normal'}} }) + api.nvim_buf_set_extmark(0, ns, row, 0, { id = 1, virt_text = {{'world', 'Normal'}} }) end screen:expect{grid=[[ | - hello | - hello | - hello | - hello | + hello |*4 hell^o world | - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*3 | ]]} end) +end) +describe('decorations: window scoped', function() + local screen, ns + before_each(function() + clear() + screen = Screen.new(20, 10) + screen:attach() + screen:set_default_attr_ids { + [1] = { foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.Blue1, bold = true }, + } + + ns = api.nvim_create_namespace 'test' + + insert('12345') + end) + + local noextmarks = { + grid = [[ + 1234^5 | + {2:~ }|*8 + | + ]]} + + local function set_scoped_extmark(line, col, opts) + return api.nvim_buf_set_extmark(0, ns, line, col, vim.tbl_extend('error', { scoped = true }, opts)) + end + + it('hl_group', function() + set_scoped_extmark(0, 0, { + hl_group = 'Comment', + end_col = 3, + }) + + screen:expect(noextmarks) + + api.nvim_win_add_ns(0, ns) + + screen:expect { + grid = [[ + {1:123}4^5 | + {2:~ }|*8 + | + ]]} + + command 'split' + command 'only' + + screen:expect(noextmarks) + end) + + it('virt_text', function() + set_scoped_extmark(0, 0, { + virt_text = { { 'a', 'Comment' } }, + virt_text_pos = 'eol', + }) + set_scoped_extmark(0, 5, { + virt_text = { { 'b', 'Comment' } }, + virt_text_pos = 'inline', + }) + set_scoped_extmark(0, 1, { + virt_text = { { 'c', 'Comment' } }, + virt_text_pos = 'overlay', + }) + set_scoped_extmark(0, 1, { + virt_text = { { 'd', 'Comment' } }, + virt_text_pos = 'right_align', + }) + + screen:expect(noextmarks) + + api.nvim_win_add_ns(0, ns) + + screen:expect { + grid = [[ + 1{1:c}34^5{1:b} {1:a} {1:d}| + {2:~ }|*8 + | + ]]} + + command 'split' + command 'only' + + screen:expect(noextmarks) + end) + + it('virt_lines', function() + set_scoped_extmark(0, 0, { + virt_lines = { { { 'a', 'Comment' } } }, + }) + + screen:expect(noextmarks) + + api.nvim_win_add_ns(0, ns) + + screen:expect { + grid = [[ + 1234^5 | + {1:a} | + {2:~ }|*7 + | + ]]} + + command 'split' + command 'only' + + screen:expect(noextmarks) + end) + + it('redraws correctly with inline virt_text and wrapping', function() + set_scoped_extmark(0, 2, { + virt_text = {{ ('b'):rep(18), 'Comment' }}, + virt_text_pos = 'inline' + }) + + screen:expect(noextmarks) + + api.nvim_win_add_ns(0, ns) + + screen:expect { + grid = [[ + 12{1:bbbbbbbbbbbbbbbbbb}| + 34^5 | + {2:~ }|*7 + | + ]]} + + api.nvim_win_remove_ns(0, ns) + + screen:expect(noextmarks) + end) + + pending('sign_text', function() + -- TODO(altermo): The window signcolumn width is calculated wrongly (when `signcolumn=auto`) + -- This happens in function `win_redraw_signcols` on line containing `buf_meta_total(buf, kMTMetaSignText) > 0` + set_scoped_extmark(0, 0, { + sign_text = 'a', + sign_hl_group = 'Comment', + }) + + screen:expect(noextmarks) + + api.nvim_win_add_ns(0, ns) + + screen:expect { + grid = [[ + a 1234^5 | + {2:~ }|*8 + | + ]]} + + command 'split' + command 'only' + + screen:expect(noextmarks) + end) + + it('statuscolumn hl group', function() + local attrs = screen:get_default_attr_ids() + table.insert(attrs, { + foreground = Screen.colors.Brown, + }) + screen:set_default_attr_ids(attrs) + + set_scoped_extmark(0, 0, { + number_hl_group='comment', + }) + set_scoped_extmark(0, 0, { + line_hl_group='comment', + }) + + command 'set number' + + screen:expect { + grid = [[ + {3: 1 }1234^5 | + {2:~ }|*8 + | + ]]} + + api.nvim_win_add_ns(0, ns) + + screen:expect { + grid = [[ + {1: 1 1234^5 }| + {2:~ }|*8 + | + ]]} + + command 'split' + command 'only' + + screen:expect { + grid = [[ + {3: 1 }1234^5 | + {2:~ }|*8 + | + ]]} + end) + + it('spell', function() + local attrs = screen:get_default_attr_ids() + table.insert(attrs, { + special = Screen.colors.Red, undercurl = true + }) + screen:set_default_attr_ids(attrs) + api.nvim_buf_set_lines(0,0,-1,true,{'aa'}) + + set_scoped_extmark(0, 0, { + spell=true, + end_col=2, + }) + + command 'set spelloptions=noplainbuffer' + command 'set spell' + command 'syntax off' + + screen:expect { + grid = [[ + a^a | + {2:~ }|*8 + | + ]]} + + api.nvim_win_add_ns(0, ns) + + screen:expect { + grid = [[ + {3:a^a} | + {2:~ }|*8 + | + ]]} + + command 'split' + command 'only' + + screen:expect { + grid = [[ + a^a | + {2:~ }|*8 + | + ]]} + end) + + it('url', function() + local url = 'https://example.com' + local attrs = screen:get_default_attr_ids() + table.insert(attrs, { + url = url, + }) + screen:set_default_attr_ids(attrs) + + set_scoped_extmark(0, 0, { + end_col=3, + url=url, + }) + + screen:expect(noextmarks) + + api.nvim_win_add_ns(0, ns) + + screen:expect { + grid = [[ + {3:123}4^5 | + {2:~ }|*8 + | + ]]} + + command 'split' + command 'only' + + screen:expect(noextmarks) + end) + + it('change extmarks scoped option', function() + local id = set_scoped_extmark(0, 0, { + hl_group = 'Comment', + end_col = 3, + }) + + api.nvim_win_add_ns(0, ns) + + screen:expect { + grid = [[ + {1:123}4^5 | + {2:~ }|*8 + | + ]]} + + command 'split' + command 'only' + + screen:expect(noextmarks) + + api.nvim_buf_set_extmark(0, ns, 0, 0, { + id = id, + hl_group = 'Comment', + end_col = 3, + scoped = false, + }) + + screen:expect { + grid = [[ + {1:123}4^5 | + {2:~ }|*8 + | + ]]} + + api.nvim_buf_set_extmark(0, ns, 0, 0, { + id = id, + hl_group = 'Comment', + end_col = 3, + scoped = true, + }) + + screen:expect(noextmarks) + end) + + it('change namespace scope', function() + set_scoped_extmark(0, 0, { + hl_group = 'Comment', + end_col = 3, + }) + + eq(true, api.nvim_win_add_ns(0, ns)) + eq({ ns }, api.nvim_win_get_ns(0)) + + screen:expect { + grid = [[ + {1:123}4^5 | + {2:~ }|*8 + | + ]]} + + command 'split' + command 'only' + eq({}, api.nvim_win_get_ns(0)) + + screen:expect(noextmarks) + + eq(true, api.nvim_win_add_ns(0, ns)) + eq({ ns }, api.nvim_win_get_ns(0)) + + screen:expect { + grid = [[ + {1:123}4^5 | + {2:~ }|*8 + | + ]]} + + eq(true, api.nvim_win_remove_ns(0, ns)) + eq({}, api.nvim_win_get_ns(0)) + + screen:expect(noextmarks) + end) end) diff --git a/test/functional/ui/diff_spec.lua b/test/functional/ui/diff_spec.lua index 92b7235885..e0dfde35f2 100644 --- a/test/functional/ui/diff_spec.lua +++ b/test/functional/ui/diff_spec.lua @@ -9,7 +9,9 @@ local write_file = helpers.write_file local dedent = helpers.dedent local exec = helpers.exec local eq = helpers.eq -local meths = helpers.meths +local api = helpers.api + +before_each(clear) describe('Diff mode screen', function() local fname = 'Xtest-functional-diff-screen-1' @@ -21,7 +23,6 @@ describe('Diff mode screen', function() end setup(function() - clear() os.remove(fname) os.remove(fname_2) end) @@ -32,7 +33,6 @@ describe('Diff mode screen', function() end) before_each(function() - clear() feed(':e ' .. fname_2 .. '<cr>') feed(':vnew ' .. fname .. '<cr>') feed(':diffthis<cr>') @@ -41,21 +41,21 @@ describe('Diff mode screen', function() screen = Screen.new(40, 16) screen:attach() screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGray}, - [2] = {background = Screen.colors.LightCyan1, bold = true, foreground = Screen.colors.Blue1}, - [3] = {reverse = true}, - [4] = {background = Screen.colors.LightBlue}, - [5] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey}, - [6] = {bold = true, foreground = Screen.colors.Blue1}, - [7] = {bold = true, reverse = true}, - [8] = {bold = true, background = Screen.colors.Red}, - [9] = {background = Screen.colors.LightMagenta}, + [1] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGray }, + [2] = { background = Screen.colors.LightCyan1, bold = true, foreground = Screen.colors.Blue1 }, + [3] = { reverse = true }, + [4] = { background = Screen.colors.LightBlue }, + [5] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey }, + [6] = { bold = true, foreground = Screen.colors.Blue1 }, + [7] = { bold = true, reverse = true }, + [8] = { bold = true, background = Screen.colors.Red }, + [9] = { background = Screen.colors.LightMagenta }, }) end) it('Add a line in beginning of file 2', function() - write_file(fname, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n", false) - write_file(fname_2, "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n", false) + write_file(fname, '1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n', false) + write_file(fname_2, '0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n', false) reread() feed(':set diffopt=filler<cr>') @@ -68,12 +68,7 @@ describe('Diff mode screen', function() {1: }5 │{1: }5 | {1: }6 │{1: }6 | {1:+ }{5:+-- 4 lines: 7···}│{1:+ }{5:+-- 4 lines: 7··}| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*6 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt=filler | ]]) @@ -88,23 +83,18 @@ describe('Diff mode screen', function() {1: }5 │{1: }5 | {1: }6 │{1: }6 | {1:+ }{5:+-- 4 lines: 7···}│{1:+ }{5:+-- 4 lines: 7··}| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*6 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt+=internal | ]]) end) it('Add a line in beginning of file 1', function() - write_file(fname, "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n", false) - write_file(fname_2, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n", false) + write_file(fname, '0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n', false) + write_file(fname_2, '1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n', false) reread() - feed(":set diffopt=filler<cr>") + feed(':set diffopt=filler<cr>') screen:expect([[ {1: }{4:^0 }│{1: }{2:-----------------}| {1: }1 │{1: }1 | @@ -114,17 +104,12 @@ describe('Diff mode screen', function() {1: }5 │{1: }5 | {1: }6 │{1: }6 | {1:+ }{5:+-- 4 lines: 7···}│{1:+ }{5:+-- 4 lines: 7··}| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*6 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt=filler | ]]) - feed(":set diffopt+=internal<cr>") + feed(':set diffopt+=internal<cr>') screen:expect([[ {1: }{4:^0 }│{1: }{2:-----------------}| {1: }1 │{1: }1 | @@ -134,23 +119,18 @@ describe('Diff mode screen', function() {1: }5 │{1: }5 | {1: }6 │{1: }6 | {1:+ }{5:+-- 4 lines: 7···}│{1:+ }{5:+-- 4 lines: 7··}| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*6 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt+=internal | ]]) end) it('Add a line at the end of file 2', function() - write_file(fname, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n", false) - write_file(fname_2, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n", false) + write_file(fname, '1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n', false) + write_file(fname_2, '1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n', false) reread() - feed(":set diffopt=filler<cr>") + feed(':set diffopt=filler<cr>') screen:expect([[ {1:+ }{5:^+-- 4 lines: 1···}│{1:+ }{5:+-- 4 lines: 1··}| {1: }5 │{1: }5 | @@ -160,17 +140,12 @@ describe('Diff mode screen', function() {1: }9 │{1: }9 | {1: }10 │{1: }10 | {1: }{2:------------------}│{1: }{4:11 }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*6 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt=filler | ]]) - feed(":set diffopt+=internal<cr>") + feed(':set diffopt+=internal<cr>') screen:expect([[ {1:+ }{5:^+-- 4 lines: 1···}│{1:+ }{5:+-- 4 lines: 1··}| {1: }5 │{1: }5 | @@ -180,12 +155,7 @@ describe('Diff mode screen', function() {1: }9 │{1: }9 | {1: }10 │{1: }10 | {1: }{2:------------------}│{1: }{4:11 }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*6 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt+=internal | ]]) @@ -205,11 +175,11 @@ describe('Diff mode screen', function() end) it('Add a line at the end of file 1', function() - write_file(fname, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n", false) - write_file(fname_2, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n", false) + write_file(fname, '1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n', false) + write_file(fname_2, '1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n', false) reread() - feed(":set diffopt=filler<cr>") + feed(':set diffopt=filler<cr>') screen:expect([[ {1:+ }{5:^+-- 4 lines: 1···}│{1:+ }{5:+-- 4 lines: 1··}| {1: }5 │{1: }5 | @@ -219,17 +189,12 @@ describe('Diff mode screen', function() {1: }9 │{1: }9 | {1: }10 │{1: }10 | {1: }{4:11 }│{1: }{2:-----------------}| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*6 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt=filler | ]]) - feed(":set diffopt+=internal<cr>") + feed(':set diffopt+=internal<cr>') screen:expect([[ {1:+ }{5:^+-- 4 lines: 1···}│{1:+ }{5:+-- 4 lines: 1··}| {1: }5 │{1: }5 | @@ -239,12 +204,7 @@ describe('Diff mode screen', function() {1: }9 │{1: }9 | {1: }10 │{1: }10 | {1: }{4:11 }│{1: }{2:-----------------}| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*6 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt+=internal | ]]) @@ -264,8 +224,8 @@ describe('Diff mode screen', function() end) it('Add a line in the middle of file 2, remove on at the end of file 1', function() - write_file(fname, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n", false) - write_file(fname_2, "1\n2\n3\n4\n4\n5\n6\n7\n8\n9\n10\n", false) + write_file(fname, '1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n', false) + write_file(fname_2, '1\n2\n3\n4\n4\n5\n6\n7\n8\n9\n10\n', false) reread() feed(':set diffopt=filler<cr>') @@ -282,8 +242,7 @@ describe('Diff mode screen', function() {1: }9 │{1: }9 | {1: }10 │{1: }10 | {1: }{4:11 }│{1: }{2:-----------------}| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*2 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt=filler | ]]) @@ -302,16 +261,15 @@ describe('Diff mode screen', function() {1: }9 │{1: }9 | {1: }10 │{1: }10 | {1: }{4:11 }│{1: }{2:-----------------}| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*2 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt+=internal | ]]) end) it('Add a line in the middle of file 1, remove on at the end of file 2', function() - write_file(fname, "1\n2\n3\n4\n4\n5\n6\n7\n8\n9\n10\n", false) - write_file(fname_2, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n", false) + write_file(fname, '1\n2\n3\n4\n4\n5\n6\n7\n8\n9\n10\n', false) + write_file(fname_2, '1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n', false) reread() feed(':set diffopt=filler<cr>') @@ -328,8 +286,7 @@ describe('Diff mode screen', function() {1: }9 │{1: }9 | {1: }10 │{1: }10 | {1: }{2:------------------}│{1: }{4:11 }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*2 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt=filler | ]]) @@ -348,8 +305,7 @@ describe('Diff mode screen', function() {1: }9 │{1: }9 | {1: }10 │{1: }10 | {1: }{2:------------------}│{1: }{4:11 }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*2 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt+=internal | ]]) @@ -567,7 +523,7 @@ int main(int argc, char **argv) it('internal', function() reread() - feed(":set diffopt=internal,filler<cr>") + feed(':set diffopt=internal,filler<cr>') screen:expect([[ {1: }^def finalize(value│{1: }def finalize(valu| {1: } │{1: } | @@ -578,11 +534,7 @@ int main(int argc, char **argv) {1: }{2:------------------}│{1: }{4: values.each do }| {1: } v.finalize │{1: } v.finalize | {1: } end │{1: } end | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*5 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt=internal,filler | ]]) @@ -601,11 +553,7 @@ int main(int argc, char **argv) {1: } values.each do |│{1: } values.each do | {1: } v.finalize │{1: } v.finalize | {1: } end │{1: } end | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*5 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| | ]]) @@ -625,11 +573,7 @@ int main(int argc, char **argv) {1: } values.each do |│{1: } values.each do | {1: } v.finalize │{1: } v.finalize | {1: } end │{1: } end | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*5 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| : | ]]) @@ -637,26 +581,14 @@ int main(int argc, char **argv) end) it('Diff the same file', function() - write_file(fname, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n", false) - write_file(fname_2, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n", false) + write_file(fname, '1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n', false) + write_file(fname_2, '1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n', false) reread() feed(':set diffopt=filler<cr>') screen:expect([[ {1:+ }{5:^+-- 10 lines: 1···}│{1:+ }{5:+-- 10 lines: 1··}| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*13 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt=filler | ]]) @@ -664,45 +596,21 @@ int main(int argc, char **argv) feed(':set diffopt+=internal<cr>') screen:expect([[ {1:+ }{5:^+-- 10 lines: 1···}│{1:+ }{5:+-- 10 lines: 1··}| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*13 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt+=internal | ]]) end) it('Diff an empty file', function() - write_file(fname, "", false) - write_file(fname_2, "", false) + write_file(fname, '', false) + write_file(fname_2, '', false) reread() feed(':set diffopt=filler<cr>') screen:expect([[ {1:- }^ │{1:- } | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*13 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt=filler | ]]) @@ -710,27 +618,15 @@ int main(int argc, char **argv) feed(':set diffopt+=internal<cr>') screen:expect([[ {1:- }^ │{1:- } | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*13 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt+=internal | ]]) end) it('diffopt+=icase', function() - write_file(fname, "a\nb\ncd\n", false) - write_file(fname_2, "A\nb\ncDe\n", false) + write_file(fname, 'a\nb\ncd\n', false) + write_file(fname_2, 'A\nb\ncDe\n', false) reread() feed(':set diffopt=filler,icase<cr>') @@ -738,17 +634,7 @@ int main(int argc, char **argv) {1: }^a │{1: }A | {1: }b │{1: }b | {1: }{9:cd }│{1: }{9:cD}{8:e}{9: }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*11 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt=filler,icase | ]]) @@ -758,17 +644,7 @@ int main(int argc, char **argv) {1: }^a │{1: }A | {1: }b │{1: }b | {1: }{9:cd }│{1: }{9:cD}{8:e}{9: }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*11 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt+=internal | ]]) @@ -778,7 +654,8 @@ int main(int argc, char **argv) setup(function() local f1 = 'int main()\n{\n printf("Hello, World!");\n return 0;\n}\n' write_file(fname, f1, false) - local f2 = 'int main()\n{\n if (0)\n {\n printf("Hello, World!");\n return 0;\n }\n}\n' + local f2 = + 'int main()\n{\n if (0)\n {\n printf("Hello, World!");\n return 0;\n }\n}\n' write_file(fname_2, f2, false) feed(':diffupdate!<cr>') end) @@ -795,12 +672,7 @@ int main(int argc, char **argv) {1: } return 0; │{1: } return 0; | {1: }{2:------------------}│{1: }{4: } }| {1: }} │{1: }} | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*6 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt=filler,iwhite | ]]) @@ -818,12 +690,7 @@ int main(int argc, char **argv) {1: } return 0; │{1: } return 0; | {1: }{2:------------------}│{1: }{4: } }| {1: }} │{1: }} | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*6 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt=filler,iwhite,internal | ]]) @@ -842,19 +709,12 @@ int main(int argc, char **argv) feed(':set diffopt=internal,filler,iblank<cr>') screen:expect([[ {1: }^a │{1: }a | - {1: }{4: }│{1: }{2:-----------------}| - {1: }{4: }│{1: }{2:-----------------}| + {1: }{4: }│{1: }{2:-----------------}|*2 {1: }cd │{1: }cd | {1: }ef │{1: } | {1: }{8:xxx}{9: }│{1: }ef | {6:~ }│{1: }{8:yyy}{9: }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*7 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt=internal,filler,iblank | ]]) @@ -871,14 +731,7 @@ int main(int argc, char **argv) {1: }cd │{1: }ef | {1: }ef │{1: }{8:yyy}{9: }| {1: }{8:xxx}{9: }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*8 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| : | ]]) @@ -895,14 +748,7 @@ int main(int argc, char **argv) {1: }cd │{1: }ef | {1: }ef │{1: }{8:yyy}{9: }| {1: }{8:xxx}{9: }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*8 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| : | ]]) @@ -919,14 +765,7 @@ int main(int argc, char **argv) {1: }cd │{1: }ef | {1: }ef │{1: }{8:yyy}{9: }| {1: }{8:xxx}{9: }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*8 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| : | ]]) @@ -953,12 +792,7 @@ int main(int argc, char **argv) {1: }foo │{1: }foo | {1: }{2:------------------}│{1: }{4: }| {1: }bar │{1: }bar | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*6 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| : | ]]) @@ -977,12 +811,7 @@ int main(int argc, char **argv) {1: }foo │{1: }foo | {1: }{2:------------------}│{1: }{4: }| {1: }bar │{1: }bar | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*6 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| : | ]]) @@ -993,7 +822,9 @@ int main(int argc, char **argv) -- This was scrolling for 'cursorbind' but 'scrollbind' is more important it('scrolling works correctly vim-patch:8.2.5155', function() screen:try_resize(40, 12) - write_file(fname, dedent([[ + write_file( + fname, + dedent([[ line 1 line 2 line 3 @@ -1007,8 +838,12 @@ int main(int argc, char **argv) // Common block // two // containing - // four lines]]), false) - write_file(fname_2, dedent([[ + // four lines]]), + false + ) + write_file( + fname_2, + dedent([[ line 1 line 2 line 3 @@ -1041,7 +876,9 @@ int main(int argc, char **argv) // Common block // two // containing - // four lines]]), false) + // four lines]]), + false + ) reread() feed('<C-W><C-W>jjjj') @@ -1116,9 +953,7 @@ int main(int argc, char **argv) {1: } ui.setupUI(Mai│{1: } ui.setupUI(Ma| {1: } MainWindow.sho│{1: } MainWindow.sh| {1: } sys.exit(app.e│{1: } sys.exit(app.| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*3 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt=internal,filler | ]]) @@ -1137,9 +972,7 @@ int main(int argc, char **argv) {1: } ui.setupUI(Mai│{1: } ui.setupUI(Ma| {1: } MainWindow.sho│{1: } MainWindow.sh| {1: } ^sys.exit(app.e│{1: } sys.exit(app.| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*3 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt+=linematch:20 | ]]) @@ -1163,17 +996,7 @@ ccca]] {1: }^DDD │{1: }DDD | {1: }{2:------------------}│{1: }{4:AAA }| {1: }{8:_a}{9:a }│{1: }{8:ccc}{9:a }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*11 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| | ]]) @@ -1182,17 +1005,7 @@ ccca]] {1: }^DDD │{1: }DDD | {1: }{8:_}{9:aa }│{1: }{8:A}{9:AA }| {1: }{2:------------------}│{1: }{4:ccca }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*11 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt+=icase | ]]) @@ -1212,53 +1025,38 @@ AAAB]] it('diffopt+=linematch:20,iwhiteall', function() reread() feed(':set diffopt=internal,filler,linematch:20<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: }^BB │{1: }BB | {1: }{9: AA}{8:A}{9: }│{1: }{9: AA}{8:B}{9: }| {1: }{2:------------------}│{1: }{4:AAAB }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*11 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| | - ]]} + ]], + } feed(':set diffopt+=iwhiteall<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: }^BB │{1: }BB | {1: }{2:------------------}│{1: }{4: AAB }| {1: }{9: AAA }│{1: }{9:AAA}{8:B}{9: }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*11 {7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }| :set diffopt+=iwhiteall | - ]]} + ]], + } end) end) it('redraws with a change to non-current buffer', function() - write_file(fname, "aaa\nbbb\nccc\n\nxx", false) - write_file(fname_2, "aaa\nbbb\nccc\n\nyy", false) + write_file(fname, 'aaa\nbbb\nccc\n\nxx', false) + write_file(fname_2, 'aaa\nbbb\nccc\n\nyy', false) reread() - local buf = meths.get_current_buf() + local buf = api.nvim_get_current_buf() command('botright new') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: }aaa │{1: }aaa | {1: }bbb │{1: }bbb | {1: }ccc │{1: }ccc | @@ -1267,18 +1065,15 @@ AAAB]] {6:~ }│{6:~ }| {3:<onal-diff-screen-1 <l-diff-screen-1.2 }| ^ | - {6:~ }| - {6:~ }| - {6:~ }| - {6:~ }| - {6:~ }| - {6:~ }| + {6:~ }|*6 {7:[No Name] }| :e | - ]]} + ]], + } - meths.buf_set_lines(buf, 1, 2, true, {'BBB'}) - screen:expect{grid=[[ + api.nvim_buf_set_lines(buf, 1, 2, true, { 'BBB' }) + screen:expect { + grid = [[ {1: }aaa │{1: }aaa | {1: }{8:BBB}{9: }│{1: }{8:bbb}{9: }| {1: }ccc │{1: }ccc | @@ -1287,24 +1082,21 @@ AAAB]] {6:~ }│{6:~ }| {3:<-diff-screen-1 [+] <l-diff-screen-1.2 }| ^ | - {6:~ }| - {6:~ }| - {6:~ }| - {6:~ }| - {6:~ }| - {6:~ }| + {6:~ }|*6 {7:[No Name] }| :e | - ]]} + ]], + } end) - it('redraws with a change current buffer in another window', function() - write_file(fname, "aaa\nbbb\nccc\n\nxx", false) - write_file(fname_2, "aaa\nbbb\nccc\n\nyy", false) + it('redraws with a change current buffer in another window', function() + write_file(fname, 'aaa\nbbb\nccc\n\nxx', false) + write_file(fname_2, 'aaa\nbbb\nccc\n\nyy', false) reread() - local buf = meths.get_current_buf() + local buf = api.nvim_get_current_buf() command('botright split | diffoff') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: }aaa │{1: }aaa | {1: }bbb │{1: }bbb | {1: }ccc │{1: }ccc | @@ -1317,14 +1109,15 @@ AAAB]] ccc | | xx | - {6:~ }| - {6:~ }| + {6:~ }|*2 {7:Xtest-functional-diff-screen-1 }| :e | - ]]} + ]], + } - meths.buf_set_lines(buf, 1, 2, true, {'BBB'}) - screen:expect{grid=[[ + api.nvim_buf_set_lines(buf, 1, 2, true, { 'BBB' }) + screen:expect { + grid = [[ {1: }aaa │{1: }aaa | {1: }{8:BBB}{9: }│{1: }{8:bbb}{9: }| {1: }ccc │{1: }ccc | @@ -1337,38 +1130,41 @@ AAAB]] ccc | | xx | - {6:~ }| - {6:~ }| + {6:~ }|*2 {7:Xtest-functional-diff-screen-1 [+] }| :e | - ]]} + ]], + } end) end) it('win_update redraws lines properly', function() local screen - clear() screen = Screen.new(50, 10) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [3] = {background = Screen.colors.Red, foreground = Screen.colors.Grey100, special = Screen.colors.Yellow}, - [4] = {bold = true, foreground = Screen.colors.SeaGreen4}, - [5] = {special = Screen.colors.Yellow}, - [6] = {special = Screen.colors.Yellow, bold = true, foreground = Screen.colors.SeaGreen4}, - [7] = {foreground = Screen.colors.Grey0, background = Screen.colors.Grey100}, - [8] = {foreground = Screen.colors.Gray90, background = Screen.colors.Grey100}, - [9] = {foreground = tonumber('0x00000c'), background = Screen.colors.Grey100}, - [10] = {background = Screen.colors.Grey100, bold = true, foreground = tonumber('0xe5e5ff')}, - [11] = {background = Screen.colors.Grey100, bold = true, foreground = tonumber('0x2b8452')}, - [12] = {bold = true, reverse = true}, - [13] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGray}, - [14] = {reverse = true}, - [15] = {background = Screen.colors.LightBlue}, - [16] = {background = Screen.colors.LightCyan1, bold = true, foreground = Screen.colors.Blue1}, - [17] = {bold = true, background = Screen.colors.Red}, - [18] = {background = Screen.colors.LightMagenta}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [3] = { + background = Screen.colors.Red, + foreground = Screen.colors.Grey100, + special = Screen.colors.Yellow, + }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [5] = { special = Screen.colors.Yellow }, + [6] = { special = Screen.colors.Yellow, bold = true, foreground = Screen.colors.SeaGreen4 }, + [7] = { foreground = Screen.colors.Grey0, background = Screen.colors.Grey100 }, + [8] = { foreground = Screen.colors.Gray90, background = Screen.colors.Grey100 }, + [9] = { foreground = tonumber('0x00000c'), background = Screen.colors.Grey100 }, + [10] = { background = Screen.colors.Grey100, bold = true, foreground = tonumber('0xe5e5ff') }, + [11] = { background = Screen.colors.Grey100, bold = true, foreground = tonumber('0x2b8452') }, + [12] = { bold = true, reverse = true }, + [13] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGray }, + [14] = { reverse = true }, + [15] = { background = Screen.colors.LightBlue }, + [16] = { background = Screen.colors.LightCyan1, bold = true, foreground = Screen.colors.Blue1 }, + [17] = { bold = true, background = Screen.colors.Red }, + [18] = { background = Screen.colors.LightMagenta }, }) insert([[ @@ -1378,18 +1174,18 @@ it('win_update redraws lines properly', function() 2 1a ]]) - command("vnew left") + command('vnew left') insert([[ 2 2a 2b ]]) - command("windo diffthis") - command("windo 1") - screen:expect{grid=[[ + command('windo diffthis') + command('windo 1') + screen:expect { + grid = [[ {13: }{16:-----------------------}│{13: }{15:^1 }| - {13: }{16:-----------------------}│{13: }{15: }| - {13: }{16:-----------------------}│{13: }{15: }| + {13: }{16:-----------------------}│{13: }{15: }|*2 {13: }2 │{13: }2 | {13: }{17:2}{18:a }│{13: }{17:1}{18:a }| {13: }{15:2b }│{13: }{16:----------------------}| @@ -1397,13 +1193,15 @@ it('win_update redraws lines properly', function() {1:~ }│{1:~ }| {14:left [+] }{12:[No Name] [+] }| | - ]]} + ]], + } feed('<C-e>') feed('<C-e>') feed('<C-y>') feed('<C-y>') feed('<C-y>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {13: }{16:-----------------------}│{13: }{15:1 }| {13: }{16:-----------------------}│{13: }{15: }| {13: }{16:-----------------------}│{13: }{15:^ }| @@ -1414,26 +1212,26 @@ it('win_update redraws lines properly', function() {1:~ }│{1:~ }| {14:left [+] }{12:[No Name] [+] }| | - ]]} + ]], + } end) -- oldtest: Test_diff_rnu() it('diff updates line numbers below filler lines', function() - clear() local screen = Screen.new(40, 14) screen:attach() screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGray}, - [2] = {background = Screen.colors.LightCyan1, bold = true, foreground = Screen.colors.Blue1}, - [3] = {reverse = true}, - [4] = {background = Screen.colors.LightBlue}, - [5] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey}, - [6] = {bold = true, foreground = Screen.colors.Blue1}, - [7] = {bold = true, reverse = true}, - [8] = {bold = true, background = Screen.colors.Red}, - [9] = {background = Screen.colors.LightMagenta}, - [10] = {bold = true, foreground = Screen.colors.Brown}, - [11] = {foreground = Screen.colors.Brown}, + [1] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGray }, + [2] = { background = Screen.colors.LightCyan1, bold = true, foreground = Screen.colors.Blue1 }, + [3] = { reverse = true }, + [4] = { background = Screen.colors.LightBlue }, + [5] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey }, + [6] = { bold = true, foreground = Screen.colors.Blue1 }, + [7] = { bold = true, reverse = true }, + [8] = { bold = true, background = Screen.colors.Red }, + [9] = { background = Screen.colors.LightMagenta }, + [10] = { bold = true, foreground = Screen.colors.Brown }, + [11] = { foreground = Screen.colors.Brown }, }) exec([[ call setline(1, ['a', 'a', 'a', 'y', 'b', 'b', 'b', 'b', 'b']) @@ -1447,8 +1245,7 @@ it('diff updates line numbers below filler lines', function() {1: }a │{11: 1 }a | {1: }a │{11: 2 }a | {1: }{8:x}{9: }│{11: 3 }{8:y}{9: }| - {1: }{4:x }│{11: }{2:----------------}| - {1: }{4:x }│{11: }{2:----------------}| + {1: }{4:x }│{11: }{2:----------------}|*2 {1: }b │{11: 4 }b | {1: }b │{11: 5 }b | {1: }b │{11: 6 }b | @@ -1464,8 +1261,7 @@ it('diff updates line numbers below filler lines', function() {1: }a │{10:2 }^a | {1: }a │{11: 1 }a | {1: }{8:x}{9: }│{11: 2 }{8:y}{9: }| - {1: }{4:x }│{11: }{2:----------------}| - {1: }{4:x }│{11: }{2:----------------}| + {1: }{4:x }│{11: }{2:----------------}|*2 {1: }b │{11: 3 }b | {1: }b │{11: 4 }b | {1: }b │{11: 5 }b | @@ -1481,8 +1277,7 @@ it('diff updates line numbers below filler lines', function() {1: }a │{11: 1 }a | {1: }a │{10:3 }^a | {1: }{8:x}{9: }│{11: 1 }{8:y}{9: }| - {1: }{4:x }│{11: }{2:----------------}| - {1: }{4:x }│{11: }{2:----------------}| + {1: }{4:x }│{11: }{2:----------------}|*2 {1: }b │{11: 2 }b | {1: }b │{11: 3 }b | {1: }b │{11: 4 }b | @@ -1496,18 +1291,17 @@ end) -- oldtest: Test_diff_with_scroll_and_change() it('Align the filler lines when changing text in diff mode', function() - clear() local screen = Screen.new(40, 20) screen:attach() screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.Gray}; - [2] = {background = Screen.colors.LightCyan, foreground = Screen.colors.Blue1, bold = true}; - [3] = {reverse = true}; - [4] = {background = Screen.colors.LightBlue}; - [5] = {background = Screen.colors.LightMagenta}; - [6] = {background = Screen.colors.Red, bold = true}; - [7] = {foreground = Screen.colors.Blue1, bold = true}; - [8] = {reverse = true, bold = true}; + [1] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.Gray }, + [2] = { background = Screen.colors.LightCyan, foreground = Screen.colors.Blue1, bold = true }, + [3] = { reverse = true }, + [4] = { background = Screen.colors.LightBlue }, + [5] = { background = Screen.colors.LightMagenta }, + [6] = { background = Screen.colors.Red, bold = true }, + [7] = { foreground = Screen.colors.Blue1, bold = true }, + [8] = { reverse = true, bold = true }, }) exec([[ call setline(1, range(1, 15)) @@ -1517,7 +1311,8 @@ it('Align the filler lines when changing text in diff mode', function() wincmd h exe "normal Gl5\<C-E>" ]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: }{2:------------------}│{1: }{4:6 }| {1: }{2:------------------}│{1: }{4:7 }| {1: }{2:------------------}│{1: }{4:8 }| @@ -1528,19 +1323,14 @@ it('Align the filler lines when changing text in diff mode', function() {1: }13 │{1: }13 | {1: }14 │{1: }14 | {1:- }1^5 │{1:- }15 | - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| + {7:~ }│{7:~ }|*8 {8:[No Name] [+] }{3:[No Name] [+] }| | - ]]} + ]], + } feed('ax<Esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: }{2:------------------}│{1: }{4:6 }| {1: }{2:------------------}│{1: }{4:7 }| {1: }{2:------------------}│{1: }{4:8 }| @@ -1551,19 +1341,14 @@ it('Align the filler lines when changing text in diff mode', function() {1: }13 │{1: }13 | {1: }14 │{1: }14 | {1: }{5:15}{6:^x}{5: }│{1: }{5:15 }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| + {7:~ }│{7:~ }|*8 {8:[No Name] [+] }{3:[No Name] [+] }| | - ]]} + ]], + } feed('<C-W>lay<Esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: }{2:-----------------}│{1: }{4:6 }| {1: }{2:-----------------}│{1: }{4:7 }| {1: }{2:-----------------}│{1: }{4:8 }| @@ -1574,52 +1359,41 @@ it('Align the filler lines when changing text in diff mode', function() {1: }13 │{1: }13 | {1: }14 │{1: }14 | {1: }{5:15}{6:x}{5: }│{1: }{5:15}{6:^y}{5: }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| + {7:~ }│{7:~ }|*8 {3:[No Name] [+] }{8:[No Name] [+] }| | - ]]} + ]], + } end) it("diff mode doesn't restore invalid 'foldcolumn' value #21647", function() - clear() local screen = Screen.new(60, 6) screen:set_default_attr_ids({ - [0] = {foreground = Screen.colors.Blue, bold = true}; + [0] = { foreground = Screen.colors.Blue, bold = true }, }) screen:attach() - eq('0', meths.get_option_value('foldcolumn', {})) + eq('0', api.nvim_get_option_value('foldcolumn', {})) command('diffsplit | bd') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) - eq('0', meths.get_option_value('foldcolumn', {})) + eq('0', api.nvim_get_option_value('foldcolumn', {})) end) -- oldtest: Test_diff_binary() it('diff mode works properly if file contains NUL bytes vim-patch:8.2.3925', function() - clear() local screen = Screen.new(40, 20) screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.Gray}; - [2] = {reverse = true}; - [3] = {background = Screen.colors.LightBlue}; - [4] = {background = Screen.colors.LightMagenta}; - [5] = {background = Screen.colors.Red, bold = true}; - [6] = {foreground = Screen.colors.Blue, bold = true}; - [7] = {background = Screen.colors.Red, foreground = Screen.colors.Blue, bold = true}; - [8] = {reverse = true, bold = true}; + [1] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.Gray }, + [2] = { reverse = true }, + [3] = { background = Screen.colors.LightBlue }, + [4] = { background = Screen.colors.LightMagenta }, + [5] = { background = Screen.colors.Red, bold = true }, + [6] = { foreground = Screen.colors.Blue, bold = true }, + [7] = { background = Screen.colors.Red, foreground = Screen.colors.Blue, bold = true }, + [8] = { reverse = true, bold = true }, }) screen:attach() exec([[ @@ -1641,17 +1415,7 @@ it('diff mode works properly if file contains NUL bytes vim-patch:8.2.3925', fun {1: }{5:E}{4: }│{1: }{5:e}{4: }| {1: }f │{1: }f | {1: }g │{1: }g | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*11 {8:[No Name] [+] }{2:[No Name] [+] }| | ]]) @@ -1667,17 +1431,7 @@ it('diff mode works properly if file contains NUL bytes vim-patch:8.2.3925', fun {1: }E │{1: }e | {1: }f │{1: }f | {1: }g │{1: }g | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*11 {8:[No Name] [+] }{2:[No Name] [+] }| | ]]) @@ -1693,17 +1447,7 @@ it('diff mode works properly if file contains NUL bytes vim-patch:8.2.3925', fun {1: }{5:E}{4: }│{1: }{5:e}{4: }| {1: }f │{1: }f | {1: }g │{1: }g | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*11 {8:[No Name] [+] }{2:[No Name] [+] }| | ]]) @@ -1719,18 +1463,36 @@ it('diff mode works properly if file contains NUL bytes vim-patch:8.2.3925', fun {1: }E │{1: }e | {1: }f │{1: }f | {1: }g │{1: }g | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*11 {8:[No Name] [+] }{2:[No Name] [+] }| | ]]) end) + +-- oldtest: Test_diff_breakindent_after_filler() +it("diff mode draws 'breakindent' correctly after filler lines", function() + local screen = Screen.new(45, 8) + screen:attach() + screen:set_default_attr_ids({ + [1] = { background = Screen.colors.Grey, foreground = Screen.colors.DarkBlue }, + [2] = { background = Screen.colors.LightBlue }, + [3] = { background = Screen.colors.LightCyan, bold = true, foreground = Screen.colors.Blue }, + [4] = { foreground = Screen.colors.Blue, bold = true }, + }) + exec([[ + set laststatus=0 diffopt+=followwrap breakindent breakindentopt=min:0 + call setline(1, ['a', ' ' .. repeat('c', 50)]) + vnew + call setline(1, ['a', 'b', ' ' .. repeat('c', 50)]) + windo diffthis + norm! G$ + ]]) + screen:expect([[ + {1: }a │{1: }a | + {1: }{2:b }│{1: }{3:--------------------}| + {1: } cccccccccccccccccc│{1: } cccccccccccccccccc|*2 + {1: } cccccccccccccc │{1: } ccccccccccccc^c | + {4:~ }│{4:~ }|*2 + | + ]]) +end) diff --git a/test/functional/ui/embed_spec.lua b/test/functional/ui/embed_spec.lua index 9729f65355..0445476780 100644 --- a/test/functional/ui/embed_spec.lua +++ b/test/functional/ui/embed_spec.lua @@ -1,56 +1,53 @@ -local uv = require'luv' +local uv = vim.uv local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') +local api = helpers.api local feed = helpers.feed local eq = helpers.eq local neq = helpers.neq local clear = helpers.clear local ok = helpers.ok -local funcs = helpers.funcs +local fn = helpers.fn local nvim_prog = helpers.nvim_prog local retry = helpers.retry +local write_file = helpers.write_file local function test_embed(ext_linegrid) local screen local function startup(...) - clear{args_rm={'--headless'}, args={...}} + clear { args_rm = { '--headless' }, args = { ... } } -- attach immediately after startup, for early UI screen = Screen.new(60, 8) - screen:attach{ext_linegrid=ext_linegrid} + screen:attach { ext_linegrid = ext_linegrid } screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [2] = {bold = true, foreground = Screen.colors.SeaGreen4}, - [3] = {bold = true, foreground = Screen.colors.Blue1}, - [4] = {bold = true, foreground = Screen.colors.Green}, - [5] = {bold = true, reverse = true}, + [1] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [2] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [3] = { bold = true, foreground = Screen.colors.Blue1 }, + [4] = { bold = true, foreground = Screen.colors.Green }, + [5] = { bold = true, reverse = true }, + [6] = { foreground = Screen.colors.NvimLightGrey3, background = Screen.colors.NvimDarkGrey3 }, + [7] = { foreground = Screen.colors.NvimDarkRed }, + [8] = { foreground = Screen.colors.NvimDarkCyan }, }) end it('can display errors', function() startup('--cmd', 'echoerr invalid+') screen:expect([[ - | - | - | - | - | - Error detected while processing pre-vimrc command line: | - E121: Undefined variable: invalid | - Press ENTER or type command to continue^ | + |*4 + {6: }| + {7:Error detected while processing pre-vimrc command line:} | + {7:E121: Undefined variable: invalid} | + {8:Press ENTER or type command to continue}^ | ]]) feed('<cr>') screen:expect([[ ^ | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*6 | ]]) end) @@ -61,36 +58,39 @@ local function test_embed(ext_linegrid) end startup('--cmd', 'echoerr "foo"', '--cmd', 'color default', '--cmd', 'echoerr "bar"') screen:expect([[ - | - | - | - {5: }| - Error detected while processing pre-vimrc command line: | - foo | - {1:bar} | - {4:Press ENTER or type command to continue}^ | + |*3 + {6: }| + {7:Error detected while processing pre-vimrc command line:} | + {7:foo} | + {7:bar} | + {8:Press ENTER or type command to continue}^ | ]]) end) it("doesn't erase output when setting Normal colors", function() startup('--cmd', 'echoerr "foo"', '--cmd', 'hi Normal guibg=Green', '--cmd', 'echoerr "bar"') - screen:expect{grid=[[ - | - | - | - | - Error detected while processing pre-vimrc command line: | - foo | - bar | - Press ENTER or type command to continue^ | - ]], condition=function() - eq(Screen.colors.Green, screen.default_colors.rgb_bg) - end} + screen:expect { + grid = [[ + |*3 + {6: }| + {7:Error detected while processing pre-vimrc command line:} | + {7:foo} | + {7:bar} | + {8:Press ENTER or type command to continue}^ | + ]], + condition = function() + eq(Screen.colors.Green, screen.default_colors.rgb_bg) + end, + } end) end -describe('--embed UI on startup (ext_linegrid=true)', function() test_embed(true) end) -describe('--embed UI on startup (ext_linegrid=false)', function() test_embed(false) end) +describe('--embed UI on startup (ext_linegrid=true)', function() + test_embed(true) +end) +describe('--embed UI on startup (ext_linegrid=false)', function() + test_embed(false) +end) describe('--embed UI', function() it('can pass stdin', function() @@ -99,43 +99,186 @@ describe('--embed UI', function() local writer = assert(uv.new_pipe(false)) writer:open(pipe.write) - clear {args_rm={'--headless'}, io_extra=pipe.read} + clear { args_rm = { '--headless' }, io_extra = pipe.read } -- attach immediately after startup, for early UI local screen = Screen.new(40, 8) - screen.rpc_async = true -- Avoid hanging. #24888 - screen:attach {stdin_fd=3} + screen.rpc_async = true -- Avoid hanging. #24888 + screen:attach { stdin_fd = 3 } screen:set_default_attr_ids { - [1] = {bold = true, foreground = Screen.colors.Blue1}; - [2] = {bold = true}; + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { bold = true }, } - writer:write "hello nvim\nfrom external input\n" - writer:shutdown(function() writer:close() end) + writer:write 'hello nvim\nfrom external input\n' + writer:shutdown(function() + writer:close() + end) - screen:expect{grid=[[ + screen:expect [[ ^hello nvim | from external input | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | - ]]} + ]] -- stdin (rpc input) still works feed 'o' - screen:expect{grid=[[ + screen:expect [[ hello nvim | ^ | from external input | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {2:-- INSERT --} | - ]]} + ]] + end) + + it('can pass stdin to -q - #17523', function() + write_file( + 'Xbadfile.c', + [[ + /* some file with an error */ + main() { + functionCall(arg; arg, arg); + return 666 + } + ]] + ) + finally(function() + os.remove('Xbadfile.c') + end) + + local pipe = assert(uv.pipe()) + + local writer = assert(uv.new_pipe(false)) + writer:open(pipe.write) + + clear { args_rm = { '--headless' }, args = { '-q', '-' }, io_extra = pipe.read } + + -- attach immediately after startup, for early UI + local screen = Screen.new(60, 8) + screen.rpc_async = true -- Avoid hanging. #24888 + screen:attach { stdin_fd = 3 } + screen:set_default_attr_ids { + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { bold = true }, + } + + writer:write [[Xbadfile.c:4:12: error: expected ';' before '}' token]] + writer:shutdown(function() + writer:close() + end) + + screen:expect [[ + /* some file with an error */ | + main() { | + functionCall(arg; arg, arg); | + return 66^6 | + } | + {1:~ }|*2 + (1 of 1): error: expected ';' before '}' token | + ]] + + -- stdin (rpc input) still works + feed 'A' + screen:expect [[ + /* some file with an error */ | + main() { | + functionCall(arg; arg, arg); | + return 666^ | + } | + {1:~ }|*2 + {2:-- INSERT --} | + ]] + + eq('-', api.nvim_get_option_value('errorfile', {})) + end) + + it('only sets background colors once even if overridden', function() + local screen, current, seen + local function handle_default_colors_set(_, _, rgb_bg, _, _, _) + seen[rgb_bg] = true + current = rgb_bg + end + local function startup(...) + seen = {} + current = nil + clear { args_rm = { '--headless' }, args = { ... } } + + -- attach immediately after startup, for early UI + screen = Screen.new(40, 8) + screen._handle_default_colors_set = handle_default_colors_set + screen:attach() + end + + startup() + screen:expect { + condition = function() + eq(16777215, current) + end, + } + eq({ [16777215] = true }, seen) + + -- NB: by accident how functional/helpers.lua currently handles the default color scheme, the + -- above is sufficient to test the behavior. But in case that workaround is removed, we need + -- a test with an explicit override like below, so do it to remain safe. + startup('--cmd', 'hi NORMAL guibg=#FF00FF') + screen:expect { + condition = function() + eq(16711935, current) + end, + } + eq({ [16711935] = true }, seen) -- we only saw the last one, despite 16777215 was set internally earlier + end) + + it('updates cwd of attached UI #21771', function() + clear { args_rm = { '--headless' } } + + local screen = Screen.new(40, 8) + screen:attach() + + screen:expect { + condition = function() + eq(helpers.paths.test_source_path, screen.pwd) + end, + } + + -- Change global cwd + helpers.command(string.format('cd %s/src/nvim', helpers.paths.test_source_path)) + + screen:expect { + condition = function() + eq(string.format('%s/src/nvim', helpers.paths.test_source_path), screen.pwd) + end, + } + + -- Split the window and change the cwd in the split + helpers.command('new') + helpers.command(string.format('lcd %s/test', helpers.paths.test_source_path)) + + screen:expect { + condition = function() + eq(string.format('%s/test', helpers.paths.test_source_path), screen.pwd) + end, + } + + -- Move to the original window + helpers.command('wincmd p') + + screen:expect { + condition = function() + eq(string.format('%s/src/nvim', helpers.paths.test_source_path), screen.pwd) + end, + } + + -- Change global cwd again + helpers.command(string.format('cd %s', helpers.paths.test_source_path)) + + screen:expect { + condition = function() + eq(helpers.paths.test_source_path, screen.pwd) + end, + } end) end) @@ -144,8 +287,18 @@ describe('--embed --listen UI', function() helpers.skip(helpers.is_os('win')) clear() local child_server = assert(helpers.new_pipename()) - funcs.jobstart({nvim_prog, '--embed', '--listen', child_server, '--clean'}) - retry(nil, nil, function() neq(nil, uv.fs_stat(child_server)) end) + fn.jobstart({ + nvim_prog, + '--embed', + '--listen', + child_server, + '--clean', + '--cmd', + 'colorscheme vim', + }) + retry(nil, nil, function() + neq(nil, uv.fs_stat(child_server)) + end) local child_session = helpers.connect(child_server) @@ -154,11 +307,15 @@ describe('--embed --listen UI', function() eq(2, #api_info) ok(api_info[1] > 2, 'channel_id > 2', api_info[1]) - child_session:request('nvim_exec2', [[ + child_session:request( + 'nvim_exec2', + [[ let g:evs = [] autocmd UIEnter * call add(g:evs, $"UIEnter:{v:event.chan}") autocmd VimEnter * call add(g:evs, "VimEnter") - ]], {}) + ]], + {} + ) -- VimEnter and UIEnter shouldn't be triggered until after attach local var_ok, var = child_session:request('nvim_get_var', 'evs') @@ -167,21 +324,22 @@ describe('--embed --listen UI', function() local child_screen = Screen.new(40, 6) child_screen:attach(nil, child_session) - child_screen:expect{grid=[[ + child_screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2:[No Name] 0,0-1 All}| | - ]], attr_ids={ - [1] = {foreground = Screen.colors.Blue, bold = true}; - [2] = {reverse = true, bold = true}; - }} + ]], + attr_ids = { + [1] = { foreground = Screen.colors.Blue, bold = true }, + [2] = { reverse = true, bold = true }, + }, + } -- VimEnter and UIEnter should now be triggered var_ok, var = child_session:request('nvim_get_var', 'evs') ok(var_ok) - eq({'VimEnter', ('UIEnter:%d'):format(api_info[1])}, var) + eq({ 'VimEnter', ('UIEnter:%d'):format(api_info[1]) }, var) end) end) diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua index 2902b4a4a5..cdb3b79963 100644 --- a/test/functional/ui/float_spec.lua +++ b/test/functional/ui/float_spec.lua @@ -1,6 +1,5 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local global_helpers = require('test.helpers') local os = require('os') local clear, feed = helpers.clear, helpers.feed local assert_alive = helpers.assert_alive @@ -12,14 +11,15 @@ local expect = helpers.expect local exec = helpers.exec local exec_lua = helpers.exec_lua local insert = helpers.insert -local meths = helpers.meths -local curbufmeths = helpers.curbufmeths -local funcs = helpers.funcs +local api = helpers.api +local fn = helpers.fn local run = helpers.run local pcall_err = helpers.pcall_err -local tbl_contains = global_helpers.tbl_contains -local curbuf, curwin, curtab = helpers.curbuf, helpers.curwin, helpers.curtab -local NIL = helpers.NIL +local tbl_contains = vim.tbl_contains +local curbuf = helpers.api.nvim_get_current_buf +local curwin = helpers.api.nvim_get_current_win +local curtab = helpers.api.nvim_get_current_tabpage +local NIL = vim.NIL describe('float window', function() before_each(function() @@ -31,36 +31,36 @@ describe('float window', function() -- Create three windows and test that ":wincmd <direction>" changes to the -- first window, if the previous window is invalid. command('split') - meths.open_win(0, true, {width=10, height=10, relative='editor', row=0, col=0}) - eq(1002, funcs.win_getid()) - eq('editor', meths.win_get_config(1002).relative) + api.nvim_open_win(0, true, {width=10, height=10, relative='editor', row=0, col=0}) + eq(1002, fn.win_getid()) + eq('editor', api.nvim_win_get_config(1002).relative) command([[ call nvim_win_close(1001, v:false) wincmd j ]]) - eq(1000, funcs.win_getid()) + eq(1000, fn.win_getid()) end) it('win_execute() should work' , function() - local buf = meths.create_buf(false, false) - meths.buf_set_lines(buf, 0, -1, true, {'the floatwin', 'abc', 'def'}) - local win = meths.open_win(buf, false, {relative='win', width=16, height=1, row=0, col=10}) - local line = funcs.win_execute(win, 'echo getline(1)') + local buf = api.nvim_create_buf(false, false) + api.nvim_buf_set_lines(buf, 0, -1, true, {'the floatwin', 'abc', 'def'}) + local win = api.nvim_open_win(buf, false, {relative='win', width=16, height=1, row=0, col=10}) + local line = fn.win_execute(win, 'echo getline(1)') eq('\nthe floatwin', line) - eq('\n1', funcs.win_execute(win, 'echo line(".",'..win.id..')')) - eq('\n3', funcs.win_execute(win, 'echo line("$",'..win.id..')')) - eq('\n0', funcs.win_execute(win, 'echo line("$", 123456)')) - funcs.win_execute(win, 'bwipe!') + eq('\n1', fn.win_execute(win, 'echo line(".",'..win..')')) + eq('\n3', fn.win_execute(win, 'echo line("$",'..win..')')) + eq('\n0', fn.win_execute(win, 'echo line("$", 123456)')) + fn.win_execute(win, 'bwipe!') end) it("win_execute() call commands that are not allowed when 'hidden' is not set" , function() command('set nohidden') - local buf = meths.create_buf(false, false) - meths.buf_set_lines(buf, 0, -1, true, {'the floatwin'}) - local win = meths.open_win(buf, true, {relative='win', width=16, height=1, row=0, col=10}) - eq('Vim(close):E37: No write since last change (add ! to override)', pcall_err(funcs.win_execute, win, 'close')) - eq('Vim(bdelete):E89: No write since last change for buffer 2 (add ! to override)', pcall_err(funcs.win_execute, win, 'bdelete')) - funcs.win_execute(win, 'bwipe!') + local buf = api.nvim_create_buf(false, false) + api.nvim_buf_set_lines(buf, 0, -1, true, {'the floatwin'}) + local win = api.nvim_open_win(buf, true, {relative='win', width=16, height=1, row=0, col=10}) + eq('Vim(close):E37: No write since last change (add ! to override)', pcall_err(fn.win_execute, win, 'close')) + eq('Vim(bdelete):E89: No write since last change for buffer 2 (add ! to override)', pcall_err(fn.win_execute, win, 'bdelete')) + fn.win_execute(win, 'bwipe!') end) it('closed immediately by autocmd #11383', function() @@ -104,14 +104,20 @@ describe('float window', function() end) it('open with WinNew autocmd', function() - local res = exec_lua([[ - local triggerd = false + local new_triggered_before_enter, new_curwin, win = unpack(exec_lua([[ + local enter_triggered = false + local new_triggered_before_enter = false + local new_curwin local buf = vim.api.nvim_create_buf(true, true) + vim.api.nvim_create_autocmd('WinEnter', { + callback = function() + enter_triggered = true + end + }) vim.api.nvim_create_autocmd('WinNew', { - callback = function(opt) - if opt.buf == buf then - triggerd = true - end + callback = function() + new_triggered_before_enter = not enter_triggered + new_curwin = vim.api.nvim_get_current_win() end }) local opts = { @@ -120,10 +126,11 @@ describe('float window', function() width = 1, height = 1, noautocmd = false, } - vim.api.nvim_open_win(buf, true, opts) - return triggerd - ]]) - eq(true, res) + local win = vim.api.nvim_open_win(buf, true, opts) + return {new_triggered_before_enter, new_curwin, win} + ]])) + eq(true, new_triggered_before_enter) + eq(win, new_curwin) end) it('opened with correct height', function() @@ -193,7 +200,7 @@ describe('float window', function() end) it('opened with correct position relative to the mouse', function() - meths.input_mouse('left', 'press', '', 0, 10, 10) + api.nvim_input_mouse('left', 'press', '', 0, 10, 10) local pos = exec_lua([[ local bufnr = vim.api.nvim_create_buf(false, true) @@ -480,67 +487,67 @@ describe('float window', function() it('no crash with bufpos and non-existent window', function() command('new') - local closed_win = meths.get_current_win().id + local closed_win = api.nvim_get_current_win() command('close') - local buf = meths.create_buf(false,false) - meths.open_win(buf, true, {relative='win', win=closed_win, width=1, height=1, bufpos={0,0}}) + local buf = api.nvim_create_buf(false,false) + api.nvim_open_win(buf, true, {relative='win', win=closed_win, width=1, height=1, bufpos={0,0}}) assert_alive() end) it("no segfault when setting minimal style after clearing local 'fillchars' #19510", function() local float_opts = {relative = 'editor', row = 1, col = 1, width = 1, height = 1} - local float_win = meths.open_win(0, true, float_opts) - meths.set_option_value('fillchars', NIL, {win=float_win.id}) + local float_win = api.nvim_open_win(0, true, float_opts) + api.nvim_set_option_value('fillchars', NIL, {win=float_win}) float_opts.style = 'minimal' - meths.win_set_config(float_win, float_opts) + api.nvim_win_set_config(float_win, float_opts) assert_alive() end) it("should re-apply 'style' when present", function() local float_opts = {style = 'minimal', relative = 'editor', row = 1, col = 1, width = 1, height = 1} - local float_win = meths.open_win(0, true, float_opts) - meths.set_option_value('number', true, { win = float_win }) + local float_win = api.nvim_open_win(0, true, float_opts) + api.nvim_set_option_value('number', true, { win = float_win }) float_opts.row = 2 - meths.win_set_config(float_win, float_opts) - eq(false, meths.get_option_value('number', { win = float_win })) + api.nvim_win_set_config(float_win, float_opts) + eq(false, api.nvim_get_option_value('number', { win = float_win })) end) it("should not re-apply 'style' when missing", function() local float_opts = {style = 'minimal', relative = 'editor', row = 1, col = 1, width = 1, height = 1} - local float_win = meths.open_win(0, true, float_opts) - meths.set_option_value('number', true, { win = float_win }) + local float_win = api.nvim_open_win(0, true, float_opts) + api.nvim_set_option_value('number', true, { win = float_win }) float_opts.row = 2 float_opts.style = nil - meths.win_set_config(float_win, float_opts) - eq(true, meths.get_option_value('number', { win = float_win })) + api.nvim_win_set_config(float_win, float_opts) + eq(true, api.nvim_get_option_value('number', { win = float_win })) end) it("'scroll' is computed correctly when opening float with splitkeep=screen #20684", function() - meths.set_option_value('splitkeep', 'screen', {}) + api.nvim_set_option_value('splitkeep', 'screen', {}) local float_opts = {relative = 'editor', row = 1, col = 1, width = 10, height = 10} - local float_win = meths.open_win(0, true, float_opts) - eq(5, meths.get_option_value('scroll', {win=float_win.id})) + local float_win = api.nvim_open_win(0, true, float_opts) + eq(5, api.nvim_get_option_value('scroll', {win=float_win})) end) it(':unhide works when there are floating windows', function() local float_opts = {relative = 'editor', row = 1, col = 1, width = 5, height = 5} local w0 = curwin() - meths.open_win(0, false, float_opts) - meths.open_win(0, false, float_opts) - eq(3, #meths.list_wins()) + api.nvim_open_win(0, false, float_opts) + api.nvim_open_win(0, false, float_opts) + eq(3, #api.nvim_list_wins()) command('unhide') - eq({ w0 }, meths.list_wins()) + eq({ w0 }, api.nvim_list_wins()) end) it(':all works when there are floating windows', function() command('args Xa.txt') local float_opts = {relative = 'editor', row = 1, col = 1, width = 5, height = 5} local w0 = curwin() - meths.open_win(0, false, float_opts) - meths.open_win(0, false, float_opts) - eq(3, #meths.list_wins()) + api.nvim_open_win(0, false, float_opts) + api.nvim_open_win(0, false, float_opts) + eq(3, #api.nvim_list_wins()) command('all') - eq({ w0 }, meths.list_wins()) + eq({ w0 }, api.nvim_list_wins()) end) describe('with only one tabpage,', function() @@ -548,42 +555,42 @@ describe('float window', function() local old_buf, old_win before_each(function() insert('foo') - old_buf = curbuf().id - old_win = curwin().id + old_buf = curbuf() + old_win = curwin() end) describe('closing the last non-floating window gives E444', function() before_each(function() - meths.open_win(old_buf, true, float_opts) + api.nvim_open_win(old_buf, true, float_opts) end) it('if called from non-floating window', function() - meths.set_current_win(old_win) + api.nvim_set_current_win(old_win) eq('Vim:E444: Cannot close last window', - pcall_err(meths.win_close, old_win, false)) + pcall_err(api.nvim_win_close, old_win, false)) end) it('if called from floating window', function() eq('Vim:E444: Cannot close last window', - pcall_err(meths.win_close, old_win, false)) + pcall_err(api.nvim_win_close, old_win, false)) end) end) describe("deleting the last non-floating window's buffer", function() describe('leaves one window with an empty buffer when there is only one buffer', function() local same_buf_float before_each(function() - same_buf_float = meths.open_win(old_buf, false, float_opts).id + same_buf_float = api.nvim_open_win(old_buf, false, float_opts) end) after_each(function() - eq(old_win, curwin().id) + eq(old_win, curwin()) expect('') - eq(1, #meths.list_wins()) + eq(1, #api.nvim_list_wins()) end) it('if called from non-floating window', function() - meths.buf_delete(old_buf, {force = true}) + api.nvim_buf_delete(old_buf, {force = true}) end) it('if called from floating window', function() - meths.set_current_win(same_buf_float) + api.nvim_set_current_win(same_buf_float) command('autocmd WinLeave * let g:win_leave = nvim_get_current_win()') command('autocmd WinEnter * let g:win_enter = nvim_get_current_win()') - meths.buf_delete(old_buf, {force = true}) + api.nvim_buf_delete(old_buf, {force = true}) eq(same_buf_float, eval('g:win_leave')) eq(old_win, eval('g:win_enter')) end) @@ -591,67 +598,67 @@ describe('float window', function() describe('closes other windows with that buffer when there are other buffers', function() local same_buf_float, other_buf, other_buf_float before_each(function() - same_buf_float = meths.open_win(old_buf, false, float_opts).id - other_buf = meths.create_buf(true, false).id - other_buf_float = meths.open_win(other_buf, true, float_opts).id + same_buf_float = api.nvim_open_win(old_buf, false, float_opts) + other_buf = api.nvim_create_buf(true, false) + other_buf_float = api.nvim_open_win(other_buf, true, float_opts) insert('bar') - meths.set_current_win(old_win) + api.nvim_set_current_win(old_win) end) after_each(function() - eq(other_buf, curbuf().id) + eq(other_buf, curbuf()) expect('bar') - eq(2, #meths.list_wins()) + eq(2, #api.nvim_list_wins()) end) it('if called from non-floating window', function() - meths.buf_delete(old_buf, {force = true}) - eq(old_win, curwin().id) + api.nvim_buf_delete(old_buf, {force = true}) + eq(old_win, curwin()) end) it('if called from floating window with the same buffer', function() - meths.set_current_win(same_buf_float) + api.nvim_set_current_win(same_buf_float) command('autocmd WinLeave * let g:win_leave = nvim_get_current_win()') command('autocmd WinEnter * let g:win_enter = nvim_get_current_win()') - meths.buf_delete(old_buf, {force = true}) + api.nvim_buf_delete(old_buf, {force = true}) eq(same_buf_float, eval('g:win_leave')) eq(old_win, eval('g:win_enter')) - eq(old_win, curwin().id) + eq(old_win, curwin()) end) -- TODO: this case is too hard to deal with pending('if called from floating window with another buffer', function() - meths.set_current_win(other_buf_float) - meths.buf_delete(old_buf, {force = true}) + api.nvim_set_current_win(other_buf_float) + api.nvim_buf_delete(old_buf, {force = true}) end) end) describe('creates an empty buffer when there is only one listed buffer', function() local same_buf_float, unlisted_buf_float before_each(function() - same_buf_float = meths.open_win(old_buf, false, float_opts).id - local unlisted_buf = meths.create_buf(true, false).id - unlisted_buf_float = meths.open_win(unlisted_buf, true, float_opts).id + same_buf_float = api.nvim_open_win(old_buf, false, float_opts) + local unlisted_buf = api.nvim_create_buf(true, false) + unlisted_buf_float = api.nvim_open_win(unlisted_buf, true, float_opts) insert('unlisted') command('set nobuflisted') - meths.set_current_win(old_win) + api.nvim_set_current_win(old_win) end) after_each(function() expect('') - eq(2, #meths.list_wins()) + eq(2, #api.nvim_list_wins()) end) it('if called from non-floating window', function() - meths.buf_delete(old_buf, {force = true}) - eq(old_win, curwin().id) + api.nvim_buf_delete(old_buf, {force = true}) + eq(old_win, curwin()) end) it('if called from floating window with the same buffer', function() - meths.set_current_win(same_buf_float) + api.nvim_set_current_win(same_buf_float) command('autocmd WinLeave * let g:win_leave = nvim_get_current_win()') command('autocmd WinEnter * let g:win_enter = nvim_get_current_win()') - meths.buf_delete(old_buf, {force = true}) + api.nvim_buf_delete(old_buf, {force = true}) eq(same_buf_float, eval('g:win_leave')) eq(old_win, eval('g:win_enter')) - eq(old_win, curwin().id) + eq(old_win, curwin()) end) -- TODO: this case is too hard to deal with pending('if called from floating window with an unlisted buffer', function() - meths.set_current_win(unlisted_buf_float) - meths.buf_delete(old_buf, {force = true}) + api.nvim_set_current_win(unlisted_buf_float) + api.nvim_buf_delete(old_buf, {force = true}) end) end) end) @@ -662,21 +669,21 @@ describe('float window', function() command('botright vnew') insert('unlisted') command('set nobuflisted') - meths.set_current_win(old_win) - same_buf_float = meths.open_win(old_buf, false, float_opts).id + api.nvim_set_current_win(old_win) + same_buf_float = api.nvim_open_win(old_buf, false, float_opts) end) after_each(function() expect('') - eq(2, #meths.list_wins()) + eq(2, #api.nvim_list_wins()) end) it('if called from non-floating window with the deleted buffer', function() - meths.buf_delete(old_buf, {force = true}) - eq(old_win, curwin().id) + api.nvim_buf_delete(old_buf, {force = true}) + eq(old_win, curwin()) end) it('if called from floating window with the deleted buffer', function() - meths.set_current_win(same_buf_float) - meths.buf_delete(old_buf, {force = true}) - eq(same_buf_float, curwin().id) + api.nvim_set_current_win(same_buf_float) + api.nvim_buf_delete(old_buf, {force = true}) + eq(same_buf_float, curwin()) end) end) end) @@ -688,63 +695,63 @@ describe('float window', function() before_each(function() insert('unlisted') command('set nobuflisted') - unlisted_buf = curbuf().id + unlisted_buf = curbuf() command('tabnew') insert('foo') - old_buf = curbuf().id - old_win = curwin().id + old_buf = curbuf() + old_win = curwin() end) describe('without splits, deleting the last listed buffer creates an empty buffer', function() local same_buf_float before_each(function() - meths.set_current_win(old_win) - same_buf_float = meths.open_win(old_buf, false, float_opts).id + api.nvim_set_current_win(old_win) + same_buf_float = api.nvim_open_win(old_buf, false, float_opts) end) after_each(function() expect('') - eq(2, #meths.list_wins()) - eq(2, #meths.list_tabpages()) + eq(2, #api.nvim_list_wins()) + eq(2, #api.nvim_list_tabpages()) end) it('if called from non-floating window', function() - meths.buf_delete(old_buf, {force = true}) - eq(old_win, curwin().id) + api.nvim_buf_delete(old_buf, {force = true}) + eq(old_win, curwin()) end) it('if called from non-floating window in another tabpage', function() command('tab split') - eq(3, #meths.list_tabpages()) - meths.buf_delete(old_buf, {force = true}) + eq(3, #api.nvim_list_tabpages()) + api.nvim_buf_delete(old_buf, {force = true}) end) it('if called from floating window with the same buffer', function() - meths.set_current_win(same_buf_float) + api.nvim_set_current_win(same_buf_float) command('autocmd WinLeave * let g:win_leave = nvim_get_current_win()') command('autocmd WinEnter * let g:win_enter = nvim_get_current_win()') - meths.buf_delete(old_buf, {force = true}) + api.nvim_buf_delete(old_buf, {force = true}) eq(same_buf_float, eval('g:win_leave')) eq(old_win, eval('g:win_enter')) - eq(old_win, curwin().id) + eq(old_win, curwin()) end) end) describe('with splits, deleting the last listed buffer creates an empty buffer', function() local same_buf_float before_each(function() command('botright vsplit') - meths.set_current_buf(unlisted_buf) - meths.set_current_win(old_win) - same_buf_float = meths.open_win(old_buf, false, float_opts).id + api.nvim_set_current_buf(unlisted_buf) + api.nvim_set_current_win(old_win) + same_buf_float = api.nvim_open_win(old_buf, false, float_opts) end) after_each(function() expect('') - eq(3, #meths.list_wins()) - eq(2, #meths.list_tabpages()) + eq(3, #api.nvim_list_wins()) + eq(2, #api.nvim_list_tabpages()) end) it('if called from non-floating window with the deleted buffer', function() - meths.buf_delete(old_buf, {force = true}) - eq(old_win, curwin().id) + api.nvim_buf_delete(old_buf, {force = true}) + eq(old_win, curwin()) end) it('if called from floating window with the deleted buffer', function() - meths.set_current_win(same_buf_float) - meths.buf_delete(old_buf, {force = true}) - eq(same_buf_float, curwin().id) + api.nvim_set_current_win(same_buf_float) + api.nvim_buf_delete(old_buf, {force = true}) + eq(same_buf_float, curwin()) end) end) end) @@ -753,48 +760,48 @@ describe('float window', function() local float_opts = {relative = 'editor', row = 1, col = 1, width = 1, height = 1} local old_tabpage, old_buf, old_win before_each(function() - old_tabpage = curtab().id + old_tabpage = curtab() insert('oldtab') command('tabnew') - old_buf = curbuf().id - old_win = curwin().id + old_buf = curbuf() + old_win = curwin() end) describe('closing the last non-floating window', function() describe('closes the tabpage when all floating windows are closeable', function() local same_buf_float before_each(function() - same_buf_float = meths.open_win(old_buf, false, float_opts).id + same_buf_float = api.nvim_open_win(old_buf, false, float_opts) end) after_each(function() - eq(old_tabpage, curtab().id) + eq(old_tabpage, curtab()) expect('oldtab') - eq(1, #meths.list_tabpages()) + eq(1, #api.nvim_list_tabpages()) end) it('if called from non-floating window', function() - meths.win_close(old_win, false) + api.nvim_win_close(old_win, false) end) it('if called from floating window', function() - meths.set_current_win(same_buf_float) - meths.win_close(old_win, false) + api.nvim_set_current_win(same_buf_float) + api.nvim_win_close(old_win, false) end) end) describe('gives E5601 when there are non-closeable floating windows', function() local other_buf_float before_each(function() command('set nohidden') - local other_buf = meths.create_buf(true, false).id - other_buf_float = meths.open_win(other_buf, true, float_opts).id + local other_buf = api.nvim_create_buf(true, false) + other_buf_float = api.nvim_open_win(other_buf, true, float_opts) insert('foo') - meths.set_current_win(old_win) + api.nvim_set_current_win(old_win) end) it('if called from non-floating window', function() eq('Vim:E5601: Cannot close window, only floating window would remain', - pcall_err(meths.win_close, old_win, false)) + pcall_err(api.nvim_win_close, old_win, false)) end) it('if called from floating window', function() - meths.set_current_win(other_buf_float) + api.nvim_set_current_win(other_buf_float) eq('Vim:E5601: Cannot close window, only floating window would remain', - pcall_err(meths.win_close, old_win, false)) + pcall_err(api.nvim_win_close, old_win, false)) end) end) end) @@ -802,27 +809,27 @@ describe('float window', function() describe('closes the tabpage when all floating windows are closeable', function() local same_buf_float, other_buf, other_buf_float before_each(function() - same_buf_float = meths.open_win(old_buf, false, float_opts).id - other_buf = meths.create_buf(true, false).id - other_buf_float = meths.open_win(other_buf, true, float_opts).id - meths.set_current_win(old_win) + same_buf_float = api.nvim_open_win(old_buf, false, float_opts) + other_buf = api.nvim_create_buf(true, false) + other_buf_float = api.nvim_open_win(other_buf, true, float_opts) + api.nvim_set_current_win(old_win) end) after_each(function() - eq(old_tabpage, curtab().id) + eq(old_tabpage, curtab()) expect('oldtab') - eq(1, #meths.list_tabpages()) + eq(1, #api.nvim_list_tabpages()) end) it('if called from non-floating window', function() - meths.buf_delete(old_buf, {force = false}) + api.nvim_buf_delete(old_buf, {force = false}) end) it('if called from floating window with the same buffer', function() - meths.set_current_win(same_buf_float) - meths.buf_delete(old_buf, {force = false}) + api.nvim_set_current_win(same_buf_float) + api.nvim_buf_delete(old_buf, {force = false}) end) -- TODO: this case is too hard to deal with pending('if called from floating window with another buffer', function() - meths.set_current_win(other_buf_float) - meths.buf_delete(old_buf, {force = false}) + api.nvim_set_current_win(other_buf_float) + api.nvim_buf_delete(old_buf, {force = false}) end) end) -- TODO: what to do when there are non-closeable floating windows? @@ -862,36 +869,27 @@ describe('float window', function() [24] = {foreground = Screen.colors.Black, background = Screen.colors.Grey80}; [25] = {blend = 100, background = Screen.colors.Gray0}; [26] = {blend = 80, background = Screen.colors.Gray0}; - [27] = {background = Screen.colors.LightGray}; - [28] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGray}; + [27] = {foreground = Screen.colors.Black, background = Screen.colors.LightGrey}; + [28] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey}; } screen:set_default_attr_ids(attrs) end) it('can be created and reconfigured', function() - local buf = meths.create_buf(false,false) - local win = meths.open_win(buf, false, {relative='editor', width=20, height=2, row=2, col=5}) + local buf = api.nvim_create_buf(false,false) + local win = api.nvim_open_win(buf, false, {relative='editor', width=20, height=2, row=2, col=5}) local expected_pos = { - [4]={{id=1001}, 'NW', 1, 2, 5, true}, + [4]={1001, 'NW', 1, 2, 5, true}, } if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -904,33 +902,23 @@ describe('float window', function() {0:~ }| {0:~ }{1: }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end - meths.win_set_config(win, {relative='editor', row=0, col=10}) + api.nvim_win_set_config(win, {relative='editor', row=0, col=10}) expected_pos[4][4] = 0 expected_pos[4][5] = 10 if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -941,43 +929,27 @@ describe('float window', function() screen:expect([[ ^ {1: } | {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) end - meths.win_close(win, false) + api.nvim_win_close(win, false) if multigrid then screen:expect([[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ]]) else screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) end @@ -985,39 +957,29 @@ describe('float window', function() it('window position fixed', function() command('rightbelow 20vsplit') - local buf = meths.create_buf(false,false) - local win = meths.open_win(buf, false, { + local buf = api.nvim_create_buf(false,false) + local win = api.nvim_open_win(buf, false, { relative='win', width=15, height=2, row=2, col=10, anchor='NW', fixed=true}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:-------------------]{5:│}[4:--------------------]| - [2:-------------------]{5:│}[4:--------------------]| - [2:-------------------]{5:│}[4:--------------------]| - [2:-------------------]{5:│}[4:--------------------]| - [2:-------------------]{5:│}[4:--------------------]| + [2:-------------------]{5:│}[4:--------------------]|*5 {5:[No Name] }{4:[No Name] }| [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 | ## grid 4 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 5 {1: }| {2:~ }| ]], float_pos={ - [5] = {{id = 1002}, "NW", 4, 2, 10, true}; + [5] = {1002, "NW", 4, 2, 10, true}; }} else screen:expect([[ @@ -1031,7 +993,7 @@ describe('float window', function() ]]) end - meths.win_set_config(win, {fixed=false}) + api.nvim_win_set_config(win, {fixed=false}) if multigrid then screen:expect_unchanged() @@ -1055,29 +1017,20 @@ describe('float window', function() -- or something. command("set redrawdebug=compositor") command("set wd=1") - local buf = meths.create_buf(false,false) - local win = meths.open_win(buf, false, {relative='editor', width=20, height=2, row=2, col=5}) + local buf = api.nvim_create_buf(false,false) + local win = api.nvim_open_win(buf, false, {relative='editor', width=20, height=2, row=2, col=5}) local expected_pos = { - [4]={{id=1001}, 'NW', 1, 2, 5, true}, + [4]={1001, 'NW', 1, 2, 5, true}, } if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -1090,33 +1043,23 @@ describe('float window', function() {0:~ }| {0:~ }{1: }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end - meths.win_set_config(win, {relative='editor', row=0, col=10}) + api.nvim_win_set_config(win, {relative='editor', row=0, col=10}) expected_pos[4][4] = 0 expected_pos[4][5] = 10 if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -1127,84 +1070,70 @@ describe('float window', function() screen:expect([[ ^ {1: } | {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) end - meths.win_close(win, false) + api.nvim_win_close(win, false) if multigrid then screen:expect([[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ]]) else screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) end end) it('return their configuration', function() - local buf = meths.create_buf(false, false) - local win = meths.open_win(buf, false, {relative='editor', width=20, height=2, row=3, col=5, zindex=60}) + local buf = api.nvim_create_buf(false, false) + local win = api.nvim_open_win(buf, false, {relative='editor', width=20, height=2, row=3, col=5, zindex=60}) local expected = {anchor='NW', col=5, external=false, focusable=true, height=2, relative='editor', row=3, width=20, zindex=60, hide=false} - eq(expected, meths.win_get_config(win)) + eq(expected, api.nvim_win_get_config(win)) + eq(true, exec_lua([[ + local expected, win = ... + local actual = vim.api.nvim_win_get_config(win) + for k,v in pairs(expected) do + if v ~= actual[k] then + error(k) + end + end + return true]], expected, win)) - eq({relative='', external=false, focusable=true, hide=false}, meths.win_get_config(0)) + eq({external=false, focusable=true, hide=false, relative='',split="left",width=40,height=6}, api.nvim_win_get_config(0)) if multigrid then - meths.win_set_config(win, {external=true, width=10, height=1}) - eq({external=true,focusable=true,width=10,height=1,relative='',hide=false}, meths.win_get_config(win)) + api.nvim_win_set_config(win, {external=true, width=10, height=1}) + eq({external=true,focusable=true,width=10,height=1,relative='',hide=false}, api.nvim_win_get_config(win)) end end) it('defaults to NormalFloat highlight and inherited options', function() command('set number') - command('hi NormalFloat guibg=#333333') + command('hi NormalFloat guibg=#333333 guifg=NONE') feed('ix<cr>y<cr><esc>gg') - local win = meths.open_win(0, false, {relative='editor', width=20, height=4, row=4, col=10}) + local win = api.nvim_open_win(0, false, {relative='editor', width=20, height=4, row=4, col=10}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 {14: 1 }^x | {14: 2 }y | {14: 3 } | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 3 | ## grid 4 @@ -1212,7 +1141,7 @@ describe('float window', function() {18: 2 }{15:y }| {18: 3 }{15: }| {16:~ }| - ]], float_pos={[4] = {{id = 1001}, "NW", 1, 4, 10, true}}} + ]], float_pos={[4] = {1001, "NW", 1, 4, 10, true}}} else screen:expect([[ {14: 1 }^x | @@ -1225,41 +1154,30 @@ describe('float window', function() ]]) end - local buf = meths.create_buf(false, true) - meths.win_set_buf(win, buf) + local buf = api.nvim_create_buf(false, true) + api.nvim_win_set_buf(win, buf) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 {14: 1 }^x | {14: 2 }y | {14: 3 } | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 3 | ## grid 4 {18: 1 }{15: }| - {16:~ }| - {16:~ }| - {16:~ }| - ]], float_pos={[4] = {{id = 1001}, "NW", 1, 4, 10, true}}} + {16:~ }|*3 + ]], float_pos={[4] = {1001, "NW", 1, 4, 10, true}}} else screen:expect([[ {14: 1 }^x | {14: 2 }y | {14: 3 } {18: 1 }{15: } | - {0:~ }{16:~ }{0: }| - {0:~ }{16:~ }{0: }| - {0:~ }{16:~ }{0: }| + {0:~ }{16:~ }{0: }|*3 | ]]) end @@ -1271,42 +1189,33 @@ describe('float window', function() command('set colorcolumn=1') command('set cursorline') command('set foldcolumn=1') - command('hi NormalFloat guibg=#333333') + command('hi NormalFloat guibg=#333333 guifg=NONE') feed('ix<cr>y<cr><esc>gg') - local win = meths.open_win(0, false, {relative='editor', width=20, height=4, row=4, col=10, style='minimal'}) + local win = api.nvim_open_win(0, false, {relative='editor', width=20, height=4, row=4, col=10, style='minimal'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 {19: }{20: 1 }{22:^x}{21: }| {19: }{14: 2 }{22:y} | {19: }{14: 3 }{22: } | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 3 | ## grid 4 {15:x }| {15:y }| - {15: }| - {15: }| - ]], float_pos={[4] = {{id = 1001}, "NW", 1, 4, 10, true}}} + {15: }|*2 + ]], float_pos={[4] = {1001, "NW", 1, 4, 10, true}}} else screen:expect{grid=[[ {19: }{20: 1 }{22:^x}{21: }| {19: }{14: 2 }{22:y} | {19: }{14: 3 }{22: } {15:x } | {0:~ }{15:y }{0: }| - {0:~ }{15: }{0: }| - {0:~ }{15: }{0: }| + {0:~ }{15: }{0: }|*2 | ]]} end @@ -1317,20 +1226,13 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 {19: }{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{22:^x}{21: }| {19: }{14: 2 }{22:y} | {19: }{14: 3 }{22: } | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 3 | ## grid 4 @@ -1338,7 +1240,7 @@ describe('float window', function() {19: }{15:y }| {19: }{15: }| {15: }| - ]], float_pos={[4] = {{id = 1001}, "NW", 1, 4, 10, true}}} + ]], float_pos={[4] = {1001, "NW", 1, 4, 10, true}}} else screen:expect([[ @@ -1353,41 +1255,29 @@ describe('float window', function() end command('sign unplace 1 buffer=1') - local buf = meths.create_buf(false, true) - meths.win_set_buf(win, buf) + local buf = api.nvim_create_buf(false, true) + api.nvim_win_set_buf(win, buf) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 {19: }{20: 1 }{22:^x}{21: }| {19: }{14: 2 }{22:y} | {19: }{14: 3 }{22: } | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 3 | ## grid 4 - {15: }| - {15: }| - {15: }| - {15: }| - ]], float_pos={[4] = {{id = 1001}, "NW", 1, 4, 10, true}}} + {15: }|*4 + ]], float_pos={[4] = {1001, "NW", 1, 4, 10, true}}} else screen:expect([[ {19: }{20: 1 }{22:^x}{21: }| {19: }{14: 2 }{22:y} | {19: }{14: 3 }{22: } {15: } | - {0:~ }{15: }{0: }| - {0:~ }{15: }{0: }| - {0:~ }{15: }{0: }| + {0:~ }{15: }{0: }|*3 | ]]) end @@ -1399,42 +1289,33 @@ describe('float window', function() command('set colorcolumn=1') command('set cursorline') command('set foldcolumn=1') - command('hi NormalFloat guibg=#333333') + command('hi NormalFloat guibg=#333333 guifg=NONE') feed('ix<cr>y<cr><esc>gg') - local win = meths.open_win(0, false, {relative='editor', width=20, height=4, row=4, col=10, style='minimal'}) + local win = api.nvim_open_win(0, false, {relative='editor', width=20, height=4, row=4, col=10, style='minimal'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 {19: }{20: 1 }{22:^x}{21: }| {19: }{14: 2 }{22:y} | {19: }{14: 3 }{22: } | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 3 | ## grid 4 {15:x }| {15:y }| - {15: }| - {15: }| - ]], float_pos={[4] = {{id = 1001}, "NW", 1, 4, 10, true}}} + {15: }|*2 + ]], float_pos={[4] = {1001, "NW", 1, 4, 10, true}}} else screen:expect{grid=[[ {19: }{20: 1 }{22:^x}{21: }| {19: }{14: 2 }{22:y} | {19: }{14: 3 }{22: } {15:x } | {0:~ }{15:y }{0: }| - {0:~ }{15: }{0: }| - {0:~ }{15: }{0: }| + {0:~ }{15: }{0: }|*2 | ]]} end @@ -1445,20 +1326,13 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 {19: }{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{22:^x}{21: }| {19: }{14: 2 }{22:y} | {19: }{14: 3 }{22: } | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 3 | ## grid 4 @@ -1466,7 +1340,7 @@ describe('float window', function() {19: }{15:y }| {19: }{15: }| {15: }| - ]], float_pos={[4] = {{id = 1001}, "NW", 1, 4, 10, true}}} + ]], float_pos={[4] = {1001, "NW", 1, 4, 10, true}}} else screen:expect([[ @@ -1481,41 +1355,29 @@ describe('float window', function() end command('sign unplace 1 buffer=1') - local buf = meths.create_buf(false, true) - meths.win_set_buf(win, buf) + local buf = api.nvim_create_buf(false, true) + api.nvim_win_set_buf(win, buf) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 {19: }{20: 1 }{22:^x}{21: }| {19: }{14: 2 }{22:y} | {19: }{14: 3 }{22: } | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 3 | ## grid 4 - {15: }| - {15: }| - {15: }| - {15: }| - ]], float_pos={[4] = {{id = 1001}, "NW", 1, 4, 10, true}}} + {15: }|*4 + ]], float_pos={[4] = {1001, "NW", 1, 4, 10, true}}} else screen:expect([[ {19: }{20: 1 }{22:^x}{21: }| {19: }{14: 2 }{22:y} | {19: }{14: 3 }{22: } {15: } | - {0:~ }{15: }{0: }| - {0:~ }{15: }{0: }| - {0:~ }{15: }{0: }| + {0:~ }{15: }{0: }|*3 | ]]) end @@ -1528,70 +1390,52 @@ describe('float window', function() command('set cursorline') command('set foldcolumn=1') command('set statuscolumn=%l%s%C') - command('hi NormalFloat guibg=#333333') + command('hi NormalFloat guibg=#333333 guifg=NONE') feed('ix<cr>y<cr><esc>gg') - meths.open_win(0, false, {relative='editor', width=20, height=4, row=4, col=10, style='minimal'}) + api.nvim_open_win(0, false, {relative='editor', width=20, height=4, row=4, col=10, style='minimal'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 {20:1}{19: }{20: }{22:^x}{21: }| {14:2}{19: }{14: }{22:y} | {14:3}{19: }{14: }{22: } | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 3 | ## grid 4 {15:x }| {15:y }| - {15: }| - {15: }| - ]], float_pos={[4] = {{id = 1001}, "NW", 1, 4, 10, true}}} + {15: }|*2 + ]], float_pos={[4] = {1001, "NW", 1, 4, 10, true}}} else screen:expect{grid=[[ {20:1}{19: }{20: }{22:^x}{21: }| {14:2}{19: }{14: }{22:y} | {14:3}{19: }{14: }{22: } {15:x } | {0:~ }{15:y }{0: }| - {0:~ }{15: }{0: }| - {0:~ }{15: }{0: }| + {0:~ }{15: }{0: }|*2 | ]]} end end) it('can have border', function() - local buf = meths.create_buf(false, false) - meths.buf_set_lines(buf, 0, -1, true, {' halloj! ', + local buf = api.nvim_create_buf(false, false) + api.nvim_buf_set_lines(buf, 0, -1, true, {' halloj! ', ' BORDAA '}) - local win = meths.open_win(buf, false, {relative='editor', width=9, height=2, row=2, col=5, border="double"}) + local win = api.nvim_open_win(buf, false, {relative='editor', width=9, height=2, row=2, col=5, border="double"}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -1600,10 +1444,10 @@ describe('float window', function() {5:║}{1: BORDAA }{5:║}| {5:╚═════════╝}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1617,24 +1461,15 @@ describe('float window', function() ]]} end - meths.win_set_config(win, {border="single"}) + api.nvim_win_set_config(win, {border="single"}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -1643,10 +1478,10 @@ describe('float window', function() {5:│}{1: BORDAA }{5:│}| {5:└─────────┘}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1660,24 +1495,15 @@ describe('float window', function() ]]} end - meths.win_set_config(win, {border="rounded"}) + api.nvim_win_set_config(win, {border="rounded"}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -1686,10 +1512,10 @@ describe('float window', function() {5:│}{1: BORDAA }{5:│}| {5:╰─────────╯}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1703,24 +1529,15 @@ describe('float window', function() ]]} end - meths.win_set_config(win, {border="solid"}) + api.nvim_win_set_config(win, {border="solid"}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -1729,10 +1546,10 @@ describe('float window', function() {5: }{1: BORDAA }{5: }| {5: }| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1747,24 +1564,15 @@ describe('float window', function() end -- support: ascii char, UTF-8 char, composed char, highlight per char - meths.win_set_config(win, {border={"x", {"å", "ErrorMsg"}, {"\\"}, {"n̈̊", "Search"}}}) + api.nvim_win_set_config(win, {border={"x", {"å", "ErrorMsg"}, {"\\"}, {"n̈̊", "Search"}}}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -1773,10 +1581,10 @@ describe('float window', function() {17:n̈̊}{1: BORDAA }{17:n̈̊}| {5:\}{7:ååååååååå}{5:x}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1790,34 +1598,25 @@ describe('float window', function() ]]} end - meths.win_set_config(win, {border="none"}) + api.nvim_win_set_config(win, {border="none"}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 {1: halloj! }| {1: BORDAA }| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1825,40 +1624,30 @@ describe('float window', function() {0:~ }| {0:~ }{1: halloj! }{0: }| {0:~ }{1: BORDAA }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]} end - meths.win_set_config(win, {border={"", "", "", ">", "", "", "", "<"}}) + api.nvim_win_set_config(win, {border={"", "", "", ">", "", "", "", "<"}}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 {5:<}{1: halloj! }{5:>}| {5:<}{1: BORDAA }{5:>}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1866,30 +1655,20 @@ describe('float window', function() {0:~ }| {0:~ }{5:<}{1: halloj! }{5:>}{0: }| {0:~ }{5:<}{1: BORDAA }{5:>}{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]} end - meths.win_set_config(win, {border={"", "_", "", "", "", "-", "", ""}}) + api.nvim_win_set_config(win, {border={"", "_", "", "", "", "-", "", ""}}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -1898,10 +1677,10 @@ describe('float window', function() {1: BORDAA }| {5:---------}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1923,16 +1702,11 @@ describe('float window', function() of border shadow ]] - meths.win_set_config(win, {border="shadow"}) + api.nvim_win_set_config(win, {border="shadow"}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 neeed some dummy | @@ -1948,10 +1722,10 @@ describe('float window', function() {1: BORDAA }{26: }| {25: }{26: }| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 6, curline = 5, curcol = 0, linecount = 6, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 6, curline = 5, curcol = 0, linecount = 6, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -1967,13 +1741,13 @@ describe('float window', function() end) it('validates title title_pos', function() - local buf = meths.create_buf(false,false) + local buf = api.nvim_create_buf(false,false) eq("title requires border to be set", - pcall_err(meths.open_win,buf, false, { + pcall_err(api.nvim_open_win,buf, false, { relative='editor', width=9, height=2, row=2, col=5, title='Title', })) eq("title_pos requires title to be set", - pcall_err(meths.open_win,buf, false, { + pcall_err(api.nvim_open_win,buf, false, { relative='editor', width=9, height=2, row=2, col=5, border='single', title_pos='left', })) @@ -2001,13 +1775,13 @@ describe('float window', function() end) it('validates footer footer_pos', function() - local buf = meths.create_buf(false,false) + local buf = api.nvim_create_buf(false,false) eq("footer requires border to be set", - pcall_err(meths.open_win,buf, false, { + pcall_err(api.nvim_open_win,buf, false, { relative='editor', width=9, height=2, row=2, col=5, footer='Footer', })) eq("footer_pos requires footer to be set", - pcall_err(meths.open_win,buf, false, { + pcall_err(api.nvim_open_win,buf, false, { relative='editor', width=9, height=2, row=2, col=5, border='single', footer_pos='left', })) @@ -2035,10 +1809,10 @@ describe('float window', function() end) it('center aligned title longer than window width #25746', function() - local buf = meths.create_buf(false, false) - meths.buf_set_lines(buf, 0, -1, true, {' halloj! ', + local buf = api.nvim_create_buf(false, false) + api.nvim_buf_set_lines(buf, 0, -1, true, {' halloj! ', ' BORDAA '}) - local win = meths.open_win(buf, false, { + local win = api.nvim_open_win(buf, false, { relative='editor', width=9, height=2, row=2, col=5, border="double", title = "abcdefghijklmnopqrstuvwxyz",title_pos = "center", }) @@ -2046,20 +1820,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -2068,10 +1833,10 @@ describe('float window', function() {5:║}{1: BORDAA }{5:║}| {5:╚═════════╝}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2085,15 +1850,15 @@ describe('float window', function() ]]} end - meths.win_close(win, false) + api.nvim_win_close(win, false) assert_alive() end) it('border with title', function() - local buf = meths.create_buf(false, false) - meths.buf_set_lines(buf, 0, -1, true, {' halloj! ', + local buf = api.nvim_create_buf(false, false) + api.nvim_buf_set_lines(buf, 0, -1, true, {' halloj! ', ' BORDAA '}) - local win = meths.open_win(buf, false, { + local win = api.nvim_open_win(buf, false, { relative='editor', width=9, height=2, row=2, col=5, border="double", title = "Left",title_pos = "left", }) @@ -2101,20 +1866,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -2123,10 +1879,10 @@ describe('float window', function() {5:║}{1: BORDAA }{5:║}| {5:╚═════════╝}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2140,24 +1896,15 @@ describe('float window', function() ]]} end - meths.win_set_config(win, {title= "Center",title_pos="center"}) + api.nvim_win_set_config(win, {title= "Center",title_pos="center"}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -2166,10 +1913,10 @@ describe('float window', function() {5:║}{1: BORDAA }{5:║}| {5:╚═════════╝}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2183,24 +1930,15 @@ describe('float window', function() ]]} end - meths.win_set_config(win, {title= "Right",title_pos="right"}) + api.nvim_win_set_config(win, {title= "Right",title_pos="right"}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -2209,10 +1947,10 @@ describe('float window', function() {5:║}{1: BORDAA }{5:║}| {5:╚═════════╝}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2226,24 +1964,15 @@ describe('float window', function() ]]} end - meths.win_set_config(win, {title= { {"🦄"},{"BB"}},title_pos="right"}) + api.nvim_win_set_config(win, {title= { {"🦄"},{"BB"}},title_pos="right"}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -2252,10 +1981,10 @@ describe('float window', function() {5:║}{1: BORDAA }{5:║}| {5:╚═════════╝}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2271,10 +2000,10 @@ describe('float window', function() end) it('border with footer', function() - local buf = meths.create_buf(false, false) - meths.buf_set_lines(buf, 0, -1, true, {' halloj! ', + local buf = api.nvim_create_buf(false, false) + api.nvim_buf_set_lines(buf, 0, -1, true, {' halloj! ', ' BORDAA '}) - local win = meths.open_win(buf, false, { + local win = api.nvim_open_win(buf, false, { relative='editor', width=9, height=2, row=2, col=5, border="double", footer = "Left",footer_pos = "left", }) @@ -2282,20 +2011,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -2304,10 +2024,10 @@ describe('float window', function() {5:║}{1: BORDAA }{5:║}| {5:╚}{11:Left}{5:═════╝}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2321,24 +2041,15 @@ describe('float window', function() ]]} end - meths.win_set_config(win, {footer= "Center",footer_pos="center"}) + api.nvim_win_set_config(win, {footer= "Center",footer_pos="center"}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -2347,10 +2058,10 @@ describe('float window', function() {5:║}{1: BORDAA }{5:║}| {5:╚═}{11:Center}{5:══╝}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2364,24 +2075,15 @@ describe('float window', function() ]]} end - meths.win_set_config(win, {footer= "Right",footer_pos="right"}) + api.nvim_win_set_config(win, {footer= "Right",footer_pos="right"}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -2390,10 +2092,10 @@ describe('float window', function() {5:║}{1: BORDAA }{5:║}| {5:╚════}{11:Right}{5:╝}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2407,24 +2109,15 @@ describe('float window', function() ]]} end - meths.win_set_config(win, {footer= { {"🦄"},{"BB"}},footer_pos="right"}) + api.nvim_win_set_config(win, {footer= { {"🦄"},{"BB"}},footer_pos="right"}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -2433,10 +2126,10 @@ describe('float window', function() {5:║}{1: BORDAA }{5:║}| {5:╚═════}🦄BB{5:╝}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2452,10 +2145,10 @@ describe('float window', function() end) it('border with title and footer', function() - local buf = meths.create_buf(false, false) - meths.buf_set_lines(buf, 0, -1, true, {' halloj! ', + local buf = api.nvim_create_buf(false, false) + api.nvim_buf_set_lines(buf, 0, -1, true, {' halloj! ', ' BORDAA '}) - local win = meths.open_win(buf, false, { + local win = api.nvim_open_win(buf, false, { relative='editor', width=9, height=2, row=2, col=5, border="double", title = "Left", title_pos = "left", footer = "Right", footer_pos = "right", }) @@ -2463,20 +2156,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -2485,10 +2169,10 @@ describe('float window', function() {5:║}{1: BORDAA }{5:║}| {5:╚════}{11:Right}{5:╝}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2502,24 +2186,15 @@ describe('float window', function() ]]} end - meths.win_set_config(win, {title= "Center",title_pos="center",footer= "Center",footer_pos="center"}) + api.nvim_win_set_config(win, {title= "Center",title_pos="center",footer= "Center",footer_pos="center"}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -2528,10 +2203,10 @@ describe('float window', function() {5:║}{1: BORDAA }{5:║}| {5:╚═}{11:Center}{5:══╝}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2545,24 +2220,15 @@ describe('float window', function() ]]} end - meths.win_set_config(win, {title= "Right",title_pos="right",footer= "Left",footer_pos="left"}) + api.nvim_win_set_config(win, {title= "Right",title_pos="right",footer= "Left",footer_pos="left"}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -2571,10 +2237,10 @@ describe('float window', function() {5:║}{1: BORDAA }{5:║}| {5:╚}{11:Left}{5:═════╝}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2590,27 +2256,18 @@ describe('float window', function() command('hi B0 guibg=Red guifg=Black') command('hi B1 guifg=White') - meths.win_set_config(win, { + api.nvim_win_set_config(win, { title = {{"🦄"}, {"BB", {"B0", "B1"}}}, title_pos = "right", footer= {{"🦄"}, {"BB", {"B0", "B1"}}}, footer_pos = "right", }) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -2619,10 +2276,10 @@ describe('float window', function() {5:║}{1: BORDAA }{5:║}| {5:╚═════}🦄{7:BB}{5:╝}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true } + [4] = { 1001, "NW", 1, 2, 5, true } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2638,51 +2295,34 @@ describe('float window', function() end) it('terminates border on edge of viewport when window extends past viewport', function() - local buf = meths.create_buf(false, false) - meths.open_win(buf, false, {relative='editor', width=40, height=7, row=0, col=0, border="single", zindex=201}) + local buf = api.nvim_create_buf(false, false) + api.nvim_open_win(buf, false, {relative='editor', width=40, height=7, row=0, col=0, border="single", zindex=201}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 {5:┌────────────────────────────────────────┐}| {5:│}{1: }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| + {5:│}{2:~ }{5:│}|*6 {5:└────────────────────────────────────────┘}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 0, 0, true, 201 } + [4] = { 1001, "NW", 1, 0, 0, true, 201 } }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ {5:^┌──────────────────────────────────────┐}| {5:│}{1: }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| + {5:│}{2:~ }{5:│}|*4 {5:└──────────────────────────────────────┘}| ]]} end @@ -2690,35 +2330,20 @@ describe('float window', function() it('with border show popupmenu', function() screen:try_resize(40,10) - local buf = meths.create_buf(false, false) - meths.buf_set_lines(buf, 0, -1, true, {'aaa aab ', + local buf = api.nvim_create_buf(false, false) + api.nvim_buf_set_lines(buf, 0, -1, true, {'aaa aab ', 'abb acc ', ''}) - meths.open_win(buf, true, {relative='editor', width=9, height=3, row=0, col=5, border="double"}) + api.nvim_open_win(buf, true, {relative='editor', width=9, height=3, row=0, col=5, border="double"}) feed 'G' if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*9 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*8 ## grid 3 | ## grid 4 @@ -2728,10 +2353,10 @@ describe('float window', function() {5:║}{1:^ }{5:║}| {5:╚═════════╝}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 0, 5, true }; + [4] = { 1001, "NW", 1, 0, 5, true }; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 2, curcol = 0, linecount = 3, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 2, curcol = 0, linecount = 3, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2740,10 +2365,7 @@ describe('float window', function() {0:~ }{5:║}{1:abb acc }{5:║}{0: }| {0:~ }{5:║}{1:^ }{5:║}{0: }| {0:~ }{5:╚═════════╝}{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]} end @@ -2752,26 +2374,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*9 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*8 ## grid 3 {3:-- }{8:match 1 of 4} | ## grid 4 @@ -2786,11 +2393,11 @@ describe('float window', function() {1: abb }| {13: acc }| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 0, 5, true, 50 }; - [5] = { { id = -1 }, "NW", 4, 4, 0, false, 100 }; + [4] = { 1001, "NW", 1, 0, 5, true, 50 }; + [5] = { -1, "NW", 4, 4, 0, false, 100 }; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount=1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 2, curcol = 3, linecount=3, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount=1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 2, curcol = 3, linecount=3, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2811,26 +2418,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*9 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*8 ## grid 3 | ## grid 4 @@ -2840,10 +2432,10 @@ describe('float window', function() {5:║}{1:ac^c }{5:║}| {5:╚═════════╝}| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 0, 5, true }; + [4] = { 1001, "NW", 1, 0, 5, true }; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 2, curcol = 2, linecount = 3, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 2, curcol = 2, linecount = 3, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2852,10 +2444,7 @@ describe('float window', function() {0:~ }{5:║}{1:abb acc }{5:║}{0: }| {0:~ }{5:║}{1:ac^c }{5:║}{0: }| {0:~ }{5:╚═════════╝}{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]} end @@ -2869,26 +2458,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*9 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*8 ## grid 3 :popup Test | ## grid 4 @@ -2902,11 +2476,11 @@ describe('float window', function() {1: bar }| {1: baz }| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 0, 5, true }; - [5] = { { id = -1 }, "NW", 4, 4, 2, false, 250 }; + [4] = { 1001, "NW", 1, 0, 5, true }; + [5] = { -1, "NW", 4, 4, 2, false, 250 }; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 2, curcol = 2, linecount = 3, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 2, curcol = 2, linecount = 3, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -2917,8 +2491,7 @@ describe('float window', function() {0:~ }{5:╚═}{1: foo }{5:═══╝}{0: }| {0:~ }{1: bar }{0: }| {0:~ }{1: baz }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 :popup Test | ]]} end @@ -2926,29 +2499,20 @@ describe('float window', function() it('show ruler of current floating window', function() command 'set ruler' - local buf = meths.create_buf(false, false) - meths.buf_set_lines(buf, 0, -1, true, {'aaa aab ', + local buf = api.nvim_create_buf(false, false) + api.nvim_buf_set_lines(buf, 0, -1, true, {'aaa aab ', 'abb acc '}) - meths.open_win(buf, true, {relative='editor', width=9, height=3, row=0, col=5}) + api.nvim_open_win(buf, true, {relative='editor', width=9, height=3, row=0, col=5}) feed 'gg' if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 1,1 All | ## grid 4 @@ -2956,19 +2520,17 @@ describe('float window', function() {1:abb acc }| {2:~ }| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 0, 5, true, 50}; + [4] = {1001, "NW", 1, 0, 5, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ {1:^aaa aab } | {0:~ }{1:abb acc }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 1,1 All | ]]} end @@ -2977,20 +2539,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 1,5 All | ## grid 4 @@ -2998,19 +2551,17 @@ describe('float window', function() {1:abb acc }| {2:~ }| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 0, 5, true, 50}; + [4] = {1001, "NW", 1, 0, 5, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 0, curcol = 4, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 0, curcol = 4, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ {1:aaa ^aab } | {0:~ }{1:abb acc }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 1,5 All | ]]} end @@ -3018,44 +2569,31 @@ describe('float window', function() it("correct ruler position in current float with 'rulerformat' set", function() command 'set ruler rulerformat=fish:<><' - meths.open_win(0, true, {relative='editor', width=9, height=3, row=0, col=5}) + api.nvim_open_win(0, true, {relative='editor', width=9, height=3, row=0, col=5}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 fish:<>< | ## grid 4 {1:^ }| - {2:~ }| - {2:~ }| + {2:~ }|*2 ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 0, 5, true, 50}; + [4] = {1001, "NW", 1, 0, 5, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ {1:^ } | - {0:~ }{2:~ }{0: }| - {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }{2:~ }{0: }|*2 + {0:~ }|*3 fish:<>< | ]]} end @@ -3064,60 +2602,40 @@ describe('float window', function() it('does not show ruler of not-last current float during ins-completion', function() screen:try_resize(50,9) command 'set ruler showmode' - meths.open_win(0, false, {relative='editor', width=3, height=3, row=0, col=0}) - meths.open_win(0, false, {relative='editor', width=3, height=3, row=0, col=5}) + api.nvim_open_win(0, false, {relative='editor', width=3, height=3, row=0, col=0}) + api.nvim_open_win(0, false, {relative='editor', width=3, height=3, row=0, col=5}) feed '<c-w>w' - neq('', meths.win_get_config(0).relative) - neq(funcs.winnr '$', funcs.winnr()) + neq('', api.nvim_win_get_config(0).relative) + neq(fn.winnr '$', fn.winnr()) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| + [2:--------------------------------------------------]|*8 [3:--------------------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*7 ## grid 3 0,0-1 All | ## grid 4 {1: }| - {2:~ }| - {2:~ }| + {2:~ }|*2 ## grid 5 {1:^ }| - {2:~ }| - {2:~ }| + {2:~ }|*2 ]], float_pos={ - [5] = {{id = 1002}, "NW", 1, 0, 5, true, 50}; - [4] = {{id = 1001}, "NW", 1, 0, 0, true, 50}; + [5] = {1002, "NW", 1, 0, 5, true, 50}; + [4] = {1001, "NW", 1, 0, 0, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [5] = {win = 1002, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ {1: } {1:^ } | - {2:~ }{0: }{2:~ }{0: }| - {2:~ }{0: }{2:~ }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {2:~ }{0: }{2:~ }{0: }|*2 + {0:~ }|*5 0,0-1 All | ]]} end @@ -3125,52 +2643,32 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| + [2:--------------------------------------------------]|*8 [3:--------------------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*7 ## grid 3 {3:-- ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)} | ## grid 4 {1: }| - {2:~ }| - {2:~ }| + {2:~ }|*2 ## grid 5 {1:^ }| - {2:~ }| - {2:~ }| + {2:~ }|*2 ]], float_pos={ - [5] = {{id = 1002}, "NW", 1, 0, 5, true, 50}; - [4] = {{id = 1001}, "NW", 1, 0, 0, true, 50}; + [5] = {1002, "NW", 1, 0, 5, true, 50}; + [4] = {1001, "NW", 1, 0, 0, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [5] = {win = 1002, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ {1: } {1:^ } | - {2:~ }{0: }{2:~ }{0: }| - {2:~ }{0: }{2:~ }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {2:~ }{0: }{2:~ }{0: }|*2 + {0:~ }|*5 {3:-- ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)} | ]]} end @@ -3178,111 +2676,72 @@ describe('float window', function() it('can have minimum size', function() insert("the background text") - local buf = meths.create_buf(false, true) - meths.buf_set_lines(buf, 0, -1, true, {'x'}) - local win = meths.open_win(buf, false, {relative='win', width=1, height=1, row=0, col=4, focusable=false}) + local buf = api.nvim_create_buf(false, true) + api.nvim_buf_set_lines(buf, 0, -1, true, {'x'}) + local win = api.nvim_open_win(buf, false, {relative='win', width=1, height=1, row=0, col=4, focusable=false}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 the background tex^t | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 {1:x}| ]], float_pos={ - [4] = {{id = 1001}, "NW", 2, 0, 4, false} + [4] = {1001, "NW", 2, 0, 4, false} }} else screen:expect([[ the {1:x}ackground tex^t | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) end - meths.win_set_config(win, {relative='win', row=0, col=15}) + api.nvim_win_set_config(win, {relative='win', row=0, col=15}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 the background tex^t | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 {1:x}| ]], float_pos={ - [4] = {{id = 1001}, "NW", 2, 0, 15, false} + [4] = {1001, "NW", 2, 0, 15, false} }} else screen:expect([[ the background {1:x}ex^t | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) end - meths.win_close(win,false) + api.nvim_win_close(win,false) if multigrid then screen:expect([[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 the background tex^t | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ]]) else screen:expect([[ the background tex^t | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) end @@ -3303,23 +2762,19 @@ describe('float window', function() command('sargument 6') local float_opts = { relative = 'editor', row = 6, col = 0, width = 40, height = 1 } - meths.win_set_config(w3, float_opts) - meths.win_set_config(w4, float_opts) + api.nvim_win_set_config(w3, float_opts) + api.nvim_win_set_config(w4, float_opts) command('wincmd =') if multigrid then screen:expect{grid=[[ ## grid 1 - [8:----------------------------------------]| - [8:----------------------------------------]| + [8:----------------------------------------]|*2 {4:X6 }| - [7:----------------------------------------]| - [7:----------------------------------------]| + [7:----------------------------------------]|*2 {5:X5 }| - [4:----------------------------------------]| - [4:----------------------------------------]| + [4:----------------------------------------]|*2 {5:X2 }| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*2 {5:X1 }| [3:----------------------------------------]| ## grid 2 @@ -3341,15 +2796,15 @@ describe('float window', function() ^ | {0:~ }| ]], float_pos={ - [5] = {{id = 1002}, "NW", 1, 6, 0, true, 50}; - [6] = {{id = 1003}, "NW", 1, 6, 0, true, 50}; + [5] = {1002, "NW", 1, 6, 0, true, 50}; + [6] = {1003, "NW", 1, 6, 0, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 1, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [6] = {win = {id = 1003}, topline = 0, botline = 1, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [7] = {win = {id = 1004}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [8] = {win = {id = 1005}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [5] = {win = 1002, topline = 0, botline = 1, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [6] = {win = 1003, topline = 0, botline = 1, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [7] = {win = 1004, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [8] = {win = 1005, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -3401,12 +2856,12 @@ describe('float window', function() ## grid 10 | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 1, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 1, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [7] = {win = {id = 1004}, topline = 0, botline = 1, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [8] = {win = {id = 1005}, topline = 0, botline = 1, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [9] = {win = {id = 1006}, topline = 0, botline = 1, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [10] = {win = {id = 1007}, topline = 0, botline = 1, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 1, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 1, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [7] = {win = 1004, topline = 0, botline = 1, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [8] = {win = 1005, topline = 0, botline = 1, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [9] = {win = 1006, topline = 0, botline = 1, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [10] = {win = 1007, topline = 0, botline = 1, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -3437,47 +2892,47 @@ describe('float window', function() end) it('API has proper error messages', function() - local buf = meths.create_buf(false,false) + local buf = api.nvim_create_buf(false,false) eq("Invalid key: 'bork'", - pcall_err(meths.open_win,buf, false, {width=20,height=2,bork=true})) - eq("'win' key is only valid with relative='win'", - pcall_err(meths.open_win,buf, false, {width=20,height=2,relative='editor',row=0,col=0,win=0})) + pcall_err(api.nvim_open_win, buf, false, {width=20,height=2,bork=true})) + eq("'win' key is only valid with relative='win' and relative=''", + pcall_err(api.nvim_open_win, buf, false, {width=20,height=2,relative='editor',row=0,col=0,win=0})) + eq("floating windows cannot have 'vertical'", + pcall_err(api.nvim_open_win, buf, false, {width=20,height=2,relative='editor',row=0,col=0,vertical=true})) + eq("floating windows cannot have 'split'", + pcall_err(api.nvim_open_win, buf, false, {width=20,height=2,relative='editor',row=0,col=0,split="left"})) eq("Only one of 'relative' and 'external' must be used", - pcall_err(meths.open_win,buf, false, {width=20,height=2,relative='editor',row=0,col=0,external=true})) + pcall_err(api.nvim_open_win, buf, false, {width=20,height=2,relative='editor',row=0,col=0,external=true})) eq("Invalid value of 'relative' key", - pcall_err(meths.open_win,buf, false, {width=20,height=2,relative='shell',row=0,col=0})) + pcall_err(api.nvim_open_win, buf, false, {width=20,height=2,relative='shell',row=0,col=0})) eq("Invalid value of 'anchor' key", - pcall_err(meths.open_win,buf, false, {width=20,height=2,relative='editor',row=0,col=0,anchor='bottom'})) + pcall_err(api.nvim_open_win, buf, false, {width=20,height=2,relative='editor',row=0,col=0,anchor='bottom'})) eq("'relative' requires 'row'/'col' or 'bufpos'", - pcall_err(meths.open_win,buf, false, {width=20,height=2,relative='editor'})) + pcall_err(api.nvim_open_win, buf, false, {width=20,height=2,relative='editor'})) eq("'width' key must be a positive Integer", - pcall_err(meths.open_win,buf, false, {width=-1,height=2,relative='editor', row=0, col=0})) + pcall_err(api.nvim_open_win, buf, false, {width=-1,height=2,relative='editor', row=0, col=0})) eq("'height' key must be a positive Integer", - pcall_err(meths.open_win,buf, false, {width=20,height=-1,relative='editor', row=0, col=0})) + pcall_err(api.nvim_open_win, buf, false, {width=20,height=-1,relative='editor', row=0, col=0})) eq("'height' key must be a positive Integer", - pcall_err(meths.open_win,buf, false, {width=20,height=0,relative='editor', row=0, col=0})) + pcall_err(api.nvim_open_win, buf, false, {width=20,height=0,relative='editor', row=0, col=0})) eq("Must specify 'width'", - pcall_err(meths.open_win,buf, false, {relative='editor', row=0, col=0})) + pcall_err(api.nvim_open_win, buf, false, {relative='editor', row=0, col=0})) eq("Must specify 'height'", - pcall_err(meths.open_win,buf, false, {relative='editor', row=0, col=0, width=2})) + pcall_err(api.nvim_open_win, buf, false, {relative='editor', row=0, col=0, width=2})) end) it('can be placed relative window or cursor', function() screen:try_resize(40,9) - meths.buf_set_lines(0, 0, -1, true, {'just some', 'example text'}) + api.nvim_buf_set_lines(0, 0, -1, true, {'just some', 'example text'}) feed('gge') - local oldwin = meths.get_current_win() + local oldwin = api.nvim_get_current_win() command('below split') if multigrid then screen:expect([[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*3 {5:[No Name] [+] }| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| + [4:----------------------------------------]|*3 {4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -3505,19 +2960,15 @@ describe('float window', function() ]]) end - local buf = meths.create_buf(false,false) + local buf = api.nvim_create_buf(false,false) -- no 'win' arg, relative default window - local win = meths.open_win(buf, false, {relative='win', width=20, height=2, row=0, col=10}) + local win = api.nvim_open_win(buf, false, {relative='win', width=20, height=2, row=0, col=10}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*3 {5:[No Name] [+] }| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| + [4:----------------------------------------]|*3 {4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -3534,7 +2985,7 @@ describe('float window', function() {1: }| {2:~ }| ]], float_pos={ - [5] = {{id = 1002}, "NW", 4, 0, 10, true} + [5] = {1002, "NW", 4, 0, 10, true} }} else screen:expect([[ @@ -3550,17 +3001,13 @@ describe('float window', function() ]]) end - meths.win_set_config(win, {relative='cursor', row=1, col=-2}) + api.nvim_win_set_config(win, {relative='cursor', row=1, col=-2}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*3 {5:[No Name] [+] }| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| + [4:----------------------------------------]|*3 {4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -3577,7 +3024,7 @@ describe('float window', function() {1: }| {2:~ }| ]], float_pos={ - [5] = {{id = 1002}, "NW", 4, 1, 1, true} + [5] = {1002, "NW", 4, 1, 1, true} }} else screen:expect([[ @@ -3593,17 +3040,13 @@ describe('float window', function() ]]) end - meths.win_set_config(win, {relative='cursor', row=0, col=0, anchor='SW'}) + api.nvim_win_set_config(win, {relative='cursor', row=0, col=0, anchor='SW'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*3 {5:[No Name] [+] }| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| + [4:----------------------------------------]|*3 {4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -3620,7 +3063,7 @@ describe('float window', function() {1: }| {2:~ }| ]], float_pos={ - [5] = {{id = 1002}, "SW", 4, 0, 3, true} + [5] = {1002, "SW", 4, 0, 3, true} }} else screen:expect([[ @@ -3636,17 +3079,13 @@ describe('float window', function() ]]) end - meths.win_set_config(win, {relative='win', win=oldwin, row=1, col=10, anchor='NW'}) + api.nvim_win_set_config(win, {relative='win', win=oldwin, row=1, col=10, anchor='NW'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*3 {5:[No Name] [+] }| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| + [4:----------------------------------------]|*3 {4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -3663,7 +3102,7 @@ describe('float window', function() {1: }| {2:~ }| ]], float_pos={ - [5] = {{id = 1002}, "NW", 2, 1, 10, true} + [5] = {1002, "NW", 2, 1, 10, true} }} else screen:expect([[ @@ -3679,17 +3118,13 @@ describe('float window', function() ]]) end - meths.win_set_config(win, {relative='win', win=oldwin, row=3, col=39, anchor='SE'}) + api.nvim_win_set_config(win, {relative='win', win=oldwin, row=3, col=39, anchor='SE'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*3 {5:[No Name] [+] }| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| + [4:----------------------------------------]|*3 {4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -3706,7 +3141,7 @@ describe('float window', function() {1: }| {2:~ }| ]], float_pos={ - [5] = {{id = 1002}, "SE", 2, 3, 39, true} + [5] = {1002, "SE", 2, 3, 39, true} }} else screen:expect([[ @@ -3722,17 +3157,13 @@ describe('float window', function() ]]) end - meths.win_set_config(win, {relative='win', win=0, row=0, col=50, anchor='NE'}) + api.nvim_win_set_config(win, {relative='win', win=0, row=0, col=50, anchor='NE'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*3 {5:[No Name] [+] }| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| + [4:----------------------------------------]|*3 {4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -3749,7 +3180,7 @@ describe('float window', function() {1: }| {2:~ }| ]], float_pos={ - [5] = {{id = 1002}, "NE", 4, 0, 50, true} + [5] = {1002, "NE", 4, 0, 50, true} }, win_viewport = { [2] = { topline = 0, @@ -3758,7 +3189,7 @@ describe('float window', function() curcol = 3, linecount = 2, sum_scroll_delta = 0, - win = { id = 1000 }, + win = 1000, }, [4] = { topline = 0, @@ -3767,7 +3198,7 @@ describe('float window', function() curcol = 3, linecount = 2, sum_scroll_delta = 0, - win = { id = 1001 } + win = 1001 }, [5] = { topline = 0, @@ -3776,7 +3207,7 @@ describe('float window', function() curcol = 0, linecount = 1, sum_scroll_delta = 0, - win = { id = 1002 } + win = 1002 } }} else @@ -3796,108 +3227,78 @@ describe('float window', function() it('always anchor to corner including border', function() screen:try_resize(40,13) - meths.buf_set_lines(0, 0, -1, true, {'just some example text', 'some more example text'}) + api.nvim_buf_set_lines(0, 0, -1, true, {'just some example text', 'some more example text'}) feed('ggeee') command('below split') if multigrid then screen:expect([[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*5 {5:[No Name] [+] }| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| + [4:----------------------------------------]|*5 {4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 just some example text | some more example text | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 3 | ## grid 4 just some exampl^e text | some more example text | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ]]) else screen:expect([[ just some example text | some more example text | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {5:[No Name] [+] }| just some exampl^e text | some more example text | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {4:[No Name] [+] }| | ]]) end - local buf = meths.create_buf(false, false) - meths.buf_set_lines(buf, 0, -1, true, {' halloj! ', + local buf = api.nvim_create_buf(false, false) + api.nvim_buf_set_lines(buf, 0, -1, true, {' halloj! ', ' BORDAA '}) - local win = meths.open_win(buf, false, {relative='cursor', width=9, height=2, row=1, col=-2, border="double"}) + local win = api.nvim_open_win(buf, false, {relative='cursor', width=9, height=2, row=1, col=-2, border="double"}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*5 {5:[No Name] [+] }| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| + [4:----------------------------------------]|*5 {4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 just some example text | some more example text | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 3 | ## grid 4 just some exampl^e text | some more example text | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 5 {5:╔═════════╗}| {5:║}{1: halloj! }{5:║}| {5:║}{1: BORDAA }{5:║}| {5:╚═════════╝}| ]], float_pos={ - [5] = {{id = 1002}, "NW", 4, 1, 14, true} + [5] = {1002, "NW", 4, 1, 14, true} }} else screen:expect([[ just some example text | some more example text | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {5:[No Name] [+] }| just some exampl^e text | some more exam{5:╔═════════╗} | @@ -3909,52 +3310,38 @@ describe('float window', function() ]]) end - meths.win_set_config(win, {relative='cursor', row=0, col=-2, anchor='NE'}) + api.nvim_win_set_config(win, {relative='cursor', row=0, col=-2, anchor='NE'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*5 {5:[No Name] [+] }| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| + [4:----------------------------------------]|*5 {4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 just some example text | some more example text | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 3 | ## grid 4 just some exampl^e text | some more example text | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 5 {5:╔═════════╗}| {5:║}{1: halloj! }{5:║}| {5:║}{1: BORDAA }{5:║}| {5:╚═════════╝}| ]], float_pos={ - [5] = {{id = 1002}, "NE", 4, 0, 14, true} + [5] = {1002, "NE", 4, 0, 14, true} }} else screen:expect([[ just some example text | some more example text | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {5:[No Name] [+] }| jus{5:╔═════════╗}pl^e text | som{5:║}{1: halloj! }{5:║}ple text | @@ -3966,44 +3353,32 @@ describe('float window', function() ]]) end - meths.win_set_config(win, {relative='cursor', row=1, col=-2, anchor='SE'}) + api.nvim_win_set_config(win, {relative='cursor', row=1, col=-2, anchor='SE'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*5 {5:[No Name] [+] }| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| + [4:----------------------------------------]|*5 {4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 just some example text | some more example text | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 3 | ## grid 4 just some exampl^e text | some more example text | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 5 {5:╔═════════╗}| {5:║}{1: halloj! }{5:║}| {5:║}{1: BORDAA }{5:║}| {5:╚═════════╝}| ]], float_pos={ - [5] = {{id = 1002}, "SE", 4, 1, 14, true} + [5] = {1002, "SE", 4, 1, 14, true} }} else screen:expect([[ @@ -4015,52 +3390,38 @@ describe('float window', function() {5:[No║}{1: BORDAA }{5:║ }| jus{5:╚═════════╝}pl^e text | some more example text | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {4:[No Name] [+] }| | ]]) end - meths.win_set_config(win, {relative='cursor', row=0, col=-2, anchor='SW'}) + api.nvim_win_set_config(win, {relative='cursor', row=0, col=-2, anchor='SW'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*5 {5:[No Name] [+] }| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| - [4:----------------------------------------]| + [4:----------------------------------------]|*5 {4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 just some example text | some more example text | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 3 | ## grid 4 just some exampl^e text | some more example text | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 5 {5:╔═════════╗}| {5:║}{1: halloj! }{5:║}| {5:║}{1: BORDAA }{5:║}| {5:╚═════════╝}| ]], float_pos={ - [5] = {{id = 1002}, "SW", 4, 0, 14, true} + [5] = {1002, "SW", 4, 0, 14, true} }} else screen:expect([[ @@ -4072,9 +3433,7 @@ describe('float window', function() {5:[No Name] [+] ╚═════════╝ }| just some exampl^e text | some more example text | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {4:[No Name] [+] }| | ]]) @@ -4121,20 +3480,12 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 - | - | - | + |*3 ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 ## grid 3 | ## grid 5 @@ -4154,14 +3505,14 @@ describe('float window', function() ## grid 12 {1:8 }| ]], float_pos={ - [5] = {{id = 1002}, "NW", 1, 1, 10, true, 50}; - [6] = {{id = 1003}, "NW", 1, 1, 30, true, 50}; - [7] = {{id = 1004}, "NE", 5, 1, 0, true, 50}; - [8] = {{id = 1005}, "NE", 6, 1, 0, true, 50}; - [9] = {{id = 1006}, "SE", 7, 0, 0, true, 50}; - [10] = {{id = 1007}, "SE", 8, 0, 0, true, 50}; - [11] = {{id = 1008}, "SW", 9, 0, 5, true, 50}; - [12] = {{id = 1009}, "SW", 10, 0, 5, true, 50}; + [5] = {1002, "NW", 1, 1, 10, true, 50}; + [6] = {1003, "NW", 1, 1, 30, true, 50}; + [7] = {1004, "NE", 5, 1, 0, true, 50}; + [8] = {1005, "NE", 6, 1, 0, true, 50}; + [9] = {1006, "SE", 7, 0, 0, true, 50}; + [10] = {1007, "SE", 8, 0, 0, true, 50}; + [11] = {1008, "SW", 9, 0, 5, true, 50}; + [12] = {1009, "SW", 10, 0, 5, true, 50}; }} else screen:expect([[ @@ -4169,8 +3520,7 @@ describe('float window', function() {1:5 } {1:1 } {1:6 } {1:2 } | {1:3 } {1:4 } | ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end @@ -4197,20 +3547,12 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 - | - | - | + |*3 ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 ## grid 3 | ## grid 5 @@ -4230,14 +3572,14 @@ describe('float window', function() ## grid 12 {1:8 }| ]], float_pos={ - [5] = {{id = 1002}, "NE", 8, 1, 0, true, 50}; - [6] = {{id = 1003}, "NE", 12, 1, 0, true, 50}; - [7] = {{id = 1004}, "SE", 5, 0, 0, true, 50}; - [8] = {{id = 1005}, "NW", 1, 1, 30, true, 50}; - [9] = {{id = 1006}, "SW", 10, 0, 5, true, 50}; - [10] = {{id = 1007}, "SE", 6, 0, 0, true, 50}; - [11] = {{id = 1008}, "SW", 7, 0, 5, true, 50}; - [12] = {{id = 1009}, "NW", 1, 1, 10, true, 50}; + [5] = {1002, "NE", 8, 1, 0, true, 50}; + [6] = {1003, "NE", 12, 1, 0, true, 50}; + [7] = {1004, "SE", 5, 0, 0, true, 50}; + [8] = {1005, "NW", 1, 1, 30, true, 50}; + [9] = {1006, "SW", 10, 0, 5, true, 50}; + [10] = {1007, "SE", 6, 0, 0, true, 50}; + [11] = {1008, "SW", 7, 0, 5, true, 50}; + [12] = {1009, "NW", 1, 1, 10, true, 50}; }} else screen:expect([[ @@ -4245,8 +3587,7 @@ describe('float window', function() {1:6 } {1:8 } {1:3 } {1:4 } | {1:2 } {1:1 } | ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end @@ -4275,15 +3616,12 @@ describe('float window', function() it('can be placed relative text in a window', function() screen:try_resize(30,5) - local firstwin = meths.get_current_win().id - meths.buf_set_lines(0, 0, -1, true, {'just some', 'example text that is wider than the window', '', '', 'more text'}) + local firstwin = api.nvim_get_current_win() + api.nvim_buf_set_lines(0, 0, -1, true, {'just some', 'example text that is wider than the window', '', '', 'more text'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| + [2:------------------------------]|*4 [3:------------------------------]| ## grid 2 ^just some | @@ -4298,22 +3636,18 @@ describe('float window', function() ^just some | example text that is wider tha| n the window | - | - | + |*2 ]]} end - local buf = meths.create_buf(false,false) - meths.buf_set_lines(buf, 0, -1, true, {'some info!'}) + local buf = api.nvim_create_buf(false,false) + api.nvim_buf_set_lines(buf, 0, -1, true, {'some info!'}) - local win = meths.open_win(buf, false, {relative='win', width=12, height=1, bufpos={1,32}}) + local win = api.nvim_open_win(buf, false, {relative='win', width=12, height=1, bufpos={1,32}}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| + [2:------------------------------]|*4 [3:------------------------------]| ## grid 2 ^just some | @@ -4325,7 +3659,7 @@ describe('float window', function() ## grid 4 {1:some info! }| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 2, 3, 2, true } + [4] = { 1001, "NW", 2, 3, 2, true } }} else screen:expect{grid=[[ @@ -4337,36 +3671,31 @@ describe('float window', function() ]]} end eq({relative='win', width=12, height=1, bufpos={1,32}, anchor='NW', hide=false, - external=false, col=0, row=1, win=firstwin, focusable=true, zindex=50}, meths.win_get_config(win)) + external=false, col=0, row=1, win=firstwin, focusable=true, zindex=50}, api.nvim_win_get_config(win)) feed('<c-e>') if multigrid then screen:expect{grid=[[ ## grid 1 - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| + [2:------------------------------]|*4 [3:------------------------------]| ## grid 2 ^example text that is wider tha| n the window | - | - | + |*2 ## grid 3 | ## grid 4 {1:some info! }| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 2, 2, 2, true }, + [4] = { 1001, "NW", 2, 2, 2, true }, }} else screen:expect{grid=[[ ^example text that is wider tha| n the window | {1:some info! } | - | - | + |*2 ]]} end @@ -4375,22 +3704,18 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*4 [3:---------------------------------------------]| ## grid 2 ^example text that is wider than the window | - | - | + |*2 more text | ## grid 3 | ## grid 4 {1:some info! }| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 2, 1, 32, true } + [4] = { 1001, "NW", 2, 1, 32, true } }} else -- note: appears misaligned due to cursor @@ -4407,32 +3732,20 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| + [2:-------------------------]|*9 [3:-------------------------]| ## grid 2 ^example text that is wide| r than the window | - | - | + |*2 more text | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 | ## grid 4 {1:some info! }| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 2, 2, 7, true } + [4] = { 1001, "NW", 2, 2, 7, true } }} else screen:expect{grid=[[ @@ -4441,56 +3754,37 @@ describe('float window', function() {1:some info! } | | more text | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]} end - meths.win_set_config(win, {relative='win', bufpos={1,32}, anchor='SW'}) + api.nvim_win_set_config(win, {relative='win', bufpos={1,32}, anchor='SW'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| + [2:-------------------------]|*9 [3:-------------------------]| ## grid 2 ^example text that is wide| r than the window | - | - | + |*2 more text | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 | ## grid 4 {1:some info! }| ]], float_pos={ - [4] = { { id = 1001 }, "SW", 2, 1, 7, true } + [4] = { 1001, "SW", 2, 1, 7, true } }} else screen:expect{grid=[[ ^example{1:some info! }s wide| r than the window | - | - | + |*2 more text | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]} end @@ -4500,15 +3794,7 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----]{5:│}[5:--------------------]| - [2:----]{5:│}[5:--------------------]| - [2:----]{5:│}[5:--------------------]| - [2:----]{5:│}[5:--------------------]| - [2:----]{5:│}[5:--------------------]| - [2:----]{5:│}[5:--------------------]| - [2:----]{5:│}[5:--------------------]| - [2:----]{5:│}[5:--------------------]| - [2:----]{5:│}[5:--------------------]| + [2:----]{5:│}[5:--------------------]|*9 [3:-------------------------]| ## grid 2 exam| @@ -4526,16 +3812,9 @@ describe('float window', function() {1:some info! }| ## grid 5 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*8 ]], float_pos={ - [4] = { { id = 1001 }, "SW", 2, 8, 0, true } + [4] = { 1001, "SW", 2, 8, 0, true } }} else screen:expect{grid=[[ @@ -4553,36 +3832,24 @@ describe('float window', function() end command('close') - meths.win_set_config(win, {relative='win', bufpos={1,32}, anchor='NW', col=-2}) + api.nvim_win_set_config(win, {relative='win', bufpos={1,32}, anchor='NW', col=-2}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| + [2:-------------------------]|*9 [3:-------------------------]| ## grid 2 ^example text that is wide| r than the window | - | - | + |*2 more text | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 | ## grid 4 {1:some info! }| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 2, 2, 5, true } + [4] = { 1001, "NW", 2, 2, 5, true } }} else screen:expect{grid=[[ @@ -4591,44 +3858,29 @@ describe('float window', function() {1:some info! } | | more text | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]} end - meths.win_set_config(win, {relative='win', bufpos={1,32}, row=2}) + api.nvim_win_set_config(win, {relative='win', bufpos={1,32}, row=2}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| + [2:-------------------------]|*9 [3:-------------------------]| ## grid 2 ^example text that is wide| r than the window | - | - | + |*2 more text | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 | ## grid 4 {1:some info! }| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 2, 3, 7, true } + [4] = { 1001, "NW", 2, 3, 7, true } }} else screen:expect{grid=[[ @@ -4637,10 +3889,7 @@ describe('float window', function() | {1:some info! } | more text | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]} end @@ -4649,44 +3898,24 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| + [2:-------------------------]|*9 [3:-------------------------]| ## grid 2 {28:^+-- 5 lines: just some··}| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*8 ## grid 3 | ## grid 4 {1:some info! }| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 2, 2, 0, true } + [4] = { 1001, "NW", 2, 2, 0, true } }} else screen:expect{grid=[[ {28:^+-- 5 lines: just some··}| {0:~ }| {1:some info! }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 | ]]} end @@ -4699,57 +3928,44 @@ describe('float window', function() if multigrid then screen:expect([[ ## grid 1 - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| + [2:------------------------------]|*4 [3:------------------------------]| ## grid 2 that is wider than the windo^w | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 3 | ]]) else screen:expect([[ that is wider than the windo^w | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) end - local buf = meths.create_buf(false,true) - meths.buf_set_lines(buf, 0, -1, true, {'some floaty text'}) - meths.open_win(buf, false, {relative='editor', width=20, height=1, row=3, col=1}) + local buf = api.nvim_create_buf(false,true) + api.nvim_buf_set_lines(buf, 0, -1, true, {'some floaty text'}) + api.nvim_open_win(buf, false, {relative='editor', width=20, height=1, row=3, col=1}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| + [2:------------------------------]|*4 [3:------------------------------]| ## grid 2 that is wider than the windo^w | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 3 | ## grid 4 {1:some floaty text }| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 3, 1, true} + [4] = {1001, "NW", 1, 3, 1, true} }} else screen:expect([[ that is wider than the windo^w | - {0:~ }| - {0:~ }| + {0:~ }|*2 {0:~}{1:some floaty text }{0: }| | ]]) @@ -4763,19 +3979,15 @@ describe('float window', function() local screen2 = Screen.new(40,7) screen2:attach(nil, session2) screen2:set_default_attr_ids(attrs) - local buf = meths.create_buf(false,false) - meths.open_win(buf, true, {relative='editor', width=20, height=2, row=2, col=5}) + local buf = api.nvim_create_buf(false,false) + api.nvim_open_win(buf, true, {relative='editor', width=20, height=2, row=2, col=5}) local expected_pos = { - [2]={{id=1001}, 'NW', 1, 2, 5} + [2]={1001, 'NW', 1, 2, 5} } screen:expect{grid=[[ ## grid 1 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ## grid 2 {1:^ }| @@ -4786,8 +3998,7 @@ describe('float window', function() {0:~ }| {0:~ }{1:^ }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end) @@ -4795,29 +4006,20 @@ describe('float window', function() it('handles resized screen', function() - local buf = meths.create_buf(false,false) - meths.buf_set_lines(buf, 0, -1, true, {'such', 'very', 'float'}) - local win = meths.open_win(buf, false, {relative='editor', width=15, height=4, row=2, col=10}) + local buf = api.nvim_create_buf(false,false) + api.nvim_buf_set_lines(buf, 0, -1, true, {'such', 'very', 'float'}) + local win = api.nvim_open_win(buf, false, {relative='editor', width=15, height=4, row=2, col=10}) local expected_pos = { - [4]={{id=1001}, 'NW', 1, 2, 10, true}, + [4]={1001, 'NW', 1, 2, 10, true}, } if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -4842,16 +4044,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*4 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 3 | ## grid 4 @@ -4874,14 +4071,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*3 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 ## grid 3 | ## grid 4 @@ -4903,8 +4097,7 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*2 [3:----------------------------------------]| ## grid 2 ^ | @@ -4928,8 +4121,7 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*2 [3:----------------------------------------]| ## grid 2 | @@ -4954,20 +4146,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -4988,25 +4171,16 @@ describe('float window', function() ]]) end - meths.win_set_config(win, {height=3}) + api.nvim_win_set_config(win, {height=3}) feed('gg') if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -5030,20 +4204,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:--------------------------]| - [2:--------------------------]| - [2:--------------------------]| - [2:--------------------------]| - [2:--------------------------]| - [2:--------------------------]| + [2:--------------------------]|*6 [3:--------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -5067,20 +4232,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| + [2:-------------------------]|*6 [3:-------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -5104,20 +4260,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:------------------------]| - [2:------------------------]| - [2:------------------------]| - [2:------------------------]| - [2:------------------------]| - [2:------------------------]| + [2:------------------------]|*6 [3:------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -5141,20 +4288,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------]| - [2:----------------]| - [2:----------------]| - [2:----------------]| - [2:----------------]| - [2:----------------]| + [2:----------------]|*6 [3:----------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -5178,20 +4316,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:---------------]| - [2:---------------]| - [2:---------------]| - [2:---------------]| - [2:---------------]| - [2:---------------]| + [2:---------------]|*6 [3:---------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -5215,20 +4344,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:--------------]| - [2:--------------]| - [2:--------------]| - [2:--------------]| - [2:--------------]| - [2:--------------]| + [2:--------------]|*6 [3:--------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -5252,20 +4372,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:------------]| - [2:------------]| - [2:------------]| - [2:------------]| - [2:------------]| - [2:------------]| + [2:------------]|*6 [3:------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -5312,20 +4423,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -5348,14 +4450,14 @@ describe('float window', function() it('does not crash with inccommand #9379', function() local expected_pos = { - [4]={{id=1001}, 'NW', 1, 2, 0, true}, + [4]={1001, 'NW', 1, 2, 0, true}, } command("set inccommand=split") command("set laststatus=2") - local buf = meths.create_buf(false,false) - meths.open_win(buf, true, {relative='editor', width=30, height=3, row=2, col=0}) + local buf = api.nvim_create_buf(false,false) + api.nvim_open_win(buf, true, {relative='editor', width=30, height=3, row=2, col=0}) insert([[ foo @@ -5365,19 +4467,12 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*5 {5:[No Name] }| [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 | ## grid 4 @@ -5402,11 +4497,7 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*5 {5:[Preview] }| [3:----------------------------------------]| ## grid 2 @@ -5435,19 +4526,12 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*5 {5:[No Name] }| [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 | ## grid 4 @@ -5469,52 +4553,39 @@ describe('float window', function() end) it('does not crash when set cmdheight #9680', function() - local buf = meths.create_buf(false,false) - meths.open_win(buf, false, {relative='editor', width=20, height=2, row=2, col=5}) + local buf = api.nvim_create_buf(false,false) + api.nvim_open_win(buf, false, {relative='editor', width=20, height=2, row=2, col=5}) command("set cmdheight=2") - eq(1, meths.eval('1')) + eq(1, api.nvim_eval('1')) end) describe('and completion', function() before_each(function() - local buf = meths.create_buf(false,false) - local win = meths.open_win(buf, true, {relative='editor', width=12, height=4, row=2, col=5}).id - meths.set_option_value('winhl', 'Normal:ErrorMsg', {win=win}) + local buf = api.nvim_create_buf(false,false) + local win = api.nvim_open_win(buf, true, {relative='editor', width=12, height=4, row=2, col=5}) + api.nvim_set_option_value('winhl', 'Normal:ErrorMsg', {win=win}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 {7:^ }| - {12:~ }| - {12:~ }| - {12:~ }| + {12:~ }|*3 ]], float_pos={ - [4] = {{ id = 1001 }, "NW", 1, 2, 5, true}, + [4] = {1001, "NW", 1, 2, 5, true}, }} else screen:expect([[ | {0:~ }| {0:~ }{7:^ }{0: }| - {0:~ }{12:~ }{0: }| - {0:~ }{12:~ }{0: }| - {0:~ }{12:~ }{0: }| + {0:~ }{12:~ }{0: }|*3 | ]]) end @@ -5522,38 +4593,27 @@ describe('float window', function() it('with builtin popupmenu', function() feed('ix ') - funcs.complete(3, {'aa', 'word', 'longtext'}) + fn.complete(3, {'aa', 'word', 'longtext'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 {3:-- INSERT --} | ## grid 4 {7:x aa^ }| - {12:~ }| - {12:~ }| - {12:~ }| + {12:~ }|*3 ## grid 5 {13: aa }| {1: word }| {1: longtext }| ]], float_pos={ - [4] = {{ id = 1001 }, "NW", 1, 2, 5, true, 50}, - [5] = {{ id = -1 }, "NW", 4, 1, 1, false, 100} + [4] = {1001, "NW", 1, 2, 5, true, 50}, + [5] = {-1, "NW", 4, 1, 1, false, 100} }} else screen:expect([[ @@ -5571,29 +4631,18 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 {7:x a^a }| - {12:~ }| - {12:~ }| - {12:~ }| + {12:~ }|*3 ]], float_pos={ - [4] = {{ id = 1001 }, "NW", 1, 2, 5, true}, + [4] = {1001, "NW", 1, 2, 5, true}, }} else @@ -5601,46 +4650,33 @@ describe('float window', function() | {0:~ }| {0:~ }{7:x a^a }{0: }| - {0:~ }{12:~ }{0: }| - {0:~ }{12:~ }{0: }| - {0:~ }{12:~ }{0: }| + {0:~ }{12:~ }{0: }|*3 | ]]) end feed('<c-w>wi') - funcs.complete(1, {'xx', 'yy', 'zz'}) + fn.complete(1, {'xx', 'yy', 'zz'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 xx^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 {3:-- INSERT --} | ## grid 4 {7:x aa }| - {12:~ }| - {12:~ }| - {12:~ }| + {12:~ }|*3 ## grid 5 {13:xx }| {1:yy }| {1:zz }| ]], float_pos={ - [4] = {{ id = 1001 }, "NW", 1, 2, 5, true, 50}, - [5] = {{ id = -1 }, "NW", 2, 1, 0, false, 100} + [4] = {1001, "NW", 1, 2, 5, true, 50}, + [5] = {-1, "NW", 2, 1, 0, false, 100} }} else screen:expect([[ @@ -5648,8 +4684,7 @@ describe('float window', function() {13:xx }{0: }| {1:yy }{7: }{0: }| {1:zz }{12: }{0: }| - {0:~ }{12:~ }{0: }| - {0:~ }{12:~ }{0: }| + {0:~ }{12:~ }{0: }|*2 {3:-- INSERT --} | ]]) end @@ -5658,38 +4693,25 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 xx^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 {3:-- INSERT --} | ## grid 4 {7:x aa }| - {12:~ }| - {12:~ }| - {12:~ }| + {12:~ }|*3 ]], float_pos={ - [4] = {{ id = 1001 }, "NW", 1, 2, 5, true}, + [4] = {1001, "NW", 1, 2, 5, true}, }} else screen:expect([[ xx^ | {0:~ }| {0:~ }{7:x aa }{0: }| - {0:~ }{12:~ }{0: }| - {0:~ }{12:~ }{0: }| - {0:~ }{12:~ }{0: }| + {0:~ }{12:~ }{0: }|*3 {3:-- INSERT --} | ]]) end @@ -5701,33 +4723,22 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 :sign un^ | ## grid 4 {7: }| - {12:~ }| - {12:~ }| - {12:~ }| + {12:~ }|*3 ## grid 5 {1: undefine }| {1: unplace }| ]], float_pos={ - [5] = {{id = -1}, "SW", 1, 6, 5, false, 250}; - [4] = {{id = 1001}, "NW", 1, 2, 5, true, 50}; + [5] = {-1, "SW", 1, 6, 5, false, 250}; + [4] = {1001, "NW", 1, 2, 5, true, 50}; }} else screen:expect{grid=[[ @@ -5745,34 +4756,23 @@ describe('float window', function() it('with ext_popupmenu', function() screen:set_option('ext_popupmenu', true) feed('ix ') - funcs.complete(3, {'aa', 'word', 'longtext'}) + fn.complete(3, {'aa', 'word', 'longtext'}) local items = {{"aa", "", "", ""}, {"word", "", "", ""}, {"longtext", "", "", ""}} if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 {3:-- INSERT --} | ## grid 4 {7:x aa^ }| - {12:~ }| - {12:~ }| - {12:~ }| + {12:~ }|*3 ]], float_pos={ - [4] = {{ id = 1001 }, "NW", 1, 2, 5, true}, + [4] = {1001, "NW", 1, 2, 5, true}, }, popupmenu={ anchor = {4, 0, 2}, items = items, pos = 0 }} @@ -5781,9 +4781,7 @@ describe('float window', function() | {0:~ }| {0:~ }{7:x aa^ }{0: }| - {0:~ }{12:~ }{0: }| - {0:~ }{12:~ }{0: }| - {0:~ }{12:~ }{0: }| + {0:~ }{12:~ }{0: }|*3 {3:-- INSERT --} | ]], popupmenu={ anchor = {1, 2, 7}, items = items, pos = 0 @@ -5794,71 +4792,47 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 {7:x a^a }| - {12:~ }| - {12:~ }| - {12:~ }| + {12:~ }|*3 ]], float_pos={ - [4] = {{ id = 1001 }, "NW", 1, 2, 5, true}, + [4] = {1001, "NW", 1, 2, 5, true}, }} else screen:expect([[ | {0:~ }| {0:~ }{7:x a^a }{0: }| - {0:~ }{12:~ }{0: }| - {0:~ }{12:~ }{0: }| - {0:~ }{12:~ }{0: }| + {0:~ }{12:~ }{0: }|*3 | ]]) end feed('<c-w>wi') - funcs.complete(1, {'xx', 'yy', 'zz'}) + fn.complete(1, {'xx', 'yy', 'zz'}) items = {{"xx", "", "", ""}, {"yy", "", "", ""}, {"zz", "", "", ""}} if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 xx^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 {3:-- INSERT --} | ## grid 4 {7:x aa }| - {12:~ }| - {12:~ }| - {12:~ }| + {12:~ }|*3 ]], float_pos={ - [4] = {{ id = 1001 }, "NW", 1, 2, 5, true}, + [4] = {1001, "NW", 1, 2, 5, true}, }, popupmenu={ anchor = {2, 0, 0}, items = items, pos = 0 }} @@ -5867,9 +4841,7 @@ describe('float window', function() xx^ | {0:~ }| {0:~ }{7:x aa }{0: }| - {0:~ }{12:~ }{0: }| - {0:~ }{12:~ }{0: }| - {0:~ }{12:~ }{0: }| + {0:~ }{12:~ }{0: }|*3 {3:-- INSERT --} | ]], popupmenu={ anchor = {1, 0, 0}, items = items, pos = 0 @@ -5880,38 +4852,25 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 xx^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 {3:-- INSERT --} | ## grid 4 {7:x aa }| - {12:~ }| - {12:~ }| - {12:~ }| + {12:~ }|*3 ]], float_pos={ - [4] = {{ id = 1001 }, "NW", 1, 2, 5, true}, + [4] = {1001, "NW", 1, 2, 5, true}, }} else screen:expect([[ xx^ | {0:~ }| {0:~ }{7:x aa }{0: }| - {0:~ }{12:~ }{0: }| - {0:~ }{12:~ }{0: }| - {0:~ }{12:~ }{0: }| + {0:~ }{12:~ }{0: }|*3 {3:-- INSERT --} | ]]) end @@ -5921,26 +4880,17 @@ describe('float window', function() describe('float shown after pum', function() local win before_each(function() - command('hi NormalFloat guibg=#333333') + command('hi NormalFloat guibg=#333333 guifg=NONE') feed('i') - funcs.complete(1, {'aa', 'word', 'longtext'}) + fn.complete(1, {'aa', 'word', 'longtext'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 aa^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 {3:-- INSERT --} | ## grid 4 @@ -5948,7 +4898,7 @@ describe('float window', function() {1:word }| {1:longtext }| ]], float_pos={ - [4] = {{id = -1}, "NW", 2, 1, 0, false, 100}} + [4] = {-1, "NW", 2, 1, 0, false, 100}} } else screen:expect([[ @@ -5956,32 +4906,22 @@ describe('float window', function() {13:aa }{0: }| {1:word }{0: }| {1:longtext }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:-- INSERT --} | ]]) end - local buf = meths.create_buf(false,true) - meths.buf_set_lines(buf,0,-1,true,{"some info", "about item"}) - win = meths.open_win(buf, false, {relative='cursor', width=12, height=2, row=1, col=10}) + local buf = api.nvim_create_buf(false,true) + api.nvim_buf_set_lines(buf,0,-1,true,{"some info", "about item"}) + win = api.nvim_open_win(buf, false, {relative='cursor', width=12, height=2, row=1, col=10}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 aa^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 {3:-- INSERT --} | ## grid 4 @@ -5992,8 +4932,8 @@ describe('float window', function() {15:some info }| {15:about item }| ]], float_pos={ - [4] = {{id = -1}, "NW", 2, 1, 0, false, 100}, - [5] = {{id = 1001}, "NW", 2, 1, 12, true, 50}, + [4] = {-1, "NW", 2, 1, 0, false, 100}, + [5] = {1001, "NW", 2, 1, 12, true, 50}, }} else screen:expect([[ @@ -6001,8 +4941,7 @@ describe('float window', function() {13:aa }{15:e info }{0: }| {1:word }{15:ut item }{0: }| {1:longtext }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:-- INSERT --} | ]]) end @@ -6013,93 +4952,60 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 aa^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 {3:-- INSERT --} | ## grid 5 {15:some info }| {15:about item }| ]], float_pos={ - [5] = {{id = 1001}, "NW", 2, 1, 12, true}, + [5] = {1001, "NW", 2, 1, 12, true}, }} else screen:expect([[ aa^ | {0:~ }{15:some info }{0: }| {0:~ }{15:about item }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- INSERT --} | ]]) end - meths.win_close(win, false) + api.nvim_win_close(win, false) if multigrid then screen:expect([[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 aa^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 {3:-- INSERT --} | ]]) else screen:expect([[ aa^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- INSERT --} | ]]) end end) it('and close float first', function() - meths.win_close(win, false) + api.nvim_win_close(win, false) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 aa^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 {3:-- INSERT --} | ## grid 4 @@ -6107,7 +5013,7 @@ describe('float window', function() {1:word }| {1:longtext }| ]], float_pos={ - [4] = {{id = -1}, "NW", 2, 1, 0, false, 100}, + [4] = {-1, "NW", 2, 1, 0, false, 100}, }} else screen:expect([[ @@ -6115,8 +5021,7 @@ describe('float window', function() {13:aa }{0: }| {1:word }{0: }| {1:longtext }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:-- INSERT --} | ]]) end @@ -6125,31 +5030,18 @@ describe('float window', function() if multigrid then screen:expect([[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 aa^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 {3:-- INSERT --} | ]]) else screen:expect([[ aa^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- INSERT --} | ]]) end @@ -6157,38 +5049,29 @@ describe('float window', function() end) it("can use Normal as background", function() - local buf = meths.create_buf(false,false) - meths.buf_set_lines(buf,0,-1,true,{"here", "float"}) - local win = meths.open_win(buf, false, {relative='editor', width=20, height=2, row=2, col=5}) - meths.set_option_value('winhl', 'Normal:Normal', {win=win}) + local buf = api.nvim_create_buf(false,false) + api.nvim_buf_set_lines(buf,0,-1,true,{"here", "float"}) + local win = api.nvim_open_win(buf, false, {relative='editor', width=20, height=2, row=2, col=5}) + api.nvim_set_option_value('winhl', 'Normal:Normal', {win=win}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 here | float | ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 2, 5, true, 50}; + [4] = {1001, "NW", 1, 2, 5, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -6196,8 +5079,7 @@ describe('float window', function() {0:~ }| {0:~ }here {0: }| {0:~ }float {0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]} end @@ -6210,30 +5092,21 @@ describe('float window', function() -- the default, but be explicit: command("set laststatus=1") command("set hidden") - meths.buf_set_lines(0,0,-1,true,{"x"}) - local buf = meths.create_buf(false,false) - win = meths.open_win(buf, false, {relative='editor', width=20, height=2, row=2, col=5}) - meths.buf_set_lines(buf,0,-1,true,{"y"}) + api.nvim_buf_set_lines(0,0,-1,true,{"x"}) + local buf = api.nvim_create_buf(false,false) + win = api.nvim_open_win(buf, false, {relative='editor', width=20, height=2, row=2, col=5}) + api.nvim_buf_set_lines(buf,0,-1,true,{"y"}) expected_pos = { - [4]={{id=1001}, 'NW', 1, 2, 5, true} + [4]={1001, 'NW', 1, 2, 5, true} } if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -6246,8 +5119,7 @@ describe('float window', function() {0:~ }| {0:~ }{1:y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end @@ -6258,20 +5130,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -6284,8 +5147,7 @@ describe('float window', function() {0:~ }| {0:~ }{1:^y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end @@ -6294,20 +5156,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -6320,34 +5173,24 @@ describe('float window', function() {0:~ }| {0:~ }{1:y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end end) it("w with focusable=false", function() - meths.win_set_config(win, {focusable=false}) + api.nvim_win_set_config(win, {focusable=false}) expected_pos[4][6] = false feed("<c-w>wi") -- i to provoke redraw if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 {3:-- INSERT --} | ## grid 4 @@ -6360,8 +5203,7 @@ describe('float window', function() {0:~ }| {0:~ }{1:y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:-- INSERT --} | ]]) end @@ -6370,20 +5212,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -6396,8 +5229,7 @@ describe('float window', function() {0:~ }| {0:~ }{1:y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end @@ -6408,20 +5240,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -6434,8 +5257,7 @@ describe('float window', function() {0:~ }| {0:~ }{1:^y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end @@ -6444,20 +5266,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -6470,8 +5283,7 @@ describe('float window', function() {0:~ }| {0:~ }{1:y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end @@ -6479,23 +5291,14 @@ describe('float window', function() it("focus by mouse", function() if multigrid then - meths.input_mouse('left', 'press', '', 4, 0, 0) + api.nvim_input_mouse('left', 'press', '', 4, 0, 0) screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -6503,36 +5306,26 @@ describe('float window', function() {2:~ }| ]], float_pos=expected_pos} else - meths.input_mouse('left', 'press', '', 0, 2, 5) + api.nvim_input_mouse('left', 'press', '', 0, 2, 5) screen:expect([[ x | {0:~ }| {0:~ }{1:^y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end if multigrid then - meths.input_mouse('left', 'press', '', 2, 0, 0) + api.nvim_input_mouse('left', 'press', '', 2, 0, 0) screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -6540,41 +5333,32 @@ describe('float window', function() {2:~ }| ]], float_pos=expected_pos} else - meths.input_mouse('left', 'press', '', 0, 0, 0) + api.nvim_input_mouse('left', 'press', '', 0, 0, 0) screen:expect([[ ^x | {0:~ }| {0:~ }{1:y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end end) it("focus by mouse (focusable=false)", function() - meths.win_set_config(win, {focusable=false}) - meths.buf_set_lines(0, -1, -1, true, {"a"}) + api.nvim_win_set_config(win, {focusable=false}) + api.nvim_buf_set_lines(0, -1, -1, true, {"a"}) expected_pos[4][6] = false if multigrid then - meths.input_mouse('left', 'press', '', 4, 0, 0) + api.nvim_input_mouse('left', 'press', '', 4, 0, 0) screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^x | a | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 | ## grid 4 @@ -6582,36 +5366,27 @@ describe('float window', function() {2:~ }| ]], float_pos=expected_pos} else - meths.input_mouse('left', 'press', '', 0, 2, 5) + api.nvim_input_mouse('left', 'press', '', 0, 2, 5) screen:expect([[ x | ^a | {0:~ }{1:y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end if multigrid then - meths.input_mouse('left', 'press', '', 2, 0, 0) + api.nvim_input_mouse('left', 'press', '', 2, 0, 0) screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^x | a | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 | ## grid 4 @@ -6619,14 +5394,13 @@ describe('float window', function() {2:~ }| ]], float_pos=expected_pos, unchanged=true} else - meths.input_mouse('left', 'press', '', 0, 0, 0) + api.nvim_input_mouse('left', 'press', '', 0, 0, 0) screen:expect([[ ^x | a | {0:~ }{1:y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end @@ -6637,20 +5411,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 {3:-- INSERT --} | ## grid 4 @@ -6663,8 +5428,7 @@ describe('float window', function() {0:~ }| {0:~ }{1:y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:-- INSERT --} | ]]) end @@ -6673,20 +5437,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -6699,8 +5454,7 @@ describe('float window', function() {0:~ }| {0:~ }{1:^y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end @@ -6709,20 +5463,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -6735,8 +5480,7 @@ describe('float window', function() {0:~ }| {0:~ }{1:y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end @@ -6748,20 +5492,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -6774,8 +5509,7 @@ describe('float window', function() {0:~ }| {0:~ }{1:^y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end @@ -6784,34 +5518,23 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 {1:^y }| - {2:~ }| - {2:~ }| + {2:~ }|*2 ]], float_pos=expected_pos} else screen:expect([[ x | {0:~ }| {0:~ }{1:^y }{0: }| - {0:~ }{2:~ }{0: }| - {0:~ }{2:~ }{0: }| + {0:~ }{2:~ }{0: }|*2 {0:~ }| | ]]) @@ -6821,20 +5544,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -6845,9 +5559,7 @@ describe('float window', function() x | {0:~ }| {0:~ }{1:^y }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) end @@ -6856,36 +5568,23 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 {1:^y }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 ]], float_pos=expected_pos} else screen:expect([[ x | {0:~ }| {0:~ }{1:^y }{0: }| - {0:~ }{2:~ }{0: }| - {0:~ }{2:~ }{0: }| - {0:~ }{2:~ }{0: }| + {0:~ }{2:~ }{0: }|*3 | ]]) end @@ -6894,38 +5593,21 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 {1:^y }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*5 ]], float_pos=expected_pos} else screen:expect([[ x {1:^y } | - {0:~ }{2:~ }{0: }| - {0:~ }{2:~ }{0: }| - {0:~ }{2:~ }{0: }| - {0:~ }{2:~ }{0: }| - {0:~ }{2:~ }{0: }| + {0:~ }{2:~ }{0: }|*5 | ]]) end @@ -6936,20 +5618,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -6962,8 +5635,7 @@ describe('float window', function() {0:~ }| {0:~ }{1:^y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end @@ -6972,20 +5644,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -6998,8 +5661,7 @@ describe('float window', function() {0:~ }| {0:~ }{1:^y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end @@ -7008,20 +5670,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -7034,8 +5687,7 @@ describe('float window', function() {0:~ }| {0:~ }{1:^y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end @@ -7044,20 +5696,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -7070,8 +5713,7 @@ describe('float window', function() {0:~ }| {0:~ }{1:^y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end @@ -7080,20 +5722,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -7106,8 +5739,7 @@ describe('float window', function() {0:~ }| {1:^y }| {2:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end @@ -7118,11 +5750,9 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [5:----------------------------------------]| - [5:----------------------------------------]| + [5:----------------------------------------]|*2 {4:[No Name] [+] }| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*2 {5:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -7153,11 +5783,9 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [5:----------------------------------------]| - [5:----------------------------------------]| + [5:----------------------------------------]|*2 {5:[No Name] [+] }| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*2 {4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -7188,11 +5816,9 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [5:----------------------------------------]| - [5:----------------------------------------]| + [5:----------------------------------------]|*2 {5:[No Name] [+] }| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*2 {5:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -7224,11 +5850,9 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [5:----------------------------------------]| - [5:----------------------------------------]| + [5:----------------------------------------]|*2 {4:[No Name] [+] }| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*2 {5:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -7261,11 +5885,9 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [5:----------------------------------------]| - [5:----------------------------------------]| + [5:----------------------------------------]|*2 {4:[No Name] [+] }| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*2 {5:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -7296,11 +5918,9 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [5:----------------------------------------]| - [5:----------------------------------------]| + [5:----------------------------------------]|*2 {5:[No Name] [+] }| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*2 {4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -7331,11 +5951,9 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [5:----------------------------------------]| - [5:----------------------------------------]| + [5:----------------------------------------]|*2 {5:[No Name] [+] }| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*2 {4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -7368,11 +5986,9 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [5:----------------------------------------]| - [5:----------------------------------------]| + [5:----------------------------------------]|*2 {4:[No Name] }| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*2 {5:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -7405,11 +6021,9 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [5:----------------------------------------]| - [5:----------------------------------------]| + [5:----------------------------------------]|*2 {4:[No Name] }| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*2 {5:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -7442,19 +6056,12 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [5:--------------------]{5:│}[2:-------------------]| - [5:--------------------]{5:│}[2:-------------------]| - [5:--------------------]{5:│}[2:-------------------]| - [5:--------------------]{5:│}[2:-------------------]| - [5:--------------------]{5:│}[2:-------------------]| + [5:--------------------]{5:│}[2:-------------------]|*5 {4:[No Name] [+] }{5:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 | ## grid 4 @@ -7462,10 +6069,7 @@ describe('float window', function() {2:~ }| ## grid 5 ^x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ]], float_pos=expected_pos} else screen:expect([[ @@ -7485,19 +6089,12 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [5:--------------------]{5:│}[2:-------------------]| - [5:--------------------]{5:│}[2:-------------------]| - [5:--------------------]{5:│}[2:-------------------]| - [5:--------------------]{5:│}[2:-------------------]| - [5:--------------------]{5:│}[2:-------------------]| + [5:--------------------]{5:│}[2:-------------------]|*5 {4:[No Name] }{5:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 :vnew | ## grid 4 @@ -7505,10 +6102,7 @@ describe('float window', function() {2:~ }| ## grid 5 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ]], float_pos=expected_pos} else screen:expect([[ @@ -7528,19 +6122,12 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [5:--------------------]{5:│}[2:-------------------]| - [5:--------------------]{5:│}[2:-------------------]| - [5:--------------------]{5:│}[2:-------------------]| - [5:--------------------]{5:│}[2:-------------------]| - [5:--------------------]{5:│}[2:-------------------]| + [5:--------------------]{5:│}[2:-------------------]|*5 {4:[No Name] }{5:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 :vnew | ## grid 4 @@ -7548,10 +6135,7 @@ describe('float window', function() {2:~ }| ## grid 5 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ]], float_pos=expected_pos} else screen:expect([[ @@ -7592,24 +6176,15 @@ describe('float window', function() -- enter first float feed('<c-w><c-w>') -- enter second float - meths.open_win(0, true, {relative='editor', width=20, height=2, row=4, col=8}) + api.nvim_open_win(0, true, {relative='editor', width=20, height=2, row=4, col=8}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -7619,8 +6194,8 @@ describe('float window', function() {1:^y }| {2:~ }| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 2, 5, true}, - [5] = {{id = 1002}, "NW", 1, 4, 8, true} + [4] = {1001, "NW", 1, 2, 5, true}, + [5] = {1002, "NW", 1, 4, 8, true} }} else screen:expect([[ @@ -7638,27 +6213,18 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 :quit | ## grid 4 {1:^y }| {2:~ }| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 2, 5, true}, + [4] = {1001, "NW", 1, 2, 5, true}, }} else screen:expect([[ @@ -7666,8 +6232,7 @@ describe('float window', function() {0:~ }| {0:~ }{1:^y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 :quit | ]]) end @@ -7676,31 +6241,18 @@ describe('float window', function() if multigrid then screen:expect([[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 :quit | ]]) else screen:expect([[ ^x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 :quit | ]]) end @@ -7713,31 +6265,18 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ]]} else screen:expect([[ ^x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) end @@ -7748,20 +6287,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [3:----------------------------------------]| - [3:----------------------------------------]| - [3:----------------------------------------]| + [2:----------------------------------------]|*4 + [3:----------------------------------------]|*3 ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 {7:E5601: Cannot close window, only floatin}| {7:g window would remain} | @@ -7787,20 +6317,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -7813,8 +6334,7 @@ describe('float window', function() {0:~ }| {0:~ }{1:^y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end @@ -7825,11 +6345,9 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [5:----------------------------------------]| - [5:----------------------------------------]| + [5:----------------------------------------]|*2 {4:[No Name] [+] }| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*2 {5:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -7860,31 +6378,18 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [5:----------------------------------------]| - [5:----------------------------------------]| - [5:----------------------------------------]| - [5:----------------------------------------]| - [5:----------------------------------------]| - [5:----------------------------------------]| + [5:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 3 | ## grid 5 ^x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ]]} else screen:expect([[ ^x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) end @@ -7895,11 +6400,9 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [5:----------------------------------------]| - [5:----------------------------------------]| + [5:----------------------------------------]|*2 {5:[No Name] [+] }| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*2 {5:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -7930,13 +6433,10 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [5:----------------------------------------]| - [5:----------------------------------------]| + [5:----------------------------------------]|*2 {5:[No Name] [+] }| [2:----------------------------------------]| - [3:----------------------------------------]| - [3:----------------------------------------]| - [3:----------------------------------------]| + [3:----------------------------------------]|*3 ## grid 2 x | {0:~ }| @@ -7969,11 +6469,9 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*2 {5:[No Name] [+] }| - [4:----------------------------------------]| - [4:----------------------------------------]| + [4:----------------------------------------]|*2 {4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -7998,23 +6496,16 @@ describe('float window', function() end if multigrid then - meths.win_set_config(0, {external=true, width=30, height=2}) + api.nvim_win_set_config(0, {external=true, width=30, height=2}) expected_pos = {[4]={external=true}} screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*5 {5:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 | ## grid 4 @@ -8023,7 +6514,7 @@ describe('float window', function() ]], float_pos=expected_pos} else eq("UI doesn't support external windows", - pcall_err(meths.win_set_config, 0, {external=true, width=30, height=2})) + pcall_err(api.nvim_win_set_config, 0, {external=true, width=30, height=2})) return end @@ -8031,11 +6522,9 @@ describe('float window', function() if multigrid then screen:expect([[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*2 {5:[No Name] [+] }| - [4:----------------------------------------]| - [4:----------------------------------------]| + [4:----------------------------------------]|*2 {4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -8051,24 +6540,15 @@ describe('float window', function() end) it('J (float with border)', function() - meths.win_set_config(win, {relative='editor', width=20, height=2, row=2, col=5, border='single'}) + api.nvim_win_set_config(win, {relative='editor', width=20, height=2, row=2, col=5, border='single'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -8093,11 +6573,9 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*2 {5:[No Name] [+] }| - [4:----------------------------------------]| - [4:----------------------------------------]| + [4:----------------------------------------]|*2 {4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -8128,11 +6606,9 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [6:--------------------]{5:│}[5:-------------------]| - [6:--------------------]{5:│}[5:-------------------]| + [6:--------------------]{5:│}[5:-------------------]|*2 {5:[No Name] [+] [No Name] [+] }| - [7:--------------------]{5:│}[2:-------------------]| - [7:--------------------]{5:│}[2:-------------------]| + [7:--------------------]{5:│}[2:-------------------]|*2 {4:[No Name] [+] }{5:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -8169,17 +6645,15 @@ describe('float window', function() for i = 1,5 do feed(i.."<c-w>w") feed_command("enew") - curbufmeths.set_lines(0,-1,true,{tostring(i)}) + api.nvim_buf_set_lines(0, 0,-1,true,{tostring(i)}) end if multigrid then screen:expect{grid=[[ ## grid 1 - [6:-------------------]{5:│}[5:--------------------]| - [6:-------------------]{5:│}[5:--------------------]| + [6:-------------------]{5:│}[5:--------------------]|*2 {5:[No Name] [+] [No Name] [+] }| - [7:-------------------]{5:│}[2:--------------------]| - [7:-------------------]{5:│}[2:--------------------]| + [7:-------------------]{5:│}[2:--------------------]|*2 {5:[No Name] [+] [No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -8227,7 +6701,7 @@ describe('float window', function() for i = 1,5 do feed(i.."<c-w>w") feed('<c-w>'..k) - local nr = funcs.winnr() + local nr = fn.winnr() eq(v[i],nr, "when using <c-w>"..k.." from window "..i) end end @@ -8238,7 +6712,7 @@ describe('float window', function() if j ~= i then feed(j.."<c-w>w") feed('<c-w>p') - local nr = funcs.winnr() + local nr = fn.winnr() eq(i,nr, "when using <c-w>p to window "..i.." from window "..j) end end @@ -8253,19 +6727,11 @@ describe('float window', function() screen:expect{grid=[[ ## grid 1 {9: }{10:2}{9:+ [No Name] }{3: [No Name] }{5: }{9:X}| - [5:----------------------------------------]| - [5:----------------------------------------]| - [5:----------------------------------------]| - [5:----------------------------------------]| - [5:----------------------------------------]| + [5:----------------------------------------]|*5 [3:----------------------------------------]| ## grid 2 (hidden) x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 :tabnew | ## grid 4 (hidden) @@ -8273,19 +6739,13 @@ describe('float window', function() {2:~ }| ## grid 5 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ]]} else screen:expect([[ {9: }{10:2}{9:+ [No Name] }{3: [No Name] }{5: }{9:X}| ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 :tabnew | ]]) end @@ -8295,18 +6755,11 @@ describe('float window', function() screen:expect{grid=[[ ## grid 1 {3: }{11:2}{3:+ [No Name] }{9: [No Name] }{5: }{9:X}| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*5 [3:----------------------------------------]| ## grid 2 ^x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 :tabnext | ## grid 4 @@ -8314,10 +6767,7 @@ describe('float window', function() {2:~ }| ## grid 5 (hidden) | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ]], float_pos=expected_pos} else screen:expect([[ @@ -8325,8 +6775,7 @@ describe('float window', function() ^x | {0:~ }{1:y }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 :tabnext | ]]) end @@ -8336,18 +6785,11 @@ describe('float window', function() screen:expect{grid=[[ ## grid 1 {9: }{10:2}{9:+ [No Name] }{3: [No Name] }{5: }{9:X}| - [5:----------------------------------------]| - [5:----------------------------------------]| - [5:----------------------------------------]| - [5:----------------------------------------]| - [5:----------------------------------------]| + [5:----------------------------------------]|*5 [3:----------------------------------------]| ## grid 2 (hidden) x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 :tabnext | ## grid 4 (hidden) @@ -8355,19 +6797,13 @@ describe('float window', function() {2:~ }| ## grid 5 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ]]} else screen:expect([[ {9: }{10:2}{9:+ [No Name] }{3: [No Name] }{5: }{9:X}| ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 :tabnext | ]]) end @@ -8376,42 +6812,29 @@ describe('float window', function() it(":tabnew and :tabnext (external)", function() if multigrid then -- also test external window wider than main screen - meths.win_set_config(win, {external=true, width=65, height=4}) + api.nvim_win_set_config(win, {external=true, width=65, height=4}) expected_pos = {[4]={external=true}} feed(":tabnew<cr>") screen:expect{grid=[[ ## grid 1 {9: + [No Name] }{3: }{11:2}{3:+ [No Name] }{5: }{9:X}| - [5:----------------------------------------]| - [5:----------------------------------------]| - [5:----------------------------------------]| - [5:----------------------------------------]| - [5:----------------------------------------]| + [5:----------------------------------------]|*5 [3:----------------------------------------]| ## grid 2 (hidden) x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 :tabnew | ## grid 4 y | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 5 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ]], float_pos=expected_pos} else eq("UI doesn't support external windows", - pcall_err(meths.win_set_config, 0, {external=true, width=65, height=4})) + pcall_err(api.nvim_win_set_config, 0, {external=true, width=65, height=4})) end feed(":tabnext<cr>") @@ -8419,31 +6842,19 @@ describe('float window', function() screen:expect{grid=[[ ## grid 1 {3: }{11:2}{3:+ [No Name] }{9: [No Name] }{5: }{9:X}| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*5 [3:----------------------------------------]| ## grid 2 ^x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 :tabnext | ## grid 4 y | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 5 (hidden) | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ]], float_pos=expected_pos} end @@ -8452,57 +6863,36 @@ describe('float window', function() screen:expect{grid=[[ ## grid 1 {9: + [No Name] }{3: }{11:2}{3:+ [No Name] }{5: }{9:X}| - [5:----------------------------------------]| - [5:----------------------------------------]| - [5:----------------------------------------]| - [5:----------------------------------------]| - [5:----------------------------------------]| + [5:----------------------------------------]|*5 [3:----------------------------------------]| ## grid 2 (hidden) x | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 :tabnext | ## grid 4 y | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 ## grid 5 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ]], float_pos=expected_pos} end end) end) it("left drag changes visual selection in float window", function() - local buf = meths.create_buf(false,false) - meths.buf_set_lines(buf, 0, -1, true, {'foo', 'bar', 'baz'}) - meths.open_win(buf, false, {relative='editor', width=20, height=3, row=2, col=5}) + local buf = api.nvim_create_buf(false,false) + api.nvim_buf_set_lines(buf, 0, -1, true, {'foo', 'bar', 'baz'}) + api.nvim_open_win(buf, false, {relative='editor', width=20, height=3, row=2, col=5}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -8510,29 +6900,20 @@ describe('float window', function() {1:bar }| {1:baz }| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 2, 5, true, 50}; + [4] = {1001, "NW", 1, 2, 5, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; }} - meths.input_mouse('left', 'press', '', 4, 0, 0) + api.nvim_input_mouse('left', 'press', '', 4, 0, 0) screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -8540,29 +6921,20 @@ describe('float window', function() {1:bar }| {1:baz }| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 2, 5, true, 50}; + [4] = {1001, "NW", 1, 2, 5, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; }} - meths.input_mouse('left', 'drag', '', 4, 1, 2) + api.nvim_input_mouse('left', 'drag', '', 4, 1, 2) screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 {3:-- VISUAL --} | ## grid 4 @@ -8570,10 +6942,10 @@ describe('float window', function() {27:ba}{1:^r }| {1:baz }| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 2, 5, true, 50}; + [4] = {1001, "NW", 1, 2, 5, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 1, curcol = 2, linecount = 3, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 1, curcol = 2, linecount = 3, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -8586,7 +6958,7 @@ describe('float window', function() | ]]} - meths.input_mouse('left', 'press', '', 0, 2, 5) + api.nvim_input_mouse('left', 'press', '', 0, 2, 5) screen:expect{grid=[[ | {0:~ }| @@ -8597,7 +6969,7 @@ describe('float window', function() | ]]} - meths.input_mouse('left', 'drag', '', 0, 3, 7) + api.nvim_input_mouse('left', 'drag', '', 0, 3, 7) screen:expect{grid=[[ | {0:~ }| @@ -8611,26 +6983,17 @@ describe('float window', function() end) it("left drag changes visual selection in float window with border", function() - local buf = meths.create_buf(false,false) - meths.buf_set_lines(buf, 0, -1, true, {'foo', 'bar', 'baz'}) - meths.open_win(buf, false, {relative='editor', width=20, height=3, row=0, col=5, border='single'}) + local buf = api.nvim_create_buf(false,false) + api.nvim_buf_set_lines(buf, 0, -1, true, {'foo', 'bar', 'baz'}) + api.nvim_open_win(buf, false, {relative='editor', width=20, height=3, row=0, col=5, border='single'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -8640,29 +7003,20 @@ describe('float window', function() {5:│}{1:baz }{5:│}| {5:└────────────────────┘}| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 0, 5, true, 50}; + [4] = {1001, "NW", 1, 0, 5, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; }} - meths.input_mouse('left', 'press', '', 4, 1, 1) + api.nvim_input_mouse('left', 'press', '', 4, 1, 1) screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -8672,29 +7026,20 @@ describe('float window', function() {5:│}{1:baz }{5:│}| {5:└────────────────────┘}| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 0, 5, true, 50}; + [4] = {1001, "NW", 1, 0, 5, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; }} - meths.input_mouse('left', 'drag', '', 4, 2, 3) + api.nvim_input_mouse('left', 'drag', '', 4, 2, 3) screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 {3:-- VISUAL --} | ## grid 4 @@ -8704,10 +7049,10 @@ describe('float window', function() {5:│}{1:baz }{5:│}| {5:└────────────────────┘}| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 0, 5, true, 50}; + [4] = {1001, "NW", 1, 0, 5, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 1, curcol = 2, linecount = 3, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 1, curcol = 2, linecount = 3, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -8720,7 +7065,7 @@ describe('float window', function() | ]]} - meths.input_mouse('left', 'press', '', 0, 1, 6) + api.nvim_input_mouse('left', 'press', '', 0, 1, 6) screen:expect{grid=[[ {5:┌────────────────────┐} | {0:~ }{5:│}{1:^foo }{5:│}{0: }| @@ -8731,7 +7076,7 @@ describe('float window', function() | ]]} - meths.input_mouse('left', 'drag', '', 0, 2, 8) + api.nvim_input_mouse('left', 'drag', '', 0, 2, 8) screen:expect{grid=[[ {5:┌────────────────────┐} | {0:~ }{5:│}{27:foo}{1: }{5:│}{0: }| @@ -8745,27 +7090,18 @@ describe('float window', function() end) it("left drag changes visual selection in float window with winbar", function() - local buf = meths.create_buf(false,false) - meths.buf_set_lines(buf, 0, -1, true, {'foo', 'bar', 'baz'}) - local float_win = meths.open_win(buf, false, {relative='editor', width=20, height=4, row=1, col=5}) - meths.set_option_value('winbar', 'floaty bar', {win=float_win.id}) + local buf = api.nvim_create_buf(false,false) + api.nvim_buf_set_lines(buf, 0, -1, true, {'foo', 'bar', 'baz'}) + local float_win = api.nvim_open_win(buf, false, {relative='editor', width=20, height=4, row=1, col=5}) + api.nvim_set_option_value('winbar', 'floaty bar', {win=float_win}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -8774,29 +7110,20 @@ describe('float window', function() {1:bar }| {1:baz }| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 1, 5, true, 50}; + [4] = {1001, "NW", 1, 1, 5, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; }} - meths.input_mouse('left', 'press', '', 4, 1, 0) + api.nvim_input_mouse('left', 'press', '', 4, 1, 0) screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -8805,29 +7132,20 @@ describe('float window', function() {1:bar }| {1:baz }| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 1, 5, true, 50}; + [4] = {1001, "NW", 1, 1, 5, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; }} - meths.input_mouse('left', 'drag', '', 4, 2, 2) + api.nvim_input_mouse('left', 'drag', '', 4, 2, 2) screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 {3:-- VISUAL --} | ## grid 4 @@ -8836,10 +7154,10 @@ describe('float window', function() {27:ba}{1:^r }| {1:baz }| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 1, 5, true, 50}; + [4] = {1001, "NW", 1, 1, 5, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 1, curcol = 2, linecount = 3, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 1, curcol = 2, linecount = 3, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -8852,7 +7170,7 @@ describe('float window', function() | ]]} - meths.input_mouse('left', 'press', '', 0, 2, 5) + api.nvim_input_mouse('left', 'press', '', 0, 2, 5) screen:expect{grid=[[ | {0:~ }{3:floaty bar }{0: }| @@ -8863,7 +7181,7 @@ describe('float window', function() | ]]} - meths.input_mouse('left', 'drag', '', 0, 3, 7) + api.nvim_input_mouse('left', 'drag', '', 0, 3, 7) screen:expect{grid=[[ | {0:~ }{3:floaty bar }{0: }| @@ -8877,116 +7195,89 @@ describe('float window', function() end) it('left drag changes visual selection if float window is turned into a split', function() - local buf = meths.create_buf(false,false) - meths.buf_set_lines(buf, 0, -1, true, {'foo', 'bar', 'baz'}) - meths.open_win(buf, true, {relative='editor', width=20, height=3, row=2, col=5}) + local buf = api.nvim_create_buf(false,false) + api.nvim_buf_set_lines(buf, 0, -1, true, {'foo', 'bar', 'baz'}) + api.nvim_open_win(buf, true, {relative='editor', width=20, height=3, row=2, col=5}) command('wincmd L') if multigrid then screen:expect([[ ## grid 1 - [2:-------------------]{5:│}[4:--------------------]| - [2:-------------------]{5:│}[4:--------------------]| - [2:-------------------]{5:│}[4:--------------------]| - [2:-------------------]{5:│}[4:--------------------]| - [2:-------------------]{5:│}[4:--------------------]| + [2:-------------------]{5:│}[4:--------------------]|*5 {5:[No Name] }{4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 | ## grid 4 ^foo | bar | baz | - {0:~ }| - {0:~ }| + {0:~ }|*2 ]]) - meths.input_mouse('left', 'press', '', 4, 2, 2) + api.nvim_input_mouse('left', 'press', '', 4, 2, 2) screen:expect([[ ## grid 1 - [2:-------------------]{5:│}[4:--------------------]| - [2:-------------------]{5:│}[4:--------------------]| - [2:-------------------]{5:│}[4:--------------------]| - [2:-------------------]{5:│}[4:--------------------]| - [2:-------------------]{5:│}[4:--------------------]| + [2:-------------------]{5:│}[4:--------------------]|*5 {5:[No Name] }{4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 | ## grid 4 foo | bar | ba^z | - {0:~ }| - {0:~ }| + {0:~ }|*2 ]]) - meths.input_mouse('left', 'drag', '', 4, 1, 1) + api.nvim_input_mouse('left', 'drag', '', 4, 1, 1) screen:expect([[ ## grid 1 - [2:-------------------]{5:│}[4:--------------------]| - [2:-------------------]{5:│}[4:--------------------]| - [2:-------------------]{5:│}[4:--------------------]| - [2:-------------------]{5:│}[4:--------------------]| - [2:-------------------]{5:│}[4:--------------------]| + [2:-------------------]{5:│}[4:--------------------]|*5 {5:[No Name] }{4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 {3:-- VISUAL --} | ## grid 4 foo | b^a{27:r} | {27:baz} | - {0:~ }| - {0:~ }| + {0:~ }|*2 ]]) else screen:expect([[ {5:│}^foo | {0:~ }{5:│}bar | {0:~ }{5:│}baz | - {0:~ }{5:│}{0:~ }| - {0:~ }{5:│}{0:~ }| + {0:~ }{5:│}{0:~ }|*2 {5:[No Name] }{4:[No Name] [+] }| | ]]) - meths.input_mouse('left', 'press', '', 0, 2, 22) + api.nvim_input_mouse('left', 'press', '', 0, 2, 22) screen:expect([[ {5:│}foo | {0:~ }{5:│}bar | {0:~ }{5:│}ba^z | - {0:~ }{5:│}{0:~ }| - {0:~ }{5:│}{0:~ }| + {0:~ }{5:│}{0:~ }|*2 {5:[No Name] }{4:[No Name] [+] }| | ]]) - meths.input_mouse('left', 'drag', '', 0, 1, 21) + api.nvim_input_mouse('left', 'drag', '', 0, 1, 21) screen:expect([[ {5:│}foo | {0:~ }{5:│}b^a{27:r} | {0:~ }{5:│}{27:baz} | - {0:~ }{5:│}{0:~ }| - {0:~ }{5:│}{0:~ }| + {0:~ }{5:│}{0:~ }|*2 {5:[No Name] }{4:[No Name] [+] }| {3:-- VISUAL --} | ]]) @@ -8994,46 +7285,33 @@ describe('float window', function() end) it('left click sets correct curswant in float window with border', function() - local buf = meths.create_buf(false,false) - meths.buf_set_lines(buf, 0, -1, true, {'', '', ''}) - meths.open_win(buf, false, {relative='editor', width=20, height=3, row=0, col=5, border='single'}) + local buf = api.nvim_create_buf(false,false) + api.nvim_buf_set_lines(buf, 0, -1, true, {'', '', ''}) + api.nvim_open_win(buf, false, {relative='editor', width=20, height=3, row=0, col=5, border='single'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 {5:┌────────────────────┐}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| + {5:│}{1: }{5:│}|*3 {5:└────────────────────┘}| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 0, 5, true, 50}; + [4] = {1001, "NW", 1, 0, 5, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ ^ {5:┌────────────────────┐} | - {0:~ }{5:│}{1: }{5:│}{0: }| - {0:~ }{5:│}{1: }{5:│}{0: }| - {0:~ }{5:│}{1: }{5:│}{0: }| + {0:~ }{5:│}{1: }{5:│}{0: }|*3 {0:~ }{5:└────────────────────┘}{0: }| {0:~ }| | @@ -9041,45 +7319,36 @@ describe('float window', function() end if multigrid then - meths.input_mouse('left', 'press', '', 4, 3, 1) + api.nvim_input_mouse('left', 'press', '', 4, 3, 1) else - meths.input_mouse('left', 'press', '', 0, 3, 6) + api.nvim_input_mouse('left', 'press', '', 0, 3, 6) end - eq({0, 3, 1, 0, 1}, funcs.getcurpos()) + eq({0, 3, 1, 0, 1}, fn.getcurpos()) if multigrid then - meths.input_mouse('left', 'press', '', 4, 3, 2) + api.nvim_input_mouse('left', 'press', '', 4, 3, 2) else - meths.input_mouse('left', 'press', '', 0, 3, 7) + api.nvim_input_mouse('left', 'press', '', 0, 3, 7) end - eq({0, 3, 1, 0, 2}, funcs.getcurpos()) + eq({0, 3, 1, 0, 2}, fn.getcurpos()) if multigrid then - meths.input_mouse('left', 'press', '', 4, 3, 10) + api.nvim_input_mouse('left', 'press', '', 4, 3, 10) else - meths.input_mouse('left', 'press', '', 0, 3, 15) + api.nvim_input_mouse('left', 'press', '', 0, 3, 15) end - eq({0, 3, 1, 0, 10}, funcs.getcurpos()) + eq({0, 3, 1, 0, 10}, fn.getcurpos()) command('setlocal foldcolumn=1') feed('zfkgg') if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -9089,10 +7358,10 @@ describe('float window', function() {5:│}{2:~ }{5:│}| {5:└────────────────────┘}| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 0, 5, true, 50}; + [4] = {1001, "NW", 1, 0, 5, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 4, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 4, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -9107,23 +7376,14 @@ describe('float window', function() end if multigrid then - meths.input_mouse('left', 'press', '', 4, 2, 1) + api.nvim_input_mouse('left', 'press', '', 4, 2, 1) screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -9133,13 +7393,13 @@ describe('float window', function() {5:│}{19:│}{1: }{5:│}| {5:└────────────────────┘}| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 0, 5, true, 50}; + [4] = {1001, "NW", 1, 0, 5, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 3, sum_scroll_delta = 0}; }} else - meths.input_mouse('left', 'press', '', 0, 2, 6) + api.nvim_input_mouse('left', 'press', '', 0, 2, 6) screen:expect{grid=[[ {5:┌────────────────────┐} | {0:~ }{5:│}{19: }{1:^ }{5:│}{0: }| @@ -9152,25 +7412,25 @@ describe('float window', function() end if multigrid then - meths.input_mouse('left', 'press', '', 4, 2, 2) + api.nvim_input_mouse('left', 'press', '', 4, 2, 2) else - meths.input_mouse('left', 'press', '', 0, 2, 7) + api.nvim_input_mouse('left', 'press', '', 0, 2, 7) end - eq({0, 2, 1, 0, 1}, funcs.getcurpos()) + eq({0, 2, 1, 0, 1}, fn.getcurpos()) if multigrid then - meths.input_mouse('left', 'press', '', 4, 2, 3) + api.nvim_input_mouse('left', 'press', '', 4, 2, 3) else - meths.input_mouse('left', 'press', '', 0, 2, 8) + api.nvim_input_mouse('left', 'press', '', 0, 2, 8) end - eq({0, 2, 1, 0, 2}, funcs.getcurpos()) + eq({0, 2, 1, 0, 2}, fn.getcurpos()) if multigrid then - meths.input_mouse('left', 'press', '', 4, 2, 11) + api.nvim_input_mouse('left', 'press', '', 4, 2, 11) else - meths.input_mouse('left', 'press', '', 0, 2, 16) + api.nvim_input_mouse('left', 'press', '', 0, 2, 16) end - eq({0, 2, 1, 0, 10}, funcs.getcurpos()) + eq({0, 2, 1, 0, 10}, fn.getcurpos()) end) it("'winblend' option", function() @@ -9188,8 +7448,8 @@ describe('float window', function() [10] = {foreground = Screen.colors.Red, background = Screen.colors.LightMagenta, blend = 0}, [11] = {foreground = Screen.colors.Red, background = Screen.colors.LightMagenta, blend = 80}, [12] = {background = Screen.colors.LightMagenta, bold = true, foreground = Screen.colors.Blue1, blend = 30}, - [13] = {background = Screen.colors.LightGray, blend = 30}, - [14] = {foreground = Screen.colors.Grey0, background = Screen.colors.Grey88}, + [13] = {foreground = Screen.colors.Black, background = Screen.colors.LightGray, blend = 30}, + [14] = {foreground = Screen.colors.Black, background = Screen.colors.Grey88}, [15] = {foreground = tonumber('0x939393'), background = Screen.colors.Grey88}, [16] = {background = Screen.colors.Grey90}; [17] = {blend = 100}; @@ -9214,20 +7474,13 @@ describe('float window', function() occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.]]) - local buf = meths.create_buf(false,false) - meths.buf_set_lines(buf, 0, -1, true, {"test", "", "popup text"}) - local win = meths.open_win(buf, false, {relative='editor', width=15, height=3, row=2, col=5}) + local buf = api.nvim_create_buf(false,false) + api.nvim_buf_set_lines(buf, 0, -1, true, {"test", "", "popup text"}) + local win = api.nvim_open_win(buf, false, {relative='editor', width=15, height=3, row=2, col=5}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| + [2:--------------------------------------------------]|*8 [3:--------------------------------------------------]| ## grid 2 Ut enim ad minim veniam, quis nostrud | @@ -9244,7 +7497,7 @@ describe('float window', function() {1:test }| {1: }| {1:popup text }| - ]], float_pos={[4] = {{id = 1001}, "NW", 1, 2, 5, true}}} + ]], float_pos={[4] = {1001, "NW", 1, 2, 5, true}}} else screen:expect([[ Ut enim ad minim veniam, quis nostrud | @@ -9259,18 +7512,11 @@ describe('float window', function() ]]) end - meths.set_option_value("winblend", 30, {win=win.id}) + api.nvim_set_option_value("winblend", 30, {win=win}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| + [2:--------------------------------------------------]|*8 [3:--------------------------------------------------]| ## grid 2 Ut enim ad minim veniam, quis nostrud | @@ -9287,7 +7533,7 @@ describe('float window', function() {9:test }| {9: }| {9:popup text }| - ]], float_pos={[4] = {{id = 1001}, "NW", 1, 2, 5, true}}, unchanged=true} + ]], float_pos={[4] = {1001, "NW", 1, 2, 5, true}}, unchanged=true} else screen:expect([[ Ut enim ad minim veniam, quis nostrud | @@ -9303,18 +7549,11 @@ describe('float window', function() end -- Check that 'winblend' works with NormalNC highlight - meths.set_option_value('winhighlight', 'NormalNC:Visual', {win = win}) + api.nvim_set_option_value('winhighlight', 'NormalNC:Visual', {win = win}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| + [2:--------------------------------------------------]|*8 [3:--------------------------------------------------]| ## grid 2 Ut enim ad minim veniam, quis nostrud | @@ -9331,7 +7570,7 @@ describe('float window', function() {13:test }| {13: }| {13:popup text }| - ]], float_pos={[4] = {{id = 1001}, "NW", 1, 2, 5, true}}} + ]], float_pos={[4] = {1001, "NW", 1, 2, 5, true}}} else screen:expect([[ Ut enim ad minim veniam, quis nostrud | @@ -9355,18 +7594,11 @@ describe('float window', function() command('hi clear NormalNC') command('hi SpecialRegion guifg=Red blend=0') - meths.buf_add_highlight(buf, -1, "SpecialRegion", 2, 0, -1) + api.nvim_buf_add_highlight(buf, -1, "SpecialRegion", 2, 0, -1) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| + [2:--------------------------------------------------]|*8 [3:--------------------------------------------------]| ## grid 2 Ut enim ad minim veniam, quis nostrud | @@ -9383,7 +7615,7 @@ describe('float window', function() {9:test }| {9: }| {10:popup text}{9: }| - ]], float_pos={[4] = {{id = 1001}, "NW", 1, 2, 5, true}}} + ]], float_pos={[4] = {1001, "NW", 1, 2, 5, true}}} else screen:expect([[ Ut enim ad minim veniam, quis nostrud | @@ -9402,14 +7634,7 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| + [2:--------------------------------------------------]|*8 [3:--------------------------------------------------]| ## grid 2 Ut enim ad minim veniam, quis nostrud | @@ -9426,7 +7651,7 @@ describe('float window', function() {9:test }| {9: }| {11:popup text}{9: }| - ]], float_pos={[4] = {{id = 1001}, "NW", 1, 2, 5, true}}, unchanged=true} + ]], float_pos={[4] = {1001, "NW", 1, 2, 5, true}}, unchanged=true} else screen:expect([[ Ut enim ad minim veniam, quis nostrud | @@ -9443,17 +7668,10 @@ describe('float window', function() -- Test scrolling by mouse if multigrid then - meths.input_mouse('wheel', 'down', '', 4, 2, 2) + api.nvim_input_mouse('wheel', 'down', '', 4, 2, 2) screen:expect{grid=[[ ## grid 1 - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| + [2:--------------------------------------------------]|*8 [3:--------------------------------------------------]| ## grid 2 Ut enim ad minim veniam, quis nostrud | @@ -9468,11 +7686,10 @@ describe('float window', function() | ## grid 4 {11:popup text}{9: }| - {12:~ }| - {12:~ }| - ]], float_pos={[4] = {{id = 1001}, "NW", 1, 2, 5, true}}} + {12:~ }|*2 + ]], float_pos={[4] = {1001, "NW", 1, 2, 5, true}}} else - meths.input_mouse('wheel', 'down', '', 0, 4, 7) + api.nvim_input_mouse('wheel', 'down', '', 0, 4, 7) screen:expect([[ Ut enim ad minim veniam, quis nostrud | exercitation ullamco laboris nisi ut aliquip ex | @@ -9487,22 +7704,15 @@ describe('float window', function() end -- Check that 'winblend' applies to border/title/footer - meths.win_set_config(win, {border='single', title='Title', footer='Footer'}) - meths.set_option_value('winblend', 100, {win=win.id}) - meths.set_option_value("cursorline", true, {win=0}) + api.nvim_win_set_config(win, {border='single', title='Title', footer='Footer'}) + api.nvim_set_option_value('winblend', 100, {win=win}) + api.nvim_set_option_value("cursorline", true, {win=0}) command('hi clear VertSplit') feed('k0') if multigrid then screen:expect{grid=[[ ## grid 1 - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| - [2:--------------------------------------------------]| + [2:--------------------------------------------------]|*8 [3:--------------------------------------------------]| ## grid 2 Ut enim ad minim veniam, quis nostrud | @@ -9518,10 +7728,9 @@ describe('float window', function() ## grid 4 {17:┌}{23:Title}{17:──────────┐}| {17:│}{11:popup text}{18: }{17:│}| - {17:│}{19:~ }{17:│}| - {17:│}{19:~ }{17:│}| + {17:│}{19:~ }{17:│}|*2 {17:└}{23:Footer}{17:─────────┘}| - ]], float_pos={[4] = {{id = 1001}, "NW", 1, 2, 5, true}}} + ]], float_pos={[4] = {1001, "NW", 1, 2, 5, true}}} else screen:expect([[ Ut enim ad minim veniam, quis nostrud | @@ -9541,63 +7750,44 @@ describe('float window', function() insert([[ # TODO: 测试字典信息的准确性 # FIXME: 测试字典信息的准确性]]) - local buf = meths.create_buf(false,false) - meths.buf_set_lines(buf, 0, -1, true, {'口', '口'}) - local win = meths.open_win(buf, false, {relative='editor', width=5, height=3, row=0, col=11, style='minimal'}) + local buf = api.nvim_create_buf(false,false) + api.nvim_buf_set_lines(buf, 0, -1, true, {'口', '口'}) + local win = api.nvim_open_win(buf, false, {relative='editor', width=5, height=3, row=0, col=11, style='minimal'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 # TODO: 测试字典信息的准确性 | # FIXME: 测试字典信息的准确^性 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 | ## grid 4 - {1:口 }| - {1:口 }| + {1:口 }|*2 {1: }| - ]], float_pos={ [4] = { { id = 1001 }, "NW", 1, 0, 11, true } }} + ]], float_pos={ [4] = { 1001, "NW", 1, 0, 11, true } }} else screen:expect([[ # TODO: 测 {1:口 }信息的准确性 | # FIXME: 测{1:口 } 信息的准确^性 | {0:~ }{1: }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) end - meths.win_close(win, false) + api.nvim_win_close(win, false) if multigrid then screen:expect([[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 # TODO: 测试字典信息的准确性 | # FIXME: 测试字典信息的准确^性 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ## grid 3 | ]]) @@ -9605,10 +7795,7 @@ describe('float window', function() screen:expect([[ # TODO: 测试字典信息的准确性 | # FIXME: 测试字典信息的准确^性 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) end @@ -9616,9 +7803,9 @@ describe('float window', function() -- The interaction between 'winblend' and doublewidth chars in the background -- does not look very good. But check no chars get incorrectly placed -- at least. Also check invisible EndOfBuffer region blends correctly. - meths.buf_set_lines(buf, 0, -1, true, {" x x x xx", " x x x x"}) - win = meths.open_win(buf, false, {relative='editor', width=12, height=3, row=0, col=11, style='minimal'}) - meths.set_option_value('winblend', 30, {win=win.id}) + api.nvim_buf_set_lines(buf, 0, -1, true, {" x x x xx", " x x x x"}) + win = api.nvim_open_win(buf, false, {relative='editor', width=12, height=3, row=0, col=11, style='minimal'}) + api.nvim_set_option_value('winblend', 30, {win=win}) screen:set_default_attr_ids({ [1] = {foreground = tonumber('0xb282b2'), background = tonumber('0xffcfff')}, [2] = {foreground = Screen.colors.Grey0, background = tonumber('0xffcfff')}, @@ -9629,20 +7816,12 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 # TODO: 测试字典信息的准确性 | # FIXME: 测试字典信息的准确^性 | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*4 ## grid 3 | ## grid 5 @@ -9650,38 +7829,28 @@ describe('float window', function() {5: x x x x}| {5: }| ]], float_pos={ - [5] = { { id = 1002 }, "NW", 1, 0, 11, true } + [5] = { 1002, "NW", 1, 0, 11, true } }} else screen:expect([[ # TODO: 测 {2: x x x}{1:息}{2: xx} 确性 | # FIXME: 测{1:试}{2:x x x}{1:息}{2: x}准确^性 | {3:~ }{4: }{3: }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*3 | ]]) end - meths.win_set_config(win, {relative='editor', row=0, col=12}) + api.nvim_win_set_config(win, {relative='editor', row=0, col=12}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 # TODO: 测试字典信息的准确性 | # FIXME: 测试字典信息的准确^性 | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*4 ## grid 3 | ## grid 5 @@ -9689,16 +7858,14 @@ describe('float window', function() {5: x x x x}| {5: }| ]], float_pos={ - [5] = { { id = 1002 }, "NW", 1, 0, 12, true } + [5] = { 1002, "NW", 1, 0, 12, true } }} else screen:expect([[ # TODO: 测试{2: x x}{1:信}{2:x }{1:的}{2:xx}确性 | # FIXME: 测 {2: x x}{1:信}{2:x }{1:的}{2:x} 确^性 | {3:~ }{4: }{3: }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*3 | ]]) end @@ -9735,20 +7902,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 | ## grid 4 @@ -9757,20 +7915,14 @@ describe('float window', function() {2:longest}| ## grid 5 {2:---------}| - {2:- -}| - {2:- -}| - {2: }| - {2: }| + {2:- -}|*2 + {2: }|*2 ]], attr_ids={ [1] = {foreground = Screen.colors.Blue1, bold = true}; [2] = {background = Screen.colors.LightMagenta}; }, float_pos={ - [4] = { { - id = 1001 - }, "NW", 1, 1, 1, true }, - [5] = { { - id = 1002 - }, "NW", 1, 0, 0, true } + [4] = { 1001, "NW", 1, 1, 1, true }, + [5] = { 1002, "NW", 1, 0, 0, true } }} else screen:expect([[ @@ -9803,20 +7955,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 | ## grid 4 @@ -9825,16 +7968,14 @@ describe('float window', function() {2:n}| ## grid 5 {2:---}| - {2:- -}| - {2:- -}| - {2: }| - {2: }| + {2:- -}|*2 + {2: }|*2 ]], attr_ids={ [1] = {foreground = Screen.colors.Blue1, bold = true}; [2] = {background = Screen.colors.LightMagenta}; }, float_pos={ - [4] = { { id = 1001 }, "NW", 1, 1, 1, true }, - [5] = { { id = 1002 }, "NW", 1, 0, 0, true } + [4] = { 1001, "NW", 1, 1, 1, true }, + [5] = { 1002, "NW", 1, 0, 0, true } }} else screen:expect([[ @@ -9850,37 +7991,28 @@ describe('float window', function() end) it("correctly orders multiple opened floats (current last)", function() - local buf = meths.create_buf(false,false) - local win = meths.open_win(buf, false, {relative='editor', width=20, height=2, row=2, col=5}) - meths.set_option_value("winhl", "Normal:ErrorMsg,EndOfBuffer:ErrorMsg", {win=win.id}) + local buf = api.nvim_create_buf(false,false) + local win = api.nvim_open_win(buf, false, {relative='editor', width=20, height=2, row=2, col=5}) + api.nvim_set_option_value("winhl", "Normal:ErrorMsg,EndOfBuffer:ErrorMsg", {win=win}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 {7: }| {7:~ }| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true }; + [4] = { 1001, "NW", 1, 2, 5, true }; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -9888,8 +8020,7 @@ describe('float window', function() {0:~ }| {0:~ }{7: }{0: }| {0:~ }{7:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]} end @@ -9906,20 +8037,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -9932,14 +8054,14 @@ describe('float window', function() {17:^ }| {17:~ }| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true }; - [5] = { { id = 1002 }, "NW", 1, 3, 8, true }; - [6] = { { id = 1003 }, "NW", 1, 4, 10, true }; + [4] = { 1001, "NW", 1, 2, 5, true }; + [5] = { 1002, "NW", 1, 3, 8, true }; + [6] = { 1003, "NW", 1, 4, 10, true }; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount=1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount=1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount=1, sum_scroll_delta = 0}; - [6] = {win = {id = 1003}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount=1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount=1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount=1, sum_scroll_delta = 0}; + [5] = {win = 1002, topline = 0, botline = 2, curline = 0, curcol = 0, linecount=1, sum_scroll_delta = 0}; + [6] = {win = 1003, topline = 0, botline = 2, curline = 0, curcol = 0, linecount=1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -9955,37 +8077,28 @@ describe('float window', function() end) it("correctly orders multiple opened floats (non-current last)", function() - local buf = meths.create_buf(false,false) - local win = meths.open_win(buf, false, {relative='editor', width=20, height=2, row=2, col=5}) - meths.set_option_value("winhl", "Normal:ErrorMsg,EndOfBuffer:ErrorMsg", {win=win.id}) + local buf = api.nvim_create_buf(false,false) + local win = api.nvim_open_win(buf, false, {relative='editor', width=20, height=2, row=2, col=5}) + api.nvim_set_option_value("winhl", "Normal:ErrorMsg,EndOfBuffer:ErrorMsg", {win=win}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 {7: }| {7:~ }| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true }; + [4] = { 1001, "NW", 1, 2, 5, true }; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -9993,8 +8106,7 @@ describe('float window', function() {0:~ }| {0:~ }{7: }{0: }| {0:~ }{7:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]} end @@ -10011,20 +8123,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -10037,14 +8140,14 @@ describe('float window', function() {1: }| {1:~ }| ]], float_pos={ - [4] = { { id = 1001 }, "NW", 1, 2, 5, true }; - [5] = { { id = 1002 }, "NW", 1, 4, 10, true }; - [6] = { { id = 1003 }, "NW", 1, 3, 8, true }; + [4] = { 1001, "NW", 1, 2, 5, true }; + [5] = { 1002, "NW", 1, 4, 10, true }; + [6] = { 1003, "NW", 1, 3, 8, true }; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [6] = {win = {id = 1003}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [5] = {win = 1002, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [6] = {win = 1003, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -10060,54 +8163,42 @@ describe('float window', function() end) it('can use z-index', function() - local buf = meths.create_buf(false,false) - local win1 = meths.open_win(buf, false, {relative='editor', width=20, height=3, row=1, col=5, zindex=30}) - meths.set_option_value("winhl", "Normal:ErrorMsg,EndOfBuffer:ErrorMsg", {win=win1.id}) - local win2 = meths.open_win(buf, false, {relative='editor', width=20, height=3, row=2, col=6, zindex=50}) - meths.set_option_value("winhl", "Normal:Search,EndOfBuffer:Search", {win=win2.id}) - local win3 = meths.open_win(buf, false, {relative='editor', width=20, height=3, row=3, col=7, zindex=40}) - meths.set_option_value("winhl", "Normal:Question,EndOfBuffer:Question", {win=win3.id}) + local buf = api.nvim_create_buf(false,false) + local win1 = api.nvim_open_win(buf, false, {relative='editor', width=20, height=3, row=1, col=5, zindex=30}) + api.nvim_set_option_value("winhl", "Normal:ErrorMsg,EndOfBuffer:ErrorMsg", {win=win1}) + local win2 = api.nvim_open_win(buf, false, {relative='editor', width=20, height=3, row=2, col=6, zindex=50}) + api.nvim_set_option_value("winhl", "Normal:Search,EndOfBuffer:Search", {win=win2}) + local win3 = api.nvim_open_win(buf, false, {relative='editor', width=20, height=3, row=3, col=7, zindex=40}) + api.nvim_set_option_value("winhl", "Normal:Question,EndOfBuffer:Question", {win=win3}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 {7: }| - {7:~ }| - {7:~ }| + {7:~ }|*2 ## grid 5 {17: }| - {17:~ }| - {17:~ }| + {17:~ }|*2 ## grid 6 {8: }| - {8:~ }| - {8:~ }| + {8:~ }|*2 ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 1, 5, true, 30}; - [5] = {{id = 1002}, "NW", 1, 2, 6, true, 50}; - [6] = {{id = 1003}, "NW", 1, 3, 7, true, 40}; + [4] = {1001, "NW", 1, 1, 5, true, 30}; + [5] = {1002, "NW", 1, 2, 6, true, 50}; + [6] = {1003, "NW", 1, 3, 7, true, 40}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [6] = {win = {id = 1003}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [5] = {win = 1002, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [6] = {win = 1003, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -10123,27 +8214,18 @@ describe('float window', function() end) it('can use winbar', function() - local buf = meths.create_buf(false,false) - local win1 = meths.open_win(buf, false, {relative='editor', width=15, height=3, row=1, col=5}) - meths.set_option_value('winbar', 'floaty bar', {win=win1.id}) + local buf = api.nvim_create_buf(false,false) + local win1 = api.nvim_open_win(buf, false, {relative='editor', width=15, height=3, row=1, col=5}) + api.nvim_set_option_value('winbar', 'floaty bar', {win=win1}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -10151,10 +8233,10 @@ describe('float window', function() {1: }| {2:~ }| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 1, 5, true, 50}; + [4] = {1001, "NW", 1, 1, 5, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -10162,54 +8244,42 @@ describe('float window', function() {0:~ }{3:floaty bar }{0: }| {0:~ }{1: }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]} end -- resize and add a border - meths.win_set_config(win1, {relative='editor', width=15, height=4, row=0, col=4, border = 'single'}) + api.nvim_win_set_config(win1, {relative='editor', width=15, height=4, row=0, col=4, border = 'single'}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 {5:┌───────────────┐}| {5:│}{3:floaty bar }{5:│}| {5:│}{1: }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| + {5:│}{2:~ }{5:│}|*2 {5:└───────────────┘}| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 0, 4, true, 50}; + [4] = {1001, "NW", 1, 0, 4, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ ^ {5:┌───────────────┐} | {0:~ }{5:│}{3:floaty bar }{5:│}{0: }| {0:~ }{5:│}{1: }{5:│}{0: }| - {0:~ }{5:│}{2:~ }{5:│}{0: }| - {0:~ }{5:│}{2:~ }{5:│}{0: }| + {0:~ }{5:│}{2:~ }{5:│}{0: }|*2 {0:~ }{5:└───────────────┘}{0: }| | ]]} @@ -10219,55 +8289,33 @@ describe('float window', function() it('it can be resized with messages and cmdheight=0 #20106', function() screen:try_resize(40,9) command 'set cmdheight=0' - local buf = meths.create_buf(false,true) - local win = meths.open_win(buf, false, {relative='editor', width=40, height=4, anchor='SW', row=9, col=0, style='minimal', border="single", noautocmd=true}) + local buf = api.nvim_create_buf(false,true) + local win = api.nvim_open_win(buf, false, {relative='editor', width=40, height=4, anchor='SW', row=9, col=0, style='minimal', border="single", noautocmd=true}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*9 ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*8 ## grid 3 ## grid 4 {5:┌────────────────────────────────────────┐}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| + {5:│}{1: }{5:│}|*4 {5:└────────────────────────────────────────┘}| ]], float_pos={ - [4] = {{id = 1001}, "SW", 1, 9, 0, true, 50}; + [4] = {1001, "SW", 1, 9, 0, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {5:┌──────────────────────────────────────┐}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| + {5:│}{1: }{5:│}|*4 {5:└──────────────────────────────────────┘}| ]]} end @@ -10281,144 +8329,83 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*9 ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*8 ## grid 3 ## grid 4 {5:┌────────────────────────────────────────┐}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| + {5:│}{1: }{5:│}|*2 {5:└────────────────────────────────────────┘}| ]], float_pos={ - [4] = {{id = 1001}, "SW", 1, 9, 0, true, 50}; + [4] = {1001, "SW", 1, 9, 0, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {5:┌──────────────────────────────────────┐}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| + {5:│}{1: }{5:│}|*2 {5:└──────────────────────────────────────┘}| ]]} end - meths.win_close(win, true) + api.nvim_win_close(win, true) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*9 ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*8 ## grid 3 ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*8 ]]} end end) it('it can be resized with messages and cmdheight=1', function() screen:try_resize(40,9) - local buf = meths.create_buf(false,true) - local win = meths.open_win(buf, false, {relative='editor', width=40, height=4, anchor='SW', row=8, col=0, style='minimal', border="single", noautocmd=true}) + local buf = api.nvim_create_buf(false,true) + local win = api.nvim_open_win(buf, false, {relative='editor', width=40, height=4, anchor='SW', row=8, col=0, style='minimal', border="single", noautocmd=true}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*8 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*7 ## grid 3 | ## grid 4 {5:┌────────────────────────────────────────┐}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| + {5:│}{1: }{5:│}|*4 {5:└────────────────────────────────────────┘}| ]], float_pos={ - [4] = {{id = 1001}, "SW", 1, 8, 0, true, 50}; + [4] = {1001, "SW", 1, 8, 0, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ ^ | {0:~ }| {5:┌──────────────────────────────────────┐}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| + {5:│}{1: }{5:│}|*4 {5:└──────────────────────────────────────┘}| | ]]} @@ -10436,48 +8423,30 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [3:----------------------------------------]| - [3:----------------------------------------]| + [2:----------------------------------------]|*7 + [3:----------------------------------------]|*2 ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*7 ## grid 3 | {8:Press ENTER or type command to continue}^ | ## grid 4 {5:┌────────────────────────────────────────┐}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| + {5:│}{1: }{5:│}|*4 {5:└────────────────────────────────────────┘}| ]], float_pos={ - [4] = {{id = 1001}, "SW", 1, 8, 0, true, 50}; + [4] = {1001, "SW", 1, 8, 0, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ | {0:~ }| {5:┌──────────────────────────────────────┐}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| + {5:│}{1: }{5:│}|*3 {4: }| | {8:Press ENTER or type command to continue}^ | @@ -10488,88 +8457,52 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*8 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*7 ## grid 3 | ## grid 4 {5:┌────────────────────────────────────────┐}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| + {5:│}{1: }{5:│}|*2 {5:└────────────────────────────────────────┘}| ]], float_pos={ - [4] = {{id = 1001}, "SW", 1, 8, 0, true, 50}; + [4] = {1001, "SW", 1, 8, 0, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {5:┌──────────────────────────────────────┐}| - {5:│}{1: }{5:│}| - {5:│}{1: }{5:│}| + {5:│}{1: }{5:│}|*2 {5:└──────────────────────────────────────┘}| | ]]} end - meths.win_close(win, true) + api.nvim_win_close(win, true) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*8 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*7 ## grid 3 | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*7 | ]]} end @@ -10578,9 +8511,9 @@ describe('float window', function() describe('no crash after moving and closing float window #21547', function() local function test_float_move_close(cmd) local float_opts = {relative = 'editor', row = 1, col = 1, width = 10, height = 10} - meths.open_win(meths.create_buf(false, false), true, float_opts) + api.nvim_open_win(api.nvim_create_buf(false, false), true, float_opts) if multigrid then - screen:expect({float_pos = {[4] = {{id = 1001}, 'NW', 1, 1, 1, true}}}) + screen:expect({float_pos = {[4] = {1001, 'NW', 1, 1, 1, true}}}) end command(cmd) exec_lua([[ @@ -10605,26 +8538,17 @@ describe('float window', function() it(':sleep cursor placement #22639', function() local float_opts = {relative = 'editor', row = 1, col = 1, width = 4, height = 3} - local win = meths.open_win(meths.create_buf(false, false), true, float_opts) + local win = api.nvim_open_win(api.nvim_create_buf(false, false), true, float_opts) feed('iab<CR>cd<Esc>') feed(':sleep 100') if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 :sleep 100^ | ## grid 4 @@ -10632,10 +8556,10 @@ describe('float window', function() {1:cd }| {2:~ }| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 1, 1, true, 50}; + [4] = {1001, "NW", 1, 1, 1, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 1, curcol = 1, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 1, curcol = 1, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -10643,8 +8567,7 @@ describe('float window', function() {0:~}{1:ab }{0: }| {0:~}{1:cd }{0: }| {0:~}{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 :sleep 100^ | ]]} end @@ -10653,20 +8576,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 :sleep 100 | ## grid 4 @@ -10674,10 +8588,10 @@ describe('float window', function() {1:c^d }| {2:~ }| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 1, 1, true, 50}; + [4] = {1001, "NW", 1, 1, 1, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 1, curcol = 1, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 1, curcol = 1, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -10685,33 +8599,23 @@ describe('float window', function() {0:~}{1:ab }{0: }| {0:~}{1:c^d }{0: }| {0:~}{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 :sleep 100 | ]]} end feed('<C-C>') screen:expect_unchanged() - meths.win_set_config(win, {border = 'single'}) + api.nvim_win_set_config(win, {border = 'single'}) feed(':sleep 100') if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 :sleep 100^ | ## grid 4 @@ -10721,10 +8625,10 @@ describe('float window', function() {5:│}{2:~ }{5:│}| {5:└────┘}| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 1, 1, true, 50}; + [4] = {1001, "NW", 1, 1, 1, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 1, curcol = 1, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 1, curcol = 1, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -10742,20 +8646,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 :sleep 100 | ## grid 4 @@ -10765,10 +8660,10 @@ describe('float window', function() {5:│}{2:~ }{5:│}| {5:└────┘}| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 1, 1, true, 50}; + [4] = {1001, "NW", 1, 1, 1, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 1, curcol = 1, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 1, curcol = 1, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -10789,20 +8684,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 :sleep 100^ | ## grid 4 @@ -10812,10 +8698,10 @@ describe('float window', function() {5:│}{1:cd }{5:│}| {5:└────┘}| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 1, 1, true, 50}; + [4] = {1001, "NW", 1, 1, 1, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 1, curcol = 1, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 1, curcol = 1, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -10833,20 +8719,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 :sleep 100 | ## grid 4 @@ -10856,10 +8733,10 @@ describe('float window', function() {5:│}{1:c^d }{5:│}| {5:└────┘}| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 1, 1, true, 50}; + [4] = {1001, "NW", 1, 1, 1, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 1, curcol = 1, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 1, curcol = 1, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -10878,26 +8755,17 @@ describe('float window', function() it('with rightleft and border #22640', function() local float_opts = {relative='editor', width=5, height=3, row=1, col=1, border='single'} - meths.open_win(meths.create_buf(false, false), true, float_opts) + api.nvim_open_win(api.nvim_create_buf(false, false), true, float_opts) command('setlocal rightleft') feed('iabc<CR>def<Esc>') if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 @@ -10907,10 +8775,10 @@ describe('float window', function() {5:│}{2: ~}{5:│}| {5:└─────┘}| ]], float_pos={ - [4] = {{id = 1001}, "NW", 1, 1, 1, true, 50}; + [4] = {1001, "NW", 1, 1, 1, true, 50}; }, win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 3, curline = 1, curcol = 2, linecount = 2, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 3, curline = 1, curcol = 2, linecount = 2, sum_scroll_delta = 0}; }} else screen:expect{grid=[[ @@ -10926,29 +8794,20 @@ describe('float window', function() end) it('float window with hide option', function() - local buf = meths.create_buf(false,false) - local win = meths.open_win(buf, false, {relative='editor', width=10, height=2, row=2, col=5, hide = true}) + local buf = api.nvim_create_buf(false,false) + local win = api.nvim_open_win(buf, false, {relative='editor', width=10, height=2, row=2, col=5, hide = true}) local expected_pos = { - [4]={{id=1001}, 'NW', 1, 2, 5, true}, + [4]={1001, 'NW', 1, 2, 5, true}, } if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | @@ -10959,33 +8818,20 @@ describe('float window', function() else screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) end - meths.win_set_config(win, {hide = false}) + api.nvim_win_set_config(win, {hide = false}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | @@ -10999,30 +8845,20 @@ describe('float window', function() {0:~ }| {0:~ }{1: }{0: }| {0:~ }{2:~ }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end - meths.win_set_config(win, {hide=true}) + api.nvim_win_set_config(win, {hide=true}) if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | @@ -11033,85 +8869,55 @@ describe('float window', function() else screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) end end) it(':fclose command #9663', function() - local buf_a = meths.create_buf(false,false) - local buf_b = meths.create_buf(false,false) - local buf_c = meths.create_buf(false,false) - local buf_d = meths.create_buf(false,false) + local buf_a = api.nvim_create_buf(false,false) + local buf_b = api.nvim_create_buf(false,false) + local buf_c = api.nvim_create_buf(false,false) + local buf_d = api.nvim_create_buf(false,false) local config_a = {relative='editor', width=11, height=11, row=5, col=5, border ='single', zindex=50} local config_b = {relative='editor', width=8, height=8, row=7, col=7, border ='single', zindex=70} local config_c = {relative='editor', width=4, height=4, row=9, col=9, border ='single',zindex=90} local config_d = {relative='editor', width=2, height=2, row=10, col=10, border ='single',zindex=100} - meths.open_win(buf_a, false, config_a) - meths.open_win(buf_b, false, config_b) - meths.open_win(buf_c, false, config_c) - meths.open_win(buf_d, false, config_d) + api.nvim_open_win(buf_a, false, config_a) + api.nvim_open_win(buf_b, false, config_b) + api.nvim_open_win(buf_c, false, config_c) + api.nvim_open_win(buf_d, false, config_d) local expected_pos = { - [4]={{id=1001}, 'NW', 1, 5, 5, true, 50}, - [5]={{id=1002}, 'NW', 1, 7, 7, true, 70}, - [6]={{id=1003}, 'NW', 1, 9, 9, true, 90}, - [7]={{id=1004}, 'NW', 1, 10, 10, true, 100}, + [4]={1001, 'NW', 1, 5, 5, true, 50}, + [5]={1002, 'NW', 1, 7, 7, true, 70}, + [6]={1003, 'NW', 1, 9, 9, true, 90}, + [7]={1004, 'NW', 1, 10, 10, true, 100}, } if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 {5:┌───────────┐}| {5:│}{1: }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| + {5:│}{2:~ }{5:│}|*10 {5:└───────────┘}| ## grid 5 {5:┌────────┐}| {5:│}{1: }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| + {5:│}{2:~ }{5:│}|*7 {5:└────────┘}| ## grid 6 {5:┌────┐}| {5:│}{1: }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| + {5:│}{2:~ }{5:│}|*3 {5:└────┘}| ## grid 7 {5:┌──┐}| @@ -11136,63 +8942,35 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 {5:┌───────────┐}| {5:│}{1: }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| + {5:│}{2:~ }{5:│}|*10 {5:└───────────┘}| ## grid 5 {5:┌────────┐}| {5:│}{1: }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| + {5:│}{2:~ }{5:│}|*7 {5:└────────┘}| ## grid 6 {5:┌────┐}| {5:│}{1: }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| + {5:│}{2:~ }{5:│}|*3 {5:└────┘}| ]], float_pos=expected_pos} else screen:expect([[ ^ {5:┌─┌─┌────┐─┐┐} | {0:~ }{5:│}{1: }{5:│}{1: }{5:│}{1: }{5:│}{1: }{5:││}{0: }| - {0:~ }{5:│}{2:~}{5:│}{2:~}{5:│}{2:~ }{5:│}{2: }{5:││}{0: }| - {0:~ }{5:│}{2:~}{5:│}{2:~}{5:│}{2:~ }{5:│}{2: }{5:││}{0: }| - {0:~ }{5:│}{2:~}{5:│}{2:~}{5:│}{2:~ }{5:│}{2: }{5:││}{0: }| + {0:~ }{5:│}{2:~}{5:│}{2:~}{5:│}{2:~ }{5:│}{2: }{5:││}{0: }|*3 {0:~ }{5:│}{2:~}{5:│}{2:~}{5:└────┘}{2: }{5:││}{0: }| | ]]) @@ -11203,57 +8981,30 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | ## grid 4 {5:┌───────────┐}| {5:│}{1: }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| + {5:│}{2:~ }{5:│}|*10 {5:└───────────┘}| ## grid 5 {5:┌────────┐}| {5:│}{1: }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| - {5:│}{2:~ }{5:│}| + {5:│}{2:~ }{5:│}|*7 {5:└────────┘}| ]], float_pos=expected_pos} else screen:expect([[ ^ {5:┌─┌────────┐┐} | {0:~ }{5:│}{1: }{5:│}{1: }{5:││}{0: }| - {0:~ }{5:│}{2:~}{5:│}{2:~ }{5:││}{0: }| - {0:~ }{5:│}{2:~}{5:│}{2:~ }{5:││}{0: }| - {0:~ }{5:│}{2:~}{5:│}{2:~ }{5:││}{0: }| - {0:~ }{5:│}{2:~}{5:│}{2:~ }{5:││}{0: }| + {0:~ }{5:│}{2:~}{5:│}{2:~ }{5:││}{0: }|*4 | ]]) end @@ -11262,20 +9013,11 @@ describe('float window', function() if multigrid then screen:expect{grid=[[ ## grid 1 - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| - [2:----------------------------------------]| + [2:----------------------------------------]|*6 [3:----------------------------------------]| ## grid 2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 ## grid 3 | @@ -11283,15 +9025,82 @@ describe('float window', function() else screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) end end) + + it('correctly placed in or above message area', function() + local float_opts = {relative='editor', width=5, height=1, row=100, col=1, border = 'single'} + api.nvim_set_option_value('cmdheight', 3, {}) + command("echo 'cmdline'") + local win = api.nvim_open_win(api.nvim_create_buf(false, false), true, float_opts) + -- Not hidden behind message area but placed above it. + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:----------------------------------------]|*4 + [3:----------------------------------------]|*3 + ## grid 2 + | + {0:~ }|*3 + ## grid 3 + cmdline | + |*2 + ## grid 4 + {5:┌─────┐}| + {5:│}{1:^ }{5:│}| + {5:└─────┘}| + ]], float_pos={ + [4] = {1001, "NW", 1, 100, 1, true, 50}; + }, win_viewport={ + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 1, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + }} + else + screen:expect{grid=[[ + | + {0:~}{5:┌─────┐}{0: }| + {0:~}{5:│}{1:^ }{5:│}{0: }| + {0:~}{5:└─────┘}{0: }| + cmdline | + |*2 + ]]} + end + -- Not placed above message area and visible on top of it. + api.nvim_win_set_config(win, {zindex = 300}) + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:----------------------------------------]|*4 + [3:----------------------------------------]|*3 + ## grid 2 + | + {0:~ }|*3 + ## grid 3 + cmdline | + |*2 + ## grid 4 + {5:┌─────┐}| + {5:│}{1:^ }{5:│}| + {5:└─────┘}| + ]], float_pos={ + [4] = {1001, "NW", 1, 100, 1, true, 300}; + }, win_viewport={ + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 1, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + }} + else + screen:expect{grid=[[ + | + {0:~ }|*3 + c{5:┌─────┐} | + {5:│}{1:^ }{5:│} | + {5:└─────┘} | + ]]} + end + end) end describe('with ext_multigrid', function() diff --git a/test/functional/ui/fold_spec.lua b/test/functional/ui/fold_spec.lua index 1addf7088e..7f13b6bd03 100644 --- a/test/functional/ui/fold_spec.lua +++ b/test/functional/ui/fold_spec.lua @@ -4,12 +4,11 @@ local clear, feed, eq = helpers.clear, helpers.feed, helpers.eq local command = helpers.command local feed_command = helpers.feed_command local insert = helpers.insert -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local exec = helpers.exec local assert_alive = helpers.assert_alive - local content1 = [[ This is a valid English @@ -18,7 +17,7 @@ local content1 = [[ in his cave. ]] -describe("folded lines", function() +describe('folded lines', function() before_each(function() clear() command('hi VertSplit gui=reverse') @@ -28,280 +27,338 @@ describe("folded lines", function() local screen before_each(function() screen = Screen.new(45, 8) - screen:attach({rgb=true, ext_multigrid=multigrid}) + screen:attach({ rgb = true, ext_multigrid = multigrid }) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {reverse = true}, - [3] = {bold = true, reverse = true}, - [4] = {foreground = Screen.colors.White, background = Screen.colors.Red}, - [5] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey}, - [6] = {background = Screen.colors.Yellow}, - [7] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGray}, - [8] = {foreground = Screen.colors.Brown }, - [9] = {bold = true, foreground = Screen.colors.Brown}, - [10] = {background = Screen.colors.LightGrey, underline = true}, - [11] = {bold = true}, - [12] = {foreground = Screen.colors.Red}, - [13] = {foreground = Screen.colors.Red, background = Screen.colors.LightGrey}, - [14] = {background = Screen.colors.Red}, - [15] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.Red}, - [16] = {background = Screen.colors.LightGrey}, - [17] = {background = Screen.colors.Yellow, foreground = Screen.colors.Red}, - [18] = {background = Screen.colors.LightGrey, bold = true, foreground = Screen.colors.Blue}, - [19] = {background = Screen.colors.Yellow, foreground = Screen.colors.DarkBlue}, - [20] = {background = Screen.colors.Red, bold = true, foreground = Screen.colors.Blue}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { reverse = true }, + [3] = { bold = true, reverse = true }, + [4] = { foreground = Screen.colors.White, background = Screen.colors.Red }, + [5] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey }, + [6] = { background = Screen.colors.Yellow }, + [7] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGray }, + [8] = { foreground = Screen.colors.Brown }, + [9] = { bold = true, foreground = Screen.colors.Brown }, + [10] = { background = Screen.colors.LightGrey, underline = true }, + [11] = { bold = true }, + [12] = { foreground = Screen.colors.Red }, + [13] = { foreground = Screen.colors.Red, background = Screen.colors.LightGrey }, + [14] = { background = Screen.colors.Red }, + [15] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.Red }, + [16] = { foreground = Screen.colors.Black, background = Screen.colors.LightGrey }, + [17] = { background = Screen.colors.Yellow, foreground = Screen.colors.Red }, + [18] = { + background = Screen.colors.LightGrey, + bold = true, + foreground = Screen.colors.Blue, + }, + [19] = { background = Screen.colors.Yellow, foreground = Screen.colors.DarkBlue }, + [20] = { background = Screen.colors.Red, bold = true, foreground = Screen.colors.Blue }, }) end) - it("work with more than one signcolumn", function() - command("set signcolumn=yes:9") - feed("i<cr><esc>") - feed("vkzf") + it('with more than one signcolumn', function() + command('set signcolumn=yes:9') + feed('i<cr><esc>') + feed('vkzf') if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {7: }{5:^+-- 2 lines: ·············}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 ## grid 3 | ]]) else screen:expect([[ {7: }{5:^+-- 2 lines: ·············}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | ]]) end end) - local function test_folded_cursorline() - command("set number cursorline foldcolumn=2") - command("hi link CursorLineFold Search") - insert(content1) - feed("ggzf3jj") - if multigrid then - screen:expect([[ - ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [3:---------------------------------------------]| - ## grid 2 - {7:+ }{8: 1 }{5:+-- 4 lines: This is a················}| - {6: }{9: 5 }{12:^in his cave. }| - {7: }{8: 6 } | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ## grid 3 - | - ]]) - else - screen:expect([[ - {7:+ }{8: 1 }{5:+-- 4 lines: This is a················}| - {6: }{9: 5 }{12:^in his cave. }| - {7: }{8: 6 } | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - | - ]]) + local function test_folded_cursorline(foldtext) + if not foldtext then + command('set foldtext=') end - feed("k") - if multigrid then - screen:expect([[ - ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [3:---------------------------------------------]| - ## grid 2 - {6:+ }{9: 1 }{13:^+-- 4 lines: This is a················}| - {7: }{8: 5 }in his cave. | - {7: }{8: 6 } | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ## grid 3 - | - ]]) - else - screen:expect([[ - {6:+ }{9: 1 }{13:^+-- 4 lines: This is a················}| - {7: }{8: 5 }in his cave. | - {7: }{8: 6 } | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - | - ]]) + command('set number cursorline foldcolumn=2') + command('hi link CursorLineFold Search') + insert(content1) + feed('ggzf3jj') + + if multigrid then + if foldtext then + screen:expect([[ + ## grid 1 + [2:---------------------------------------------]|*7 + [3:---------------------------------------------]| + ## grid 2 + {7:+ }{8: 1 }{5:+-- 4 lines: This is a················}| + {6: }{9: 5 }{12:^in his cave. }| + {7: }{8: 6 } | + {1:~ }|*4 + ## grid 3 + | + ]]) + else + screen:expect([[ + ## grid 1 + [2:---------------------------------------------]|*7 + [3:---------------------------------------------]| + ## grid 2 + {7:+ }{8: 1 }{5:This is a······························}| + {6: }{9: 5 }{12:^in his cave. }| + {7: }{8: 6 } | + {1:~ }|*4 + ## grid 3 + | + ]]) + end + else + if foldtext then + screen:expect([[ + {7:+ }{8: 1 }{5:+-- 4 lines: This is a················}| + {6: }{9: 5 }{12:^in his cave. }| + {7: }{8: 6 } | + {1:~ }|*4 + | + ]]) + else + screen:expect([[ + {7:+ }{8: 1 }{5:This is a······························}| + {6: }{9: 5 }{12:^in his cave. }| + {7: }{8: 6 } | + {1:~ }|*4 + | + ]]) + end + end + + feed('k') + + if multigrid then + if foldtext then + screen:expect([[ + ## grid 1 + [2:---------------------------------------------]|*7 + [3:---------------------------------------------]| + ## grid 2 + {6:+ }{9: 1 }{13:^+-- 4 lines: This is a················}| + {7: }{8: 5 }in his cave. | + {7: }{8: 6 } | + {1:~ }|*4 + ## grid 3 + | + ]]) + else + screen:expect([[ + ## grid 1 + [2:---------------------------------------------]|*7 + [3:---------------------------------------------]| + ## grid 2 + {6:+ }{9: 1 }{13:^This is a······························}| + {7: }{8: 5 }in his cave. | + {7: }{8: 6 } | + {1:~ }|*4 + ## grid 3 + | + ]]) + end + else + if foldtext then + screen:expect([[ + {6:+ }{9: 1 }{13:^+-- 4 lines: This is a················}| + {7: }{8: 5 }in his cave. | + {7: }{8: 6 } | + {1:~ }|*4 + | + ]]) + else + screen:expect([[ + {6:+ }{9: 1 }{13:^This is a······························}| + {7: }{8: 5 }in his cave. | + {7: }{8: 6 } | + {1:~ }|*4 + | + ]]) + end end + -- CursorLine is applied correctly with screenrow motions #22232 - feed("jgk") + feed('jgk') screen:expect_unchanged() -- CursorLine is applied correctly when closing a fold when cursor is not at fold start - feed("zo4Gzc") + feed('zo4Gzc') screen:expect_unchanged() - command("set cursorlineopt=line") - if multigrid then - screen:expect([[ - ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [3:---------------------------------------------]| - ## grid 2 - {7:+ }{8: 1 }{13:^+-- 4 lines: This is a················}| - {7: }{8: 5 }in his cave. | - {7: }{8: 6 } | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ## grid 3 - | - ]]) - else - screen:expect([[ - {7:+ }{8: 1 }{13:^+-- 4 lines: This is a················}| - {7: }{8: 5 }in his cave. | - {7: }{8: 6 } | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - | - ]]) - end - command("set relativenumber cursorlineopt=number") - if multigrid then - screen:expect([[ - ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [3:---------------------------------------------]| - ## grid 2 - {6:+ }{9:1 }{5:^+-- 4 lines: This is a················}| - {7: }{8: 1 }in his cave. | - {7: }{8: 2 } | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ## grid 3 - | - ]]) - else - screen:expect([[ - {6:+ }{9:1 }{5:^+-- 4 lines: This is a················}| - {7: }{8: 1 }in his cave. | - {7: }{8: 2 } | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - | - ]]) + command('set cursorlineopt=line') + + if multigrid then + if foldtext then + screen:expect([[ + ## grid 1 + [2:---------------------------------------------]|*7 + [3:---------------------------------------------]| + ## grid 2 + {7:+ }{8: 1 }{13:^+-- 4 lines: This is a················}| + {7: }{8: 5 }in his cave. | + {7: }{8: 6 } | + {1:~ }|*4 + ## grid 3 + | + ]]) + else + screen:expect([[ + ## grid 1 + [2:---------------------------------------------]|*7 + [3:---------------------------------------------]| + ## grid 2 + {7:+ }{8: 1 }{13:^This is a······························}| + {7: }{8: 5 }in his cave. | + {7: }{8: 6 } | + {1:~ }|*4 + ## grid 3 + | + ]]) + end + else + if foldtext then + screen:expect([[ + {7:+ }{8: 1 }{13:^+-- 4 lines: This is a················}| + {7: }{8: 5 }in his cave. | + {7: }{8: 6 } | + {1:~ }|*4 + | + ]]) + else + screen:expect([[ + {7:+ }{8: 1 }{13:^This is a······························}| + {7: }{8: 5 }in his cave. | + {7: }{8: 6 } | + {1:~ }|*4 + | + ]]) + end + end + + command('set relativenumber cursorlineopt=number') + + if multigrid then + if foldtext then + screen:expect([[ + ## grid 1 + [2:---------------------------------------------]|*7 + [3:---------------------------------------------]| + ## grid 2 + {6:+ }{9:1 }{5:^+-- 4 lines: This is a················}| + {7: }{8: 1 }in his cave. | + {7: }{8: 2 } | + {1:~ }|*4 + ## grid 3 + | + ]]) + else + screen:expect([[ + ## grid 1 + [2:---------------------------------------------]|*7 + [3:---------------------------------------------]| + ## grid 2 + {6:+ }{9:1 }{5:^This is a······························}| + {7: }{8: 1 }in his cave. | + {7: }{8: 2 } | + {1:~ }|*4 + ## grid 3 + | + ]]) + end + else + if foldtext then + screen:expect([[ + {6:+ }{9:1 }{5:^+-- 4 lines: This is a················}| + {7: }{8: 1 }in his cave. | + {7: }{8: 2 } | + {1:~ }|*4 + | + ]]) + else + screen:expect([[ + {6:+ }{9:1 }{5:^This is a······························}| + {7: }{8: 1 }in his cave. | + {7: }{8: 2 } | + {1:~ }|*4 + | + ]]) + end end end describe("when 'cursorline' is set", function() - it('with high-priority CursorLine', function() - command("hi! CursorLine guibg=NONE guifg=Red gui=NONE") - test_folded_cursorline() - end) - - it('with low-priority CursorLine', function() - command("hi! CursorLine guibg=NONE guifg=NONE gui=underline") - local attrs = screen:get_default_attr_ids() - attrs[12] = {underline = true} - attrs[13] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey, underline = true} - screen:set_default_attr_ids(attrs) - test_folded_cursorline() - end) + local function cursorline_tests(foldtext) + local sfx = not foldtext and ' (transparent foldtext)' or '' + it('with high-priority CursorLine' .. sfx, function() + command('hi! CursorLine guibg=NONE guifg=Red gui=NONE') + test_folded_cursorline(foldtext) + end) + + it('with low-priority CursorLine' .. sfx, function() + command('hi! CursorLine guibg=NONE guifg=NONE gui=underline') + local attrs = screen:get_default_attr_ids() + attrs[12] = { underline = true } + attrs[13] = { + foreground = Screen.colors.DarkBlue, + background = Screen.colors.LightGrey, + underline = true, + } + screen:set_default_attr_ids(attrs) + test_folded_cursorline(foldtext) + end) + end + + cursorline_tests(true) + cursorline_tests(false) end) - it("work with spell", function() - command("set spell") + it('with spell', function() + command('set spell') insert(content1) - feed("gg") - feed("zf3j") + feed('gg') + feed('zf3j') if not multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ {5:^+-- 4 lines: This is a······················}| in his cave. | | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | - ]]} + ]], + } end end) - it("work with matches", function() + it('with matches', function() insert(content1) - command("highlight MyWord gui=bold guibg=red guifg=white") + command('highlight MyWord gui=bold guibg=red guifg=white') command("call matchadd('MyWord', '\\V' . 'test', -1)") - feed("gg") - feed("zf3j") + feed('gg') + feed('zf3j') if not multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ {5:^+-- 4 lines: This is a······················}| in his cave. | | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | - ]]} + ]], + } end end) - it("works with multibyte fillchars", function() + it('with multibyte fillchars', function() insert([[ aa bb @@ -309,22 +366,16 @@ describe("folded lines", function() dd ee ff]]) - command("set fillchars+=foldopen:▾,foldsep:│,foldclose:▸") + command('set fillchars+=foldopen:▾,foldsep:│,foldclose:▸') feed_command('1') - command("set foldcolumn=2") + command('set foldcolumn=2') feed('zf4j') feed('zf2j') feed('zO') if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {7:▾▾}^aa | @@ -350,17 +401,11 @@ describe("folded lines", function() ]]) end - feed_command("set rightleft") + feed_command('set rightleft') if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 a^a{7:▾▾}| @@ -386,77 +431,47 @@ describe("folded lines", function() ]]) end - feed_command("set norightleft") + feed_command('set norightleft') if multigrid then - meths.input_mouse('left', 'press', '', 2, 0, 1) + api.nvim_input_mouse('left', 'press', '', 2, 0, 1) screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {7:▾▸}{5:^+--- 5 lines: aa··························}| {7:│ }ff | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 :set norightleft | ]]) else - meths.input_mouse('left', 'press', '', 0, 0, 1) + api.nvim_input_mouse('left', 'press', '', 0, 0, 1) screen:expect([[ {7:▾▸}{5:^+--- 5 lines: aa··························}| {7:│ }ff | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 :set norightleft | ]]) end if multigrid then - meths.input_mouse('left', 'press', '', 2, 0, 0) + api.nvim_input_mouse('left', 'press', '', 2, 0, 0) screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {7:▸ }{5:^+-- 6 lines: aa···························}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 ## grid 3 :set norightleft | ]]) else - meths.input_mouse('left', 'press', '', 0, 0, 0) + api.nvim_input_mouse('left', 'press', '', 0, 0, 0) screen:expect([[ {7:▸ }{5:^+-- 6 lines: aa···························}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 :set norightleft | ]]) end @@ -464,53 +479,35 @@ describe("folded lines", function() -- Add a winbar to avoid double-clicks command('setlocal winbar=!!!!!!') if multigrid then - meths.input_mouse('left', 'press', '', 2, 1, 0) + api.nvim_input_mouse('left', 'press', '', 2, 1, 0) screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {11:!!!!!! }| {7:▾▸}{5:^+--- 5 lines: aa··························}| {7:│ }ff | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 :set norightleft | ]]) else - meths.input_mouse('left', 'press', '', 0, 1, 0) + api.nvim_input_mouse('left', 'press', '', 0, 1, 0) screen:expect([[ {11:!!!!!! }| {7:▾▸}{5:^+--- 5 lines: aa··························}| {7:│ }ff | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 :set norightleft | ]]) end if multigrid then - meths.input_mouse('left', 'press', '', 2, 1, 1) + api.nvim_input_mouse('left', 'press', '', 2, 1, 1) screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {11:!!!!!! }| @@ -524,7 +521,7 @@ describe("folded lines", function() :set norightleft | ]]) else - meths.input_mouse('left', 'press', '', 0, 1, 1) + api.nvim_input_mouse('left', 'press', '', 0, 1, 1) screen:expect([[ {11:!!!!!! }| {7:▾▾}^aa | @@ -538,7 +535,7 @@ describe("folded lines", function() end end) - it("works with split", function() + it('with split', function() insert([[ aa bb @@ -547,12 +544,12 @@ describe("folded lines", function() ee ff]]) feed_command('2') - command("set foldcolumn=1") + command('set foldcolumn=1') feed('zf3j') feed_command('1') feed('zf2j') feed('zO') - feed_command("rightbelow new") + feed_command('rightbelow new') insert([[ aa bb @@ -561,20 +558,17 @@ describe("folded lines", function() ee ff]]) feed_command('2') - command("set foldcolumn=1") + command('set foldcolumn=1') feed('zf3j') feed_command('1') feed('zf2j') if multigrid then - meths.input_mouse('left', 'press', '', 4, 0, 0) + api.nvim_input_mouse('left', 'press', '', 4, 0, 0) screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*2 {2:[No Name] [+] }| - [4:---------------------------------------------]| - [4:---------------------------------------------]| - [4:---------------------------------------------]| + [4:---------------------------------------------]|*3 {3:[No Name] [+] }| [3:---------------------------------------------]| ## grid 2 @@ -588,7 +582,7 @@ describe("folded lines", function() {7:│}ff | ]]) else - meths.input_mouse('left', 'press', '', 0, 3, 0) + api.nvim_input_mouse('left', 'press', '', 0, 3, 0) screen:expect([[ {7:-}aa | {7:-}bb | @@ -602,15 +596,12 @@ describe("folded lines", function() end if multigrid then - meths.input_mouse('left', 'press', '', 4, 1, 0) + api.nvim_input_mouse('left', 'press', '', 4, 1, 0) screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*2 {2:[No Name] [+] }| - [4:---------------------------------------------]| - [4:---------------------------------------------]| - [4:---------------------------------------------]| + [4:---------------------------------------------]|*3 {3:[No Name] [+] }| [3:---------------------------------------------]| ## grid 2 @@ -624,7 +615,7 @@ describe("folded lines", function() {7:2}cc | ]]) else - meths.input_mouse('left', 'press', '', 0, 4, 0) + api.nvim_input_mouse('left', 'press', '', 0, 4, 0) screen:expect([[ {7:-}aa | {7:-}bb | @@ -638,15 +629,12 @@ describe("folded lines", function() end if multigrid then - meths.input_mouse('left', 'press', '', 2, 1, 0) + api.nvim_input_mouse('left', 'press', '', 2, 1, 0) screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*2 {3:[No Name] [+] }| - [4:---------------------------------------------]| - [4:---------------------------------------------]| - [4:---------------------------------------------]| + [4:---------------------------------------------]|*3 {2:[No Name] [+] }| [3:---------------------------------------------]| ## grid 2 @@ -660,7 +648,7 @@ describe("folded lines", function() {7:2}cc | ]]) else - meths.input_mouse('left', 'press', '', 0, 1, 0) + api.nvim_input_mouse('left', 'press', '', 0, 1, 0) screen:expect([[ {7:-}aa | {7:+}{5:^+--- 4 lines: bb···························}| @@ -674,15 +662,12 @@ describe("folded lines", function() end if multigrid then - meths.input_mouse('left', 'press', '', 2, 0, 0) + api.nvim_input_mouse('left', 'press', '', 2, 0, 0) screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*2 {3:[No Name] [+] }| - [4:---------------------------------------------]| - [4:---------------------------------------------]| - [4:---------------------------------------------]| + [4:---------------------------------------------]|*3 {2:[No Name] [+] }| [3:---------------------------------------------]| ## grid 2 @@ -696,7 +681,7 @@ describe("folded lines", function() {7:2}cc | ]]) else - meths.input_mouse('left', 'press', '', 0, 0, 0) + api.nvim_input_mouse('left', 'press', '', 0, 0, 0) screen:expect([[ {7:+}{5:^+-- 6 lines: aa····························}| {1:~ }| @@ -710,7 +695,7 @@ describe("folded lines", function() end end) - it("works with vsplit", function() + it('with vsplit', function() insert([[ aa bb @@ -719,12 +704,12 @@ describe("folded lines", function() ee ff]]) feed_command('2') - command("set foldcolumn=1") + command('set foldcolumn=1') feed('zf3j') feed_command('1') feed('zf2j') feed('zO') - feed_command("rightbelow vnew") + feed_command('rightbelow vnew') insert([[ aa bb @@ -733,20 +718,15 @@ describe("folded lines", function() ee ff]]) feed_command('2') - command("set foldcolumn=1") + command('set foldcolumn=1') feed('zf3j') feed_command('1') feed('zf2j') if multigrid then - meths.input_mouse('left', 'press', '', 4, 0, 0) + api.nvim_input_mouse('left', 'press', '', 4, 0, 0) screen:expect([[ ## grid 1 - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| + [2:----------------------]{2:│}[4:----------------------]|*6 {2:[No Name] [+] }{3:[No Name] [+] }| [3:---------------------------------------------]| ## grid 2 @@ -762,12 +742,10 @@ describe("folded lines", function() {7:-}^aa | {7:+}{5:+--- 4 lines: bb····}| {7:│}ff | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ]]) else - meths.input_mouse('left', 'press', '', 0, 0, 23) + api.nvim_input_mouse('left', 'press', '', 0, 0, 23) screen:expect([[ {7:-}aa {2:│}{7:-}^aa | {7:-}bb {2:│}{7:+}{5:+--- 4 lines: bb····}| @@ -781,15 +759,10 @@ describe("folded lines", function() end if multigrid then - meths.input_mouse('left', 'press', '', 4, 1, 0) + api.nvim_input_mouse('left', 'press', '', 4, 1, 0) screen:expect([[ ## grid 1 - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| + [2:----------------------]{2:│}[4:----------------------]|*6 {2:[No Name] [+] }{3:[No Name] [+] }| [3:---------------------------------------------]| ## grid 2 @@ -810,7 +783,7 @@ describe("folded lines", function() {7:│}ff | ]]) else - meths.input_mouse('left', 'press', '', 0, 1, 23) + api.nvim_input_mouse('left', 'press', '', 0, 1, 23) screen:expect([[ {7:-}aa {2:│}{7:-}^aa | {7:-}bb {2:│}{7:-}bb | @@ -824,24 +797,17 @@ describe("folded lines", function() end if multigrid then - meths.input_mouse('left', 'press', '', 2, 1, 0) + api.nvim_input_mouse('left', 'press', '', 2, 1, 0) screen:expect([[ ## grid 1 - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| + [2:----------------------]{2:│}[4:----------------------]|*6 {3:[No Name] [+] }{2:[No Name] [+] }| [3:---------------------------------------------]| ## grid 2 {7:-}aa | {7:+}{5:^+--- 4 lines: bb····}| {7:│}ff | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 :1 | ## grid 4 @@ -853,7 +819,7 @@ describe("folded lines", function() {7:│}ff | ]]) else - meths.input_mouse('left', 'press', '', 0, 1, 0) + api.nvim_input_mouse('left', 'press', '', 0, 1, 0) screen:expect([[ {7:-}aa {2:│}{7:-}aa | {7:+}{5:^+--- 4 lines: bb····}{2:│}{7:-}bb | @@ -867,24 +833,15 @@ describe("folded lines", function() end if multigrid then - meths.input_mouse('left', 'press', '', 2, 0, 0) + api.nvim_input_mouse('left', 'press', '', 2, 0, 0) screen:expect([[ ## grid 1 - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| - [2:----------------------]{2:│}[4:----------------------]| + [2:----------------------]{2:│}[4:----------------------]|*6 {3:[No Name] [+] }{2:[No Name] [+] }| [3:---------------------------------------------]| ## grid 2 {7:+}{5:^+-- 6 lines: aa·····}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 :1 | ## grid 4 @@ -896,7 +853,7 @@ describe("folded lines", function() {7:│}ff | ]]) else - meths.input_mouse('left', 'press', '', 0, 0, 0) + api.nvim_input_mouse('left', 'press', '', 0, 0, 0) screen:expect([[ {7:+}{5:^+-- 6 lines: aa·····}{2:│}{7:-}aa | {1:~ }{2:│}{7:-}bb | @@ -910,7 +867,7 @@ describe("folded lines", function() end end) - it("works with tab", function() + it('with tabpages', function() insert([[ aa bb @@ -919,23 +876,18 @@ describe("folded lines", function() ee ff]]) feed_command('2') - command("set foldcolumn=2") + command('set foldcolumn=2') feed('zf3j') feed_command('1') feed('zf2j') feed('zO') - feed_command("tab split") + feed_command('tab split') if multigrid then - meths.input_mouse('left', 'press', '', 4, 1, 1) + api.nvim_input_mouse('left', 'press', '', 4, 1, 1) screen:expect([[ ## grid 1 {10: + [No Name] }{11: + [No Name] }{2: }{10:X}| - [4:---------------------------------------------]| - [4:---------------------------------------------]| - [4:---------------------------------------------]| - [4:---------------------------------------------]| - [4:---------------------------------------------]| - [4:---------------------------------------------]| + [4:---------------------------------------------]|*6 [3:---------------------------------------------]| ## grid 2 (hidden) {7:- }aa | @@ -951,35 +903,26 @@ describe("folded lines", function() {7:- }^aa | {7:│+}{5:+--- 4 lines: bb··························}| {7:│ }ff | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ]]) else - meths.input_mouse('left', 'press', '', 0, 2, 1) + api.nvim_input_mouse('left', 'press', '', 0, 2, 1) screen:expect([[ {10: + [No Name] }{11: + [No Name] }{2: }{10:X}| {7:- }^aa | {7:│+}{5:+--- 4 lines: bb··························}| {7:│ }ff | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 :tab split | ]]) end if multigrid then - meths.input_mouse('left', 'press', '', 4, 0, 0) + api.nvim_input_mouse('left', 'press', '', 4, 0, 0) screen:expect([[ ## grid 1 {10: + [No Name] }{11: + [No Name] }{2: }{10:X}| - [4:---------------------------------------------]| - [4:---------------------------------------------]| - [4:---------------------------------------------]| - [4:---------------------------------------------]| - [4:---------------------------------------------]| - [4:---------------------------------------------]| + [4:---------------------------------------------]|*6 [3:---------------------------------------------]| ## grid 2 (hidden) {7:- }aa | @@ -993,138 +936,90 @@ describe("folded lines", function() :tab split | ## grid 4 {7:+ }{5:^+-- 6 lines: aa···························}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]) else - meths.input_mouse('left', 'press', '', 0, 1, 0) + api.nvim_input_mouse('left', 'press', '', 0, 1, 0) screen:expect([[ {10: + [No Name] }{11: + [No Name] }{2: }{10:X}| {7:+ }{5:^+-- 6 lines: aa···························}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 :tab split | ]]) end - feed_command("tabnext") + feed_command('tabnext') if multigrid then - meths.input_mouse('left', 'press', '', 2, 1, 1) + api.nvim_input_mouse('left', 'press', '', 2, 1, 1) screen:expect([[ ## grid 1 {11: + [No Name] }{10: + [No Name] }{2: }{10:X}| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*6 [3:---------------------------------------------]| ## grid 2 {7:- }^aa | {7:│+}{5:+--- 4 lines: bb··························}| {7:│ }ff | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 :tabnext | ## grid 4 (hidden) {7:+ }{5:+-- 6 lines: aa···························}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]) else - meths.input_mouse('left', 'press', '', 0, 2, 1) + api.nvim_input_mouse('left', 'press', '', 0, 2, 1) screen:expect([[ {11: + [No Name] }{10: + [No Name] }{2: }{10:X}| {7:- }^aa | {7:│+}{5:+--- 4 lines: bb··························}| {7:│ }ff | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 :tabnext | ]]) end if multigrid then - meths.input_mouse('left', 'press', '', 2, 0, 0) + api.nvim_input_mouse('left', 'press', '', 2, 0, 0) screen:expect([[ ## grid 1 {11: + [No Name] }{10: + [No Name] }{2: }{10:X}| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*6 [3:---------------------------------------------]| ## grid 2 {7:+ }{5:^+-- 6 lines: aa···························}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 :tabnext | ## grid 4 (hidden) {7:+ }{5:+-- 6 lines: aa···························}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]) else - meths.input_mouse('left', 'press', '', 0, 1, 0) + api.nvim_input_mouse('left', 'press', '', 0, 1, 0) screen:expect([[ {11: + [No Name] }{10: + [No Name] }{2: }{10:X}| {7:+ }{5:^+-- 6 lines: aa···························}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 :tabnext | ]]) end end) - it("works with multibyte text", function() - eq(true, meths.get_option_value('arabicshape', {})) + it('with multibyte text', function() + eq(true, api.nvim_get_option_value('arabicshape', {})) insert([[ å 语 x̨̣̘̫̲͚͎̎͂̀̂͛͛̾͢͟ العَرَبِيَّة möre text]]) if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 å 语 x̨̣̘̫̲͚͎̎͂̀̂͛͛̾͢ ﺎﻠﻋَﺮَﺒِﻳَّﺓ | möre tex^t | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 | ]]) @@ -1132,11 +1027,7 @@ describe("folded lines", function() screen:expect([[ å 语 x̨̣̘̫̲͚͎̎͂̀̂͛͛̾͢ ﺎﻠﻋَﺮَﺒِﻳَّﺓ | möre tex^t | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | ]]) end @@ -1145,215 +1036,119 @@ describe("folded lines", function() if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {5:^+-- 2 lines: å 语 x̨̣̘̫̲͚͎̎͂̀̂͛͛̾͢ ﺎﻠﻋَﺮَﺒِﻳَّﺓ·················}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 ## grid 3 | ]]) else screen:expect([[ {5:^+-- 2 lines: å 语 x̨̣̘̫̲͚͎̎͂̀̂͛͛̾͢ ﺎﻠﻋَﺮَﺒِﻳَّﺓ·················}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | ]]) end - feed_command("set noarabicshape") + feed_command('set noarabicshape') if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {5:^+-- 2 lines: å 语 x̨̣̘̫̲͚͎̎͂̀̂͛͛̾͢ العَرَبِيَّة·················}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 ## grid 3 :set noarabicshape | ]]) else screen:expect([[ {5:^+-- 2 lines: å 语 x̨̣̘̫̲͚͎̎͂̀̂͛͛̾͢ العَرَبِيَّة·················}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 :set noarabicshape | ]]) end - feed_command("set number foldcolumn=2") + feed_command('set number foldcolumn=2') if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {7:+ }{8: 1 }{5:^+-- 2 lines: å 语 x̨̣̘̫̲͚͎̎͂̀̂͛͛̾͢ العَرَبِيَّة···········}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 ## grid 3 :set number foldcolumn=2 | ]]) else screen:expect([[ {7:+ }{8: 1 }{5:^+-- 2 lines: å 语 x̨̣̘̫̲͚͎̎͂̀̂͛͛̾͢ العَرَبِيَّة···········}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 :set number foldcolumn=2 | ]]) end -- Note: too much of the folded line gets cut off.This is a vim bug. - feed_command("set rightleft") + feed_command('set rightleft') if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {5:···········ةيَّبِرَعَلا x̨̣̘̫̲͚͎̎͂̀̂͛͛̾͢ 语 å :senil 2 --^+}{8: 1 }{7: +}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*6 ## grid 3 :set rightleft | ]]) else screen:expect([[ {5:···········ةيَّبِرَعَلا x̨̣̘̫̲͚͎̎͂̀̂͛͛̾͢ 语 å :senil 2 --^+}{8: 1 }{7: +}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*6 :set rightleft | ]]) end - feed_command("set nonumber foldcolumn=0") + feed_command('set nonumber foldcolumn=0') if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {5:·················ةيَّبِرَعَلا x̨̣̘̫̲͚͎̎͂̀̂͛͛̾͢ 语 å :senil 2 --^+}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*6 ## grid 3 :set nonumber foldcolumn=0 | ]]) else screen:expect([[ {5:·················ةيَّبِرَعَلا x̨̣̘̫̲͚͎̎͂̀̂͛͛̾͢ 语 å :senil 2 --^+}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*6 :set nonumber foldcolumn=0 | ]]) end - feed_command("set arabicshape") + feed_command('set arabicshape') if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {5:·················ﺔﻴَّﺑِﺮَﻌَﻟﺍ x̨̣̘̫̲͚͎̎͂̀̂͛͛̾͢ 语 å :senil 2 --^+}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*6 ## grid 3 :set arabicshape | ]]) else screen:expect([[ {5:·················ﺔﻴَّﺑِﺮَﻌَﻟﺍ x̨̣̘̫̲͚͎̎͂̀̂͛͛̾͢ 语 å :senil 2 --^+}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*6 :set arabicshape | ]]) end @@ -1362,22 +1157,12 @@ describe("folded lines", function() if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 ﺔﻴَّﺑِﺮَﻌَ^ﻟﺍ x̨̣̘̫̲͚͎̎͂̀̂͛͛̾͢ 语 å| txet eröm| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*5 ## grid 3 :set arabicshape | ]]) @@ -1385,11 +1170,7 @@ describe("folded lines", function() screen:expect([[ ﺔﻴَّﺑِﺮَﻌَ^ﻟﺍ x̨̣̘̫̲͚͎̎͂̀̂͛͛̾͢ 语 å| txet eröm| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*5 :set arabicshape | ]]) end @@ -1398,22 +1179,12 @@ describe("folded lines", function() if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 ةيَّبِرَعَ^لا x̨̣̘̫̲͚͎̎͂̀̂͛͛̾͢ 语 å| txet eröm| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*5 ## grid 3 :set noarabicshape | ]]) @@ -1421,229 +1192,179 @@ describe("folded lines", function() screen:expect([[ ةيَّبِرَعَ^لا x̨̣̘̫̲͚͎̎͂̀̂͛͛̾͢ 语 å| txet eröm| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*5 :set noarabicshape | ]]) end - end) - it("work in cmdline window", function() - feed_command("set foldmethod=manual") - feed_command("let x = 1") - feed_command("/alpha") - feed_command("/omega") + it('in cmdline window', function() + feed_command('set foldmethod=manual foldcolumn=1') + feed_command('let x = 1') + feed_command('/alpha') + feed_command('/omega') - feed("<cr>q:") + feed('<cr>q:') if multigrid then screen:expect([[ ## grid 1 [2:---------------------------------------------]| {2:[No Name] }| - [4:---------------------------------------------]| - [4:---------------------------------------------]| - [4:---------------------------------------------]| - [4:---------------------------------------------]| + [4:---------------------------------------------]|*4 {3:[Command Line] }| [3:---------------------------------------------]| ## grid 2 - | + {7: } | ## grid 3 : | ## grid 4 - {1::}set foldmethod=manual | - {1::}let x = 1 | - {1::}^ | + {1::}{7: }set foldmethod=manual foldcolumn=1 | + {1::}{7: }let x = 1 | + {1::}{7: }^ | {1:~ }| ]]) else screen:expect([[ - | + {7: } | {2:[No Name] }| - {1::}set foldmethod=manual | - {1::}let x = 1 | - {1::}^ | + {1::}{7: }set foldmethod=manual foldcolumn=1 | + {1::}{7: }let x = 1 | + {1::}{7: }^ | {1:~ }| {3:[Command Line] }| : | ]]) end - feed("kzfk") + feed('kzfk') if multigrid then screen:expect([[ ## grid 1 [2:---------------------------------------------]| {2:[No Name] }| - [4:---------------------------------------------]| - [4:---------------------------------------------]| - [4:---------------------------------------------]| - [4:---------------------------------------------]| + [4:---------------------------------------------]|*4 {3:[Command Line] }| [3:---------------------------------------------]| ## grid 2 - | + {7: } | ## grid 3 : | ## grid 4 - {1::}{5:^+-- 2 lines: set foldmethod=manual·········}| - {1::} | - {1:~ }| - {1:~ }| + {1::}{7:+}{5:^+-- 2 lines: set foldmethod=manual foldcol}| + {1::}{7: } | + {1:~ }|*2 ]]) else screen:expect([[ - | + {7: } | {2:[No Name] }| - {1::}{5:^+-- 2 lines: set foldmethod=manual·········}| - {1::} | - {1:~ }| - {1:~ }| + {1::}{7:+}{5:^+-- 2 lines: set foldmethod=manual foldcol}| + {1::}{7: } | + {1:~ }|*2 {3:[Command Line] }| : | ]]) end - feed("<cr>") + feed('<cr>') if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 - ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {7: }^ | + {1:~ }|*6 ## grid 3 : | ]]) else screen:expect([[ - ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {7: }^ | + {1:~ }|*6 : | ]]) end - feed("/<c-f>") + feed('/<c-f>') if multigrid then screen:expect([[ ## grid 1 [2:---------------------------------------------]| {2:[No Name] }| - [5:---------------------------------------------]| - [5:---------------------------------------------]| - [5:---------------------------------------------]| - [5:---------------------------------------------]| + [5:---------------------------------------------]|*4 {3:[Command Line] }| [3:---------------------------------------------]| ## grid 2 - | + {7: } | ## grid 3 / | ## grid 5 - {1:/}alpha | - {1:/}{6:omega} | - {1:/}^ | + {1:/}{7: }alpha | + {1:/}{7: }{6:omega} | + {1:/}{7: }^ | {1:~ }| ]]) else screen:expect([[ - | + {7: } | {2:[No Name] }| - {1:/}alpha | - {1:/}{6:omega} | - {1:/}^ | + {1:/}{7: }alpha | + {1:/}{7: }{6:omega} | + {1:/}{7: }^ | {1:~ }| {3:[Command Line] }| / | ]]) end - feed("ggzfG") + feed('ggzfG') if multigrid then screen:expect([[ ## grid 1 [2:---------------------------------------------]| {2:[No Name] }| - [5:---------------------------------------------]| - [5:---------------------------------------------]| - [5:---------------------------------------------]| - [5:---------------------------------------------]| + [5:---------------------------------------------]|*4 {3:[Command Line] }| [3:---------------------------------------------]| ## grid 2 - | + {7: } | ## grid 3 / | ## grid 5 - {1:/}{5:^+-- 3 lines: alpha·························}| - {1:~ }| - {1:~ }| - {1:~ }| + {1:/}{7:+}{5:^+-- 3 lines: alpha························}| + {1:~ }|*3 ]]) else screen:expect([[ - | + {7: } | {2:[No Name] }| - {1:/}{5:^+-- 3 lines: alpha·························}| - {1:~ }| - {1:~ }| - {1:~ }| + {1:/}{7:+}{5:^+-- 3 lines: alpha························}| + {1:~ }|*3 {3:[Command Line] }| / | ]]) end - end) - it("work with autoresize", function() + it('foldcolumn autoresize', function() + fn.setline(1, 'line 1') + fn.setline(2, 'line 2') + fn.setline(3, 'line 3') + fn.setline(4, 'line 4') - funcs.setline(1, 'line 1') - funcs.setline(2, 'line 2') - funcs.setline(3, 'line 3') - funcs.setline(4, 'line 4') - - feed("zfj") - command("set foldcolumn=0") + feed('zfj') + command('set foldcolumn=0') if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {5:^+-- 2 lines: line 1·························}| line 3 | line 4 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ]]) @@ -1652,34 +1373,22 @@ describe("folded lines", function() {5:^+-- 2 lines: line 1·························}| line 3 | line 4 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]) end -- should adapt to the current nesting of folds (e.g., 1) - command("set foldcolumn=auto:1") + command('set foldcolumn=auto:1') if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {7:+}{5:^+-- 2 lines: line 1························}| {7: }line 3 | {7: }line 4 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ]]) @@ -1688,267 +1397,140 @@ describe("folded lines", function() {7:+}{5:^+-- 2 lines: line 1························}| {7: }line 3 | {7: }line 4 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]) end - command("set foldcolumn=auto") + command('set foldcolumn=auto') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {7:+}{5:^+-- 2 lines: line 1························}| {7: }line 3 | {7: }line 4 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | - ]], unchanged=true} + ]], + unchanged = true, + } else - screen:expect{grid=[[ + screen:expect { + grid = [[ {7:+}{5:^+-- 2 lines: line 1························}| {7: }line 3 | {7: }line 4 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | - ]], unchanged=true} + ]], + unchanged = true, + } end -- fdc should not change with a new fold as the maximum is 1 - feed("zf3j") + feed('zf3j') if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {7:+}{5:^+-- 4 lines: line 1························}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 ## grid 3 | ]]) else screen:expect([[ {7:+}{5:^+-- 4 lines: line 1························}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | ]]) end - command("set foldcolumn=auto:1") - if multigrid then screen:expect{grid=[[ + command('set foldcolumn=auto:1') + if multigrid then + screen:expect { + grid = [[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {7:+}{5:^+-- 4 lines: line 1························}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 ## grid 3 | - ]], unchanged=true} + ]], + unchanged = true, + } else - screen:expect{grid=[[ + screen:expect { + grid = [[ {7:+}{5:^+-- 4 lines: line 1························}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | - ]], unchanged=true} + ]], + unchanged = true, + } end -- relax the maximum fdc thus fdc should expand to -- accommodate the current number of folds - command("set foldcolumn=auto:4") + command('set foldcolumn=auto:4') if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {7:+ }{5:^+-- 4 lines: line 1·······················}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 ## grid 3 | ]]) else screen:expect([[ {7:+ }{5:^+-- 4 lines: line 1·······················}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | ]]) end end) - it('does not crash when foldtext is longer than columns #12988', function() + it('no crash when foldtext is longer than columns #12988', function() exec([[ function! MyFoldText() abort return repeat('-', &columns + 100) endfunction ]]) command('set foldtext=MyFoldText()') - feed("i<cr><esc>") - feed("vkzf") + feed('i<cr><esc>') + feed('vkzf') if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {5:^---------------------------------------------}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 ## grid 3 | ]]) else screen:expect([[ {5:^---------------------------------------------}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | ]]) end assert_alive() end) - it('work correctly with :move #18668', function() - screen:try_resize(45, 12) - exec([[ - set foldmethod=expr foldexpr=indent(v:lnum) - let content = ['', '', 'Line1', ' Line2', ' Line3', - \ 'Line4', ' Line5', ' Line6', - \ 'Line7', ' Line8', ' Line9'] - call append(0, content) - normal! zM - call cursor(4, 1) - move 2 - move 1 - ]]) - if multigrid then - screen:expect([[ - ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [3:---------------------------------------------]| - ## grid 2 - | - {5:^+-- 2 lines: Line2··························}| - | - Line1 | - Line4 | - {5:+-- 2 lines: Line5··························}| - Line7 | - {5:+-- 2 lines: Line8··························}| - | - {1:~ }| - {1:~ }| - ## grid 3 - | - ]]) - else - screen:expect([[ - | - {5:^+-- 2 lines: Line2··························}| - | - Line1 | - Line4 | - {5:+-- 2 lines: Line5··························}| - Line7 | - {5:+-- 2 lines: Line8··························}| - | - {1:~ }| - {1:~ }| - | - ]]) - end - end) - it('fold text is shown when text has been scrolled to the right #19123', function() insert(content1) command('set number nowrap') @@ -1957,13 +1539,7 @@ describe("folded lines", function() if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {8: 1 }^This is a | @@ -1971,8 +1547,7 @@ describe("folded lines", function() {8: 3 }{5:+-- 2 lines: sentence composed by·······}| {8: 5 }in his cave. | {8: 6 } | - {1:~ }| - {1:~ }| + {1:~ }|*2 ## grid 3 | ]]) @@ -1983,8 +1558,7 @@ describe("folded lines", function() {8: 3 }{5:+-- 2 lines: sentence composed by·······}| {8: 5 }in his cave. | {8: 6 } | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) end @@ -1993,13 +1567,7 @@ describe("folded lines", function() if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {8: 1 }^his is a | @@ -2007,8 +1575,7 @@ describe("folded lines", function() {8: 3 }{5:+-- 2 lines: sentence composed by·······}| {8: 5 }n his cave. | {8: 6 } | - {1:~ }| - {1:~ }| + {1:~ }|*2 ## grid 3 | ]]) @@ -2019,34 +1586,52 @@ describe("folded lines", function() {8: 3 }{5:+-- 2 lines: sentence composed by·······}| {8: 5 }n his cave. | {8: 6 } | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) end end) it('fold attached virtual lines are drawn and scrolled correctly #21837', function() - funcs.setline(1, 'line 1') - funcs.setline(2, 'line 2') - funcs.setline(3, 'line 3') - funcs.setline(4, 'line 4') - feed("zfj") - local ns = meths.create_namespace('ns') - meths.buf_set_extmark(0, ns, 0, 0, { virt_lines_above = true, virt_lines = {{{"virt_line above line 1", ""}}} }) - meths.buf_set_extmark(0, ns, 1, 0, { virt_lines = {{{"virt_line below line 2", ""}}} }) - meths.buf_set_extmark(0, ns, 2, 0, { virt_lines_above = true, virt_lines = {{{"virt_line above line 3", ""}}} }) - meths.buf_set_extmark(0, ns, 3, 0, { virt_lines = {{{"virt_line below line 4", ""}}} }) - if multigrid then - screen:expect{grid=[[ - ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + fn.setline(1, 'line 1') + fn.setline(2, 'line 2') + fn.setline(3, 'line 3') + fn.setline(4, 'line 4') + feed('zfj') + local ns = api.nvim_create_namespace('ns') + api.nvim_buf_set_extmark( + 0, + ns, + 0, + 0, + { virt_lines_above = true, virt_lines = { { { 'virt_line above line 1', '' } } } } + ) + api.nvim_buf_set_extmark( + 0, + ns, + 1, + 0, + { virt_lines = { { { 'virt_line below line 2', '' } } } } + ) + api.nvim_buf_set_extmark( + 0, + ns, + 2, + 0, + { virt_lines_above = true, virt_lines = { { { 'virt_line above line 3', '' } } } } + ) + api.nvim_buf_set_extmark( + 0, + ns, + 3, + 0, + { virt_lines = { { { 'virt_line below line 4', '' } } } } + ) + if multigrid then + screen:expect { + grid = [[ + ## grid 1 + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {5:^+-- 2 lines: line 1·························}| @@ -2054,13 +1639,22 @@ describe("folded lines", function() line 3 | line 4 | virt_line below line 4 | - {1:~ }| - {1:~ }| + {1:~ }|*2 ## grid 3 | - ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 5, curline = 0, curcol = 0, linecount = 4, sum_scroll_delta = 0}; - }} + ]], + win_viewport = { + [2] = { + win = 1000, + topline = 0, + botline = 5, + curline = 0, + curcol = 0, + linecount = 4, + sum_scroll_delta = 0, + }, + }, + } else screen:expect([[ {5:^+-- 2 lines: line 1·························}| @@ -2068,62 +1662,53 @@ describe("folded lines", function() line 3 | line 4 | virt_line below line 4 | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) end feed('jzfj') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {5:+-- 2 lines: line 1·························}| {5:^+-- 2 lines: line 3·························}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 | - ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 5, curline = 2, curcol = 0, linecount = 4, sum_scroll_delta = 0}; - }} + ]], + win_viewport = { + [2] = { + win = 1000, + topline = 0, + botline = 5, + curline = 2, + curcol = 0, + linecount = 4, + sum_scroll_delta = 0, + }, + }, + } else screen:expect([[ {5:+-- 2 lines: line 1·························}| {5:^+-- 2 lines: line 3·························}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | ]]) end feed('kzo<C-Y>') - funcs.setline(5, 'line 5') + fn.setline(5, 'line 5') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 virt_line above line 1 | @@ -2135,9 +1720,19 @@ describe("folded lines", function() {1:~ }| ## grid 3 | - ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 6, curline = 0, curcol = 0, linecount = 5, sum_scroll_delta = -1}; - }} + ]], + win_viewport = { + [2] = { + win = 1000, + topline = 0, + botline = 6, + curline = 0, + curcol = 0, + linecount = 5, + sum_scroll_delta = -1, + }, + }, + } else screen:expect([[ virt_line above line 1 | @@ -2151,7 +1746,7 @@ describe("folded lines", function() ]]) end - meths.input_mouse('left', 'press', '', multigrid and 2 or 0, 4, 0) + api.nvim_input_mouse('left', 'press', '', multigrid and 2 or 0, 4, 0) eq({ screencol = 1, screenrow = 5, @@ -2161,20 +1756,21 @@ describe("folded lines", function() line = 3, column = 1, coladd = 0, - }, funcs.getmousepos()) - - meths.buf_set_extmark(0, ns, 1, 0, { virt_lines = {{{"more virt_line below line 2", ""}}} }) + }, fn.getmousepos()) + + api.nvim_buf_set_extmark( + 0, + ns, + 1, + 0, + { virt_lines = { { { 'more virt_line below line 2', '' } } } } + ) feed('G<C-E>') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 line 1 | @@ -2186,9 +1782,19 @@ describe("folded lines", function() {1:~ }| ## grid 3 | - ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 6, curline = 4, curcol = 0, linecount = 5, sum_scroll_delta = 0}; - }} + ]], + win_viewport = { + [2] = { + win = 1000, + topline = 0, + botline = 6, + curline = 4, + curcol = 0, + linecount = 5, + sum_scroll_delta = 0, + }, + }, + } else screen:expect([[ line 1 | @@ -2204,15 +1810,10 @@ describe("folded lines", function() feed('<C-E>') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 line 2 | @@ -2220,13 +1821,22 @@ describe("folded lines", function() more virt_line below line 2 | {5:+-- 2 lines: line 3·························}| ^line 5 | - {1:~ }| - {1:~ }| + {1:~ }|*2 ## grid 3 | - ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 1, botline = 6, curline = 4, curcol = 0, linecount = 5, sum_scroll_delta = 1}; - }} + ]], + win_viewport = { + [2] = { + win = 1000, + topline = 1, + botline = 6, + curline = 4, + curcol = 0, + linecount = 5, + sum_scroll_delta = 1, + }, + }, + } else screen:expect([[ line 2 | @@ -2234,312 +1844,301 @@ describe("folded lines", function() more virt_line below line 2 | {5:+-- 2 lines: line 3·························}| ^line 5 | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) end feed('<C-E>') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 virt_line below line 2 | more virt_line below line 2 | {5:+-- 2 lines: line 3·························}| ^line 5 | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 | - ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 2, botline = 6, curline = 4, curcol = 0, linecount = 5, sum_scroll_delta = 2}; - }} + ]], + win_viewport = { + [2] = { + win = 1000, + topline = 2, + botline = 6, + curline = 4, + curcol = 0, + linecount = 5, + sum_scroll_delta = 2, + }, + }, + } else screen:expect([[ virt_line below line 2 | more virt_line below line 2 | {5:+-- 2 lines: line 3·························}| ^line 5 | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]) end feed('<C-E>') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 more virt_line below line 2 | {5:+-- 2 lines: line 3·························}| ^line 5 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | - ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 2, botline = 6, curline = 4, curcol = 0, linecount = 5, sum_scroll_delta = 3}; - }} + ]], + win_viewport = { + [2] = { + win = 1000, + topline = 2, + botline = 6, + curline = 4, + curcol = 0, + linecount = 5, + sum_scroll_delta = 3, + }, + }, + } else screen:expect([[ more virt_line below line 2 | {5:+-- 2 lines: line 3·························}| ^line 5 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]) end feed('<C-E>') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {5:+-- 2 lines: line 3·························}| ^line 5 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 | - ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 2, botline = 6, curline = 4, curcol = 0, linecount = 5, sum_scroll_delta = 4}; - }} + ]], + win_viewport = { + [2] = { + win = 1000, + topline = 2, + botline = 6, + curline = 4, + curcol = 0, + linecount = 5, + sum_scroll_delta = 4, + }, + }, + } else screen:expect([[ {5:+-- 2 lines: line 3·························}| ^line 5 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | ]]) end feed('<C-E>') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 ^line 5 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 ## grid 3 | - ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 4, botline = 6, curline = 4, curcol = 0, linecount = 5, sum_scroll_delta = 5}; - }} + ]], + win_viewport = { + [2] = { + win = 1000, + topline = 4, + botline = 6, + curline = 4, + curcol = 0, + linecount = 5, + sum_scroll_delta = 5, + }, + }, + } else screen:expect([[ ^line 5 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | ]]) end feed('3<C-Y>') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 virt_line below line 2 | more virt_line below line 2 | {5:+-- 2 lines: line 3·························}| ^line 5 | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 | - ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 2, botline = 6, curline = 4, curcol = 0, linecount = 5, sum_scroll_delta = 2}; - }} + ]], + win_viewport = { + [2] = { + win = 1000, + topline = 2, + botline = 6, + curline = 4, + curcol = 0, + linecount = 5, + sum_scroll_delta = 2, + }, + }, + } else screen:expect([[ virt_line below line 2 | more virt_line below line 2 | {5:+-- 2 lines: line 3·························}| ^line 5 | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]) end - meths.input_mouse('left', 'press', '3', multigrid and 2 or 0, 3, 0) + api.nvim_input_mouse('left', 'press', '3', multigrid and 2 or 0, 3, 0) if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 virt_line below line 2 | more virt_line below line 2 | {5:+-- 2 lines: line 3·························}| ^l{16:ine 5} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 {11:-- VISUAL LINE --} | - ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 2, botline = 6, curline = 4, curcol = 0, linecount = 5, sum_scroll_delta = 2}; - }} + ]], + win_viewport = { + [2] = { + win = 1000, + topline = 2, + botline = 6, + curline = 4, + curcol = 0, + linecount = 5, + sum_scroll_delta = 2, + }, + }, + } else screen:expect([[ virt_line below line 2 | more virt_line below line 2 | {5:+-- 2 lines: line 3·························}| ^l{16:ine 5} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {11:-- VISUAL LINE --} | ]]) end - meths.input_mouse('left', 'drag', '3', multigrid and 2 or 0, 7, 0) + api.nvim_input_mouse('left', 'drag', '3', multigrid and 2 or 0, 7, 0) if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 more virt_line below line 2 | {5:+-- 2 lines: line 3·························}| ^l{16:ine 5} | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 {11:-- VISUAL LINE --} | - ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 2, botline = 6, curline = 4, curcol = 0, linecount = 5, sum_scroll_delta = 3}; - }} + ]], + win_viewport = { + [2] = { + win = 1000, + topline = 2, + botline = 6, + curline = 4, + curcol = 0, + linecount = 5, + sum_scroll_delta = 3, + }, + }, + } else screen:expect([[ more virt_line below line 2 | {5:+-- 2 lines: line 3·························}| ^l{16:ine 5} | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {11:-- VISUAL LINE --} | ]]) end - meths.input_mouse('left', 'drag', '3', multigrid and 2 or 0, 7, 5) + api.nvim_input_mouse('left', 'drag', '3', multigrid and 2 or 0, 7, 5) if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {5:+-- 2 lines: line 3·························}| {16:line }^5 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 {11:-- VISUAL LINE --} | - ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 2, botline = 6, curline = 4, curcol = 5, linecount = 5, sum_scroll_delta = 4}; - }} + ]], + win_viewport = { + [2] = { + win = 1000, + topline = 2, + botline = 6, + curline = 4, + curcol = 5, + linecount = 5, + sum_scroll_delta = 4, + }, + }, + } else screen:expect([[ {5:+-- 2 lines: line 3·························}| {16:line }^5 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {11:-- VISUAL LINE --} | ]]) end @@ -2547,12 +2146,10 @@ describe("folded lines", function() feed('<Esc>gg') command('botright 1split | wincmd w') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*4 {3:[No Name] [+] }| [4:---------------------------------------------]| {2:[No Name] [+] }| @@ -2566,10 +2163,28 @@ describe("folded lines", function() | ## grid 4 line 1 | - ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 5, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 5, sum_scroll_delta = 0}; - }} + ]], + win_viewport = { + [2] = { + win = 1000, + topline = 0, + botline = 3, + curline = 0, + curcol = 0, + linecount = 5, + sum_scroll_delta = 0, + }, + [4] = { + win = 1001, + topline = 0, + botline = 2, + curline = 0, + curcol = 0, + linecount = 5, + sum_scroll_delta = 0, + }, + }, + } else screen:expect([[ ^line 1 | @@ -2585,12 +2200,10 @@ describe("folded lines", function() feed('<C-Y>') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*4 {3:[No Name] [+] }| [4:---------------------------------------------]| {2:[No Name] [+] }| @@ -2604,10 +2217,28 @@ describe("folded lines", function() | ## grid 4 line 1 | - ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 5, sum_scroll_delta = -1}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 5, sum_scroll_delta = 0}; - }} + ]], + win_viewport = { + [2] = { + win = 1000, + topline = 0, + botline = 3, + curline = 0, + curcol = 0, + linecount = 5, + sum_scroll_delta = -1, + }, + [4] = { + win = 1001, + topline = 0, + botline = 2, + curline = 0, + curcol = 0, + linecount = 5, + sum_scroll_delta = 0, + }, + }, + } else screen:expect([[ virt_line above line 1 | @@ -2623,7 +2254,7 @@ describe("folded lines", function() end) it('Folded and Visual highlights are combined #19691', function() - command('hi! Visual guibg=Red') + command('hi! Visual guifg=NONE guibg=Red') insert([[ " foofoofoofoofoofoo " 口 {{{1 @@ -2640,13 +2271,7 @@ describe("folded lines", function() if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {14:" foofoofoofoofo}ofoo | @@ -2654,8 +2279,7 @@ describe("folded lines", function() {14:" barbarbarbarba}rbar | {15:+-- 3 lines: " }{5:口···························}| {14:" bazbazbazbazb}^azbaz | - {1:~ }| - {1:~ }| + {1:~ }|*2 ## grid 3 {11:-- VISUAL BLOCK --} | ]]) @@ -2666,8 +2290,7 @@ describe("folded lines", function() {14:" barbarbarbarba}rbar | {15:+-- 3 lines: " }{5:口···························}| {14:" bazbazbazbazb}^azbaz | - {1:~ }| - {1:~ }| + {1:~ }|*2 {11:-- VISUAL BLOCK --} | ]]) end @@ -2676,13 +2299,7 @@ describe("folded lines", function() if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {14:" foofoofoofoofoo}foo | @@ -2690,8 +2307,7 @@ describe("folded lines", function() {14:" barbarbarbarbar}bar | {15:+-- 3 lines: " 口}{5:···························}| {14:" bazbazbazbazba}^zbaz | - {1:~ }| - {1:~ }| + {1:~ }|*2 ## grid 3 {11:-- VISUAL BLOCK --} | ]]) @@ -2702,8 +2318,7 @@ describe("folded lines", function() {14:" barbarbarbarbar}bar | {15:+-- 3 lines: " 口}{5:···························}| {14:" bazbazbazbazba}^zbaz | - {1:~ }| - {1:~ }| + {1:~ }|*2 {11:-- VISUAL BLOCK --} | ]]) end @@ -2712,13 +2327,7 @@ describe("folded lines", function() if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {14:" foofoofoofoofoof}oo | @@ -2726,8 +2335,7 @@ describe("folded lines", function() {14:" barbarbarbarbarb}ar | {15:+-- 3 lines: " 口}{5:···························}| {14:" bazbazbazbazbaz}^baz | - {1:~ }| - {1:~ }| + {1:~ }|*2 ## grid 3 {11:-- VISUAL BLOCK --} | ]]) @@ -2738,8 +2346,7 @@ describe("folded lines", function() {14:" barbarbarbarbarb}ar | {15:+-- 3 lines: " 口}{5:···························}| {14:" bazbazbazbazbaz}^baz | - {1:~ }| - {1:~ }| + {1:~ }|*2 {11:-- VISUAL BLOCK --} | ]]) end @@ -2748,13 +2355,7 @@ describe("folded lines", function() if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {14:" foofoofoofoofoofoo} | @@ -2762,8 +2363,7 @@ describe("folded lines", function() {14:" barbarbarbarbarbar} | {15:+-- 3 lines: " 口··}{5:·························}| {14:" bazbazbazbazbazba}^z | - {1:~ }| - {1:~ }| + {1:~ }|*2 ## grid 3 {11:-- VISUAL BLOCK --} | ]]) @@ -2774,8 +2374,7 @@ describe("folded lines", function() {14:" barbarbarbarbarbar} | {15:+-- 3 lines: " 口··}{5:·························}| {14:" bazbazbazbazbazba}^z | - {1:~ }| - {1:~ }| + {1:~ }|*2 {11:-- VISUAL BLOCK --} | ]]) end @@ -2784,13 +2383,7 @@ describe("folded lines", function() if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 " foofoofoofoofo{14:ofoo} | @@ -2798,8 +2391,7 @@ describe("folded lines", function() " barbarbarbarba{14:rbar} | {5:+-- 3 lines: " }{15:口··}{5:·························}| " bazbazbazbazba^z{14:baz} | - {1:~ }| - {1:~ }| + {1:~ }|*2 ## grid 3 {11:-- VISUAL BLOCK --} | ]]) @@ -2810,8 +2402,7 @@ describe("folded lines", function() " barbarbarbarba{14:rbar} | {5:+-- 3 lines: " }{15:口··}{5:·························}| " bazbazbazbazba^z{14:baz} | - {1:~ }| - {1:~ }| + {1:~ }|*2 {11:-- VISUAL BLOCK --} | ]]) end @@ -2820,13 +2411,7 @@ describe("folded lines", function() if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 " foofoofoofoofoo{14:foo} | @@ -2834,8 +2419,7 @@ describe("folded lines", function() " barbarbarbarbar{14:bar} | {5:+-- 3 lines: " }{15:口··}{5:·························}| " bazbazbazbazbaz^b{14:az} | - {1:~ }| - {1:~ }| + {1:~ }|*2 ## grid 3 {11:-- VISUAL BLOCK --} | ]]) @@ -2846,8 +2430,7 @@ describe("folded lines", function() " barbarbarbarbar{14:bar} | {5:+-- 3 lines: " }{15:口··}{5:·························}| " bazbazbazbazbaz^b{14:az} | - {1:~ }| - {1:~ }| + {1:~ }|*2 {11:-- VISUAL BLOCK --} | ]]) end @@ -2864,22 +2447,13 @@ describe("folded lines", function() if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {2:line} 1 | {5:+-- 2 lines: line 2·························}| {6:line} 4 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 /line^ | ]]) @@ -2888,34 +2462,22 @@ describe("folded lines", function() {2:line} 1 | {5:+-- 2 lines: line 2·························}| {6:line} 4 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 /line^ | ]]) end feed('<Esc>') - funcs.matchadd('Search', 'line') + fn.matchadd('Search', 'line') if multigrid then screen:expect([[ ## grid 1 - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| - [2:---------------------------------------------]| + [2:---------------------------------------------]|*7 [3:---------------------------------------------]| ## grid 2 {6:line} 1 | {5:+-- 2 lines: line 2·························}| {6:line} ^4 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ]]) @@ -2924,28 +2486,29 @@ describe("folded lines", function() {6:line} 1 | {5:+-- 2 lines: line 2·························}| {6:line} ^4 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]) end end) - it('support foldtext with virtual text format', function() + it('foldtext with virtual text format', function() screen:try_resize(30, 7) insert(content1) - command("hi! CursorLine guibg=NONE guifg=Red gui=NONE") + command('hi! CursorLine guibg=NONE guifg=Red gui=NONE') command('hi F0 guibg=Red guifg=Black') command('hi F1 guifg=White') - meths.set_option_value('cursorline', true, {}) - meths.set_option_value('foldcolumn', '4', {}) - meths.set_option_value('foldtext', '[' - .. '["▶", ["F0", "F1"]], ' - .. '[v:folddashes], ' - .. '["\t", "Search"], ' - .. '[getline(v:foldstart), "NonText"]]', {}) + api.nvim_set_option_value('cursorline', true, {}) + api.nvim_set_option_value('foldcolumn', '4', {}) + api.nvim_set_option_value( + 'foldtext', + '[' + .. '["▶", ["F0", "F1"]], ' + .. '[v:folddashes], ' + .. '["\t", "Search"], ' + .. '[getline(v:foldstart), "NonText"]]', + {} + ) command('3,4fold') command('5,6fold') @@ -2953,20 +2516,12 @@ describe("folded lines", function() if multigrid then screen:expect([[ ## grid 1 - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| + [2:------------------------------]|*6 [3:------------------------------]| ## grid 2 {7: }This is a | {7:+ }{4:^▶}{13:-}{17: }{18:valid English}{13:·····}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ]]) @@ -2974,33 +2529,24 @@ describe("folded lines", function() screen:expect([[ {7: }This is a | {7:+ }{4:^▶}{13:-}{17: }{18:valid English}{13:·····}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]) end - eq('▶-\tvalid English', funcs.foldtextresult(2)) + eq('▶-\tvalid English', fn.foldtextresult(2)) feed('zo') if multigrid then screen:expect([[ ## grid 1 - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| + [2:------------------------------]|*6 [3:------------------------------]| ## grid 2 {7: }This is a | {7:- }valid English | {7:│+ }{4:▶}{5:--}{19: }{18:sentence composed }| {7:│+ }{4:^▶}{13:--}{17: }{18:in his cave.}{13:······}| - {1:~ }| - {1:~ }| + {1:~ }|*2 ## grid 3 | ]]) @@ -3010,33 +2556,26 @@ describe("folded lines", function() {7:- }valid English | {7:│+ }{4:▶}{5:--}{19: }{18:sentence composed }| {7:│+ }{4:^▶}{13:--}{17: }{18:in his cave.}{13:······}| - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) end - eq('▶--\tsentence composed by', funcs.foldtextresult(3)) - eq('▶--\tin his cave.', funcs.foldtextresult(5)) + eq('▶--\tsentence composed by', fn.foldtextresult(3)) + eq('▶--\tin his cave.', fn.foldtextresult(5)) - command('hi! Visual guibg=Red') + command('hi! Visual guifg=NONE guibg=Red') feed('V2k') if multigrid then screen:expect([[ ## grid 1 - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| + [2:------------------------------]|*6 [3:------------------------------]| ## grid 2 {7: }This is a | {7:- }^v{14:alid English} | {7:│+ }{4:▶}{15:--}{19: }{20:sentence composed }| {7:│+ }{4:▶}{15:--}{19: }{20:in his cave.}{15:······}| - {1:~ }| - {1:~ }| + {1:~ }|*2 ## grid 3 {11:-- VISUAL LINE --} | ]]) @@ -3046,30 +2585,23 @@ describe("folded lines", function() {7:- }^v{14:alid English} | {7:│+ }{4:▶}{15:--}{19: }{20:sentence composed }| {7:│+ }{4:▶}{15:--}{19: }{20:in his cave.}{15:······}| - {1:~ }| - {1:~ }| + {1:~ }|*2 {11:-- VISUAL LINE --} | ]]) end - meths.set_option_value('rightleft', true, {}) + api.nvim_set_option_value('rightleft', true, {}) if multigrid then screen:expect([[ ## grid 1 - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| - [2:------------------------------]| + [2:------------------------------]|*6 [3:------------------------------]| ## grid 2 a si sihT{7: }| {14:hsilgnE dila}^v{7: -}| {20: desopmoc ecnetnes}{19: }{15:--}{4:▶}{7: +│}| {15:······}{20:.evac sih ni}{19: }{15:--}{4:▶}{7: +│}| - {1: ~}| - {1: ~}| + {1: ~}|*2 ## grid 3 {11:-- VISUAL LINE --} | ]]) @@ -3079,15 +2611,128 @@ describe("folded lines", function() {14:hsilgnE dila}^v{7: -}| {20: desopmoc ecnetnes}{19: }{15:--}{4:▶}{7: +│}| {15:······}{20:.evac sih ni}{19: }{15:--}{4:▶}{7: +│}| - {1: ~}| - {1: ~}| + {1: ~}|*2 + {11:-- VISUAL LINE --} | + ]]) + end + end) + + it('transparent foldtext', function() + screen:try_resize(30, 7) + insert(content1) + command('hi! CursorLine guibg=NONE guifg=Red gui=NONE') + command('hi F0 guibg=Red guifg=Black') + command('hi F1 guifg=White') + api.nvim_set_option_value('cursorline', true, {}) + api.nvim_set_option_value('foldcolumn', '4', {}) + api.nvim_set_option_value('foldtext', '', {}) + + command('3,4fold') + command('5,6fold') + command('2,6fold') + if multigrid then + screen:expect([[ + ## grid 1 + [2:------------------------------]|*6 + [3:------------------------------]| + ## grid 2 + {7: }This is a | + {7:+ }{13:^valid English·············}| + {1:~ }|*4 + ## grid 3 + | + ]]) + else + screen:expect([[ + {7: }This is a | + {7:+ }{13:^valid English·············}| + {1:~ }|*4 + | + ]]) + end + + feed('zo') + if multigrid then + screen:expect([[ + ## grid 1 + [2:------------------------------]|*6 + [3:------------------------------]| + ## grid 2 + {7: }This is a | + {7:- }valid English | + {7:│+ }{5:sentence composed by······}| + {7:│+ }{13:^in his cave.··············}| + {1:~ }|*2 + ## grid 3 + | + ]]) + else + screen:expect([[ + {7: }This is a | + {7:- }valid English | + {7:│+ }{5:sentence composed by······}| + {7:│+ }{13:^in his cave.··············}| + {1:~ }|*2 + | + ]]) + end + + command('hi! Visual guifg=NONE guibg=Red') + feed('V2k') + if multigrid then + screen:expect([[ + ## grid 1 + [2:------------------------------]|*6 + [3:------------------------------]| + ## grid 2 + {7: }This is a | + {7:- }^v{14:alid English} | + {7:│+ }{15:sentence composed by······}| + {7:│+ }{15:in his cave.··············}| + {1:~ }|*2 + ## grid 3 + {11:-- VISUAL LINE --} | + ]]) + else + screen:expect([[ + {7: }This is a | + {7:- }^v{14:alid English} | + {7:│+ }{15:sentence composed by······}| + {7:│+ }{15:in his cave.··············}| + {1:~ }|*2 + {11:-- VISUAL LINE --} | + ]]) + end + + api.nvim_set_option_value('rightleft', true, {}) + if multigrid then + screen:expect([[ + ## grid 1 + [2:------------------------------]|*6 + [3:------------------------------]| + ## grid 2 + a si sihT{7: }| + {14:hsilgnE dila}^v{7: -}| + {15:······yb desopmoc ecnetnes}{7: +│}| + {15:··············.evac sih ni}{7: +│}| + {1: ~}|*2 + ## grid 3 + {11:-- VISUAL LINE --} | + ]]) + else + screen:expect([[ + a si sihT{7: }| + {14:hsilgnE dila}^v{7: -}| + {15:······yb desopmoc ecnetnes}{7: +│}| + {15:··············.evac sih ni}{7: +│}| + {1: ~}|*2 {11:-- VISUAL LINE --} | ]]) end end) end - describe("with ext_multigrid", function() + describe('with ext_multigrid', function() with_ext_multigrid(true) end) diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua index 7776e024b0..727dc38829 100644 --- a/test/functional/ui/highlight_spec.lua +++ b/test/functional/ui/highlight_spec.lua @@ -5,9 +5,8 @@ local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert local command, exec = helpers.command, helpers.exec local eval = helpers.eval local feed_command, eq = helpers.feed_command, helpers.eq -local curbufmeths = helpers.curbufmeths -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local exec_lua = helpers.exec_lua describe('colorscheme compatibility', function() @@ -16,8 +15,8 @@ describe('colorscheme compatibility', function() end) it('&t_Co exists and is set to 256 by default', function() - eq(1, funcs.exists('&t_Co')) - eq(1, funcs.exists('+t_Co')) + eq(1, fn.exists('&t_Co')) + eq(1, fn.exists('+t_Co')) eq('256', eval('&t_Co')) end) end) @@ -30,13 +29,14 @@ describe('highlight: `:syntax manual`', function() before_each(function() clear() - screen = Screen.new(20,5) + screen = Screen.new(20, 5) screen:attach() - --syntax highlight for vimcscripts "echo" - screen:set_default_attr_ids( { - [0] = {bold=true, foreground=Screen.colors.Blue}, - [1] = {bold=true, foreground=Screen.colors.Brown} - } ) + -- syntax highlight for vimscript's "echo" + screen:set_default_attr_ids({ + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { bold = true, foreground = Screen.colors.Brown }, + [2] = { foreground = Screen.colors.Magenta1 }, + }) end) after_each(function() @@ -57,10 +57,8 @@ describe('highlight: `:syntax manual`', function() command('bn') feed_command('bp') screen:expect([[ - {1:^echo} 1 | - {0:~ }| - {0:~ }| - {0:~ }| + {1:^echo} {2:1} | + {0:~ }|*3 :bp | ]]) end) @@ -77,20 +75,17 @@ describe('highlight: `:syntax manual`', function() command('set nohidden') command('w') command('silent bn') - eq("tmp1.vim", eval("fnamemodify(bufname('%'), ':t')")) + eq('tmp1.vim', eval("fnamemodify(bufname('%'), ':t')")) feed_command('silent bp') - eq("Xtest-functional-ui-highlight.tmp.vim", eval("fnamemodify(bufname('%'), ':t')")) + eq('Xtest-functional-ui-highlight.tmp.vim', eval("fnamemodify(bufname('%'), ':t')")) screen:expect([[ - {1:^echo} 1 | - {0:~ }| - {0:~ }| - {0:~ }| + {1:^echo} {2:1} | + {0:~ }|*3 :silent bp | ]]) end) end) - describe('highlight defaults', function() local screen @@ -98,16 +93,16 @@ describe('highlight defaults', function() clear() screen = Screen.new() screen:set_default_attr_ids { - [0] = {bold=true, foreground=Screen.colors.Blue}; - [1] = {reverse = true, bold = true}; - [2] = {reverse = true}; - [3] = {bold = true}; - [4] = {bold = true, foreground = Screen.colors.SeaGreen}; - [5] = {foreground = Screen.colors.Red1, background = Screen.colors.WebGreen}; - [6] = {background = Screen.colors.Red1, foreground = Screen.colors.Grey100}; - [7] = {foreground = Screen.colors.Red}; - [8] = {foreground = Screen.colors.Blue}; - [9] = {italic = true}; + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { reverse = true, bold = true }, + [2] = { reverse = true }, + [3] = { bold = true }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen }, + [5] = { foreground = Screen.colors.Red1, background = Screen.colors.WebGreen }, + [6] = { background = Screen.colors.Red1, foreground = Screen.colors.Grey100 }, + [7] = { foreground = Screen.colors.Red }, + [8] = { foreground = Screen.colors.Blue }, + [9] = { italic = true }, } screen:attach() end) @@ -116,17 +111,10 @@ describe('highlight defaults', function() feed_command('sp', 'vsp', 'vsp') screen:expect([[ ^ │ │ | - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| + {0:~ }│{0:~ }│{0:~ }|*5 {1:[No Name] }{2:[No Name] [No Name] }| | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {2:[No Name] }| :vsp | ]]) @@ -134,17 +122,10 @@ describe('highlight defaults', function() feed('<c-w>j') screen:expect([[ │ │ | - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| + {0:~ }│{0:~ }│{0:~ }|*5 {2:[No Name] [No Name] [No Name] }| ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {1:[No Name] }| :vsp | ]]) @@ -154,51 +135,30 @@ describe('highlight defaults', function() feed('<c-w>k<c-w>l') screen:expect([[ │^ │ | - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| + {0:~ }│{0:~ }│{0:~ }|*5 {2:[No Name] }{1:[No Name] }{2:[No Name] }| | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {2:[No Name] }| :vsp | ]]) feed('<c-w>l') screen:expect([[ │ │^ | - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| + {0:~ }│{0:~ }│{0:~ }|*5 {2:[No Name] [No Name] }{1:[No Name] }| | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {2:[No Name] }| :vsp | ]]) feed('<c-w>h<c-w>h') screen:expect([[ ^ │ │ | - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| + {0:~ }│{0:~ }│{0:~ }|*5 {1:[No Name] }{2:[No Name] [No Name] }| | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {2:[No Name] }| :vsp | ]]) @@ -209,8 +169,7 @@ describe('highlight defaults', function() screen:try_resize(53, 4) screen:expect([[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:-- INSERT --} | ]]) end) @@ -219,8 +178,7 @@ describe('highlight defaults', function() screen:try_resize(53, 4) screen:expect([[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end) @@ -243,8 +201,7 @@ describe('highlight defaults', function() feed('i') screen:expect([[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 -- INSERT -- | ]]) feed('<esc>') @@ -253,8 +210,7 @@ describe('highlight defaults', function() feed('i') screen:expect([[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {5:-- INSERT --} | ]]) end) @@ -266,16 +222,16 @@ describe('highlight defaults', function() insert('neovim') screen:expect([[ {6:neovi^m} | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) - feed_command("hi ErrorMsg term=NONE cterm=NONE ctermfg=NONE ctermbg=NONE" - .. " gui=NONE guifg=NONE guibg=NONE guisp=NONE") + feed_command( + 'hi ErrorMsg term=NONE cterm=NONE ctermfg=NONE ctermbg=NONE' + .. ' gui=NONE guifg=NONE guibg=NONE guisp=NONE' + ) screen:expect([[ neovi^m | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end) @@ -284,18 +240,19 @@ describe('highlight defaults', function() screen:try_resize(53, 4) screen:expect([[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) - feed_command("hi NonTextAlt guifg=Red") - feed_command("hi! link NonText NonTextAlt") - screen:expect([[ + feed_command('hi NonTextAlt guifg=Red') + feed_command('hi! link NonText NonTextAlt') + screen:expect( + [[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 :hi! link NonText NonTextAlt | - ]], {[0] = {foreground=Screen.colors.Red}}) + ]], + { [0] = { foreground = Screen.colors.Red } } + ) end) it('Cursor after `:hi clear|syntax reset` #6508', function() @@ -310,90 +267,199 @@ describe('highlight defaults', function() insert(' ne \t o\tv im ') screen:expect([[ ne{7:.>----.}o{7:>-----}v{7:..}im{7:*^*¬} | - {7:~ }| - {7:~ }| + {7:~ }|*2 | ]]) feed_command('highlight Whitespace gui=NONE guifg=#0000FF') screen:expect([[ ne{8:.>----.}o{8:>-----}v{8:..}im{8:*^*}{7:¬} | - {7:~ }| - {7:~ }| + {7:~ }|*2 :highlight Whitespace gui=NONE guifg=#0000FF | ]]) end) it('are sent to UIs', function() screen:try_resize(53, 4) - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]], hl_groups={EndOfBuffer=0, MsgSeparator=1}} + ]], + hl_groups = { EndOfBuffer = 0, MsgSeparator = 1 }, + } command('highlight EndOfBuffer gui=italic') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {9:~ }| - {9:~ }| + {9:~ }|*2 | - ]], hl_groups={EndOfBuffer=9, MsgSeparator=1}} + ]], + hl_groups = { EndOfBuffer = 9, MsgSeparator = 1 }, + } command('highlight clear EndOfBuffer') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]], hl_groups={EndOfBuffer=0, MsgSeparator=1}} + ]], + hl_groups = { EndOfBuffer = 0, MsgSeparator = 1 }, + } end) end) describe('highlight', function() before_each(clear) - it('visual', function() - local screen = Screen.new(20,4) + it('Visual', function() + local screen = Screen.new(45, 5) screen:attach() screen:set_default_attr_ids({ - [1] = {background = Screen.colors.LightGrey}, - [2] = {bold = true, foreground = Screen.colors.Blue1}, - [3] = {bold = true}, + [1] = { foreground = Screen.colors.Black, background = Screen.colors.LightGrey }, + [2] = { bold = true, foreground = Screen.colors.Blue }, + [3] = { bold = true }, + [4] = { reverse = true, bold = true }, + [5] = { reverse = true }, + [6] = { background = Screen.colors.Grey90 }, }) insert([[ line1 foo bar + abcdefghijklmnopqrs + ABCDEFGHIJKLMNOPQRS ]]) + feed('gg') + command('vsplit') -- Non-blinking block cursor: does NOT highlight char-at-cursor. command('set guicursor=a:block-blinkon0') - feed('gg$vhhh') + feed('V') screen:expect([[ - line1 foo^ {1:bar} | - | - {2:~ }| - {3:-- VISUAL --} | + {1: }^l{1:ine1 foo bar} │{1: line1 foo bar} | + abcdefghijklmnopqrs │abcdefghijklmnopqrs | + ABCDEFGHIJKLMNOPQRS │ABCDEFGHIJKLMNOPQRS | + {4:[No Name] [+] }{5:[No Name] [+] }| + {3:-- VISUAL LINE --} | + ]]) + + feed('<Esc>$vhhh') + screen:expect([[ + line1 foo^ {1:bar} │ line1 foo{1: bar} | + abcdefghijklmnopqrs │abcdefghijklmnopqrs | + ABCDEFGHIJKLMNOPQRS │ABCDEFGHIJKLMNOPQRS | + {4:[No Name] [+] }{5:[No Name] [+] }| + {3:-- VISUAL --} | ]]) -- Vertical cursor: highlights char-at-cursor. #8983 command('set guicursor=a:block-blinkon175') screen:expect([[ - line1 foo{1:^ bar} | - | - {2:~ }| - {3:-- VISUAL --} | + line1 foo{1:^ bar} │ line1 foo{1: bar} | + abcdefghijklmnopqrs │abcdefghijklmnopqrs | + ABCDEFGHIJKLMNOPQRS │ABCDEFGHIJKLMNOPQRS | + {4:[No Name] [+] }{5:[No Name] [+] }| + {3:-- VISUAL --} | + ]]) + + command('set selection=exclusive') + screen:expect([[ + line1 foo{1:^ ba}r │ line1 foo{1: ba}r | + abcdefghijklmnopqrs │abcdefghijklmnopqrs | + ABCDEFGHIJKLMNOPQRS │ABCDEFGHIJKLMNOPQRS | + {4:[No Name] [+] }{5:[No Name] [+] }| + {3:-- VISUAL --} | + ]]) + + feed('o') + screen:expect([[ + line1 foo{1: ba}^r │ line1 foo{1: ba}r | + abcdefghijklmnopqrs │abcdefghijklmnopqrs | + ABCDEFGHIJKLMNOPQRS │ABCDEFGHIJKLMNOPQRS | + {4:[No Name] [+] }{5:[No Name] [+] }| + {3:-- VISUAL --} | + ]]) + + feed('V') + screen:expect([[ + {1: line1 foo ba^r} │{1: line1 foo bar} | + abcdefghijklmnopqrs │abcdefghijklmnopqrs | + ABCDEFGHIJKLMNOPQRS │ABCDEFGHIJKLMNOPQRS | + {4:[No Name] [+] }{5:[No Name] [+] }| + {3:-- VISUAL LINE --} | + ]]) + + command('set cursorcolumn') + feed('<C-V>') + screen:expect([[ + line1 foo{1: ba}^r │ line1 foo{1: ba}r | + abcdefghijklmn{6:o}pqrs │abcdefghijklmnopqrs | + ABCDEFGHIJKLMN{6:O}PQRS │ABCDEFGHIJKLMNOPQRS | + {4:[No Name] [+] }{5:[No Name] [+] }| + {3:-- VISUAL BLOCK --} | + ]]) + + command('set selection&') + screen:expect([[ + line1 foo{1: ba^r} │ line1 foo{1: bar} | + abcdefghijklmn{6:o}pqrs │abcdefghijklmnopqrs | + ABCDEFGHIJKLMN{6:O}PQRS │ABCDEFGHIJKLMNOPQRS | + {4:[No Name] [+] }{5:[No Name] [+] }| + {3:-- VISUAL BLOCK --} | + ]]) + + feed('^') + screen:expect([[ + {1:^line1 foo }bar │ {1:line1 foo }bar | + ab{6:c}defghijklmnopqrs │abcdefghijklmnopqrs | + AB{6:C}DEFGHIJKLMNOPQRS │ABCDEFGHIJKLMNOPQRS | + {4:[No Name] [+] }{5:[No Name] [+] }| + {3:-- VISUAL BLOCK --} | + ]]) + + feed('2j') + screen:expect([[ + {1:line1 foo }bar │ {1:line1 foo }bar | + ab{1:cdefghijkl}mnopqrs │ab{1:cdefghijkl}mnopqrs | + AB{1:^CDEFGHIJKL}MNOPQRS │AB{1:CDEFGHIJKL}MNOPQRS | + {4:[No Name] [+] }{5:[No Name] [+] }| + {3:-- VISUAL BLOCK --} | + ]]) + + command('set nocursorcolumn') + feed('O') + screen:expect([[ + {1:line1 foo }bar │ {1:line1 foo }bar | + ab{1:cdefghijkl}mnopqrs │ab{1:cdefghijkl}mnopqrs | + AB{1:CDEFGHIJK^L}MNOPQRS │AB{1:CDEFGHIJKL}MNOPQRS | + {4:[No Name] [+] }{5:[No Name] [+] }| + {3:-- VISUAL BLOCK --} | + ]]) + + command('set selection=exclusive') + screen:expect([[ + {1:line1 foo} bar │ {1:line1 foo} bar | + ab{1:cdefghijk}lmnopqrs │ab{1:cdefghijk}lmnopqrs | + AB{1:CDEFGHIJK}^LMNOPQRS │AB{1:CDEFGHIJK}LMNOPQRS | + {4:[No Name] [+] }{5:[No Name] [+] }| + {3:-- VISUAL BLOCK --} | ]]) end) it('cterm=standout gui=standout', function() - local screen = Screen.new(20,5) + local screen = Screen.new(20, 5) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {standout = true, bold = true, underline = true, - background = Screen.colors.Gray90, foreground = Screen.colors.Blue1}, - [3] = {standout = true, underline = true, - background = Screen.colors.Gray90} + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { + standout = true, + bold = true, + underline = true, + background = Screen.colors.Gray90, + foreground = Screen.colors.Blue1, + }, + [3] = { standout = true, underline = true, background = Screen.colors.Gray90 }, }) feed_command('hi CursorLine cterm=standout,underline gui=standout,underline') feed_command('set cursorline') @@ -409,7 +475,7 @@ describe('highlight', function() end) it('strikethrough', function() - local screen = Screen.new(25,6) + local screen = Screen.new(25, 6) screen:attach() feed_command('syntax on') feed_command('syn keyword TmpKeyword foo') @@ -420,27 +486,34 @@ describe('highlight', function() foo bar foobarfoobar ]]) - screen:expect([[ + screen:expect( + [[ {1:foo} | {1:foo} bar | foobarfoobar | ^ | {2:~ }| | - ]], { - [1] = {strikethrough = true}, - [2] = {bold = true, foreground = Screen.colors.Blue1}, - }) + ]], + { + [1] = { strikethrough = true }, + [2] = { bold = true, foreground = Screen.colors.Blue1 }, + } + ) end) it('nocombine', function() - local screen = Screen.new(25,6) - screen:set_default_attr_ids{ - [1] = {foreground = Screen.colors.SlateBlue, underline = true}, - [2] = {bold = true, foreground = Screen.colors.Blue1}, - [3] = {underline = true, reverse = true, foreground = Screen.colors.SlateBlue}, - [4] = {background = Screen.colors.Yellow, reverse = true, foreground = Screen.colors.SlateBlue}, - [5] = {foreground = Screen.colors.Red}, + local screen = Screen.new(25, 6) + screen:set_default_attr_ids { + [1] = { foreground = Screen.colors.SlateBlue, underline = true }, + [2] = { bold = true, foreground = Screen.colors.Blue1 }, + [3] = { underline = true, reverse = true, foreground = Screen.colors.SlateBlue }, + [4] = { + background = Screen.colors.Yellow, + reverse = true, + foreground = Screen.colors.SlateBlue, + }, + [5] = { foreground = Screen.colors.Red }, } screen:attach() feed_command('syntax on') @@ -451,37 +524,39 @@ describe('highlight', function() foobar foobar ]]) - screen:expect{grid=[[ - {1:foobar} | - {1:foobar} | + screen:expect { + grid = [[ + {1:foobar} |*2 ^ | - {2:~ }| - {2:~ }| + {2:~ }|*2 | - ]]} + ]], + } feed('/foo') - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:foo}{1:bar} | {4:foo}{1:bar} | | - {2:~ }| - {2:~ }| + {2:~ }|*2 /foo^ | - ]]} + ]], + } feed('<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {4:^foo}{1:bar} | {4:foo}{1:bar} | | - {2:~ }| - {2:~ }| + {2:~ }|*2 {5:search hit...uing at TOP} | - ]]} + ]], + } end) it('guisp (special/undercurl)', function() - local screen = Screen.new(25,10) + local screen = Screen.new(25, 10) screen:attach() feed_command('syntax on') feed_command('syn keyword TmpKeyword neovim') @@ -505,7 +580,8 @@ describe('highlight', function() specialwithfg ]]) feed('Go<tab>neovim tabbed') - screen:expect([[ + screen:expect( + [[ {1:neovim} | awesome {1:neovim} | wordcontainingneovim | @@ -516,20 +592,24 @@ describe('highlight', function() {1:neovim} tabbed^ | {0:~ }| {5:-- INSERT --} | - ]], { - [0] = {bold=true, foreground=Screen.colors.Blue}, - [1] = {background = Screen.colors.Yellow, foreground = Screen.colors.Red, - special = Screen.colors.Red}, - [2] = {special = Screen.colors.Red}, - [3] = {special = Screen.colors.Red, background = Screen.colors.Yellow}, - [4] = {foreground = Screen.colors.Red, special = Screen.colors.Red}, - [5] = {bold=true}, - }) - + ]], + { + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { + background = Screen.colors.Yellow, + foreground = Screen.colors.Red, + special = Screen.colors.Red, + }, + [2] = { special = Screen.colors.Red }, + [3] = { special = Screen.colors.Red, background = Screen.colors.Yellow }, + [4] = { foreground = Screen.colors.Red, special = Screen.colors.Red }, + [5] = { bold = true }, + } + ) end) it("'diff', syntax and extmark #23722", function() - local screen = Screen.new(25,10) + local screen = Screen.new(25, 10) screen:attach() exec([[ new @@ -539,28 +619,34 @@ describe('highlight', function() syn match WarningMsg "^.*$" call nvim_buf_add_highlight(0, -1, 'ErrorMsg', 1, 2, 8) ]]) - screen:expect([[ + screen:expect( + [[ {1: }^ | {1: }{2:01}{3:234 67}{2:89}{5: }| - {4:~ }| - {4:~ }| + {4:~ }|*2 {7:[No Name] [+] }| {1: } | {1: }{6:-----------------------}| {4:~ }| {8:[No Name] }| | - ]], { - [0] = {Screen.colors.WebGray, foreground = Screen.colors.DarkBlue}, - [1] = {background = Screen.colors.Grey, foreground = Screen.colors.Blue4}, - [2] = {foreground = Screen.colors.Red, background = Screen.colors.LightBlue}, - [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.LightBlue}, - [4] = {bold = true, foreground = Screen.colors.Blue}, - [5] = {background = Screen.colors.LightBlue}, - [6] = {bold = true, background = Screen.colors.LightCyan, foreground = Screen.colors.Blue1}, - [7] = {reverse = true, bold = true}, - [8] = {reverse = true}, - }) + ]], + { + [0] = { Screen.colors.WebGray, foreground = Screen.colors.DarkBlue }, + [1] = { background = Screen.colors.Grey, foreground = Screen.colors.Blue4 }, + [2] = { foreground = Screen.colors.Red, background = Screen.colors.LightBlue }, + [3] = { foreground = Screen.colors.Grey100, background = Screen.colors.LightBlue }, + [4] = { bold = true, foreground = Screen.colors.Blue }, + [5] = { background = Screen.colors.LightBlue }, + [6] = { + bold = true, + background = Screen.colors.LightCyan, + foreground = Screen.colors.Blue1, + }, + [7] = { reverse = true, bold = true }, + [8] = { reverse = true }, + } + ) end) end) @@ -569,62 +655,55 @@ describe("'listchars' highlight", function() before_each(function() clear() - screen = Screen.new(20,5) + screen = Screen.new(20, 5) screen:attach() end) it("'cursorline' and 'cursorcolumn'", function() screen:set_default_attr_ids({ - [0] = {bold=true, foreground=Screen.colors.Blue}, - [1] = {background=Screen.colors.Grey90} + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { background = Screen.colors.Grey90 }, }) feed_command('highlight clear ModeMsg') feed_command('set cursorline') feed('i') screen:expect([[ {1:^ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 -- INSERT -- | ]]) feed('abcdefg<cr>kkasdf') screen:expect([[ abcdefg | {1:kkasdf^ }| - {0:~ }| - {0:~ }| + {0:~ }|*2 -- INSERT -- | ]]) feed('<esc>') screen:expect([[ abcdefg | {1:kkasd^f }| - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) feed_command('set nocursorline') screen:expect([[ abcdefg | kkasd^f | - {0:~ }| - {0:~ }| + {0:~ }|*2 :set nocursorline | ]]) feed('k') screen:expect([[ abcde^fg | kkasdf | - {0:~ }| - {0:~ }| + {0:~ }|*2 :set nocursorline | ]]) feed('jjji<cr><cr><cr><esc>') screen:expect([[ kkasd | - | - | + |*2 ^f | | ]]) @@ -650,22 +729,22 @@ describe("'listchars' highlight", function() it("'cursorline' and with 'listchars' option", function() screen:set_default_attr_ids({ - [1] = {background=Screen.colors.Grey90}, + [1] = { background = Screen.colors.Grey90 }, [2] = { - foreground=Screen.colors.Red, - background=Screen.colors.Grey90, + foreground = Screen.colors.Red, + background = Screen.colors.Grey90, }, [3] = { - background=Screen.colors.Grey90, - foreground=Screen.colors.Blue, - bold=true, + background = Screen.colors.Grey90, + foreground = Screen.colors.Blue, + bold = true, }, [4] = { - foreground=Screen.colors.Blue, - bold=true, + foreground = Screen.colors.Blue, + bold = true, }, [5] = { - foreground=Screen.colors.Red, + foreground = Screen.colors.Red, }, }) feed_command('highlight clear ModeMsg') @@ -717,8 +796,7 @@ describe("'listchars' highlight", function() feed('$') screen:expect([[ {3:<}{1:r}{2:.}{1:sit}{2:.}{1:ame^t}{3:¬}{1: }| - {4:<} | - {4:<} | + {4:<} |*2 {4:~ }| :set cursorline | ]]) @@ -734,66 +812,42 @@ describe("'listchars' highlight", function() it("'listchar' with wrap", function() screen:set_default_attr_ids({ - [0] = {bold=true, foreground=Screen.colors.Blue}, + [0] = { bold = true, foreground = Screen.colors.Blue }, }) feed_command('set wrap') feed_command('set listchars=eol:¬,precedes:< list') feed('90ia<esc>') screen:expect([[ {0:<}aaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaa| + aaaaaaaaaaaaaaaaaaaa|*2 aaaaaaaaa^a{0:¬} | | ]]) feed('0') screen:expect([[ ^aaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaa| + aaaaaaaaaaaaaaaaaaaa|*3 | ]]) end) it("'listchar' in visual mode", function() screen:set_default_attr_ids({ - [1] = {background=Screen.colors.Grey90}, - [2] = { - foreground=Screen.colors.Red, - background=Screen.colors.Grey90, - }, - [3] = { - background=Screen.colors.Grey90, - foreground=Screen.colors.Blue, - bold=true, - }, - [4] = { - foreground=Screen.colors.Blue, - bold=true, - }, - [5] = { - foreground=Screen.colors.Red, - }, - [6] = { - background=Screen.colors.LightGrey, - }, - [7] = { - background=Screen.colors.LightGrey, - foreground=Screen.colors.Red, - }, - [8] = { - background=Screen.colors.LightGrey, - foreground=Screen.colors.Blue, - bold=true, - }, + [1] = { background = Screen.colors.Grey90 }, + [2] = { foreground = Screen.colors.Red, background = Screen.colors.Grey90 }, + [3] = { background = Screen.colors.Grey90, foreground = Screen.colors.Blue, bold = true }, + [4] = { foreground = Screen.colors.Blue, bold = true }, + [5] = { foreground = Screen.colors.Red }, + [6] = { background = Screen.colors.LightGrey, foreground = Screen.colors.Black }, + [7] = { background = Screen.colors.LightGrey, foreground = Screen.colors.Red }, + [8] = { background = Screen.colors.LightGrey, foreground = Screen.colors.Blue, bold = true }, }) - feed_command('highlight clear ModeMsg') - feed_command('highlight Whitespace guifg=#FF0000') - feed_command('set cursorline') - feed_command('set tabstop=8') - feed_command('set nowrap') - feed_command('set listchars=space:.,eol:¬,tab:>-,extends:>,precedes:<,trail:* list') + command('highlight clear ModeMsg') + command('highlight Whitespace guifg=#FF0000') + command('set cursorline') + command('set tabstop=8') + command('set nowrap') + command('set listchars=space:.,eol:¬,tab:>-,extends:>,precedes:<,trail:* list') feed('i\t abcd <cr>\t abcd Lorem ipsum dolor sit amet<cr><esc>kkk0') screen:expect([[ {2:^>-------.}{1:abcd}{2:*}{3:¬}{1: }| @@ -830,10 +884,10 @@ describe("'listchars' highlight", function() it("'cursorline' with :match", function() screen:set_default_attr_ids({ - [0] = {bold=true, foreground=Screen.colors.Blue}, - [1] = {background=Screen.colors.Grey90}, - [2] = {foreground=Screen.colors.Red}, - [3] = {foreground=Screen.colors.X11Green, background=Screen.colors.Red1}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { background = Screen.colors.Grey90 }, + [2] = { foreground = Screen.colors.Red }, + [3] = { foreground = Screen.colors.X11Green, background = Screen.colors.Red1 }, }) feed_command('highlight clear ModeMsg') feed_command('highlight Whitespace guifg=#FF0000') @@ -842,25 +896,19 @@ describe("'listchars' highlight", function() feed('ia \t bc \t <esc>') screen:expect([[ a bc ^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) feed_command('set listchars=space:.,eol:¬,tab:>-,extends:>,precedes:<,trail:* list') screen:expect([[ a{2:.>-----.}bc{2:*>---*^*}{0:¬} | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) feed_command('match Error /\\s\\+$/') screen:expect([[ a{2:.>-----.}bc{3:*>---*^*}{0:¬} | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) end) @@ -870,15 +918,15 @@ describe('CursorLine and CursorLineNr highlights', function() before_each(clear) it('overridden by Error, ColorColumn if fg not set', function() - local screen = Screen.new(50,5) + local screen = Screen.new(50, 5) screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.SlateBlue}, - [2] = {bold = true, foreground = Screen.colors.Brown}, - [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [4] = {foreground = Screen.colors.SlateBlue, background = Screen.colors.Gray90}, - [5] = {background = Screen.colors.Gray90}, - [6] = {bold = true, foreground = Screen.colors.Blue1}, - [7] = {background = Screen.colors.LightRed}, + [1] = { foreground = Screen.colors.SlateBlue }, + [2] = { bold = true, foreground = Screen.colors.Brown }, + [3] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [4] = { foreground = Screen.colors.SlateBlue, background = Screen.colors.Gray90 }, + [5] = { background = Screen.colors.Gray90 }, + [6] = { bold = true, foreground = Screen.colors.Blue1 }, + [7] = { background = Screen.colors.LightRed }, }) screen:attach() @@ -906,12 +954,12 @@ describe('CursorLine and CursorLineNr highlights', function() end) it("overridden by NonText in 'showbreak' characters", function() - local screen = Screen.new(20,5) + local screen = Screen.new(20, 5) screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.Yellow, background = Screen.colors.Blue}; - [2] = {foreground = Screen.colors.Black, background = Screen.colors.White}; - [3] = {foreground = Screen.colors.Yellow, background = Screen.colors.White}; - [4] = {foreground = Screen.colors.Yellow}; + [1] = { foreground = Screen.colors.Yellow, background = Screen.colors.Blue }, + [2] = { foreground = Screen.colors.Black, background = Screen.colors.White }, + [3] = { foreground = Screen.colors.Yellow, background = Screen.colors.White }, + [4] = { foreground = Screen.colors.Yellow }, }) screen:attach() @@ -957,13 +1005,13 @@ describe('CursorLine and CursorLineNr highlights', function() end) it("'cursorlineopt' screenline", function() - local screen = Screen.new(20,5) + local screen = Screen.new(20, 5) screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.Black, background = Screen.colors.White}; - [2] = {foreground = Screen.colors.Yellow}; - [3] = {foreground = Screen.colors.Red, background = Screen.colors.Green}; - [4] = {foreground = Screen.colors.Green, background = Screen.colors.Red}; - [5] = {bold = true}, -- ModeMsg + [1] = { foreground = Screen.colors.Black, background = Screen.colors.White }, + [2] = { foreground = Screen.colors.Yellow }, + [3] = { foreground = Screen.colors.Red, background = Screen.colors.Green }, + [4] = { foreground = Screen.colors.Green, background = Screen.colors.Red }, + [5] = { bold = true }, -- ModeMsg }) screen:attach() @@ -1088,16 +1136,16 @@ describe('CursorLine and CursorLineNr highlights', function() -- oldtest: Test_cursorline_after_yank() it('always updated. vim-patch:8.1.0849', function() - local screen = Screen.new(50,5) + local screen = Screen.new(50, 5) screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.SlateBlue}, - [2] = {bold = true, foreground = Screen.colors.Brown}, - [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [4] = {foreground = Screen.colors.SlateBlue, background = Screen.colors.Gray90}, - [5] = {background = Screen.colors.Gray90}, - [6] = {bold = true, foreground = Screen.colors.Blue1}, - [7] = {background = Screen.colors.LightRed}, - [8] = {foreground = Screen.colors.Brown}, + [1] = { foreground = Screen.colors.SlateBlue }, + [2] = { bold = true, foreground = Screen.colors.Brown }, + [3] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [4] = { foreground = Screen.colors.SlateBlue, background = Screen.colors.Gray90 }, + [5] = { background = Screen.colors.Gray90 }, + [6] = { bold = true, foreground = Screen.colors.Blue1 }, + [7] = { background = Screen.colors.LightRed }, + [8] = { foreground = Screen.colors.Brown }, }) screen:attach() command('set cursorline relativenumber') @@ -1122,18 +1170,18 @@ describe('CursorLine and CursorLineNr highlights', function() -- oldtest: Test_cursorline_with_visualmode() it('with visual area. vim-patch:8.1.1001', function() - local screen = Screen.new(50,5) + local screen = Screen.new(50, 5) screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.SlateBlue}, - [2] = {bold = true, foreground = Screen.colors.Brown}, - [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [4] = {foreground = Screen.colors.SlateBlue, background = Screen.colors.Gray90}, - [5] = {background = Screen.colors.Gray90}, - [6] = {bold = true, foreground = Screen.colors.Blue1}, - [7] = {background = Screen.colors.LightRed}, - [8] = {foreground = Screen.colors.Brown}, - [9] = {background = Screen.colors.LightGrey}, - [10] = {bold = true}, + [1] = { foreground = Screen.colors.SlateBlue }, + [2] = { bold = true, foreground = Screen.colors.Brown }, + [3] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [4] = { foreground = Screen.colors.SlateBlue, background = Screen.colors.Gray90 }, + [5] = { background = Screen.colors.Gray90 }, + [6] = { bold = true, foreground = Screen.colors.Blue1 }, + [7] = { background = Screen.colors.LightRed }, + [8] = { foreground = Screen.colors.Brown }, + [9] = { foreground = Screen.colors.Black, background = Screen.colors.LightGrey }, + [10] = { bold = true }, }) screen:attach() command('set cursorline') @@ -1142,8 +1190,7 @@ describe('CursorLine and CursorLineNr highlights', function() screen:expect([[ {9:abc} | ^a{9:bc} | - abc | - abc | + abc |*2 {10:-- VISUAL LINE --} | ]]) end) @@ -1152,8 +1199,8 @@ describe('CursorLine and CursorLineNr highlights', function() it('is updated if cursor is moved up from timer vim-patch:8.2.4591', function() local screen = Screen.new(50, 8) screen:set_default_attr_ids({ - [1] = {background = Screen.colors.Gray90}, -- CursorLine - [2] = {bold = true, foreground = Screen.colors.Blue1}, -- NonText + [1] = { background = Screen.colors.Gray90 }, -- CursorLine + [2] = { bold = true, foreground = Screen.colors.Blue1 }, -- NonText }) screen:attach() exec([[ @@ -1167,40 +1214,41 @@ describe('CursorLine and CursorLineNr highlights', function() call timer_start(300, 'Func') ]]) - screen:expect({grid = [[ + screen:expect({ + grid = [[ aaaaa | bbbbb | ccccc | {1:^ddddd }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 | - ]], timeout = 100}) - screen:expect({grid = [[ + ]], + timeout = 100, + }) + screen:expect({ + grid = [[ aaaaa | {1:^bbbbb }| ccccc | ddddd | - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 | - ]]}) + ]], + }) end) it('with split windows in diff mode', function() - local screen = Screen.new(50,12) + local screen = Screen.new(50, 12) screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGray}, - [2] = {bold = true, background = Screen.colors.Red}, - [3] = {background = Screen.colors.LightMagenta}, - [4] = {reverse = true}, - [5] = {background = Screen.colors.LightBlue}, - [6] = {background = Screen.colors.LightCyan1, bold = true, foreground = Screen.colors.Blue1}, - [7] = {background = Screen.colors.Red, foreground = Screen.colors.White}, - [8] = {bold = true, foreground = Screen.colors.Blue1}, - [9] = {bold = true, reverse = true}, + [1] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGray }, + [2] = { bold = true, background = Screen.colors.Red }, + [3] = { background = Screen.colors.LightMagenta }, + [4] = { reverse = true }, + [5] = { background = Screen.colors.LightBlue }, + [6] = { background = Screen.colors.LightCyan1, bold = true, foreground = Screen.colors.Blue1 }, + [7] = { background = Screen.colors.Red, foreground = Screen.colors.White }, + [8] = { bold = true, foreground = Screen.colors.Blue1 }, + [9] = { bold = true, reverse = true }, }) screen:attach() @@ -1210,20 +1258,19 @@ describe('CursorLine and CursorLineNr highlights', function() feed('<esc>gg') command('vsplit') command('enew') - feed('iline 1 some text<cr>line 2 moRe text!<cr>extra line!<cr>extra line!<cr>extra line!<cr>last line ...<cr>') + feed( + 'iline 1 some text<cr>line 2 moRe text!<cr>extra line!<cr>extra line!<cr>extra line!<cr>last line ...<cr>' + ) feed('<esc>gg') command('windo diffthis') screen:expect([[ {1: }{7:line 1 some text }│{1: }{7:^line 1 some text }| {1: }{3:line 2 mo}{2:Re text!}{3: }│{1: }{3:line 2 mo}{2:re text}{3: }| {1: }{5:extra line! }│{1: }{6:----------------------}| - {1: }extra line! │{1: }extra line! | - {1: }extra line! │{1: }extra line! | + {1: }extra line! │{1: }extra line! |*2 {1: }last line ... │{1: }last line ... | {1: } │{1: } | - {8:~ }│{8:~ }| - {8:~ }│{8:~ }| - {8:~ }│{8:~ }| + {8:~ }│{8:~ }|*3 {4:[No Name] [+] }{9:[No Name] [+] }| | ]]) @@ -1232,13 +1279,10 @@ describe('CursorLine and CursorLineNr highlights', function() {1: }line 1 some text │{1: }line 1 some text | {1: }{3:line 2 mo}{2:Re text!}{3: }│{1: }{3:line 2 mo}{2:re text}{3: }| {1: }{5:extra line! }│{1: }{6:----------------------}| - {1: }extra line! │{1: }extra line! | - {1: }extra line! │{1: }extra line! | + {1: }extra line! │{1: }extra line! |*2 {1: }last line ... │{1: }last line ... | {1: }{7: }│{1: }{7:^ }| - {8:~ }│{8:~ }| - {8:~ }│{8:~ }| - {8:~ }│{8:~ }| + {8:~ }│{8:~ }|*3 {4:[No Name] [+] }{9:[No Name] [+] }| | ]]) @@ -1247,50 +1291,52 @@ describe('CursorLine and CursorLineNr highlights', function() -- Rendered as underline in a diff-line. #9028 command('hi CursorLine ctermbg=red ctermfg=NONE guibg=red guifg=NONE') feed('kkkk') - screen:expect([[ + screen:expect( + [[ {1: }line 1 some text │{1: }line 1 some text | {1: }{11:line 2 mo}{12:Re text!}{11: }│{1: }{11:^line 2 mo}{12:re text}{11: }| {1: }{5:extra line! }│{1: }{6:----------------------}| - {1: }extra line! │{1: }extra line! | - {1: }extra line! │{1: }extra line! | + {1: }extra line! │{1: }extra line! |*2 {1: }last line ... │{1: }last line ... | {1: } │{1: } | - {8:~ }│{8:~ }| - {8:~ }│{8:~ }| - {8:~ }│{8:~ }| + {8:~ }│{8:~ }|*3 {4:[No Name] [+] }{9:[No Name] [+] }| | - ]], { - [1] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGray}, - [2] = {bold = true, background = Screen.colors.Red}, - [3] = {background = Screen.colors.LightMagenta}, - [4] = {reverse = true}, - [5] = {background = Screen.colors.LightBlue}, - [6] = {background = Screen.colors.LightCyan1, bold = true, foreground = Screen.colors.Blue1}, - [7] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [8] = {bold = true, foreground = Screen.colors.Blue1}, - [9] = {bold = true, reverse = true}, - [10] = {bold = true}, - [11] = {underline = true, - background = Screen.colors.LightMagenta}, - [12] = {bold = true, underline = true, - background = Screen.colors.Red}, - }) + ]], + { + [1] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGray }, + [2] = { bold = true, background = Screen.colors.Red }, + [3] = { background = Screen.colors.LightMagenta }, + [4] = { reverse = true }, + [5] = { background = Screen.colors.LightBlue }, + [6] = { + background = Screen.colors.LightCyan1, + bold = true, + foreground = Screen.colors.Blue1, + }, + [7] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [8] = { bold = true, foreground = Screen.colors.Blue1 }, + [9] = { bold = true, reverse = true }, + [10] = { bold = true }, + [11] = { underline = true, background = Screen.colors.LightMagenta }, + [12] = { bold = true, underline = true, background = Screen.colors.Red }, + } + ) end) -- oldtest: Test_diff_with_cursorline_number() it('CursorLineNr shows correctly just below filler lines', function() - local screen = Screen.new(50,12) + local screen = Screen.new(50, 12) screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGray}, - [2] = {background = Screen.colors.LightCyan1, bold = true, foreground = Screen.colors.Blue1}, - [3] = {reverse = true}, - [4] = {background = Screen.colors.LightBlue}, - [5] = {background = Screen.colors.Red, foreground = Screen.colors.White}, - [6] = {background = Screen.colors.White, bold = true, foreground = Screen.colors.Black}, - [7] = {bold = true, foreground = Screen.colors.Blue1}, - [8] = {bold = true, reverse = true}, - [9] = {foreground = Screen.colors.Brown}, + [1] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGray }, + [2] = { background = Screen.colors.LightCyan1, bold = true, foreground = Screen.colors.Blue1 }, + [3] = { reverse = true }, + [4] = { background = Screen.colors.LightBlue }, + [5] = { background = Screen.colors.Red, foreground = Screen.colors.White }, + [6] = { background = Screen.colors.White, bold = true, foreground = Screen.colors.Black }, + [7] = { bold = true, foreground = Screen.colors.Blue1 }, + [8] = { bold = true, reverse = true }, + [9] = { foreground = Screen.colors.Brown }, }) screen:attach() @@ -1308,12 +1354,7 @@ describe('CursorLine and CursorLineNr highlights', function() {1: }{6: 1 }{5:^foo }│{1: }{6: 2 }{5:foo }| {1: }{9: 2 }foo │{1: }{9: 3 }foo | {1: }{9: 3 }bar │{1: }{9: 4 }bar | - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| + {7:~ }│{7:~ }|*6 {8:[No Name] [+] }{3:[No Name] [+] }| | ]]) @@ -1323,12 +1364,7 @@ describe('CursorLine and CursorLineNr highlights', function() {1: }{6: 1 }^foo │{1: }{6: 2 }{5:foo }| {1: }{9: 2 }foo │{1: }{9: 3 }foo | {1: }{9: 3 }bar │{1: }{9: 4 }bar | - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| - {7:~ }│{7:~ }| + {7:~ }│{7:~ }|*6 {8:[No Name] [+] }{3:[No Name] [+] }| | ]]) @@ -1341,9 +1377,9 @@ describe('CursorColumn highlight', function() clear() screen = Screen.new(50, 8) screen:set_default_attr_ids({ - [1] = {background = Screen.colors.Gray90}, -- CursorColumn - [2] = {bold = true, foreground = Screen.colors.Blue1}, -- NonText - [3] = {bold = true}, -- ModeMsg + [1] = { background = Screen.colors.Gray90 }, -- CursorColumn + [2] = { bold = true, foreground = Screen.colors.Blue1 }, -- NonText + [3] = { bold = true }, -- ModeMsg }) screen:attach() end) @@ -1357,44 +1393,28 @@ describe('CursorColumn highlight', function() screen:expect([[ 1234567{1:8}9 | a ^ b | - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*5 | ]]) feed('i') screen:expect([[ 1{1:2}3456789 | a^ b | - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*5 {3:-- INSERT --} | ]]) feed('<C-O>') screen:expect([[ 1234567{1:8}9 | a ^ b | - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*5 {3:-- (insert) --} | ]]) feed('i') screen:expect([[ 1{1:2}3456789 | a^ b | - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*5 {3:-- INSERT --} | ]]) end) @@ -1412,26 +1432,27 @@ describe('CursorColumn highlight', function() call timer_start(300, 'Func') ]]) - screen:expect({grid = [[ + screen:expect({ + grid = [[ aaaa{1:a} | bbbb{1:b} | cccc{1:c} | dddd^d | - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 | - ]], timeout = 100}) - screen:expect({grid = [[ + ]], + timeout = 100, + }) + screen:expect({ + grid = [[ ^aaaaa | {1:b}bbbb | {1:c}cccc | {1:d}dddd | - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 | - ]]}) + ]], + }) end) end) @@ -1442,15 +1463,15 @@ describe('ColorColumn highlight', function() clear() screen = Screen.new(40, 15) screen:set_default_attr_ids({ - [1] = {background = Screen.colors.LightRed}, -- ColorColumn - [2] = {background = Screen.colors.Grey90}, -- CursorLine - [3] = {foreground = Screen.colors.Brown}, -- LineNr - [4] = {foreground = Screen.colors.Brown, bold = true}, -- CursorLineNr - [5] = {foreground = Screen.colors.Blue, bold = true}, -- NonText - [6] = {foreground = Screen.colors.Blue, background = Screen.colors.LightRed, bold = true}, - [7] = {reverse = true, bold = true}, -- StatusLine - [8] = {reverse = true}, -- StatusLineNC - [9] = {background = Screen.colors.Grey90, foreground = Screen.colors.Red}, + [1] = { background = Screen.colors.LightRed }, -- ColorColumn + [2] = { background = Screen.colors.Grey90 }, -- CursorLine + [3] = { foreground = Screen.colors.Brown }, -- LineNr + [4] = { foreground = Screen.colors.Brown, bold = true }, -- CursorLineNr + [5] = { foreground = Screen.colors.Blue, bold = true }, -- NonText + [6] = { foreground = Screen.colors.Blue, background = Screen.colors.LightRed, bold = true }, + [7] = { reverse = true, bold = true }, -- StatusLine + [8] = { reverse = true }, -- StatusLineNC + [9] = { background = Screen.colors.Grey90, foreground = Screen.colors.Red }, }) screen:attach() end) @@ -1472,16 +1493,12 @@ describe('ColorColumn highlight', function() {4: 1 }11{1:1}11111{1:1}1 | {3: 2 }22{1:2}22222{1:2}22 | {3: 3 }33{1:3}33333{1:3}3 | - {5:~ }| - {5:~ }| - {5:~ }| + {5:~ }|*3 {8:X }| {4: 1 }^11{1:1}11111{1:1}1 | {3: 2 }22{1:2}22222{1:2}22 | {3: 3 }33{1:3}33333{1:3}3 | - {5:~ }| - {5:~ }| - {5:~ }| + {5:~ }|*3 {7:X }| | ]]) @@ -1496,18 +1513,7 @@ describe('ColorColumn highlight', function() screen:expect([[ ^The quick brown fox jumped over the {1: }| {1: } {1:l}azy dogs | - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| + {5:~ }|*12 | ]]) end) @@ -1521,18 +1527,7 @@ describe('ColorColumn highlight', function() screen:expect([[ ^The quick brown fox jumped over the laz{1:y}| {6:+}{5:+}{6:+}{5:>\} dogs | - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| + {5:~ }|*12 | ]]) end) @@ -1557,33 +1552,36 @@ describe('ColorColumn highlight', function() end) end) -describe("MsgSeparator highlight and msgsep fillchar", function() +describe('MsgSeparator highlight and msgsep fillchar', function() local screen before_each(function() clear() - screen = Screen.new(50,5) + screen = Screen.new(50, 5) screen:set_default_attr_ids({ - [1] = {bold=true, foreground=Screen.colors.Blue}, - [2] = {bold=true, reverse=true}, - [3] = {bold = true, foreground = Screen.colors.SeaGreen4}, - [4] = {background = Screen.colors.Cyan, bold = true, reverse = true}, - [5] = {bold = true, background = Screen.colors.Magenta}, - [6] = {background = Screen.colors.WebGray}, - [7] = {background = Screen.colors.WebGray, bold = true, foreground = Screen.colors.SeaGreen4}, - [8] = {foreground = Screen.colors.Grey0, background = Screen.colors.Gray60}, - [9] = {foreground = Screen.colors.Grey40, background = Screen.colors.Gray60}, - [10] = {foreground = tonumber('0x000019'), background = Screen.colors.Gray60}, - [11] = {background = Screen.colors.Gray60, bold = true, foreground = tonumber('0x666699')}, - [12] = {background = Screen.colors.Gray60, bold = true, foreground = tonumber('0x297d4e')}, - [13] = {background = tonumber('0xff4cff'), bold = true, foreground = tonumber('0xb200ff')}, + [1] = { bold = true, foreground = Screen.colors.Blue }, + [2] = { bold = true, reverse = true }, + [3] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [4] = { background = Screen.colors.Cyan, bold = true, reverse = true }, + [5] = { bold = true, background = Screen.colors.Magenta }, + [6] = { background = Screen.colors.WebGray }, + [7] = { + background = Screen.colors.WebGray, + bold = true, + foreground = Screen.colors.SeaGreen4, + }, + [8] = { foreground = Screen.colors.Grey0, background = Screen.colors.Gray60 }, + [9] = { foreground = Screen.colors.Grey40, background = Screen.colors.Gray60 }, + [10] = { foreground = tonumber('0x000019'), background = Screen.colors.Gray60 }, + [11] = { background = Screen.colors.Gray60, bold = true, foreground = tonumber('0x666699') }, + [12] = { background = Screen.colors.Gray60, bold = true, foreground = tonumber('0x297d4e') }, + [13] = { background = tonumber('0xff4cff'), bold = true, foreground = tonumber('0xb200ff') }, }) screen:attach() end) - it("works", function() - + it('works', function() -- defaults - feed_command("ls") + feed_command('ls') screen:expect([[ | {2: }| @@ -1593,8 +1591,8 @@ describe("MsgSeparator highlight and msgsep fillchar", function() ]]) feed('<cr>') - feed_command("set fillchars+=msgsep:-") - feed_command("ls") + feed_command('set fillchars+=msgsep:-') + feed_command('ls') screen:expect([[ | {2:--------------------------------------------------}| @@ -1604,8 +1602,8 @@ describe("MsgSeparator highlight and msgsep fillchar", function() ]]) -- linked to StatusLine per default - feed_command("hi StatusLine guibg=Cyan") - feed_command("ls") + feed_command('hi StatusLine guibg=Cyan') + feed_command('ls') screen:expect([[ | {4:--------------------------------------------------}| @@ -1615,9 +1613,9 @@ describe("MsgSeparator highlight and msgsep fillchar", function() ]]) -- but can be unlinked - feed_command("hi clear MsgSeparator") - feed_command("hi MsgSeparator guibg=Magenta gui=bold") - feed_command("ls") + feed_command('hi clear MsgSeparator') + feed_command('hi MsgSeparator guibg=Magenta gui=bold') + feed_command('ls') screen:expect([[ | {5:--------------------------------------------------}| @@ -1627,169 +1625,63 @@ describe("MsgSeparator highlight and msgsep fillchar", function() ]]) end) - it("and MsgArea", function() - feed_command("hi MsgArea guibg=Gray") - screen:expect{grid=[[ + it('and MsgArea', function() + feed_command('hi MsgArea guibg=Gray') + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {6: }| - ]]} - feed(":ls") - screen:expect{grid=[[ + ]], + } + feed(':ls') + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {6::ls^ }| - ]]} - feed(":<cr>") - screen:expect{grid=[[ + ]], + } + feed(':<cr>') + screen:expect { + grid = [[ | {2: }| {6::ls: }| {6: 1 %a "[No Name]" line 1 }| {7:Press ENTER or type command to continue}{6:^ }| - ]]} + ]], + } -- support madness^Wblending of message "overlay" - feed_command("hi MsgArea blend=20") - feed_command("hi clear MsgSeparator") - feed_command("hi MsgSeparator blend=30 guibg=Magenta") - screen:expect{grid=[[ + feed_command('hi MsgArea blend=20') + feed_command('hi clear MsgSeparator') + feed_command('hi MsgSeparator blend=30 guibg=Magenta') + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {8::hi}{9: }{8:MsgSeparator}{9: }{8:blend=30}{9: }{8:guibg=Magenta}{9: }| - ]]} - feed(":ls") - screen:expect{grid=[[ + ]], + } + feed(':ls') + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {8::ls}{9:^ }| - ]]} - feed("<cr>") - screen:expect{grid=[[ + ]], + } + feed('<cr>') + screen:expect { + grid = [[ | {13:~ }| {10::ls}{11: }| {11:~ }{10:1}{11: }{10:%a}{11: }{10:"[No}{11: }{10:Name]"}{11: }{10:line}{11: }{10:1}{11: }| {12:Press}{9: }{12:ENTER}{9: }{12:or}{9: }{12:type}{9: }{12:command}{9: }{12:to}{9: }{12:continue}{9:^ }| - ]]} - end) -end) - -describe("'number' and 'relativenumber' highlight", function() - before_each(clear) - - it('LineNr, LineNrAbove and LineNrBelow', function() - local screen = Screen.new(20,10) - screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.Red}, - [2] = {foreground = Screen.colors.Blue}, - [3] = {foreground = Screen.colors.Green}, - }) - screen:attach() - command('set number relativenumber') - command('call setline(1, range(50))') - command('highlight LineNr guifg=Red') - feed('4j') - screen:expect([[ - {1: 4 }0 | - {1: 3 }1 | - {1: 2 }2 | - {1: 1 }3 | - {1:5 }^4 | - {1: 1 }5 | - {1: 2 }6 | - {1: 3 }7 | - {1: 4 }8 | - | - ]]) - command('highlight LineNrAbove guifg=Blue') - screen:expect([[ - {2: 4 }0 | - {2: 3 }1 | - {2: 2 }2 | - {2: 1 }3 | - {1:5 }^4 | - {1: 1 }5 | - {1: 2 }6 | - {1: 3 }7 | - {1: 4 }8 | - | - ]]) - command('highlight LineNrBelow guifg=Green') - screen:expect([[ - {2: 4 }0 | - {2: 3 }1 | - {2: 2 }2 | - {2: 1 }3 | - {1:5 }^4 | - {3: 1 }5 | - {3: 2 }6 | - {3: 3 }7 | - {3: 4 }8 | - | - ]]) - feed('3j') - screen:expect([[ - {2: 7 }0 | - {2: 6 }1 | - {2: 5 }2 | - {2: 4 }3 | - {2: 3 }4 | - {2: 2 }5 | - {2: 1 }6 | - {1:8 }^7 | - {3: 1 }8 | - | - ]]) - end) - - -- oldtest: Test_relativenumber_callback() - it('relative number highlight is updated if cursor is moved from timer', function() - local screen = Screen.new(50, 8) - screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.Brown}, -- LineNr - [2] = {bold = true, foreground = Screen.colors.Blue1}, -- NonText - }) - screen:attach() - exec([[ - call setline(1, ['aaaaa', 'bbbbb', 'ccccc', 'ddddd']) - set relativenumber - call cursor(4, 1) - - func Func(timer) - call cursor(1, 1) - endfunc - - call timer_start(300, 'Func') - ]]) - screen:expect({grid = [[ - {1: 3 }aaaaa | - {1: 2 }bbbbb | - {1: 1 }ccccc | - {1: 0 }^ddddd | - {2:~ }| - {2:~ }| - {2:~ }| - | - ]], timeout = 100}) - screen:expect({grid = [[ - {1: 0 }^aaaaa | - {1: 1 }bbbbb | - {1: 2 }ccccc | - {1: 3 }ddddd | - {2:~ }| - {2:~ }| - {2:~ }| - | - ]]}) + ]], + } end) end) @@ -1798,54 +1690,57 @@ describe("'winhighlight' highlight", function() before_each(function() clear() - screen = Screen.new(20,8) + screen = Screen.new(20, 8) screen:attach() screen:set_default_attr_ids { - [0] = {bold=true, foreground=Screen.colors.Blue}; - [1] = {background = Screen.colors.DarkBlue}; - [2] = {background = Screen.colors.DarkBlue, bold = true, foreground = Screen.colors.Blue1}; - [3] = {bold = true, reverse = true}; - [4] = {reverse = true}; - [5] = {background = Screen.colors.DarkGreen}; - [6] = {background = Screen.colors.DarkGreen, bold = true, foreground = Screen.colors.Blue1}; - [7] = {background = Screen.colors.DarkMagenta}; - [8] = {background = Screen.colors.DarkMagenta, bold = true, foreground = Screen.colors.Blue1}; - [9] = {foreground = Screen.colors.Brown}; - [10] = {foreground = Screen.colors.Brown, background = Screen.colors.DarkBlue}; - [11] = {background = Screen.colors.DarkBlue, bold = true, reverse = true}; - [12] = {background = Screen.colors.DarkGreen, reverse = true}; - [13] = {background = Screen.colors.Magenta4, reverse = true}; - [14] = {background = Screen.colors.DarkBlue, reverse = true}; - [15] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}; - [16] = {foreground = Screen.colors.Blue1}; - [17] = {background = Screen.colors.LightRed}; - [18] = {background = Screen.colors.Gray90}; - [19] = {foreground = Screen.colors.LightGrey, background = Screen.colors.DarkGray}; - [20] = {background = Screen.colors.LightGrey, underline = true}; - [21] = {bold = true}; - [22] = {bold = true, foreground = Screen.colors.SeaGreen4}; - [23] = {background = Screen.colors.LightMagenta}; - [24] = {background = Screen.colors.WebGray}; - [25] = {bold = true, foreground = Screen.colors.Green1}; - [26] = {background = Screen.colors.Red}; - [27] = {background = Screen.colors.DarkBlue, bold = true, foreground = Screen.colors.Green1}; - [28] = {bold = true, foreground = Screen.colors.Brown}; - [29] = {foreground = Screen.colors.Blue1, background = Screen.colors.Red, bold = true}; - [30] = {background = tonumber('0xff8800')}; - [31] = {background = tonumber('0xff8800'), bold = true, foreground = Screen.colors.Blue}; + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { background = Screen.colors.DarkBlue }, + [2] = { background = Screen.colors.DarkBlue, bold = true, foreground = Screen.colors.Blue1 }, + [3] = { bold = true, reverse = true }, + [4] = { reverse = true }, + [5] = { background = Screen.colors.DarkGreen }, + [6] = { background = Screen.colors.DarkGreen, bold = true, foreground = Screen.colors.Blue1 }, + [7] = { background = Screen.colors.DarkMagenta }, + [8] = { + background = Screen.colors.DarkMagenta, + bold = true, + foreground = Screen.colors.Blue1, + }, + [9] = { foreground = Screen.colors.Brown }, + [10] = { foreground = Screen.colors.Brown, background = Screen.colors.DarkBlue }, + [11] = { background = Screen.colors.DarkBlue, bold = true, reverse = true }, + [12] = { background = Screen.colors.DarkGreen, reverse = true }, + [13] = { background = Screen.colors.Magenta4, reverse = true }, + [14] = { background = Screen.colors.DarkBlue, reverse = true }, + [15] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [16] = { foreground = Screen.colors.Blue1 }, + [17] = { background = Screen.colors.LightRed }, + [18] = { background = Screen.colors.Gray90 }, + [19] = { foreground = Screen.colors.LightGrey, background = Screen.colors.DarkGray }, + [20] = { background = Screen.colors.LightGrey, underline = true }, + [21] = { bold = true }, + [22] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [23] = { background = Screen.colors.LightMagenta }, + [24] = { background = Screen.colors.WebGray }, + [25] = { bold = true, foreground = Screen.colors.Green1 }, + [26] = { background = Screen.colors.Red }, + [27] = { background = Screen.colors.DarkBlue, bold = true, foreground = Screen.colors.Green1 }, + [28] = { bold = true, foreground = Screen.colors.Brown }, + [29] = { foreground = Screen.colors.Blue1, background = Screen.colors.Red, bold = true }, + [30] = { background = tonumber('0xff8800') }, + [31] = { background = tonumber('0xff8800'), bold = true, foreground = Screen.colors.Blue }, } - command("hi Background1 guibg=DarkBlue") - command("hi Background2 guibg=DarkGreen") + command('hi Background1 guibg=DarkBlue') + command('hi Background2 guibg=DarkGreen') end) it('works for background color', function() - insert("aa") - command("split") - command("set winhl=Normal:Background1") + insert('aa') + command('split') + command('set winhl=Normal:Background1') screen:expect([[ {1:a^a }| - {2:~ }| - {2:~ }| + {2:~ }|*2 {3:[No Name] [+] }| aa | {0:~ }| @@ -1853,11 +1748,10 @@ describe("'winhighlight' highlight", function() | ]]) - command("enew") + command('enew') screen:expect([[ {1:^ }| - {2:~ }| - {2:~ }| + {2:~ }|*2 {3:[No Name] }| aa | {0:~ }| @@ -1874,84 +1768,64 @@ describe("'winhighlight' highlight", function() command('setlocal winhl=Normal:Background1') screen:expect([[ {1: ^aa}| - {2: ~}| - {2: ~}| - {2: ~}| - {2: ~}| + {2: ~}|*4 | ]]) command('botright vsplit') screen:expect([[ {1: aa│ ^aa}| - {2: ~}{1:│}{2: ~}| - {2: ~}{1:│}{2: ~}| - {2: ~}{1:│}{2: ~}| + {2: ~}{1:│}{2: ~}|*3 {4:[No Name] [+] }{3:[No Name] [+] }| | ]]) end) it('handles undefined groups', function() - command("set winhl=Normal:Background1") + command('set winhl=Normal:Background1') screen:expect([[ {1:^ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*6 | ]]) - command("set winhl=xxx:yyy") + command('set winhl=xxx:yyy') eq('xxx:yyy', eval('&winhl')) - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 | - ]]} + ]], + } end) it('can be changed to define different groups', function() - command("set winhl=EndOfBuffer:Background1") - screen:expect{grid=[[ + command('set winhl=EndOfBuffer:Background1') + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | - ]]} + ]], + } - command("set winhl=Normal:ErrorMsg") - screen:expect{grid=[[ + command('set winhl=Normal:ErrorMsg') + screen:expect { + grid = [[ {15:^ }| - {29:~ }| - {29:~ }| - {29:~ }| - {29:~ }| - {29:~ }| - {29:~ }| + {29:~ }|*6 | - ]]} + ]], + } end) it('works local to the window', function() - insert("aa") - command("split") - command("setlocal winhl=Normal:Background1") + insert('aa') + command('split') + command('setlocal winhl=Normal:Background1') screen:expect([[ {1:a^a }| - {2:~ }| - {2:~ }| + {2:~ }|*2 {3:[No Name] [+] }| aa | {0:~ }| @@ -1959,11 +1833,10 @@ describe("'winhighlight' highlight", function() | ]]) - command("enew") + command('enew') screen:expect([[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:[No Name] }| aa | {0:~ }| @@ -1971,11 +1844,10 @@ describe("'winhighlight' highlight", function() | ]]) - command("bnext") + command('bnext') screen:expect([[ {1:^aa }| - {2:~ }| - {2:~ }| + {2:~ }|*2 {3:[No Name] [+] }| aa | {0:~ }| @@ -1985,13 +1857,12 @@ describe("'winhighlight' highlight", function() end) it('for inactive window background works', function() - command("set winhl=Normal:Background1,NormalNC:Background2") + command('set winhl=Normal:Background1,NormalNC:Background2') -- tests global value is copied across split - command("split") + command('split') screen:expect([[ {1:^ }| - {2:~ }| - {2:~ }| + {2:~ }|*2 {3:[No Name] }| {5: }| {6:~ }| @@ -1999,11 +1870,10 @@ describe("'winhighlight' highlight", function() | ]]) - feed("<c-w><c-w>") + feed('<c-w><c-w>') screen:expect([[ {5: }| - {6:~ }| - {6:~ }| + {6:~ }|*2 {4:[No Name] }| {1:^ }| {2:~ }| @@ -2011,11 +1881,10 @@ describe("'winhighlight' highlight", function() | ]]) - feed("<c-w><c-w>") + feed('<c-w><c-w>') screen:expect([[ {1:^ }| - {2:~ }| - {2:~ }| + {2:~ }|*2 {3:[No Name] }| {5: }| {6:~ }| @@ -2025,13 +1894,12 @@ describe("'winhighlight' highlight", function() end) it('works with NormalNC', function() - command("hi NormalNC guibg=DarkMagenta") + command('hi NormalNC guibg=DarkMagenta') -- tests global value is copied across split - command("split") + command('split') screen:expect([[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:[No Name] }| {7: }| {8:~ }| @@ -2039,11 +1907,10 @@ describe("'winhighlight' highlight", function() | ]]) - command("wincmd w") + command('wincmd w') screen:expect([[ {7: }| - {8:~ }| - {8:~ }| + {8:~ }|*2 {4:[No Name] }| ^ | {0:~ }| @@ -2051,13 +1918,11 @@ describe("'winhighlight' highlight", function() | ]]) - -- winbg=Normal:... overrides global NormalNC - command("set winhl=Normal:Background1") + command('set winhl=Normal:Background1') screen:expect([[ {7: }| - {8:~ }| - {8:~ }| + {8:~ }|*2 {4:[No Name] }| {1:^ }| {2:~ }| @@ -2065,11 +1930,10 @@ describe("'winhighlight' highlight", function() | ]]) - command("wincmd w") + command('wincmd w') screen:expect([[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:[No Name] }| {1: }| {2:~ }| @@ -2077,12 +1941,11 @@ describe("'winhighlight' highlight", function() | ]]) - command("wincmd w") - command("set winhl=Normal:Background1,NormalNC:Background2") + command('wincmd w') + command('set winhl=Normal:Background1,NormalNC:Background2') screen:expect([[ {7: }| - {8:~ }| - {8:~ }| + {8:~ }|*2 {4:[No Name] }| {1:^ }| {2:~ }| @@ -2090,11 +1953,10 @@ describe("'winhighlight' highlight", function() | ]]) - command("wincmd w") + command('wincmd w') screen:expect([[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:[No Name] }| {5: }| {6:~ }| @@ -2104,30 +1966,32 @@ describe("'winhighlight' highlight", function() end) it('updates background to changed linked group', function() - command("split") - command("setlocal winhl=Normal:FancyGroup") -- does not yet exist - screen:expect{grid=[[ + command('split') + command('setlocal winhl=Normal:FancyGroup') -- does not yet exist + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:[No Name] }| | {0:~ }| {4:[No Name] }| | - ]]} + ]], + } - command("hi FancyGroup guibg=#FF8800") -- nice orange - screen:expect{grid=[[ + command('hi FancyGroup guibg=#FF8800') -- nice orange + screen:expect { + grid = [[ {30:^ }| - {31:~ }| - {31:~ }| + {31:~ }|*2 {3:[No Name] }| | {0:~ }| {4:[No Name] }| | - ]]} + ]], + } end) it('background applies also to non-text', function() @@ -2144,10 +2008,7 @@ describe("'winhighlight' highlight", function() {9: 1 } ^Lorem ipsum do| {9: } {0:↪}lor sit | {9: } {0:↪}amet{0:-} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) @@ -2156,10 +2017,7 @@ describe("'winhighlight' highlight", function() {10: 1 }{1: ^Lorem ipsum do}| {10: }{1: }{2:↪}{1:lor sit }| {10: }{1: }{2:↪}{1:amet}{2:-}{1: }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*4 | ]]) @@ -2168,12 +2026,7 @@ describe("'winhighlight' highlight", function() feed('3w') screen:expect([[ {10: 1 }{2:❮}{1: dolor ^sit ame}{2:❯}| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*6 | ]]) end) @@ -2188,11 +2041,7 @@ describe("'winhighlight' highlight", function() screen:expect([[ {25:the} {26:foobar} was {26:fooba}| {26:^r} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) @@ -2202,28 +2051,22 @@ describe("'winhighlight' highlight", function() screen:expect([[ {27:the}{1: }{26:foobar}{1: was }{26:fooba}| {26:^r}{1: }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*5 | ]]) end) it('can override NonText, Conceal and EndOfBuffer', function() - curbufmeths.set_lines(0,-1,true, {"raa\000"}) + api.nvim_buf_set_lines(0, 0, -1, true, { 'raa\000' }) command('call matchaddpos("Conceal", [[1,2]], 0, -1, {"conceal": "#"})') command('set cole=2 cocu=nvic') command('split') command('call matchaddpos("Conceal", [[1,2]], 0, -1, {"conceal": "#"})') - command('set winhl=SpecialKey:ErrorMsg,EndOfBuffer:Background1,' - ..'Conceal:Background2') + command('set winhl=SpecialKey:ErrorMsg,EndOfBuffer:Background1,' .. 'Conceal:Background2') screen:expect([[ ^r{5:#}a{15:^@} | - {1:~ }| - {1:~ }| + {1:~ }|*2 {3:[No Name] [+] }| r{19:#}a{16:^@} | {0:~ }| @@ -2240,8 +2083,7 @@ describe("'winhighlight' highlight", function() feed('k') command('split') - command('set winhl=LineNr:Background1,CursorColumn:Background2,' - ..'ColorColumn:ErrorMsg') + command('set winhl=LineNr:Background1,CursorColumn:Background2,' .. 'ColorColumn:ErrorMsg') screen:expect([[ {1: 1 }v{15:e}ry tex^t | {1: 2 }m{15:o}re tex{5:t} | @@ -2261,22 +2103,14 @@ describe("'winhighlight' highlight", function() screen:expect([[ {20: No Name] }{15: No Name]}{20:X}| ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) - command("tabnext") + command('tabnext') screen:expect([[ {21: No Name] }{1: No Name]}{20:X}| ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) end) @@ -2284,12 +2118,12 @@ describe("'winhighlight' highlight", function() it('can override popupmenu', function() insert('word wording wordy') command('split') - command('set winhl=Pmenu:Background1,PmenuSel:Background2,' - ..'PmenuSbar:ErrorMsg,PmenuThumb:Normal') + command( + 'set winhl=Pmenu:Background1,PmenuSel:Background2,' .. 'PmenuSbar:ErrorMsg,PmenuThumb:Normal' + ) screen:expect([[ word wording word^y | - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:[No Name] [+] }| word wording wordy | {0:~ }| @@ -2327,40 +2161,43 @@ describe("'winhighlight' highlight", function() command('set cursorline number') command('split') command('set winhl=CursorLine:Background1') - screen:expect{grid=[[ + screen:expect { + grid = [[ {28: 1 }{1:^ }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:[No Name] }| {28: 1 }{18: }| {0:~ }| {4:[No Name] }| | - ]]} + ]], + } command('set winhl=CursorLineNr:Background2,CursorLine:Background1') - screen:expect{grid=[[ + screen:expect { + grid = [[ {5: 1 }{1:^ }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:[No Name] }| {28: 1 }{18: }| {0:~ }| {4:[No Name] }| | - ]]} + ]], + } feed('<c-w>w') - screen:expect{grid=[[ + screen:expect { + grid = [[ {5: 1 }{1: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {4:[No Name] }| {28: 1 }{18:^ }| {0:~ }| {3:[No Name] }| | - ]]} + ]], + } end) it('can override StatusLine and StatusLineNC', function() @@ -2368,8 +2205,7 @@ describe("'winhighlight' highlight", function() command('split') screen:expect([[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {1:[No Name] }| | {0:~ }| @@ -2394,8 +2230,7 @@ describe("'winhighlight' highlight", function() ]]) end) - - it("can override syntax groups", function() + it('can override syntax groups', function() command('syntax on') command('syntax keyword Foobar foobar') command('syntax keyword Article the') @@ -2405,17 +2240,14 @@ describe("'winhighlight' highlight", function() screen:expect([[ {25:the} {26:foobar} was {26:fooba}| {26:^r} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) command('split') command('set winhl=Foobar:Background1,Article:ErrorMsg') - screen:expect{grid=[[ + screen:expect { + grid = [[ {15:the} {1:foobar} was {1:fooba}| {1:^r} | {0:~ }| @@ -2424,21 +2256,23 @@ describe("'winhighlight' highlight", function() {26:r} | {4:[No Name] [+] }| | - ]]} + ]], + } end) it('can be disabled in newly opened window #19823', function() command('split | set winhl=Normal:ErrorMsg | set winhl=') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:[No Name] }| | {0:~ }| {4:[No Name] }| | - ]]} + ]], + } helpers.assert_alive() end) @@ -2452,7 +2286,8 @@ describe("'winhighlight' highlight", function() insert [[ some text more text]] - screen:expect{grid=[[ + screen:expect { + grid = [[ some text | more tex^t | {0:~ }| @@ -2461,10 +2296,12 @@ describe("'winhighlight' highlight", function() more text | {4:[No Name] }{1:1,1 All}| | - ]]} + ]], + } command 'set winhl=Background1:Background2' - screen:expect{grid=[[ + screen:expect { + grid = [[ some text | more tex^t | {0:~ }| @@ -2473,10 +2310,12 @@ describe("'winhighlight' highlight", function() more text | {4:[No Name] }{1:1,1 All}| | - ]]} + ]], + } feed 'k' - screen:expect{grid=[[ + screen:expect { + grid = [[ some tex^t | more text | {0:~ }| @@ -2485,7 +2324,8 @@ describe("'winhighlight' highlight", function() more text | {4:[No Name] }{1:1,1 All}| | - ]]} + ]], + } end) it('can link to empty highlight group', function() @@ -2493,16 +2333,17 @@ describe("'winhighlight' highlight", function() command 'set winhl=NormalNC:Normal' command 'split' - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:[No Name] }| | {0:~ }| {4:[No Name] }| | - ]]} + ]], + } end) end) @@ -2512,97 +2353,82 @@ describe('highlight namespaces', function() before_each(function() clear() - screen = Screen.new(25,10) + screen = Screen.new(25, 10) screen:attach() screen:set_default_attr_ids { - [1] = {foreground = Screen.colors.Blue, bold = true}; - [2] = {background = Screen.colors.DarkGrey}; - [3] = {italic = true, foreground = Screen.colors.DarkCyan, background = Screen.colors.DarkOrange4}; - [4] = {background = Screen.colors.Magenta4}; - [5] = {background = Screen.colors.Magenta4, foreground = Screen.colors.Crimson}; - [6] = {bold = true, reverse = true}; - [7] = {reverse = true}; - [8] = {foreground = Screen.colors.Gray20}; - [9] = {foreground = Screen.colors.Blue}; - [10] = {bold = true, foreground = Screen.colors.SeaGreen}; + [1] = { foreground = Screen.colors.Blue, bold = true }, + [2] = { background = Screen.colors.DarkGrey }, + [3] = { + italic = true, + foreground = Screen.colors.DarkCyan, + background = Screen.colors.DarkOrange4, + }, + [4] = { background = Screen.colors.Magenta4 }, + [5] = { background = Screen.colors.Magenta4, foreground = Screen.colors.Crimson }, + [6] = { bold = true, reverse = true }, + [7] = { reverse = true }, + [8] = { foreground = Screen.colors.Gray20 }, + [9] = { foreground = Screen.colors.Blue }, + [10] = { bold = true, foreground = Screen.colors.SeaGreen }, } - ns1 = meths.create_namespace 'grungy' - ns2 = meths.create_namespace 'ultrared' + ns1 = api.nvim_create_namespace 'grungy' + ns2 = api.nvim_create_namespace 'ultrared' - meths.set_hl(ns1, 'Normal', {bg='DarkGrey'}) - meths.set_hl(ns1, 'NonText', {bg='DarkOrange4', fg='DarkCyan', italic=true}) - meths.set_hl(ns2, 'Normal', {bg='DarkMagenta'}) - meths.set_hl(ns2, 'NonText', {fg='Crimson'}) + api.nvim_set_hl(ns1, 'Normal', { bg = 'DarkGrey' }) + api.nvim_set_hl(ns1, 'NonText', { bg = 'DarkOrange4', fg = 'DarkCyan', italic = true }) + api.nvim_set_hl(ns2, 'Normal', { bg = 'DarkMagenta' }) + api.nvim_set_hl(ns2, 'NonText', { fg = 'Crimson' }) end) it('can be used globally', function() - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 | - ]]} + ]], + } - meths.set_hl_ns(ns1) - screen:expect{grid=[[ + api.nvim_set_hl_ns(ns1) + screen:expect { + grid = [[ {2:^ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*8 | - ]]} + ]], + } - meths.set_hl_ns(ns2) - screen:expect{grid=[[ + api.nvim_set_hl_ns(ns2) + screen:expect { + grid = [[ {4:^ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| + {5:~ }|*8 | - ]]} + ]], + } - meths.set_hl_ns(0) - screen:expect{grid=[[ + api.nvim_set_hl_ns(0) + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 | - ]]} + ]], + } end) it('can be used per window', function() - local win1 = meths.get_current_win() + local win1 = api.nvim_get_current_win() command 'split' - local win2 = meths.get_current_win() + local win2 = api.nvim_get_current_win() command 'split' - meths.win_set_hl_ns(win1, ns1) - meths.win_set_hl_ns(win2, ns2) + api.nvim_win_set_hl_ns(win1, ns1) + api.nvim_win_set_hl_ns(win2, ns2) - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | {1:~ }| {6:[No Name] }| @@ -2613,36 +2439,27 @@ describe('highlight namespaces', function() {3:~ }| {7:[No Name] }| | - ]]} + ]], + } end) it('redraws correctly when ns=0', function() - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 | - ]]} + ]], + } - meths.set_hl(0, 'EndOfBuffer', {fg='#333333'}) - screen:expect{grid=[[ + api.nvim_set_hl(0, 'EndOfBuffer', { fg = '#333333' }) + screen:expect { + grid = [[ ^ | - {8:~ }| - {8:~ }| - {8:~ }| - {8:~ }| - {8:~ }| - {8:~ }| - {8:~ }| - {8:~ }| + {8:~ }|*8 | - ]]} + ]], + } end) it('winhl does not accept invalid value #24586', function() @@ -2653,18 +2470,19 @@ describe('highlight namespaces', function() return { msg, vim.wo[curwin].winhl } ]]) eq({ - "Vim(set):E5248: Invalid character in group name", - "Normal:Visual", - },res) + 'Vim(set):E5248: Invalid character in group name', + 'Normal:Visual', + }, res) end) it('Normal in set_hl #25474', function() - meths.set_hl(0, 'Normal', {bg='#333333'}) + command('highlight Ignore guifg=bg ctermfg=White') + api.nvim_set_hl(0, 'Normal', { bg = '#333333' }) command('highlight Ignore') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {6: }| | Ignore {8:xxx} {9:ctermf}| @@ -2672,6 +2490,7 @@ describe('highlight namespaces', function() bg | {10:Press ENTER or type comma}| {10:nd to continue}^ | - ]]} + ]], + } end) end) diff --git a/test/functional/ui/hlstate_spec.lua b/test/functional/ui/hlstate_spec.lua index 55f873e827..8b36ad5431 100644 --- a/test/functional/ui/hlstate_spec.lua +++ b/test/functional/ui/hlstate_spec.lua @@ -3,7 +3,7 @@ local Screen = require('test.functional.ui.screen') local clear, insert = helpers.clear, helpers.insert local command = helpers.command -local meths = helpers.meths +local api = helpers.api local testprg = helpers.testprg local thelpers = require('test.functional.terminal.helpers') local skip = helpers.skip @@ -17,127 +17,157 @@ describe('ext_hlstate detailed highlights', function() command('syntax on') command('hi VertSplit gui=reverse') screen = Screen.new(40, 8) - screen:attach({ext_hlstate=true}) + screen:attach({ ext_hlstate = true }) end) after_each(function() screen:detach() end) - it('work with combined UI and syntax highlights', function() insert([[ these are some lines with colorful text]]) - meths.buf_add_highlight(0, -1, "String", 0 , 10, 14) - meths.buf_add_highlight(0, -1, "Statement", 1 , 5, -1) - command("/th co") + api.nvim_buf_add_highlight(0, -1, 'String', 0, 10, 14) + api.nvim_buf_add_highlight(0, -1, 'Statement', 1, 5, -1) + command('/th co') - screen:expect([[ + screen:expect( + [[ these are {1:some} lines | ^wi{2:th }{4:co}{3:lorful text} | - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| + {5:~ }|*5 {8:search hit BOTTOM, continuing at TOP}{7: }| - ]], { - [1] = {{foreground = Screen.colors.Magenta}, - {{hi_name = "Constant", kind = "syntax"}}}, - [2] = {{background = Screen.colors.Yellow}, - {{hi_name = "Search", ui_name = "Search", kind = "ui"}}}, - [3] = {{bold = true, foreground = Screen.colors.Brown}, - {{hi_name = "Statement", kind = "syntax"}}}, - [4] = {{bold = true, background = Screen.colors.Yellow, foreground = Screen.colors.Brown}, {3, 2}}, - [5] = {{bold = true, foreground = Screen.colors.Blue1}, - {{hi_name = "NonText", ui_name = "EndOfBuffer", kind = "ui"}}}, - [6] = {{foreground = Screen.colors.Red}, - {{hi_name = "WarningMsg", ui_name = "WarningMsg", kind = "ui"}}}, - [7] = {{}, {{hi_name = "MsgArea", ui_name = "MsgArea", kind = "ui"}}}, - [8] = {{foreground = Screen.colors.Red}, {7, 6}}, - }) + ]], + { + [1] = { + { foreground = Screen.colors.Magenta }, + { { hi_name = 'Constant', kind = 'syntax' } }, + }, + [2] = { + { background = Screen.colors.Yellow }, + { { hi_name = 'Search', ui_name = 'Search', kind = 'ui' } }, + }, + [3] = { + { bold = true, foreground = Screen.colors.Brown }, + { { hi_name = 'Statement', kind = 'syntax' } }, + }, + [4] = { + { bold = true, background = Screen.colors.Yellow, foreground = Screen.colors.Brown }, + { 3, 2 }, + }, + [5] = { + { bold = true, foreground = Screen.colors.Blue1 }, + { { hi_name = 'NonText', ui_name = 'EndOfBuffer', kind = 'ui' } }, + }, + [6] = { + { foreground = Screen.colors.Red }, + { { hi_name = 'WarningMsg', ui_name = 'WarningMsg', kind = 'ui' } }, + }, + [7] = { {}, { { hi_name = 'MsgArea', ui_name = 'MsgArea', kind = 'ui' } } }, + [8] = { { foreground = Screen.colors.Red }, { 7, 6 } }, + } + ) end) it('work with cleared UI highlights', function() screen:set_default_attr_ids({ - [1] = {{}, {{hi_name = "Normal", ui_name = "WinSeparator", kind = "ui"}}}, - [2] = {{bold = true, foreground = Screen.colors.Blue1}, - {{hi_name = "NonText", ui_name = "EndOfBuffer", kind = "ui"}}}, - [3] = {{bold = true, reverse = true}, - {{hi_name = "StatusLine", ui_name = "StatusLine", kind = "ui"}}} , - [4] = {{reverse = true}, - {{hi_name = "StatusLineNC", ui_name = "StatusLineNC" , kind = "ui"}}}, - [5] = {{}, {{hi_name = "StatusLine", ui_name = "StatusLine", kind = "ui"}}}, - [6] = {{}, {{hi_name = "StatusLineNC", ui_name = "StatusLineNC", kind = "ui"}}}, - [7] = {{}, {{hi_name = "MsgArea", ui_name = "MsgArea", kind = "ui"}}}, + [1] = { {}, { { hi_name = 'Normal', ui_name = 'WinSeparator', kind = 'ui' } } }, + [2] = { + { bold = true, foreground = Screen.colors.Blue1 }, + { { hi_name = 'NonText', ui_name = 'EndOfBuffer', kind = 'ui' } }, + }, + [3] = { + { bold = true, reverse = true }, + { { hi_name = 'StatusLine', ui_name = 'StatusLine', kind = 'ui' } }, + }, + [4] = { + { reverse = true }, + { { hi_name = 'StatusLineNC', ui_name = 'StatusLineNC', kind = 'ui' } }, + }, + [5] = { {}, { { hi_name = 'StatusLine', ui_name = 'StatusLine', kind = 'ui' } } }, + [6] = { {}, { { hi_name = 'StatusLineNC', ui_name = 'StatusLineNC', kind = 'ui' } } }, + [7] = { {}, { { hi_name = 'MsgArea', ui_name = 'MsgArea', kind = 'ui' } } }, }) - command("hi clear VertSplit") - command("vsplit") + command('hi clear WinSeparator') + command('vsplit') screen:expect([[ ^ {1:│} | - {2:~ }{1:│}{2:~ }| - {2:~ }{1:│}{2:~ }| - {2:~ }{1:│}{2:~ }| - {2:~ }{1:│}{2:~ }| - {2:~ }{1:│}{2:~ }| + {2:~ }{1:│}{2:~ }|*5 {3:[No Name] }{4:[No Name] }| {7: }| ]]) - command("hi clear StatusLine | hi clear StatuslineNC") + command('hi clear StatusLine | hi clear StatuslineNC') screen:expect([[ ^ {1:│} | - {2:~ }{1:│}{2:~ }| - {2:~ }{1:│}{2:~ }| - {2:~ }{1:│}{2:~ }| - {2:~ }{1:│}{2:~ }| - {2:~ }{1:│}{2:~ }| + {2:~ }{1:│}{2:~ }|*5 {5:[No Name] }{6:[No Name] }| {7: }| ]]) -- redrawing is done even if visible highlights didn't change - command("wincmd w") + command('wincmd w') screen:expect([[ {1:│}^ | - {2:~ }{1:│}{2:~ }| - {2:~ }{1:│}{2:~ }| - {2:~ }{1:│}{2:~ }| - {2:~ }{1:│}{2:~ }| - {2:~ }{1:│}{2:~ }| + {2:~ }{1:│}{2:~ }|*5 {6:[No Name] }{5:[No Name] }| {7: }| ]]) - end) - it("work with window-local highlights", function() + it('work with window-local highlights', function() screen:set_default_attr_ids({ - [1] = {{foreground = Screen.colors.Brown}, {{hi_name = "LineNr", ui_name = "LineNr", kind = "ui"}}}, - [2] = {{bold = true, foreground = Screen.colors.Blue1}, {{hi_name = "NonText", ui_name = "EndOfBuffer", kind = "ui"}}}, - [3] = {{bold = true, reverse = true}, {{hi_name = "StatusLine", ui_name = "StatusLine", kind = "ui"}}}, - [4] = {{reverse = true}, {{hi_name = "StatusLineNC", ui_name = "StatusLineNC", kind = "ui"}}}, - [5] = {{background = Screen.colors.Red, foreground = Screen.colors.Grey100}, {{hi_name = "ErrorMsg", ui_name = "LineNr", kind = "ui"}}}, - [6] = {{bold = true, reverse = true}, {{hi_name = "Normal", ui_name = "Normal", kind = "ui"}}}, - [7] = {{foreground = Screen.colors.Brown, bold = true, reverse = true}, {6, 1}}, - [8] = {{foreground = Screen.colors.Blue1, bold = true, reverse = true}, {6, 14}}, - [9] = {{bold = true, foreground = Screen.colors.Brown}, {{hi_name = "NormalNC", ui_name = "NormalNC", kind = "ui"}}}, - [10] = {{bold = true, foreground = Screen.colors.Brown}, {9, 1}}, - [11] = {{bold = true, foreground = Screen.colors.Blue1}, {9, 14}}, - [12] = {{}, {{hi_name = "MsgArea", ui_name = "MsgArea", kind = "ui"}}}, - [13] = {{background = Screen.colors.Red1, foreground = Screen.colors.Gray100}, {{ui_name = "LineNr", kind = "ui", hi_name = "LineNr"}}}; - [14] = {{bold = true, foreground = Screen.colors.Blue}, {{ui_name = "EndOfBuffer", kind = "ui", hi_name = "EndOfBuffer"}}}; + [1] = { + { foreground = Screen.colors.Brown }, + { { hi_name = 'LineNr', ui_name = 'LineNr', kind = 'ui' } }, + }, + [2] = { + { bold = true, foreground = Screen.colors.Blue1 }, + { { hi_name = 'NonText', ui_name = 'EndOfBuffer', kind = 'ui' } }, + }, + [3] = { + { bold = true, reverse = true }, + { { hi_name = 'StatusLine', ui_name = 'StatusLine', kind = 'ui' } }, + }, + [4] = { + { reverse = true }, + { { hi_name = 'StatusLineNC', ui_name = 'StatusLineNC', kind = 'ui' } }, + }, + [5] = { + { background = Screen.colors.Red, foreground = Screen.colors.Grey100 }, + { { hi_name = 'ErrorMsg', ui_name = 'LineNr', kind = 'ui' } }, + }, + [6] = { + { bold = true, reverse = true }, + { { hi_name = 'Normal', ui_name = 'Normal', kind = 'ui' } }, + }, + [7] = { { foreground = Screen.colors.Brown, bold = true, reverse = true }, { 6, 1 } }, + [8] = { { foreground = Screen.colors.Blue1, bold = true, reverse = true }, { 6, 14 } }, + [9] = { + { bold = true, foreground = Screen.colors.Brown }, + { { hi_name = 'NormalNC', ui_name = 'NormalNC', kind = 'ui' } }, + }, + [10] = { { bold = true, foreground = Screen.colors.Brown }, { 9, 1 } }, + [11] = { { bold = true, foreground = Screen.colors.Blue1 }, { 9, 14 } }, + [12] = { {}, { { hi_name = 'MsgArea', ui_name = 'MsgArea', kind = 'ui' } } }, + [13] = { + { background = Screen.colors.Red1, foreground = Screen.colors.Gray100 }, + { { ui_name = 'LineNr', kind = 'ui', hi_name = 'LineNr' } }, + }, + [14] = { + { bold = true, foreground = Screen.colors.Blue }, + { { ui_name = 'EndOfBuffer', kind = 'ui', hi_name = 'EndOfBuffer' } }, + }, }) - command("set number") - command("split") + command('set number') + command('split') -- NormalNC is not applied if not set, to avoid spurious redraws screen:expect([[ {1: 1 }^ | - {2:~ }| - {2:~ }| + {2:~ }|*2 {3:[No Name] }| {1: 1 } | {2:~ }| @@ -145,23 +175,23 @@ describe('ext_hlstate detailed highlights', function() {12: }| ]]) - command("set winhl=LineNr:ErrorMsg") - screen:expect{grid=[[ + command('set winhl=LineNr:ErrorMsg') + screen:expect { + grid = [[ {13: 1 }^ | - {14:~ }| - {14:~ }| + {14:~ }|*2 {3:[No Name] }| {1: 1 } | {2:~ }| {4:[No Name] }| {12: }| - ]]} + ]], + } - command("set winhl=Normal:MsgSeparator,NormalNC:Statement") + command('set winhl=Normal:MsgSeparator,NormalNC:Statement') screen:expect([[ {7: 1 }{6:^ }| - {8:~ }| - {8:~ }| + {8:~ }|*2 {3:[No Name] }| {1: 1 } | {2:~ }| @@ -169,11 +199,10 @@ describe('ext_hlstate detailed highlights', function() {12: }| ]]) - command("wincmd w") + command('wincmd w') screen:expect([[ {10: 1 }{9: }| - {11:~ }| - {11:~ }| + {11:~ }|*2 {4:[No Name] }| {1: 1 }^ | {2:~ }| @@ -182,27 +211,28 @@ describe('ext_hlstate detailed highlights', function() ]]) end) - it("work with :terminal", function() + it('work with :terminal', function() skip(is_os('win')) screen:set_default_attr_ids({ - [1] = {{}, {{hi_name = "TermCursorNC", ui_name = "TermCursorNC", kind = "ui"}}}, - [2] = {{foreground = tonumber('0x00ccff'), fg_indexed=true}, {{kind = "term"}}}, - [3] = {{bold = true, foreground = tonumber('0x00ccff'), fg_indexed=true}, {{kind = "term"}}}, - [4] = {{foreground = tonumber('0x00ccff'), fg_indexed=true}, {2, 1}}, - [5] = {{foreground = tonumber('0x40ffff'), fg_indexed=true}, {{kind = "term"}}}, - [6] = {{foreground = tonumber('0x40ffff'), fg_indexed=true}, {5, 1}}, - [7] = {{}, {{hi_name = "MsgArea", ui_name = "MsgArea", kind = "ui"}}}, + [1] = { {}, { { hi_name = 'TermCursorNC', ui_name = 'TermCursorNC', kind = 'ui' } } }, + [2] = { { foreground = tonumber('0x00ccff'), fg_indexed = true }, { { kind = 'term' } } }, + [3] = { + { bold = true, foreground = tonumber('0x00ccff'), fg_indexed = true }, + { + { kind = 'term' }, + }, + }, + [4] = { { foreground = tonumber('0x00ccff'), fg_indexed = true }, { 2, 1 } }, + [5] = { { foreground = tonumber('0x40ffff'), fg_indexed = true }, { { kind = 'term' } } }, + [6] = { { foreground = tonumber('0x40ffff'), fg_indexed = true }, { 5, 1 } }, + [7] = { {}, { { hi_name = 'MsgArea', ui_name = 'MsgArea', kind = 'ui' } } }, }) command(("enew | call termopen(['%s'])"):format(testprg('tty-test'))) screen:expect([[ ^tty ready | {1: } | - | - | - | - | - | + |*5 {7: }| ]]) @@ -217,10 +247,7 @@ describe('ext_hlstate detailed highlights', function() ^tty ready | x {5:y z} | {1: } | - | - | - | - | + |*4 {7: }| ]]) else @@ -228,72 +255,337 @@ describe('ext_hlstate detailed highlights', function() ^tty ready | x {2:y }{3:z} | {1: } | - | - | - | - | + |*4 {7: }| ]]) end - thelpers.feed_termcode("[A") - thelpers.feed_termcode("[2C") + thelpers.feed_termcode('[A') + thelpers.feed_termcode('[2C') if is_os('win') then screen:expect([[ ^tty ready | x {6:y}{5: z} | - | - | - | - | - | + |*5 {7: }| ]]) else screen:expect([[ ^tty ready | x {4:y}{2: }{3:z} | - | - | - | - | - | + |*5 {7: }| ]]) end end) - it("can use independent cterm and rgb colors", function() + it('can use independent cterm and rgb colors', function() -- tell test module to save all attributes (doesn't change nvim options) screen:set_rgb_cterm(true) screen:set_default_attr_ids({ - [1] = {{bold = true, foreground = Screen.colors.Blue1}, {foreground = 12}, {{hi_name = "NonText", ui_name = "EndOfBuffer", kind = "ui"}}}, - [2] = {{reverse = true, foreground = Screen.colors.Red}, {foreground = 10, italic=true}, {{hi_name = "NonText", ui_name = "EndOfBuffer", kind = "ui"}}}, - [3] = {{}, {}, {{hi_name = "MsgArea", ui_name = "MsgArea", kind = "ui"}}}, + [1] = { + { bold = true, foreground = Screen.colors.Blue1 }, + { foreground = 12 }, + { { hi_name = 'NonText', ui_name = 'EndOfBuffer', kind = 'ui' } }, + }, + [2] = { + { reverse = true, foreground = Screen.colors.Red }, + { foreground = 10, italic = true }, + { { hi_name = 'NonText', ui_name = 'EndOfBuffer', kind = 'ui' } }, + }, + [3] = { {}, {}, { { hi_name = 'MsgArea', ui_name = 'MsgArea', kind = 'ui' } } }, }) screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 {3: }| ]]) - command("hi NonText guifg=Red gui=reverse ctermfg=Green cterm=italic") + command('hi NonText guifg=Red gui=reverse ctermfg=Green cterm=italic') screen:expect([[ ^ | + {2:~ }|*6 + {3: }| + ]]) + end) + + it('combines deleted extmark highlights', function() + insert([[ + line1 + line2 + line3 + line4 + line5 + line6]]) + + screen:expect { + grid = [[ + line1 | + line2 | + line3 | + line4 | + line5 | + line^6 | + {1:~ }| + {2: }| + ]], + attr_ids = { + [1] = { + { foreground = Screen.colors.Blue, bold = true }, + { { ui_name = 'EndOfBuffer', hi_name = 'NonText', kind = 'ui' } }, + }, + [2] = { {}, { { ui_name = 'MsgArea', hi_name = 'MsgArea', kind = 'ui' } } }, + }, + } + + local ns = api.nvim_create_namespace('test') + + local add_indicator = function(line, col) + api.nvim_buf_set_extmark(0, ns, line, col, { + hl_mode = 'combine', + priority = 2, + right_gravity = false, + virt_text = { { '|', 'Delimiter' } }, + virt_text_win_col = 0, + virt_text_pos = 'overlay', + }) + end + + add_indicator(1, 0) + add_indicator(2, 0) + add_indicator(3, 0) + add_indicator(4, 0) + + screen:expect { + grid = [[ + line1 | + {1:|} line2 | + {1:|} line3 | + {1:|} line4 | + {1:|} line5 | + line^6 | {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {3: }| + ]], + attr_ids = { + [1] = { + { foreground = Screen.colors.SlateBlue }, + { { hi_name = 'Special', kind = 'syntax' } }, + }, + [2] = { + { bold = true, foreground = Screen.colors.Blue }, + { { ui_name = 'EndOfBuffer', kind = 'ui', hi_name = 'NonText' } }, + }, + [3] = { {}, { { ui_name = 'MsgArea', kind = 'ui', hi_name = 'MsgArea' } } }, + }, + } + + helpers.feed('3ggV2jd') + --screen:redraw_debug() + screen:expect { + grid = [[ + line1 | + {1:|} line2 | + {2:^|}ine6 | + {3:~ }|*4 + {4:3 fewer lines }| + ]], + attr_ids = { + [1] = { + { foreground = Screen.colors.SlateBlue }, + { { kind = 'syntax', hi_name = 'Special' } }, + }, + [2] = { { foreground = Screen.colors.SlateBlue }, { 1, 1, 1 } }, + [3] = { + { bold = true, foreground = Screen.colors.Blue }, + { { kind = 'ui', ui_name = 'EndOfBuffer', hi_name = 'NonText' } }, + }, + [4] = { {}, { { kind = 'ui', ui_name = 'MsgArea', hi_name = 'MsgArea' } } }, + }, + } + end) + + it('removes deleted extmark highlights with invalidate', function() + insert([[ + line1 + line2 + line3 + line4 + line5 + line6]]) + + screen:expect { + grid = [[ + line1 | + line2 | + line3 | + line4 | + line5 | + line^6 | + {1:~ }| + {2: }| + ]], + attr_ids = { + [1] = { + { foreground = Screen.colors.Blue, bold = true }, + { { ui_name = 'EndOfBuffer', hi_name = 'NonText', kind = 'ui' } }, + }, + [2] = { {}, { { ui_name = 'MsgArea', hi_name = 'MsgArea', kind = 'ui' } } }, + }, + } + + local ns = api.nvim_create_namespace('test') + + local add_indicator = function(line, col) + api.nvim_buf_set_extmark(0, ns, line, col, { + hl_mode = 'combine', + priority = 2, + right_gravity = false, + virt_text = { { '|', 'Delimiter' } }, + virt_text_win_col = 0, + virt_text_pos = 'overlay', + invalidate = true, + }) + end + + add_indicator(1, 0) + add_indicator(2, 0) + add_indicator(3, 0) + add_indicator(4, 0) + + screen:expect { + grid = [[ + line1 | + {1:|} line2 | + {1:|} line3 | + {1:|} line4 | + {1:|} line5 | + line^6 | {2:~ }| {3: }| - ]]) + ]], + attr_ids = { + [1] = { + { foreground = Screen.colors.SlateBlue }, + { { hi_name = 'Special', kind = 'syntax' } }, + }, + [2] = { + { bold = true, foreground = Screen.colors.Blue }, + { { ui_name = 'EndOfBuffer', kind = 'ui', hi_name = 'NonText' } }, + }, + [3] = { {}, { { ui_name = 'MsgArea', kind = 'ui', hi_name = 'MsgArea' } } }, + }, + } + helpers.feed('3ggV2jd') + --screen:redraw_debug() + screen:expect { + grid = [[ + line1 | + {1:|} line2 | + ^line6 | + {2:~ }|*4 + {3:3 fewer lines }| + ]], + attr_ids = { + [1] = { + { foreground = Screen.colors.SlateBlue }, + { { kind = 'syntax', hi_name = 'Special' } }, + }, + [2] = { + { foreground = Screen.colors.Blue, bold = true }, + { { kind = 'ui', ui_name = 'EndOfBuffer', hi_name = 'NonText' } }, + }, + [3] = { {}, { { kind = 'ui', ui_name = 'MsgArea', hi_name = 'MsgArea' } } }, + }, + } + end) + + it('does not hang when combining too many highlights', function() + local num_lines = 500 + insert('first line\n') + for _ = 1, num_lines do + insert([[ + line + ]]) + end + insert('last line') + + helpers.feed('gg') + screen:expect { + grid = [[ + ^first line | + line |*6 + {1: }| + ]], + attr_ids = { + [1] = { {}, { { kind = 'ui', hi_name = 'MsgArea', ui_name = 'MsgArea' } } }, + }, + } + local ns = api.nvim_create_namespace('test') + + local add_indicator = function(line, col) + api.nvim_buf_set_extmark(0, ns, line, col, { + hl_mode = 'combine', + priority = 2, + right_gravity = false, + virt_text = { { '|', 'Delimiter' } }, + virt_text_win_col = 0, + virt_text_pos = 'overlay', + }) + end + + for i = 1, num_lines do + add_indicator(i, 0) + end + + screen:expect { + grid = [[ + ^first line | + {1:|} line |*6 + {2: }| + ]], + attr_ids = { + [1] = { + { foreground = Screen.colors.SlateBlue }, + { { kind = 'syntax', hi_name = 'Special' } }, + }, + [2] = { {}, { { kind = 'ui', ui_name = 'MsgArea', hi_name = 'MsgArea' } } }, + }, + } + + helpers.feed(string.format('3ggV%ijd', num_lines - 2)) + --screen:redraw_debug(nil, nil, 100000) + + local expected_ids = {} + for i = 1, num_lines - 1 do + expected_ids[i] = 1 + end + screen:expect { + grid = string.format( + [[ + first line | + {1:|} line | + {2:^|}ast line | + {3:~ }|*4 + {4:%-40s}| + ]], + tostring(num_lines - 1) .. ' fewer lines' + ), + attr_ids = { + [1] = { + { foreground = Screen.colors.SlateBlue }, + { { kind = 'syntax', hi_name = 'Special' } }, + }, + [2] = { { foreground = Screen.colors.SlateBlue }, expected_ids }, + [3] = { + { foreground = Screen.colors.Blue, bold = true }, + { { kind = 'ui', hi_name = 'NonText', ui_name = 'EndOfBuffer' } }, + }, + [4] = { {}, { { kind = 'ui', hi_name = 'MsgArea', ui_name = 'MsgArea' } } }, + }, + timeout = 100000, + } end) end) diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua index 3ee67a710c..29c8c43ca1 100644 --- a/test/functional/ui/inccommand_spec.lua +++ b/test/functional/ui/inccommand_spec.lua @@ -4,18 +4,17 @@ local clear = helpers.clear local command = helpers.command local eq = helpers.eq local eval = helpers.eval -local feed_command = helpers.feed_command local expect = helpers.expect local feed = helpers.feed local insert = helpers.insert -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local neq = helpers.neq local ok = helpers.ok local retry = helpers.retry local source = helpers.source local poke_eventloop = helpers.poke_eventloop -local nvim = helpers.nvim -local sleep = helpers.sleep +local sleep = vim.uv.sleep local testprg = helpers.testprg local assert_alive = helpers.assert_alive @@ -32,7 +31,7 @@ local multiline_text = [[ 7 8 9 ]] -local multimatch_text = [[ +local multimatch_text = [[ a bdc eae a fgl lzia r x ]] @@ -62,70 +61,70 @@ local long_multiline_text = [[ local function common_setup(screen, inccommand, text) if screen then - command("syntax on") - command("set nohlsearch") - command("hi Substitute guifg=red guibg=yellow") + command('syntax on') + command('set nohlsearch') + command('hi Substitute guifg=red guibg=yellow') screen:attach() screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.Fuchsia}, - [2] = {foreground = Screen.colors.Brown, bold = true}, - [3] = {foreground = Screen.colors.SlateBlue}, - [4] = {bold = true, foreground = Screen.colors.SlateBlue}, - [5] = {foreground = Screen.colors.DarkCyan}, - [6] = {bold = true}, - [7] = {underline = true, bold = true, foreground = Screen.colors.SlateBlue}, - [8] = {foreground = Screen.colors.Slateblue, underline = true}, - [9] = {background = Screen.colors.Yellow}, - [10] = {reverse = true}, - [11] = {reverse = true, bold=true}, - [12] = {foreground = Screen.colors.Red, background = Screen.colors.Yellow}, - [13] = {bold = true, foreground = Screen.colors.SeaGreen}, - [14] = {foreground = Screen.colors.White, background = Screen.colors.Red}, - [15] = {bold=true, foreground=Screen.colors.Blue}, - [16] = {background=Screen.colors.Grey90}, -- cursorline - [17] = {foreground = Screen.colors.Blue1}, - vis = {background=Screen.colors.LightGrey} + [1] = { foreground = Screen.colors.Fuchsia }, + [2] = { foreground = Screen.colors.Brown, bold = true }, + [3] = { foreground = Screen.colors.SlateBlue }, + [4] = { bold = true, foreground = Screen.colors.SlateBlue }, + [5] = { foreground = Screen.colors.DarkCyan }, + [6] = { bold = true }, + [7] = { underline = true, bold = true, foreground = Screen.colors.SlateBlue }, + [8] = { foreground = Screen.colors.Slateblue, underline = true }, + [9] = { background = Screen.colors.Yellow }, + [10] = { reverse = true }, + [11] = { reverse = true, bold = true }, + [12] = { foreground = Screen.colors.Red, background = Screen.colors.Yellow }, + [13] = { bold = true, foreground = Screen.colors.SeaGreen }, + [14] = { foreground = Screen.colors.White, background = Screen.colors.Red }, + [15] = { bold = true, foreground = Screen.colors.Blue }, + [16] = { background = Screen.colors.Grey90 }, -- cursorline + [17] = { foreground = Screen.colors.Blue1 }, + vis = { background = Screen.colors.LightGrey }, }) end - command("set inccommand=" .. (inccommand or "")) + command('set inccommand=' .. (inccommand or '')) if text then insert(text) end end -describe(":substitute, inccommand=split interactivity", function() +describe(':substitute, inccommand=split interactivity', function() before_each(function() clear() - common_setup(nil, "split", default_text) + common_setup(nil, 'split', default_text) end) -- Test the tests: verify that the `1==bufnr('$')` assertion -- in the "no preview" tests (below) actually means something. - it("previews interactive cmdline", function() + it('previews interactive cmdline', function() feed(':%s/tw/MO/g') retry(nil, 1000, function() eq(2, eval("bufnr('$')")) end) end) - it("no preview if invoked by a script", function() + it('no preview if invoked by a script', function() source('%s/tw/MO/g') poke_eventloop() eq(1, eval("bufnr('$')")) -- sanity check: assert the buffer state - expect(default_text:gsub("tw", "MO")) + expect(default_text:gsub('tw', 'MO')) end) - it("no preview if invoked by feedkeys()", function() + it('no preview if invoked by feedkeys()', function() -- in a script... source([[:call feedkeys(":%s/tw/MO/g\<CR>")]]) -- or interactively... feed([[:call feedkeys(":%s/bs/BUU/g\<lt>CR>")<CR>]]) eq(1, eval("bufnr('$')")) -- sanity check: assert the buffer state - expect(default_text:gsub("tw", "MO"):gsub("bs", "BUU")) + expect(default_text:gsub('tw', 'MO'):gsub('bs', 'BUU')) end) end) @@ -133,17 +132,17 @@ describe(":substitute, 'inccommand' preserves", function() before_each(clear) it('listed buffers (:ls)', function() - local screen = Screen.new(30,10) - common_setup(screen, "split", "ABC") + local screen = Screen.new(30, 10) + common_setup(screen, 'split', 'ABC') - feed_command("%s/AB/BA/") - feed_command("ls") + feed(':%s/AB/BA/') + poke_eventloop() + feed('<CR>') + feed(':ls<CR>') screen:expect([[ BAC | - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*3 {11: }| :ls | 1 %a + "[No Name]" | @@ -153,43 +152,68 @@ describe(":substitute, 'inccommand' preserves", function() ]]) end) - for _, case in pairs{"", "split", "nosplit"} do - it("various delimiters (inccommand="..case..")", function() + it("'[ and '] marks #26439", function() + local screen = Screen.new(30, 10) + common_setup(screen, 'nosplit', ('abc\ndef\n'):rep(50)) + + feed('ggyG') + local X = api.nvim_get_vvar('maxcol') + eq({ 0, 1, 1, 0 }, fn.getpos("'[")) + eq({ 0, 101, X, 0 }, fn.getpos("']")) + + feed(":'[,']s/def/") + poke_eventloop() + eq({ 0, 1, 1, 0 }, fn.getpos("'[")) + eq({ 0, 101, X, 0 }, fn.getpos("']")) + + feed('DEF/g') + poke_eventloop() + eq({ 0, 1, 1, 0 }, fn.getpos("'[")) + eq({ 0, 101, X, 0 }, fn.getpos("']")) + + feed('<CR>') + expect(('abc\nDEF\n'):rep(50)) + end) + + for _, case in pairs { '', 'split', 'nosplit' } do + it('various delimiters (inccommand=' .. case .. ')', function() insert(default_text) - feed_command("set inccommand=" .. case) + command('set inccommand=' .. case) local delims = { '/', '#', ';', '%', ',', '@', '!' } - for _,delim in pairs(delims) do - feed_command("%s"..delim.."lines"..delim.."LINES"..delim.."g") + for _, delim in pairs(delims) do + feed(':%s' .. delim .. 'lines' .. delim .. 'LINES' .. delim .. 'g') + poke_eventloop() + feed('<CR>') expect([[ Inc substitution on two LINES ]]) - feed_command("undo") + command('undo') end end) end - for _, case in pairs{"", "split", "nosplit"} do - it("'undolevels' (inccommand="..case..")", function() - feed_command("set undolevels=139") - feed_command("setlocal undolevels=34") - feed_command("split") -- Show the buffer in multiple windows - feed_command("set inccommand=" .. case) - insert("as") - feed(":%s/as/glork/") + for _, case in pairs { '', 'split', 'nosplit' } do + it("'undolevels' (inccommand=" .. case .. ')', function() + command('set undolevels=139') + command('setlocal undolevels=34') + command('split') -- Show the buffer in multiple windows + command('set inccommand=' .. case) + insert('as') + feed(':%s/as/glork/') poke_eventloop() - feed("<enter>") - eq(meths.get_option_value('undolevels', {scope='global'}), 139) - eq(meths.get_option_value('undolevels', {buf=0}), 34) + feed('<enter>') + eq(api.nvim_get_option_value('undolevels', { scope = 'global' }), 139) + eq(api.nvim_get_option_value('undolevels', { buf = 0 }), 34) end) end - for _, case in ipairs({"", "split", "nosplit"}) do - it("empty undotree() (inccommand="..case..")", function() - feed_command("set undolevels=1000") - feed_command("set inccommand=" .. case) - local expected_undotree = eval("undotree()") + for _, case in ipairs({ '', 'split', 'nosplit' }) do + it('empty undotree() (inccommand=' .. case .. ')', function() + command('set undolevels=1000') + command('set inccommand=' .. case) + local expected_undotree = eval('undotree()') -- Start typing an incomplete :substitute command. feed([[:%s/e/YYYY/g]]) @@ -198,15 +222,15 @@ describe(":substitute, 'inccommand' preserves", function() feed([[<C-\><C-N>]]) -- The undo tree should be unchanged. - eq(expected_undotree, eval("undotree()")) - eq({}, eval("undotree()")["entries"]) + eq(expected_undotree, eval('undotree()')) + eq({}, eval('undotree()')['entries']) end) end - for _, case in ipairs({"", "split", "nosplit"}) do - it("undotree() with branches (inccommand="..case..")", function() - feed_command("set undolevels=1000") - feed_command("set inccommand=" .. case) + for _, case in ipairs({ '', 'split', 'nosplit' }) do + it('undotree() with branches (inccommand=' .. case .. ')', function() + command('set undolevels=1000') + command('set inccommand=' .. case) -- Make some changes. feed([[isome text 1<C-\><C-N>]]) feed([[osome text 2<C-\><C-N>]]) @@ -224,8 +248,8 @@ describe(":substitute, 'inccommand' preserves", function() some text 1 some text 3XX some text 5]]) - local expected_undotree = eval("undotree()") - eq(5, #expected_undotree["entries"]) -- sanity + local expected_undotree = eval('undotree()') + eq(5, #expected_undotree['entries']) -- sanity -- Start typing an incomplete :substitute command. feed([[:%s/e/YYYY/g]]) @@ -234,31 +258,31 @@ describe(":substitute, 'inccommand' preserves", function() feed([[<C-\><C-N>]]) -- The undo tree should be unchanged. - eq(expected_undotree, eval("undotree()")) + eq(expected_undotree, eval('undotree()')) end) end - for _, case in pairs{"", "split", "nosplit"} do - it("b:changedtick (inccommand="..case..")", function() - feed_command("set inccommand=" .. case) + for _, case in pairs { '', 'split', 'nosplit' } do + it('b:changedtick (inccommand=' .. case .. ')', function() + command('set inccommand=' .. case) feed([[isome text 1<C-\><C-N>]]) feed([[osome text 2<C-\><C-N>]]) - local expected_tick = eval("b:changedtick") + local expected_tick = eval('b:changedtick') ok(expected_tick > 0) expect([[ some text 1 some text 2]]) - feed(":%s/e/XXX/") + feed(':%s/e/XXX/') poke_eventloop() - eq(expected_tick, eval("b:changedtick")) + eq(expected_tick, eval('b:changedtick')) end) end - for _, case in ipairs({'', 'split', 'nosplit'}) do - it('previous substitute string ~ (inccommand='..case..') #12109', function() - local screen = Screen.new(30,10) + for _, case in ipairs({ '', 'split', 'nosplit' }) do + it('previous substitute string ~ (inccommand=' .. case .. ') #12109', function() + local screen = Screen.new(30, 10) common_setup(screen, case, default_text) feed(':%s/Inc/SUB<CR>') @@ -323,47 +347,51 @@ describe(":substitute, 'inccommand' preserves", function() end) describe(":substitute, 'inccommand' preserves undo", function() - local cases = { "", "split", "nosplit" } + local cases = { '', 'split', 'nosplit' } local substrings = { - ":%s/1", - ":%s/1/", - ":%s/1/<bs>", - ":%s/1/a", - ":%s/1/a<bs>", - ":%s/1/ax", - ":%s/1/ax<bs>", - ":%s/1/ax<bs><bs>", - ":%s/1/ax<bs><bs><bs>", - ":%s/1/ax/", - ":%s/1/ax/<bs>", - ":%s/1/ax/<bs>/", - ":%s/1/ax/g", - ":%s/1/ax/g<bs>", - ":%s/1/ax/g<bs><bs>" + { ':%s/', '1' }, + { ':%s/', '1', '/' }, + { ':%s/', '1', '/', '<bs>' }, + { ':%s/', '1', '/', 'a' }, + { ':%s/', '1', '/', 'a', '<bs>' }, + { ':%s/', '1', '/', 'a', 'x' }, + { ':%s/', '1', '/', 'a', 'x', '<bs>' }, + { ':%s/', '1', '/', 'a', 'x', '<bs>', '<bs>' }, + { ':%s/', '1', '/', 'a', 'x', '<bs>', '<bs>', '<bs>' }, + { ':%s/', '1', '/', 'a', 'x', '/' }, + { ':%s/', '1', '/', 'a', 'x', '/', '<bs>' }, + { ':%s/', '1', '/', 'a', 'x', '/', '<bs>', '/' }, + { ':%s/', '1', '/', 'a', 'x', '/', 'g' }, + { ':%s/', '1', '/', 'a', 'x', '/', 'g', '<bs>' }, + { ':%s/', '1', '/', 'a', 'x', '/', 'g', '<bs>', '<bs>' }, } local function test_sub(substring, split, redoable) command('bwipe!') - feed_command("set inccommand=" .. split) + command('set inccommand=' .. split) - insert("1") - feed("o2<esc>") - feed_command("undo") - feed("o3<esc>") + insert('1') + feed('o2<esc>') + command('undo') + feed('o3<esc>') if redoable then - feed("o4<esc>") - feed_command("undo") + feed('o4<esc>') + command('undo') + end + for _, s in pairs(substring) do + feed(s) end - feed(substring.. "<enter>") - feed_command("undo") + poke_eventloop() + feed('<enter>') + command('undo') - feed("g-") + feed('g-') expect([[ 1 2]]) - feed("g+") + feed('g+') expect([[ 1 3]]) @@ -371,30 +399,34 @@ describe(":substitute, 'inccommand' preserves undo", function() local function test_notsub(substring, split, redoable) command('bwipe!') - feed_command("set inccommand=" .. split) + command('set inccommand=' .. split) - insert("1") - feed("o2<esc>") - feed_command("undo") - feed("o3<esc>") + insert('1') + feed('o2<esc>') + command('undo') + feed('o3<esc>') if redoable then - feed("o4<esc>") - feed_command("undo") + feed('o4<esc>') + command('undo') + end + for _, s in pairs(substring) do + feed(s) end - feed(substring .. "<esc>") + poke_eventloop() + feed('<esc>') - feed("g-") + feed('g-') expect([[ 1 2]]) - feed("g+") + feed('g+') expect([[ 1 3]]) if redoable then - feed("<c-r>") + feed('<c-r>') expect([[ 1 3 @@ -402,20 +434,19 @@ describe(":substitute, 'inccommand' preserves undo", function() end end - local function test_threetree(substring, split) command('bwipe!') - feed_command("set inccommand=" .. split) - - insert("1") - feed("o2<esc>") - feed("o3<esc>") - feed("uu") - feed("oa<esc>") - feed("ob<esc>") - feed("uu") - feed("oA<esc>") - feed("oB<esc>") + command('set inccommand=' .. split) + + insert('1') + feed('o2<esc>') + feed('o3<esc>') + feed('uu') + feed('oa<esc>') + feed('ob<esc>') + feed('uu') + feed('oA<esc>') + feed('oB<esc>') -- This is the undo tree (x-Axis is timeline), we're at B now -- ----------------A - B @@ -424,33 +455,45 @@ describe(":substitute, 'inccommand' preserves undo", function() -- |/ -- 1 - 2 - 3 - feed("2u") - feed(substring .. "<esc>") + feed('2u') + for _, s in pairs(substring) do + feed(s) + poke_eventloop() + end + feed('<esc>') expect([[ 1]]) - feed("g-") + feed('g-') expect([[ ]]) - feed("g+") + feed('g+') expect([[ 1]]) - feed("<c-r>") + feed('<c-r>') expect([[ 1 A]]) - feed("g-") -- go to b - feed("2u") - feed(substring .. "<esc>") - feed("<c-r>") + feed('g-') -- go to b + feed('2u') + for _, s in pairs(substring) do + feed(s) + poke_eventloop() + end + feed('<esc>') + feed('<c-r>') expect([[ 1 a]]) - feed("g-") -- go to 3 - feed("2u") - feed(substring .. "<esc>") - feed("<c-r>") + feed('g-') -- go to 3 + feed('2u') + for _, s in pairs(substring) do + feed(s) + poke_eventloop() + end + feed('<esc>') + feed('<c-r>') expect([[ 1 2]]) @@ -458,37 +501,37 @@ describe(":substitute, 'inccommand' preserves undo", function() before_each(clear) - it("at a non-leaf of the undo tree", function() - for _, case in pairs(cases) do - for _, str in pairs(substrings) do - for _, redoable in pairs({true}) do - test_sub(str, case, redoable) - end - end - end + it('at a non-leaf of the undo tree', function() + for _, case in pairs(cases) do + for _, str in pairs(substrings) do + for _, redoable in pairs({ true }) do + test_sub(str, case, redoable) + end + end + end end) - it("at a leaf of the undo tree", function() + it('at a leaf of the undo tree', function() for _, case in pairs(cases) do for _, str in pairs(substrings) do - for _, redoable in pairs({false}) do + for _, redoable in pairs({ false }) do test_sub(str, case, redoable) end end end end) - it("when interrupting substitution", function() + it('when interrupting substitution', function() for _, case in pairs(cases) do for _, str in pairs(substrings) do - for _, redoable in pairs({true,false}) do + for _, redoable in pairs({ true, false }) do test_notsub(str, case, redoable) end end end end) - it("in a complex undo scenario", function() + it('in a complex undo scenario', function() for _, case in pairs(cases) do for _, str in pairs(substrings) do test_threetree(str, case) @@ -500,28 +543,32 @@ describe(":substitute, 'inccommand' preserves undo", function() for _, case in pairs(cases) do clear() common_setup(nil, case, default_text) - feed_command("set undolevels=0") + command('set undolevels=0') - feed("1G0") - insert("X") - feed(":%s/tw/MO/<esc>") - feed_command("undo") + feed('1G0') + insert('X') + feed(':%s/tw/MO/') + poke_eventloop() + feed('<esc>') + command('undo') expect(default_text) - feed_command("undo") - expect(default_text:gsub("Inc", "XInc")) - feed_command("undo") + command('undo') + expect(default_text:gsub('Inc', 'XInc')) + command('undo') - feed_command("%s/tw/MO/g") - expect(default_text:gsub("tw", "MO")) - feed_command("undo") + feed(':%s/tw/MO/g') + poke_eventloop() + feed('<CR>') + expect(default_text:gsub('tw', 'MO')) + command('undo') expect(default_text) - feed_command("undo") - expect(default_text:gsub("tw", "MO")) + command('undo') + expect(default_text:gsub('tw', 'MO')) end end) it('with undolevels=1', function() - local screen = Screen.new(20,10) + local screen = Screen.new(20, 10) for _, case in pairs(cases) do clear() @@ -530,46 +577,43 @@ describe(":substitute, 'inccommand' preserves undo", function() Inc substitution on | two lines | ^ | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 | ]]) - feed_command("set undolevels=1") - - feed("1G0") - insert("X") - feed("IY<esc>") - feed(":%s/tw/MO/<esc>") - -- feed_command("undo") here would cause "Press ENTER". - feed("u") - expect(default_text:gsub("Inc", "XInc")) - feed("u") + command('set undolevels=1') + + feed('1G0') + insert('X') + feed('IY<esc>') + feed(':%s/tw/MO/') + poke_eventloop() + feed('<esc>') + feed('u') + expect(default_text:gsub('Inc', 'XInc')) + feed('u') expect(default_text) - feed(":%s/tw/MO/g<enter>") - feed(":%s/MO/GO/g<enter>") - feed(":%s/GO/NO/g<enter>") - feed("u") - expect(default_text:gsub("tw", "GO")) - feed("u") - expect(default_text:gsub("tw", "MO")) - feed("u") + feed(':%s/tw/MO/g') + poke_eventloop() + feed('<enter>') + feed(':%s/MO/GO/g') + poke_eventloop() + feed('<enter>') + feed(':%s/GO/NO/g') + poke_eventloop() + feed('<enter>') + feed('u') + expect(default_text:gsub('tw', 'GO')) + feed('u') + expect(default_text:gsub('tw', 'MO')) + feed('u') - if case == "split" then + if case == 'split' then screen:expect([[ Inc substitution on | ^MOo lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 Already ...t change | ]]) else @@ -577,12 +621,7 @@ describe(":substitute, 'inccommand' preserves undo", function() Inc substitution on | ^MOo lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 Already ...t change | ]]) end @@ -590,37 +629,33 @@ describe(":substitute, 'inccommand' preserves undo", function() end) it('with undolevels=2', function() - local screen = Screen.new(20,10) + local screen = Screen.new(20, 10) for _, case in pairs(cases) do clear() common_setup(screen, case, default_text) - feed_command("set undolevels=2") - - feed("2GAx<esc>") - feed("Ay<esc>") - feed("Az<esc>") - feed(":%s/tw/AR<esc>") - -- feed_command("undo") here would cause "Press ENTER". - feed("u") - expect(default_text:gsub("lines", "linesxy")) - feed("u") - expect(default_text:gsub("lines", "linesx")) - feed("u") + command('set undolevels=2') + + feed('2GAx<esc>') + feed('Ay<esc>') + feed('Az<esc>') + feed(':%s/tw/AR') + poke_eventloop() + feed('<esc>') + feed('u') + expect(default_text:gsub('lines', 'linesxy')) + feed('u') + expect(default_text:gsub('lines', 'linesx')) + feed('u') expect(default_text) - feed("u") + feed('u') - if case == "split" then + if case == 'split' then screen:expect([[ Inc substitution on | two line^s | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 Already ...t change | ]]) else @@ -628,39 +663,37 @@ describe(":substitute, 'inccommand' preserves undo", function() Inc substitution on | two line^s | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 Already ...t change | ]]) end - feed(":%s/tw/MO/g<enter>") - feed(":%s/MO/GO/g<enter>") - feed(":%s/GO/NO/g<enter>") - feed(":%s/NO/LO/g<enter>") - feed("u") - expect(default_text:gsub("tw", "NO")) - feed("u") - expect(default_text:gsub("tw", "GO")) - feed("u") - expect(default_text:gsub("tw", "MO")) - feed("u") - - if case == "split" then + feed(':%s/tw/MO/g') + poke_eventloop() + feed('<enter>') + feed(':%s/MO/GO/g') + poke_eventloop() + feed('<enter>') + feed(':%s/GO/NO/g') + poke_eventloop() + feed('<enter>') + feed(':%s/NO/LO/g') + poke_eventloop() + feed('<enter>') + feed('u') + expect(default_text:gsub('tw', 'NO')) + feed('u') + expect(default_text:gsub('tw', 'GO')) + feed('u') + expect(default_text:gsub('tw', 'MO')) + feed('u') + + if case == 'split' then screen:expect([[ Inc substitution on | ^MOo lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 Already ...t change | ]]) else @@ -668,12 +701,7 @@ describe(":substitute, 'inccommand' preserves undo", function() Inc substitution on | ^MOo lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 Already ...t change | ]]) end @@ -681,27 +709,23 @@ describe(":substitute, 'inccommand' preserves undo", function() end) it('with undolevels=-1', function() - local screen = Screen.new(20,10) + local screen = Screen.new(20, 10) for _, case in pairs(cases) do clear() common_setup(screen, case, default_text) - feed_command("set undolevels=-1") - feed(":%s/tw/MO/g<enter>") - -- feed_command("undo") here will result in a "Press ENTER" prompt - feed("u") - if case == "split" then + command('set undolevels=-1') + feed(':%s/tw/MO/g') + poke_eventloop() + feed('<enter>') + feed('u') + if case == 'split' then screen:expect([[ Inc substitution on | ^MOo lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 Already ...t change | ]]) else @@ -709,12 +733,7 @@ describe(":substitute, 'inccommand' preserves undo", function() Inc substitution on | ^MOo lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 Already ...t change | ]]) end @@ -723,41 +742,37 @@ describe(":substitute, 'inccommand' preserves undo", function() clear() common_setup(screen, case, default_text) - feed_command("set undolevels=-1") - feed("1G") - feed("IL<esc>") - feed(":%s/tw/MO/g<esc>") - feed("u") + command('set undolevels=-1') + feed('1G') + feed('IL<esc>') + feed(':%s/tw/MO/g') + poke_eventloop() + feed('<esc>') + feed('u') screen:expect([[ ^LInc substitution on| two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 Already ...t change | ]]) end end) - end) -describe(":substitute, inccommand=split", function() +describe(':substitute, inccommand=split', function() local screen before_each(function() clear() - screen = Screen.new(30,15) - common_setup(screen, "split", default_text .. default_text) + screen = Screen.new(30, 15) + common_setup(screen, 'split', default_text .. default_text) end) it("preserves 'modified' buffer flag", function() - feed_command("set nomodified") - feed(":%s/tw") + command('set nomodified') + feed(':%s/tw') screen:expect([[ Inc substitution on | {12:tw}o lines | @@ -767,30 +782,26 @@ describe(":substitute, inccommand=split", function() {11:[No Name] }| |2| {12:tw}o lines | |4| {12:tw}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :%s/tw^ | ]]) - feed([[<C-\><C-N>]]) -- Cancel the :substitute command. - eq(0, eval("&modified")) + feed([[<C-\><C-N>]]) -- Cancel the :substitute command. + eq(0, eval('&modified')) end) - it("shows preview when cmd modifiers are present", function() + it('shows preview when cmd modifiers are present', function() -- one modifier feed(':keeppatterns %s/tw/to') - screen:expect{any=[[{12:to}o lines]]} + screen:expect { any = [[{12:to}o lines]] } feed('<Esc>') - screen:expect{any=[[two lines]]} + screen:expect { any = [[two lines]] } -- multiple modifiers feed(':keeppatterns silent %s/tw/to') - screen:expect{any=[[{12:to}o lines]]} + screen:expect { any = [[{12:to}o lines]] } feed('<Esc>') - screen:expect{any=[[two lines]]} + screen:expect { any = [[two lines]] } -- non-modifier prefix feed(':silent tabedit %s/tw/to') @@ -800,27 +811,19 @@ describe(":substitute, inccommand=split", function() Inc substitution on | two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*9 :silent tabedit %s/tw/to^ | ]]) feed('<Esc>') -- leading colons feed(':::%s/tw/to') - screen:expect{any=[[{12:to}o lines]]} + screen:expect { any = [[{12:to}o lines]] } feed('<Esc>') - screen:expect{any=[[two lines]]} + screen:expect { any = [[two lines]] } end) - it("ignores new-window modifiers when splitting the preview window", function() + it('ignores new-window modifiers when splitting the preview window', function() -- one modifier feed(':topleft %s/tw/to') screen:expect([[ @@ -832,16 +835,12 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |2| {12:to}o lines | |4| {12:to}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :topleft %s/tw/to^ | ]]) feed('<Esc>') - screen:expect{any=[[two lines]]} + screen:expect { any = [[two lines]] } -- multiple modifiers feed(':topleft vert %s/tw/to') @@ -854,20 +853,16 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |2| {12:to}o lines | |4| {12:to}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :topleft vert %s/tw/to^ | ]]) feed('<Esc>') - screen:expect{any=[[two lines]]} + screen:expect { any = [[two lines]] } end) it('shows split window when typing the pattern', function() - feed(":%s/tw") + feed(':%s/tw') screen:expect([[ Inc substitution on | {12:tw}o lines | @@ -877,18 +872,14 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |2| {12:tw}o lines | |4| {12:tw}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :%s/tw^ | ]]) end) it('shows preview with empty replacement', function() - feed(":%s/tw/") + feed(':%s/tw/') screen:expect([[ Inc substitution on | o lines | @@ -898,16 +889,12 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |2| o lines | |4| o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :%s/tw/^ | ]]) - feed("x") + feed('x') screen:expect([[ Inc substitution on | {12:x}o lines | @@ -917,16 +904,12 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |2| {12:x}o lines | |4| {12:x}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :%s/tw/x^ | ]]) - feed("<bs>") + feed('<bs>') screen:expect([[ Inc substitution on | o lines | @@ -936,19 +919,14 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |2| o lines | |4| o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :%s/tw/^ | ]]) - end) it('shows split window when typing replacement', function() - feed(":%s/tw/XX") + feed(':%s/tw/XX') screen:expect([[ Inc substitution on | {12:XX}o lines | @@ -958,41 +936,29 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |2| {12:XX}o lines | |4| {12:XX}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :%s/tw/XX^ | ]]) end) it('does not show split window for :s/', function() - feed("2gg") - feed(":s/tw") + feed('2gg') + feed(':s/tw') screen:expect([[ Inc substitution on | {12:tw}o lines | Inc substitution on | two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*9 :s/tw^ | ]]) end) it("'hlsearch' is active, 'cursorline' is not", function() - feed_command("set hlsearch cursorline") - feed("gg") + command('set hlsearch cursorline') + feed('gg') -- Assert that 'cursorline' is active. screen:expect([[ @@ -1001,19 +967,11 @@ describe(":substitute, inccommand=split", function() Inc substitution on | two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - :set hlsearch cursorline | + {15:~ }|*9 + | ]]) - feed(":%s/tw") + feed(':%s/tw') -- 'cursorline' is NOT active during preview. screen:expect([[ Inc substitution on | @@ -1024,11 +982,7 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |2| {12:tw}o lines | |4| {12:tw}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :%s/tw^ | ]]) @@ -1046,12 +1000,7 @@ describe(":substitute, inccommand=split", function() two lines | {11:[No Name] [+] }| |1| {12:123} {12:123} {12:123} | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/M/123/g^ | ]]) @@ -1068,33 +1017,20 @@ describe(":substitute, inccommand=split", function() | {11:[No Name] [+] }| | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/Inx^ | ]]) end) it('previews correctly when previewhight is small', function() - feed_command('set cwh=3') - feed_command('set hls') + command('set cwh=3') + command('set hls') feed('ggdG') insert(string.rep('abc abc abc\n', 20)) feed(':%s/abc/MMM/g') screen:expect([[ - {12:MMM} {12:MMM} {12:MMM} | - {12:MMM} {12:MMM} {12:MMM} | - {12:MMM} {12:MMM} {12:MMM} | - {12:MMM} {12:MMM} {12:MMM} | - {12:MMM} {12:MMM} {12:MMM} | - {12:MMM} {12:MMM} {12:MMM} | - {12:MMM} {12:MMM} {12:MMM} | - {12:MMM} {12:MMM} {12:MMM} | - {12:MMM} {12:MMM} {12:MMM} | + {12:MMM} {12:MMM} {12:MMM} |*9 {11:[No Name] [+] }| | 1| {12:MMM} {12:MMM} {12:MMM} | | 2| {12:MMM} {12:MMM} {12:MMM} | @@ -1105,7 +1041,9 @@ describe(":substitute, inccommand=split", function() end) it('actually replaces text', function() - feed(":%s/tw/XX/g<Enter>") + feed(':%s/tw/XX/g') + poke_eventloop() + feed('<Enter>') screen:expect([[ Inc substitution on | @@ -1113,32 +1051,24 @@ describe(":substitute, inccommand=split", function() Inc substitution on | ^XXo lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*9 :%s/tw/XX/g | ]]) end) it('shows correct line numbers with many lines', function() - feed("gg") - feed("2yy") - feed("2000p") - feed_command("1,1000s/tw/BB/g") + feed('gg') + feed('2yy') + feed('2000p') + command('1,1000s/tw/BB/g') - feed(":%s/tw/X") + feed(':%s/tw/X') screen:expect([[ + Inc substitution on | BBo lines | Inc substitution on | {12:X}o lines | Inc substitution on | - {12:X}o lines | {11:[No Name] [+] }| |1001| {12:X}o lines | |1003| {12:X}o lines | @@ -1155,58 +1085,52 @@ describe(":substitute, inccommand=split", function() it('does not spam the buffer numbers', function() -- The preview buffer is re-used (unless user deleted it), so buffer numbers -- will not increase on each keystroke. - feed(":%s/tw/Xo/g") + feed(':%s/tw/Xo/g') -- Delete and re-type the g a few times. - feed("<BS>") + feed('<BS>') poke_eventloop() - feed("g") + feed('g') poke_eventloop() - feed("<BS>") + feed('<BS>') poke_eventloop() - feed("g") + feed('g') poke_eventloop() - feed("<CR>") + feed('<CR>') poke_eventloop() - feed(":vs tmp<enter>") - eq(3, helpers.call('bufnr', '$')) + feed(':vs tmp<enter>') + eq(3, fn.bufnr('$')) end) it('works with the n flag', function() - feed(":%s/tw/Mix/n<Enter>") + feed(':%s/tw/Mix/n') + poke_eventloop() + feed('<Enter>') screen:expect([[ Inc substitution on | two lines | Inc substitution on | two lines | ^ | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*9 2 matches on 2 lines | ]]) end) it("deactivates if 'redrawtime' is exceeded #5602", function() -- prevent redraws from 'incsearch' - meths.set_option_value('incsearch', false, {}) + api.nvim_set_option_value('incsearch', false, {}) -- Assert that 'inccommand' is ENABLED initially. - eq("split", eval("&inccommand")) + eq('split', eval('&inccommand')) -- Set 'redrawtime' to minimal value, to ensure timeout is triggered. - feed_command("set redrawtime=1 nowrap") + command('set redrawtime=1 nowrap') -- Load a big file. - feed_command("silent edit! test/functional/fixtures/bigfile_oneline.txt") + command('silent edit! test/functional/fixtures/bigfile_oneline.txt') -- Start :substitute with a slow pattern. feed([[:%s/B.*N/x]]) poke_eventloop() -- Assert that 'inccommand' is DISABLED in cmdline mode. - eq("", eval("&inccommand")) + eq('', eval('&inccommand')) -- Assert that preview cleared (or never manifested). screen:expect([[ 0000;<control>;Cc;0;BN;;;;;N;N| @@ -1228,7 +1152,7 @@ describe(":substitute, inccommand=split", function() -- Assert that 'inccommand' is again ENABLED after leaving cmdline mode. feed([[<C-\><C-N>]]) - eq("split", eval("&inccommand")) + eq('split', eval('&inccommand')) end) it("deactivates if 'foldexpr' is slow #9557", function() @@ -1264,12 +1188,12 @@ describe(":substitute, inccommand=split", function() end) end) - it("clears preview if non-previewable command is edited #5585", function() + it('clears preview if non-previewable command is edited #5585', function() feed('gg') -- Put a non-previewable command in history. - feed_command("echo 'foo'") + feed(":echo 'foo'<CR>") -- Start an incomplete :substitute command. - feed(":1,2s/t/X") + feed(':1,2s/t/X') screen:expect([[ Inc subs{12:X}itution on | @@ -1280,17 +1204,13 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |1| Inc subs{12:X}itution on | |2| {12:X}wo lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :1,2s/t/X^ | ]]) -- Select the previous command. - feed("<C-P>") + feed('<C-P>') -- Assert that preview was cleared. screen:expect([[ Inc substitution on | @@ -1298,22 +1218,14 @@ describe(":substitute, inccommand=split", function() Inc substitution on | two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*9 :echo 'foo'^ | ]]) end) it([[preview changes correctly with c_CTRL-R_= and c_CTRL-\_e]], function() feed('gg') - feed(":1,2s/t/X") + feed(':1,2s/t/X') screen:expect([[ Inc subs{12:X}itution on | {12:X}wo lines | @@ -1323,11 +1235,7 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |1| Inc subs{12:X}itution on | |2| {12:X}wo lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :1,2s/t/X^ | ]]) @@ -1343,11 +1251,7 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |1| Inc subs{12:X}itution on | |2| {12:X}wo lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| ={1:'Y'}^ | ]]) @@ -1363,11 +1267,7 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |1| Inc subs{12:XY}itution on | |2| {12:XY}wo lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :1,2s/t/XY^ | ]]) @@ -1383,11 +1283,7 @@ describe(":substitute, inccommand=split", function() {11:[No Name] [+] }| |1| Inc subs{12:XY}itution on | |2| {12:XY}wo lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| ={1:'echo'}^ | ]]) @@ -1400,76 +1296,61 @@ describe(":substitute, inccommand=split", function() Inc substitution on | two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*9 :echo^ | ]]) end) - end) -describe("inccommand=nosplit", function() +describe('inccommand=nosplit', function() local screen before_each(function() clear() - screen = Screen.new(20,10) - common_setup(screen, "nosplit", default_text .. default_text) + screen = Screen.new(20, 10) + common_setup(screen, 'nosplit', default_text .. default_text) end) - it("works with :smagic, :snomagic", function() - feed_command("set hlsearch") - insert("Line *.3.* here") + it('works with :smagic, :snomagic', function() + command('set hlsearch') + insert('Line *.3.* here') - feed(":%smagic/3.*/X") -- start :smagic command + feed(':%smagic/3.*/X') -- start :smagic command screen:expect([[ Inc substitution on | two lines | Inc substitution on | two lines | Line *.{12:X} | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :%smagic/3.*/X^ | ]]) - feed([[<C-\><C-N>]]) -- cancel - feed(":%snomagic/3.*/X") -- start :snomagic command + feed([[<C-\><C-N>]]) -- cancel + feed(':%snomagic/3.*/X') -- start :snomagic command screen:expect([[ Inc substitution on | two lines | Inc substitution on | two lines | Line *.{12:X} here | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :%snomagic/3.*/X^ | ]]) end) - it("shows preview when cmd modifiers are present", function() + it('shows preview when cmd modifiers are present', function() -- one modifier feed(':keeppatterns %s/tw/to') - screen:expect{any=[[{12:to}o lines]]} + screen:expect { any = [[{12:to}o lines]] } feed('<Esc>') - screen:expect{any=[[two lines]]} + screen:expect { any = [[two lines]] } -- multiple modifiers feed(':keeppatterns silent %s/tw/to') - screen:expect{any=[[{12:to}o lines]]} + screen:expect { any = [[{12:to}o lines]] } feed('<Esc>') - screen:expect{any=[[two lines]]} + screen:expect { any = [[two lines]] } -- non-modifier prefix feed(':silent tabedit %s/tw/to') @@ -1479,22 +1360,21 @@ describe("inccommand=nosplit", function() Inc substitution on | two lines | | - {15:~ }| - {15:~ }| + {15:~ }|*2 {11: }| :silent tabedit %s/t| w/to^ | ]]) end) - it("does not show window after toggling :set inccommand", function() - feed(":%s/tw/OKOK") - feed("<Esc>") - command("set icm=split") - feed(":%s/tw/OKOK") - feed("<Esc>") - command("set icm=nosplit") - feed(":%s/tw/OKOK") + it('does not show window after toggling :set inccommand', function() + feed(':%s/tw/OKOK') + feed('<Esc>') + command('set icm=split') + feed(':%s/tw/OKOK') + feed('<Esc>') + command('set icm=nosplit') + feed(':%s/tw/OKOK') poke_eventloop() screen:expect([[ Inc substitution on | @@ -1502,79 +1382,64 @@ describe("inccommand=nosplit", function() Inc substitution on | {12:OKOK}o lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :%s/tw/OKOK^ | ]]) end) it('never shows preview buffer', function() - feed_command("set hlsearch") + command('set hlsearch') - feed(":%s/tw") + feed(':%s/tw') screen:expect([[ Inc substitution on | {12:tw}o lines | Inc substitution on | {12:tw}o lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :%s/tw^ | ]]) - feed("/BM") + feed('/BM') screen:expect([[ Inc substitution on | {12:BM}o lines | Inc substitution on | {12:BM}o lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :%s/tw/BM^ | ]]) - feed("/") + feed('/') screen:expect([[ Inc substitution on | {12:BM}o lines | Inc substitution on | {12:BM}o lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :%s/tw/BM/^ | ]]) - feed("<enter>") + feed('<enter>') screen:expect([[ Inc substitution on | BMo lines | Inc substitution on | ^BMo lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :%s/tw/BM/ | ]]) end) - it("clears preview if non-previewable command is edited", function() + it('clears preview if non-previewable command is edited', function() -- Put a non-previewable command in history. - feed_command("echo 'foo'") + feed(":echo 'foo'<CR>") -- Start an incomplete :substitute command. - feed(":1,2s/t/X") + feed(':1,2s/t/X') screen:expect([[ Inc subs{12:X}itution on | @@ -1582,15 +1447,12 @@ describe("inccommand=nosplit", function() Inc substitution on | two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :1,2s/t/X^ | ]]) -- Select the previous command. - feed("<C-P>") + feed('<C-P>') -- Assert that preview was cleared. screen:expect([[ Inc substitution on | @@ -1598,15 +1460,12 @@ describe("inccommand=nosplit", function() Inc substitution on | two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :echo 'foo'^ | ]]) end) - it("does not execute trailing bar-separated commands #7494", function() + it('does not execute trailing bar-separated commands #7494', function() feed(':%s/two/three/g|q!') screen:expect([[ Inc substitution on | @@ -1614,16 +1473,13 @@ describe("inccommand=nosplit", function() Inc substitution on | {12:three} lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :%s/two/three/g|q!^ | ]]) eq(eval('v:null'), eval('v:exiting')) end) - it("does not break bar-separated command #8796", function() + it('does not break bar-separated command #8796', function() source([[ function! F() if v:false | return | endif @@ -1631,17 +1487,14 @@ describe("inccommand=nosplit", function() ]]) command('call timer_start(10, {-> F()}, {"repeat":-1})') feed(':%s/') - sleep(20) -- Allow some timer activity. + sleep(20) -- Allow some timer activity. screen:expect([[ Inc substitution on | two lines | Inc substitution on | two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :%s/^ | ]]) end) @@ -1649,19 +1502,21 @@ end) describe(":substitute, 'inccommand' with a failing expression", function() local screen - local cases = { "", "split", "nosplit" } + local cases = { '', 'split', 'nosplit' } local function refresh(case) clear() - screen = Screen.new(20,10) + screen = Screen.new(20, 10) common_setup(screen, case, default_text) end it('in the pattern does nothing', function() for _, case in pairs(cases) do refresh(case) - feed_command("set inccommand=" .. case) - feed(":silent! %s/tw\\(/LARD/<enter>") + command('set inccommand=' .. case) + feed(':silent! %s/tw\\(/LARD/') + poke_eventloop() + feed('<enter>') expect(default_text) end end) @@ -1669,13 +1524,15 @@ describe(":substitute, 'inccommand' with a failing expression", function() it('in the replacement deletes the matches', function() for _, case in pairs(cases) do refresh(case) - local replacements = { "\\='LARD", "\\=xx_novar__xx" } + local replacements = { "\\='LARD", '\\=xx_novar__xx' } for _, repl in pairs(replacements) do - feed_command("set inccommand=" .. case) - feed(":silent! %s/tw/" .. repl .. "/<enter>") - expect(default_text:gsub("tw", "")) - feed_command("undo") + command('set inccommand=' .. case) + feed(':silent! %s/tw/' .. repl .. '/') + poke_eventloop() + feed('<enter>') + expect(default_text:gsub('tw', '')) + command('undo') end end end) @@ -1689,12 +1546,7 @@ describe(":substitute, 'inccommand' with a failing expression", function() Inc substitution on | two lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 :100s/^ | ]]) @@ -1703,88 +1555,101 @@ describe(":substitute, 'inccommand' with a failing expression", function() Inc substitution on | two lines | ^ | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {14:E16: Invalid range} | ]]) end end) - end) describe("'inccommand' and :cnoremap", function() - local cases = { "", "split", "nosplit" } + local cases = { '', 'split', 'nosplit' } local screen local function refresh(case, visual) clear() - screen = visual and Screen.new(80,10) or nil + screen = visual and Screen.new(80, 10) or nil common_setup(screen, case, default_text) end it('work with remapped characters', function() for _, case in pairs(cases) do refresh(case) - local cmd = "%s/lines/LINES/g" + local cmd = '%s/lines/LINES/g' for i = 1, string.len(cmd) do local c = string.sub(cmd, i, i) - feed_command("cnoremap ".. c .. " " .. c) + command('cnoremap ' .. c .. ' ' .. c) end - feed_command(cmd) + feed(':' .. cmd) + poke_eventloop() + feed('<CR>') expect([[ Inc substitution on two LINES ]]) - end + end end) it('work when mappings move the cursor', function() for _, case in pairs(cases) do refresh(case) - feed_command("cnoremap ,S LINES/<left><left><left><left><left><left>") + command('cnoremap ,S LINES/<left><left><left><left><left><left>') - feed(":%s/lines/,Sor three <enter>") + feed(':%s/lines/') + poke_eventloop() + feed(',S') + poke_eventloop() + feed('or three <enter>') + poke_eventloop() expect([[ Inc substitution on two or three LINES ]]) - feed_command("cnoremap ;S /X/<left><left><left>") - feed(":%s/;SI<enter>") + command('cnoremap ;S /X/<left><left><left>') + feed(':%s/') + poke_eventloop() + feed(';S') + poke_eventloop() + feed('I<enter>') expect([[ Xnc substitution on two or three LXNES ]]) - feed_command("cnoremap ,T //Y/<left><left><left>") - feed(":%s,TX<enter>") + command('cnoremap ,T //Y/<left><left><left>') + feed(':%s') + poke_eventloop() + feed(',T') + poke_eventloop() + feed('X<enter>') expect([[ Ync substitution on two or three LYNES ]]) - feed_command("cnoremap ;T s//Z/<left><left><left>") - feed(":%;TY<enter>") + command('cnoremap ;T s//Z/<left><left><left>') + feed(':%') + poke_eventloop() + feed(';T') + poke_eventloop() + feed('Y<enter>') expect([[ Znc substitution on two or three LZNES ]]) - end + end end) it('still works with a broken mapping', function() for _, case in pairs(cases) do refresh(case, true) - feed_command("cnoremap <expr> x execute('bwipeout!')[-1].'x'") + command("cnoremap <expr> x execute('bwipeout!')[-1].'x'") - feed(":%s/tw/tox<enter>") - screen:expect{any=[[{14:^E565:]]} + feed(':%s/tw/tox<enter>') + screen:expect { any = [[{14:^E565:]] } feed('<c-c>') -- error thrown b/c of the mapping @@ -1799,20 +1664,24 @@ describe("'inccommand' and :cnoremap", function() it('work when temporarily moving the cursor', function() for _, case in pairs(cases) do refresh(case) - feed_command("cnoremap <expr> x cursor(1, 1)[-1].'x'") + command("cnoremap <expr> x cursor(1, 1)[-1].'x'") - feed(":%s/tw/tox/g<enter>") - expect(default_text:gsub("tw", "tox")) + feed(':%s/tw/tox') + poke_eventloop() + feed('/g<enter>') + expect(default_text:gsub('tw', 'tox')) end end) it("work when a mapping disables 'inccommand'", function() for _, case in pairs(cases) do refresh(case) - feed_command("cnoremap <expr> x execute('set inccommand=')[-1]") + command("cnoremap <expr> x execute('set inccommand=')[-1]") - feed(":%s/tw/toxa/g<enter>") - expect(default_text:gsub("tw", "toa")) + feed(':%s/tw/tox') + poke_eventloop() + feed('a/g<enter>') + expect(default_text:gsub('tw', 'toa')) end end) @@ -1822,12 +1691,12 @@ describe("'inccommand' and :cnoremap", function() source([[cnoremap x <C-\>eextend(g:, {'fo': getcmdline()}) \.fo<CR><C-c>:new<CR>:bw!<CR>:<C-r>=remove(g:, 'fo')<CR>x]]) - feed(":%s/tw/tox") - feed("/<enter>") - expect(default_text:gsub("tw", "tox")) + feed(':%s/tw/tox') + poke_eventloop() + feed('/<enter>') + expect(default_text:gsub('tw', 'tox')) end end) - end) describe("'inccommand' autocommands", function() @@ -1868,9 +1737,9 @@ describe("'inccommand' autocommands", function() } local function bufferlist(t) - local s = "" + local s = '' for _, buffer in pairs(t) do - s = s .. ", " .. tostring(buffer) + s = s .. ', ' .. tostring(buffer) end return s end @@ -1882,12 +1751,12 @@ describe("'inccommand' autocommands", function() end local function register_autocmd(event) - meths.set_var(event .. "_fired", {}) - feed_command("autocmd " .. event .. " * call add(g:" .. event .. "_fired, expand('<abuf>'))") + api.nvim_set_var(event .. '_fired', {}) + command('autocmd ' .. event .. ' * call add(g:' .. event .. "_fired, expand('<abuf>'))") end it('are not fired when splitting', function() - common_setup(nil, "split", default_text) + common_setup(nil, 'split', default_text) local eventsObserved = {} for event, _ in pairs(eventsExpected) do @@ -1895,162 +1764,112 @@ describe("'inccommand' autocommands", function() register_autocmd(event) end - feed(":%s/tw") + feed(':%s/tw') for event, _ in pairs(eventsExpected) do - eventsObserved[event].open = meths.get_var(event .. "_fired") - meths.set_var(event .. "_fired", {}) + eventsObserved[event].open = api.nvim_get_var(event .. '_fired') + api.nvim_set_var(event .. '_fired', {}) end - feed("/<enter>") + feed('/<enter>') for event, _ in pairs(eventsExpected) do - eventsObserved[event].close = meths.get_var(event .. "_fired") + eventsObserved[event].close = api.nvim_get_var(event .. '_fired') end for event, _ in pairs(eventsExpected) do - eq(event .. bufferlist(eventsExpected[event].open), - event .. bufferlist(eventsObserved[event].open)) - eq(event .. bufferlist(eventsExpected[event].close), - event .. bufferlist(eventsObserved[event].close)) + eq( + event .. bufferlist(eventsExpected[event].open), + event .. bufferlist(eventsObserved[event].open) + ) + eq( + event .. bufferlist(eventsExpected[event].close), + event .. bufferlist(eventsObserved[event].close) + ) end end) - end) describe("'inccommand' split windows", function() local screen local function refresh() clear() - screen = Screen.new(40,30) - common_setup(screen, "split", default_text) + screen = Screen.new(40, 30) + common_setup(screen, 'split', default_text) end it('work after more splits', function() refresh() - feed("gg") - feed_command("vsplit") - feed_command("split") - feed(":%s/tw") + feed('gg') + command('vsplit') + command('split') + feed(':%s/tw') screen:expect([[ Inc substitution on │Inc substitution on| {12:tw}o lines │{12:tw}o lines | │ | - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| + {15:~ }│{15:~ }|*11 {11:[No Name] [+] }│{15:~ }| Inc substitution on │{15:~ }| {12:tw}o lines │{15:~ }| │{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| + {15:~ }│{15:~ }|*2 {10:[No Name] [+] [No Name] [+] }| |2| {12:tw}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/tw^ | ]]) - feed("<esc>") - feed_command("only") - feed_command("split") - feed_command("vsplit") + feed('<esc>') + command('only') + command('split') + command('vsplit') - feed(":%s/tw") + feed(':%s/tw') screen:expect([[ Inc substitution on │Inc substitution on| {12:tw}o lines │{12:tw}o lines | │ | - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| - {15:~ }│{15:~ }| + {15:~ }│{15:~ }|*11 {11:[No Name] [+] }{10:[No Name] [+] }| Inc substitution on | {12:tw}o lines | | - {15:~ }| - {15:~ }| + {15:~ }|*2 {10:[No Name] [+] }| |2| {12:tw}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/tw^ | ]]) end) local settings = { - "splitbelow", - "splitright", - "noequalalways", - "equalalways eadirection=ver", - "equalalways eadirection=hor", - "equalalways eadirection=both", + 'splitbelow', + 'splitright', + 'noequalalways', + 'equalalways eadirection=ver', + 'equalalways eadirection=hor', + 'equalalways eadirection=both', } - it("are not affected by various settings", function() + it('are not affected by various settings', function() for _, setting in pairs(settings) do refresh() - feed_command("set " .. setting) + command('set ' .. setting) - feed(":%s/tw") + feed(':%s/tw') screen:expect([[ Inc substitution on | {12:tw}o lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*17 {11:[No Name] [+] }| |2| {12:tw}o lines | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/tw^ | ]]) @@ -2060,7 +1879,7 @@ describe("'inccommand' split windows", function() it("don't open if there's not enough room", function() refresh() screen:try_resize(40, 3) - feed("gg:%s/tw") + feed('gg:%s/tw') screen:expect([[ Inc substitution on | {12:tw}o lines | @@ -2074,43 +1893,43 @@ describe("'inccommand' with 'gdefault'", function() clear() end) - it("does not lock up #7244", function() - common_setup(nil, "nosplit", "{") - command("set gdefault") - feed(":s/{\\n") - eq({mode='c', blocking=false}, nvim("get_mode")) - feed("/A<Enter>") - expect("A") - eq({mode='n', blocking=false}, nvim("get_mode")) + it('does not lock up #7244', function() + common_setup(nil, 'nosplit', '{') + command('set gdefault') + feed(':s/{\\n') + eq({ mode = 'c', blocking = false }, api.nvim_get_mode()) + feed('/A<Enter>') + expect('A') + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) end) - it("with multiline text and range, does not lock up #7244", function() - common_setup(nil, "nosplit", "{\n\n{") - command("set gdefault") - feed(":%s/{\\n") - eq({mode='c', blocking=false}, nvim("get_mode")) - feed("/A<Enter>") - expect("A\nA") - eq({mode='n', blocking=false}, nvim("get_mode")) + it('with multiline text and range, does not lock up #7244', function() + common_setup(nil, 'nosplit', '{\n\n{') + command('set gdefault') + feed(':%s/{\\n') + eq({ mode = 'c', blocking = false }, api.nvim_get_mode()) + feed('/A<Enter>') + expect('A\nA') + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) end) - it("does not crash on zero-width matches #7485", function() - common_setup(nil, "split", default_text) - command("set gdefault") - feed("gg") - feed("Vj") - feed(":s/\\%V") - eq({mode='c', blocking=false}, nvim("get_mode")) - feed("<Esc>") - eq({mode='n', blocking=false}, nvim("get_mode")) + it('does not crash on zero-width matches #7485', function() + common_setup(nil, 'split', default_text) + command('set gdefault') + feed('gg') + feed('Vj') + feed(':s/\\%V') + eq({ mode = 'c', blocking = false }, api.nvim_get_mode()) + feed('<Esc>') + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) end) - it("removes highlights after abort for a zero-width match", function() - local screen = Screen.new(30,5) - common_setup(screen, "nosplit", default_text) - command("set gdefault") + it('removes highlights after abort for a zero-width match', function() + local screen = Screen.new(30, 5) + common_setup(screen, 'nosplit', default_text) + command('set gdefault') - feed(":%s/\\%1c/a/") + feed(':%s/\\%1c/a/') screen:expect([[ {12:a}Inc substitution on | {12:a}two lines | @@ -2119,7 +1938,7 @@ describe("'inccommand' with 'gdefault'", function() :%s/\%1c/a/^ | ]]) - feed("<Esc>") + feed('<Esc>') screen:expect([[ Inc substitution on | two lines | @@ -2128,21 +1947,20 @@ describe("'inccommand' with 'gdefault'", function() | ]]) end) - end) -describe(":substitute", function() +describe(':substitute', function() local screen before_each(function() clear() - screen = Screen.new(30,15) + screen = Screen.new(30, 15) end) - it("inccommand=split, highlights multiline substitutions", function() - common_setup(screen, "split", multiline_text) - feed("gg") + it('inccommand=split, highlights multiline substitutions', function() + common_setup(screen, 'split', multiline_text) + feed('gg') - feed(":%s/2\\_.*X") + feed(':%s/2\\_.*X') screen:expect([[ 1 {12:2 3} | {12:A B C} | @@ -2154,33 +1972,25 @@ describe(":substitute", function() |2|{12: A B C} | |3|{12: 4 5 6} | |4|{12: X} Y Z | - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*3 {10:[Preview] }| :%s/2\_.*X^ | ]]) - feed("/MMM") + feed('/MMM') screen:expect([[ 1 {12:MMM} Y Z | 7 8 9 | | - {15:~ }| - {15:~ }| + {15:~ }|*2 {11:[No Name] [+] }| |1| 1 {12:MMM} Y Z | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/2\_.*X/MMM^ | ]]) - feed("\\rK\\rLLL") + feed('\\rK\\rLLL') screen:expect([[ 1 {12:MMM} | {12:K} | @@ -2191,113 +2001,77 @@ describe(":substitute", function() |1| 1 {12:MMM} | |2|{12: K} | |3|{12: LLL} Y Z | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 {10:[Preview] }| :%s/2\_.*X/MMM\rK\rLLL^ | ]]) end) - it("inccommand=nosplit, highlights multiline substitutions", function() - common_setup(screen, "nosplit", multiline_text) - feed("gg") + it('inccommand=nosplit, highlights multiline substitutions', function() + common_setup(screen, 'nosplit', multiline_text) + feed('gg') - feed(":%s/2\\_.*X/MMM") + feed(':%s/2\\_.*X/MMM') screen:expect([[ 1 {12:MMM} Y Z | 7 8 9 | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*11 :%s/2\_.*X/MMM^ | ]]) - feed("\\rK\\rLLL") + feed('\\rK\\rLLL') screen:expect([[ 1 {12:MMM} | {12:K} | {12:LLL} Y Z | 7 8 9 | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*9 :%s/2\_.*X/MMM\rK\rLLL^ | ]]) end) - it("inccommand=split, highlights multiple matches on a line", function() - common_setup(screen, "split", multimatch_text) - command("set gdefault") - feed("gg") + it('inccommand=split, highlights multiple matches on a line', function() + common_setup(screen, 'split', multimatch_text) + command('set gdefault') + feed('gg') - feed(":%s/a/XLK") + feed(':%s/a/XLK') screen:expect([[ {12:XLK} bdc e{12:XLK}e {12:XLK} fgl lzi{12:XLK} r| x | | - {15:~ }| - {15:~ }| + {15:~ }|*2 {11:[No Name] [+] }| |1| {12:XLK} bdc e{12:XLK}e {12:XLK} fgl lzi{12:X}| {12:LK} r | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :%s/a/XLK^ | ]]) end) - it("inccommand=nosplit, highlights multiple matches on a line", function() - common_setup(screen, "nosplit", multimatch_text) - command("set gdefault") - feed("gg") + it('inccommand=nosplit, highlights multiple matches on a line', function() + common_setup(screen, 'nosplit', multimatch_text) + command('set gdefault') + feed('gg') - feed(":%s/a/XLK") + feed(':%s/a/XLK') screen:expect([[ {12:XLK} bdc e{12:XLK}e {12:XLK} fgl lzi{12:XLK} r| x | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*11 :%s/a/XLK^ | ]]) end) - it("inccommand=split, with \\zs", function() - common_setup(screen, "split", multiline_text) - feed("gg") + it('inccommand=split, with \\zs', function() + common_setup(screen, 'split', multiline_text) + feed('gg') - feed(":%s/[0-9]\\n\\zs[A-Z]/OKO") + feed(':%s/[0-9]\\n\\zs[A-Z]/OKO') screen:expect([[ {12:OKO} B C | 4 5 6 | @@ -2309,19 +2083,17 @@ describe(":substitute", function() |2| {12:OKO} B C | |3| 4 5 6 | |4| {12:OKO} Y Z | - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*3 {10:[Preview] }| :%s/[0-9]\n\zs[A-Z]/OKO^ | ]]) end) - it("inccommand=nosplit, with \\zs", function() - common_setup(screen, "nosplit", multiline_text) - feed("gg") + it('inccommand=nosplit, with \\zs', function() + common_setup(screen, 'nosplit', multiline_text) + feed('gg') - feed(":%s/[0-9]\\n\\zs[A-Z]/OKO") + feed(':%s/[0-9]\\n\\zs[A-Z]/OKO') screen:expect([[ 1 2 3 | {12:OKO} B C | @@ -2329,65 +2101,41 @@ describe(":substitute", function() {12:OKO} Y Z | 7 8 9 | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*8 :%s/[0-9]\n\zs[A-Z]/OKO^ | ]]) end) - it("inccommand=split, substitutions of different length", function() - common_setup(screen, "split", "T T123 T2T TTT T090804\nx") + it('inccommand=split, substitutions of different length', function() + common_setup(screen, 'split', 'T T123 T2T TTT T090804\nx') - feed(":%s/T\\([0-9]\\+\\)/\\1\\1/g") + feed(':%s/T\\([0-9]\\+\\)/\\1\\1/g') screen:expect([[ T {12:123123} {12:22}T TTT {12:090804090804} | x | - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*3 {11:[No Name] [+] }| |1| T {12:123123} {12:22}T TTT {12:090804090}| {12:804} | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 {10:[Preview] }| :%s/T\([0-9]\+\)/\1\1/g^ | ]]) end) - it("inccommand=nosplit, substitutions of different length", function() - common_setup(screen, "nosplit", "T T123 T2T TTT T090804\nx") + it('inccommand=nosplit, substitutions of different length', function() + common_setup(screen, 'nosplit', 'T T123 T2T TTT T090804\nx') - feed(":%s/T\\([0-9]\\+\\)/\\1\\1/g") + feed(':%s/T\\([0-9]\\+\\)/\\1\\1/g') screen:expect([[ T {12:123123} {12:22}T TTT {12:090804090804} | x | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*12 :%s/T\([0-9]\+\)/\1\1/g^ | ]]) end) - it("inccommand=split, contraction of lines", function() + it('inccommand=split, contraction of lines', function() local text = [[ T T123 T T123 T2T TT T23423424 x @@ -2396,8 +2144,8 @@ describe(":substitute", function() alx ]] - common_setup(screen, "split", text) - feed(":%s/[QR]\\n") + common_setup(screen, 'split', text) + feed(':%s/[QR]\\n') screen:expect([[ afa {12:Q} | adf la;lkd {12:R} | @@ -2408,15 +2156,12 @@ describe(":substitute", function() |3| afa {12:Q} | |4|{12: }adf la;lkd {12:R} | |5|{12: }alx | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 {10:[Preview] }| :%s/[QR]\n^ | ]]) - feed("/KKK") + feed('/KKK') screen:expect([[ T T123 T T123 T2T TT T23423424| x | @@ -2425,18 +2170,13 @@ describe(":substitute", function() {15:~ }| {11:[No Name] [+] }| |3| afa {12:KKK}adf la;lkd {12:KKK}alx | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/[QR]\n/KKK^ | ]]) end) - it("inccommand=nosplit, contraction of lines", function() + it('inccommand=nosplit, contraction of lines', function() local text = [[ T T123 T T123 T2T TT T23423424 x @@ -2445,28 +2185,19 @@ describe(":substitute", function() alx ]] - common_setup(screen, "nosplit", text) - feed(":%s/[QR]\\n/KKK") + common_setup(screen, 'nosplit', text) + feed(':%s/[QR]\\n/KKK') screen:expect([[ T T123 T T123 T2T TT T23423424| x | afa {12:KKK}adf la;lkd {12:KKK}alx | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*10 :%s/[QR]\n/KKK^ | ]]) end) - it("inccommand=split, contraction of two subsequent NL chars", function() + it('inccommand=split, contraction of two subsequent NL chars', function() local text = [[ AAA AA @@ -2478,9 +2209,10 @@ describe(":substitute", function() -- This used to crash, but more than 20 highlight entries are required -- to reproduce it (so that the marktree has multiple nodes) - common_setup(screen, "split", string.rep(text,10)) - feed(":%s/\\n\\n/<c-v><c-m>/g") - screen:expect{grid=[[ + common_setup(screen, 'split', string.rep(text, 10)) + feed(':%s/\\n\\n/<c-v><c-m>/g') + screen:expect { + grid = [[ CCC CC | AAA AA | BBB BB | @@ -2496,11 +2228,12 @@ describe(":substitute", function() | 7|{12: }AAA AA | {10:[Preview] }| :%s/\n\n/{17:^M}/g^ | - ]]} + ]], + } assert_alive() end) - it("inccommand=nosplit, contraction of two subsequent NL chars", function() + it('inccommand=nosplit, contraction of two subsequent NL chars', function() local text = [[ AAA AA @@ -2510,9 +2243,10 @@ describe(":substitute", function() ]] - common_setup(screen, "nosplit", string.rep(text,10)) - feed(":%s/\\n\\n/<c-v><c-m>/g") - screen:expect{grid=[[ + common_setup(screen, 'nosplit', string.rep(text, 10)) + feed(':%s/\\n\\n/<c-v><c-m>/g') + screen:expect { + grid = [[ CCC CC | AAA AA | BBB BB | @@ -2528,13 +2262,14 @@ describe(":substitute", function() CCC CC | | :%s/\n\n/{17:^M}/g^ | - ]]} + ]], + } assert_alive() end) - it("inccommand=split, multibyte text", function() - common_setup(screen, "split", multibyte_text) - feed(":%s/£.*ѫ/X¥¥") + it('inccommand=split, multibyte text', function() + common_setup(screen, 'split', multibyte_text) + feed(':%s/£.*ѫ/X¥¥') screen:expect([[ a{12:X¥¥}¥KOL | £ ¥ libm | @@ -2545,15 +2280,12 @@ describe(":substitute", function() |1| {12:X¥¥} PEPPERS | |2| {12:X¥¥} | |3| a{12:X¥¥}¥KOL | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 {10:[Preview] }| :%s/£.*ѫ/X¥¥^ | ]]) - feed("\\ra££ ¥") + feed('\\ra££ ¥') screen:expect([[ a{12:X¥¥} | {12:a££ ¥}¥KOL | @@ -2573,9 +2305,9 @@ describe(":substitute", function() ]]) end) - it("inccommand=nosplit, multibyte text", function() - common_setup(screen, "nosplit", multibyte_text) - feed(":%s/£.*ѫ/X¥¥") + it('inccommand=nosplit, multibyte text', function() + common_setup(screen, 'nosplit', multibyte_text) + feed(':%s/£.*ѫ/X¥¥') screen:expect([[ {12:X¥¥} PEPPERS | {12:X¥¥} | @@ -2583,18 +2315,11 @@ describe(":substitute", function() £ ¥ libm | £ ¥ | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*8 :%s/£.*ѫ/X¥¥^ | ]]) - feed("\\ra££ ¥") + feed('\\ra££ ¥') screen:expect([[ {12:X¥¥} | {12:a££ ¥} PEPPERS | @@ -2605,20 +2330,16 @@ describe(":substitute", function() £ ¥ libm | £ ¥ | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*5 :%s/£.*ѫ/X¥¥\ra££ ¥^ | ]]) end) - it("inccommand=split, small cmdwinheight", function() - common_setup(screen, "split", long_multiline_text) - command("set cmdwinheight=2") + it('inccommand=split, small cmdwinheight', function() + common_setup(screen, 'split', long_multiline_text) + command('set cmdwinheight=2') - feed(":%s/[a-z]") + feed(':%s/[a-z]') screen:expect([[ X Y Z | 7 8 9 | @@ -2637,7 +2358,7 @@ describe(":substitute", function() :%s/[a-z]^ | ]]) - feed("/JLKR £") + feed('/JLKR £') screen:expect([[ X Y Z | 7 8 9 | @@ -2656,7 +2377,7 @@ describe(":substitute", function() :%s/[a-z]/JLKR £^ | ]]) - feed("\\rѫ ab \\rXXXX") + feed('\\rѫ ab \\rXXXX') screen:expect([[ 7 8 9 | K L M | @@ -2676,11 +2397,11 @@ describe(":substitute", function() ]]) end) - it("inccommand=split, large cmdwinheight", function() - common_setup(screen, "split", long_multiline_text) - command("set cmdwinheight=11") + it('inccommand=split, large cmdwinheight', function() + common_setup(screen, 'split', long_multiline_text) + command('set cmdwinheight=11') - feed(":%s/. .$") + feed(':%s/. .$') screen:expect([[ t {12:œ ¥} | {11:[No Name] [+] }| @@ -2699,7 +2420,7 @@ describe(":substitute", function() :%s/. .$^ | ]]) - feed("/ YYY") + feed('/ YYY') screen:expect([[ t {12: YYY} | {11:[No Name] [+] }| @@ -2718,7 +2439,7 @@ describe(":substitute", function() :%s/. .$/ YYY^ | ]]) - feed("\\r KKK") + feed('\\r KKK') screen:expect([[ a {12: YYY} | {11:[No Name] [+] }| @@ -2738,28 +2459,22 @@ describe(":substitute", function() ]]) end) - it("inccommand=split, lookaround", function() - common_setup(screen, "split", "something\neverything\nsomeone") + it('inccommand=split, lookaround', function() + common_setup(screen, 'split', 'something\neverything\nsomeone') feed([[:%s/\(some\)\@<lt>=thing/one/]]) screen:expect([[ some{12:one} | everything | someone | - {15:~ }| - {15:~ }| + {15:~ }|*2 {11:[No Name] [+] }| |1| some{12:one} | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/\(some\)\@<=thing/one/^ | ]]) - feed("<C-c>") + feed('<C-c>') feed('gg') poke_eventloop() feed([[:%s/\(some\)\@<lt>!thing/one/]]) @@ -2767,16 +2482,10 @@ describe(":substitute", function() something | every{12:one} | someone | - {15:~ }| - {15:~ }| + {15:~ }|*2 {11:[No Name] [+] }| |2| every{12:one} | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/\(some\)\@<!thing/one/^ | ]]) @@ -2788,16 +2497,10 @@ describe(":substitute", function() {12:every}thing | everything | someone | - {15:~ }| - {15:~ }| + {15:~ }|*2 {11:[No Name] [+] }| |1| {12:every}thing | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/some\(thing\)\@=/every/^ | ]]) @@ -2809,16 +2512,10 @@ describe(":substitute", function() something | everything | {12:every}one | - {15:~ }| - {15:~ }| + {15:~ }|*2 {11:[No Name] [+] }| |3| {12:every}one | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*6 {10:[Preview] }| :%s/some\(thing\)\@!/every/^ | ]]) @@ -2826,7 +2523,7 @@ describe(":substitute", function() it("doesn't prompt to swap cmd range", function() screen = Screen.new(50, 8) -- wide to avoid hit-enter prompt - common_setup(screen, "split", default_text) + common_setup(screen, 'split', default_text) feed(':2,1s/tw/MO/g') -- substitution preview should have been made, without prompting @@ -2834,9 +2531,7 @@ describe(":substitute", function() {12:MO}o lines | {11:[No Name] [+] }| |2| {12:MO}o lines | - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*3 {10:[Preview] }| :2,1s/tw/MO/g^ | ]]) @@ -2847,9 +2542,7 @@ describe(":substitute", function() {12:MO}o lines | {11:[No Name] [+] }| |2| {12:MO}o lines | - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*3 {10:[Preview] }| {13:Backwards range given, OK to swap (y/n)?}^ | ]]) @@ -2859,10 +2552,7 @@ describe(":substitute", function() Inc substitution on | ^MOo lines | | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 {13:Backwards range given, OK to swap (y/n)?}y | ]]) end) @@ -2874,19 +2564,19 @@ it(':substitute with inccommand during :terminal activity', function() end retry(2, 40000, function() clear() - local screen = Screen.new(30,15) + local screen = Screen.new(30, 15) - command("set cmdwinheight=3") + command('set cmdwinheight=3') feed(([[:terminal "%s" REP 5000 xxx<cr>]]):format(testprg('shell-test'))) command('file term') - feed('G') -- Follow :terminal output. + feed('G') -- Follow :terminal output. command('new') common_setup(screen, 'split', 'foo bar baz\nbar baz fox\nbar foo baz') command('wincmd =') feed('gg') feed(':%s/foo/ZZZ') - sleep(20) -- Allow some terminal activity. + sleep(20) -- Allow some terminal activity. poke_eventloop() screen:sleep(0) screen:expect_unchanged() @@ -2895,7 +2585,7 @@ end) it(':substitute with inccommand, timer-induced :redraw #9777', function() clear() - local screen = Screen.new(30,12) + local screen = Screen.new(30, 12) command('set cmdwinheight=3') command('call timer_start(10, {-> execute("redraw")}, {"repeat":-1})') command('call timer_start(10, {-> execute("redrawstatus")}, {"repeat":-1})') @@ -2903,14 +2593,12 @@ it(':substitute with inccommand, timer-induced :redraw #9777', function() feed('gg') feed(':%s/foo/ZZZ') - sleep(20) -- Allow some timer activity. + sleep(20) -- Allow some timer activity. screen:expect([[ {12:ZZZ} bar baz | bar baz fox | bar {12:ZZZ} baz | - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*3 {11:[No Name] [+] }| |1| {12:ZZZ} bar baz | |3| bar {12:ZZZ} baz | @@ -2922,12 +2610,17 @@ end) it(':substitute with inccommand, allows :redraw before first separator is typed #18857', function() clear() - local screen = Screen.new(30,6) + local screen = Screen.new(30, 6) common_setup(screen, 'split', 'foo bar baz\nbar baz fox\nbar foo baz') command('hi! link NormalFloat CursorLine') - local float_buf = meths.create_buf(false, true) - meths.open_win(float_buf, false, { - relative = 'editor', height = 1, width = 5, row = 3, col = 0, focusable = false, + local float_buf = api.nvim_create_buf(false, true) + api.nvim_open_win(float_buf, false, { + relative = 'editor', + height = 1, + width = 5, + row = 3, + col = 0, + focusable = false, }) feed(':') screen:expect([[ @@ -2947,7 +2640,7 @@ it(':substitute with inccommand, allows :redraw before first separator is typed {15:~ }| :%s^ | ]]) - meths.buf_set_lines(float_buf, 0, -1, true, {'foo'}) + api.nvim_buf_set_lines(float_buf, 0, -1, true, { 'foo' }) command('redraw') screen:expect([[ foo bar baz | @@ -2966,10 +2659,7 @@ it(':substitute with inccommand, does not crash if range contains invalid marks' feed([[:'a,'bs]]) screen:expect([[ test | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :'a,'bs^ | ]]) -- v:errmsg shouldn't be set either before the first separator is typed @@ -2977,10 +2667,7 @@ it(':substitute with inccommand, does not crash if range contains invalid marks' feed('/') screen:expect([[ test | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :'a,'bs/^ | ]]) end) @@ -3030,17 +2717,14 @@ it(':substitute with inccommand, no unnecessary redraw if preview is not shown', -- now inccommand is shown, so screen is redrawn screen:expect([[ {12:test} | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :s/test^ | ]]) end) it(":substitute doesn't crash with inccommand, if undo is empty #12932", function() clear() - local screen = Screen.new(10,5) + local screen = Screen.new(10, 5) command('set undolevels=-1') common_setup(screen, 'split', 'test') feed(':%s/test') @@ -3050,9 +2734,7 @@ it(":substitute doesn't crash with inccommand, if undo is empty #12932", functio feed('f') screen:expect([[ {12:f} | - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*3 :%s/test/f^ | ]]) assert_alive() @@ -3062,7 +2744,7 @@ it(':substitute with inccommand works properly if undo is not synced #20029', fu clear() local screen = Screen.new(30, 6) common_setup(screen, 'nosplit', 'foo\nbar\nbaz') - meths.set_keymap('x', '<F2>', '<Esc>`<Oaaaaa asdf<Esc>`>obbbbb asdf<Esc>V`<k:s/asdf/', {}) + api.nvim_set_keymap('x', '<F2>', '<Esc>`<Oaaaaa asdf<Esc>`>obbbbb asdf<Esc>V`<k:s/asdf/', {}) feed('gg0<C-V>lljj<F2>') screen:expect([[ aaaaa | @@ -3127,10 +2809,31 @@ end) it('long :%s/ with inccommand does not collapse cmdline', function() clear() - local screen = Screen.new(10,5) + local screen = Screen.new(10, 5) common_setup(screen, 'nosplit') - feed(':%s/AAAAAAA', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', - 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A') + feed( + ':%s/AAAAAAA', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A', + 'A' + ) screen:expect([[ | {11: }| @@ -3147,10 +2850,7 @@ it("with 'inccommand' typing invalid `={expr}` does not show error", function() feed(':edit `=`') screen:expect([[ | - {15:~ }| - {15:~ }| - {15:~ }| - {15:~ }| + {15:~ }|*4 :edit `=`^ | ]]) end) @@ -3195,3 +2895,54 @@ it("'inccommand' cannot be changed during preview #23136", function() feed(':%s/foo/bar<C-E><C-E><C-E>') assert_alive() end) + +it("'inccommand' value can be changed multiple times #27086", function() + clear() + local screen = Screen.new(30, 20) + common_setup(screen, 'split', 'foo1\nfoo2\nfoo3') + for _ = 1, 3 do + feed(':%s/foo/bar') + screen:expect([[ + {12:bar}1 | + {12:bar}2 | + {12:bar}3 | + {15:~ }|*7 + {11:[No Name] [+] }| + |1| {12:bar}1 | + |2| {12:bar}2 | + |3| {12:bar}3 | + {15:~ }|*4 + {10:[Preview] }| + :%s/foo/bar^ | + ]]) + feed('<Esc>') + command('set inccommand=nosplit') + feed(':%s/foo/bar') + screen:expect([[ + {12:bar}1 | + {12:bar}2 | + {12:bar}3 | + {15:~ }|*16 + :%s/foo/bar^ | + ]]) + feed('<Esc>') + command('set inccommand=split') + end +end) + +it("'inccommand' disables preview if preview buffer can't be created #27086", function() + clear() + api.nvim_buf_set_name(0, '[Preview]') + local screen = Screen.new(30, 20) + common_setup(screen, 'split', 'foo1\nfoo2\nfoo3') + eq('split', api.nvim_get_option_value('inccommand', {})) + feed(':%s/foo/bar') + screen:expect([[ + {12:bar}1 | + {12:bar}2 | + {12:bar}3 | + {15:~ }|*16 + :%s/foo/bar^ | + ]]) + eq('nosplit', api.nvim_get_option_value('inccommand', {})) +end) diff --git a/test/functional/ui/inccommand_user_spec.lua b/test/functional/ui/inccommand_user_spec.lua index da7508fad1..a714df72b7 100644 --- a/test/functional/ui/inccommand_user_spec.lua +++ b/test/functional/ui/inccommand_user_spec.lua @@ -1,6 +1,8 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') +local api = helpers.api local clear = helpers.clear +local eq = helpers.eq local exec_lua = helpers.exec_lua local insert = helpers.insert local feed = helpers.feed @@ -236,16 +238,16 @@ describe("'inccommand' for user commands", function() clear() screen = Screen.new(40, 17) screen:set_default_attr_ids({ - [1] = {background = Screen.colors.Yellow1}, - [2] = {foreground = Screen.colors.Blue1, bold = true}, - [3] = {reverse = true}, - [4] = {reverse = true, bold = true}, - [5] = {foreground = Screen.colors.Blue}, + [1] = { background = Screen.colors.Yellow1 }, + [2] = { foreground = Screen.colors.Blue1, bold = true }, + [3] = { reverse = true }, + [4] = { reverse = true, bold = true }, + [5] = { foreground = Screen.colors.Blue }, }) screen:attach() exec_lua(setup_replace_cmd) command('set cmdwinheight=5') - insert[[ + insert [[ text on line 1 more text on line 2 oh no, even more text @@ -270,13 +272,7 @@ describe("'inccommand' for user commands", function() why won't it stop | make the {1:cats} stop | | - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*7 :Replace text cats^ | ]]) end) @@ -318,13 +314,7 @@ describe("'inccommand' for user commands", function() why won't it stop | make the text stop | ^ | - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*7 | ]]) end) @@ -342,13 +332,7 @@ describe("'inccommand' for user commands", function() why won't it stop | make the cats stop | ^ | - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*7 :Replace text cats | ]]) end) @@ -366,13 +350,7 @@ describe("'inccommand' for user commands", function() why won't it stop | make the text stop | | - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*7 :.Replace text cats^ | ]]) end) @@ -425,13 +403,7 @@ describe("'inccommand' for user commands", function() why won't it stop | make the cats stop | | - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*7 :C^ | ]]) assert_alive() @@ -481,13 +453,7 @@ describe("'inccommand' for user commands", function() why won't it stop | make the text stop | a.a.a.a. | - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*7 :Test a.a.a.a.^ | ]]) feed('<C-V><Esc>u') @@ -501,13 +467,7 @@ describe("'inccommand' for user commands", function() why won't it stop | make the text stop | a.a.a. | - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*7 :Test a.a.a.a.{5:^[}u^ | ]]) feed('<Esc>') @@ -521,13 +481,7 @@ describe("'inccommand' for user commands", function() why won't it stop | make the text stop | ^ | - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*7 | ]]) end @@ -543,6 +497,22 @@ describe("'inccommand' for user commands", function() test_preview_break_undo() end) end) + + it('disables preview if preview buffer cannot be created #27086', function() + command('set inccommand=split') + api.nvim_buf_set_name(0, '[Preview]') + exec_lua([[ + vim.api.nvim_create_user_command('Test', function() end, { + nargs = '*', + preview = function(_, _, _) + return 2 + end + }) + ]]) + eq('split', api.nvim_get_option_value('inccommand', {})) + feed(':Test') + eq('nosplit', api.nvim_get_option_value('inccommand', {})) + end) end) describe("'inccommand' with multiple buffers", function() @@ -552,21 +522,21 @@ describe("'inccommand' with multiple buffers", function() clear() screen = Screen.new(40, 17) screen:set_default_attr_ids({ - [1] = {background = Screen.colors.Yellow1}, - [2] = {foreground = Screen.colors.Blue1, bold = true}, - [3] = {reverse = true}, - [4] = {reverse = true, bold = true} + [1] = { background = Screen.colors.Yellow1 }, + [2] = { foreground = Screen.colors.Blue1, bold = true }, + [3] = { reverse = true }, + [4] = { reverse = true, bold = true }, }) screen:attach() exec_lua(setup_replace_cmd) command('set cmdwinheight=10') - insert[[ + insert [[ foo bar baz bar baz foo baz foo bar ]] command('vsplit | enew') - insert[[ + insert [[ bar baz foo baz foo bar foo bar baz @@ -581,17 +551,7 @@ describe("'inccommand' with multiple buffers", function() baz {1:bar} bar │ bar baz {1:bar} | {1:bar} bar baz │ baz {1:bar} bar | │ | - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| + {2:~ }│{2:~ }|*11 {4:[No Name] [+] }{3:[No Name] [+] }| :Replace foo bar^ | ]]) @@ -601,17 +561,7 @@ describe("'inccommand' with multiple buffers", function() baz bar bar │ bar baz bar | bar bar baz │ baz bar bar | ^ │ | - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| + {2:~ }│{2:~ }|*11 {4:[No Name] [+] }{3:[No Name] [+] }| :Replace foo bar | ]]) @@ -645,17 +595,7 @@ describe("'inccommand' with multiple buffers", function() baz bar bar │ bar baz bar | bar bar baz │ baz bar bar | ^ │ | - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| - {2:~ }│{2:~ }| + {2:~ }│{2:~ }|*11 {4:[No Name] [+] }{3:[No Name] [+] }| :Replace foo bar | ]]) diff --git a/test/functional/ui/input_spec.lua b/test/functional/ui/input_spec.lua index 05d55b94fb..b2899bf82d 100644 --- a/test/functional/ui/input_spec.lua +++ b/test/functional/ui/input_spec.lua @@ -4,10 +4,10 @@ local feed, next_msg, eq = helpers.feed, helpers.next_msg, helpers.eq local command = helpers.command local expect = helpers.expect local curbuf_contents = helpers.curbuf_contents -local meths = helpers.meths +local api = helpers.api local exec_lua = helpers.exec_lua local write_file = helpers.write_file -local funcs = helpers.funcs +local fn = helpers.fn local eval = helpers.eval local Screen = require('test.functional.ui.screen') @@ -15,17 +15,24 @@ before_each(clear) describe('mappings', function() local add_mapping = function(mapping, send) - local cmd = "nnoremap "..mapping.." :call rpcnotify(1, 'mapped', '" - ..send:gsub('<', '<lt>').."')<cr>" + local cmd = 'nnoremap ' + .. mapping + .. " :call rpcnotify(1, 'mapped', '" + .. send:gsub('<', '<lt>') + .. "')<cr>" feed_command(cmd) end local check_mapping = function(mapping, expected) feed(mapping) - eq({'notification', 'mapped', {expected}}, next_msg()) + eq({ 'notification', 'mapped', { expected } }, next_msg()) end before_each(function() + add_mapping('<A-l>', '<A-l>') + add_mapping('<A-L>', '<A-L>') + add_mapping('<D-l>', '<D-l>') + add_mapping('<D-L>', '<D-L>') add_mapping('<C-L>', '<C-L>') add_mapping('<C-S-L>', '<C-S-L>') add_mapping('<s-up>', '<s-up>') @@ -35,30 +42,40 @@ describe('mappings', function() add_mapping('<c-s-a-d-up>', '<c-s-a-d-up>') add_mapping('<c-d-a>', '<c-d-a>') add_mapping('<d-1>', '<d-1>') - add_mapping('<khome>','<khome>') - add_mapping('<kup>','<kup>') - add_mapping('<kpageup>','<kpageup>') - add_mapping('<kleft>','<kleft>') - add_mapping('<korigin>','<korigin>') - add_mapping('<kright>','<kright>') - add_mapping('<kend>','<kend>') - add_mapping('<kdown>','<kdown>') - add_mapping('<kpagedown>','<kpagedown>') - add_mapping('<kinsert>','<kinsert>') - add_mapping('<kdel>','<kdel>') - add_mapping('<kdivide>','<kdivide>') - add_mapping('<kmultiply>','<kmultiply>') - add_mapping('<kminus>','<kminus>') - add_mapping('<kplus>','<kplus>') - add_mapping('<kenter>','<kenter>') - add_mapping('<kcomma>','<kcomma>') - add_mapping('<kequal>','<kequal>') - add_mapping('<f38>','<f38>') - add_mapping('<f63>','<f63>') + add_mapping('<khome>', '<khome>') + add_mapping('<kup>', '<kup>') + add_mapping('<kpageup>', '<kpageup>') + add_mapping('<kleft>', '<kleft>') + add_mapping('<korigin>', '<korigin>') + add_mapping('<kright>', '<kright>') + add_mapping('<kend>', '<kend>') + add_mapping('<kdown>', '<kdown>') + add_mapping('<kpagedown>', '<kpagedown>') + add_mapping('<kinsert>', '<kinsert>') + add_mapping('<kdel>', '<kdel>') + add_mapping('<kdivide>', '<kdivide>') + add_mapping('<kmultiply>', '<kmultiply>') + add_mapping('<kminus>', '<kminus>') + add_mapping('<kplus>', '<kplus>') + add_mapping('<kenter>', '<kenter>') + add_mapping('<kcomma>', '<kcomma>') + add_mapping('<kequal>', '<kequal>') + add_mapping('<f38>', '<f38>') + add_mapping('<f63>', '<f63>') end) it('ok', function() + check_mapping('<A-l>', '<A-l>') + check_mapping('<A-L>', '<A-L>') + check_mapping('<A-S-l>', '<A-L>') + check_mapping('<A-S-L>', '<A-L>') + check_mapping('<D-l>', '<D-l>') + check_mapping('<D-L>', '<D-L>') + check_mapping('<D-S-l>', '<D-L>') + check_mapping('<D-S-L>', '<D-L>') + check_mapping('<C-l>', '<C-L>') check_mapping('<C-L>', '<C-L>') + check_mapping('<C-S-l>', '<C-S-L>') check_mapping('<C-S-L>', '<C-S-L>') check_mapping('<s-up>', '<s-up>') check_mapping('<c-s-up>', '<c-s-up>') @@ -75,44 +92,44 @@ describe('mappings', function() check_mapping('<c-d-a>', '<c-d-a>') check_mapping('<d-c-a>', '<c-d-a>') check_mapping('<d-1>', '<d-1>') - check_mapping('<khome>','<khome>') - check_mapping('<KP7>','<khome>') - check_mapping('<kup>','<kup>') - check_mapping('<KP8>','<kup>') - check_mapping('<kpageup>','<kpageup>') - check_mapping('<KP9>','<kpageup>') - check_mapping('<kleft>','<kleft>') - check_mapping('<KP4>','<kleft>') - check_mapping('<korigin>','<korigin>') - check_mapping('<KP5>','<korigin>') - check_mapping('<kright>','<kright>') - check_mapping('<KP6>','<kright>') - check_mapping('<kend>','<kend>') - check_mapping('<KP1>','<kend>') - check_mapping('<kdown>','<kdown>') - check_mapping('<KP2>','<kdown>') - check_mapping('<kpagedown>','<kpagedown>') - check_mapping('<KP3>','<kpagedown>') - check_mapping('<kinsert>','<kinsert>') - check_mapping('<KP0>','<kinsert>') - check_mapping('<kdel>','<kdel>') - check_mapping('<KPPeriod>','<kdel>') - check_mapping('<kdivide>','<kdivide>') - check_mapping('<KPDiv>','<kdivide>') - check_mapping('<kmultiply>','<kmultiply>') - check_mapping('<KPMult>','<kmultiply>') - check_mapping('<kminus>','<kminus>') - check_mapping('<KPMinus>','<kminus>') - check_mapping('<kplus>','<kplus>') - check_mapping('<KPPlus>','<kplus>') - check_mapping('<kenter>','<kenter>') - check_mapping('<KPEnter>','<kenter>') - check_mapping('<kcomma>','<kcomma>') - check_mapping('<KPComma>','<kcomma>') - check_mapping('<kequal>','<kequal>') - check_mapping('<KPEquals>','<kequal>') - check_mapping('<f38>','<f38>') - check_mapping('<f63>','<f63>') + check_mapping('<khome>', '<khome>') + check_mapping('<KP7>', '<khome>') + check_mapping('<kup>', '<kup>') + check_mapping('<KP8>', '<kup>') + check_mapping('<kpageup>', '<kpageup>') + check_mapping('<KP9>', '<kpageup>') + check_mapping('<kleft>', '<kleft>') + check_mapping('<KP4>', '<kleft>') + check_mapping('<korigin>', '<korigin>') + check_mapping('<KP5>', '<korigin>') + check_mapping('<kright>', '<kright>') + check_mapping('<KP6>', '<kright>') + check_mapping('<kend>', '<kend>') + check_mapping('<KP1>', '<kend>') + check_mapping('<kdown>', '<kdown>') + check_mapping('<KP2>', '<kdown>') + check_mapping('<kpagedown>', '<kpagedown>') + check_mapping('<KP3>', '<kpagedown>') + check_mapping('<kinsert>', '<kinsert>') + check_mapping('<KP0>', '<kinsert>') + check_mapping('<kdel>', '<kdel>') + check_mapping('<KPPeriod>', '<kdel>') + check_mapping('<kdivide>', '<kdivide>') + check_mapping('<KPDiv>', '<kdivide>') + check_mapping('<kmultiply>', '<kmultiply>') + check_mapping('<KPMult>', '<kmultiply>') + check_mapping('<kminus>', '<kminus>') + check_mapping('<KPMinus>', '<kminus>') + check_mapping('<kplus>', '<kplus>') + check_mapping('<KPPlus>', '<kplus>') + check_mapping('<kenter>', '<kenter>') + check_mapping('<KPEnter>', '<kenter>') + check_mapping('<kcomma>', '<kcomma>') + check_mapping('<KPComma>', '<kcomma>') + check_mapping('<kequal>', '<kequal>') + check_mapping('<KPEquals>', '<kequal>') + check_mapping('<f38>', '<f38>') + check_mapping('<f63>', '<f63>') end) it('support meta + multibyte char mapping', function() @@ -151,7 +168,7 @@ describe('input split utf sequences', function() it('ok', function() local str = '►' feed('i' .. str:sub(1, 1)) - helpers.sleep(10) + vim.uv.sleep(10) feed(str:sub(2, 3)) expect('►') end) @@ -160,7 +177,7 @@ describe('input split utf sequences', function() command('inoremap ► E296BA') local str = '►' feed('i' .. str:sub(1, 1)) - helpers.sleep(10) + vim.uv.sleep(10) feed(str:sub(2, 3)) expect('E296BA') end) @@ -241,7 +258,7 @@ it('Ctrl-6 is Ctrl-^ vim-patch:8.1.2333', function() command('split aaa') command('edit bbb') feed('<C-6>') - eq('aaa', funcs.bufname()) + eq('aaa', fn.bufname()) end) it('c_CTRL-R_CTRL-R, i_CTRL-R_CTRL-R, i_CTRL-G_CTRL-K work properly vim-patch:8.1.2346', function() @@ -262,20 +279,18 @@ it('c_CTRL-R_CTRL-R, i_CTRL-R_CTRL-R, i_CTRL-G_CTRL-K work properly vim-patch:8. end) it('typing a simplifiable key at hit-enter prompt triggers mapping vim-patch:8.2.0839', function() - local screen = Screen.new(60,8) + local screen = Screen.new(60, 8) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [2] = {bold = true, reverse = true}, -- MsgSeparator - [3] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg + [1] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [2] = { bold = true, reverse = true }, -- MsgSeparator + [3] = { bold = true, foreground = Screen.colors.SeaGreen }, -- MoreMsg }) screen:attach() command([[nnoremap <C-6> <Cmd>echo 'hit ctrl-6'<CR>]]) feed_command('ls') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2: }| :ls | 1 %a "[No Name]" line 1 | @@ -284,12 +299,7 @@ it('typing a simplifiable key at hit-enter prompt triggers mapping vim-patch:8.2 feed('<C-6>') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 hit ctrl-6 | ]]) end) @@ -307,7 +317,7 @@ it('unsimplified mapping works when there was a partial match vim-patch:8.2.4504 command('nnoremap <C-J> a') command('nnoremap <NL> x') command('nnoremap <C-J>x <Nop>') - funcs.setline(1, 'x') + fn.setline(1, 'x') -- CTRL-J b should have trigger the <C-J> mapping and then insert "b" feed('<C-J>b<Esc>') expect('xb') @@ -319,49 +329,41 @@ describe('input non-printable chars', function() end) it("doesn't crash when echoing them back", function() - write_file("Xtest-overwrite", [[foobar]]) - local screen = Screen.new(60,8) + write_file('Xtest-overwrite', [[foobar]]) + local screen = Screen.new(60, 8) screen:set_default_attr_ids { - [1] = {bold = true, foreground = Screen.colors.Blue1}; - [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}; - [3] = {bold = true, foreground = Screen.colors.SeaGreen4}; - [4] = {bold = true, reverse = true}; + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [3] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [4] = { bold = true, reverse = true }, } screen:attach() - command("set shortmess-=F") + command('set shortmess-=F') - feed_command("e Xtest-overwrite") + feed_command('e Xtest-overwrite') screen:expect([[ ^foobar | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 "Xtest-overwrite" [noeol] 1L, 6B | ]]) -- The timestamp is in second resolution, wait two seconds to be sure. screen:sleep(2000) - write_file("Xtest-overwrite", [[smurf]]) - feed_command("w") + write_file('Xtest-overwrite', [[smurf]]) + feed_command('w') screen:expect([[ foobar | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {4: }| "Xtest-overwrite" | {2:WARNING: The file has been changed since reading it!!!} | {3:Do you really want to write to it (y/n)?}^ | ]]) - feed("u") + feed('u') screen:expect([[ foobar | - {1:~ }| - {1:~ }| + {1:~ }|*2 {4: }| "Xtest-overwrite" | {2:WARNING: The file has been changed since reading it!!!} | @@ -369,7 +371,7 @@ describe('input non-printable chars', function() {3:Do you really want to write to it (y/n)?}^ | ]]) - feed("\005") + feed('\005') screen:expect([[ foobar | {1:~ }| @@ -381,7 +383,7 @@ describe('input non-printable chars', function() {3:Do you really want to write to it (y/n)?}^ | ]]) - feed("n") + feed('n') screen:expect([[ foobar | {4: }| @@ -393,23 +395,23 @@ describe('input non-printable chars', function() {3:Press ENTER or type command to continue}^ | ]]) - feed("<cr>") + feed('<cr>') screen:expect([[ ^foobar | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | ]]) end) end) -describe("event processing and input", function() +describe('event processing and input', function() it('not blocked by event bursts', function() - meths.set_keymap('', '<f2>', "<cmd>lua vim.rpcnotify(1, 'stop') winning = true <cr>", {noremap=true}) + api.nvim_set_keymap( + '', + '<f2>', + "<cmd>lua vim.rpcnotify(1, 'stop') winning = true <cr>", + { noremap = true } + ) exec_lua [[ winning = false @@ -425,9 +427,9 @@ describe("event processing and input", function() burst(true) ]] - eq({'notification', 'start', {}}, next_msg()) + eq({ 'notification', 'start', {} }, next_msg()) feed '<f2>' - eq({'notification', 'stop', {}}, next_msg()) + eq({ 'notification', 'stop', {} }, next_msg()) end) end) @@ -436,8 +438,8 @@ describe('display is updated', function() before_each(function() screen = Screen.new(60, 8) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, -- NonText - [2] = {bold = true}, -- ModeMsg + [1] = { bold = true, foreground = Screen.colors.Blue1 }, -- NonText + [2] = { bold = true }, -- ModeMsg }) screen:attach() end) @@ -449,11 +451,7 @@ describe('display is updated', function() screen:expect([[ abc | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | ]]) end) @@ -465,11 +463,7 @@ describe('display is updated', function() screen:expect([[ abc | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | ]]) end) diff --git a/test/functional/ui/linematch_spec.lua b/test/functional/ui/linematch_spec.lua index ef47ea7ed0..40df5cadf1 100644 --- a/test/functional/ui/linematch_spec.lua +++ b/test/functional/ui/linematch_spec.lua @@ -39,32 +39,33 @@ describe('Diff mode screen with 3 diffs open', function() screen = Screen.new(100, 16) screen:attach() screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.Gray}; - [2] = {foreground = Screen.colors.Blue1, bold = true, background = Screen.colors.LightCyan1}; - [3] = {reverse = true}; - [4] = {background = Screen.colors.LightBlue}; - [5] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGray}; - [6] = {foreground = Screen.colors.Blue1, bold = true}; - [7] = {reverse = true, bold = true}; - [8] = {background = Screen.colors.Red1, bold = true}; - [10] = {foreground = Screen.colors.Brown}; - [9] = {background = Screen.colors.Plum1}; + [1] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.Gray }, + [2] = { foreground = Screen.colors.Blue1, bold = true, background = Screen.colors.LightCyan1 }, + [3] = { reverse = true }, + [4] = { background = Screen.colors.LightBlue }, + [5] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGray }, + [6] = { foreground = Screen.colors.Blue1, bold = true }, + [7] = { reverse = true, bold = true }, + [8] = { background = Screen.colors.Red1, bold = true }, + [10] = { foreground = Screen.colors.Brown }, + [9] = { background = Screen.colors.Plum1 }, }) feed('<c-w>=') feed(':windo set nu!<cr>') end) - describe('setup the diff screen to look like a merge conflict with 3 files in diff mode', function() - before_each(function() - - local f1 = [[ + describe( + 'setup the diff screen to look like a merge conflict with 3 files in diff mode', + function() + before_each(function() + local f1 = [[ common line AAA AAA AAA ]] - local f2 = [[ + local f2 = [[ common line <<<<<<< HEAD @@ -77,7 +78,7 @@ describe('Diff mode screen with 3 diffs open', function() BBB >>>>>>> branch1 ]] - local f3 = [[ + local f3 = [[ common line BBB @@ -85,16 +86,16 @@ describe('Diff mode screen with 3 diffs open', function() BBB ]] - write_file(fname, f1, false) - write_file(fname_2, f2, false) - write_file(fname_3, f3, false) - reread() - end) + write_file(fname, f1, false) + write_file(fname_2, f2, false) + write_file(fname_3, f3, false) + reread() + end) - it('get from window 1', function() - feed('1<c-w>w') - feed(':2,6diffget screen-1.2<cr>') - screen:expect([[ + it('get from window 1', function() + feed('1<c-w>w') + feed(':2,6diffget screen-1.2<cr>') + screen:expect([[ {1: }{10: 1 }^ │{1: }{10: 1 } │{1: }{10: 1 } | {1: }{10: 2 }common line │{1: }{10: 2 }common line │{1: }{10: 2 }common line | {1: }{10: 3 }{9:<<<<<<< HEAD }│{1: }{10: 3 }{9:<<<<<<< HEAD }│{1: }{10: }{2:---------------------------}| @@ -107,17 +108,16 @@ describe('Diff mode screen with 3 diffs open', function() {1: }{10: 10 }{9: BBB }│{1: }{10: 10 }{9: BBB }│{1: }{10: }{2:---------------------------}| {1: }{10: 11 }{9:>>>>>>> branch1 }│{1: }{10: 11 }{9:>>>>>>> branch1 }│{1: }{10: }{2:---------------------------}| {1: }{10: 12 } │{1: }{10: 12 } │{1: }{10: 6 } | - {6:~ }│{6:~ }│{6:~ }| - {6:~ }│{6:~ }│{6:~ }| + {6:~ }│{6:~ }│{6:~ }|*2 {7:<-functional-diff-screen-1.3 [+] }{3:<est-functional-diff-screen-1.2 Xtest-functional-diff-screen-1 }| :2,6diffget screen-1.2 | ]]) - end) + end) - it('get from window 2', function() - feed('2<c-w>w') - feed(':5,7diffget screen-1.3<cr>') - screen:expect([[ + it('get from window 2', function() + feed('2<c-w>w') + feed(':5,7diffget screen-1.3<cr>') + screen:expect([[ {1: }{10: 1 } │{1: }{10: 1 }^ │{1: }{10: 1 } | {1: }{10: 2 }common line │{1: }{10: 2 }common line │{1: }{10: 2 }common line | {1: }{10: }{2:---------------------------}│{1: }{10: 3 }{4:<<<<<<< HEAD }│{1: }{10: }{2:---------------------------}| @@ -127,20 +127,16 @@ describe('Diff mode screen with 3 diffs open', function() {1: }{10: 5 }{9: }{8:BBB}{9: }│{1: }{10: 7 }{9: }{8:BBB}{9: }│{1: }{10: 5 }{9: }{8:AAA}{9: }| {1: }{10: }{2:---------------------------}│{1: }{10: 8 }{4:>>>>>>> branch1 }│{1: }{10: }{2:---------------------------}| {1: }{10: 6 } │{1: }{10: 9 } │{1: }{10: 6 } | - {6:~ }│{6:~ }│{6:~ }| - {6:~ }│{6:~ }│{6:~ }| - {6:~ }│{6:~ }│{6:~ }| - {6:~ }│{6:~ }│{6:~ }| - {6:~ }│{6:~ }│{6:~ }| + {6:~ }│{6:~ }│{6:~ }|*5 {3:<test-functional-diff-screen-1.3 }{7:<functional-diff-screen-1.2 [+] }{3:Xtest-functional-diff-screen-1 }| :5,7diffget screen-1.3 | ]]) - end) + end) - it('get from window 3', function() - feed('3<c-w>w') - feed(':5,6diffget screen-1.2<cr>') - screen:expect([[ + it('get from window 3', function() + feed('3<c-w>w') + feed(':5,6diffget screen-1.2<cr>') + screen:expect([[ {1: }{10: 1 } │{1: }{10: 1 } │{1: }{10: 1 }^ | {1: }{10: 2 }common line │{1: }{10: 2 }common line │{1: }{10: 2 }common line | {1: }{10: }{2:---------------------------}│{1: }{10: 3 }{4:<<<<<<< HEAD }│{1: }{10: }{2:---------------------------}| @@ -153,17 +149,16 @@ describe('Diff mode screen with 3 diffs open', function() {1: }{10: 5 } BBB │{1: }{10: 10 } BBB │{1: }{10: 9 } BBB | {1: }{10: }{2:---------------------------}│{1: }{10: 11 }{9:>>>>>>> branch1 }│{1: }{10: 10 }{9:>>>>>>> branch1 }| {1: }{10: 6 } │{1: }{10: 12 } │{1: }{10: 11 } | - {6:~ }│{6:~ }│{6:~ }| - {6:~ }│{6:~ }│{6:~ }| + {6:~ }│{6:~ }│{6:~ }|*2 {3:<test-functional-diff-screen-1.3 <est-functional-diff-screen-1.2 }{7:<st-functional-diff-screen-1 [+] }| :5,6diffget screen-1.2 | ]]) - end) + end) - it('put from window 2 - part', function() - feed('2<c-w>w') - feed(':6,8diffput screen-1<cr>') - screen:expect([[ + it('put from window 2 - part', function() + feed('2<c-w>w') + feed(':6,8diffput screen-1<cr>') + screen:expect([[ {1: }{10: 1 } │{1: }{10: 1 }^ │{1: }{10: 1 } | {1: }{10: 2 }common line │{1: }{10: 2 }common line │{1: }{10: 2 }common line | {1: }{10: }{2:---------------------------}│{1: }{10: 3 }{4:<<<<<<< HEAD }│{1: }{10: }{2:---------------------------}| @@ -176,17 +171,15 @@ describe('Diff mode screen with 3 diffs open', function() {1: }{10: 5 } BBB │{1: }{10: 10 } BBB │{1: }{10: 7 } BBB | {1: }{10: }{2:---------------------------}│{1: }{10: 11 }{4:>>>>>>> branch1 }│{1: }{10: }{2:---------------------------}| {1: }{10: 6 } │{1: }{10: 12 } │{1: }{10: 8 } | - {6:~ }│{6:~ }│{6:~ }| - {6:~ }│{6:~ }│{6:~ }| + {6:~ }│{6:~ }│{6:~ }|*2 {3:<test-functional-diff-screen-1.3 }{7:<est-functional-diff-screen-1.2 }{3:<st-functional-diff-screen-1 [+] }| :6,8diffput screen-1 | ]]) - - end) - it('put from window 2 - part to end', function() - feed('2<c-w>w') - feed(':6,11diffput screen-1<cr>') - screen:expect([[ + end) + it('put from window 2 - part to end', function() + feed('2<c-w>w') + feed(':6,11diffput screen-1<cr>') + screen:expect([[ {1: }{10: 1 } │{1: }{10: 1 }^ │{1: }{10: 1 } | {1: }{10: 2 }common line │{1: }{10: 2 }common line │{1: }{10: 2 }common line | {1: }{10: }{2:---------------------------}│{1: }{10: 3 }{4:<<<<<<< HEAD }│{1: }{10: }{2:---------------------------}| @@ -199,14 +192,13 @@ describe('Diff mode screen with 3 diffs open', function() {1: }{10: 5 } BBB │{1: }{10: 10 } BBB │{1: }{10: 9 } BBB | {1: }{10: }{2:---------------------------}│{1: }{10: 11 }{9:>>>>>>> branch1 }│{1: }{10: 10 }{9:>>>>>>> branch1 }| {1: }{10: 6 } │{1: }{10: 12 } │{1: }{10: 11 } | - {6:~ }│{6:~ }│{6:~ }| - {6:~ }│{6:~ }│{6:~ }| + {6:~ }│{6:~ }│{6:~ }|*2 {3:<test-functional-diff-screen-1.3 }{7:<est-functional-diff-screen-1.2 }{3:<st-functional-diff-screen-1 [+] }| :6,11diffput screen-1 | ]]) - - end) - end) + end) + end + ) end) describe('Diff mode screen with 2 diffs open', function() @@ -238,16 +230,16 @@ describe('Diff mode screen with 2 diffs open', function() screen = Screen.new(100, 20) screen:attach() screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.Gray}; - [2] = {foreground = Screen.colors.Blue1, bold = true, background = Screen.colors.LightCyan1}; - [3] = {reverse = true}; - [4] = {background = Screen.colors.LightBlue}; - [5] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGray}; - [6] = {foreground = Screen.colors.Blue1, bold = true}; - [7] = {reverse = true, bold = true}; - [8] = {background = Screen.colors.Red1, bold = true}; - [10] = {foreground = Screen.colors.Brown}; - [9] = {background = Screen.colors.Plum1}; + [1] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.Gray }, + [2] = { foreground = Screen.colors.Blue1, bold = true, background = Screen.colors.LightCyan1 }, + [3] = { reverse = true }, + [4] = { background = Screen.colors.LightBlue }, + [5] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGray }, + [6] = { foreground = Screen.colors.Blue1, bold = true }, + [7] = { reverse = true, bold = true }, + [8] = { background = Screen.colors.Red1, bold = true }, + [10] = { foreground = Screen.colors.Brown }, + [9] = { background = Screen.colors.Plum1 }, }) feed('<c-w>=') feed(':windo set nu!<cr>') @@ -310,12 +302,7 @@ something {1: }{10: }{2:-------------------------------------------}│{1: }{10: 16 }{4:DEF }| {1: }{10: 15 }something │{1: }{10: 17 }something | {1: }{10: 16 } │{1: }{10: 18 } | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*6 {7:Xtest-functional-diff-screen-1.2 [+] }{3:Xtest-functional-diff-screen-1 }| :5,9diffget | ]]) @@ -339,9 +326,7 @@ something {1: }{10: }{2:-------------------------------------------}│{1: }{10: 13 }{4:DEF }| {1: }{10: 12 }something │{1: }{10: 14 }something | {1: }{10: 13 } │{1: }{10: 15 } | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*3 {3:Xtest-functional-diff-screen-1.2 }{7:Xtest-functional-diff-screen-1 [+] }| :5,10diffget | ]]) @@ -363,15 +348,10 @@ something {1: }{10: 11 }common line │{1: }{10: 11 }common line | {1: }{10: 12 }something │{1: }{10: 12 }something | {1: }{10: 13 } │{1: }{10: 13 } | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*5 {3:Xtest-functional-diff-screen-1.2 }{7:Xtest-functional-diff-screen-1 [+] }| :4,17diffget | ]]) - end) it('get all from window 1', function() feed('1<c-w>w') @@ -776,7 +756,6 @@ something {3:Xtest-functional-diff-screen-1.2 [+] }{7:Xtest-functional-diff-screen-1 }| :e | ]]) - end) end) describe('setup a diff with 2 files and set linematch:30', function() @@ -804,19 +783,7 @@ d {1: }{10: 3 }{9:d }│{1: }{10: 2 }{8:// }{9:d }| {1: }{10: }{2:-------------------------------------------}│{1: }{10: 3 }{4:// d }| {1: }{10: 4 } │{1: }{10: 4 } | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*13 {7:Xtest-functional-diff-screen-1.2 }{3:Xtest-functional-diff-screen-1 }| :e | ]]) @@ -853,17 +820,7 @@ void testFunction () { {1: }{10: }{2:-------------------------------------------}│{1: }{10: 5 }{4: } }| {1: }{10: 4 }} │{1: }{10: 6 }} | {1: }{10: 5 } │{1: }{10: 7 } | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*11 {7:Xtest-functional-diff-screen-1.2 }{3:Xtest-functional-diff-screen-1 }| :e | ]]) @@ -903,15 +860,7 @@ void testFunction () { {1: }{10: 7 }{4:?B }│{1: }{10: }{2:--------------------------------------------}| {1: }{10: 8 }{4:?C }│{1: }{10: }{2:--------------------------------------------}| {1: }{10: 9 } │{1: }{10: 4 } | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*9 {7:Xtest-functional-diff-screen-1.2 }{3:Xtest-functional-diff-screen-1 }| :e | ]]) @@ -951,15 +900,7 @@ void testFunction () { {1: }{10: 7 }{8:?}{9:C }│{1: }{10: 3 }{8:!}{9:C }| {1: }{10: 8 }{4:?C }│{1: }{10: }{2:--------------------------------------------}| {1: }{10: 9 } │{1: }{10: 4 } | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*9 {7:Xtest-functional-diff-screen-1.2 }{3:Xtest-functional-diff-screen-1 }| :e | ]]) @@ -1006,10 +947,12 @@ something reread() end) - it('enable linematch for the longest diff block by increasing the number argument passed to linematch', function() - feed('1<c-w>w') - -- linematch is disabled for the longest diff because it's combined line length is over 10 - screen:expect([[ + it( + 'enable linematch for the longest diff block by increasing the number argument passed to linematch', + function() + feed('1<c-w>w') + -- linematch is disabled for the longest diff because it's combined line length is over 10 + screen:expect([[ {1: }{10: 1 }^common line │{1: }{10: 1 }common line | {1: }{10: 2 }{4:DEF }│{1: }{10: }{2:--------------------------------------------}| {1: }{10: 3 }{8:GHI}{9: }│{1: }{10: 2 }{8:HIL}{9: }| @@ -1031,10 +974,10 @@ something {7:Xtest-functional-diff-screen-1.2 }{3:Xtest-functional-diff-screen-1 }| :e | ]]) - -- enable it by increasing the number - feed(":set diffopt-=linematch:10<cr>") - feed(":set diffopt+=linematch:30<cr>") - screen:expect([[ + -- enable it by increasing the number + feed(':set diffopt-=linematch:10<cr>') + feed(':set diffopt+=linematch:30<cr>') + screen:expect([[ {1: }{10: 1 }^common line │{1: }{10: 1 }common line | {1: }{10: 2 }{4:DEF }│{1: }{10: }{2:--------------------------------------------}| {1: }{10: 3 }{8:GHI}{9: }│{1: }{10: 2 }{8:HIL}{9: }| @@ -1056,7 +999,8 @@ something {7:Xtest-functional-diff-screen-1.2 }{3:Xtest-functional-diff-screen-1 }| :set diffopt+=linematch:30 | ]]) - end) + end + ) it('get all from second window', function() feed('2<c-w>w') feed(':1,12diffget<cr>') @@ -1099,20 +1043,17 @@ something {1: }{10: 10 }common line │{1: }{10: 10 }common line | {1: }{10: 11 }something │{1: }{10: 11 }something | {1: }{10: 12 } │{1: }{10: 12 } | - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| - {6:~ }│{6:~ }| + {6:~ }│{6:~ }|*6 {7:Xtest-functional-diff-screen-1.2 [+] }{3:Xtest-functional-diff-screen-1 }| :1,19diffget | ]]) end) - it('get part of the non linematched diff block in window 2 line 7 - 8 (non line matched block)', function() - feed('2<c-w>w') - feed(':7,8diffget<cr>') - screen:expect([[ + it( + 'get part of the non linematched diff block in window 2 line 7 - 8 (non line matched block)', + function() + feed('2<c-w>w') + feed(':7,8diffget<cr>') + screen:expect([[ {1: }{10: 1 }common line │{1: }{10: 1 }^common line | {1: }{10: 2 }{4:DEF }│{1: }{10: }{2:--------------------------------------------}| {1: }{10: 3 }{8:GHI}{9: }│{1: }{10: 2 }{8:HIL}{9: }| @@ -1134,11 +1075,14 @@ something {3:Xtest-functional-diff-screen-1.2 }{7:Xtest-functional-diff-screen-1 [+] }| :7,8diffget | ]]) - end) - it('get part of the non linematched diff block in window 2 line 8 - 10 (line matched block)', function() - feed('2<c-w>w') - feed(':8,10diffget<cr>') - screen:expect([[ + end + ) + it( + 'get part of the non linematched diff block in window 2 line 8 - 10 (line matched block)', + function() + feed('2<c-w>w') + feed(':8,10diffget<cr>') + screen:expect([[ {1: }{10: 1 }common line │{1: }{10: 1 }^common line | {1: }{10: 2 }{4:DEF }│{1: }{10: }{2:--------------------------------------------}| {1: }{10: 3 }{8:GHI}{9: }│{1: }{10: 2 }{8:HIL}{9: }| @@ -1160,7 +1104,8 @@ something {3:Xtest-functional-diff-screen-1.2 }{7:Xtest-functional-diff-screen-1 [+] }| :8,10diffget | ]]) - end) + end + ) end) end) @@ -1173,13 +1118,13 @@ describe('regressions', function() screen = Screen.new(100, 20) screen:attach() -- line must be greater than MATCH_CHAR_MAX_LEN - helpers.curbufmeths.set_lines(0, -1, false, { string.rep('a', 1000)..'hello' }) + helpers.api.nvim_buf_set_lines(0, 0, -1, false, { string.rep('a', 1000) .. 'hello' }) helpers.exec 'vnew' - helpers.curbufmeths.set_lines(0, -1, false, { string.rep('a', 1010)..'world' }) + helpers.api.nvim_buf_set_lines(0, 0, -1, false, { string.rep('a', 1010) .. 'world' }) helpers.exec 'windo diffthis' end) - it("properly computes filler lines for hunks bigger than linematch limit", function() + it('properly computes filler lines for hunks bigger than linematch limit', function() clear() feed(':set diffopt+=linematch:10<cr>') screen = Screen.new(100, 20) @@ -1188,12 +1133,13 @@ describe('regressions', function() for i = 0, 29 do lines[#lines + 1] = tostring(i) end - helpers.curbufmeths.set_lines(0, -1, false, lines) + helpers.api.nvim_buf_set_lines(0, 0, -1, false, lines) helpers.exec 'vnew' - helpers.curbufmeths.set_lines(0, -1, false, { '00', '29' }) + helpers.api.nvim_buf_set_lines(0, 0, -1, false, { '00', '29' }) helpers.exec 'windo diffthis' feed('<C-e>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: }{2:------------------------------------------------}│{1: }{3:^1 }| {1: }{2:------------------------------------------------}│{1: }{3:2 }| {1: }{2:------------------------------------------------}│{1: }{3:3 }| @@ -1214,12 +1160,18 @@ describe('regressions', function() {1: }29 │{1: }{3:18 }| {4:[No Name] [+] }{5:[No Name] [+] }| | - ]], attr_ids={ - [1] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.Grey}; - [2] = {bold = true, background = Screen.colors.LightCyan, foreground = Screen.colors.Blue1}; - [3] = {background = Screen.colors.LightBlue}; - [4] = {reverse = true}; - [5] = {reverse = true, bold = true}; - }} + ]], + attr_ids = { + [1] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.Grey }, + [2] = { + bold = true, + background = Screen.colors.LightCyan, + foreground = Screen.colors.Blue1, + }, + [3] = { background = Screen.colors.LightBlue }, + [4] = { reverse = true }, + [5] = { reverse = true, bold = true }, + }, + } end) end) diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua index 1d11a12af4..31b1464589 100644 --- a/test/functional/ui/messages_spec.lua +++ b/test/functional/ui/messages_spec.lua @@ -5,9 +5,9 @@ local eval = helpers.eval local eq = helpers.eq local command = helpers.command local set_method_error = helpers.set_method_error -local meths = helpers.meths +local api = helpers.api local async_meths = helpers.async_meths -local test_build_dir = helpers.test_build_dir +local test_build_dir = helpers.paths.test_build_dir local nvim_prog = helpers.nvim_prog local exec = helpers.exec local exec_capture = helpers.exec_capture @@ -17,7 +17,7 @@ local poke_eventloop = helpers.poke_eventloop local assert_alive = helpers.assert_alive local is_os = helpers.is_os local is_ci = helpers.is_ci -local funcs = helpers.funcs +local fn = helpers.fn local skip = helpers.skip describe('ui/ext_messages', function() @@ -27,18 +27,18 @@ describe('ui/ext_messages', function() before_each(function() clear() screen = Screen.new(25, 5) - screen:attach({rgb=true, ext_messages=true, ext_popupmenu=true}) + screen:attach({ rgb = true, ext_messages = true, ext_popupmenu = true }) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [3] = {bold = true}, - [4] = {bold = true, foreground = Screen.colors.SeaGreen4}, - [5] = {foreground = Screen.colors.Blue1}, - [6] = {bold = true, reverse = true}, - [7] = {background = Screen.colors.Yellow}, - [8] = {foreground = Screen.colors.Red}, - [9] = {special = Screen.colors.Red, undercurl = true}, - [10] = {foreground = Screen.colors.Brown}; + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [3] = { bold = true }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [5] = { foreground = Screen.colors.Blue1 }, + [6] = { bold = true, reverse = true }, + [7] = { background = Screen.colors.Yellow }, + [8] = { foreground = Screen.colors.Red }, + [9] = { special = Screen.colors.Red, undercurl = true }, + [10] = { foreground = Screen.colors.Brown }, }) end) after_each(function() @@ -48,25 +48,26 @@ describe('ui/ext_messages', function() it('msg_clear follows msg_show kind of confirm', function() feed('iline 1<esc>') feed(':call confirm("test")<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ line ^1 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={ { - content = {{"\ntest\n[O]k: ", 4}}, - kind = 'confirm', - }}} + {1:~ }|*4 + ]], + messages = { + { + content = { { '\ntest\n[O]k: ', 4 } }, + kind = 'confirm', + }, + }, + } feed('<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ line ^1 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]]} + {1:~ }|*4 + ]], + } end) it('msg_show kind=confirm,confirm_sub,emsg,wmsg,quickfix', function() @@ -74,293 +75,335 @@ describe('ui/ext_messages', function() -- kind=confirm feed(':echo confirm("test")<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ line 1 | line ^2 | - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={ { - content = {{"\ntest\n[O]k: ", 4}}, - kind = 'confirm', - }}} + {1:~ }|*3 + ]], + messages = { + { + content = { { '\ntest\n[O]k: ', 4 } }, + kind = 'confirm', + }, + }, + } feed('<cr><cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ line 1 | line ^2 | - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={ { - content = { { "\ntest\n[O]k: ", 4 } }, - kind = "confirm" - }, { - content = { { "1" } }, - kind = "echo" - }, { - content = { { "Press ENTER or type command to continue", 4 } }, - kind = "return_prompt" - } }} + {1:~ }|*3 + ]], + messages = { + { + content = { { '\ntest\n[O]k: ', 4 } }, + kind = 'confirm', + }, + { + content = { { '1' } }, + kind = 'echo', + }, + { + content = { { 'Press ENTER or type command to continue', 4 } }, + kind = 'return_prompt', + }, + }, + } feed('<cr><cr>') -- kind=confirm_sub feed(':%s/i/X/gc<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ l{7:i}ne 1 | l{8:i}ne ^2 | - {1:~ }| - {1:~ }| - {1:~ }| - ]], attr_ids={ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [3] = {bold = true}, - [4] = {bold = true, foreground = Screen.colors.SeaGreen4}, - [5] = {foreground = Screen.colors.Blue1}, - [6] = {bold = true, reverse = true}, - [7] = {reverse = true}, - [8] = {background = Screen.colors.Yellow}, - }, messages={ { - content = { { "replace with X (y/n/a/q/l/^E/^Y)?", 4 } }, - kind = "confirm_sub" - } }} + {1:~ }|*3 + ]], + attr_ids = { + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [3] = { bold = true }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [5] = { foreground = Screen.colors.Blue1 }, + [6] = { bold = true, reverse = true }, + [7] = { reverse = true }, + [8] = { background = Screen.colors.Yellow }, + }, + messages = { + { + content = { { 'replace with X (y/n/a/q/l/^E/^Y)?', 4 } }, + kind = 'confirm_sub', + }, + }, + } feed('nq') -- kind=wmsg (editing readonly file) command('write ' .. fname) command('set readonly nohls') feed('G$x') - screen:expect{grid=[[ + screen:expect { + grid = [[ line 1 | {MATCH:.*}| - {1:~ }| - {1:~ }| - {1:~ }| - ]], attr_ids={ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [7] = {foreground = Screen.colors.Red}, - }, messages={ { - content = { { "W10: Warning: Changing a readonly file", 7 } }, - kind = "wmsg" - } - }} + {1:~ }|*3 + ]], + attr_ids = { + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [7] = { foreground = Screen.colors.Red }, + }, + messages = { + { + content = { { 'W10: Warning: Changing a readonly file', 7 } }, + kind = 'wmsg', + }, + }, + } -- kind=wmsg ('wrapscan' after search reaches EOF) feed('uG$/i<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ l^ine 1 | line 2 | - {1:~ }| - {1:~ }| - {1:~ }| - ]], attr_ids={ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [3] = {bold = true}, - [4] = {bold = true, foreground = Screen.colors.SeaGreen4}, - [5] = {foreground = Screen.colors.Blue1}, - [6] = {bold = true, reverse = true}, - [7] = {foreground = Screen.colors.Red}, - }, messages={ { - content = { { "search hit BOTTOM, continuing at TOP", 7 } }, - kind = "wmsg" - } }} + {1:~ }|*3 + ]], + attr_ids = { + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [3] = { bold = true }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [5] = { foreground = Screen.colors.Blue1 }, + [6] = { bold = true, reverse = true }, + [7] = { foreground = Screen.colors.Red }, + }, + messages = { + { + content = { { 'search hit BOTTOM, continuing at TOP', 7 } }, + kind = 'wmsg', + }, + }, + } -- kind=emsg after :throw feed(':throw "foo"<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ l^ine 1 | line 2 | - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={ { - content = { { "Error detected while processing :", 2 } }, - kind = "emsg" - }, { - content = { { "E605: Exception not caught: foo", 2 } }, - kind = "" - }, { - content = { { "Press ENTER or type command to continue", 4 } }, - kind = "return_prompt" - } } + {1:~ }|*3 + ]], + messages = { + { + content = { { 'Error detected while processing :', 2 } }, + kind = 'emsg', + }, + { + content = { { 'E605: Exception not caught: foo', 2 } }, + kind = '', + }, + { + content = { { 'Press ENTER or type command to continue', 4 } }, + kind = 'return_prompt', + }, + }, } -- kind=quickfix after :cnext feed('<c-c>') command("caddexpr [expand('%').':1:line1',expand('%').':2:line2']") feed(':cnext<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ line 1 | ^line 2 | - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={ { - content = { { "(2 of 2): line2" } }, - kind = "quickfix" - } }} + {1:~ }|*3 + ]], + messages = { + { + content = { { '(2 of 2): line2' } }, + kind = 'quickfix', + }, + }, + } end) it(':echoerr', function() feed(':echoerr "raa"<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={{ - content = {{"raa", 2}}, - kind = "echoerr", - }}} + {1:~ }|*4 + ]], + messages = { { + content = { { 'raa', 2 } }, + kind = 'echoerr', + } }, + } -- cmdline in a later input cycle clears error message feed(':') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], cmdline={{ - firstc = ":", - content = {{ "" }}, - pos = 0, - }}} - + {1:~ }|*4 + ]], + cmdline = { { + firstc = ':', + content = { { '' } }, + pos = 0, + } }, + } feed('echoerr "bork" | echoerr "fail"<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={{ - content = {{ "bork", 2 }}, - kind = "echoerr" - }, { - content = {{ "fail", 2 }}, - kind = "echoerr" - }, { - content = {{ "Press ENTER or type command to continue", 4 }}, - kind = "return_prompt" - }}} + {1:~ }|*4 + ]], + messages = { + { + content = { { 'bork', 2 } }, + kind = 'echoerr', + }, + { + content = { { 'fail', 2 } }, + kind = 'echoerr', + }, + { + content = { { 'Press ENTER or type command to continue', 4 } }, + kind = 'return_prompt', + }, + }, + } feed(':echoerr "extrafail"<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={{ - content = { { "bork", 2 } }, - kind = "echoerr" - }, { - content = { { "fail", 2 } }, - kind = "echoerr" - }, { - content = { { "extrafail", 2 } }, - kind = "echoerr" - }, { - content = { { "Press ENTER or type command to continue", 4 } }, - kind = "return_prompt" - }}} + {1:~ }|*4 + ]], + messages = { + { + content = { { 'bork', 2 } }, + kind = 'echoerr', + }, + { + content = { { 'fail', 2 } }, + kind = 'echoerr', + }, + { + content = { { 'extrafail', 2 } }, + kind = 'echoerr', + }, + { + content = { { 'Press ENTER or type command to continue', 4 } }, + kind = 'return_prompt', + }, + }, + } feed('<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]]} + {1:~ }|*4 + ]], + } -- cmdline without interleaving wait/display keeps the error message feed(':echoerr "problem" | let x = input("foo> ")<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={{ - content = {{ "problem", 2 }}, - kind = "echoerr" - }}, cmdline={{ - prompt = "foo> ", - content = {{ "" }}, - pos = 0, - }}} + {1:~ }|*4 + ]], + messages = { { + content = { { 'problem', 2 } }, + kind = 'echoerr', + } }, + cmdline = { + { + prompt = 'foo> ', + content = { { '' } }, + pos = 0, + }, + }, + } feed('solution<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]]} + {1:~ }|*4 + ]], + } eq('solution', eval('x')) - feed(":messages<cr>") - screen:expect{grid=[[ + feed(':messages<cr>') + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], msg_history={ - {kind="echoerr", content={{"raa", 2}}}, - {kind="echoerr", content={{"bork", 2}}}, - {kind="echoerr", content={{"fail", 2}}}, - {kind="echoerr", content={{"extrafail", 2}}}, - {kind="echoerr", content={{"problem", 2}}} - }, messages={{ - content = {{ "Press ENTER or type command to continue", 4 }}, - kind = "return_prompt" - }}} + {1:~ }|*4 + ]], + msg_history = { + { kind = 'echoerr', content = { { 'raa', 2 } } }, + { kind = 'echoerr', content = { { 'bork', 2 } } }, + { kind = 'echoerr', content = { { 'fail', 2 } } }, + { kind = 'echoerr', content = { { 'extrafail', 2 } } }, + { kind = 'echoerr', content = { { 'problem', 2 } } }, + }, + messages = { + { + content = { { 'Press ENTER or type command to continue', 4 } }, + kind = 'return_prompt', + }, + }, + } feed '<cr>' - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]]} + {1:~ }|*4 + ]], + } end) it(':echoerr multiline', function() exec_lua([[vim.g.multi = table.concat({ "bork", "fail" }, "\n")]]) feed(':echoerr g:multi<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={{ - content = {{ "bork\nfail", 2 }}, - kind = "echoerr" - }}} + {1:~ }|*4 + ]], + messages = { { + content = { { 'bork\nfail', 2 } }, + kind = 'echoerr', + } }, + } feed(':messages<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={{ - content = {{ "Press ENTER or type command to continue", 4 }}, - kind = "return_prompt" - }}, msg_history={{ - content = {{ "bork\nfail", 2 }}, - kind = "echoerr" - }}} + {1:~ }|*4 + ]], + messages = { + { + content = { { 'Press ENTER or type command to continue', 4 } }, + kind = 'return_prompt', + }, + }, + msg_history = { + { + content = { { 'bork\nfail', 2 } }, + kind = 'echoerr', + }, + }, + } end) it('shortmess-=S', function() @@ -368,470 +411,533 @@ describe('ui/ext_messages', function() feed('iline 1\nline 2<esc>') feed('/line<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {7:^line} 1 | {7:line} 2 | - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={ - {content = {{"/line W [1/2]"}}, kind = "search_count"} - }} + {1:~ }|*3 + ]], + messages = { + { content = { { '/line W [1/2]' } }, kind = 'search_count' }, + }, + } feed('n') - screen:expect{grid=[[ + screen:expect { + grid = [[ {7:line} 1 | {7:^line} 2 | - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={ - {content = {{"/line [2/2]"}}, kind = "search_count"} - }} + {1:~ }|*3 + ]], + messages = { + { content = { { '/line [2/2]' } }, kind = 'search_count' }, + }, + } end) it(':hi Group output', function() feed(':hi ErrorMsg<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={ - {content = {{"\nErrorMsg " }, {"xxx", 2}, {" "}, - {"ctermfg=", 5 }, { "15 " }, { "ctermbg=", 5 }, { "1 " }, - {"guifg=", 5 }, { "White " }, { "guibg=", 5 }, { "Red" }}, - kind = ""} - }} + {1:~ }|*4 + ]], + messages = { + { + content = { + { '\nErrorMsg ' }, + { 'xxx', 2 }, + { ' ' }, + { 'ctermfg=', 5 }, + { '15 ' }, + { 'ctermbg=', 5 }, + { '1 ' }, + { 'guifg=', 5 }, + { 'White ' }, + { 'guibg=', 5 }, + { 'Red' }, + }, + kind = '', + }, + }, + } end) it("doesn't crash with column adjustment #10069", function() feed(':let [x,y] = [1,2]<cr>') feed(':let x y<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={ - {content = {{ "x #1" }}, kind = ""}, - {content = {{ "y #2" }}, kind = ""}, - {content = {{ "Press ENTER or type command to continue", 4 }}, kind = "return_prompt"} - }} + {1:~ }|*4 + ]], + messages = { + { content = { { 'x #1' } }, kind = '' }, + { content = { { 'y #2' } }, kind = '' }, + { content = { { 'Press ENTER or type command to continue', 4 } }, kind = 'return_prompt' }, + }, + } end) it('&showmode', function() command('imap <f2> <cmd>echomsg "stuff"<cr>') feed('i') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], showmode={{"-- INSERT --", 3}}} + {1:~ }|*4 + ]], + showmode = { { '-- INSERT --', 3 } }, + } feed('alphpabet<cr>alphanum<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ alphpabet | alphanum | ^ | - {1:~ }| - {1:~ }| - ]], showmode={ { "-- INSERT --", 3 } }} + {1:~ }|*2 + ]], + showmode = { { '-- INSERT --', 3 } }, + } feed('<c-x>') - screen:expect{grid=[[ + screen:expect { + grid = [[ alphpabet | alphanum | ^ | - {1:~ }| - {1:~ }| - ]], showmode={ { "-- ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)", 3 } }} + {1:~ }|*2 + ]], + showmode = { { '-- ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)', 3 } }, + } feed('<c-p>') - screen:expect{grid=[[ + screen:expect { + grid = [[ alphpabet | alphanum | alphanum^ | - {1:~ }| - {1:~ }| - ]], popupmenu={ - anchor = { 1, 2, 0 }, - items = { { "alphpabet", "", "", "" }, { "alphanum", "", "", "" } }, - pos = 1 - }, showmode={ { "-- Keyword Local completion (^N^P) ", 3 }, { "match 1 of 2", 4 } }} + {1:~ }|*2 + ]], + popupmenu = { + anchor = { 1, 2, 0 }, + items = { { 'alphpabet', '', '', '' }, { 'alphanum', '', '', '' } }, + pos = 1, + }, + showmode = { { '-- Keyword Local completion (^N^P) ', 3 }, { 'match 1 of 2', 4 } }, + } -- echomsg and showmode don't overwrite each other, this is the same -- as the TUI behavior with cmdheight=2 or larger. feed('<f2>') - screen:expect{grid=[[ + screen:expect { + grid = [[ alphpabet | alphanum | alphanum^ | - {1:~ }| - {1:~ }| - ]], popupmenu={ - anchor = { 1, 2, 0 }, - items = { { "alphpabet", "", "", "" }, { "alphanum", "", "", "" } }, - pos = 1 - }, messages={ { - content = { { "stuff" } }, - kind = "echomsg" - } }, showmode={ { "-- Keyword Local completion (^N^P) ", 3 }, { "match 1 of 2", 4 } }} + {1:~ }|*2 + ]], + popupmenu = { + anchor = { 1, 2, 0 }, + items = { { 'alphpabet', '', '', '' }, { 'alphanum', '', '', '' } }, + pos = 1, + }, + messages = { { + content = { { 'stuff' } }, + kind = 'echomsg', + } }, + showmode = { { '-- Keyword Local completion (^N^P) ', 3 }, { 'match 1 of 2', 4 } }, + } feed('<c-p>') - screen:expect{grid=[[ + screen:expect { + grid = [[ alphpabet | alphanum | alphpabet^ | - {1:~ }| - {1:~ }| - ]], popupmenu={ - anchor = { 1, 2, 0 }, - items = { { "alphpabet", "", "", "" }, { "alphanum", "", "", "" } }, - pos = 0 - }, messages={ { - content = { { "stuff" } }, - kind = "echomsg" - } }, showmode={ { "-- Keyword Local completion (^N^P) ", 3 }, { "match 2 of 2", 4 } }} - - feed("<esc>:messages<cr>") - screen:expect{grid=[[ + {1:~ }|*2 + ]], + popupmenu = { + anchor = { 1, 2, 0 }, + items = { { 'alphpabet', '', '', '' }, { 'alphanum', '', '', '' } }, + pos = 0, + }, + messages = { { + content = { { 'stuff' } }, + kind = 'echomsg', + } }, + showmode = { { '-- Keyword Local completion (^N^P) ', 3 }, { 'match 2 of 2', 4 } }, + } + + feed('<esc>:messages<cr>') + screen:expect { + grid = [[ alphpabet | alphanum | alphpabe^t | - {1:~ }| - {1:~ }| - ]], msg_history={{ - content = {{ "stuff" }}, - kind = "echomsg", - }}, messages={{ - content = {{ "Press ENTER or type command to continue", 4}}, - kind = "return_prompt" - }}} + {1:~ }|*2 + ]], + msg_history = { { + content = { { 'stuff' } }, + kind = 'echomsg', + } }, + messages = { + { + content = { { 'Press ENTER or type command to continue', 4 } }, + kind = 'return_prompt', + }, + }, + } end) it('&showmode with macro-recording message', function() feed('qq') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], showmode={ { "recording @q", 3 } }} + {1:~ }|*4 + ]], + showmode = { { 'recording @q', 3 } }, + } feed('i') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], showmode={ { "-- INSERT --recording @q", 3 } }} + {1:~ }|*4 + ]], + showmode = { { '-- INSERT --recording @q', 3 } }, + } feed('<esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], showmode={ { "recording @q", 3 } }} + {1:~ }|*4 + ]], + showmode = { { 'recording @q', 3 } }, + } feed('q') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ]]) end) it('shows macro-recording message with &noshowmode', function() - command("set noshowmode") + command('set noshowmode') feed('qq') -- also check mode to avoid immediate success - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], showmode={ { "recording @q", 3 } }, mode="normal"} + {1:~ }|*4 + ]], + showmode = { { 'recording @q', 3 } }, + mode = 'normal', + } feed('i') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], showmode={ { "recording @q", 3 } }, mode="insert"} + {1:~ }|*4 + ]], + showmode = { { 'recording @q', 3 } }, + mode = 'insert', + } feed('<esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], showmode={ { "recording @q", 3 } }, mode="normal"} + {1:~ }|*4 + ]], + showmode = { { 'recording @q', 3 } }, + mode = 'normal', + } feed('q') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], mode="normal"} + {1:~ }|*4 + ]], + mode = 'normal', + } end) it('supports &showcmd and &ruler', function() command('set showcmd ruler') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], ruler={ { "0,0-1 All" } }} + {1:~ }|*4 + ]], + ruler = { { '0,0-1 All' } }, + } feed('i') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], showmode={ { "-- INSERT --", 3 } }, ruler={ { "0,1 All" } }} + {1:~ }|*4 + ]], + showmode = { { '-- INSERT --', 3 } }, + ruler = { { '0,1 All' } }, + } feed('abcde<cr>12345<esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ abcde | 1234^5 | - {1:~ }| - {1:~ }| - {1:~ }| - ]], ruler={ { "2,5 All" } }} + {1:~ }|*3 + ]], + ruler = { { '2,5 All' } }, + } feed('d') - screen:expect{grid=[[ + screen:expect { + grid = [[ abcde | 1234^5 | - {1:~ }| - {1:~ }| - {1:~ }| - ]], showcmd={ { "d" } }, ruler={ { "2,5 All" } }} + {1:~ }|*3 + ]], + showcmd = { { 'd' } }, + ruler = { { '2,5 All' } }, + } feed('<esc>^') - screen:expect{grid=[[ + screen:expect { + grid = [[ abcde | ^12345 | - {1:~ }| - {1:~ }| - {1:~ }| - ]], ruler={ { "2,1 All" } }} + {1:~ }|*3 + ]], + ruler = { { '2,1 All' } }, + } feed('d') - screen:expect{grid=[[ + screen:expect { + grid = [[ abcde | ^12345 | - {1:~ }| - {1:~ }| - {1:~ }| - ]], showcmd={ { "d" } }, ruler={ { "2,1 All" } }} + {1:~ }|*3 + ]], + showcmd = { { 'd' } }, + ruler = { { '2,1 All' } }, + } feed('i') - screen:expect{grid=[[ + screen:expect { + grid = [[ abcde | ^12345 | - {1:~ }| - {1:~ }| - {1:~ }| - ]], showcmd={ { "di" } }, ruler={ { "2,1 All" } }} + {1:~ }|*3 + ]], + showcmd = { { 'di' } }, + ruler = { { '2,1 All' } }, + } feed('w') - screen:expect{grid=[[ + screen:expect { + grid = [[ abcde | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - ]], ruler={ { "2,0-1 All" } }} + {1:~ }|*3 + ]], + ruler = { { '2,0-1 All' } }, + } -- when ruler is part of statusline it is not externalized. -- this will be added as part of future ext_statusline support - command("set laststatus=2") + command('set laststatus=2') screen:expect([[ abcde | ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {6:<o Name] [+] 2,0-1 All}| ]]) end) it('keeps history of message of different kinds', function() feed(':echomsg "howdy"<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={{ - content = {{ "howdy" }}, kind = "echomsg"} - }} + {1:~ }|*4 + ]], + messages = { { + content = { { 'howdy' } }, + kind = 'echomsg', + } }, + } -- always test a message without kind. If this one gets promoted to a -- category, add a new message without kind. feed('<c-c>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={{ - content = {{ "Type :qa and press <Enter> to exit Nvim" }}, - kind = ""} - }} + {1:~ }|*4 + ]], + messages = { + { + content = { { 'Type :qa and press <Enter> to exit Nvim' } }, + kind = '', + }, + }, + } feed(':echoerr "bork"<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={{ - content = {{ "bork", 2 }}, kind = "echoerr"} - }} + {1:~ }|*4 + ]], + messages = { { + content = { { 'bork', 2 } }, + kind = 'echoerr', + } }, + } feed(':echo "xyz"<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={{ - content = {{ "xyz" }}, kind = "echo"} - }} + {1:~ }|*4 + ]], + messages = { { + content = { { 'xyz' } }, + kind = 'echo', + } }, + } feed(':call nosuchfunction()<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={{ - content = {{ "E117: Unknown function: nosuchfunction", 2 }}, - kind = "emsg"} - }} + {1:~ }|*4 + ]], + messages = { + { + content = { { 'E117: Unknown function: nosuchfunction', 2 } }, + kind = 'emsg', + }, + }, + } feed(':messages<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], msg_history={ - {kind="echomsg", content={{"howdy"}}}, - {kind="", content={{"Type :qa and press <Enter> to exit Nvim"}}}, - {kind="echoerr", content={{"bork", 2}}}, - {kind="emsg", content={{"E117: Unknown function: nosuchfunction", 2}}} - }, messages={{ - content = {{ "Press ENTER or type command to continue", 4}}, - kind = "return_prompt" - }}} + {1:~ }|*4 + ]], + msg_history = { + { kind = 'echomsg', content = { { 'howdy' } } }, + { kind = '', content = { { 'Type :qa and press <Enter> to exit Nvim' } } }, + { kind = 'echoerr', content = { { 'bork', 2 } } }, + { kind = 'emsg', content = { { 'E117: Unknown function: nosuchfunction', 2 } } }, + }, + messages = { + { + content = { { 'Press ENTER or type command to continue', 4 } }, + kind = 'return_prompt', + }, + }, + } end) it('implies ext_cmdline and ignores cmdheight', function() eq(0, eval('&cmdheight')) feed(':set cmdheight=1') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], cmdline={{ - content = { { "set cmdheight=1" } }, - firstc = ":", - pos = 15 } - }} + {1:~ }|*4 + ]], + cmdline = { + { + content = { { 'set cmdheight=1' } }, + firstc = ':', + pos = 15, + }, + }, + } feed('<cr>') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ]]) eq(0, eval('&cmdheight')) feed(':set cmdheight=0') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], cmdline={{ - content = { { "set cmdheight=0" } }, - firstc = ":", - pos = 15 } - }} + {1:~ }|*4 + ]], + cmdline = { + { + content = { { 'set cmdheight=0' } }, + firstc = ':', + pos = 15, + }, + }, + } feed('<cr>') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ]]) eq(0, eval('&cmdheight')) end) it('supports multiline messages from lua', function() feed(':lua error("such\\nmultiline\\nerror")<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={{ - content = {{[[E5108: Error executing lua [string ":lua"]:1: such + {1:~ }|*4 + ]], + messages = { + { + content = { + { + [[E5108: Error executing lua [string ":lua"]:1: such multiline error stack traceback: [C]: in function 'error' - [string ":lua"]:1: in main chunk]], 2}}, - kind = "lua_error", - }}} + [string ":lua"]:1: in main chunk]], + 2, + }, + }, + kind = 'lua_error', + }, + }, + } end) it('supports multiline messages from rpc', function() feed(':call rpcrequest(1, "test_method")<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={{ - content = {{"Error invoking 'test_method' on channel 1:\ncomplete\nerror\n\nmessage", 2}}, - kind = "rpc_error" - }}, request_cb=function (name) - if name == "test_method" then - set_method_error("complete\nerror\n\nmessage") - end - end} + {1:~ }|*4 + ]], + messages = { + { + content = { + { "Error invoking 'test_method' on channel 1:\ncomplete\nerror\n\nmessage", 2 }, + }, + kind = 'rpc_error', + }, + }, + request_cb = function(name) + if name == 'test_method' then + set_method_error('complete\nerror\n\nmessage') + end + end, + } end) it('supports multiline messages for :map', function() @@ -841,10 +947,18 @@ stack traceback: command('nnoremap j k') feed(':map<cr>') - screen:expect{messages={{ - content = {{ "\nn Q @@\nn Y y$\nn j " }, { "*", 5 }, { " k" }}, - kind = '' - }}} + screen:expect { + messages = { + { + content = { + { '\nn Q @@\nn Y y$\nn j ' }, + { '*', 5 }, + { ' k' }, + }, + kind = '', + }, + }, + } end) it('wildmode=list', function() @@ -853,23 +967,23 @@ stack traceback: command('set wildmenu wildmode=list') feed(':set wildm<tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={{ - content = {{'wildmenu wildmode'}}, + {1:~ }|*6 + ]], + messages = { { + content = { { 'wildmenu wildmode' } }, kind = '', - }}, - cmdline={{ - firstc = ':', - content = {{ 'set wildm' }}, - pos = 9, - }}} + } }, + cmdline = { + { + firstc = ':', + content = { { 'set wildm' } }, + pos = 9, + }, + }, + } end) it('hides prompt_for_number messages', function() @@ -877,89 +991,110 @@ stack traceback: feed('ihelllo<esc>') feed('z=') - screen:expect{grid=[[ + screen:expect { + grid = [[ {9:helllo} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {1:^~ }| - ]], messages={ - {content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Hullo"\nType number and <Enter> or click with the mouse (q or empty cancels): ' } }, kind = ""} - }} + ]], + messages = { + { + content = { + { + 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Hullo"\nType number and <Enter> or click with the mouse (q or empty cancels): ', + }, + }, + kind = '', + }, + }, + } feed('1') - screen:expect{grid=[[ + screen:expect { + grid = [[ {9:helllo} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {1:^~ }| - ]], messages={ - {content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Hullo"\nType number and <Enter> or click with the mouse (q or empty cancels): ' } }, kind = ""}, - { content = { { "1" } }, kind = "" } - }} + ]], + messages = { + { + content = { + { + 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Hullo"\nType number and <Enter> or click with the mouse (q or empty cancels): ', + }, + }, + kind = '', + }, + { content = { { '1' } }, kind = '' }, + }, + } feed('<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^Hello | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]]} + {1:~ }|*4 + ]], + } end) it('supports nvim_echo messages with multiple attrs', function() - async_meths.echo({{'wow, ',"Search"}, {"such\n\nvery ", "ErrorMsg"}, {"color", "LineNr"}}, true, {}) - screen:expect{grid=[[ + async_meths.nvim_echo( + { { 'wow, ', 'Search' }, { 'such\n\nvery ', 'ErrorMsg' }, { 'color', 'LineNr' } }, + true, + {} + ) + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={ - { content = { { "wow, ", 7 }, { "such\n\nvery ", 2 }, { "color", 10 } }, kind = "echomsg" } - }} + {1:~ }|*4 + ]], + messages = { + { content = { { 'wow, ', 7 }, { 'such\n\nvery ', 2 }, { 'color', 10 } }, kind = 'echomsg' }, + }, + } feed ':ls<cr>' - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={ - { content = { { '\n 1 %a "[No Name]" line 1' } }, kind = "" } - }} + {1:~ }|*4 + ]], + messages = { + { content = { { '\n 1 %a "[No Name]" line 1' } }, kind = '' }, + }, + } feed ':messages<cr>' - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]], messages={ - { content = { { "Press ENTER or type command to continue", 4 } }, kind = "return_prompt" } - }, msg_history={ - { content = { { "wow, ", 7 }, { "such\n\nvery ", 2 }, { "color", 10 } }, kind = "echomsg" } - }} + {1:~ }|*4 + ]], + messages = { + { content = { { 'Press ENTER or type command to continue', 4 } }, kind = 'return_prompt' }, + }, + msg_history = { + { content = { { 'wow, ', 7 }, { 'such\n\nvery ', 2 }, { 'color', 10 } }, kind = 'echomsg' }, + }, + } feed '<cr>' - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]]} + {1:~ }|*4 + ]], + } end) it('does not truncate messages', function() - command('write '.. fname) - screen:expect({messages={ - {content = { { string.format('"%s" [New] 0L, 0B written', fname) } }, kind = "" } - }}) + command('write ' .. fname) + screen:expect({ + messages = { + { content = { { string.format('"%s" [New] 0L, 0B written', fname) } }, kind = '' }, + }, + }) end) end) @@ -968,26 +1103,27 @@ describe('ui/builtin messages', function() before_each(function() clear() screen = Screen.new(60, 7) - screen:attach({rgb=true, ext_popupmenu=true}) - screen:set_default_attr_ids { - [1] = {bold = true, foreground = Screen.colors.Blue1}; - [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}; - [3] = {bold = true, reverse = true}; - [4] = {bold = true, foreground = Screen.colors.SeaGreen4}; - [5] = {foreground = Screen.colors.Blue1}; - [6] = {bold = true, foreground = Screen.colors.Magenta}; - [7] = {background = Screen.colors.Grey20}; - [8] = {reverse = true}; - [9] = {background = Screen.colors.LightRed}; - [10] = {background = Screen.colors.Yellow}; - [11] = {foreground = Screen.colors.Brown}; + screen:attach({ rgb = true, ext_popupmenu = true }) + screen:set_default_attr_ids { + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [3] = { bold = true, reverse = true }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [5] = { foreground = Screen.colors.Blue1 }, + [6] = { bold = true, foreground = Screen.colors.Magenta }, + [7] = { background = Screen.colors.Grey20 }, + [8] = { reverse = true }, + [9] = { background = Screen.colors.LightRed }, + [10] = { background = Screen.colors.Yellow }, + [11] = { foreground = Screen.colors.Brown }, } end) it('supports multiline messages from rpc', function() feed(':call rpcrequest(1, "test_method")<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {3: }| {2:Error invoking 'test_method' on channel 1:} | {2:complete} | @@ -995,20 +1131,21 @@ describe('ui/builtin messages', function() | {2:message} | {4:Press ENTER or type command to continue}^ | - ]], request_cb=function (name) - if name == "test_method" then - set_method_error("complete\nerror\n\nmessage") - end - end} + ]], + request_cb = function(name) + if name == 'test_method' then + set_method_error('complete\nerror\n\nmessage') + end + end, + } end) it(':hi Group output', function() - screen:try_resize(70,7) + screen:try_resize(70, 7) feed(':hi ErrorMsg<cr>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {3: }| :hi ErrorMsg | ErrorMsg {2:xxx} {5:ctermfg=}15 {5:ctermbg=}1 {5:guifg=}White {5:guibg=}Red | @@ -1016,7 +1153,7 @@ describe('ui/builtin messages', function() ]]) feed('<cr>') - screen:try_resize(30,7) + screen:try_resize(30, 7) feed(':hi ErrorMsg<cr>') screen:expect([[ :hi ErrorMsg | @@ -1030,14 +1167,13 @@ describe('ui/builtin messages', function() feed('<cr>') -- screen size doesn't affect internal output #10285 - eq('ErrorMsg xxx ctermfg=15 ctermbg=1 guifg=White guibg=Red', - exec_capture("hi ErrorMsg")) + eq('ErrorMsg xxx ctermfg=15 ctermbg=1 guifg=White guibg=Red', exec_capture('hi ErrorMsg')) end) it(':syntax list langGroup output', function() - command("syntax on") - command("set syntax=vim") - screen:try_resize(110,7) + command('syntax on') + command('set syntax=vim') + screen:try_resize(110, 7) feed(':syntax list vimComment<cr>') screen:expect([[ {6:--- Syntax items ---} | @@ -1050,7 +1186,7 @@ describe('ui/builtin messages', function() ]]) feed('<cr>') - screen:try_resize(55,7) + screen:try_resize(55, 7) feed(':syntax list vimComment<cr>') screen:expect([[ | @@ -1065,12 +1201,14 @@ describe('ui/builtin messages', function() -- ignore final whitespace inside string -- luacheck: push ignore - eq([[--- Syntax items --- + eq( + [[--- Syntax items --- vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vimCommentGroup,vimCommentString match /\<endif\s\+".*$/ms=s+5,lc=5 contains=@vimCommentGroup,vimCommentString match /\<else\s\+".*$/ms=s+4,lc=4 contains=@vimCommentGroup,vimCommentString links to Comment]], - exec_capture('syntax list vimComment')) + exec_capture('syntax list vimComment') + ) -- luacheck: pop end) @@ -1090,103 +1228,91 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim endfunc ]]) feed(':call T1()<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 message T1 | - ]]} + ]], + } feed(':call T2()<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 message T2 | - ]]} + ]], + } feed(':call T3()<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 message T3 | - ]]} + ]], + } end) it('supports ruler with laststatus=0', function() - command("set ruler laststatus=0") - screen:expect{grid=[[ + command('set ruler laststatus=0') + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 0,0-1 All | - ]]} + ]], + } - command("hi MsgArea guibg=#333333") - screen:expect{grid=[[ + command('hi MsgArea guibg=#333333') + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {7: 0,0-1 All }| - ]]} + ]], + } - command("set rulerformat=%15(%c%V\\ %p%%%)") - screen:expect{grid=[[ + command('set rulerformat=%15(%c%V\\ %p%%%)') + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {7: 0,0-1 100% }| - ]]} + ]], + } end) it('supports echo with CRLF line separators', function() feed(':echo "line 1\\r\\nline 2"<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {3: }| line 1 | line 2 | {4:Press ENTER or type command to continue}^ | - ]]} + ]], + } feed('<cr>:echo "abc\\rz"<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 zbc | - ]]} + ]], + } end) it('redraws UPD_NOT_VALID correctly after message', function() -- edge case: only one window was set UPD_NOT_VALID. Original report -- used :make, but fake it using one command to set the current -- window UPD_NOT_VALID and another to show a long message. - command("set more") + command('set more') feed(':new<cr><c-w><c-w>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | {1:~ }| {8:[No Name] }| @@ -1194,10 +1320,12 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim {1:~ }| {3:[No Name] }| :new | - ]]} + ]], + } feed(':set colorcolumn=10 | digraphs<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ :set colorcolumn=10 | digraphs | NU {5:^@} 10 SH {5:^A} 1 SX {5:^B} 2 EX {5:^C} 3 | ET {5:^D} 4 EQ {5:^E} 5 AK {5:^F} 6 BL {5:^G} 7 | @@ -1205,10 +1333,12 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim FF {5:^L} 12 CR {5:^M} 13 SO {5:^N} 14 SI {5:^O} 15 | DL {5:^P} 16 D1 {5:^Q} 17 D2 {5:^R} 18 D3 {5:^S} 19 | {4:-- More --}^ | - ]]} + ]], + } feed('q') - screen:expect{grid=[[ + screen:expect { + grid = [[ | {1:~ }| {8:[No Name] }| @@ -1216,11 +1346,13 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim {1:~ }| {3:[No Name] }| | - ]]} + ]], + } -- edge case: just covers statusline feed(':set colorcolumn=5 | lua error("x\\n\\nx")<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:E5108: Error executing lua [string ":lua"]:1: x} | | {2:x} | @@ -1228,10 +1360,12 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim {2: [C]: in function 'error'} | {2: [string ":lua"]:1: in main chunk} | {4:Press ENTER or type command to continue}^ | - ]]} + ]], + } feed('<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | {1:~ }| {8:[No Name] }| @@ -1239,35 +1373,43 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim {1:~ }| {3:[No Name] }| | - ]]} + ]], + } -- edge case: just covers lowest window line feed(':set colorcolumn=5 | lua error("x\\n\\n\\nx")<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:E5108: Error executing lua [string ":lua"]:1: x} | - | - | + |*2 {2:x} | {2:stack traceback:} | {2: [C]: in function 'error'} | {4:-- More --}^ | - ]]} + ]], + } feed('<cr>') - screen:expect{grid=[[ - | - | + screen:expect { + grid = [[ + |*2 {2:x} | {2:stack traceback:} | {2: [C]: in function 'error'} | {2: [string ":lua"]:1: in main chunk} | {4:Press ENTER or type command to continue}^ | - ]]} + ]], + } end) it('supports nvim_echo messages with multiple attrs', function() - async_meths.echo({{'wow, ',"Search"}, {"such\n\nvery ", "ErrorMsg"}, {"color", "LineNr"}}, true, {}) - screen:expect{grid=[[ + async_meths.nvim_echo( + { { 'wow, ', 'Search' }, { 'such\n\nvery ', 'ErrorMsg' }, { 'color', 'LineNr' } }, + true, + {} + ) + screen:expect { + grid = [[ | {1:~ }| {3: }| @@ -1275,21 +1417,21 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim | {2:very }{11:color} | {4:Press ENTER or type command to continue}^ | - ]]} + ]], + } feed '<cr>' - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | - ]]} + ]], + } feed ':messages<cr>' - screen:expect{grid=[[ + screen:expect { + grid = [[ | {1:~ }| {3: }| @@ -1297,12 +1439,13 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim | {2:very }{11:color} | {4:Press ENTER or type command to continue}^ | - ]]} + ]], + } end) it('prints lines in Ex mode correctly with a burst of carriage returns #19341', function() command('set number') - meths.buf_set_lines(0, 0, 0, true, {'aaa', 'bbb', 'ccc'}) + api.nvim_buf_set_lines(0, 0, 0, true, { 'aaa', 'bbb', 'ccc' }) feed('gggQ<CR><CR>1<CR><CR>vi') screen:expect([[ Entering Ex mode. Type "visual" to go to Normal mode. | @@ -1319,8 +1462,7 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim {11: 2 }^bbb | {11: 3 }ccc | {11: 4 } | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) end) @@ -1339,19 +1481,21 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim endfunc ]]):format(to_block)) feed(':call PrintAndWait()<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {3: }| aaa | bbb^ | - ]], timeout=timeout} + ]], + timeout = timeout, + } if type(to_unblock) == 'string' then feed(to_unblock) end - screen:expect{grid=[[ + screen:expect { + grid = [[ | {1:~ }| {3: }| @@ -1359,7 +1503,8 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim bbb | ccc | {4:Press ENTER or type command to continue}^ | - ]]} + ]], + } end it('getchar()', function() @@ -1375,17 +1520,18 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim end) end) - it('consecutive calls to win_move_statusline() work after multiline message #21014',function() - async_meths.exec([[ + it('consecutive calls to win_move_statusline() work after multiline message #21014', function() + async_meths.nvim_exec( + [[ echo "\n" call win_move_statusline(0, -4) call win_move_statusline(0, 4) - ]], false) + ]], + false + ) screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {3: }| | {4:Press ENTER or type command to continue}^ | @@ -1393,14 +1539,10 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim feed('<CR>') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | ]]) - eq(1, meths.get_option_value('cmdheight', {})) + eq(1, api.nvim_get_option_value('cmdheight', {})) end) it('using nvim_echo in VimResized does not cause hit-enter prompt #26139', function() @@ -1408,12 +1550,27 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim screen:try_resize(60, 5) screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]) - eq({ mode = 'n', blocking = false }, meths.get_mode()) + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) + end) + + it('bottom of screen is cleared after increasing &cmdheight #20360', function() + command('set laststatus=2') + screen:expect([[ + ^ | + {1:~ }|*4 + {3:[No Name] }| + | + ]]) + command('set cmdheight=4') + screen:expect([[ + ^ | + {1:~ }| + {3:[No Name] }| + |*4 + ]]) end) end) @@ -1432,17 +1589,17 @@ describe('ui/ext_messages', function() local screen before_each(function() - clear{args_rm={'--headless'}, args={"--cmd", "set shortmess-=I"}} + clear { args_rm = { '--headless' }, args = { '--cmd', 'set shortmess-=I' } } screen = Screen.new(80, 24) - screen:attach({rgb=true, ext_messages=true, ext_popupmenu=true}) + screen:attach({ rgb = true, ext_messages = true, ext_popupmenu = true }) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [3] = {bold = true}, - [4] = {bold = true, foreground = Screen.colors.SeaGreen4}, - [5] = {foreground = Screen.colors.Blue1}, - [6] = {reverse = true}, - [7] = {bold = true, reverse = true}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [3] = { bold = true }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [5] = { foreground = Screen.colors.Blue1 }, + [6] = { reverse = true }, + [7] = { bold = true, reverse = true }, }) end) @@ -1451,10 +1608,7 @@ describe('ui/ext_messages', function() -- Note parts of it depends on version or is indeterministic. We ignore those parts. screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {MATCH:.*}| {1:~ }| {1:~ }Nvim is open source and freely distributable{1: }| @@ -1467,50 +1621,21 @@ describe('ui/ext_messages', function() {1:~ }| {1:~{MATCH: +}}type :help news{5:<Enter>} to see changes in v{MATCH:%d+%.%d+}{1:{MATCH: +}}| {1:~ }| - {MATCH:.*}| - {MATCH:.*}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {MATCH:.*}|*2 + {1:~ }|*5 ]]) - feed("<c-l>") + feed('<c-l>') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*23 ]]) - feed(":intro<cr>") - screen:expect{grid=[[ + feed(':intro<cr>') + screen:expect { + grid = [[ ^ | - | - | - | - | + |*4 {MATCH:.*}| | Nvim is open source and freely distributable | @@ -1523,116 +1648,68 @@ describe('ui/ext_messages', function() | {MATCH: +}type :help news{5:<Enter>} to see changes in v{MATCH:%d+%.%d+ +}| | - {MATCH:.*}| - {MATCH:.*}| - | - | - | - | - | - ]], messages={ - {content = { { "Press ENTER or type command to continue", 4 } }, kind = "return_prompt" } - }} + {MATCH:.*}|*2 + |*5 + ]], + messages = { + { content = { { 'Press ENTER or type command to continue', 4 } }, kind = 'return_prompt' }, + }, + } end) it('supports global statusline', function() - feed(":set laststatus=3<cr>") - feed(":sp<cr>") - feed(":set cmdheight<cr>") - screen:expect({grid=[[ + feed(':set laststatus=3<cr>') + feed(':sp<cr>') + feed(':set cmdheight<cr>') + screen:expect({ + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*10 ────────────────────────────────────────────────────────────────────────────────| | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*10 {7:[No Name] }| - ]], messages={ - {content = { { " cmdheight=0" } }, kind = "" } - }}) + ]], + messages = { + { content = { { ' cmdheight=0' } }, kind = '' }, + }, + }) - feed("<c-w>+") - feed(":set laststatus<cr>") - screen:expect({grid=[[ + feed('<c-w>+') + feed(':set laststatus<cr>') + screen:expect({ + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ────────────────────────────────────────────────────────────────────────────────| | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*9 {7:[No Name] }| - ]], messages={ - {content = { { " laststatus=3" } }, kind = "" } - }}) + ]], + messages = { + { content = { { ' laststatus=3' } }, kind = '' }, + }, + }) - feed(":set mouse=a<cr>") - meths.input_mouse('left', 'press', '', 0, 12, 10) + feed(':set mouse=a<cr>') + api.nvim_input_mouse('left', 'press', '', 0, 12, 10) poke_eventloop() - meths.input_mouse('left', 'drag', '', 0, 11, 10) - feed("<c-l>") - feed(":set cmdheight<cr>") - screen:expect({grid=[[ + api.nvim_input_mouse('left', 'drag', '', 0, 11, 10) + feed('<c-l>') + feed(':set cmdheight<cr>') + screen:expect({ + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*10 ────────────────────────────────────────────────────────────────────────────────| | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*10 {7:[No Name] }| - ]], messages={ - {content = { { " cmdheight=0" } }, kind = "" } - }}) + ]], + messages = { + { content = { { ' cmdheight=0' } }, kind = '' }, + }, + }) end) end) @@ -1640,9 +1717,9 @@ describe('ui/msg_puts_printf', function() it('output multibyte characters correctly', function() local screen local cmd = '' - local locale_dir = test_build_dir..'/share/locale/ja/LC_MESSAGES' + local locale_dir = test_build_dir .. '/share/locale/ja/LC_MESSAGES' - clear({env={LANG='ja_JP.UTF-8'}}) + clear({ env = { LANG = 'ja_JP.UTF-8' } }) screen = Screen.new(25, 5) screen:attach() @@ -1654,7 +1731,7 @@ describe('ui/msg_puts_printf', function() cmd = 'chcp 932 > NULL & ' end else - if (exc_exec('lang ja_JP.UTF-8') ~= 0) then + if exc_exec('lang ja_JP.UTF-8') ~= 0 then pending('Locale ja_JP.UTF-8 not supported', function() end) return elseif is_ci() then @@ -1664,11 +1741,13 @@ describe('ui/msg_puts_printf', function() end end - os.execute('cmake -E make_directory '..locale_dir) - os.execute('cmake -E copy '..test_build_dir..'/src/nvim/po/ja.mo '..locale_dir..'/nvim.mo') + os.execute('cmake -E make_directory ' .. locale_dir) + os.execute( + 'cmake -E copy ' .. test_build_dir .. '/src/nvim/po/ja.mo ' .. locale_dir .. '/nvim.mo' + ) - cmd = cmd..'"'..nvim_prog..'" -u NONE -i NONE -Es -V1' - command([[call termopen(']]..cmd..[[')]]) + cmd = cmd .. '"' .. nvim_prog .. '" -u NONE -i NONE -Es -V1' + command([[call termopen(']] .. cmd .. [[')]]) screen:expect([[ ^Exモードに入ります. ノー | マルモードに戻るには"visu| @@ -1677,7 +1756,7 @@ describe('ui/msg_puts_printf', function() | ]]) - os.execute('cmake -E remove_directory '..test_build_dir..'/share') + os.execute('cmake -E remove_directory ' .. test_build_dir .. '/share') end) end) @@ -1689,92 +1768,108 @@ describe('pager', function() screen = Screen.new(35, 8) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red, special=Screen.colors.Yellow}, - [4] = {bold = true, foreground = Screen.colors.SeaGreen4}, - [5] = {special = Screen.colors.Yellow}, - [6] = {special = Screen.colors.Yellow, bold = true, foreground = Screen.colors.SeaGreen4}, - [7] = {foreground = Screen.colors.Grey0, background = Screen.colors.Grey100}, - [8] = {foreground = Screen.colors.Gray90, background = Screen.colors.Grey100}, - [9] = {foreground = tonumber('0x00000c'), background = Screen.colors.Grey100}, - [10] = {background = Screen.colors.Grey100, bold = true, foreground = tonumber('0xe5e5ff')}, - [11] = {background = Screen.colors.Grey100, bold = true, foreground = tonumber ('0x2b8452')}, - [12] = {bold = true, reverse = true}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [3] = { + foreground = Screen.colors.Grey100, + background = Screen.colors.Red, + special = Screen.colors.Yellow, + }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [5] = { special = Screen.colors.Yellow }, + [6] = { special = Screen.colors.Yellow, bold = true, foreground = Screen.colors.SeaGreen4 }, + [7] = { foreground = Screen.colors.Grey0, background = Screen.colors.Grey100 }, + [8] = { foreground = Screen.colors.Gray90, background = Screen.colors.Grey100 }, + [9] = { foreground = tonumber('0x00000c'), background = Screen.colors.Grey100 }, + [10] = { background = Screen.colors.Grey100, bold = true, foreground = tonumber('0xe5e5ff') }, + [11] = { background = Screen.colors.Grey100, bold = true, foreground = tonumber('0x2b8452') }, + [12] = { bold = true, reverse = true }, }) - command("set more") + command('set more') - exec_lua('_G.x = ...', [[ + exec_lua( + '_G.x = ...', + [[ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud xercitation ullamco laboris nisi ut -aliquip ex ea commodo consequat.]]) +aliquip ex ea commodo consequat.]] + ) end) it('can be quit with echon', function() - screen:try_resize(25,5) + screen:try_resize(25, 5) feed(':echon join(map(range(0, &lines*10), "v:val"), "\\n")<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ 0 | 1 | 2 | 3 | {4:-- More --}^ | - ]]} + ]], + } feed('q') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]]} + ]], + } end) it('can be quit with Lua #11224 #16537', function() -- NOTE: adds "4" to message history, although not displayed initially -- (triggered the more prompt). - screen:try_resize(40,5) + screen:try_resize(40, 5) feed(':lua for i=0,10 do print(i) end<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ 0 | 1 | 2 | 3 | {4:-- More --}^ | - ]]} + ]], + } feed('q') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]]} + ]], + } feed(':mess<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ 0 | 1 | 2 | 3 | {4:-- More --}^ | - ]]} + ]], + } feed('j') - screen:expect{grid=[[ + screen:expect { + grid = [[ 1 | 2 | 3 | 4 | {4:Press ENTER or type command to continue}^ | - ]]} + ]], + } feed('<cr>') end) it('handles wrapped lines with line scroll', function() feed(':lua error(_G.x)<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:E5108: Error executing lua [string }| {2:":lua"]:1: Lorem ipsum dolor sit am}| {2:et, consectetur} | @@ -1783,10 +1878,12 @@ aliquip ex ea commodo consequat.]]) {2:incididunt ut labore et dolore magn}| {2:a aliqua.} | {4:-- More --}^ | - ]]} + ]], + } feed('j') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:":lua"]:1: Lorem ipsum dolor sit am}| {2:et, consectetur} | {2:adipisicing elit, sed do eiusmod te}| @@ -1795,10 +1892,12 @@ aliquip ex ea commodo consequat.]]) {2:a aliqua.} | {2:Ut enim ad minim veniam, quis nostr}| {4:-- More --}^ | - ]]} + ]], + } feed('k') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:E5108: Error executing lua [string }| {2:":lua"]:1: Lorem ipsum dolor sit am}| {2:et, consectetur} | @@ -1807,10 +1906,12 @@ aliquip ex ea commodo consequat.]]) {2:incididunt ut labore et dolore magn}| {2:a aliqua.} | {4:-- More --}^ | - ]]} + ]], + } feed('j') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:":lua"]:1: Lorem ipsum dolor sit am}| {2:et, consectetur} | {2:adipisicing elit, sed do eiusmod te}| @@ -1819,12 +1920,14 @@ aliquip ex ea commodo consequat.]]) {2:a aliqua.} | {2:Ut enim ad minim veniam, quis nostr}| {4:-- More --}^ | - ]]} + ]], + } end) it('handles wrapped lines with page scroll', function() feed(':lua error(_G.x)<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:E5108: Error executing lua [string }| {2:":lua"]:1: Lorem ipsum dolor sit am}| {2:et, consectetur} | @@ -1833,9 +1936,11 @@ aliquip ex ea commodo consequat.]]) {2:incididunt ut labore et dolore magn}| {2:a aliqua.} | {4:-- More --}^ | - ]]} + ]], + } feed('d') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:mpor} | {2:incididunt ut labore et dolore magn}| {2:a aliqua.} | @@ -1844,9 +1949,11 @@ aliquip ex ea commodo consequat.]]) {2:ullamco laboris nisi ut} | {2:aliquip ex ea commodo consequat.} | {4:-- More --}^ | - ]]} + ]], + } feed('u') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:E5108: Error executing lua [string }| {2:":lua"]:1: Lorem ipsum dolor sit am}| {2:et, consectetur} | @@ -1855,9 +1962,11 @@ aliquip ex ea commodo consequat.]]) {2:incididunt ut labore et dolore magn}| {2:a aliqua.} | {4:-- More --}^ | - ]]} + ]], + } feed('d') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:mpor} | {2:incididunt ut labore et dolore magn}| {2:a aliqua.} | @@ -1866,14 +1975,16 @@ aliquip ex ea commodo consequat.]]) {2:ullamco laboris nisi ut} | {2:aliquip ex ea commodo consequat.} | {4:-- More --}^ | - ]]} + ]], + } end) it('handles wrapped lines with line scroll and MsgArea highlight', function() - command("hi MsgArea guisp=Yellow") + command('hi MsgArea guisp=Yellow') feed(':lua error(_G.x)<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:E5108: Error executing lua [string }| {3:":lua"]:1: Lorem ipsum dolor sit am}| {3:et, consectetur}{5: }| @@ -1882,10 +1993,12 @@ aliquip ex ea commodo consequat.]]) {3:incididunt ut labore et dolore magn}| {3:a aliqua.}{5: }| {6:-- More --}{5:^ }| - ]]} + ]], + } feed('j') - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:":lua"]:1: Lorem ipsum dolor sit am}| {3:et, consectetur}{5: }| {3:adipisicing elit, sed do eiusmod te}| @@ -1894,10 +2007,12 @@ aliquip ex ea commodo consequat.]]) {3:a aliqua.}{5: }| {3:Ut enim ad minim veniam, quis nostr}| {6:-- More --}{5:^ }| - ]]} + ]], + } feed('k') - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:E5108: Error executing lua [string }| {3:":lua"]:1: Lorem ipsum dolor sit am}| {3:et, consectetur}{5: }| @@ -1906,10 +2021,12 @@ aliquip ex ea commodo consequat.]]) {3:incididunt ut labore et dolore magn}| {3:a aliqua.}{5: }| {6:-- More --}{5:^ }| - ]]} + ]], + } feed('j') - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:":lua"]:1: Lorem ipsum dolor sit am}| {3:et, consectetur}{5: }| {3:adipisicing elit, sed do eiusmod te}| @@ -1918,13 +2035,15 @@ aliquip ex ea commodo consequat.]]) {3:a aliqua.}{5: }| {3:Ut enim ad minim veniam, quis nostr}| {6:-- More --}{5:^ }| - ]]} + ]], + } end) it('handles wrapped lines with page scroll and MsgArea highlight', function() - command("hi MsgArea guisp=Yellow") + command('hi MsgArea guisp=Yellow') feed(':lua error(_G.x)<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:E5108: Error executing lua [string }| {3:":lua"]:1: Lorem ipsum dolor sit am}| {3:et, consectetur}{5: }| @@ -1933,9 +2052,11 @@ aliquip ex ea commodo consequat.]]) {3:incididunt ut labore et dolore magn}| {3:a aliqua.}{5: }| {6:-- More --}{5:^ }| - ]]} + ]], + } feed('d') - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:mpor}{5: }| {3:incididunt ut labore et dolore magn}| {3:a aliqua.}{5: }| @@ -1944,9 +2065,11 @@ aliquip ex ea commodo consequat.]]) {3:ullamco laboris nisi ut}{5: }| {3:aliquip ex ea commodo consequat.}{5: }| {6:-- More --}{5:^ }| - ]]} + ]], + } feed('u') - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:E5108: Error executing lua [string }| {3:":lua"]:1: Lorem ipsum dolor sit am}| {3:et, consectetur}{5: }| @@ -1955,9 +2078,11 @@ aliquip ex ea commodo consequat.]]) {3:incididunt ut labore et dolore magn}| {3:a aliqua.}{5: }| {6:-- More --}{5:^ }| - ]]} + ]], + } feed('d') - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:mpor}{5: }| {3:incididunt ut labore et dolore magn}| {3:a aliqua.}{5: }| @@ -1966,52 +2091,60 @@ aliquip ex ea commodo consequat.]]) {3:ullamco laboris nisi ut}{5: }| {3:aliquip ex ea commodo consequat.}{5: }| {6:-- More --}{5:^ }| - ]]} + ]], + } end) it('preserves MsgArea highlighting after more prompt', function() - screen:try_resize(70,6) - command("hi MsgArea guisp=Yellow") - command("map x Lorem ipsum labore et dolore magna aliqua") - command("map y adipisicing elit") - command("map z incididunt ut") - command("map a labore et dolore") - command("map b ex ea commodo") - command("map xx yy") - command("map xy yz") + screen:try_resize(70, 6) + command('hi MsgArea guisp=Yellow') + command('map x Lorem ipsum labore et dolore magna aliqua') + command('map y adipisicing elit') + command('map z incididunt ut') + command('map a labore et dolore') + command('map b ex ea commodo') + command('map xx yy') + command('map xy yz') feed(':map<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {5: a labore et dolore }| {5: b ex ea commodo }| {5: xy yz }| {5: xx yy }| {5: x Lorem ipsum labore et dolore magna aliqua }| {6:-- More --}{5:^ }| - ]]} + ]], + } feed('j') - screen:expect{grid=[[ + screen:expect { + grid = [[ {5: b ex ea commodo }| {5: xy yz }| {5: xx yy }| {5: x Lorem ipsum labore et dolore magna aliqua }| {5: y adipisicing elit }| {6:-- More --}{5:^ }| - ]]} + ]], + } feed('j') - screen:expect{grid=[[ + screen:expect { + grid = [[ {5: xy yz }| {5: xx yy }| {5: x Lorem ipsum labore et dolore magna aliqua }| {5: y adipisicing elit }| {5: z incididunt ut }| {6:Press ENTER or type command to continue}{5:^ }| - ]]} + ]], + } end) it('clears "-- more --" message', function() - command("hi MsgArea guisp=Yellow blend=10") + command('hi MsgArea guisp=Yellow blend=10') feed(':echon join(range(20), "\\n")<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {7:0}{8: }| {9:1}{10: }| {9:2}{10: }| @@ -2020,10 +2153,12 @@ aliquip ex ea commodo consequat.]]) {9:5}{10: }| {9:6}{10: }| {11:--}{8: }{11:More}{8: }{11:--}{8:^ }| - ]]} + ]], + } feed('j') - screen:expect{grid=[[ + screen:expect { + grid = [[ {7:1}{8: }| {9:2}{10: }| {9:3}{10: }| @@ -2032,10 +2167,12 @@ aliquip ex ea commodo consequat.]]) {9:6}{10: }| {9:7}{10: }| {11:--}{8: }{11:More}{8: }{11:--}{8:^ }| - ]]} + ]], + } feed('k') - screen:expect{grid=[[ + screen:expect { + grid = [[ {7:0}{8: }| {9:1}{10: }| {9:2}{10: }| @@ -2044,10 +2181,12 @@ aliquip ex ea commodo consequat.]]) {9:5}{10: }| {9:6}{10: }| {11:--}{8: }{11:More}{8: }{11:--}{8:^ }| - ]]} + ]], + } feed('j') - screen:expect{grid=[[ + screen:expect { + grid = [[ {7:1}{8: }| {9:2}{10: }| {9:3}{10: }| @@ -2056,52 +2195,54 @@ aliquip ex ea commodo consequat.]]) {9:6}{10: }| {9:7}{10: }| {11:--}{8: }{11:More}{8: }{11:--}{8:^ }| - ]]} + ]], + } end) it('with :!cmd does not crash on resize', function() - skip(funcs.executable('sleep') == 0, 'missing "sleep" command') + skip(fn.executable('sleep') == 0, 'missing "sleep" command') feed(':!sleep 1<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {12: }| :!sleep 1 | | - ]]} + ]], + } -- not processed while command is executing - async_meths.ui_try_resize(35, 5) + async_meths.nvim_ui_try_resize(35, 5) -- TODO(bfredl): ideally it should be processed just -- before the "press ENTER" prompt though - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {12: }| :!sleep 1 | | {4:Press ENTER or type command to cont}| {4:inue}^ | - ]]} + ]], + } feed('<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]]} + ]], + } end) it('can be resized', function() feed(':lua error(_G.x)<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:E5108: Error executing lua [string }| {2:":lua"]:1: Lorem ipsum dolor sit am}| {2:et, consectetur} | @@ -2110,22 +2251,26 @@ aliquip ex ea commodo consequat.]]) {2:incididunt ut labore et dolore magn}| {2:a aliqua.} | {4:-- More --}^ | - ]]} + ]], + } -- responds to resize, but text is not reflown screen:try_resize(45, 5) - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:adipisicing elit, sed do eiusmod te} | {2:mpor} | {2:incididunt ut labore et dolore magn} | {2:a aliqua.} | {4:-- More --}^ | - ]]} + ]], + } -- can create empty space, as the command hasn't output the text below yet. -- text is not reflown; existing lines get cut screen:try_resize(30, 12) - screen:expect{grid=[[ + screen:expect { + grid = [[ :lua error(_G.x) | {2:E5108: Error executing lua [st}| {2:":lua"]:1: Lorem ipsum dolor s}| @@ -2134,16 +2279,16 @@ aliquip ex ea commodo consequat.]]) {2:mpore} | {2:incididunt ut labore et dolore}| {2:a aliqua.} | - | - | - | + |*3 {4:-- More --}^ | - ]]} + ]], + } -- continues in a mostly consistent state, but only new lines are -- wrapped at the new screen size. feed('<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:E5108: Error executing lua [st}| {2:":lua"]:1: Lorem ipsum dolor s}| {2:et, consectetur} | @@ -2156,10 +2301,12 @@ aliquip ex ea commodo consequat.]]) {2:ullamco laboris nisi ut} | {2:aliquip ex ea commodo consequa}| {4:-- More --}^ | - ]]} + ]], + } feed('<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {2:":lua"]:1: Lorem ipsum dolor s}| {2:et, consectetur} | {2:adipisicing elit, sed do eiusm}| @@ -2172,29 +2319,24 @@ aliquip ex ea commodo consequat.]]) {2:aliquip ex ea commodo consequa}| {2:t.} | {4:-- More --}^ | - ]]} + ]], + } feed('q') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*10 | - ]]} + ]], + } end) it('with cmdheight=0 does not crash with g<', function() command('set cmdheight=0') feed(':ls<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | {1:~ }| {12: }| @@ -2203,22 +2345,20 @@ aliquip ex ea commodo consequat.]]) line 1 | {4:Press ENTER or type command to cont}| {4:inue}^ | - ]]} + ]], + } feed('<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]]} + {1:~ }|*7 + ]], + } feed('g<lt>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | {1:~ }| {12: }| @@ -2227,18 +2367,15 @@ aliquip ex ea commodo consequat.]]) line 1 | {4:Press ENTER or type command to cont}| {4:inue}^ | - ]]} + ]], + } feed('<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]]} + {1:~ }|*7 + ]], + } end) end) diff --git a/test/functional/ui/mode_spec.lua b/test/functional/ui/mode_spec.lua index e870d6f25f..8d7fae3e91 100644 --- a/test/functional/ui/mode_spec.lua +++ b/test/functional/ui/mode_spec.lua @@ -11,39 +11,45 @@ describe('ui mode_change event', function() before_each(function() clear() screen = Screen.new(25, 4) - screen:attach({rgb= true}) - screen:set_default_attr_ids( { - [0] = {bold=true, foreground=255}, - [1] = {bold=true, reverse=true}, - [2] = {bold=true}, - [3] = {reverse=true}, - [4] = {background=Screen.colors.Red, foreground=Screen.colors.White}, -- ErrorMsg + screen:attach({ rgb = true }) + screen:set_default_attr_ids({ + [0] = { bold = true, foreground = 255 }, + [1] = { bold = true, reverse = true }, + [2] = { bold = true }, + [3] = { reverse = true }, + [4] = { background = Screen.colors.Red, foreground = Screen.colors.White }, -- ErrorMsg }) end) it('works in normal mode', function() - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]], mode="normal"} + ]], + mode = 'normal', + } feed('d') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]], mode="operator"} + ]], + mode = 'operator', + } feed('<esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]], mode="normal"} + ]], + mode = 'normal', + } end) -- oldtest: Test_mouse_shape_after_failed_change() @@ -52,185 +58,226 @@ describe('ui mode_change event', function() command('set nomodifiable') feed('c') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]], mode="operator"} + ]], + mode = 'operator', + } feed('c') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {4:E21: Cannot make changes, 'modifiable' is off} | - ]], mode="normal"} + ]], + mode = 'normal', + } end) -- oldtest: Test_mouse_shape_after_cancelling_gr() it('is restored to Normal mode after cancelling "gr"', function() feed('gr') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]], mode="replace"} + ]], + mode = 'replace', + } feed('<Esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]], mode="normal"} + ]], + mode = 'normal', + } end) it('works in insert mode', function() feed('i') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {2:-- INSERT --} | - ]], mode="insert"} + ]], + mode = 'insert', + } feed('word<esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ wor^d | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]], mode="normal"} + ]], + mode = 'normal', + } local matchtime = 0 - command("set showmatch") + command('set showmatch') retry(nil, nil, function() matchtime = matchtime + 1 - local screen_timeout = 1000 * matchtime -- fail faster for retry. + local screen_timeout = 1000 * matchtime -- fail faster for retry. - command("set matchtime=" .. matchtime) -- tenths of seconds + command('set matchtime=' .. matchtime) -- tenths of seconds feed('a(stuff') - screen:expect{grid=[[ + screen:expect { + grid = [[ word(stuff^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {2:-- INSERT --} | - ]], mode="insert", timeout=screen_timeout} + ]], + mode = 'insert', + timeout = screen_timeout, + } feed(')') - screen:expect{grid=[[ + screen:expect { + grid = [[ word^(stuff) | - {0:~ }| - {0:~ }| + {0:~ }|*2 {2:-- INSERT --} | - ]], mode="showmatch", timeout=screen_timeout} + ]], + mode = 'showmatch', + timeout = screen_timeout, + } - screen:expect{grid=[[ + screen:expect { + grid = [[ word(stuff)^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {2:-- INSERT --} | - ]], mode="insert", timeout=screen_timeout} + ]], + mode = 'insert', + timeout = screen_timeout, + } end) end) it('works in replace mode', function() feed('R') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {2:-- REPLACE --} | - ]], mode="replace"} + ]], + mode = 'replace', + } feed('word<esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ wor^d | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]], mode="normal"} + ]], + mode = 'normal', + } end) it('works in cmdline mode', function() feed(':') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| + {0:~ }|*2 :^ | - ]], mode="cmdline_normal"} + ]], + mode = 'cmdline_normal', + } feed('x<left>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| + {0:~ }|*2 :^x | - ]], mode="cmdline_insert"} + ]], + mode = 'cmdline_insert', + } feed('<insert>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| + {0:~ }|*2 :^x | - ]], mode="cmdline_replace"} - + ]], + mode = 'cmdline_replace', + } feed('<right>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| + {0:~ }|*2 :x^ | - ]], mode="cmdline_normal"} + ]], + mode = 'cmdline_normal', + } feed('<esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]], mode="normal"} + ]], + mode = 'normal', + } end) it('works in visual mode', function() - insert("text") + insert('text') feed('v') - screen:expect{grid=[[ + screen:expect { + grid = [[ tex^t | - {0:~ }| - {0:~ }| + {0:~ }|*2 {2:-- VISUAL --} | - ]], mode="visual"} + ]], + mode = 'visual', + } feed('<esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ tex^t | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]], mode="normal"} + ]], + mode = 'normal', + } command('set selection=exclusive') feed('v') - screen:expect{grid=[[ + screen:expect { + grid = [[ tex^t | - {0:~ }| - {0:~ }| + {0:~ }|*2 {2:-- VISUAL --} | - ]], mode="visual_select"} + ]], + mode = 'visual_select', + } feed('<esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ tex^t | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]], mode="normal"} + ]], + mode = 'normal', + } end) end) - diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua index 1356ba3db8..0f30bf4471 100644 --- a/test/functional/ui/mouse_spec.lua +++ b/test/functional/ui/mouse_spec.lua @@ -1,8 +1,8 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local clear, feed, meths = helpers.clear, helpers.feed, helpers.meths +local clear, feed, api = helpers.clear, helpers.feed, helpers.api local insert, feed_command = helpers.insert, helpers.feed_command -local eq, funcs = helpers.eq, helpers.funcs +local eq, fn = helpers.eq, helpers.fn local poke_eventloop = helpers.poke_eventloop local command = helpers.command local exec = helpers.exec @@ -12,8 +12,8 @@ describe('ui/mouse/input', function() before_each(function() clear() - meths.set_option_value('mouse', 'a', {}) - meths.set_option_value('list', true, {}) + api.nvim_set_option_value('mouse', 'a', {}) + api.nvim_set_option_value('list', true, {}) -- NB: this is weird, but mostly irrelevant to the test -- So I didn't bother to change it command('set listchars=eol:$') @@ -21,21 +21,21 @@ describe('ui/mouse/input', function() screen = Screen.new(25, 5) screen:attach() screen:set_default_attr_ids({ - [0] = {bold=true, foreground=Screen.colors.Blue}, - [1] = {background = Screen.colors.LightGrey}, - [2] = {bold = true}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { background = Screen.colors.LightGrey, foreground = Screen.colors.Black }, + [2] = { bold = true }, [3] = { foreground = Screen.colors.Blue, background = Screen.colors.LightGrey, bold = true, }, - [4] = {reverse = true}, - [5] = {bold = true, reverse = true}, - [6] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [7] = {bold = true, foreground = Screen.colors.SeaGreen4}, - [8] = {foreground = Screen.colors.Brown}, + [4] = { reverse = true }, + [5] = { bold = true, reverse = true }, + [6] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [7] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [8] = { foreground = Screen.colors.Brown }, }) - command("set mousemodel=extend") + command('set mousemodel=extend') feed('itesting<cr>mouse<cr>support and selection<esc>') screen:expect([[ testing | @@ -48,13 +48,16 @@ describe('ui/mouse/input', function() it('single left click moves cursor', function() feed('<LeftMouse><2,1>') - screen:expect{grid=[[ + screen:expect { + grid = [[ testing | mo^use | support and selection | {0:~ }| | - ]], mouse_enabled=true} + ]], + mouse_enabled = true, + } feed('<LeftMouse><0,0>') screen:expect([[ ^testing | @@ -66,15 +69,18 @@ describe('ui/mouse/input', function() end) it("in external ui works with unset 'mouse'", function() - meths.set_option_value('mouse', '', {}) + api.nvim_set_option_value('mouse', '', {}) feed('<LeftMouse><2,1>') - screen:expect{grid=[[ + screen:expect { + grid = [[ testing | mo^use | support and selection | {0:~ }| | - ]], mouse_enabled=false} + ]], + mouse_enabled = false, + } feed('<LeftMouse><0,0>') screen:expect([[ ^testing | @@ -135,11 +141,11 @@ describe('ui/mouse/input', function() describe('tab drag', function() before_each(function() - screen:set_default_attr_ids( { - [0] = {bold=true, foreground=Screen.colors.Blue}, - tab = { background=Screen.colors.LightGrey, underline=true }, - sel = { bold=true }, - fill = { reverse=true } + screen:set_default_attr_ids({ + [0] = { bold = true, foreground = Screen.colors.Blue }, + tab = { background = Screen.colors.LightGrey, underline = true }, + sel = { bold = true }, + fill = { reverse = true }, }) end) @@ -151,24 +157,21 @@ describe('ui/mouse/input', function() screen:expect([[ {tab: + foo }{sel: + bar }{fill: }{tab:X}| this is ba^r{0:$} | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) feed('<LeftMouse><4,0>') screen:expect([[ {sel: + foo }{tab: + bar }{fill: }{tab:X}| this is fo^o | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) feed('<LeftDrag><14,0>') screen:expect([[ {tab: + bar }{sel: + foo }{fill: }{tab:X}| this is fo^o | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end) @@ -181,24 +184,27 @@ describe('ui/mouse/input', function() screen:expect([[ {tab: + foo }{sel: + bar }{fill: }{tab:X}| this is ba^r{0:$} | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) feed('<LeftMouse><11,0>') - screen:expect{grid=[[ + -- Prevent the case where screen:expect() with "unchanged" returns too early, + -- causing the click position to be overwritten by the next drag. + poke_eventloop() + screen:expect { + grid = [[ {tab: + foo }{sel: + bar }{fill: }{tab:X}| this is ba^r{0:$} | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]], unchanged=true} + ]], + unchanged = true, + } feed('<LeftDrag><6,0>') screen:expect([[ {sel: + bar }{tab: + foo }{fill: }{tab:X}| this is ba^r{0:$} | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end) @@ -211,24 +217,21 @@ describe('ui/mouse/input', function() screen:expect([[ {tab: + foo }{sel: + bar }{fill: }{tab:X}| this is ba^r{0:$} | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) feed('<LeftMouse><4,0>') screen:expect([[ {sel: + foo }{tab: + bar }{fill: }{tab:X}| this is fo^o | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) feed('<LeftDrag><7,0>') screen:expect([[ {tab: + bar }{sel: + foo }{fill: }{tab:X}| this is fo^o | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end) @@ -241,32 +244,31 @@ describe('ui/mouse/input', function() screen:expect([[ {tab: + foo }{sel: + bar }{fill: }{tab:X}| this is ba^r{0:$} | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) feed('<LeftMouse><4,0>') screen:expect([[ {sel: + foo }{tab: + bar }{fill: }{tab:X}| this is fo^o | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) feed('<LeftDrag><4,1>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {sel: + foo }{tab: + bar }{fill: }{tab:X}| this is fo^o | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]], unchanged=true} + ]], + unchanged = true, + } feed('<LeftDrag><14,1>') screen:expect([[ {tab: + bar }{sel: + foo }{fill: }{tab:X}| this is fo^o | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end) @@ -279,32 +281,37 @@ describe('ui/mouse/input', function() screen:expect([[ {tab: + foo }{sel: + bar }{fill: }{tab:X}| this is ba^r{0:$} | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) feed('<LeftMouse><11,0>') - screen:expect{grid=[[ + -- Prevent the case where screen:expect() with "unchanged" returns too early, + -- causing the click position to be overwritten by the next drag. + poke_eventloop() + screen:expect { + grid = [[ {tab: + foo }{sel: + bar }{fill: }{tab:X}| this is ba^r{0:$} | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]], unchanged=true} + ]], + unchanged = true, + } feed('<LeftDrag><11,1>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {tab: + foo }{sel: + bar }{fill: }{tab:X}| this is ba^r{0:$} | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]], unchanged=true} + ]], + unchanged = true, + } feed('<LeftDrag><6,1>') screen:expect([[ {sel: + bar }{tab: + foo }{fill: }{tab:X}| this is ba^r{0:$} | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end) @@ -317,32 +324,31 @@ describe('ui/mouse/input', function() screen:expect([[ {tab: + foo }{sel: + bar }{fill: }{tab:X}| this is ba^r{0:$} | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) feed('<LeftMouse><4,0>') screen:expect([[ {sel: + foo }{tab: + bar }{fill: }{tab:X}| this is fo^o | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) feed('<LeftDrag><4,1>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {sel: + foo }{tab: + bar }{fill: }{tab:X}| this is fo^o | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]], unchanged=true} + ]], + unchanged = true, + } feed('<LeftDrag><7,1>') screen:expect([[ {tab: + bar }{sel: + foo }{fill: }{tab:X}| this is fo^o | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end) @@ -350,11 +356,11 @@ describe('ui/mouse/input', function() describe('tabline', function() before_each(function() - screen:set_default_attr_ids( { - [0] = {bold=true, foreground=Screen.colors.Blue}, - tab = { background=Screen.colors.LightGrey, underline=true }, - sel = { bold=true }, - fill = { reverse=true } + screen:set_default_attr_ids({ + [0] = { bold = true, foreground = Screen.colors.Blue }, + tab = { background = Screen.colors.LightGrey, underline = true }, + sel = { bold = true }, + fill = { reverse = true }, }) end) @@ -366,22 +372,20 @@ describe('ui/mouse/input', function() screen:expect([[ {tab: + foo }{sel: + bar }{fill: }{tab:X}| this is ba^r{0:$} | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) feed('<LeftMouse><4,0>') screen:expect([[ {sel: + foo }{tab: + bar }{fill: }{tab:X}| this is fo^o | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end) it('left click in default tabline (position 24) closes tab', function() - meths.set_option_value('hidden', true, {}) + api.nvim_set_option_value('hidden', true, {}) feed_command('%delete') insert('this is foo') feed_command('silent file foo | tabnew | file bar') @@ -389,22 +393,19 @@ describe('ui/mouse/input', function() screen:expect([[ {tab: + foo }{sel: + bar }{fill: }{tab:X}| this is ba^r{0:$} | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) feed('<LeftMouse><24,0>') screen:expect([[ this is fo^o | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) end) it('double click in default tabline (position 4) opens new tab', function() - meths.set_option_value('hidden', true, {}) + api.nvim_set_option_value('hidden', true, {}) feed_command('%delete') insert('this is foo') feed_command('silent file foo | tabnew | file bar') @@ -412,16 +413,14 @@ describe('ui/mouse/input', function() screen:expect([[ {tab: + foo }{sel: + bar }{fill: }{tab:X}| this is ba^r{0:$} | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) feed('<2-LeftMouse><4,0>') screen:expect([[ {sel: Name] }{tab: + foo + bar }{fill: }{tab:X}| {0:^$} | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end) @@ -439,8 +438,8 @@ describe('ui/mouse/input', function() return call('Test', a:000 + [2]) endfunction ]]) - meths.set_option_value('tabline', '%@Test@test%X-%5@Test2@test2', {}) - meths.set_option_value('showtabline', 2, {}) + api.nvim_set_option_value('tabline', '%@Test@test%X-%5@Test2@test2', {}) + api.nvim_set_option_value('showtabline', 2, {}) screen:expect([[ {fill:test-test2 }| testing | @@ -448,59 +447,65 @@ describe('ui/mouse/input', function() support and selectio^n | | ]]) - meths.set_var('reply', {}) + api.nvim_set_var('reply', {}) end) local check_reply = function(expected) - eq(expected, meths.get_var('reply')) - meths.set_var('reply', {}) + eq(expected, api.nvim_get_var('reply')) + api.nvim_set_var('reply', {}) end - local test_click = function(name, click_str, click_num, mouse_button, - modifiers) - + local test_click = function(name, click_str, click_num, mouse_button, modifiers) local function doit(do_click) - eq(1, funcs.has('tablineat')) - do_click(0,3) - check_reply({0, click_num, mouse_button, modifiers}) - do_click(0,4) + eq(1, fn.has('tablineat')) + do_click(0, 3) + check_reply({ 0, click_num, mouse_button, modifiers }) + do_click(0, 4) check_reply({}) - do_click(0,6) - check_reply({5, click_num, mouse_button, modifiers, 2}) - do_click(0,13) - check_reply({5, click_num, mouse_button, modifiers, 2}) + do_click(0, 6) + check_reply({ 5, click_num, mouse_button, modifiers, 2 }) + do_click(0, 13) + check_reply({ 5, click_num, mouse_button, modifiers, 2 }) end it(name .. ' works (pseudokey)', function() - doit(function (row,col) - feed(click_str .. '<' .. col .. ',' .. row .. '>') + doit(function(row, col) + feed(click_str .. '<' .. col .. ',' .. row .. '>') end) end) it(name .. ' works (nvim_input_mouse)', function() - doit(function (row,col) - local buttons = {l='left',m='middle',r='right'} + doit(function(row, col) + local buttons = { l = 'left', m = 'middle', r = 'right' } local modstr = (click_num > 1) and tostring(click_num) or '' for char in string.gmatch(modifiers, '%w') do modstr = modstr .. char .. '-' -- - not needed but should be accepted end - meths.input_mouse(buttons[mouse_button], 'press', modstr, 0, row, col) + api.nvim_input_mouse(buttons[mouse_button], 'press', modstr, 0, row, col) end) end) end test_click('single left click', '<LeftMouse>', 1, 'l', ' ') test_click('shifted single left click', '<S-LeftMouse>', 1, 'l', 's ') - test_click('shifted single left click with alt modifier', - '<S-A-LeftMouse>', 1, 'l', 's a ') - test_click('shifted single left click with alt and ctrl modifiers', - '<S-C-A-LeftMouse>', 1, 'l', 'sca ') + test_click('shifted single left click with alt modifier', '<S-A-LeftMouse>', 1, 'l', 's a ') + test_click( + 'shifted single left click with alt and ctrl modifiers', + '<S-C-A-LeftMouse>', + 1, + 'l', + 'sca ' + ) -- <C-RightMouse> does not work - test_click('shifted single right click with alt modifier', - '<S-A-RightMouse>', 1, 'r', 's a ') + test_click('shifted single right click with alt modifier', '<S-A-RightMouse>', 1, 'r', 's a ') -- Modifiers do not work with MiddleMouse - test_click('shifted single middle click with alt and ctrl modifiers', - '<MiddleMouse>', 1, 'm', ' ') + test_click( + 'shifted single middle click with alt and ctrl modifiers', + '<MiddleMouse>', + 1, + 'm', + ' ' + ) -- Modifiers do not work with N-*Mouse test_click('double left click', '<2-LeftMouse>', 2, 'l', ' ') test_click('triple left click', '<3-LeftMouse>', 3, 'l', ' ') @@ -552,15 +557,15 @@ describe('ui/mouse/input', function() it('left drag changes visual selection after tab click', function() screen:set_default_attr_ids({ - [0] = {bold=true, foreground=Screen.colors.Blue}, - tab = { background=Screen.colors.LightGrey, underline=true }, - sel = { bold=true }, - fill = { reverse=true }, - vis = { background=Screen.colors.LightGrey } + [0] = { bold = true, foreground = Screen.colors.Blue }, + tab = { background = Screen.colors.LightGrey, underline = true }, + sel = { bold = true }, + fill = { reverse = true }, + vis = { background = Screen.colors.LightGrey, foreground = Screen.colors.Black }, }) feed_command('silent file foo | tabnew | file bar') insert('this is bar') - feed_command('tabprevious') -- go to first tab + feed_command('tabprevious') -- go to first tab screen:expect([[ {sel: + foo }{tab: + bar }{fill: }{tab:X}| testing | @@ -568,28 +573,26 @@ describe('ui/mouse/input', function() support and selectio^n | :tabprevious | ]]) - feed('<LeftMouse><10,0><LeftRelease>') -- go to second tab + feed('<LeftMouse><10,0><LeftRelease>') -- go to second tab helpers.poke_eventloop() feed('<LeftMouse><0,1>') screen:expect([[ {tab: + foo }{sel: + bar }{fill: }{tab:X}| ^this is bar{0:$} | - {0:~ }| - {0:~ }| + {0:~ }|*2 :tabprevious | ]]) feed('<LeftDrag><4,1>') screen:expect([[ {tab: + foo }{sel: + bar }{fill: }{tab:X}| {vis:this}^ is bar{0:$} | - {0:~ }| - {0:~ }| + {0:~ }|*2 {sel:-- VISUAL --} | ]]) end) it('left drag changes visual selection in split layout', function() - screen:try_resize(53,14) + screen:try_resize(53, 14) command('set mouse=a') command('vsplit') command('wincmd l') @@ -597,58 +600,52 @@ describe('ui/mouse/input', function() command('enew') feed('ifoo\nbar<esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ testing │testing | mouse │mouse | support and selection │support and selection | - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| + {0:~ }│{0:~ }|*2 {0:~ }│{4:[No Name] [+] }| {0:~ }│foo{0:$} | {0:~ }│ba^r{0:$} | - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| + {0:~ }│{0:~ }|*4 {4:[No Name] [+] }{5:[No Name] [+] }| | - ]]} + ]], + } - meths.input_mouse('left', 'press', '', 0, 6, 27) - screen:expect{grid=[[ + api.nvim_input_mouse('left', 'press', '', 0, 6, 27) + screen:expect { + grid = [[ testing │testing | mouse │mouse | support and selection │support and selection | - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| + {0:~ }│{0:~ }|*2 {0:~ }│{4:[No Name] [+] }| {0:~ }│^foo{0:$} | {0:~ }│bar{0:$} | - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| + {0:~ }│{0:~ }|*4 {4:[No Name] [+] }{5:[No Name] [+] }| | - ]]} - meths.input_mouse('left', 'drag', '', 0, 7, 30) + ]], + } + api.nvim_input_mouse('left', 'drag', '', 0, 7, 30) - screen:expect{grid=[[ + screen:expect { + grid = [[ testing │testing | mouse │mouse | support and selection │support and selection | - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| + {0:~ }│{0:~ }|*2 {0:~ }│{4:[No Name] [+] }| {0:~ }│{1:foo}{3:$} | {0:~ }│{1:bar}{0:^$} | - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| + {0:~ }│{0:~ }|*4 {4:[No Name] [+] }{5:[No Name] [+] }| {2:-- VISUAL --} | - ]]} + ]], + } end) it('two clicks will enter VISUAL and dragging selects words', function() @@ -788,7 +785,7 @@ describe('ui/mouse/input', function() end) it('ctrl + left click will search for a tag', function() - meths.set_option_value('tags', './non-existent-tags-file', {}) + api.nvim_set_option_value('tags', './non-existent-tags-file', {}) feed('<C-LeftMouse><0,0>') screen:expect([[ {6:E433: No tags file} | @@ -800,10 +797,29 @@ describe('ui/mouse/input', function() feed('<cr>') end) + it('x1 and x2 can be triggered by api', function() + api.nvim_set_var('x1_pressed', 0) + api.nvim_set_var('x1_released', 0) + api.nvim_set_var('x2_pressed', 0) + api.nvim_set_var('x2_released', 0) + command('nnoremap <X1Mouse> <Cmd>let g:x1_pressed += 1<CR>') + command('nnoremap <X1Release> <Cmd>let g:x1_released += 1<CR>') + command('nnoremap <X2Mouse> <Cmd>let g:x2_pressed += 1<CR>') + command('nnoremap <X2Release> <Cmd>let g:x2_released += 1<CR>') + api.nvim_input_mouse('x1', 'press', '', 0, 0, 0) + api.nvim_input_mouse('x1', 'release', '', 0, 0, 0) + api.nvim_input_mouse('x2', 'press', '', 0, 0, 0) + api.nvim_input_mouse('x2', 'release', '', 0, 0, 0) + eq(1, api.nvim_get_var('x1_pressed'), 'x1 pressed once') + eq(1, api.nvim_get_var('x1_released'), 'x1 released once') + eq(1, api.nvim_get_var('x2_pressed'), 'x2 pressed once') + eq(1, api.nvim_get_var('x2_released'), 'x2 released once') + end) + it('dragging vertical separator', function() screen:try_resize(45, 5) command('setlocal nowrap') - local oldwin = meths.get_current_win().id + local oldwin = api.nvim_get_current_win() command('rightbelow vnew') screen:expect([[ testing │{0:^$} | @@ -812,9 +828,9 @@ describe('ui/mouse/input', function() {4:[No Name] [+] }{5:[No Name] }| | ]]) - meths.input_mouse('left', 'press', '', 0, 0, 22) + api.nvim_input_mouse('left', 'press', '', 0, 0, 22) poke_eventloop() - meths.input_mouse('left', 'drag', '', 0, 1, 12) + api.nvim_input_mouse('left', 'drag', '', 0, 1, 12) screen:expect([[ testing │{0:^$} | mouse │{0:~ }| @@ -822,7 +838,7 @@ describe('ui/mouse/input', function() {4:< Name] [+] }{5:[No Name] }| | ]]) - meths.input_mouse('left', 'drag', '', 0, 2, 2) + api.nvim_input_mouse('left', 'drag', '', 0, 2, 2) screen:expect([[ te│{0:^$} | mo│{0:~ }| @@ -830,18 +846,17 @@ describe('ui/mouse/input', function() {4:< }{5:[No Name] }| | ]]) - meths.input_mouse('left', 'release', '', 0, 2, 2) - meths.set_option_value('statuscolumn', 'foobar', { win = oldwin }) + api.nvim_input_mouse('left', 'release', '', 0, 2, 2) + api.nvim_set_option_value('statuscolumn', 'foobar', { win = oldwin }) screen:expect([[ {8:fo}│{0:^$} | - {8:fo}│{0:~ }| - {8:fo}│{0:~ }| + {8:fo}│{0:~ }|*2 {4:< }{5:[No Name] }| | ]]) - meths.input_mouse('left', 'press', '', 0, 0, 2) + api.nvim_input_mouse('left', 'press', '', 0, 0, 2) poke_eventloop() - meths.input_mouse('left', 'drag', '', 0, 1, 12) + api.nvim_input_mouse('left', 'drag', '', 0, 1, 12) screen:expect([[ {8:foobar}testin│{0:^$} | {8:foobar}mouse │{0:~ }| @@ -849,7 +864,7 @@ describe('ui/mouse/input', function() {4:< Name] [+] }{5:[No Name] }| | ]]) - meths.input_mouse('left', 'drag', '', 0, 2, 22) + api.nvim_input_mouse('left', 'drag', '', 0, 2, 22) screen:expect([[ {8:foobar}testing │{0:^$} | {8:foobar}mouse │{0:~ }| @@ -857,7 +872,7 @@ describe('ui/mouse/input', function() {4:[No Name] [+] }{5:[No Name] }| | ]]) - meths.input_mouse('left', 'release', '', 0, 2, 22) + api.nvim_input_mouse('left', 'release', '', 0, 2, 22) end) local function wheel(use_api) @@ -892,7 +907,7 @@ describe('ui/mouse/input', function() :vsp | ]]) if use_api then - meths.input_mouse('wheel', 'down', '', 0, 0, 0) + api.nvim_input_mouse('wheel', 'down', '', 0, 0, 0) else feed('<ScrollWheelDown><0,0>') end @@ -913,7 +928,7 @@ describe('ui/mouse/input', function() :vsp | ]]) if use_api then - meths.input_mouse('wheel', 'up', '', 0, 0, 27) + api.nvim_input_mouse('wheel', 'up', '', 0, 0, 27) else feed('<ScrollWheelUp><27,0>') end @@ -934,8 +949,8 @@ describe('ui/mouse/input', function() :vsp | ]]) if use_api then - meths.input_mouse('wheel', 'up', '', 0, 7, 27) - meths.input_mouse('wheel', 'up', '', 0, 7, 27) + api.nvim_input_mouse('wheel', 'up', '', 0, 7, 27) + api.nvim_input_mouse('wheel', 'up', '', 0, 7, 27) else feed('<ScrollWheelUp><27,7><ScrollWheelUp>') end @@ -967,27 +982,25 @@ describe('ui/mouse/input', function() it('horizontal scrolling (pseudokey)', function() command('set sidescroll=0') - feed("<esc>:set nowrap<cr>") + feed('<esc>:set nowrap<cr>') - feed("a <esc>20Ab<esc>") + feed('a <esc>20Ab<esc>') screen:expect([[ - | - | + |*2 bbbbbbbbbbbbbbb^b | {0:~ }| | ]]) - feed("<ScrollWheelLeft><0,0>") + feed('<ScrollWheelLeft><0,0>') screen:expect([[ - | - | + |*2 n bbbbbbbbbbbbbbbbbbb^b | {0:~ }| | ]]) - feed("^<ScrollWheelRight><0,0>") + feed('^<ScrollWheelRight><0,0>') screen:expect([[ g | | @@ -999,28 +1012,26 @@ describe('ui/mouse/input', function() it('horizontal scrolling (nvim_input_mouse)', function() command('set sidescroll=0') - feed("<esc>:set nowrap<cr>") + feed('<esc>:set nowrap<cr>') - feed("a <esc>20Ab<esc>") + feed('a <esc>20Ab<esc>') screen:expect([[ - | - | + |*2 bbbbbbbbbbbbbbb^b | {0:~ }| | ]]) - meths.input_mouse('wheel', 'left', '', 0, 0, 27) + api.nvim_input_mouse('wheel', 'left', '', 0, 0, 27) screen:expect([[ - | - | + |*2 n bbbbbbbbbbbbbbbbbbb^b | {0:~ }| | ]]) - feed("^") - meths.input_mouse('wheel', 'right', '', 0, 0, 0) + feed('^') + api.nvim_input_mouse('wheel', 'right', '', 0, 0, 0) screen:expect([[ g | | @@ -1034,7 +1045,7 @@ describe('ui/mouse/input', function() command('set nowrap') command('set sidescrolloff=4') - feed("I <esc>020ib<esc>0") + feed('I <esc>020ib<esc>0') screen:expect([[ testing | mouse | @@ -1043,7 +1054,7 @@ describe('ui/mouse/input', function() | ]]) - meths.input_mouse('wheel', 'right', '', 0, 0, 27) + api.nvim_input_mouse('wheel', 'right', '', 0, 0, 27) screen:expect([[ g | | @@ -1063,7 +1074,7 @@ describe('ui/mouse/input', function() | ]]) - meths.input_mouse('wheel', 'right', '', 0, 0, 27) + api.nvim_input_mouse('wheel', 'right', '', 0, 0, 27) screen:expect([[ g | | @@ -1083,8 +1094,7 @@ describe('ui/mouse/input', function() {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }| {c:>} 私は猫が大好き{0:>---}{c: X } {0:>}| | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) @@ -1094,8 +1104,7 @@ describe('ui/mouse/input', function() {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }| {c:>} 私は猫が大好き{0:>---}{c: X } {0:>}| | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) @@ -1105,8 +1114,7 @@ describe('ui/mouse/input', function() {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }| {c:>} 私は猫が大好き{0:>---}{c: X } {0:>}| | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) @@ -1116,8 +1124,7 @@ describe('ui/mouse/input', function() {0:>--->--->---} {c: }t2{c: } {c: }t^3{c: } {c: }| {c:>} 私は猫が大好き{0:>---}{c: X } {0:>}| | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) @@ -1127,8 +1134,7 @@ describe('ui/mouse/input', function() {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }| {c:^>} 私は猫が大好き{0:>---}{c: X } {0:>}| | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) @@ -1138,8 +1144,7 @@ describe('ui/mouse/input', function() {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }| {c:>} 私は^猫が大好き{0:>---}{c: X } {0:>}| | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) @@ -1149,11 +1154,9 @@ describe('ui/mouse/input', function() {0:>--->--->---} {c: }t2{c: } {c: }t3{c: } {c: }| {c:>} 私は猫が大好き{0:>---}{c: ^X } {0:>}| | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) - end) -- level 1 - non wrapped it('(level 1) click on wrapped lines', function() @@ -1166,8 +1169,7 @@ describe('ui/mouse/input', function() t4{c: } | {c:>} 私は猫が大好き{0:>---}{c: X} | {c: } ✨🐈✨ | - | - | + |*2 ]]) feed('<esc><LeftMouse><0,2>') @@ -1177,8 +1179,7 @@ describe('ui/mouse/input', function() ^t4{c: } | {c:>} 私は猫が大好き{0:>---}{c: X} | {c: } ✨🐈✨ | - | - | + |*2 ]]) feed('<esc><LeftMouse><8,3>') @@ -1188,8 +1189,7 @@ describe('ui/mouse/input', function() t4{c: } | {c:>} 私は猫^が大好き{0:>---}{c: X} | {c: } ✨🐈✨ | - | - | + |*2 ]]) feed('<esc><LeftMouse><21,3>') @@ -1199,8 +1199,7 @@ describe('ui/mouse/input', function() t4{c: } | {c:>} 私は猫が大好き{0:>---}{c: ^X} | {c: } ✨🐈✨ | - | - | + |*2 ]]) feed('<esc><LeftMouse><4,4>') @@ -1210,12 +1209,10 @@ describe('ui/mouse/input', function() t4{c: } | {c:>} 私は猫が大好き{0:>---}{c: X} | {c: } ✨^🐈✨ | - | - | + |*2 ]]) end) -- level 1 - wrapped - it('(level 2) click on non-wrapped lines', function() feed_command('let &conceallevel=2', 'echo') @@ -1225,8 +1222,7 @@ describe('ui/mouse/input', function() {0:>--->--->---} t2 t3 t4 | {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}| | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) @@ -1236,8 +1232,7 @@ describe('ui/mouse/input', function() {0:>--->--->---} ^t2 t3 t4 | {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}| | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) @@ -1247,19 +1242,17 @@ describe('ui/mouse/input', function() {0:>--->--->---} t2 t^3 t4 | {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}| | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) - feed('<esc><LeftMouse><0,2>') -- Weirdness + feed('<esc><LeftMouse><0,2>') -- Weirdness screen:expect([[ Section{0:>>--->--->---}t1 | {0:>--->--->---} t2 t3 t4 | {c:^>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}| | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) @@ -1269,8 +1262,7 @@ describe('ui/mouse/input', function() {0:>--->--->---} t2 t3 t4 | {c:>} 私は猫^が大好き{0:>---}{c:X} ✨{0:>}| | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) @@ -1280,8 +1272,7 @@ describe('ui/mouse/input', function() {0:>--->--->---} t2 t3 t4 | {c:>} 私は猫が大好き{0:>---}{c:^X} ✨{0:>}| | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end) -- level 2 - non wrapped @@ -1295,8 +1286,7 @@ describe('ui/mouse/input', function() {0:>--->--->---} t2 t3 t4 | {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}| | - {0:~ }| - {0:~ }| + {0:~ }|*2 {sm:-- INSERT --} | ]]) @@ -1306,8 +1296,7 @@ describe('ui/mouse/input', function() {0:>--->--->---} ^t2 t3 t4 | {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}| | - {0:~ }| - {0:~ }| + {0:~ }|*2 {sm:-- INSERT --} | ]]) @@ -1317,19 +1306,17 @@ describe('ui/mouse/input', function() {0:>--->--->---} t2 t^3 t4 | {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}| | - {0:~ }| - {0:~ }| + {0:~ }|*2 {sm:-- INSERT --} | ]]) - feed('<LeftMouse><0,2>') -- Weirdness + feed('<LeftMouse><0,2>') -- Weirdness screen:expect([[ Section{0:>>--->--->---}t1 | {0:>--->--->---} t2 t3 t4 | {c:^>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}| | - {0:~ }| - {0:~ }| + {0:~ }|*2 {sm:-- INSERT --} | ]]) @@ -1339,8 +1326,7 @@ describe('ui/mouse/input', function() {0:>--->--->---} t2 t3 t4 | {c:>} 私は猫^が大好き{0:>---}{c:X} ✨{0:>}| | - {0:~ }| - {0:~ }| + {0:~ }|*2 {sm:-- INSERT --} | ]]) @@ -1350,8 +1336,7 @@ describe('ui/mouse/input', function() {0:>--->--->---} t2 t3 t4 | {c:>} 私は猫が大好き{0:>---}{c:^X} ✨{0:>}| | - {0:~ }| - {0:~ }| + {0:~ }|*2 {sm:-- INSERT --} | ]]) end) -- level 2 - non wrapped (insert mode) @@ -1366,8 +1351,7 @@ describe('ui/mouse/input', function() t4 | {c:>} 私は猫が大好き{0:>---}{c:X} | ✨🐈✨ | - | - | + |*2 ]]) feed('<esc><LeftMouse><14,1>') @@ -1377,8 +1361,7 @@ describe('ui/mouse/input', function() t4 | {c:>} 私は猫が大好き{0:>---}{c:X} | ✨🐈✨ | - | - | + |*2 ]]) feed('<esc><LeftMouse><18,1>') @@ -1388,8 +1371,7 @@ describe('ui/mouse/input', function() t4 | {c:>} 私は猫が大好き{0:>---}{c:X} | ✨🐈✨ | - | - | + |*2 ]]) -- NOTE: The click would ideally be on the 't' in 't4', but wrapping @@ -1405,8 +1387,7 @@ describe('ui/mouse/input', function() t4 | {c:>} 私は猫が大好き{0:>---}{c:X} | ✨🐈✨ | - | - | + |*2 ]]) feed('<esc><LeftMouse><1,2>') @@ -1416,8 +1397,7 @@ describe('ui/mouse/input', function() t^4 | {c:>} 私は猫が大好き{0:>---}{c:X} | ✨🐈✨ | - | - | + |*2 ]]) feed('<esc><LeftMouse><0,3>') @@ -1427,8 +1407,7 @@ describe('ui/mouse/input', function() t4 | {c:^>} 私は猫が大好き{0:>---}{c:X} | ✨🐈✨ | - | - | + |*2 ]]) feed('<esc><LeftMouse><20,3>') @@ -1438,8 +1417,7 @@ describe('ui/mouse/input', function() t4 | {c:>} 私は猫が大好き{0:>---}{c:^X} | ✨🐈✨ | - | - | + |*2 ]]) feed('<esc><LeftMouse><1,4>') @@ -1449,8 +1427,7 @@ describe('ui/mouse/input', function() t4 | {c:>} 私は猫が大好き{0:>---}{c:X} | ^✨🐈✨ | - | - | + |*2 ]]) feed('<esc><LeftMouse><5,4>') @@ -1460,8 +1437,7 @@ describe('ui/mouse/input', function() t4 | {c:>} 私は猫が大好き{0:>---}{c:X} | ✨🐈^✨ | - | - | + |*2 ]]) end) -- level 2 - wrapped @@ -1474,8 +1450,7 @@ describe('ui/mouse/input', function() {0:>--->--->---} t2 t3 t4 | ^ 私は猫が大好き{0:>----} ✨🐈| | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) @@ -1485,8 +1460,7 @@ describe('ui/mouse/input', function() {0:>--->--->---} t2 t3 t4 | ^私は猫が大好き{0:>----} ✨🐈| | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) @@ -1496,20 +1470,18 @@ describe('ui/mouse/input', function() {0:>--->--->---} t2 t3 t4 | 私は猫が大好^き{0:>----} ✨🐈| | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) feed('<esc><LeftMouse><20,2>') - feed('zH') -- FIXME: unnecessary horizontal scrolling + feed('zH') -- FIXME: unnecessary horizontal scrolling screen:expect([[ Section{0:>>--->--->---}t1 | {0:>--->--->---} t2 t3 t4 | 私は猫が大好き{0:>----}^ ✨🐈| | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end) -- level 3 - non wrapped @@ -1524,8 +1496,7 @@ describe('ui/mouse/input', function() t4 | 私は猫が大好き{0:>----} | ✨🐈✨ | - | - | + |*2 ]]) feed('<esc><LeftMouse><18,1>') @@ -1535,8 +1506,7 @@ describe('ui/mouse/input', function() t4 | 私は猫が大好き{0:>----} | ✨🐈✨ | - | - | + |*2 ]]) feed('<esc><LeftMouse><1,2>') @@ -1546,8 +1516,7 @@ describe('ui/mouse/input', function() t^4 | 私は猫が大好き{0:>----} | ✨🐈✨ | - | - | + |*2 ]]) feed('<esc><LeftMouse><0,3>') @@ -1557,8 +1526,7 @@ describe('ui/mouse/input', function() t4 | ^ 私は猫が大好き{0:>----} | ✨🐈✨ | - | - | + |*2 ]]) feed('<esc><LeftMouse><20,3>') @@ -1568,8 +1536,7 @@ describe('ui/mouse/input', function() t4 | 私は猫が大好き{0:>----}^ | ✨🐈✨ | - | - | + |*2 ]]) feed('<esc><LeftMouse><1,4>') @@ -1579,8 +1546,7 @@ describe('ui/mouse/input', function() t4 | 私は猫が大好き{0:>----} | ^✨🐈✨ | - | - | + |*2 ]]) feed('<esc><LeftMouse><3,4>') @@ -1590,8 +1556,7 @@ describe('ui/mouse/input', function() t4 | 私は猫が大好き{0:>----} | ✨^🐈✨ | - | - | + |*2 ]]) feed('<esc><LeftMouse><5,4>') @@ -1601,10 +1566,8 @@ describe('ui/mouse/input', function() t4 | 私は猫が大好き{0:>----} | ✨🐈^✨ | - | - | + |*2 ]]) - end) -- level 3 - wrapped end @@ -1648,66 +1611,65 @@ describe('ui/mouse/input', function() describe('(matchadd())', function() before_each(function() - funcs.matchadd('Conceal', [[\*]]) - funcs.matchadd('Conceal', [[cats]], 10, -1, { conceal = 'X' }) - funcs.matchadd('Conceal', [[\n\@<=x]], 10, -1, { conceal = '>' }) + fn.matchadd('Conceal', [[\*]]) + fn.matchadd('Conceal', [[cats]], 10, -1, { conceal = 'X' }) + fn.matchadd('Conceal', [[\n\@<=x]], 10, -1, { conceal = '>' }) end) test_mouse_click_conceal() end) describe('(extmarks)', function() before_each(function() - local ns = meths.create_namespace('conceal') - meths.buf_set_extmark(0, ns, 0, 11, { end_col = 12, conceal = '' }) - meths.buf_set_extmark(0, ns, 0, 14, { end_col = 15, conceal = '' }) - meths.buf_set_extmark(0, ns, 1, 5, { end_col = 6, conceal = '' }) - meths.buf_set_extmark(0, ns, 1, 8, { end_col = 9, conceal = '' }) - meths.buf_set_extmark(0, ns, 1, 10, { end_col = 11, conceal = '' }) - meths.buf_set_extmark(0, ns, 1, 13, { end_col = 14, conceal = '' }) - meths.buf_set_extmark(0, ns, 1, 15, { end_col = 16, conceal = '' }) - meths.buf_set_extmark(0, ns, 1, 18, { end_col = 19, conceal = '' }) - meths.buf_set_extmark(0, ns, 2, 24, { end_col = 25, conceal = '' }) - meths.buf_set_extmark(0, ns, 2, 29, { end_col = 30, conceal = '' }) - meths.buf_set_extmark(0, ns, 2, 25, { end_col = 29, conceal = 'X' }) - meths.buf_set_extmark(0, ns, 2, 0, { end_col = 1, conceal = '>' }) + local ns = api.nvim_create_namespace('conceal') + api.nvim_buf_set_extmark(0, ns, 0, 11, { end_col = 12, conceal = '' }) + api.nvim_buf_set_extmark(0, ns, 0, 14, { end_col = 15, conceal = '' }) + api.nvim_buf_set_extmark(0, ns, 1, 5, { end_col = 6, conceal = '' }) + api.nvim_buf_set_extmark(0, ns, 1, 8, { end_col = 9, conceal = '' }) + api.nvim_buf_set_extmark(0, ns, 1, 10, { end_col = 11, conceal = '' }) + api.nvim_buf_set_extmark(0, ns, 1, 13, { end_col = 14, conceal = '' }) + api.nvim_buf_set_extmark(0, ns, 1, 15, { end_col = 16, conceal = '' }) + api.nvim_buf_set_extmark(0, ns, 1, 18, { end_col = 19, conceal = '' }) + api.nvim_buf_set_extmark(0, ns, 2, 24, { end_col = 25, conceal = '' }) + api.nvim_buf_set_extmark(0, ns, 2, 29, { end_col = 30, conceal = '' }) + api.nvim_buf_set_extmark(0, ns, 2, 25, { end_col = 29, conceal = 'X' }) + api.nvim_buf_set_extmark(0, ns, 2, 0, { end_col = 1, conceal = '>' }) end) test_mouse_click_conceal() end) - end) it('getmousepos() works correctly', function() - local winwidth = meths.get_option_value('winwidth', {}) + local winwidth = api.nvim_get_option_value('winwidth', {}) -- Set winwidth=1 so that window sizes don't change. - meths.set_option_value('winwidth', 1, {}) + api.nvim_set_option_value('winwidth', 1, {}) command('tabedit') - local tabpage = meths.get_current_tabpage() + local tabpage = api.nvim_get_current_tabpage() insert('hello') command('vsplit') local opts = { - relative='editor', - width=12, - height=1, - col=8, - row=1, - anchor='NW', - style='minimal', - border='single', - focusable=1 + relative = 'editor', + width = 12, + height = 1, + col = 8, + row = 1, + anchor = 'NW', + style = 'minimal', + border = 'single', + focusable = 1, } - local float = meths.open_win(meths.get_current_buf(), false, opts) + local float = api.nvim_open_win(api.nvim_get_current_buf(), false, opts) command('redraw') - local lines = meths.get_option_value('lines', {}) - local columns = meths.get_option_value('columns', {}) + local lines = api.nvim_get_option_value('lines', {}) + local columns = api.nvim_get_option_value('columns', {}) -- Test that screenrow and screencol are set properly for all positions. for row = 0, lines - 1 do for col = 0, columns - 1 do -- Skip the X button that would close the tab. if row ~= 0 or col ~= columns - 1 then - meths.input_mouse('left', 'press', '', 0, row, col) - meths.set_current_tabpage(tabpage) - local mousepos = funcs.getmousepos() + api.nvim_input_mouse('left', 'press', '', 0, row, col) + api.nvim_set_current_tabpage(tabpage) + local mousepos = fn.getmousepos() eq(row + 1, mousepos.screenrow) eq(col + 1, mousepos.screencol) -- All other values should be 0 when clicking on the command line. @@ -1730,20 +1692,24 @@ describe('ui/mouse/input', function() for win_col = 0, opts.width + 1 do local row = win_row + opts.row local col = win_col + opts.col - meths.input_mouse('left', 'press', '', 0, row, col) - local mousepos = funcs.getmousepos() - eq(float.id, mousepos.winid) + api.nvim_input_mouse('left', 'press', '', 0, row, col) + local mousepos = fn.getmousepos() + eq(float, mousepos.winid) eq(win_row + 1, mousepos.winrow) eq(win_col + 1, mousepos.wincol) local line = 0 local column = 0 local coladd = 0 - if win_row > 0 and win_row < opts.height + 1 - and win_col > 0 and win_col < opts.width + 1 then + if + win_row > 0 + and win_row < opts.height + 1 + and win_col > 0 + and win_col < opts.width + 1 + then -- Because of border, win_row and win_col don't need to be -- incremented by 1. - line = math.min(win_row, funcs.line('$')) - column = math.min(win_col, #funcs.getline(line) + 1) + line = math.min(win_row, fn.line('$')) + column = math.min(win_col, #fn.getline(line) + 1) coladd = win_col - column end eq(line, mousepos.line) @@ -1755,19 +1721,19 @@ describe('ui/mouse/input', function() -- Test that mouse position values are properly set for the floating -- window, after removing the border. opts.border = 'none' - meths.win_set_config(float, opts) + api.nvim_win_set_config(float, opts) command('redraw') for win_row = 0, opts.height - 1 do for win_col = 0, opts.width - 1 do local row = win_row + opts.row local col = win_col + opts.col - meths.input_mouse('left', 'press', '', 0, row, col) - local mousepos = funcs.getmousepos() - eq(float.id, mousepos.winid) + api.nvim_input_mouse('left', 'press', '', 0, row, col) + local mousepos = fn.getmousepos() + eq(float, mousepos.winid) eq(win_row + 1, mousepos.winrow) eq(win_col + 1, mousepos.wincol) - local line = math.min(win_row + 1, funcs.line('$')) - local column = math.min(win_col + 1, #funcs.getline(line) + 1) + local line = math.min(win_row + 1, fn.line('$')) + local column = math.min(win_col + 1, #fn.getline(line) + 1) local coladd = win_col + 1 - column eq(line, mousepos.line) eq(column, mousepos.column) @@ -1780,20 +1746,20 @@ describe('ui/mouse/input', function() -- that getmousepos() does not consider unfocusable floats. (see discussion -- in PR #14937 for details). opts.focusable = false - meths.win_set_config(float, opts) + api.nvim_win_set_config(float, opts) command('redraw') for nr = 1, 2 do - for win_row = 0, funcs.winheight(nr) - 1 do - for win_col = 0, funcs.winwidth(nr) - 1 do - local row = win_row + funcs.win_screenpos(nr)[1] - 1 - local col = win_col + funcs.win_screenpos(nr)[2] - 1 - meths.input_mouse('left', 'press', '', 0, row, col) - local mousepos = funcs.getmousepos() - eq(funcs.win_getid(nr), mousepos.winid) + for win_row = 0, fn.winheight(nr) - 1 do + for win_col = 0, fn.winwidth(nr) - 1 do + local row = win_row + fn.win_screenpos(nr)[1] - 1 + local col = win_col + fn.win_screenpos(nr)[2] - 1 + api.nvim_input_mouse('left', 'press', '', 0, row, col) + local mousepos = fn.getmousepos() + eq(fn.win_getid(nr), mousepos.winid) eq(win_row + 1, mousepos.winrow) eq(win_col + 1, mousepos.wincol) - local line = math.min(win_row + 1, funcs.line('$')) - local column = math.min(win_col + 1, #funcs.getline(line) + 1) + local line = math.min(win_row + 1, fn.line('$')) + local column = math.min(win_col + 1, #fn.getline(line) + 1) local coladd = win_col + 1 - column eq(line, mousepos.line) eq(column, mousepos.column) @@ -1804,34 +1770,34 @@ describe('ui/mouse/input', function() -- Restore state and release mouse. command('tabclose!') - meths.set_option_value('winwidth', winwidth, {}) - meths.input_mouse('left', 'release', '', 0, 0, 0) + api.nvim_set_option_value('winwidth', winwidth, {}) + api.nvim_input_mouse('left', 'release', '', 0, 0, 0) end) it('scroll keys are not translated into multiclicks and can be mapped #6211 #6989', function() - meths.set_var('mouse_up', 0) - meths.set_var('mouse_up2', 0) + api.nvim_set_var('mouse_up', 0) + api.nvim_set_var('mouse_up2', 0) command('nnoremap <ScrollWheelUp> <Cmd>let g:mouse_up += 1<CR>') command('nnoremap <2-ScrollWheelUp> <Cmd>let g:mouse_up2 += 1<CR>') feed('<ScrollWheelUp><0,0>') feed('<ScrollWheelUp><0,0>') - meths.input_mouse('wheel', 'up', '', 0, 0, 0) - meths.input_mouse('wheel', 'up', '', 0, 0, 0) - eq(4, meths.get_var('mouse_up')) - eq(0, meths.get_var('mouse_up2')) + api.nvim_input_mouse('wheel', 'up', '', 0, 0, 0) + api.nvim_input_mouse('wheel', 'up', '', 0, 0, 0) + eq(4, api.nvim_get_var('mouse_up')) + eq(0, api.nvim_get_var('mouse_up2')) end) it('<MouseMove> is not translated into multiclicks and can be mapped', function() - meths.set_var('mouse_move', 0) - meths.set_var('mouse_move2', 0) + api.nvim_set_var('mouse_move', 0) + api.nvim_set_var('mouse_move2', 0) command('nnoremap <MouseMove> <Cmd>let g:mouse_move += 1<CR>') command('nnoremap <2-MouseMove> <Cmd>let g:mouse_move2 += 1<CR>') feed('<MouseMove><0,0>') feed('<MouseMove><0,0>') - meths.input_mouse('move', '', '', 0, 0, 0) - meths.input_mouse('move', '', '', 0, 0, 0) - eq(4, meths.get_var('mouse_move')) - eq(0, meths.get_var('mouse_move2')) + api.nvim_input_mouse('move', '', '', 0, 0, 0) + api.nvim_input_mouse('move', '', '', 0, 0, 0) + eq(4, api.nvim_get_var('mouse_move')) + eq(0, api.nvim_get_var('mouse_move2')) end) it('feeding <MouseMove> in Normal mode does not use uninitialized memory #19480', function() @@ -1858,127 +1824,127 @@ describe('ui/mouse/input', function() vmenu PopUp.baz y:<C-U>let g:menustr = 'baz'<CR> ]]) - meths.win_set_cursor(0, {1, 0}) - meths.input_mouse('right', 'press', '', 0, 0, 4) - meths.input_mouse('right', 'release', '', 0, 0, 4) + api.nvim_win_set_cursor(0, { 1, 0 }) + api.nvim_input_mouse('right', 'press', '', 0, 0, 4) + api.nvim_input_mouse('right', 'release', '', 0, 0, 4) feed('<Down><Down><CR>') - eq('bar', meths.get_var('menustr')) - eq({1, 4}, meths.win_get_cursor(0)) + eq('bar', api.nvim_get_var('menustr')) + eq({ 1, 4 }, api.nvim_win_get_cursor(0)) -- Test for right click in visual mode inside the selection - funcs.setreg('"', '') - meths.win_set_cursor(0, {1, 9}) + fn.setreg('"', '') + api.nvim_win_set_cursor(0, { 1, 9 }) feed('vee') - meths.input_mouse('right', 'press', '', 0, 0, 11) - meths.input_mouse('right', 'release', '', 0, 0, 11) + api.nvim_input_mouse('right', 'press', '', 0, 0, 11) + api.nvim_input_mouse('right', 'release', '', 0, 0, 11) feed('<Down><CR>') - eq({1, 9}, meths.win_get_cursor(0)) - eq('ran away', funcs.getreg('"')) + eq({ 1, 9 }, api.nvim_win_get_cursor(0)) + eq('ran away', fn.getreg('"')) -- Test for right click in visual mode right before the selection - funcs.setreg('"', '') - meths.win_set_cursor(0, {1, 9}) + fn.setreg('"', '') + api.nvim_win_set_cursor(0, { 1, 9 }) feed('vee') - meths.input_mouse('right', 'press', '', 0, 0, 8) - meths.input_mouse('right', 'release', '', 0, 0, 8) + api.nvim_input_mouse('right', 'press', '', 0, 0, 8) + api.nvim_input_mouse('right', 'release', '', 0, 0, 8) feed('<Down><CR>') - eq({1, 8}, meths.win_get_cursor(0)) - eq('', funcs.getreg('"')) + eq({ 1, 8 }, api.nvim_win_get_cursor(0)) + eq('', fn.getreg('"')) -- Test for right click in visual mode right after the selection - funcs.setreg('"', '') - meths.win_set_cursor(0, {1, 9}) + fn.setreg('"', '') + api.nvim_win_set_cursor(0, { 1, 9 }) feed('vee') - meths.input_mouse('right', 'press', '', 0, 0, 17) - meths.input_mouse('right', 'release', '', 0, 0, 17) + api.nvim_input_mouse('right', 'press', '', 0, 0, 17) + api.nvim_input_mouse('right', 'release', '', 0, 0, 17) feed('<Down><CR>') - eq({1, 17}, meths.win_get_cursor(0)) - eq('', funcs.getreg('"')) + eq({ 1, 17 }, api.nvim_win_get_cursor(0)) + eq('', fn.getreg('"')) -- Test for right click in block-wise visual mode inside the selection - funcs.setreg('"', '') - meths.win_set_cursor(0, {1, 15}) + fn.setreg('"', '') + api.nvim_win_set_cursor(0, { 1, 15 }) feed('<C-V>j3l') - meths.input_mouse('right', 'press', '', 0, 1, 16) - meths.input_mouse('right', 'release', '', 0, 1, 16) + api.nvim_input_mouse('right', 'press', '', 0, 1, 16) + api.nvim_input_mouse('right', 'release', '', 0, 1, 16) feed('<Down><CR>') - eq({1, 15}, meths.win_get_cursor(0)) - eq('\0224', funcs.getregtype('"')) + eq({ 1, 15 }, api.nvim_win_get_cursor(0)) + eq('\0224', fn.getregtype('"')) -- Test for right click in block-wise visual mode outside the selection - funcs.setreg('"', '') - meths.win_set_cursor(0, {1, 15}) + fn.setreg('"', '') + api.nvim_win_set_cursor(0, { 1, 15 }) feed('<C-V>j3l') - meths.input_mouse('right', 'press', '', 0, 1, 1) - meths.input_mouse('right', 'release', '', 0, 1, 1) + api.nvim_input_mouse('right', 'press', '', 0, 1, 1) + api.nvim_input_mouse('right', 'release', '', 0, 1, 1) feed('<Down><CR>') - eq({2, 1}, meths.win_get_cursor(0)) - eq('v', funcs.getregtype('"')) - eq('', funcs.getreg('"')) + eq({ 2, 1 }, api.nvim_win_get_cursor(0)) + eq('v', fn.getregtype('"')) + eq('', fn.getreg('"')) -- Test for right click in line-wise visual mode inside the selection - funcs.setreg('"', '') - meths.win_set_cursor(0, {1, 15}) + fn.setreg('"', '') + api.nvim_win_set_cursor(0, { 1, 15 }) feed('V') - meths.input_mouse('right', 'press', '', 0, 0, 9) - meths.input_mouse('right', 'release', '', 0, 0, 9) + api.nvim_input_mouse('right', 'press', '', 0, 0, 9) + api.nvim_input_mouse('right', 'release', '', 0, 0, 9) feed('<Down><CR>') - eq({1, 0}, meths.win_get_cursor(0)) -- After yanking, the cursor goes to 1,1 - eq('V', funcs.getregtype('"')) - eq(1, #funcs.getreg('"', 1, true)) + eq({ 1, 0 }, api.nvim_win_get_cursor(0)) -- After yanking, the cursor goes to 1,1 + eq('V', fn.getregtype('"')) + eq(1, #fn.getreg('"', 1, true)) -- Test for right click in multi-line line-wise visual mode inside the selection - funcs.setreg('"', '') - meths.win_set_cursor(0, {1, 15}) + fn.setreg('"', '') + api.nvim_win_set_cursor(0, { 1, 15 }) feed('Vj') - meths.input_mouse('right', 'press', '', 0, 1, 19) - meths.input_mouse('right', 'release', '', 0, 1, 19) + api.nvim_input_mouse('right', 'press', '', 0, 1, 19) + api.nvim_input_mouse('right', 'release', '', 0, 1, 19) feed('<Down><CR>') - eq({1, 0}, meths.win_get_cursor(0)) -- After yanking, the cursor goes to 1,1 - eq('V', funcs.getregtype('"')) - eq(2, #funcs.getreg('"', 1, true)) + eq({ 1, 0 }, api.nvim_win_get_cursor(0)) -- After yanking, the cursor goes to 1,1 + eq('V', fn.getregtype('"')) + eq(2, #fn.getreg('"', 1, true)) -- Test for right click in line-wise visual mode outside the selection - funcs.setreg('"', '') - meths.win_set_cursor(0, {1, 15}) + fn.setreg('"', '') + api.nvim_win_set_cursor(0, { 1, 15 }) feed('V') - meths.input_mouse('right', 'press', '', 0, 1, 9) - meths.input_mouse('right', 'release', '', 0, 1, 9) + api.nvim_input_mouse('right', 'press', '', 0, 1, 9) + api.nvim_input_mouse('right', 'release', '', 0, 1, 9) feed('<Down><CR>') - eq({2, 9}, meths.win_get_cursor(0)) - eq('', funcs.getreg('"')) + eq({ 2, 9 }, api.nvim_win_get_cursor(0)) + eq('', fn.getreg('"')) -- Try clicking outside the window - funcs.setreg('"', '') - meths.win_set_cursor(0, {2, 1}) + fn.setreg('"', '') + api.nvim_win_set_cursor(0, { 2, 1 }) feed('vee') - meths.input_mouse('right', 'press', '', 0, 6, 1) - meths.input_mouse('right', 'release', '', 0, 6, 1) + api.nvim_input_mouse('right', 'press', '', 0, 6, 1) + api.nvim_input_mouse('right', 'release', '', 0, 6, 1) feed('<Down><CR>') - eq(2, funcs.winnr()) - eq('', funcs.getreg('"')) + eq(2, fn.winnr()) + eq('', fn.getreg('"')) -- Test for right click in visual mode inside the selection with vertical splits command('wincmd t') command('rightbelow vsplit') - funcs.setreg('"', '') - meths.win_set_cursor(0, {1, 9}) + fn.setreg('"', '') + api.nvim_win_set_cursor(0, { 1, 9 }) feed('vee') - meths.input_mouse('right', 'press', '', 0, 0, 52) - meths.input_mouse('right', 'release', '', 0, 0, 52) + api.nvim_input_mouse('right', 'press', '', 0, 0, 52) + api.nvim_input_mouse('right', 'release', '', 0, 0, 52) feed('<Down><CR>') - eq({1, 9}, meths.win_get_cursor(0)) - eq('ran away', funcs.getreg('"')) + eq({ 1, 9 }, api.nvim_win_get_cursor(0)) + eq('ran away', fn.getreg('"')) -- Test for right click inside visual selection at bottom of window with winbar command('setlocal winbar=WINBAR') feed('2yyP') - funcs.setreg('"', '') + fn.setreg('"', '') feed('G$vbb') - meths.input_mouse('right', 'press', '', 0, 4, 61) - meths.input_mouse('right', 'release', '', 0, 4, 61) + api.nvim_input_mouse('right', 'press', '', 0, 4, 61) + api.nvim_input_mouse('right', 'release', '', 0, 4, 61) feed('<Down><CR>') - eq({4, 20}, meths.win_get_cursor(0)) - eq('the moon', funcs.getreg('"')) + eq({ 4, 20 }, api.nvim_win_get_cursor(0)) + eq('the moon', fn.getreg('"')) end) end) diff --git a/test/functional/ui/multibyte_spec.lua b/test/functional/ui/multibyte_spec.lua index d72bf27d6b..c2fc763401 100644 --- a/test/functional/ui/multibyte_spec.lua +++ b/test/functional/ui/multibyte_spec.lua @@ -5,51 +5,49 @@ local command = helpers.command local feed = helpers.feed local feed_command = helpers.feed_command local insert = helpers.insert -local funcs = helpers.funcs -local meths = helpers.meths -local split = helpers.split +local fn = helpers.fn +local api = helpers.api +local split = vim.split local dedent = helpers.dedent -describe("multibyte rendering", function() +describe('multibyte rendering', function() local screen before_each(function() clear() screen = Screen.new(60, 6) - screen:attach({rgb=true}) + screen:attach({ rgb = true }) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue}, - [2] = {background = Screen.colors.WebGray}, - [3] = {background = Screen.colors.LightMagenta}, - [4] = {bold = true}, - [5] = {foreground = Screen.colors.Blue}, + [1] = { bold = true, foreground = Screen.colors.Blue }, + [2] = { background = Screen.colors.WebGray }, + [3] = { background = Screen.colors.LightMagenta }, + [4] = { bold = true }, + [5] = { foreground = Screen.colors.Blue }, + [6] = { reverse = true, bold = true }, + [7] = { reverse = true }, }) end) - it("works with composed char at start of line", function() + it('works with composed char at start of line', function() insert([[ ̊ x]]) - feed("gg") - -- verify the modifier in fact is alone - feed_command("ascii") + feed('gg') + -- verify the modifier in fact is alone + feed_command('ascii') screen:expect([[ ^ ̊ | x | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 < ̊> 778, Hex 030a, Octal 1412 | ]]) -- a char inserted before will spontaneously merge with it - feed("ia<esc>") - feed_command("ascii") + feed('ia<esc>') + feed_command('ascii') screen:expect([[ ^å | x | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 <a> 97, Hex 61, Octal 141 < ̊> 778, Hex 030a, Octal 1412 | ]]) end) @@ -58,10 +56,7 @@ describe("multibyte rendering", function() feed('58a <esc>a馬<esc>') screen:expect([[ ^馬| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | ]]) @@ -69,9 +64,7 @@ describe("multibyte rendering", function() screen:expect([[ ^ {1:>}| 馬 | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]) @@ -79,9 +72,7 @@ describe("multibyte rendering", function() screen:expect([[ {1:>}| ^馬 | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]) end) @@ -91,20 +82,17 @@ describe("multibyte rendering", function() screen:expect([[ ab ^ | -馬 | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {4:-- INSERT --} | ]]) - -- check double-with char is temporarily hidden when overlapped - funcs.complete(4, {'xx', 'yy'}) + -- check double-width char is temporarily hidden when overlapped + fn.complete(4, { 'xx', 'yy' }) screen:expect([[ ab xx^ | - {2: xx } | {1:~ }{3: yy }{1: }| - {1:~ }| - {1:~ }| + {1:~ }|*2 {4:-- INSERT --} | ]]) @@ -113,29 +101,60 @@ describe("multibyte rendering", function() screen:expect([[ ab xxz^ | -馬 | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {4:-- INSERT --} | ]]) end) + it('no stray chars when splitting left of window with double-width chars', function() + api.nvim_buf_set_lines(0, 0, -1, true, { + ('口'):rep(16), + 'a' .. ('口'):rep(16), + 'aa' .. ('口'):rep(16), + 'aaa' .. ('口'):rep(16), + 'aaaa' .. ('口'):rep(16), + }) + screen:expect([[ + ^口口口口口口口口口口口口口口口口 | + a口口口口口口口口口口口口口口口口 | + aa口口口口口口口口口口口口口口口口 | + aaa口口口口口口口口口口口口口口口口 | + aaaa口口口口口口口口口口口口口口口口 | + | + ]]) + + command('20vnew') + screen:expect([[ + ^ │口口口口口口口口口口口口口口口口 | + {1:~ }│a口口口口口口口口口口口口口口口口 | + {1:~ }│aa口口口口口口口口口口口口口口口口 | + {1:~ }│aaa口口口口口口口口口口口口口口口口 | + {6:[No Name] }{7:[No Name] [+] }| + | + ]]) + end) + it('0xffff is shown as 4 hex digits', function() command([[call setline(1, "\uFFFF!!!")]]) feed('$') - screen:expect{grid=[[ + screen:expect { + grid = [[ {5:<ffff>}!!^! | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | - ]]} + ]], + } end) it('works with a lot of unicode (zalgo) text', function() screen:try_resize(65, 10) - meths.buf_set_lines(0,0,-1,true, split(dedent [[ + api.nvim_buf_set_lines( + 0, + 0, + -1, + true, + split( + dedent [[ L̓̉̑̒̌̚ơ̗̌̒̄̀ŕ̈̈̎̐̕è̇̅̄̄̐m̖̟̟̅̄̚ ̛̓̑̆̇̍i̗̟̞̜̅̐p̗̞̜̉̆̕s̟̜̘̍̑̏ū̟̞̎̃̉ḿ̘̙́́̐ ̖̍̌̇̉̚d̞̄̃̒̉̎ò́̌̌̂̐l̞̀̄̆̌̚ȯ̖̞̋̀̐r̓̇̌̃̃̚ ̗̘̀̏̍́s̜̀̎̎̑̕i̟̗̐̄̄̚t̝̎̆̓̐̒ ̘̇̔̓̊̚ȃ̛̟̗̏̅m̜̟̙̞̈̓é̘̞̟̔̆t̝̂̂̈̑̔,̜̜̖̅̄̍ ̛̗̊̓̆̚c̟̍̆̍̈̔ȯ̖̖̝̑̀n̜̟̎̊̃̚s̟̏̇̎̒̚e̙̐̈̓̌̚c̙̍̈̏̅̕ť̇̄̇̆̓e̛̓̌̈̓̈t̟̍̀̉̆̅u̝̞̎̂̄̚r̘̀̅̈̅̐ ̝̞̓́̇̉ã̏̀̆̅̕d̛̆̐̉̆̋ȉ̞̟̍̃̚p̛̜̊̍̂̓ȋ̏̅̃̋̚ṥ̛̏̃̕č̛̞̝̀̂í̗̘̌́̎n̔̎́̒̂̕ǧ̗̜̋̇̂ ̛̜̔̄̎̃ê̛̔̆̇̕l̘̝̏̐̊̏ĩ̛̍̏̏̄t̟̐́̀̐̎,̙̘̍̆̉̐ ̋̂̏̄̌̅s̙̓̌̈́̇e̛̗̋̒̎̏d̜̗̊̍̊̚ ď̘̋̌̌̕ǒ̝̗̔̇̕ ̙̍́̄̄̉è̛̛̞̌̌i̜̖̐̈̆̚ȕ̇̈̓̃̓ŝ̛̞̙̉̋m̜̐̂̄̋̂ȯ̈̎̎̅̕d̜̙̓̔̋̑ ̞̗̄̂̂̚t̝̊́̃́̄e̛̘̜̞̓̑m̊̅̏̉̌̕p̛̈̂̇̀̐ỏ̙̘̈̉̔r̘̞̋̍̃̚ ̝̄̀̇̅̇ỉ̛̖̍̓̈n̛̛̝̎̕̕c̛̛̊̅́̐ĭ̗̓̀̍̐d̞̜̋̐̅̚i̟̙̇̄̊̄d̞̊̂̀̇̚ủ̝̉̑̃̕n̜̏̇̄̐̋ť̗̜̞̋̉ ̝̒̓̌̓̚ȕ̖̙̀̚̕t̖̘̎̉̂̌ ̛̝̄̍̌̂l̛̟̝̃̑̋á̛̝̝̔̅b̝̙̜̗̅̒ơ̖̌̒̄̆r̒̇̓̎̈̄e̛̛̖̅̏̇ ̖̗̜̝̃́e̛̛̘̅̔̌ẗ̛̙̗̐̕ ̖̟̇̋̌̈d̞̙̀̉̑̕ŏ̝̂́̐̑l̞̟̗̓̓̀ơ̘̎̃̄̂r̗̗̖̔̆̍ẻ̖̝̞̋̅ ̜̌̇̍̈̊m̈̉̇̄̒̀a̜̞̘̔̅̆g̗̖̈̃̈̉n̙̖̄̈̉̄â̛̝̜̄̃ ̛́̎̕̕̚ā̊́́̆̌l̟̙̞̃̒́i̖̇̎̃̀̋q̟̇̒̆́̊ủ́̌̇̑̚ã̛̘̉̐̚.̛́̏̐̍̊ U̝̙̎̈̐̆t̜̍̌̀̔̏ ̞̉̍̇̈̃e̟̟̊̄̕̕n̝̜̒̓̆̕i̖̒̌̅̇̚m̞̊̃̔̊̂ ̛̜̊̎̄̂a̘̜̋̒̚̚d̟̊̎̇̂̍ ̜̖̏̑̉̕m̜̒̎̅̄̚i̝̖̓̂̍̕n̙̉̒̑̀̔ỉ̖̝̌̒́m̛̖̘̅̆̎ ̖̉̎̒̌̕v̖̞̀̔́̎e̖̙̗̒̎̉n̛̗̝̎̀̂ȉ̞̗̒̕̚ȧ̟̜̝̅̚m̆̉̐̐̇̈,̏̐̎́̍́ ̜̞̙̘̏̆q̙̖̙̅̓̂ủ̇́̀̔̚í̙̟̟̏̐s̖̝̍̏̂̇ ̛̘̋̈̕̕ń̛̞̜̜̎o̗̜̔̔̈̆s̞̘̘̄̒̋t̛̅̋́̔̈ȓ̓̒́̇̅ủ̜̄̃̒̍d̙̝̘̊̏̚ ̛̟̞̄́̔e̛̗̝̍̃̀x̞̖̃̄̂̅e̖̅̇̐̔̃r̗̞̖̔̎̚c̘̜̖̆̊̏ï̙̝̙̂̕t̖̏́̓̋̂ă̖̄̆̑̒t̜̟̍̉̑̏i̛̞̞̘̒̑ǒ̜̆̅̃̉ṅ̖̜̒̎̚ @@ -144,11 +163,14 @@ describe("multibyte rendering", function() ē̟̊̇̕̚s̖̘̘̒̄̑s̛̘̀̊̆̇e̛̝̘̒̏̚ ̉̅̑̂̐̎c̛̟̙̎̋̓i̜̇̒̏̆̆l̟̄́̆̊̌l̍̊̋̃̆̌ủ̗̙̒̔̚m̛̘̘̖̅̍ ̖̙̈̎̂̕d̞̟̏̋̈̔ơ̟̝̌̃̄l̗̙̝̂̉̒õ̒̃̄̄̚ŕ̗̏̏̊̍ê̞̝̞̋̈ ̜̔̒̎̃̚e̞̟̞̒̃̄ư̖̏̄̑̃ ̛̗̜̄̓̎f̛̖̞̅̓̃ü̞̏̆̋̕g̜̝̞̑̑̆i̛̘̐̐̅̚à̜̖̌̆̎t̙̙̎̉̂̍ ̋̔̈̎̎̉n̞̓́̔̊̕ư̘̅̋̔̚l̗̍̒̄̀̚l̞̗̘̙̓̍â̘̔̒̎̚ ̖̓̋̉̃̆p̛̛̘̋̌̀ä̙̔́̒̕r̟̟̖̋̐̋ì̗̙̎̓̓ȃ̔̋̑̚̕t̄́̎̓̂̋ư̏̈̂̑̃r̖̓̋̊̚̚.̒̆̑̆̊̎ ̘̜̍̐̂̚E̞̅̐̇́̂x̄́̈̌̉̕ć̘̃̉̃̕è̘̂̑̏̑p̝̘̑̂̌̆t̔̐̅̍̌̂ȇ̞̈̐̚̕ű̝̞̜́̚ŕ̗̝̉̆́ š̟́̔̏̀ȉ̝̟̝̏̅n̑̆̇̒̆̚t̝̒́̅̋̏ ̗̑̌̋̇̚ơ̙̗̟̆̅c̙̞̙̎̊̎c̘̟̍̔̊̊a̛̒̓̉́̐e̜̘̙̒̅̇ć̝̝̂̇̕ả̓̍̎̂̚t̗̗̗̟̒̃ ̘̒̓̐̇́c̟̞̉̐̓̄ȕ̙̗̅́̏p̛̍̋̈́̅i̖̓̒̍̈̄d̞̃̈̌̆̐a̛̗̝̎̋̉t̞̙̀̊̆̇a̛̙̒̆̉̚t̜̟̘̉̓̚ ̝̘̗̐̇̕n̛̘̑̏̂́ō̑̋̉̏́ň̞̊̆̄̃ ̙̙̙̜̄̏p̒̆̋̋̓̏r̖̖̅̉́̚ơ̜̆̑̈̚i̟̒̀̃̂̌d̛̏̃̍̋̚ë̖̞̙̗̓n̛̘̓̒̅̎t̟̗̙̊̆̚,̘̙̔̊̚̕ ̟̗̘̜̑̔s̜̝̍̀̓̌û̞̙̅̇́n̘̗̝̒̃̎t̗̅̀̅̊̈ ̗̖̅̅̀̄i̛̖̍̅̋̂n̙̝̓̓̎̚ ̞̋̅̋̃̚c̗̒̀̆̌̎ū̞̂̑̌̓ĺ̛̐̍̑́p̝̆̌̎̈̚a̖̙̒̅̈̌ ̝̝̜̂̈̀q̝̖̔̍̒̚ư̔̐̂̎̊ǐ̛̟̖̘̕ o̖̜̔̋̅̚f̛̊̀̉́̕f̏̉̀̔̃̃i̘̍̎̐̔̎c̙̅̑̂̐̅ȋ̛̜̀̒̚a̋̍̇̏̀̋ ̖̘̒̅̃̒d̗̘̓̈̇̋é̝́̎̒̄š̙̒̊̉̋e̖̓̐̀̍̕r̗̞̂̅̇̄ù̘̇̐̉̀n̐̑̀̄̍̐t̟̀̂̊̄̚ ̟̝̂̍̏́m̜̗̈̂̏̚ő̞̊̑̇̒l̘̑̏́̔̄l̛̛̇̃̋̊i̓̋̒̃̉̌t̛̗̜̏̀̋ ̙̟̒̂̌̐a̙̝̔̆̏̅n̝̙̙̗̆̅i̍̔́̊̃̕m̖̝̟̒̍̚ ̛̃̃̑̌́ǐ̘̉̔̅̚d̝̗̀̌̏̒ ̖̝̓̑̊̚ȇ̞̟̖̌̕š̙̙̈̔̀t̂̉̒̍̄̄ ̝̗̊̋̌̄l̛̞̜̙̘̔å̝̍̂̍̅b̜̆̇̈̉̌ǒ̜̙̎̃̆r̝̀̄̍́̕ư̋̊́̊̕m̜̗̒̐̕̚.̟̘̀̒̌̚]], - '\n')) + '\n' + ) + ) -- tests that we can handle overflow of the buffer -- for redraw events (4096 bytes) gracefully - screen:expect{grid=[[ + screen:expect { + grid = [[ ^L̓̉̑̒̌̚ơ̗̌̒̄̀ŕ̈̈̎̐̕è̇̅̄̄̐m̖̟̟̅̄̚ ̛̓̑̆̇̍i̗̟̞̜̅̐p̗̞̜̉̆̕s̟̜̘̍̑̏ū̟̞̎̃̉ḿ̘̙́́̐ ̖̍̌̇̉̚d̞̄̃̒̉̎ò́̌̌̂̐l̞̀̄̆̌̚ȯ̖̞̋̀̐r̓̇̌̃̃̚ ̗̘̀̏̍́s̜̀̎̎̑̕i̟̗̐̄̄̚t̝̎̆̓̐̒ ̘̇̔̓̊̚ȃ̛̟̗̏̅m̜̟̙̞̈̓é̘̞̟̔̆t̝̂̂̈̑̔,̜̜̖̅̄̍ ̛̗̊̓̆̚c̟̍̆̍̈̔ȯ̖̖̝̑̀n̜̟̎̊̃̚s̟̏̇̎̒̚e̙̐̈̓̌̚c̙̍̈̏̅̕ť̇̄̇̆̓e̛̓̌̈̓̈t̟̍̀̉̆̅u̝̞̎̂̄̚r̘̀̅̈̅̐ ̝̞̓́̇̉ã̏̀̆̅̕d̛̆̐̉̆̋ȉ̞̟̍̃̚p̛̜̊̍̂̓ȋ̏̅̃̋̚ṥ̛̏̃̕č̛̞̝̀̂í̗̘̌́̎n̔̎́̒̂̕ǧ̗̜̋̇̂ ̛̜̔̄̎̃ê̛̔̆̇̕l̘̝̏̐̊̏ĩ̛̍̏̏̄t̟̐́̀̐̎,̙̘̍̆̉̐ ̋̂̏̄̌̅s̙̓̌̈́̇e̛̗̋̒̎̏d̜̗̊̍̊̚ | ď̘̋̌̌̕ǒ̝̗̔̇̕ ̙̍́̄̄̉è̛̛̞̌̌i̜̖̐̈̆̚ȕ̇̈̓̃̓ŝ̛̞̙̉̋m̜̐̂̄̋̂ȯ̈̎̎̅̕d̜̙̓̔̋̑ ̞̗̄̂̂̚t̝̊́̃́̄e̛̘̜̞̓̑m̊̅̏̉̌̕p̛̈̂̇̀̐ỏ̙̘̈̉̔r̘̞̋̍̃̚ ̝̄̀̇̅̇ỉ̛̖̍̓̈n̛̛̝̎̕̕c̛̛̊̅́̐ĭ̗̓̀̍̐d̞̜̋̐̅̚i̟̙̇̄̊̄d̞̊̂̀̇̚ủ̝̉̑̃̕n̜̏̇̄̐̋ť̗̜̞̋̉ ̝̒̓̌̓̚ȕ̖̙̀̚̕t̖̘̎̉̂̌ ̛̝̄̍̌̂l̛̟̝̃̑̋á̛̝̝̔̅b̝̙̜̗̅̒ơ̖̌̒̄̆r̒̇̓̎̈̄e̛̛̖̅̏̇ ̖̗̜̝̃́e̛̛̘̅̔̌ẗ̛̙̗̐̕ ̖̟̇̋̌̈d̞̙̀̉̑̕ŏ̝̂́̐̑l̞̟̗̓̓̀ơ̘̎̃̄̂r̗̗̖̔̆̍ẻ̖̝̞̋̅ ̜̌̇̍̈̊m̈̉̇̄̒̀a̜̞̘̔̅̆g̗̖̈̃̈̉n̙̖̄̈̉̄â̛̝̜̄̃ ̛́̎̕̕̚ā̊́́̆̌l̟̙̞̃̒́i̖̇̎̃̀̋q̟̇̒̆́̊ủ́̌̇̑̚ã̛̘̉̐̚.̛́̏̐̍̊ | U̝̙̎̈̐̆t̜̍̌̀̔̏ ̞̉̍̇̈̃e̟̟̊̄̕̕n̝̜̒̓̆̕i̖̒̌̅̇̚m̞̊̃̔̊̂ ̛̜̊̎̄̂a̘̜̋̒̚̚d̟̊̎̇̂̍ ̜̖̏̑̉̕m̜̒̎̅̄̚i̝̖̓̂̍̕n̙̉̒̑̀̔ỉ̖̝̌̒́m̛̖̘̅̆̎ ̖̉̎̒̌̕v̖̞̀̔́̎e̖̙̗̒̎̉n̛̗̝̎̀̂ȉ̞̗̒̕̚ȧ̟̜̝̅̚m̆̉̐̐̇̈,̏̐̎́̍́ ̜̞̙̘̏̆q̙̖̙̅̓̂ủ̇́̀̔̚í̙̟̟̏̐s̖̝̍̏̂̇ ̛̘̋̈̕̕ń̛̞̜̜̎o̗̜̔̔̈̆s̞̘̘̄̒̋t̛̅̋́̔̈ȓ̓̒́̇̅ủ̜̄̃̒̍d̙̝̘̊̏̚ ̛̟̞̄́̔e̛̗̝̍̃̀x̞̖̃̄̂̅e̖̅̇̐̔̃r̗̞̖̔̎̚c̘̜̖̆̊̏ï̙̝̙̂̕t̖̏́̓̋̂ă̖̄̆̑̒t̜̟̍̉̑̏i̛̞̞̘̒̑ǒ̜̆̅̃̉ṅ̖̜̒̎̚ | @@ -159,12 +181,14 @@ describe("multibyte rendering", function() o̖̜̔̋̅̚f̛̊̀̉́̕f̏̉̀̔̃̃i̘̍̎̐̔̎c̙̅̑̂̐̅ȋ̛̜̀̒̚a̋̍̇̏̀̋ ̖̘̒̅̃̒d̗̘̓̈̇̋é̝́̎̒̄š̙̒̊̉̋e̖̓̐̀̍̕r̗̞̂̅̇̄ù̘̇̐̉̀n̐̑̀̄̍̐t̟̀̂̊̄̚ ̟̝̂̍̏́m̜̗̈̂̏̚ő̞̊̑̇̒l̘̑̏́̔̄l̛̛̇̃̋̊i̓̋̒̃̉̌t̛̗̜̏̀̋ ̙̟̒̂̌̐a̙̝̔̆̏̅n̝̙̙̗̆̅i̍̔́̊̃̕m̖̝̟̒̍̚ ̛̃̃̑̌́ǐ̘̉̔̅̚d̝̗̀̌̏̒ ̖̝̓̑̊̚ȇ̞̟̖̌̕š̙̙̈̔̀t̂̉̒̍̄̄ ̝̗̊̋̌̄l̛̞̜̙̘̔å̝̍̂̍̅b̜̆̇̈̉̌ǒ̜̙̎̃̆r̝̀̄̍́̕ư̋̊́̊̕m̜̗̒̐̕̚.̟̘̀̒̌̚ | {1:~ }| | - ]]} + ]], + } -- nvim will reset the zalgo text^W^W glyph cache if it gets too full. -- this should be exceedingly rare, but fake it to make sure it works - meths._invalidate_glyph_cache() - screen:expect{grid=[[ + api.nvim__invalidate_glyph_cache() + screen:expect { + grid = [[ ^L̓̉̑̒̌̚ơ̗̌̒̄̀ŕ̈̈̎̐̕è̇̅̄̄̐m̖̟̟̅̄̚ ̛̓̑̆̇̍i̗̟̞̜̅̐p̗̞̜̉̆̕s̟̜̘̍̑̏ū̟̞̎̃̉ḿ̘̙́́̐ ̖̍̌̇̉̚d̞̄̃̒̉̎ò́̌̌̂̐l̞̀̄̆̌̚ȯ̖̞̋̀̐r̓̇̌̃̃̚ ̗̘̀̏̍́s̜̀̎̎̑̕i̟̗̐̄̄̚t̝̎̆̓̐̒ ̘̇̔̓̊̚ȃ̛̟̗̏̅m̜̟̙̞̈̓é̘̞̟̔̆t̝̂̂̈̑̔,̜̜̖̅̄̍ ̛̗̊̓̆̚c̟̍̆̍̈̔ȯ̖̖̝̑̀n̜̟̎̊̃̚s̟̏̇̎̒̚e̙̐̈̓̌̚c̙̍̈̏̅̕ť̇̄̇̆̓e̛̓̌̈̓̈t̟̍̀̉̆̅u̝̞̎̂̄̚r̘̀̅̈̅̐ ̝̞̓́̇̉ã̏̀̆̅̕d̛̆̐̉̆̋ȉ̞̟̍̃̚p̛̜̊̍̂̓ȋ̏̅̃̋̚ṥ̛̏̃̕č̛̞̝̀̂í̗̘̌́̎n̔̎́̒̂̕ǧ̗̜̋̇̂ ̛̜̔̄̎̃ê̛̔̆̇̕l̘̝̏̐̊̏ĩ̛̍̏̏̄t̟̐́̀̐̎,̙̘̍̆̉̐ ̋̂̏̄̌̅s̙̓̌̈́̇e̛̗̋̒̎̏d̜̗̊̍̊̚ | ď̘̋̌̌̕ǒ̝̗̔̇̕ ̙̍́̄̄̉è̛̛̞̌̌i̜̖̐̈̆̚ȕ̇̈̓̃̓ŝ̛̞̙̉̋m̜̐̂̄̋̂ȯ̈̎̎̅̕d̜̙̓̔̋̑ ̞̗̄̂̂̚t̝̊́̃́̄e̛̘̜̞̓̑m̊̅̏̉̌̕p̛̈̂̇̀̐ỏ̙̘̈̉̔r̘̞̋̍̃̚ ̝̄̀̇̅̇ỉ̛̖̍̓̈n̛̛̝̎̕̕c̛̛̊̅́̐ĭ̗̓̀̍̐d̞̜̋̐̅̚i̟̙̇̄̊̄d̞̊̂̀̇̚ủ̝̉̑̃̕n̜̏̇̄̐̋ť̗̜̞̋̉ ̝̒̓̌̓̚ȕ̖̙̀̚̕t̖̘̎̉̂̌ ̛̝̄̍̌̂l̛̟̝̃̑̋á̛̝̝̔̅b̝̙̜̗̅̒ơ̖̌̒̄̆r̒̇̓̎̈̄e̛̛̖̅̏̇ ̖̗̜̝̃́e̛̛̘̅̔̌ẗ̛̙̗̐̕ ̖̟̇̋̌̈d̞̙̀̉̑̕ŏ̝̂́̐̑l̞̟̗̓̓̀ơ̘̎̃̄̂r̗̗̖̔̆̍ẻ̖̝̞̋̅ ̜̌̇̍̈̊m̈̉̇̄̒̀a̜̞̘̔̅̆g̗̖̈̃̈̉n̙̖̄̈̉̄â̛̝̜̄̃ ̛́̎̕̕̚ā̊́́̆̌l̟̙̞̃̒́i̖̇̎̃̀̋q̟̇̒̆́̊ủ́̌̇̑̚ã̛̘̉̐̚.̛́̏̐̍̊ | U̝̙̎̈̐̆t̜̍̌̀̔̏ ̞̉̍̇̈̃e̟̟̊̄̕̕n̝̜̒̓̆̕i̖̒̌̅̇̚m̞̊̃̔̊̂ ̛̜̊̎̄̂a̘̜̋̒̚̚d̟̊̎̇̂̍ ̜̖̏̑̉̕m̜̒̎̅̄̚i̝̖̓̂̍̕n̙̉̒̑̀̔ỉ̖̝̌̒́m̛̖̘̅̆̎ ̖̉̎̒̌̕v̖̞̀̔́̎e̖̙̗̒̎̉n̛̗̝̎̀̂ȉ̞̗̒̕̚ȧ̟̜̝̅̚m̆̉̐̐̇̈,̏̐̎́̍́ ̜̞̙̘̏̆q̙̖̙̅̓̂ủ̇́̀̔̚í̙̟̟̏̐s̖̝̍̏̂̇ ̛̘̋̈̕̕ń̛̞̜̜̎o̗̜̔̔̈̆s̞̘̘̄̒̋t̛̅̋́̔̈ȓ̓̒́̇̅ủ̜̄̃̒̍d̙̝̘̊̏̚ ̛̟̞̄́̔e̛̗̝̍̃̀x̞̖̃̄̂̅e̖̅̇̐̔̃r̗̞̖̔̎̚c̘̜̖̆̊̏ï̙̝̙̂̕t̖̏́̓̋̂ă̖̄̆̑̒t̜̟̍̉̑̏i̛̞̞̘̒̑ǒ̜̆̅̃̉ṅ̖̜̒̎̚ | @@ -175,7 +199,9 @@ describe("multibyte rendering", function() o̖̜̔̋̅̚f̛̊̀̉́̕f̏̉̀̔̃̃i̘̍̎̐̔̎c̙̅̑̂̐̅ȋ̛̜̀̒̚a̋̍̇̏̀̋ ̖̘̒̅̃̒d̗̘̓̈̇̋é̝́̎̒̄š̙̒̊̉̋e̖̓̐̀̍̕r̗̞̂̅̇̄ù̘̇̐̉̀n̐̑̀̄̍̐t̟̀̂̊̄̚ ̟̝̂̍̏́m̜̗̈̂̏̚ő̞̊̑̇̒l̘̑̏́̔̄l̛̛̇̃̋̊i̓̋̒̃̉̌t̛̗̜̏̀̋ ̙̟̒̂̌̐a̙̝̔̆̏̅n̝̙̙̗̆̅i̍̔́̊̃̕m̖̝̟̒̍̚ ̛̃̃̑̌́ǐ̘̉̔̅̚d̝̗̀̌̏̒ ̖̝̓̑̊̚ȇ̞̟̖̌̕š̙̙̈̔̀t̂̉̒̍̄̄ ̝̗̊̋̌̄l̛̞̜̙̘̔å̝̍̂̍̅b̜̆̇̈̉̌ǒ̜̙̎̃̆r̝̀̄̍́̕ư̋̊́̊̕m̜̗̒̐̕̚.̟̘̀̒̌̚ | {1:~ }| | - ]], reset=true} + ]], + reset = true, + } end) it('works with arabic input and arabicshape', function() @@ -183,24 +209,22 @@ describe("multibyte rendering", function() command('set noarabicshape') feed('isghl!<esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^!مالس| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*4 | - ]]} + ]], + } command('set arabicshape') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^!ﻡﻼﺳ| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*4 | - ]]} + ]], + } end) it('works with arabic input and arabicshape and norightleft', function() @@ -208,25 +232,22 @@ describe("multibyte rendering", function() command('set noarabicshape') feed('isghl!<esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ سلام^! | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | - ]]} + ]], + } command('set arabicshape') - screen:expect{grid=[[ + screen:expect { + grid = [[ ﺱﻼﻣ^! | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | - ]]} - + ]], + } end) it('works with arabicshape and multiple composing chars', function() @@ -236,27 +257,25 @@ describe("multibyte rendering", function() -- If we would increase the schar_t size, say from 32 to 64 bytes, we need to extend the -- test text with even more zalgo energy to still touch this edge case. - meths.buf_set_lines(0,0,-1,true, {"سلام့̀́̂̃̄̅̆̇̈̉̊̋̌"}) + api.nvim_buf_set_lines(0, 0, -1, true, { 'سلام့̀́̂̃̄̅̆̇̈̉̊̋̌' }) command('set noarabicshape') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^سلام့̀́̂̃̄̅̆̇̈̉̊̋̌ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | - ]]} + ]], + } command('set arabicshape') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ﺱﻼﻣ̀́̂̃̄̅̆̇̈̉̊̋̌ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | - ]]} + ]], + } end) end) @@ -267,9 +286,9 @@ describe('multibyte rendering: statusline', function() clear() screen = Screen.new(40, 4) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {bold = true, reverse = true}, - [3] = {background = Screen.colors.Red, foreground = Screen.colors.Gray100}; + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { bold = true, reverse = true }, + [3] = { background = Screen.colors.Red, foreground = Screen.colors.Gray100 }, }) screen:attach() command('set laststatus=2') @@ -325,34 +344,40 @@ describe('multibyte rendering: statusline', function() it('hidden group %( %) does not cause invalid unicode', function() command("let &statusline = '%#StatColorHi2#%(✓%#StatColorHi2#%) Q≡'") - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | {1:~ }| {2: Q≡ }| | - ]]} + ]], + } end) it('unprintable chars in filename with default stl', function() - command("file 🧑💻") + command('file 🧑💻') -- TODO: this is wrong but avoids a crash - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | {1:~ }| {2:🧑�💻 }| | - ]]} + ]], + } end) it('unprintable chars in filename with custom stl', function() command('set statusline=xx%#ErrorMsg#%f%##yy') - command("file 🧑💻") + command('file 🧑💻') -- TODO: this is also wrong but also avoids a crash - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | {1:~ }| {2:xx}{3:🧑<200d>💻}{2:yy }| | - ]]} + ]], + } end) end) diff --git a/test/functional/ui/multigrid_spec.lua b/test/functional/ui/multigrid_spec.lua index 5b982df2b5..c1d3af085f 100644 --- a/test/functional/ui/multigrid_spec.lua +++ b/test/functional/ui/multigrid_spec.lua @@ -3,9 +3,9 @@ local Screen = require('test.functional.ui.screen') local clear = helpers.clear local feed, command, insert = helpers.feed, helpers.command, helpers.insert local eq = helpers.eq -local funcs = helpers.funcs -local meths = helpers.meths -local curwin = helpers.curwin +local fn = helpers.fn +local api = helpers.api +local curwin = helpers.api.nvim_get_current_win local poke_eventloop = helpers.poke_eventloop @@ -36,7 +36,7 @@ describe('ext_multigrid', function() [17] = {background = Screen.colors.LightGrey, underline = true, bold = true, foreground = Screen.colors.Magenta}, [18] = {bold = true, foreground = Screen.colors.Magenta}, [19] = {foreground = Screen.colors.Brown}, - [20] = {background = Screen.colors.LightGrey}, + [20] = {background = Screen.colors.LightGrey, foreground = Screen.colors.Black}, [21] = {background = Screen.colors.LightMagenta}, [22] = {background = Screen.colors.LightMagenta, bold = true, foreground = Screen.colors.Blue}, [23] = {background = Screen.colors.Grey90}, @@ -47,33 +47,12 @@ describe('ext_multigrid', function() it('default initial screen', function() screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ## grid 3 | ]]} @@ -83,144 +62,71 @@ describe('ext_multigrid', function() command('vsplit') screen:expect{grid=[[ ## grid 1 - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| + [4:--------------------------]│[2:--------------------------]|*12 {11:[No Name] }{12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ## grid 3 | ## grid 4 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ]], condition=function() eq({ - [2] = { win = {id=1000}, startrow = 0, startcol = 27, width = 26, height = 12 }, - [4] = { win = {id=1001}, startrow = 0, startcol = 0, width = 26, height = 12 } + [2] = { win = 1000, startrow = 0, startcol = 27, width = 26, height = 12 }, + [4] = { win = 1001, startrow = 0, startcol = 0, width = 26, height = 12 } }, screen.win_position) end} command('wincmd l') command('split') screen:expect{grid=[[ ## grid 1 - [4:--------------------------]│[5:--------------------------]| - [4:--------------------------]│[5:--------------------------]| - [4:--------------------------]│[5:--------------------------]| - [4:--------------------------]│[5:--------------------------]| - [4:--------------------------]│[5:--------------------------]| - [4:--------------------------]│[5:--------------------------]| + [4:--------------------------]│[5:--------------------------]|*6 [4:--------------------------]│{11:[No Name] }| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| + [4:--------------------------]│[2:--------------------------]|*5 {12:[No Name] [No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ## grid 4 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ## grid 5 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]], condition=function() eq({ - [2] = { win = {id=1000}, startrow = 7, startcol = 27, width = 26, height = 5 }, - [4] = { win = {id=1001}, startrow = 0, startcol = 0, width = 26, height = 12 }, - [5] = { win = {id=1002}, startrow = 0, startcol = 27, width = 26, height = 6 } + [2] = { win = 1000, startrow = 7, startcol = 27, width = 26, height = 5 }, + [4] = { win = 1001, startrow = 0, startcol = 0, width = 26, height = 12 }, + [5] = { win = 1002, startrow = 0, startcol = 27, width = 26, height = 6 } }, screen.win_position) end} command('wincmd h') command('q') screen:expect{grid=[[ ## grid 1 - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| + [5:-----------------------------------------------------]|*6 {11:[No Name] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*5 {12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ## grid 5 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]], condition=function() eq({ - [2] = { win = {id=1000}, startrow = 7, startcol = 0, width = 53, height = 5 }, - [5] = { win = {id=1002}, startrow = 0, startcol = 0, width = 53, height = 6 } + [2] = { win = 1000, startrow = 7, startcol = 0, width = 53, height = 5 }, + [5] = { win = 1002, startrow = 0, startcol = 0, width = 53, height = 6 } }, screen.win_position) end} end) @@ -231,35 +137,19 @@ describe('ext_multigrid', function() command('sp') screen:expect([[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*6 {11:[No Name] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*5 {12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ## grid 4 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]) end) @@ -268,35 +158,19 @@ describe('ext_multigrid', function() command('resize 8') screen:expect([[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*8 {11:[No Name] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*3 {12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| + {1:~ }|*2 ## grid 3 | ## grid 4 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*7 ]]) end) @@ -306,162 +180,77 @@ describe('ext_multigrid', function() command('vsp') screen:expect{grid=[[ ## grid 1 - [6:--------------------]│[5:----------------]│[4:---------------]| - [6:--------------------]│[5:----------------]│[4:---------------]| - [6:--------------------]│[5:----------------]│[4:---------------]| - [6:--------------------]│[5:----------------]│[4:---------------]| - [6:--------------------]│[5:----------------]│[4:---------------]| - [6:--------------------]│[5:----------------]│[4:---------------]| + [6:--------------------]│[5:----------------]│[4:---------------]|*6 {11:[No Name] }{12:[No Name] [No Name] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*5 {12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ## grid 4 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 5 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 6 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]} insert('hello') screen:expect{grid=[[ ## grid 1 - [6:--------------------]│[5:----------------]│[4:---------------]| - [6:--------------------]│[5:----------------]│[4:---------------]| - [6:--------------------]│[5:----------------]│[4:---------------]| - [6:--------------------]│[5:----------------]│[4:---------------]| - [6:--------------------]│[5:----------------]│[4:---------------]| - [6:--------------------]│[5:----------------]│[4:---------------]| + [6:--------------------]│[5:----------------]│[4:---------------]|*6 {11:[No Name] [+] }{12:[No Name] [+] [No Name] [+] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*5 {12:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 hello | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ## grid 4 hello | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 5 hello | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 6 hell^o | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]} end) it('closes splits', function () command('sp') screen:expect{grid=[[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*6 {11:[No Name] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*5 {12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ## grid 4 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]} command('q') screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ## grid 3 | ]]} @@ -473,48 +262,17 @@ describe('ext_multigrid', function() command('vsp') screen:expect{grid=[[ ## grid 1 - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| + [4:--------------------------]│[2:--------------------------]|*12 {11:[No Name] }{12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ## grid 3 | ## grid 4 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ]]} end) it('resizes grids', function () @@ -522,48 +280,17 @@ describe('ext_multigrid', function() command('vertical resize 10') screen:expect{grid=[[ ## grid 1 - [4:----------]│[2:------------------------------------------]| - [4:----------]│[2:------------------------------------------]| - [4:----------]│[2:------------------------------------------]| - [4:----------]│[2:------------------------------------------]| - [4:----------]│[2:------------------------------------------]| - [4:----------]│[2:------------------------------------------]| - [4:----------]│[2:------------------------------------------]| - [4:----------]│[2:------------------------------------------]| - [4:----------]│[2:------------------------------------------]| - [4:----------]│[2:------------------------------------------]| - [4:----------]│[2:------------------------------------------]| - [4:----------]│[2:------------------------------------------]| + [4:----------]│[2:------------------------------------------]|*12 {11:<No Name] }{12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ## grid 3 | ## grid 4 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ]]} end) it('splits horizontally', function () @@ -571,173 +298,69 @@ describe('ext_multigrid', function() command('sp') screen:expect{grid=[[ ## grid 1 - [5:--------------------------]│[2:--------------------------]| - [5:--------------------------]│[2:--------------------------]| - [5:--------------------------]│[2:--------------------------]| - [5:--------------------------]│[2:--------------------------]| - [5:--------------------------]│[2:--------------------------]| - [5:--------------------------]│[2:--------------------------]| + [5:--------------------------]│[2:--------------------------]|*6 {11:[No Name] }│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| + [4:--------------------------]│[2:--------------------------]|*5 {12:[No Name] [No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ## grid 3 | ## grid 4 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 5 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]} insert('hello') screen:expect{grid=[[ ## grid 1 - [5:--------------------------]│[2:--------------------------]| - [5:--------------------------]│[2:--------------------------]| - [5:--------------------------]│[2:--------------------------]| - [5:--------------------------]│[2:--------------------------]| - [5:--------------------------]│[2:--------------------------]| - [5:--------------------------]│[2:--------------------------]| + [5:--------------------------]│[2:--------------------------]|*6 {11:[No Name] [+] }│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| + [4:--------------------------]│[2:--------------------------]|*5 {12:[No Name] [+] [No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 hello | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ## grid 3 | ## grid 4 hello | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 5 hell^o | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]} end) it('closes splits', function () command('vsp') screen:expect{grid=[[ ## grid 1 - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| + [4:--------------------------]│[2:--------------------------]|*12 {11:[No Name] }{12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ## grid 3 | ## grid 4 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ]]} command('q') screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ## grid 3 | ]]} @@ -750,17 +373,12 @@ describe('ext_multigrid', function() screen:try_resize(25, 6) screen:expect{grid=[[ ## grid 1 - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| - [2:-------------------------]| + [2:-------------------------]|*4 {11:[No Name] }| [3:-------------------------]| ## grid 2 ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 | ]]} @@ -799,26 +417,12 @@ describe('ext_multigrid', function() screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ]]} @@ -831,41 +435,12 @@ describe('ext_multigrid', function() screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*19 ## grid 3 | ]]} @@ -879,52 +454,30 @@ describe('ext_multigrid', function() end) it('winwidth() winheight() getwininfo() return inner width and height #19743', function() - eq(60, funcs.winwidth(0)) - eq(20, funcs.winheight(0)) - local win_info = funcs.getwininfo(curwin().id)[1] + eq(60, fn.winwidth(0)) + eq(20, fn.winheight(0)) + local win_info = fn.getwininfo(curwin())[1] eq(60, win_info.width) eq(20, win_info.height) end) + it("'scroll' option works properly", function() + eq(10, api.nvim_get_option_value('scroll', { win = 0 })) + api.nvim_set_option_value('scroll', 15, { win = 0 }) + eq(15, api.nvim_get_option_value('scroll', { win = 0 })) + end) + it('gets written till grid width', function() insert(('a'):rep(60).."\n") screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*18 ## grid 3 | ]]} @@ -936,82 +489,24 @@ describe('ext_multigrid', function() feed('0') screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 ^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa哦| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*19 ## grid 3 | ]]} feed('g$') screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa^哦| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*19 ## grid 3 | ]]} @@ -1021,41 +516,14 @@ describe('ext_multigrid', function() insert(('b'):rep(160).."\n") screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|*2 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*16 ## grid 3 | ]]} @@ -1063,18 +531,7 @@ describe('ext_multigrid', function() command('setlocal cursorline cursorlineopt=screenline') screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 @@ -1082,22 +539,7 @@ describe('ext_multigrid', function() {23:^bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb}| bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb | | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*16 ## grid 3 | ]]} @@ -1108,41 +550,12 @@ describe('ext_multigrid', function() ' long message"') screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*19 ## grid 3 this is a very very very...ry very very long message | ]]} @@ -1153,41 +566,13 @@ describe('ext_multigrid', function() feed('kzfgg') screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 {13:^+-- 2 lines: this is a fold································}| this is outside fold | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*18 ## grid 3 | ]]} @@ -1197,46 +582,18 @@ describe('ext_multigrid', function() insert(('c'):rep(1111)) screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| + cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc|*18 cccccccccccccccccccccccccccccc^c | {1:~ }| ## grid 3 | ]]} - local float_buf = meths.create_buf(false, false) - meths.open_win(float_buf, false, { + local float_buf = api.nvim_create_buf(false, false) + api.nvim_open_win(float_buf, false, { relative = 'win', win = curwin(), bufpos = {0, 1018}, @@ -1246,51 +603,20 @@ describe('ext_multigrid', function() }) screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| - cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc| + cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc|*18 cccccccccccccccccccccccccccccc^c | {1:~ }| ## grid 3 | ## grid 4 {21: }| - {22:~ }| - {22:~ }| - {22:~ }| - {22:~ }| + {22:~ }|*4 ]], float_pos={ - [4] = {{id = 1001}, "SE", 2, 16, 58, true, 50}; + [4] = {1001, "SE", 2, 16, 58, true, 50}; }} end) @@ -1299,48 +625,20 @@ describe('ext_multigrid', function() feed('A<C-X><C-N>') screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 - | - | - | - | - | - | - | - | - | - | - | - | - | - | + |*14 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 {7:-- Keyword Local completion (^N^P) }{15:match 1 of 2} | ## grid 4 {24: foo}| {21: bar}| ]], float_pos={ - [4] = {{id = -1}, "NW", 2, 15, 55, false, 100}; + [4] = {-1, "NW", 2, 15, 55, false, 100}; }} feed('<C-E><Esc>') @@ -1348,48 +646,21 @@ describe('ext_multigrid', function() feed('o<C-X><C-N>') screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 - | - | - | - | - | - | - | - | - | - | - | - | - | - | + |*14 rab oof rab oof rab oof rab oof rab oof rab oof rab oof| ^ oof| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*4 ## grid 3 {7:-- Keyword Local completion (^N^P) }{15:match 1 of 2} | ## grid 4 {24: oof}| {21: rab}| ]], float_pos={ - [4] = {{id = -1}, "NW", 2, 16, 45, false, 100}; + [4] = {-1, "NW", 2, 16, 45, false, 100}; }} feed('<C-E><Esc>') @@ -1397,48 +668,21 @@ describe('ext_multigrid', function() feed(':sign un<Tab>') screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 - | - | - | - | - | - | - | - | - | - | - | - | - | - | + |*14 rab oof rab oof rab oof rab oof rab oof rab oof rab oof| | - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*4 ## grid 3 :sign undefine^ | ## grid 4 {24: undefine }| {21: unplace }| ]], float_pos={ - [4] = {{id = -1}, "SW", 1, 13, 5, false, 250}; + [4] = {-1, "SW", 1, 13, 5, false, 250}; }} end) end) @@ -1448,67 +692,34 @@ describe('ext_multigrid', function() command('vsp') screen:expect{grid=[[ ## grid 1 - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| + [5:--------------------------]│[4:--------------------------]|*6 {11:[No Name] }{12:[No Name] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*5 {12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ## grid 4 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 5 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]} feed(":echoerr 'very' | echoerr 'much' | echoerr 'fail'<cr>") screen:expect{grid=[[ ## grid 1 - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| + [5:--------------------------]│[4:--------------------------]|*6 {11:[No Name] }{12:[No Name] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [3:-----------------------------------------------------]| - [3:-----------------------------------------------------]| - [3:-----------------------------------------------------]| - [3:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*3 + [3:-----------------------------------------------------]|*4 ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 {14:very} | {14:much} | @@ -1516,59 +727,31 @@ describe('ext_multigrid', function() {15:Press ENTER or type command to continue}^ | ## grid 4 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 5 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]} feed('<cr>') screen:expect{grid=[[ ## grid 1 - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| + [5:--------------------------]│[4:--------------------------]|*6 {11:[No Name] }{12:[No Name] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*5 {12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ## grid 4 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 5 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]} command([[ @@ -1580,26 +763,10 @@ describe('ext_multigrid', function() feed(":call ErrMsg()<cr>") screen:expect{grid=[[ ## grid 1 - [3:-----------------------------------------------------]| - [3:-----------------------------------------------------]| - [3:-----------------------------------------------------]| - [3:-----------------------------------------------------]| - [3:-----------------------------------------------------]| - [3:-----------------------------------------------------]| - [3:-----------------------------------------------------]| - [3:-----------------------------------------------------]| - [3:-----------------------------------------------------]| - [3:-----------------------------------------------------]| - [3:-----------------------------------------------------]| - [3:-----------------------------------------------------]| - [3:-----------------------------------------------------]| - [3:-----------------------------------------------------]| + [3:-----------------------------------------------------]|*14 ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 {14:Error detected while processing function ErrMsg:} | {19:line 2:} | @@ -1617,59 +784,31 @@ describe('ext_multigrid', function() {15:Press ENTER or type command to continue}^ | ## grid 4 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 5 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]} feed("<c-c>") screen:expect{grid=[[ ## grid 1 - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| - [5:--------------------------]│[4:--------------------------]| + [5:--------------------------]│[4:--------------------------]|*6 {11:[No Name] }{12:[No Name] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*5 {12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ## grid 4 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 5 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]} end) @@ -1677,48 +816,17 @@ describe('ext_multigrid', function() command('vsp') screen:expect{grid=[[ ## grid 1 - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| + [4:--------------------------]│[2:--------------------------]|*12 {11:[No Name] }{12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ## grid 3 | ## grid 4 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ]]} @@ -1727,232 +835,93 @@ describe('ext_multigrid', function() screen:expect{grid=[[ ## grid 1 {16: }{17:2}{16: [No Name] }{7: [No Name] }{12: }{16:X}| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| + [5:-----------------------------------------------------]|*11 {11:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 (hidden) | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ## grid 3 | ## grid 4 (hidden) | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ## grid 5 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*10 ]]} command('sp') screen:expect{grid=[[ ## grid 1 {16: }{17:2}{16: [No Name] }{7: }{18:2}{7: [No Name] }{12: }{16:X}| - [6:-----------------------------------------------------]| - [6:-----------------------------------------------------]| - [6:-----------------------------------------------------]| - [6:-----------------------------------------------------]| - [6:-----------------------------------------------------]| + [6:-----------------------------------------------------]|*5 {11:[No Name] }| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| + [5:-----------------------------------------------------]|*5 {12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 (hidden) | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ## grid 3 | ## grid 4 (hidden) | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ## grid 5 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 6 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ]]} command('tabnext') screen:expect{grid=[[ ## grid 1 {7: }{18:2}{7: [No Name] }{16: }{17:2}{16: [No Name] }{12: }{16:X}| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| + [4:--------------------------]│[2:--------------------------]|*11 {11:[No Name] }{12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*10 ## grid 3 | ## grid 4 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*10 ## grid 5 (hidden) | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 6 (hidden) | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ]]} command('tabnext') screen:expect{grid=[[ ## grid 1 {16: }{17:2}{16: [No Name] }{7: }{18:2}{7: [No Name] }{12: }{16:X}| - [6:-----------------------------------------------------]| - [6:-----------------------------------------------------]| - [6:-----------------------------------------------------]| - [6:-----------------------------------------------------]| - [6:-----------------------------------------------------]| + [6:-----------------------------------------------------]|*5 {11:[No Name] }| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| - [5:-----------------------------------------------------]| + [5:-----------------------------------------------------]|*5 {12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 (hidden) | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*10 ## grid 3 | ## grid 4 (hidden) | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*10 ## grid 5 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 6 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ]]} command('tabnext') @@ -1960,117 +929,43 @@ describe('ext_multigrid', function() screen:expect{grid=[[ ## grid 1 {16: }{17:2}{16: [No Name] }{17:2}{16: [No Name] }{7: [No Name] }{12: }{16:X}| - [7:-----------------------------------------------------]| - [7:-----------------------------------------------------]| - [7:-----------------------------------------------------]| - [7:-----------------------------------------------------]| - [7:-----------------------------------------------------]| - [7:-----------------------------------------------------]| - [7:-----------------------------------------------------]| - [7:-----------------------------------------------------]| - [7:-----------------------------------------------------]| - [7:-----------------------------------------------------]| - [7:-----------------------------------------------------]| + [7:-----------------------------------------------------]|*11 {11:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 (hidden) | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*10 ## grid 3 | ## grid 4 (hidden) | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*10 ## grid 5 (hidden) | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 6 (hidden) | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 7 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*10 ]]} command('tabclose') command('tabclose') screen:expect{grid=[[ ## grid 1 - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| + [4:--------------------------]│[2:--------------------------]|*12 {11:[No Name] }{12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ## grid 3 | ## grid 4 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ]]} end) @@ -2078,67 +973,27 @@ describe('ext_multigrid', function() insert('some text\nto be clicked') screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be clicke^d | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*10 ## grid 3 | ]]} - meths.input_mouse('left', 'press', '', 2, 0, 5) + api.nvim_input_mouse('left', 'press', '', 2, 0, 5) screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some ^text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*10 ## grid 3 | ]]} @@ -2148,128 +1003,75 @@ describe('ext_multigrid', function() screen:expect{grid=[[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*6 {11:[No Name] [+] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*5 {12:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 | ## grid 4 Lorem ipsum dolor sit amet, consectetur adipiscing el| it, sed do eiusm^o | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ]]} - meths.input_mouse('left', 'press', '', 2, 1, 6) + api.nvim_input_mouse('left', 'press', '', 2, 1, 6) screen:expect{grid=[[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*6 {12:[No Name] [+] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*5 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be ^clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 | ## grid 4 Lorem ipsum dolor sit amet, consectetur adipiscing el| it, sed do eiusmo | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ]]} - meths.input_mouse('left', 'press', '', 4, 1, 4) + api.nvim_input_mouse('left', 'press', '', 4, 1, 4) screen:expect{grid=[[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*6 {11:[No Name] [+] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*5 {12:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 | ## grid 4 Lorem ipsum dolor sit amet, consectetur adipiscing el| it, ^sed do eiusmo | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ]]} screen:try_resize_grid(4, 80, 2) screen:expect{grid=[[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*6 {11:[No Name] [+] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*5 {12:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 | ## grid 4 @@ -2277,29 +1079,18 @@ describe('ext_multigrid', function() {1:~ }| ]]} - meths.input_mouse('left', 'press', '', 4, 0, 64) + api.nvim_input_mouse('left', 'press', '', 4, 0, 64) screen:expect{grid=[[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*6 {11:[No Name] [+] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*5 {12:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 | ## grid 4 @@ -2308,36 +1099,23 @@ describe('ext_multigrid', function() ]]} -- XXX: mouse_check_grid() doesn't work properly when clicking on grid 1 - meths.input_mouse('left', 'press', '', 1, 6, 20) + api.nvim_input_mouse('left', 'press', '', 1, 6, 20) -- TODO(bfredl): "batching" input_mouse is formally not supported yet. -- Normally it should work fine in async context when nvim is not blocked, -- but add a poke_eventloop be sure. poke_eventloop() - meths.input_mouse('left', 'drag', '', 1, 4, 20) + api.nvim_input_mouse('left', 'drag', '', 1, 4, 20) screen:expect{grid=[[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*4 {11:[No Name] [+] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*7 {12:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 | ## grid 4 @@ -2348,28 +1126,15 @@ describe('ext_multigrid', function() feed('<c-w><c-w><c-w>v') screen:expect{grid=[[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*4 {12:[No Name] [+] }| - [5:--------------------------]│[2:--------------------------]| - [5:--------------------------]│[2:--------------------------]| - [5:--------------------------]│[2:--------------------------]| - [5:--------------------------]│[2:--------------------------]| - [5:--------------------------]│[2:--------------------------]| - [5:--------------------------]│[2:--------------------------]| - [5:--------------------------]│[2:--------------------------]| + [5:--------------------------]│[2:--------------------------]|*7 {11:[No Name] [+] }{12:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 | ## grid 4 @@ -2378,40 +1143,23 @@ describe('ext_multigrid', function() ## grid 5 some text | to be ^clicked | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]} - meths.input_mouse('left', 'press', '', 1, 8, 26) + api.nvim_input_mouse('left', 'press', '', 1, 8, 26) poke_eventloop() - meths.input_mouse('left', 'drag', '', 1, 6, 30) + api.nvim_input_mouse('left', 'drag', '', 1, 6, 30) screen:expect{grid=[[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*4 {12:[No Name] [+] }| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| + [5:------------------------------]│[2:----------------------]|*7 {11:[No Name] [+] }{12:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 | ## grid 4 @@ -2420,41 +1168,24 @@ describe('ext_multigrid', function() ## grid 5 some text | to be ^clicked | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]} command('aunmenu PopUp | vmenu PopUp.Copy y') - funcs.setreg('"', '') - meths.input_mouse('left', 'press', '2', 2, 1, 6) + fn.setreg('"', '') + api.nvim_input_mouse('left', 'press', '2', 2, 1, 6) screen:expect{grid=[[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*4 {12:[No Name] [+] }| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| + [5:------------------------------]│[2:----------------------]|*7 {12:[No Name] [+] }{11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be {20:clicke}^d | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 {7:-- VISUAL --} | ## grid 4 @@ -2463,38 +1194,21 @@ describe('ext_multigrid', function() ## grid 5 some text | to be {20:clicked} | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]} - meths.input_mouse('right', 'press', '', 2, 1, 6) - meths.input_mouse('right', 'release', '', 2, 1, 6) + api.nvim_input_mouse('right', 'press', '', 2, 1, 6) + api.nvim_input_mouse('right', 'release', '', 2, 1, 6) screen:expect{grid=[[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*4 {12:[No Name] [+] }| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| + [5:------------------------------]│[2:----------------------]|*7 {12:[No Name] [+] }{11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be {20:clicke}^d | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 {7:-- VISUAL --} | ## grid 4 @@ -2503,41 +1217,24 @@ describe('ext_multigrid', function() ## grid 5 some text | to be {20:clicked} | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 6 {21: Copy }| ]], float_pos={ - [6] = {{id = -1}, "NW", 2, 2, 5, false, 250}; + [6] = {-1, "NW", 2, 2, 5, false, 250}; }} feed('<Down><CR>') screen:expect{grid=[[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*4 {12:[No Name] [+] }| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| + [5:------------------------------]│[2:----------------------]|*7 {12:[No Name] [+] }{11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be ^clicked | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 | ## grid 4 @@ -2546,40 +1243,23 @@ describe('ext_multigrid', function() ## grid 5 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]} - eq('clicked', funcs.getreg('"')) + eq('clicked', fn.getreg('"')) - funcs.setreg('"', '') - meths.input_mouse('left', 'press', '2', 4, 0, 64) + fn.setreg('"', '') + api.nvim_input_mouse('left', 'press', '2', 4, 0, 64) screen:expect{grid=[[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*4 {11:[No Name] [+] }| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| + [5:------------------------------]│[2:----------------------]|*7 {12:[No Name] [+] [No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 {7:-- VISUAL --} | ## grid 4 @@ -2588,38 +1268,21 @@ describe('ext_multigrid', function() ## grid 5 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]} - meths.input_mouse('right', 'press', '', 4, 0, 64) - meths.input_mouse('right', 'release', '', 4, 0, 64) + api.nvim_input_mouse('right', 'press', '', 4, 0, 64) + api.nvim_input_mouse('right', 'release', '', 4, 0, 64) screen:expect{grid=[[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*4 {11:[No Name] [+] }| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| + [5:------------------------------]│[2:----------------------]|*7 {12:[No Name] [+] [No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 {7:-- VISUAL --} | ## grid 4 @@ -2628,41 +1291,24 @@ describe('ext_multigrid', function() ## grid 5 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 6 {21: Copy }| ]], float_pos={ - [6] = {{id = -1}, "NW", 4, 1, 63, false, 250}; + [6] = {-1, "NW", 4, 1, 63, false, 250}; }} feed('<Down><CR>') screen:expect{grid=[[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*4 {11:[No Name] [+] }| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| + [5:------------------------------]│[2:----------------------]|*7 {12:[No Name] [+] [No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 | ## grid 4 @@ -2671,38 +1317,23 @@ describe('ext_multigrid', function() ## grid 5 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]} - eq('eiusmo', funcs.getreg('"')) + eq('eiusmo', fn.getreg('"')) command('wincmd J') screen:try_resize_grid(4, 7, 10) screen:expect{grid=[[ ## grid 1 - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| + [5:------------------------------]│[2:----------------------]|*5 {12:[No Name] [+] [No Name] [+] }| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*6 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 | ## grid 4 @@ -2719,35 +1350,22 @@ describe('ext_multigrid', function() ## grid 5 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ]]} - funcs.setreg('"', '') - meths.input_mouse('left', 'press', '2', 4, 9, 1) + fn.setreg('"', '') + api.nvim_input_mouse('left', 'press', '2', 4, 9, 1) screen:expect{grid=[[ ## grid 1 - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| + [5:------------------------------]│[2:----------------------]|*5 {12:[No Name] [+] [No Name] [+] }| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*6 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 {7:-- VISUAL --} | ## grid 4 @@ -2764,34 +1382,21 @@ describe('ext_multigrid', function() ## grid 5 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ]]} - meths.input_mouse('right', 'press', '', 4, 9, 1) - meths.input_mouse('right', 'release', '', 4, 9, 1) + api.nvim_input_mouse('right', 'press', '', 4, 9, 1) + api.nvim_input_mouse('right', 'release', '', 4, 9, 1) screen:expect{grid=[[ ## grid 1 - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| + [5:------------------------------]│[2:----------------------]|*5 {12:[No Name] [+] [No Name] [+] }| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*6 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 {7:-- VISUAL --} | ## grid 4 @@ -2808,37 +1413,24 @@ describe('ext_multigrid', function() ## grid 5 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 6 {21: Copy }| ]], float_pos={ - [6] = {{id = -1}, "SW", 4, 9, 0, false, 250}; + [6] = {-1, "SW", 4, 9, 0, false, 250}; }} feed('<Down><CR>') screen:expect{grid=[[ ## grid 1 - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| + [5:------------------------------]│[2:----------------------]|*5 {12:[No Name] [+] [No Name] [+] }| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*6 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 | ## grid 4 @@ -2855,35 +1447,22 @@ describe('ext_multigrid', function() ## grid 5 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ]]} - eq('eiusmo', funcs.getreg('"')) + eq('eiusmo', fn.getreg('"')) screen:try_resize_grid(4, 7, 11) screen:expect{grid=[[ ## grid 1 - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| + [5:------------------------------]│[2:----------------------]|*5 {12:[No Name] [+] [No Name] [+] }| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*6 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 | ## grid 4 @@ -2901,35 +1480,22 @@ describe('ext_multigrid', function() ## grid 5 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ]]} - funcs.setreg('"', '') - meths.input_mouse('left', 'press', '2', 4, 9, 1) + fn.setreg('"', '') + api.nvim_input_mouse('left', 'press', '2', 4, 9, 1) screen:expect{grid=[[ ## grid 1 - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| + [5:------------------------------]│[2:----------------------]|*5 {12:[No Name] [+] [No Name] [+] }| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*6 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 {7:-- VISUAL --} | ## grid 4 @@ -2947,34 +1513,21 @@ describe('ext_multigrid', function() ## grid 5 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ]]} - meths.input_mouse('right', 'press', '', 4, 9, 1) - meths.input_mouse('right', 'release', '', 4, 9, 1) + api.nvim_input_mouse('right', 'press', '', 4, 9, 1) + api.nvim_input_mouse('right', 'release', '', 4, 9, 1) screen:expect{grid=[[ ## grid 1 - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| + [5:------------------------------]│[2:----------------------]|*5 {12:[No Name] [+] [No Name] [+] }| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*6 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 {7:-- VISUAL --} | ## grid 4 @@ -2992,37 +1545,24 @@ describe('ext_multigrid', function() ## grid 5 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 6 {21: Copy }| ]], float_pos={ - [6] = {{id = -1}, "NW", 4, 10, 0, false, 250}; + [6] = {-1, "NW", 4, 10, 0, false, 250}; }} feed('<Down><CR>') screen:expect{grid=[[ ## grid 1 - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| - [5:------------------------------]│[2:----------------------]| + [5:------------------------------]│[2:----------------------]|*5 {12:[No Name] [+] [No Name] [+] }| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*6 {11:[No Name] [+] }| [3:-----------------------------------------------------]| ## grid 2 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 | ## grid 4 @@ -3040,11 +1580,9 @@ describe('ext_multigrid', function() ## grid 5 some text | to be clicked | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ]]} - eq('eiusmo', funcs.getreg('"')) + eq('eiusmo', fn.getreg('"')) end) it('supports mouse drag with mouse=a', function() @@ -3055,54 +1593,29 @@ describe('ext_multigrid', function() command('enew') feed('ifoo\nbar<esc>') - meths.input_mouse('left', 'press', '', 5, 0, 0) + api.nvim_input_mouse('left', 'press', '', 5, 0, 0) poke_eventloop() - meths.input_mouse('left', 'drag', '', 5, 1, 2) + api.nvim_input_mouse('left', 'drag', '', 5, 1, 2) screen:expect{grid=[[ ## grid 1 - [4:--------------------------]│[5:--------------------------]| - [4:--------------------------]│[5:--------------------------]| - [4:--------------------------]│[5:--------------------------]| - [4:--------------------------]│[5:--------------------------]| - [4:--------------------------]│[5:--------------------------]| - [4:--------------------------]│[5:--------------------------]| + [4:--------------------------]│[5:--------------------------]|*6 [4:--------------------------]│{11:[No Name] [+] }| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| - [4:--------------------------]│[2:--------------------------]| + [4:--------------------------]│[2:--------------------------]|*5 {12:[No Name] [No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 {7:-- VISUAL --} | ## grid 4 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 ## grid 5 {20:foo} | {20:ba}^r | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ]]} end) @@ -3110,25 +1623,16 @@ describe('ext_multigrid', function() screen:try_resize(48, 8) screen:expect{grid=[[ ## grid 1 - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| + [2:------------------------------------------------]|*6 {11:[No Name] }| [3:------------------------------------------------]| ## grid 2 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 | ]], win_viewport={ - [2] = {win = { id = 1000 }, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0} + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0} }} insert([[ Lorem ipsum dolor sit amet, consectetur @@ -3145,12 +1649,7 @@ describe('ext_multigrid', function() screen:expect{grid=[[ ## grid 1 - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| + [2:------------------------------------------------]|*6 {11:[No Name] [+] }| [3:------------------------------------------------]| ## grid 2 @@ -3163,19 +1662,14 @@ describe('ext_multigrid', function() ## grid 3 | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 5, botline = 11, curline = 10, curcol = 7, linecount = 11, sum_scroll_delta = 5}, + [2] = {win = 1000, topline = 5, botline = 11, curline = 10, curcol = 7, linecount = 11, sum_scroll_delta = 5}, }} feed('<c-u>') screen:expect{grid=[[ ## grid 1 - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| + [2:------------------------------------------------]|*6 {11:[No Name] [+] }| [3:------------------------------------------------]| ## grid 2 @@ -3188,18 +1682,15 @@ describe('ext_multigrid', function() ## grid 3 | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 2, botline = 9, curline = 7, curcol = 0, linecount = 11, sum_scroll_delta = 2}, + [2] = {win = 1000, topline = 2, botline = 9, curline = 7, curcol = 0, linecount = 11, sum_scroll_delta = 2}, }} command("split") screen:expect{grid=[[ ## grid 1 - [4:------------------------------------------------]| - [4:------------------------------------------------]| - [4:------------------------------------------------]| + [4:------------------------------------------------]|*3 {11:[No Name] [+] }| - [2:------------------------------------------------]| - [2:------------------------------------------------]| + [2:------------------------------------------------]|*2 {12:[No Name] [+] }| [3:------------------------------------------------]| ## grid 2 @@ -3212,19 +1703,16 @@ describe('ext_multigrid', function() reprehenderit in voluptate velit esse cillum | ^dolore eu fugiat nulla pariatur. Excepteur sint | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 6, botline = 9, curline = 7, curcol = 0, linecount = 11, sum_scroll_delta = 6}, - [4] = {win = {id = 1001}, topline = 5, botline = 9, curline = 7, curcol = 0, linecount = 11, sum_scroll_delta = 5}, + [2] = {win = 1000, topline = 6, botline = 9, curline = 7, curcol = 0, linecount = 11, sum_scroll_delta = 6}, + [4] = {win = 1001, topline = 5, botline = 9, curline = 7, curcol = 0, linecount = 11, sum_scroll_delta = 5}, }} feed("b") screen:expect{grid=[[ ## grid 1 - [4:------------------------------------------------]| - [4:------------------------------------------------]| - [4:------------------------------------------------]| + [4:------------------------------------------------]|*3 {11:[No Name] [+] }| - [2:------------------------------------------------]| - [2:------------------------------------------------]| + [2:------------------------------------------------]|*2 {12:[No Name] [+] }| [3:------------------------------------------------]| ## grid 2 @@ -3237,19 +1725,16 @@ describe('ext_multigrid', function() reprehenderit in voluptate velit esse ^cillum | dolore eu fugiat nulla pariatur. Excepteur sint | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 6, botline = 9, curline = 7, curcol = 0, linecount = 11, sum_scroll_delta = 6}, - [4] = {win = {id = 1001}, topline = 5, botline = 9, curline = 6, curcol = 38, linecount = 11, sum_scroll_delta = 5}, + [2] = {win = 1000, topline = 6, botline = 9, curline = 7, curcol = 0, linecount = 11, sum_scroll_delta = 6}, + [4] = {win = 1001, topline = 5, botline = 9, curline = 6, curcol = 38, linecount = 11, sum_scroll_delta = 5}, }} feed("2k") screen:expect{grid=[[ ## grid 1 - [4:------------------------------------------------]| - [4:------------------------------------------------]| - [4:------------------------------------------------]| + [4:------------------------------------------------]|*3 {11:[No Name] [+] }| - [2:------------------------------------------------]| - [2:------------------------------------------------]| + [2:------------------------------------------------]|*2 {12:[No Name] [+] }| [3:------------------------------------------------]| ## grid 2 @@ -3262,20 +1747,17 @@ describe('ext_multigrid', function() ea commodo consequat. Duis aute irure dolor in | reprehenderit in voluptate velit esse cillum | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 6, botline = 9, curline = 7, curcol = 0, linecount = 11, sum_scroll_delta = 6}, - [4] = {win = {id = 1001}, topline = 4, botline = 8, curline = 4, curcol = 38, linecount = 11, sum_scroll_delta = 4}, + [2] = {win = 1000, topline = 6, botline = 9, curline = 7, curcol = 0, linecount = 11, sum_scroll_delta = 6}, + [4] = {win = 1001, topline = 4, botline = 8, curline = 4, curcol = 38, linecount = 11, sum_scroll_delta = 4}, }} -- handles non-current window - meths.win_set_cursor(1000, {1, 10}) + api.nvim_win_set_cursor(1000, {1, 10}) screen:expect{grid=[[ ## grid 1 - [4:------------------------------------------------]| - [4:------------------------------------------------]| - [4:------------------------------------------------]| + [4:------------------------------------------------]|*3 {11:[No Name] [+] }| - [2:------------------------------------------------]| - [2:------------------------------------------------]| + [2:------------------------------------------------]|*2 {12:[No Name] [+] }| [3:------------------------------------------------]| ## grid 2 @@ -3288,20 +1770,17 @@ describe('ext_multigrid', function() ea commodo consequat. Duis aute irure dolor in | reprehenderit in voluptate velit esse cillum | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 3, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}, - [4] = {win = {id = 1001}, topline = 4, botline = 8, curline = 4, curcol = 38, linecount = 11, sum_scroll_delta = 4}, + [2] = {win = 1000, topline = 0, botline = 3, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}, + [4] = {win = 1001, topline = 4, botline = 8, curline = 4, curcol = 38, linecount = 11, sum_scroll_delta = 4}, }} -- sum_scroll_delta works with folds feed('zfj') screen:expect{grid=[[ ## grid 1 - [4:------------------------------------------------]| - [4:------------------------------------------------]| - [4:------------------------------------------------]| + [4:------------------------------------------------]|*3 {11:[No Name] [+] }| - [2:------------------------------------------------]| - [2:------------------------------------------------]| + [2:------------------------------------------------]|*2 {12:[No Name] [+] }| [3:------------------------------------------------]| ## grid 2 @@ -3314,19 +1793,16 @@ describe('ext_multigrid', function() reprehenderit in voluptate velit esse cillum | dolore eu fugiat nulla pariatur. Excepteur sint | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 3, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}, - [4] = {win = {id = 1001}, topline = 4, botline = 9, curline = 4, curcol = 38, linecount = 11, sum_scroll_delta = 4}, + [2] = {win = 1000, topline = 0, botline = 3, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}, + [4] = {win = 1001, topline = 4, botline = 9, curline = 4, curcol = 38, linecount = 11, sum_scroll_delta = 4}, }} feed('<c-e>') screen:expect{grid=[[ ## grid 1 - [4:------------------------------------------------]| - [4:------------------------------------------------]| - [4:------------------------------------------------]| + [4:------------------------------------------------]|*3 {11:[No Name] [+] }| - [2:------------------------------------------------]| - [2:------------------------------------------------]| + [2:------------------------------------------------]|*2 {12:[No Name] [+] }| [3:------------------------------------------------]| ## grid 2 @@ -3339,19 +1815,14 @@ describe('ext_multigrid', function() dolore eu fugiat nulla pariatur. Excepteur sint | occaecat cupidatat non proident, sunt in culpa | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 3, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}, - [4] = {win = {id = 1001}, topline = 6, botline = 10, curline = 6, curcol = 0, linecount = 11, sum_scroll_delta = 5}, + [2] = {win = 1000, topline = 0, botline = 3, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}, + [4] = {win = 1001, topline = 6, botline = 10, curline = 6, curcol = 0, linecount = 11, sum_scroll_delta = 5}, }} command('close | 21vsplit | setlocal number smoothscroll') screen:expect{grid=[[ ## grid 1 - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| + [5:---------------------]│[2:--------------------------]|*6 {11:[No Name] [+] }{12:[No Name] [+] }| [3:------------------------------------------------]| ## grid 2 @@ -3371,19 +1842,14 @@ describe('ext_multigrid', function() {19: } sed do eiusmod t| {19: }empor | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 4, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 4, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; + [5] = {win = 1002, topline = 0, botline = 3, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; }} feed('5<C-E>') screen:expect{grid=[[ ## grid 1 - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| + [5:---------------------]│[2:--------------------------]|*6 {11:[No Name] [+] }{12:[No Name] [+] }| [3:------------------------------------------------]| ## grid 2 @@ -3403,19 +1869,14 @@ describe('ext_multigrid', function() {19: 4 }Ut enim ad minim | {19: }veniam, quis n{1:@@@}| ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 4, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 1, botline = 4, curline = 1, curcol = 38, linecount = 11, sum_scroll_delta = 5}; + [2] = {win = 1000, topline = 0, botline = 4, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; + [5] = {win = 1002, topline = 1, botline = 4, curline = 1, curcol = 38, linecount = 11, sum_scroll_delta = 5}; }} feed('<C-Y>') screen:expect{grid=[[ ## grid 1 - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| + [5:---------------------]│[2:--------------------------]|*6 {11:[No Name] [+] }{12:[No Name] [+] }| [3:------------------------------------------------]| ## grid 2 @@ -3435,19 +1896,14 @@ describe('ext_multigrid', function() {19: }na aliqua. | {19: 4 }Ut enim ad min{1:@@@}| ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 4, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 1, botline = 4, curline = 1, curcol = 38, linecount = 11, sum_scroll_delta = 4}; + [2] = {win = 1000, topline = 0, botline = 4, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; + [5] = {win = 1002, topline = 1, botline = 4, curline = 1, curcol = 38, linecount = 11, sum_scroll_delta = 4}; }} command('set cpoptions+=n') screen:expect{grid=[[ ## grid 1 - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| + [5:---------------------]│[2:--------------------------]|*6 {11:[No Name] [+] }{12:[No Name] [+] }| [3:------------------------------------------------]| ## grid 2 @@ -3467,19 +1923,14 @@ describe('ext_multigrid', function() liqua. | {19: 4 }Ut enim ad min{1:@@@}| ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 4, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 1, botline = 4, curline = 1, curcol = 38, linecount = 11, sum_scroll_delta = 4}; + [2] = {win = 1000, topline = 0, botline = 4, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; + [5] = {win = 1002, topline = 1, botline = 4, curline = 1, curcol = 38, linecount = 11, sum_scroll_delta = 4}; }} feed('4<C-E>') screen:expect{grid=[[ ## grid 1 - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| + [5:---------------------]│[2:--------------------------]|*6 {11:[No Name] [+] }{12:[No Name] [+] }| [3:------------------------------------------------]| ## grid 2 @@ -3499,19 +1950,14 @@ describe('ext_multigrid', function() mco laboris nisi ut a| liquip ex | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 4, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 2, botline = 6, curline = 2, curcol = 43, linecount = 11, sum_scroll_delta = 8}; + [2] = {win = 1000, topline = 0, botline = 4, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; + [5] = {win = 1002, topline = 2, botline = 6, curline = 2, curcol = 43, linecount = 11, sum_scroll_delta = 8}; }} feed('2<C-Y>') screen:expect{grid=[[ ## grid 1 - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| + [5:---------------------]│[2:--------------------------]|*6 {11:[No Name] [+] }{12:[No Name] [+] }| [3:------------------------------------------------]| ## grid 2 @@ -3531,19 +1977,14 @@ describe('ext_multigrid', function() veniam, quis nostrud | {19: 5 }exercitation u{1:@@@}| ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 4, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 2, botline = 5, curline = 2, curcol = 43, linecount = 11, sum_scroll_delta = 6}; + [2] = {win = 1000, topline = 0, botline = 4, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; + [5] = {win = 1002, topline = 2, botline = 5, curline = 2, curcol = 43, linecount = 11, sum_scroll_delta = 6}; }} command('setlocal numberwidth=12') screen:expect{grid=[[ ## grid 1 - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| + [5:---------------------]│[2:--------------------------]|*6 {11:[No Name] [+] }{12:[No Name] [+] }| [3:------------------------------------------------]| ## grid 2 @@ -3563,19 +2004,14 @@ describe('ext_multigrid', function() d minim veniam, quis | nostrud | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 4, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 2, botline = 5, curline = 2, curcol = 43, linecount = 11, sum_scroll_delta = 6}; + [2] = {win = 1000, topline = 0, botline = 4, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; + [5] = {win = 1002, topline = 2, botline = 5, curline = 2, curcol = 43, linecount = 11, sum_scroll_delta = 6}; }} feed('2<C-E>') screen:expect{grid=[[ ## grid 1 - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| + [5:---------------------]│[2:--------------------------]|*6 {11:[No Name] [+] }{12:[No Name] [+] }| [3:------------------------------------------------]| ## grid 2 @@ -3595,19 +2031,14 @@ describe('ext_multigrid', function() {19: 5 }exercitat| ion ullamco labori{1:@@@}| ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 4, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 2, botline = 5, curline = 2, curcol = 43, linecount = 11, sum_scroll_delta = 8}; + [2] = {win = 1000, topline = 0, botline = 4, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; + [5] = {win = 1002, topline = 2, botline = 5, curline = 2, curcol = 43, linecount = 11, sum_scroll_delta = 8}; }} feed('<C-E>') screen:expect{grid=[[ ## grid 1 - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| - [5:---------------------]│[2:--------------------------]| + [5:---------------------]│[2:--------------------------]|*6 {11:[No Name] [+] }{12:[No Name] [+] }| [3:------------------------------------------------]| ## grid 2 @@ -3627,8 +2058,8 @@ describe('ext_multigrid', function() ion ullamco laboris n| isi ut aliquip ex | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 4, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; - [5] = {win = {id = 1002}, topline = 3, botline = 6, curline = 3, curcol = 36, linecount = 11, sum_scroll_delta = 9}; + [2] = {win = 1000, topline = 0, botline = 4, curline = 0, curcol = 10, linecount = 11, sum_scroll_delta = 0}; + [5] = {win = 1002, topline = 3, botline = 6, curline = 3, curcol = 36, linecount = 11, sum_scroll_delta = 9}; }} end) @@ -3637,18 +2068,7 @@ describe('ext_multigrid', function() command('edit test/functional/fixtures/bigfile.txt') screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:test/functional/fixtures/bigfile.txt }| [3:-----------------------------------------------------]| ## grid 2 @@ -3667,23 +2087,12 @@ describe('ext_multigrid', function() ## grid 3 | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 13, curline = 0, curcol = 0, linecount = 30592, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 13, curline = 0, curcol = 0, linecount = 30592, sum_scroll_delta = 0}; }} feed('G') screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:test/functional/fixtures/bigfile.txt }| [3:-----------------------------------------------------]| ## grid 2 @@ -3702,23 +2111,12 @@ describe('ext_multigrid', function() ## grid 3 | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 30580, botline = 30592, curline = 30591, curcol = 0, linecount = 30592, sum_scroll_delta = 30580}; + [2] = {win = 1000, topline = 30580, botline = 30592, curline = 30591, curcol = 0, linecount = 30592, sum_scroll_delta = 30580}; }} feed('gg') screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:test/functional/fixtures/bigfile.txt }| [3:-----------------------------------------------------]| ## grid 2 @@ -3737,23 +2135,12 @@ describe('ext_multigrid', function() ## grid 3 | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 13, curline = 0, curcol = 0, linecount = 30592, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 13, curline = 0, curcol = 0, linecount = 30592, sum_scroll_delta = 0}; }} command('setlocal wrap') screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:test/functional/fixtures/bigfile.txt }| [3:-----------------------------------------------------]| ## grid 2 @@ -3772,23 +2159,12 @@ describe('ext_multigrid', function() ## grid 3 | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 10, curline = 0, curcol = 0, linecount = 30592, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 10, curline = 0, curcol = 0, linecount = 30592, sum_scroll_delta = 0}; }} feed('G') screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:test/functional/fixtures/bigfile.txt }| [3:-----------------------------------------------------]| ## grid 2 @@ -3807,23 +2183,12 @@ describe('ext_multigrid', function() ## grid 3 | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 30586, botline = 30592, curline = 30591, curcol = 0, linecount = 30592, sum_scroll_delta = 30588}; + [2] = {win = 1000, topline = 30586, botline = 30592, curline = 30591, curcol = 0, linecount = 30592, sum_scroll_delta = 30588}; }} feed('gg') screen:expect{grid=[[ ## grid 1 - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*12 {11:test/functional/fixtures/bigfile.txt }| [3:-----------------------------------------------------]| ## grid 2 @@ -3842,7 +2207,7 @@ describe('ext_multigrid', function() ## grid 3 | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 10, curline = 0, curcol = 0, linecount = 30592, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 10, curline = 0, curcol = 0, linecount = 30592, sum_scroll_delta = 0}; }} end) @@ -3850,25 +2215,16 @@ describe('ext_multigrid', function() screen:try_resize(48, 8) screen:expect{grid=[[ ## grid 1 - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| + [2:------------------------------------------------]|*6 {11:[No Name] }| [3:------------------------------------------------]| ## grid 2 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 | ]], win_viewport={ - [2] = {win = { id = 1000 }, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0} + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0} }} insert([[ Lorem ipsum dolor sit amet, consectetur @@ -3885,12 +2241,7 @@ describe('ext_multigrid', function() screen:expect{grid=[[ ## grid 1 - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| + [2:------------------------------------------------]|*6 {11:[No Name] [+] }| [3:------------------------------------------------]| ## grid 2 @@ -3903,21 +2254,16 @@ describe('ext_multigrid', function() ## grid 3 | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 5, botline = 11, curline = 10, curcol = 7, linecount = 11, sum_scroll_delta = 5}, + [2] = {win = 1000, topline = 5, botline = 11, curline = 10, curcol = 7, linecount = 11, sum_scroll_delta = 5}, }} - meths.input_mouse('left', 'press', '', 1,5, 1) + api.nvim_input_mouse('left', 'press', '', 1,5, 1) poke_eventloop() - meths.input_mouse('left', 'drag', '', 1, 6, 1) + api.nvim_input_mouse('left', 'drag', '', 1, 6, 1) screen:expect{grid=[[ ## grid 1 - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| - [2:------------------------------------------------]| + [2:------------------------------------------------]|*6 {11:[No Name] [+] }| [3:------------------------------------------------]| ## grid 2 @@ -3930,7 +2276,7 @@ describe('ext_multigrid', function() ## grid 3 {7:-- VISUAL --} | ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 6, botline = 12, curline = 10, curcol = 1, linecount = 11, sum_scroll_delta = 6}, + [2] = {win = 1000, topline = 6, botline = 12, curline = 10, curcol = 1, linecount = 11, sum_scroll_delta = 6}, }} end) @@ -3938,38 +2284,22 @@ describe('ext_multigrid', function() command('split') screen:expect{grid=[[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*6 {11:[No Name] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*5 {12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ## grid 4 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} -- XXX: hack to get notifications. Could use next_msg() also. @@ -3983,256 +2313,155 @@ describe('ext_multigrid', function() command('setlocal winbar=very%=bar') screen:expect{grid=[[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*6 {11:[No Name] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*5 {12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ## grid 4 {7:very bar}| ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} eq({}, win_pos) command('setlocal winbar=') screen:expect{grid=[[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*6 {11:[No Name] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*5 {12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ## grid 4 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; - [4] = {win = {id = 1001}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; }} eq({}, win_pos) end) it('with winbar dragging statusline with mouse works correctly', function() - meths.set_option_value('winbar', 'Set Up The Bars', {}) + api.nvim_set_option_value('winbar', 'Set Up The Bars', {}) command('split') screen:expect([[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*6 {11:[No Name] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*5 {12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 {7:Set Up The Bars }| | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 | ## grid 4 {7:Set Up The Bars }| ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ]]) - meths.input_mouse('left', 'press', '', 1, 6, 20) + api.nvim_input_mouse('left', 'press', '', 1, 6, 20) poke_eventloop() - meths.input_mouse('left', 'drag', '', 1, 7, 20) + api.nvim_input_mouse('left', 'drag', '', 1, 7, 20) screen:expect([[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*7 {11:[No Name] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*4 {12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 {7:Set Up The Bars }| | - {1:~ }| - {1:~ }| + {1:~ }|*2 ## grid 3 | ## grid 4 {7:Set Up The Bars }| ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ]]) - meths.input_mouse('left', 'drag', '', 1, 4, 20) + api.nvim_input_mouse('left', 'drag', '', 1, 4, 20) screen:expect([[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*4 {11:[No Name] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*7 {12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 {7:Set Up The Bars }| | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 | ## grid 4 {7:Set Up The Bars }| ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 ]]) - meths.input_mouse('left', 'press', '', 1, 12, 10) + api.nvim_input_mouse('left', 'press', '', 1, 12, 10) poke_eventloop() - meths.input_mouse('left', 'drag', '', 1, 10, 10) + api.nvim_input_mouse('left', 'drag', '', 1, 10, 10) screen:expect([[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*4 {11:[No Name] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*5 {12:[No Name] }| - [3:-----------------------------------------------------]| - [3:-----------------------------------------------------]| - [3:-----------------------------------------------------]| + [3:-----------------------------------------------------]|*3 ## grid 2 {7:Set Up The Bars }| | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 - | - | - | + |*3 ## grid 4 {7:Set Up The Bars }| ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 ]]) - eq(3, meths.get_option_value('cmdheight', {})) + eq(3, api.nvim_get_option_value('cmdheight', {})) - meths.input_mouse('left', 'drag', '', 1, 12, 10) + api.nvim_input_mouse('left', 'drag', '', 1, 12, 10) screen:expect([[ ## grid 1 - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| - [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]|*4 {11:[No Name] }| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| - [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]|*7 {12:[No Name] }| [3:-----------------------------------------------------]| ## grid 2 {7:Set Up The Bars }| | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ## grid 3 | ## grid 4 {7:Set Up The Bars }| ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 ]]) - eq(1, meths.get_option_value('cmdheight', {})) + eq(1, api.nvim_get_option_value('cmdheight', {})) end) end) diff --git a/test/functional/ui/options_spec.lua b/test/functional/ui/options_spec.lua index 2c649709c6..98af82a7c5 100644 --- a/test/functional/ui/options_spec.lua +++ b/test/functional/ui/options_spec.lua @@ -9,45 +9,48 @@ local eval = helpers.eval describe('UI receives option updates', function() local screen - local function reset(opts, ...) + local function reset(screen_opts, clear_opts) local defaults = { - ambiwidth='single', - arabicshape=true, - emoji=true, - guifont='', - guifontwide='', - linespace=0, - pumblend=0, - mousefocus=false, - mousehide=true, - mousemoveevent=false, - showtabline=1, - termguicolors=false, - termsync=true, - ttimeout=true, - ttimeoutlen=50, - verbose=0, - ext_cmdline=false, - ext_popupmenu=false, - ext_tabline=false, - ext_wildmenu=false, - ext_linegrid=false, - ext_hlstate=false, - ext_multigrid=false, - ext_messages=false, - ext_termcolors=false, + ambiwidth = 'single', + arabicshape = true, + emoji = true, + guifont = '', + guifontwide = '', + linespace = 0, + pumblend = 0, + mousefocus = false, + mousehide = true, + mousemoveevent = false, + showtabline = 1, + termguicolors = false, + termsync = true, + ttimeout = true, + ttimeoutlen = 50, + verbose = 0, + ext_cmdline = false, + ext_popupmenu = false, + ext_tabline = false, + ext_wildmenu = false, + ext_linegrid = false, + ext_hlstate = false, + ext_multigrid = false, + ext_messages = false, + ext_termcolors = false, } - clear(...) - screen = Screen.new(20,5) - screen:attach(opts) + clear_opts = shallowcopy(clear_opts or {}) + clear_opts.args_rm = clear_opts.args_rm or {} + table.insert(clear_opts.args_rm or {}, '--cmd') + clear(clear_opts) + screen = Screen.new(20, 5) + screen:attach(screen_opts) -- NB: UI test suite can be run in both "linegrid" and legacy grid mode. -- In both cases check that the received value is the one requested. defaults.ext_linegrid = screen._options.ext_linegrid or false return defaults end - it("for defaults", function() + it('for defaults', function() local expected = reset() screen:expect(function() eq(expected, screen.options) @@ -55,9 +58,9 @@ describe('UI receives option updates', function() end) it('on attach #11372', function() - clear{args_rm={'--headless'}} + clear { args_rm = { '--headless' } } local evs = {} - screen = Screen.new(20,5) + screen = Screen.new(20, 5) -- Override mouse_on/mouse_off handlers. function screen:_handle_mouse_on() table.insert(evs, 'mouse_on') @@ -67,109 +70,109 @@ describe('UI receives option updates', function() end screen:attach() screen:expect(function() - eq({'mouse_on'}, evs) + eq({ 'mouse_on' }, evs) end) - command("set mouse=") + command('set mouse=') screen:expect(function() - eq({'mouse_on', 'mouse_off'}, evs) + eq({ 'mouse_on', 'mouse_off' }, evs) end) - command("set mouse&") + command('set mouse&') screen:expect(function() - eq({'mouse_on', 'mouse_off', 'mouse_on'}, evs) + eq({ 'mouse_on', 'mouse_off', 'mouse_on' }, evs) end) screen:detach() - eq({'mouse_on', 'mouse_off', 'mouse_on'}, evs) + eq({ 'mouse_on', 'mouse_off', 'mouse_on' }, evs) screen:attach() screen:expect(function() - eq({'mouse_on', 'mouse_off', 'mouse_on', 'mouse_on'}, evs) + eq({ 'mouse_on', 'mouse_off', 'mouse_on', 'mouse_on' }, evs) end) end) - it("when setting options", function() + it('when setting options', function() local expected = reset() local defaults = shallowcopy(expected) - command("set termguicolors") + command('set termguicolors') expected.termguicolors = true screen:expect(function() eq(expected, screen.options) end) - command("set pumblend=50") + command('set pumblend=50') expected.pumblend = 50 screen:expect(function() - eq(expected, screen.options) + eq(expected, screen.options) end) -- check handling of out-of-bounds value - command("set pumblend=-1") + command('set pumblend=-1') expected.pumblend = 0 screen:expect(function() - eq(expected, screen.options) + eq(expected, screen.options) end) - command("set guifont=Comic\\ Sans") - expected.guifont = "Comic Sans" + command('set guifont=Comic\\ Sans') + expected.guifont = 'Comic Sans' screen:expect(function() eq(expected, screen.options) end) - command("set showtabline=0") + command('set showtabline=0') expected.showtabline = 0 screen:expect(function() eq(expected, screen.options) end) - command("set linespace=13") + command('set linespace=13') expected.linespace = 13 screen:expect(function() eq(expected, screen.options) end) - command("set linespace=-11") + command('set linespace=-11') expected.linespace = -11 screen:expect(function() eq(expected, screen.options) end) - command("set mousefocus") + command('set mousefocus') expected.mousefocus = true screen:expect(function() eq(expected, screen.options) end) - command("set nomousehide") + command('set nomousehide') expected.mousehide = false screen:expect(function() eq(expected, screen.options) end) - command("set mousemoveevent") + command('set mousemoveevent') expected.mousemoveevent = true screen:expect(function() eq(expected, screen.options) end) - command("set nottimeout") + command('set nottimeout') expected.ttimeout = false screen:expect(function() eq(expected, screen.options) end) - command("set ttimeoutlen=100") + command('set ttimeoutlen=100') expected.ttimeoutlen = 100 screen:expect(function() eq(expected, screen.options) end) - command("set all&") + command('set all&') screen:expect(function() eq(defaults, screen.options) end) end) it('with UI extensions', function() - local expected = reset({ext_cmdline=true, ext_wildmenu=true}) + local expected = reset({ ext_cmdline = true, ext_wildmenu = true }) expected.ext_cmdline = true expected.ext_wildmenu = true @@ -191,37 +194,43 @@ describe('UI receives option updates', function() end) local function startup_test(headless) - local expected = reset(nil, {args_rm=(headless and {} or {'--headless'}), - args={'--cmd', 'set guifont=Comic\\ Sans\\ 12'}}) - expected.guifont = "Comic Sans 12" + local expected = reset(nil, { + args_rm = (headless and {} or { '--headless' }), + args = { '--cmd', 'set guifont=Comic\\ Sans\\ 12' }, + }) + expected.guifont = 'Comic Sans 12' screen:expect(function() eq(expected, screen.options) end) end - it('from startup options with --headless', function() startup_test(true) end) - it('from startup options with --embed', function() startup_test(false) end) + it('from startup options with --headless', function() + startup_test(true) + end) + it('from startup options with --embed', function() + startup_test(false) + end) end) describe('UI can set terminal option', function() local screen before_each(function() -- by default we implicitly "--cmd 'set bg=light'" which ruins everything - clear{args_rm={'--cmd'}} - screen = Screen.new(20,5) + clear { args_rm = { '--cmd' } } + screen = Screen.new(20, 5) end) it('term_name', function() eq('nvim', eval '&term') - screen:attach {term_name='xterm'} + screen:attach { term_name = 'xterm' } eq('xterm', eval '&term') end) it('term_colors', function() eq('256', eval '&t_Co') - screen:attach {term_colors=8} + screen:attach { term_colors = 8 } eq('8', eval '&t_Co') end) end) diff --git a/test/functional/ui/output_spec.lua b/test/functional/ui/output_spec.lua index 7b93b74eac..5e340af89c 100644 --- a/test/functional/ui/output_spec.lua +++ b/test/functional/ui/output_spec.lua @@ -15,38 +15,42 @@ local set_shell_powershell = helpers.set_shell_powershell local skip = helpers.skip local is_os = helpers.is_os -clear() -- for has_powershell() +clear() -- for has_powershell() -describe("shell command :!", function() +describe('shell command :!', function() local screen before_each(function() clear() - screen = child_session.screen_setup(0, '["'..helpers.nvim_prog.. - '", "-u", "NONE", "-i", "NONE", "--cmd", "'..helpers.nvim_set..'"]') + screen = child_session.setup_child_nvim({ + '-u', + 'NONE', + '-i', + 'NONE', + '--cmd', + 'colorscheme vim', + '--cmd', + helpers.nvim_set .. ' notermguicolors', + }) screen:expect([[ {1: } | - {4:~ }| - {4:~ }| - {4:~ }| - {4:~ }| + {4:~ }|*4 | {3:-- TERMINAL --} | ]]) end) after_each(function() - child_session.feed_data("\3") -- Ctrl-C + child_session.feed_data('\3') -- Ctrl-C end) - it("displays output without LF/EOF. #4646 #4569 #3772", function() + it('displays output without LF/EOF. #4646 #4569 #3772', function() skip(is_os('win')) -- NOTE: We use a child nvim (within a :term buffer) -- to avoid triggering a UI flush. - child_session.feed_data(":!printf foo; sleep 200\n") + child_session.feed_data(':!printf foo; sleep 200\n') screen:expect([[ | - {4:~ }| - {4:~ }| + {4:~ }|*2 {5: }| :!printf foo; sleep 200 | foo | @@ -54,18 +58,19 @@ describe("shell command :!", function() ]]) end) - it("throttles shell-command output greater than ~10KB", function() + it('throttles shell-command output greater than ~10KB', function() skip(is_os('openbsd'), 'FIXME #10804') skip(is_os('win')) - child_session.feed_data((":!%s REP 30001 foo\n"):format(testprg('shell-test'))) + child_session.feed_data((':!%s REP 30001 foo\n'):format(testprg('shell-test'))) -- If we observe any line starting with a dot, then throttling occurred. -- Avoid false failure on slow systems. - screen:expect{any="\n%.", timeout=20000} + screen:expect { any = '\n%.', timeout = 20000 } -- Final chunk of output should always be displayed, never skipped. -- (Throttling is non-deterministic, this test is merely a sanity check.) - screen:expect([[ + screen:expect( + [[ 29997: foo | 29998: foo | 29999: foo | @@ -73,27 +78,29 @@ describe("shell command :!", function() | {10:Press ENTER or type command to continue}{1: } | {3:-- TERMINAL --} | - ]], { - -- test/functional/helpers.lua defaults to background=light. - [1] = {reverse = true}, - [3] = {bold = true}, - [10] = {foreground = 2}, - }) + ]], + { + -- test/functional/helpers.lua defaults to background=light. + [1] = { reverse = true }, + [3] = { bold = true }, + [10] = { foreground = 2 }, + } + ) end) end) -describe("shell command :!", function() +describe('shell command :!', function() before_each(function() clear() end) - it("cat a binary file #4142", function() + it('cat a binary file #4142', function() feed(":exe 'silent !cat '.shellescape(v:progpath)<CR>") assert_alive() end) it([[display \x08 char #4142]], function() - feed(":silent !echo \08<CR>") + feed(':silent !echo \08<CR>') assert_alive() end) @@ -101,32 +108,37 @@ describe("shell command :!", function() skip(is_os('win'), 'missing printf') local screen = Screen.new(50, 4) screen:set_default_attr_ids { - [1] = {bold = true, reverse = true}; - [2] = {bold = true, foreground = Screen.colors.SeaGreen}; - [3] = {foreground = Screen.colors.Blue}; + [1] = { bold = true, reverse = true }, + [2] = { bold = true, foreground = Screen.colors.SeaGreen }, + [3] = { foreground = Screen.colors.Blue }, } screen:attach() -- Print TAB chars. #2958 feed([[:!printf '1\t2\t3'<CR>]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: }| :!printf '1\t2\t3' | 1 2 3 | {2:Press ENTER or type command to continue}^ | - ]]} + ]], + } feed([[<CR>]]) -- Print BELL control code. #4338 screen.bell = false feed([[:!printf '\007\007\007\007text'<CR>]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: }| :!printf '\007\007\007\007text' | text | {2:Press ENTER or type command to continue}^ | - ]], condition=function() - eq(true, screen.bell) - end} + ]], + condition = function() + eq(true, screen.bell) + end, + } feed([[<CR>]]) -- Print BS control code. @@ -143,8 +155,7 @@ describe("shell command :!", function() feed([[:!printf '\n'<CR>]]) screen:expect([[ :!printf '\n' | - | - | + |*2 {2:Press ENTER or type command to continue}^ | ]]) feed([[<CR>]]) @@ -158,12 +169,12 @@ describe("shell command :!", function() write_file('bang_filter_spec/f1', 'f1') write_file('bang_filter_spec/f2', 'f2') write_file('bang_filter_spec/f3', 'f3') - screen = Screen.new(53,10) + screen = Screen.new(53, 10) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {foreground = Screen.colors.Blue1}, - [3] = {bold = true, foreground = Screen.colors.SeaGreen4}, - [4] = {bold = true, reverse = true}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.Blue1 }, + [3] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [4] = { bold = true, reverse = true }, }) screen:attach() end) @@ -173,19 +184,19 @@ describe("shell command :!", function() end) it("doesn't truncate Last line of shell output #3269", function() - command(is_os('win') - and [[nnoremap <silent>\l :!dir /b bang_filter_spec<cr>]] - or [[nnoremap <silent>\l :!ls bang_filter_spec<cr>]]) - local result = (is_os('win') - and [[:!dir /b bang_filter_spec]] - or [[:!ls bang_filter_spec ]]) + command( + is_os('win') and [[nnoremap <silent>\l :!dir /b bang_filter_spec<cr>]] + or [[nnoremap <silent>\l :!ls bang_filter_spec<cr>]] + ) + local result = ( + is_os('win') and [[:!dir /b bang_filter_spec]] or [[:!ls bang_filter_spec ]] + ) feed([[\l]]) screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {4: }| - ]]..result..[[ | + ]] .. result .. [[ | f1 | f2 | f3 | @@ -197,7 +208,8 @@ describe("shell command :!", function() it('handles binary and multibyte data', function() feed_command('!cat test/functional/fixtures/shell_data.txt') screen.bell = false - screen:expect{grid=[[ + screen:expect { + grid = [[ | {1:~ }| {4: }| @@ -208,20 +220,22 @@ describe("shell command :!", function() t {2:<ff>} | | {3:Press ENTER or type command to continue}^ | - ]], condition=function() - eq(true, screen.bell) - end} + ]], + condition = function() + eq(true, screen.bell) + end, + } end) it('handles multibyte sequences split over buffer boundaries', function() - command('cd '..nvim_dir) + command('cd ' .. nvim_dir) local cmd = is_os('win') and '!shell-test UTF-8 ' or '!./shell-test UTF-8' feed_command(cmd) -- Note: only the first example of split composed char works screen:expect([[ | {4: }| - :]]..cmd..[[ | + :]] .. cmd .. [[ | å | ref: å̲ | 1: å̲ | diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index a6cd216d84..1f0d20f66d 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -4,10 +4,10 @@ local assert_alive = helpers.assert_alive local clear, feed = helpers.clear, helpers.feed local source = helpers.source local insert = helpers.insert -local meths = helpers.meths +local api = helpers.api local async_meths = helpers.async_meths local command = helpers.command -local funcs = helpers.funcs +local fn = helpers.fn local eq = helpers.eq local pcall_err = helpers.pcall_err local exec_lua = helpers.exec_lua @@ -18,16 +18,16 @@ describe('ui/ext_popupmenu', function() before_each(function() clear() screen = Screen.new(60, 8) - screen:attach({rgb=true, ext_popupmenu=true}) + screen:attach({ rgb = true, ext_popupmenu = true }) screen:set_default_attr_ids({ - [1] = {bold=true, foreground=Screen.colors.Blue}, - [2] = {bold = true}, - [3] = {reverse = true}, - [4] = {bold = true, reverse = true}, - [5] = {bold = true, foreground = Screen.colors.SeaGreen}, - [6] = {background = Screen.colors.WebGray}, - [7] = {background = Screen.colors.LightMagenta}, - [8] = {foreground = Screen.colors.Red}, + [1] = { bold = true, foreground = Screen.colors.Blue }, + [2] = { bold = true }, + [3] = { reverse = true }, + [4] = { bold = true, reverse = true }, + [5] = { bold = true, foreground = Screen.colors.SeaGreen }, + [6] = { background = Screen.colors.WebGray }, + [7] = { background = Screen.colors.LightMagenta }, + [8] = { foreground = Screen.colors.Red }, }) source([[ function! TestComplete() abort @@ -38,447 +38,399 @@ describe('ui/ext_popupmenu', function() end) local expected = { - {'fo', 'x', 'the foo', 'foo-y'}, - {'bar', '', '', ''}, - {'spam', '', '', ''}, + { 'fo', 'x', 'the foo', 'foo-y' }, + { 'bar', '', '', '' }, + { 'spam', '', '', '' }, } it('works', function() feed('o<C-r>=TestComplete()<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | foo^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=expected, - pos=0, - anchor={1,1,0}, - }} + ]], + popupmenu = { + items = expected, + pos = 0, + anchor = { 1, 1, 0 }, + }, + } feed('<c-p>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=expected, - pos=-1, - anchor={1,1,0}, - }} + ]], + popupmenu = { + items = expected, + pos = -1, + anchor = { 1, 1, 0 }, + }, + } -- down moves the selection in the menu, but does not insert anything feed('<down><down>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=expected, - pos=1, - anchor={1,1,0}, - }} + ]], + popupmenu = { + items = expected, + pos = 1, + anchor = { 1, 1, 0 }, + }, + } feed('<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | bar^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]]} + ]], + } end) it('can be controlled by API', function() feed('o<C-r>=TestComplete()<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | foo^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=expected, - pos=0, - anchor={1,1,0}, - }} - - meths.select_popupmenu_item(1,false,false,{}) - screen:expect{grid=[[ + ]], + popupmenu = { + items = expected, + pos = 0, + anchor = { 1, 1, 0 }, + }, + } + + api.nvim_select_popupmenu_item(1, false, false, {}) + screen:expect { + grid = [[ | foo^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=expected, - pos=1, - anchor={1,1,0}, - }} - - meths.select_popupmenu_item(2,true,false,{}) - screen:expect{grid=[[ + ]], + popupmenu = { + items = expected, + pos = 1, + anchor = { 1, 1, 0 }, + }, + } + + api.nvim_select_popupmenu_item(2, true, false, {}) + screen:expect { + grid = [[ | spam^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=expected, - pos=2, - anchor={1,1,0}, - }} + ]], + popupmenu = { + items = expected, + pos = 2, + anchor = { 1, 1, 0 }, + }, + } - meths.select_popupmenu_item(0,true,true,{}) + api.nvim_select_popupmenu_item(0, true, true, {}) screen:expect([[ | foo^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | ]]) - feed('<c-w><C-r>=TestComplete()<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | foo^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=expected, - pos=0, - anchor={1,1,0}, - }} - - meths.select_popupmenu_item(-1,false,false,{}) - screen:expect{grid=[[ + ]], + popupmenu = { + items = expected, + pos = 0, + anchor = { 1, 1, 0 }, + }, + } + + api.nvim_select_popupmenu_item(-1, false, false, {}) + screen:expect { + grid = [[ | foo^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=expected, - pos=-1, - anchor={1,1,0}, - }} - - meths.select_popupmenu_item(1,true,false,{}) - screen:expect{grid=[[ + ]], + popupmenu = { + items = expected, + pos = -1, + anchor = { 1, 1, 0 }, + }, + } + + api.nvim_select_popupmenu_item(1, true, false, {}) + screen:expect { + grid = [[ | bar^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=expected, - pos=1, - anchor={1,1,0}, - }} - - meths.select_popupmenu_item(-1,true,false,{}) - screen:expect{grid=[[ + ]], + popupmenu = { + items = expected, + pos = 1, + anchor = { 1, 1, 0 }, + }, + } + + api.nvim_select_popupmenu_item(-1, true, false, {}) + screen:expect { + grid = [[ | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=expected, - pos=-1, - anchor={1,1,0}, - }} - - meths.select_popupmenu_item(0,true,false,{}) - screen:expect{grid=[[ + ]], + popupmenu = { + items = expected, + pos = -1, + anchor = { 1, 1, 0 }, + }, + } + + api.nvim_select_popupmenu_item(0, true, false, {}) + screen:expect { + grid = [[ | foo^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=expected, - pos=0, - anchor={1,1,0}, - }} + ]], + popupmenu = { + items = expected, + pos = 0, + anchor = { 1, 1, 0 }, + }, + } - meths.select_popupmenu_item(-1,true,true,{}) + api.nvim_select_popupmenu_item(-1, true, true, {}) screen:expect([[ | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | ]]) command('set wildmenu') command('set wildoptions=pum') local expected_wildpum = { - { "define", "", "", "" }, - { "jump", "", "", "" }, - { "list", "", "", "" }, - { "place", "", "", "" }, - { "undefine", "", "", "" }, - { "unplace", "", "", "" }, + { 'define', '', '', '' }, + { 'jump', '', '', '' }, + { 'list', '', '', '' }, + { 'place', '', '', '' }, + { 'undefine', '', '', '' }, + { 'unplace', '', '', '' }, } feed('<Esc>:sign <Tab>') - screen:expect({grid = [[ - | - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + screen:expect({ + grid = [[ + |*2 + {1:~ }|*5 :sign define^ | - ]], popupmenu = { - items = expected_wildpum, - pos = 0, - anchor = { 1, 7, 6 }, - }}) - - meths.select_popupmenu_item(-1, true, false, {}) - screen:expect({grid = [[ - | - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + ]], + popupmenu = { + items = expected_wildpum, + pos = 0, + anchor = { 1, 7, 6 }, + }, + }) + + api.nvim_select_popupmenu_item(-1, true, false, {}) + screen:expect({ + grid = [[ + |*2 + {1:~ }|*5 :sign ^ | - ]], popupmenu = { - items = expected_wildpum, - pos = -1, - anchor = { 1, 7, 6 }, - }}) - - meths.select_popupmenu_item(5, true, false, {}) - screen:expect({grid = [[ - | - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + ]], + popupmenu = { + items = expected_wildpum, + pos = -1, + anchor = { 1, 7, 6 }, + }, + }) + + api.nvim_select_popupmenu_item(5, true, false, {}) + screen:expect({ + grid = [[ + |*2 + {1:~ }|*5 :sign unplace^ | - ]], popupmenu = { - items = expected_wildpum, - pos = 5, - anchor = { 1, 7, 6 }, - }}) - - meths.select_popupmenu_item(-1, true, true, {}) - screen:expect({grid = [[ - | - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + ]], + popupmenu = { + items = expected_wildpum, + pos = 5, + anchor = { 1, 7, 6 }, + }, + }) + + api.nvim_select_popupmenu_item(-1, true, true, {}) + screen:expect({ + grid = [[ + |*2 + {1:~ }|*5 :sign ^ | - ]]}) + ]], + }) feed('<Tab>') - screen:expect({grid = [[ - | - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + screen:expect({ + grid = [[ + |*2 + {1:~ }|*5 :sign define^ | - ]], popupmenu = { - items = expected_wildpum, - pos = 0, - anchor = { 1, 7, 6 }, - }}) - - meths.select_popupmenu_item(5, true, true, {}) - screen:expect({grid = [[ - | - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + ]], + popupmenu = { + items = expected_wildpum, + pos = 0, + anchor = { 1, 7, 6 }, + }, + }) + + api.nvim_select_popupmenu_item(5, true, true, {}) + screen:expect({ + grid = [[ + |*2 + {1:~ }|*5 :sign unplace^ | - ]]}) + ]], + }) local function test_pum_select_mappings() screen:set_option('ext_popupmenu', true) feed('<Esc>A<C-r>=TestComplete()<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | foo^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=expected, - pos=0, - anchor={1,1,0}, - }} + ]], + popupmenu = { + items = expected, + pos = 0, + anchor = { 1, 1, 0 }, + }, + } feed('<f1>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | spam^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=expected, - pos=2, - anchor={1,1,0}, - }} + ]], + popupmenu = { + items = expected, + pos = 2, + anchor = { 1, 1, 0 }, + }, + } feed('<f2>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | spam^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=expected, - pos=-1, - anchor={1,1,0}, - }} + ]], + popupmenu = { + items = expected, + pos = -1, + anchor = { 1, 1, 0 }, + }, + } feed('<f3>') screen:expect([[ | bar^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | ]]) feed('<Esc>:sign <Tab>') - screen:expect({grid = [[ + screen:expect({ + grid = [[ | bar | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 :sign define^ | - ]], popupmenu = { - items = expected_wildpum, - pos = 0, - anchor = { 1, 7, 6 }, - }}) + ]], + popupmenu = { + items = expected_wildpum, + pos = 0, + anchor = { 1, 7, 6 }, + }, + }) feed('<f1>') - screen:expect({grid = [[ + screen:expect({ + grid = [[ | bar | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 :sign list^ | - ]], popupmenu = { - items = expected_wildpum, - pos = 2, - anchor = { 1, 7, 6 }, - }}) + ]], + popupmenu = { + items = expected_wildpum, + pos = 2, + anchor = { 1, 7, 6 }, + }, + }) feed('<f2>') - screen:expect({grid = [[ + screen:expect({ + grid = [[ | bar | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 :sign ^ | - ]], popupmenu = { - items = expected_wildpum, - pos = -1, - anchor = { 1, 7, 6 }, - }}) + ]], + popupmenu = { + items = expected_wildpum, + pos = -1, + anchor = { 1, 7, 6 }, + }, + }) feed('<f3>') - screen:expect({grid = [[ + screen:expect({ + grid = [[ | bar | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 :sign jump^ | - ]]}) + ]], + }) -- also should work for builtin popupmenu screen:set_option('ext_popupmenu', false) @@ -489,8 +441,7 @@ describe('ui/ext_popupmenu', function() {6:fo x the foo }{1: }| {7:bar }{1: }| {7:spam }{1: }| - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:-- INSERT --} | ]]) @@ -501,8 +452,7 @@ describe('ui/ext_popupmenu', function() {7:fo x the foo }{1: }| {7:bar }{1: }| {6:spam }{1: }| - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:-- INSERT --} | ]]) @@ -513,8 +463,7 @@ describe('ui/ext_popupmenu', function() {7:fo x the foo }{1: }| {7:bar }{1: }| {7:spam }{1: }| - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:-- INSERT --} | ]]) @@ -522,11 +471,7 @@ describe('ui/ext_popupmenu', function() screen:expect([[ | bar^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | ]]) @@ -570,11 +515,7 @@ describe('ui/ext_popupmenu', function() screen:expect([[ | bar | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 :sign jump^ | ]]) end @@ -602,8 +543,7 @@ describe('ui/ext_popupmenu', function() {6:aa }{1: }| {7:bb }{1: }| {7:cc }{1: }| - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:-- Keyword Local completion (^N^P) }{5:match 1 of 3} | ]]) @@ -614,8 +554,7 @@ describe('ui/ext_popupmenu', function() {7:aa }{1: }| {7:bb }{1: }| {6:cc }{1: }| - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:-- Keyword Local completion (^N^P) }{5:match 3 of 3} | ]]) @@ -626,8 +565,7 @@ describe('ui/ext_popupmenu', function() {7:aa }{1: }| {7:bb }{1: }| {7:cc }{1: }| - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:-- Keyword Local completion (^N^P) }{8:Back at original} | ]]) @@ -635,11 +573,7 @@ describe('ui/ext_popupmenu', function() screen:expect([[ aa bb cc | bb^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | ]]) end) @@ -659,52 +593,49 @@ describe('ui/ext_popupmenu', function() it('can set pum height', function() source_complete_month() local month_expected = { - {'January', '', '', ''}, - {'February', '', '', ''}, - {'March', '', '', ''}, - {'April', '', '', ''}, - {'May', '', '', ''}, - {'June', '', '', ''}, - {'July', '', '', ''}, - {'August', '', '', ''}, - {'September', '', '', ''}, - {'October', '', '', ''}, - {'November', '', '', ''}, - {'December', '', '', ''}, + { 'January', '', '', '' }, + { 'February', '', '', '' }, + { 'March', '', '', '' }, + { 'April', '', '', '' }, + { 'May', '', '', '' }, + { 'June', '', '', '' }, + { 'July', '', '', '' }, + { 'August', '', '', '' }, + { 'September', '', '', '' }, + { 'October', '', '', '' }, + { 'November', '', '', '' }, + { 'December', '', '', '' }, } local pum_height = 6 feed('o<C-r>=TestCompleteMonth()<CR>') - meths.ui_pum_set_height(pum_height) + api.nvim_ui_pum_set_height(pum_height) feed('<PageDown>') -- pos becomes pum_height-2 because it is subtracting 2 to keep some -- context in ins_compl_key2count() - screen:expect{grid=[[ + screen:expect { + grid = [[ | January^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=month_expected, - pos=pum_height-2, - anchor={1,1,0}, - }} + ]], + popupmenu = { + items = month_expected, + pos = pum_height - 2, + anchor = { 1, 1, 0 }, + }, + } end) it('an error occurs if set 0 or less', function() - meths.ui_pum_set_height(1) - eq('Expected pum height > 0', - pcall_err(meths.ui_pum_set_height, 0)) + api.nvim_ui_pum_set_height(1) + eq('Expected pum height > 0', pcall_err(api.nvim_ui_pum_set_height, 0)) end) it('an error occurs when ext_popupmenu is false', function() - meths.ui_pum_set_height(1) + api.nvim_ui_pum_set_height(1) screen:set_option('ext_popupmenu', false) - eq('It must support the ext_popupmenu option', - pcall_err(meths.ui_pum_set_height, 1)) + eq('It must support the ext_popupmenu option', pcall_err(api.nvim_ui_pum_set_height, 1)) end) end) @@ -712,239 +643,205 @@ describe('ui/ext_popupmenu', function() it('can set pum bounds', function() source_complete_month() local month_expected = { - {'January', '', '', ''}, - {'February', '', '', ''}, - {'March', '', '', ''}, - {'April', '', '', ''}, - {'May', '', '', ''}, - {'June', '', '', ''}, - {'July', '', '', ''}, - {'August', '', '', ''}, - {'September', '', '', ''}, - {'October', '', '', ''}, - {'November', '', '', ''}, - {'December', '', '', ''}, + { 'January', '', '', '' }, + { 'February', '', '', '' }, + { 'March', '', '', '' }, + { 'April', '', '', '' }, + { 'May', '', '', '' }, + { 'June', '', '', '' }, + { 'July', '', '', '' }, + { 'August', '', '', '' }, + { 'September', '', '', '' }, + { 'October', '', '', '' }, + { 'November', '', '', '' }, + { 'December', '', '', '' }, } local pum_height = 6 feed('o<C-r>=TestCompleteMonth()<CR>') - meths.ui_pum_set_height(pum_height) + api.nvim_ui_pum_set_height(pum_height) -- set bounds w h r c - meths.ui_pum_set_bounds(10.5, 5.2, 6.3, 7.4) + api.nvim_ui_pum_set_bounds(10.5, 5.2, 6.3, 7.4) feed('<PageDown>') -- pos becomes pum_height-2 because it is subtracting 2 to keep some -- context in ins_compl_key2count() - screen:expect{grid=[[ + screen:expect { + grid = [[ | January^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=month_expected, - pos=pum_height-2, - anchor={1,1,0}, - }} + ]], + popupmenu = { + items = month_expected, + pos = pum_height - 2, + anchor = { 1, 1, 0 }, + }, + } end) it('no error occurs if row or col set less than 0', function() - meths.ui_pum_set_bounds(1.0, 1.0, 0.0, 1.5) - meths.ui_pum_set_bounds(1.0, 1.0, -1.0, 0.0) - meths.ui_pum_set_bounds(1.0, 1.0, 0.0, -1.0) + api.nvim_ui_pum_set_bounds(1.0, 1.0, 0.0, 1.5) + api.nvim_ui_pum_set_bounds(1.0, 1.0, -1.0, 0.0) + api.nvim_ui_pum_set_bounds(1.0, 1.0, 0.0, -1.0) end) it('an error occurs if width or height set 0 or less', function() - meths.ui_pum_set_bounds(1.0, 1.0, 0.0, 1.5) - eq('Expected width > 0', - pcall_err(meths.ui_pum_set_bounds, 0.0, 1.0, 1.0, 0.0)) - eq('Expected height > 0', - pcall_err(meths.ui_pum_set_bounds, 1.0, -1.0, 1.0, 0.0)) + api.nvim_ui_pum_set_bounds(1.0, 1.0, 0.0, 1.5) + eq('Expected width > 0', pcall_err(api.nvim_ui_pum_set_bounds, 0.0, 1.0, 1.0, 0.0)) + eq('Expected height > 0', pcall_err(api.nvim_ui_pum_set_bounds, 1.0, -1.0, 1.0, 0.0)) end) it('an error occurs when ext_popupmenu is false', function() - meths.ui_pum_set_bounds(1.0, 1.0, 0.0, 1.5) + api.nvim_ui_pum_set_bounds(1.0, 1.0, 0.0, 1.5) screen:set_option('ext_popupmenu', false) - eq('UI must support the ext_popupmenu option', - pcall_err(meths.ui_pum_set_bounds, 1.0, 1.0, 0.0, 1.5)) + eq( + 'UI must support the ext_popupmenu option', + pcall_err(api.nvim_ui_pum_set_bounds, 1.0, 1.0, 0.0, 1.5) + ) end) end) it('<PageUP>, <PageDown> works without ui_pum_set_height', function() source_complete_month() local month_expected = { - {'January', '', '', ''}, - {'February', '', '', ''}, - {'March', '', '', ''}, - {'April', '', '', ''}, - {'May', '', '', ''}, - {'June', '', '', ''}, - {'July', '', '', ''}, - {'August', '', '', ''}, - {'September', '', '', ''}, - {'October', '', '', ''}, - {'November', '', '', ''}, - {'December', '', '', ''}, + { 'January', '', '', '' }, + { 'February', '', '', '' }, + { 'March', '', '', '' }, + { 'April', '', '', '' }, + { 'May', '', '', '' }, + { 'June', '', '', '' }, + { 'July', '', '', '' }, + { 'August', '', '', '' }, + { 'September', '', '', '' }, + { 'October', '', '', '' }, + { 'November', '', '', '' }, + { 'December', '', '', '' }, } feed('o<C-r>=TestCompleteMonth()<CR>') feed('<PageDown>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | January^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=month_expected, - pos=3, - anchor={1,1,0}, - }} + ]], + popupmenu = { + items = month_expected, + pos = 3, + anchor = { 1, 1, 0 }, + }, + } feed('<PageUp>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | January^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=month_expected, - pos=0, - anchor={1,1,0}, - }} + ]], + popupmenu = { + items = month_expected, + pos = 0, + anchor = { 1, 1, 0 }, + }, + } end) it('works with wildoptions=pum', function() - screen:try_resize(32,10) + screen:try_resize(32, 10) command('set wildmenu') command('set wildoptions=pum') local wild_expected = { - {'define', '', '', ''}, - {'jump', '', '', ''}, - {'list', '', '', ''}, - {'place', '', '', ''}, - {'undefine', '', '', ''}, - {'unplace', '', '', ''}, + { 'define', '', '', '' }, + { 'jump', '', '', '' }, + { 'list', '', '', '' }, + { 'place', '', '', '' }, + { 'undefine', '', '', '' }, + { 'unplace', '', '', '' }, } feed(':sign ') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 :sign ^ | ]]) - eq(0, funcs.wildmenumode()) + eq(0, fn.wildmenumode()) feed('<tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 :sign define^ | - ]], popupmenu={items=wild_expected, pos=0, anchor={1, 9, 6}}} - eq(1, funcs.wildmenumode()) + ]], + popupmenu = { items = wild_expected, pos = 0, anchor = { 1, 9, 6 } }, + } + eq(1, fn.wildmenumode()) feed('<left>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 :sign ^ | - ]], popupmenu={items=wild_expected, pos=-1, anchor={1, 9, 6}}} + ]], + popupmenu = { items = wild_expected, pos = -1, anchor = { 1, 9, 6 } }, + } feed('<left>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 :sign unplace^ | - ]], popupmenu={items=wild_expected, pos=5, anchor={1, 9, 6}}} + ]], + popupmenu = { items = wild_expected, pos = 5, anchor = { 1, 9, 6 } }, + } feed('x') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 :sign unplacex^ | ]]) feed('<esc>') -- #10042: make sure shift-tab also triggers the pum feed(':sign <S-tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 :sign unplace^ | - ]], popupmenu={items=wild_expected, pos=5, anchor={1, 9, 6}}} + ]], + popupmenu = { items = wild_expected, pos = 5, anchor = { 1, 9, 6 } }, + } feed('<esc>') - eq(0, funcs.wildmenumode()) + eq(0, fn.wildmenumode()) -- check positioning with multibyte char in pattern - command("e långfile1") - command("sp långfile2") + command('e långfile1') + command('sp långfile2') feed(':b lå<tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {4:långfile2 }| | - {1:~ }| - {1:~ }| + {1:~ }|*2 {3:långfile1 }| :b långfile1^ | - ]], popupmenu={ - anchor = {1, 9, 3}, - items = {{"långfile1", "", "", "" }, {"långfile2", "", "", ""}}, - pos = 0, - }} - + ]], + popupmenu = { + anchor = { 1, 9, 3 }, + items = { { 'långfile1', '', '', '' }, { 'långfile2', '', '', '' } }, + pos = 0, + }, + } end) it('does not interfere with mousemodel=popup', function() @@ -957,68 +854,58 @@ describe('ui/ext_popupmenu', function() menu PopUp.baz :let g:menustr = 'baz'<CR> ]]) feed('o<C-r>=TestComplete()<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | foo^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=expected, - pos=0, - anchor={1,1,0}, - }} + ]], + popupmenu = { + items = expected, + pos = 0, + anchor = { 1, 1, 0 }, + }, + } feed('<c-p>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | - ]], popupmenu={ - items=expected, - pos=-1, - anchor={1,1,0}, - }} + ]], + popupmenu = { + items = expected, + pos = -1, + anchor = { 1, 1, 0 }, + }, + } feed('<esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | - ]]} + ]], + } feed('<RightMouse><0,0>') screen:expect([[ | {7:^foo } | {7:bar }{1: }| {7:baz }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]) feed('<esc>') screen:expect([[ | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | ]]) end) @@ -1030,51 +917,51 @@ describe("builtin popupmenu 'pumblend'", function() it('RGB-color', function() local screen = Screen.new(60, 14) screen:set_default_attr_ids({ - [1] = {background = Screen.colors.Yellow}, - [2] = {bold = true, reverse = true}, - [3] = {bold = true, foreground = Screen.colors.Brown}, - [4] = {foreground = Screen.colors.Blue1}, - [5] = {reverse = true}, - [6] = {background = Screen.colors.Gray55, foreground = Screen.colors.Grey45}, - [7] = {background = Screen.colors.Gray55, foreground = Screen.colors.Grey0}, - [8] = {background = tonumber('0x191919'), foreground = Screen.colors.Grey0}, - [9] = {background = tonumber('0xffc1ff'), foreground = tonumber('0xe5a8e5')}, - [10] = {background = tonumber('0xffc1ff'), foreground = Screen.colors.Grey0}, - [11] = {foreground = tonumber('0xffc1ff'), background = tonumber('0xe5a8e5'), bold = true}, - [12] = {foreground = Screen.colors.Grey55, background = Screen.colors.Gray45, bold = true}, - [13] = {background = tonumber('0xffc1e5'), foreground = Screen.colors.Grey0}, - [14] = {background = tonumber('0xffc1e5'), foreground = tonumber('0xe5a8e5')}, - [15] = {background = tonumber('0xffc1ff'), foreground = tonumber('0x080202')}, - [16] = {background = tonumber('0xffc1ff'), bold = true, foreground = tonumber('0xf6ace9')}, - [17] = {background = tonumber('0xffc1ff'), foreground = tonumber('0xe5a8ff')}, - [18] = {background = tonumber('0xe5a8e5'), foreground = tonumber('0xffc1ff')}, - [19] = {background = Screen.colors.Gray45, foreground = Screen.colors.Grey55}, - [20] = {bold = true}, - [21] = {bold = true, foreground = Screen.colors.SeaGreen4}, - [22] = {background = Screen.colors.WebGray}, - [23] = {background = Screen.colors.Grey0}, - [24] = {background = Screen.colors.LightMagenta}, - [25] = {background = Screen.colors.Gray75, foreground = Screen.colors.Grey25}, - [26] = {background = Screen.colors.Gray75, foreground = Screen.colors.Grey0}, - [27] = {background = Screen.colors.Gray50, foreground = Screen.colors.Grey0}, - [28] = {background = tonumber('0xffddff'), foreground = tonumber('0x7f5d7f')}, - [29] = {background = tonumber('0xffddff'), foreground = Screen.colors.Grey0}, - [30] = {foreground = tonumber('0xffddff'), background = tonumber('0x7f5d7f'), bold = true}, - [31] = {foreground = tonumber('0xffddff'), background = Screen.colors.Grey0, bold = true}, - [32] = {foreground = Screen.colors.Gray75, background = Screen.colors.Grey25, bold = true}, - [33] = {background = tonumber('0xffdd7f'), foreground = Screen.colors.Grey0}, - [34] = {background = tonumber('0xffdd7f'), foreground = tonumber('0x7f5d7f')}, - [35] = {background = tonumber('0xffddff'), bold = true, foreground = tonumber('0x290a0a')}, - [36] = {background = tonumber('0xffddff'), bold = true, foreground = tonumber('0xd27294')}, - [37] = {background = tonumber('0xffddff'), foreground = tonumber('0x7f5dff')}, - [38] = {background = tonumber('0x7f5d7f'), foreground = tonumber('0xffddff')}, - [39] = {background = Screen.colors.Grey0, foreground = tonumber('0xffddff')}, - [40] = {background = Screen.colors.Gray25, foreground = Screen.colors.Grey75}, - [41] = {background = tonumber('0xffddff'), foreground = tonumber('0x00003f')}, - [42] = {foreground = tonumber('0x0c0c0c'), background = tonumber('0xe5a8e5')}, - [43] = {background = tonumber('0x7f5d7f'), bold = true, foreground = tonumber('0x3f3f3f')}, - [44] = {foreground = tonumber('0x3f3f3f'), background = tonumber('0x7f5d7f')}, - [45] = {background = Screen.colors.WebGray, blend=0}, + [1] = { background = Screen.colors.Yellow }, + [2] = { bold = true, reverse = true }, + [3] = { bold = true, foreground = Screen.colors.Brown }, + [4] = { foreground = Screen.colors.Blue1 }, + [5] = { reverse = true }, + [6] = { background = Screen.colors.Gray55, foreground = Screen.colors.Grey45 }, + [7] = { background = Screen.colors.Gray55, foreground = Screen.colors.Grey0 }, + [8] = { background = tonumber('0x191919'), foreground = Screen.colors.Grey0 }, + [9] = { background = tonumber('0xffc1ff'), foreground = tonumber('0xe5a8e5') }, + [10] = { background = tonumber('0xffc1ff'), foreground = Screen.colors.Grey0 }, + [11] = { foreground = tonumber('0xffc1ff'), background = tonumber('0xe5a8e5'), bold = true }, + [12] = { foreground = Screen.colors.Grey55, background = Screen.colors.Gray45, bold = true }, + [13] = { background = tonumber('0xffc1e5'), foreground = Screen.colors.Grey0 }, + [14] = { background = tonumber('0xffc1e5'), foreground = tonumber('0xe5a8e5') }, + [15] = { background = tonumber('0xffc1ff'), foreground = tonumber('0x080202') }, + [16] = { background = tonumber('0xffc1ff'), bold = true, foreground = tonumber('0xf6ace9') }, + [17] = { background = tonumber('0xffc1ff'), foreground = tonumber('0xe5a8ff') }, + [18] = { background = tonumber('0xe5a8e5'), foreground = tonumber('0xffc1ff') }, + [19] = { background = Screen.colors.Gray45, foreground = Screen.colors.Grey55 }, + [20] = { bold = true }, + [21] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + [22] = { background = Screen.colors.WebGray }, + [23] = { background = Screen.colors.Grey0 }, + [24] = { background = Screen.colors.LightMagenta }, + [25] = { background = Screen.colors.Gray75, foreground = Screen.colors.Grey25 }, + [26] = { background = Screen.colors.Gray75, foreground = Screen.colors.Grey0 }, + [27] = { background = Screen.colors.Gray50, foreground = Screen.colors.Grey0 }, + [28] = { background = tonumber('0xffddff'), foreground = tonumber('0x7f5d7f') }, + [29] = { background = tonumber('0xffddff'), foreground = Screen.colors.Grey0 }, + [30] = { foreground = tonumber('0xffddff'), background = tonumber('0x7f5d7f'), bold = true }, + [31] = { foreground = tonumber('0xffddff'), background = Screen.colors.Grey0, bold = true }, + [32] = { foreground = Screen.colors.Gray75, background = Screen.colors.Grey25, bold = true }, + [33] = { background = tonumber('0xffdd7f'), foreground = Screen.colors.Grey0 }, + [34] = { background = tonumber('0xffdd7f'), foreground = tonumber('0x7f5d7f') }, + [35] = { background = tonumber('0xffddff'), bold = true, foreground = tonumber('0x290a0a') }, + [36] = { background = tonumber('0xffddff'), bold = true, foreground = tonumber('0xd27294') }, + [37] = { background = tonumber('0xffddff'), foreground = tonumber('0x7f5dff') }, + [38] = { background = tonumber('0x7f5d7f'), foreground = tonumber('0xffddff') }, + [39] = { background = Screen.colors.Grey0, foreground = tonumber('0xffddff') }, + [40] = { background = Screen.colors.Gray25, foreground = Screen.colors.Grey75 }, + [41] = { background = tonumber('0xffddff'), foreground = tonumber('0x00003f') }, + [42] = { foreground = tonumber('0x0c0c0c'), background = tonumber('0xe5a8e5') }, + [43] = { background = tonumber('0x7f5d7f'), bold = true, foreground = tonumber('0x3f3f3f') }, + [44] = { foreground = tonumber('0x3f3f3f'), background = tonumber('0x7f5d7f') }, + [45] = { background = Screen.colors.WebGray, blend = 0 }, }) screen:attach() command('syntax on') @@ -1168,7 +1055,7 @@ describe("builtin popupmenu 'pumblend'", function() {20:-- Keyword Local completion (^N^P) }{21:match 1 of 65} | ]]) - meths.input_mouse('wheel', 'down', '', 0, 9, 40) + api.nvim_input_mouse('wheel', 'down', '', 0, 9, 40) screen:expect([[ Lorem ipsum d{1:ol}or sit amet, consectetur | adipisicing elit, sed do eiusmod tempor | @@ -1228,18 +1115,18 @@ describe("builtin popupmenu 'pumblend'", function() it('256-color (non-RGB)', function() local screen = Screen.new(60, 8) screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.Grey0, background = tonumber('0x000007')}, - [2] = {foreground = tonumber('0x000055'), background = tonumber('0x000007')}, - [3] = {foreground = tonumber('0x00008f'), background = Screen.colors.Grey0}, - [4] = {foreground = Screen.colors.Grey0, background = tonumber('0x0000e1')}, - [5] = {foreground = tonumber('0x0000d1'), background = tonumber('0x0000e1')}, - [6] = {foreground = Screen.colors.NavyBlue, background = tonumber('0x0000f8')}, - [7] = {foreground = tonumber('0x0000a5'), background = tonumber('0x0000f8')}, - [8] = {foreground = tonumber('0x00000c')}, - [9] = {bold = true}, - [10] = {foreground = tonumber('0x000002')}, + [1] = { foreground = Screen.colors.Grey0, background = tonumber('0x000007') }, + [2] = { foreground = tonumber('0x000055'), background = tonumber('0x000007') }, + [3] = { foreground = tonumber('0x00008f'), background = Screen.colors.Grey0 }, + [4] = { foreground = Screen.colors.Grey0, background = tonumber('0x0000e1') }, + [5] = { foreground = tonumber('0x0000d1'), background = tonumber('0x0000e1') }, + [6] = { foreground = Screen.colors.NavyBlue, background = tonumber('0x0000f8') }, + [7] = { foreground = tonumber('0x0000a5'), background = tonumber('0x0000f8') }, + [8] = { foreground = tonumber('0x00000c') }, + [9] = { bold = true }, + [10] = { foreground = tonumber('0x000002') }, }) - screen:attach({rgb=false}) + screen:attach({ rgb = false }) command('set notermguicolors pumblend=10') insert([[ Lorem ipsum dolor sit amet, consectetur @@ -1271,21 +1158,21 @@ describe('builtin popupmenu', function() screen = Screen.new(32, 20) screen:set_default_attr_ids({ -- popup selected item / scrollbar track - ['s'] = {background = Screen.colors.WebGray}, + ['s'] = { background = Screen.colors.WebGray }, -- popup non-selected item - ['n'] = {background = Screen.colors.LightMagenta}, + ['n'] = { background = Screen.colors.LightMagenta }, -- popup scrollbar knob - ['c'] = {background = Screen.colors.Grey0}, - [1] = {bold = true, foreground = Screen.colors.Blue}, - [2] = {bold = true}, - [3] = {reverse = true}, - [4] = {bold = true, reverse = true}, - [5] = {bold = true, foreground = Screen.colors.SeaGreen}, - [6] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [7] = {background = Screen.colors.Yellow}, -- Search - [8] = {foreground = Screen.colors.Red}, + ['c'] = { background = Screen.colors.Grey0 }, + [1] = { bold = true, foreground = Screen.colors.Blue }, + [2] = { bold = true }, + [3] = { reverse = true }, + [4] = { bold = true, reverse = true }, + [5] = { bold = true, foreground = Screen.colors.SeaGreen }, + [6] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [7] = { background = Screen.colors.Yellow }, -- Search + [8] = { foreground = Screen.colors.Red }, }) - screen:attach({ext_multigrid=multigrid}) + screen:attach({ ext_multigrid = multigrid }) end) it('with preview-window above', function() @@ -1293,49 +1180,24 @@ describe('builtin popupmenu', function() feed('iaa bb cc dd ee ff gg hh ii jj<cr>') feed('<c-x><c-n>') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| + [4:--------------------------------]|*8 {3:[No Name] [Preview][+] }| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*9 {4:[No Name] [+] }| [3:--------------------------------]| ## grid 2 aa bb cc dd ee ff gg hh ii jj | aa^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*7 ## grid 3 {2:-- }{5:match 1 of 10} | ## grid 4 aa bb cc dd ee ff gg hh ii jj | aa | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 ## grid 5 {s:aa }{c: }| {n:bb }{c: }| @@ -1345,19 +1207,16 @@ describe('builtin popupmenu', function() {n:ff }{c: }| {n:gg }{s: }| {n:hh }{s: }| - ]], float_pos={ - [5] = {{id = -1}, "NW", 2, 2, 0, false, 100}; - }} + ]], + float_pos = { + [5] = { -1, 'NW', 2, 2, 0, false, 100 }, + }, + } else screen:expect([[ aa bb cc dd ee ff gg hh ii jj | aa | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 {3:[No Name] [Preview][+] }| aa bb cc dd ee ff gg hh ii jj | aa^ | @@ -1379,49 +1238,24 @@ describe('builtin popupmenu', function() feed('iaa bb cc dd ee ff gg hh ii jj<cr>') feed('<c-x><c-n>') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*9 {4:[No Name] [+] }| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| + [4:--------------------------------]|*8 {3:[No Name] [Preview][+] }| [3:--------------------------------]| ## grid 2 aa bb cc dd ee ff gg hh ii jj | aa^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*7 ## grid 3 {2:-- }{5:match 1 of 10} | ## grid 4 aa bb cc dd ee ff gg hh ii jj | aa | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 ## grid 5 {s:aa }{c: }| {n:bb }{c: }| @@ -1431,9 +1265,11 @@ describe('builtin popupmenu', function() {n:ff }{c: }| {n:gg }{s: }| {n:hh }{s: }| - ]], float_pos={ - [5] = {{id = -1}, "NW", 2, 2, 0, false, 100}; - }} + ]], + float_pos = { + [5] = { -1, 'NW', 2, 2, 0, false, 100 }, + }, + } else screen:expect([[ aa bb cc dd ee ff gg hh ii jj | @@ -1448,12 +1284,7 @@ describe('builtin popupmenu', function() {n:hh }{s: }{4: }| aa bb cc dd ee ff gg hh ii jj | aa | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 {3:[No Name] [Preview][+] }| {2:-- }{5:match 1 of 10} | ]]) @@ -1467,26 +1298,12 @@ describe('builtin popupmenu', function() feed('kk<cr>ll<cr>mm<cr>nn<cr>oo<cr>') feed('<c-x><c-n>') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| + [4:--------------------------------]|*4 {3:[No Name] [Preview][+] }| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*13 {4:[No Name] [+] }| [3:--------------------------------]| ## grid 2 @@ -1524,9 +1341,11 @@ describe('builtin popupmenu', function() {n:kk }{c: }| {n:ll }{s: }| {n:mm }{s: }| - ]], float_pos={ - [5] = {{id = -1}, "SW", 2, 12, 0, false, 100}; - }} + ]], + float_pos = { + [5] = { -1, 'SW', 2, 12, 0, false, 100 }, + }, + } else screen:expect([[ aa | @@ -1559,26 +1378,12 @@ describe('builtin popupmenu', function() feed('ff<cr>gg<cr>hh<cr>ii<cr>jj<cr>') feed('<c-x><c-n>') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| + [4:--------------------------------]|*8 {3:[No Name] [Preview][+] }| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*9 {4:[No Name] [+] }| [3:--------------------------------]| ## grid 2 @@ -1612,9 +1417,11 @@ describe('builtin popupmenu', function() {n:gg }{c: }| {n:hh }{c: }| {n:ii }{s: }| - ]], float_pos={ - [5] = {{id = -1}, "SW", 2, 8, 0, false, 100}; - }} + ]], + float_pos = { + [5] = { -1, 'SW', 2, 8, 0, false, 100 }, + }, + } else screen:expect([[ aa | @@ -1647,26 +1454,12 @@ describe('builtin popupmenu', function() feed('ff<cr>gg<cr>hh<cr>ii<cr>jj<cr>') feed('<c-x><c-n>') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*9 {4:[No Name] [+] }| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| - [4:--------------------------------]| + [4:--------------------------------]|*8 {3:[No Name] [Preview][+] }| [3:--------------------------------]| ## grid 2 @@ -1699,9 +1492,11 @@ describe('builtin popupmenu', function() {n:ff }{c: }| {n:gg }{s: }| {n:hh }{s: }| - ]], float_pos={ - [5] = {{id = -1}, "SW", 2, 8, 0, false, 100}; - }} + ]], + float_pos = { + [5] = { -1, 'SW', 2, 8, 0, false, 100 }, + }, + } else screen:expect([[ {s:aa }{c: } | @@ -1747,43 +1542,19 @@ describe('builtin popupmenu', function() {n:one }{1: }| {n:two }{1: }| {n:three }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*15 {2:-- }{8:Back at original} | ]]) feed('<C-N>') screen:expect([[ 1info | - | - {1:~ }| + {1:~ }|*2 {3:[Scratch] [Preview] }| one^ | {s:one }{1: }| {n:two }{1: }| {n:three }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*10 {4:[No Name] [+] }| {2:-- }{5:match 1 of 3} | ]]) @@ -1814,46 +1585,203 @@ describe('builtin popupmenu', function() end) end + describe('floating window preview #popup', function() + it('pum popup preview', function() + --row must > 10 + screen:try_resize(30, 11) + exec([[ + funct Omni_test(findstart, base) + if a:findstart + return col(".") - 1 + endif + return [#{word: "one", info: "1info"}, #{word: "two", info: "2info"}, #{word: "three"}] + endfunc + set omnifunc=Omni_test + set completeopt=menu,popup + + funct Set_info() + let comp_info = complete_info() + if comp_info['selected'] == 2 + call nvim_complete_set(comp_info['selected'], {"info": "3info"}) + endif + endfunc + autocmd CompleteChanged * call Set_info() + ]]) + feed('Gi<C-x><C-o>') + + --floating preview in right + if multigrid then + screen:expect { + grid = [[ + ## grid 1 + [2:------------------------------]|*10 + [3:------------------------------]| + ## grid 2 + one^ | + {1:~ }|*9 + ## grid 3 + {2:-- }{5:match 1 of 3} | + ## grid 4 + {n:1info}| + {n: }| + ## grid 5 + {s:one }| + {n:two }| + {n:three }| + ]], + float_pos = { + [5] = { -1, 'NW', 2, 1, 0, false, 100 }, + [4] = { 1001, 'NW', 1, 1, 15, true, 50 }, + }, + } + else + screen:expect { + grid = [[ + one^ | + {s:one }{n:1info}{1: }| + {n:two }{1: }| + {n:three }{1: }| + {1:~ }|*6 + {2:-- }{5:match 1 of 3} | + ]], + unchanged = true, + } + end + + -- test nvim_complete_set_info + feed('<C-N><C-N>') + vim.uv.sleep(10) + if multigrid then + screen:expect { + grid = [[ + ## grid 1 + [2:------------------------------]|*10 + [3:------------------------------]| + ## grid 2 + three^ | + {1:~ }|*9 + ## grid 3 + {2:-- }{5:match 3 of 3} | + ## grid 4 + {n:3info}| + {n: }| + ## grid 5 + {n:one }| + {n:two }| + {s:three }| + ]], + float_pos = { + [5] = { -1, 'NW', 2, 1, 0, false, 100 }, + [4] = { 1001, 'NW', 1, 1, 15, true, 50 }, + }, + } + else + screen:expect { + grid = [[ + three^ | + {n:one 3info}{1: }| + {n:two }{1: }| + {s:three }{1: }| + {1:~ }|*6 + {2:-- }{5:match 3 of 3} | + ]], + } + end + -- make sure info has set + feed('<C-y>') + eq('3info', exec_lua('return vim.v.completed_item.info')) + + -- preview in left + feed('<ESC>cc') + insert(('test'):rep(5)) + feed('i<C-x><C-o>') + if multigrid then + screen:expect { + grid = [[ + ## grid 1 + [2:------------------------------]|*10 + [3:------------------------------]| + ## grid 2 + itesttesttesttesttesone^t | + {1:~ }|*9 + ## grid 3 + {2:-- }{5:match 1 of 3} | + ## grid 5 + {s: one }| + {n: two }| + {n: three }| + ## grid 6 + {n:1info}| + {n: }| + ]], + float_pos = { + [5] = { -1, 'NW', 2, 1, 19, false, 100 }, + [6] = { 1002, 'NW', 1, 1, 1, true, 50 }, + }, + win_viewport = { + [2] = { + win = 1000, + topline = 0, + botline = 2, + curline = 0, + curcol = 23, + linecount = 1, + sum_scroll_delta = 0, + }, + [6] = { + win = 1002, + topline = 0, + botline = 2, + curline = 0, + curcol = 0, + linecount = 1, + sum_scroll_delta = 0, + }, + }, + } + else + screen:expect { + grid = [[ + itesttesttesttesttesone^t | + {1:~}{n:1info}{1: }{s: one }{1: }| + {1:~}{n: }{1: }{n: two }{1: }| + {1:~ }{n: three }{1: }| + {1:~ }|*6 + {2:-- }{5:match 1 of 3} | + ]], + } + end + end) + end) + it('with vsplits', function() screen:try_resize(32, 8) insert('aaa aab aac\n') feed(':vsplit<cr>') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [4:--------------------]│[2:-----------]| - [4:--------------------]│[2:-----------]| - [4:--------------------]│[2:-----------]| - [4:--------------------]│[2:-----------]| - [4:--------------------]│[2:-----------]| - [4:--------------------]│[2:-----------]| + [4:--------------------]│[2:-----------]|*6 {4:[No Name] [+] }{3:<Name] [+] }| [3:--------------------------------]| ## grid 2 aaa aab aac| | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 :vsplit | ## grid 4 aaa aab aac | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ]]} + {1:~ }|*4 + ]], + } else screen:expect([[ aaa aab aac │aaa aab aac| ^ │ | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*4 {4:[No Name] [+] }{3:<Name] [+] }| :vsplit | ]]) @@ -1861,39 +1789,31 @@ describe('builtin popupmenu', function() feed('ibbb a<c-x><c-n>') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [4:--------------------]│[2:-----------]| - [4:--------------------]│[2:-----------]| - [4:--------------------]│[2:-----------]| - [4:--------------------]│[2:-----------]| - [4:--------------------]│[2:-----------]| - [4:--------------------]│[2:-----------]| + [4:--------------------]│[2:-----------]|*6 {4:[No Name] [+] }{3:<Name] [+] }| [3:--------------------------------]| ## grid 2 aaa aab aac| bbb aaa | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 {2:-- }{5:match 1 of 3} | ## grid 4 aaa aab aac | bbb aaa^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 5 {s: aaa }| {n: aab }| {n: aac }| - ]], float_pos={ - [5] = {{id = -1}, "NW", 4, 2, 3, false, 100}; - }} + ]], + float_pos = { + [5] = { -1, 'NW', 4, 2, 3, false, 100 }, + }, + } else screen:expect([[ aaa aab aac │aaa aab aac| @@ -1909,39 +1829,33 @@ describe('builtin popupmenu', function() feed('<esc><c-w><c-w>oc a<c-x><c-n>') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [4:-----------]│[2:--------------------]| - [4:-----------]│[2:--------------------]| - [4:-----------]│[2:--------------------]| - [4:-----------]│[2:--------------------]| - [4:-----------]│[2:--------------------]| - [4:-----------]│[2:--------------------]| + [4:-----------]│[2:--------------------]|*6 {3:<Name] [+] }{4:[No Name] [+] }| [3:--------------------------------]| ## grid 2 aaa aab aac | bbb aaa | c aaa^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 {2:-- }{5:match 1 of 3} | ## grid 4 aaa aab aac| bbb aaa | c aaa | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 5 {s: aaa }| {n: aab }| {n: aac }| - ]], float_pos={ - [5] = {{id = -1}, "NW", 2, 3, 1, false, 100}; - }} + ]], + float_pos = { + [5] = { -1, 'NW', 2, 3, 1, false, 100 }, + }, + } else screen:expect([[ aaa aab aac│aaa aab aac | @@ -1957,23 +1871,17 @@ describe('builtin popupmenu', function() feed('bcdef ccc a<c-x><c-n>') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [4:-----------]│[2:--------------------]| - [4:-----------]│[2:--------------------]| - [4:-----------]│[2:--------------------]| - [4:-----------]│[2:--------------------]| - [4:-----------]│[2:--------------------]| - [4:-----------]│[2:--------------------]| + [4:-----------]│[2:--------------------]|*6 {3:<Name] [+] }{4:[No Name] [+] }| [3:--------------------------------]| ## grid 2 aaa aab aac | bbb aaa | c aaabcdef ccc aaa^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 ## grid 3 {2:-- }{5:match 1 of 4} | ## grid 4 @@ -1981,16 +1889,17 @@ describe('builtin popupmenu', function() bbb aaa | c aaabcdef | ccc aaa | - {1:~ }| - {1:~ }| + {1:~ }|*2 ## grid 5 {s: aaa }| {n: aab }| {n: aac }| {n: aaabcdef}| - ]], float_pos={ - [5] = {{id = -1}, "NW", 2, 3, 11, false, 100}; - }} + ]], + float_pos = { + [5] = { -1, 'NW', 2, 3, 11, false, 100 }, + }, + } else screen:expect([[ aaa aab aac│aaa aab aac | @@ -2006,14 +1915,10 @@ describe('builtin popupmenu', function() feed('\n<c-x><c-n>') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [4:-----------]│[2:--------------------]| - [4:-----------]│[2:--------------------]| - [4:-----------]│[2:--------------------]| - [4:-----------]│[2:--------------------]| - [4:-----------]│[2:--------------------]| - [4:-----------]│[2:--------------------]| + [4:-----------]│[2:--------------------]|*6 {3:<Name] [+] }{4:[No Name] [+] }| [3:--------------------------------]| ## grid 2 @@ -2021,8 +1926,7 @@ describe('builtin popupmenu', function() bbb aaa | c aaabcdef ccc aaa | aaa^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 ## grid 3 {2:-- }{5:match 1 of 6} | ## grid 4 @@ -2036,9 +1940,11 @@ describe('builtin popupmenu', function() {s: aaa }{c: }| {n: aab }{s: }| {n: aac }{s: }| - ]], float_pos={ - [5] = {{id = -1}, "NW", 2, 4, -1, false, 100}; - }} + ]], + float_pos = { + [5] = { -1, 'NW', 2, 4, -1, false, 100 }, + }, + } else screen:expect([[ aaa aab aac│aaa aab aac | @@ -2055,10 +1961,10 @@ describe('builtin popupmenu', function() if not multigrid then it('with split and scroll', function() - screen:try_resize(60,14) - command("split") - command("set completeopt+=noinsert") - command("set mouse=a") + screen:try_resize(60, 14) + command('split') + command('set completeopt+=noinsert') + command('set mouse=a') insert([[ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor @@ -2108,7 +2014,7 @@ describe('builtin popupmenu', function() {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | ]]) - meths.input_mouse('wheel', 'down', '', 0, 9, 40) + api.nvim_input_mouse('wheel', 'down', '', 0, 9, 40) screen:expect([[ Est ^ | L{n: sunt }{s: }sit amet, consectetur | @@ -2144,7 +2050,7 @@ describe('builtin popupmenu', function() {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | ]]) - meths.input_mouse('wheel', 'up', '', 0, 9, 40) + api.nvim_input_mouse('wheel', 'up', '', 0, 9, 40) screen:expect([[ Est e^ | L{n: elit } sit amet, consectetur | @@ -2180,7 +2086,7 @@ describe('builtin popupmenu', function() {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | ]]) - meths.input_mouse('wheel', 'down', '', 0, 9, 40) + api.nvim_input_mouse('wheel', 'down', '', 0, 9, 40) screen:expect([[ Est es^ | L{n: esse } sit amet, consectetur | @@ -2234,7 +2140,7 @@ describe('builtin popupmenu', function() {2:-- Keyword Local completion (^N^P) }{5:match 22 of 65} | ]]) - meths.input_mouse('wheel', 'down', '', 0, 9, 40) + api.nvim_input_mouse('wheel', 'down', '', 0, 9, 40) screen:expect([[ Est eu^ | L{n: elit } sit amet, consectetur | @@ -2252,7 +2158,7 @@ describe('builtin popupmenu', function() {2:-- Keyword Local completion (^N^P) }{5:match 22 of 65} | ]]) - funcs.complete(4, {'ea', 'eeeeeeeeeeeeeeeeee', 'ei', 'eo', 'eu', 'ey', 'eå', 'eä', 'eö'}) + fn.complete(4, { 'ea', 'eeeeeeeeeeeeeeeeee', 'ei', 'eo', 'eu', 'ey', 'eå', 'eä', 'eö' }) screen:expect([[ Est eu^ | {s: ea }t amet, consectetur | @@ -2270,7 +2176,7 @@ describe('builtin popupmenu', function() {2:-- Keyword Local completion (^N^P) }{5:match 1 of 9} | ]]) - funcs.complete(4, {'ea', 'eee', 'ei', 'eo', 'eu', 'ey', 'eå', 'eä', 'eö'}) + fn.complete(4, { 'ea', 'eee', 'ei', 'eo', 'eu', 'ey', 'eå', 'eä', 'eö' }) screen:expect([[ Est eu^ | {s: ea }r sit amet, consectetur | @@ -2306,7 +2212,7 @@ describe('builtin popupmenu', function() {2:-- INSERT --} | ]]) - funcs.complete(6, {'foo', 'bar'}) + fn.complete(6, { 'foo', 'bar' }) screen:expect([[ Esteee^ | Lo{s: foo }sit amet, consectetur | @@ -2345,29 +2251,16 @@ describe('builtin popupmenu', function() it('can be moved due to wrap or resize', function() feed('isome long prefix before the ') - command("set completeopt+=noinsert,noselect") - command("set linebreak") - funcs.complete(29, {'word', 'choice', 'text', 'thing'}) + command('set completeopt+=noinsert,noselect') + command('set linebreak') + fn.complete(29, { 'word', 'choice', 'text', 'thing' }) screen:expect([[ some long prefix before the ^ | {1:~ }{n: word }| {1:~ }{n: choice}| {1:~ }{n: text }| {1:~ }{n: thing }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*14 {2:-- INSERT --} | ]]) @@ -2379,19 +2272,7 @@ describe('builtin popupmenu', function() {n:choice }{1: }| {n:text }{1: }| {s:thing }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*13 {2:-- INSERT --} | ]]) @@ -2402,24 +2283,11 @@ describe('builtin popupmenu', function() {1:~ }{n: choice}| {1:~ }{s: text }| {1:~ }{n: thing }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*14 {2:-- INSERT --} | ]]) - screen:try_resize(30,8) + screen:try_resize(30, 8) screen:expect([[ some long prefix before the | text^ | @@ -2431,19 +2299,18 @@ describe('builtin popupmenu', function() {2:-- INSERT --} | ]]) - screen:try_resize(50,8) + screen:try_resize(50, 8) screen:expect([[ some long prefix before the text^ | {1:~ }{n: word }{1: }| {1:~ }{n: choice }{1: }| {1:~ }{s: text }{1: }| {1:~ }{n: thing }{1: }| - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:-- INSERT --} | ]]) - screen:try_resize(25,10) + screen:try_resize(25, 10) screen:expect([[ some long prefix before | the text^ | @@ -2451,13 +2318,11 @@ describe('builtin popupmenu', function() {1:~ }{n: choice }{1: }| {1:~ }{s: text }{1: }| {1:~ }{n: thing }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2:-- INSERT --} | ]]) - screen:try_resize(12,5) + screen:try_resize(12, 5) screen:expect([[ some long | prefix | @@ -2467,14 +2332,14 @@ describe('builtin popupmenu', function() ]]) -- can't draw the pum, but check we don't crash - screen:try_resize(12,2) + screen:try_resize(12, 2) screen:expect([[ {1:<<<}t^ | {2:-- INSERT --}| ]]) -- but state is preserved, pum reappears - screen:try_resize(20,8) + screen:try_resize(20, 8) screen:expect([[ some long prefix | before the text^ | @@ -2489,34 +2354,21 @@ describe('builtin popupmenu', function() it('with VimResized autocmd', function() feed('isome long prefix before the ') - command("set completeopt+=noinsert,noselect") - command("autocmd VimResized * redraw!") - command("set linebreak") - funcs.complete(29, {'word', 'choice', 'text', 'thing'}) + command('set completeopt+=noinsert,noselect') + command('autocmd VimResized * redraw!') + command('set linebreak') + fn.complete(29, { 'word', 'choice', 'text', 'thing' }) screen:expect([[ some long prefix before the ^ | {1:~ }{n: word }| {1:~ }{n: choice}| {1:~ }{n: text }| {1:~ }{n: thing }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*14 {2:-- INSERT --} | ]]) - screen:try_resize(16,10) + screen:try_resize(16, 10) screen:expect([[ some long | prefix before | @@ -2525,60 +2377,29 @@ describe('builtin popupmenu', function() {1:~ }{n: choice }| {1:~ }{n: text }| {1:~ }{n: thing }| - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:-- INSERT --} | ]]) end) it('with rightleft window', function() - command("set rl wildoptions+=pum") + command('set rl wildoptions+=pum') feed('isome rightleft ') screen:expect([[ ^ tfelthgir emos| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*18 {2:-- INSERT --} | ]]) - command("set completeopt+=noinsert,noselect") - funcs.complete(16, {'word', 'choice', 'text', 'thing'}) + command('set completeopt+=noinsert,noselect') + fn.complete(16, { 'word', 'choice', 'text', 'thing' }) screen:expect([[ ^ tfelthgir emos| {1: }{n: drow }{1: ~}| {1: }{n: eciohc }{1: ~}| {1: }{n: txet }{1: ~}| {1: }{n: gniht }{1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*14 {2:-- INSERT --} | ]]) @@ -2589,87 +2410,32 @@ describe('builtin popupmenu', function() {1: }{n: eciohc }{1: ~}| {1: }{n: txet }{1: ~}| {1: }{n: gniht }{1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*14 {2:-- INSERT --} | ]]) feed('<c-y>') screen:expect([[ ^ drow tfelthgir emos| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*18 {2:-- INSERT --} | ]]) -- not rightleft on the cmdline feed('<esc>:sign ') - screen:expect{grid=[[ + screen:expect { + grid = [[ drow tfelthgir emos| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*18 :sign ^ | - ]]} + ]], + } feed('<tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ drow tfelthgir emos| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*12 {1: }{s: define }{1: ~}| {1: }{n: jump }{1: ~}| {1: }{n: list }{1: ~}| @@ -2677,7 +2443,8 @@ describe('builtin popupmenu', function() {1: }{n: undefine }{1: ~}| {1: }{n: unplace }{1: ~}| :sign define^ | - ]]} + ]], + } end) end @@ -2688,34 +2455,30 @@ describe('builtin popupmenu', function() command('set completeopt+=noinsert,noselect') command('set pumheight=2') feed('isome rightleft ') - funcs.complete(16, {'word', 'choice', 'text', 'thing'}) + fn.complete(16, { 'word', 'choice', 'text', 'thing' }) if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]|*4 {3:[No Name] [+] }{4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 tfelthgir emos| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*3 ## grid 3 {2:-- INSERT --} | ## grid 4 ^ tfelthgir emos| - {1: ~}| - {1: ~}| - {1: ~}| + {1: ~}|*3 ## grid 5 {c: }{n: drow }| {s: }{n: eciohc }| - ]], float_pos={ - [5] = {{id = -1}, "NW", 4, 1, -11, false, 100}; - }} + ]], + float_pos = { + [5] = { -1, 'NW', 4, 1, -11, false, 100 }, + }, + } else screen:expect([[ tfelthgir emos│ ^ tfelthgir emos| @@ -2727,34 +2490,32 @@ describe('builtin popupmenu', function() ]]) end feed('<C-E><CR>') - funcs.complete(1, {'word', 'choice', 'text', 'thing'}) + fn.complete(1, { 'word', 'choice', 'text', 'thing' }) if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]|*4 {3:[No Name] [+] }{4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 tfelthgir emos| | - {1: ~}| - {1: ~}| + {1: ~}|*2 ## grid 3 {2:-- INSERT --} | ## grid 4 tfelthgir emos| ^ | - {1: ~}| - {1: ~}| + {1: ~}|*2 ## grid 5 {c: }{n: drow}| {s: }{n: eciohc}| - ]], float_pos={ - [5] = {{id = -1}, "NW", 4, 2, 4, false, 100}; - }} + ]], + float_pos = { + [5] = { -1, 'NW', 4, 2, 4, false, 100 }, + }, + } else screen:expect([[ tfelthgir emos│ tfelthgir emos| @@ -2766,35 +2527,31 @@ describe('builtin popupmenu', function() ]]) end feed('<C-E>') - async_meths.call_function('input', {'', '', 'sign'}) + async_meths.nvim_call_function('input', { '', '', 'sign' }) if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]|*4 {3:[No Name] [+] }{4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 tfelthgir emos| | - {1: ~}| - {1: ~}| + {1: ~}|*2 ## grid 3 ^ | ## grid 4 tfelthgir emos| | - {1: ~}| - {1: ~}| - ]]} + {1: ~}|*2 + ]], + } else screen:expect([[ tfelthgir emos│ tfelthgir emos| │ | - {1: ~}│{1: ~}| - {1: ~}│{1: ~}| + {1: ~}│{1: ~}|*2 {3:[No Name] [+] }{4:[No Name] [+] }| ^ | ]]) @@ -2802,32 +2559,30 @@ describe('builtin popupmenu', function() command('set wildoptions+=pum') feed('<Tab>') if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]|*4 {3:[No Name] [+] }{4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 tfelthgir emos| | - {1: ~}| - {1: ~}| + {1: ~}|*2 ## grid 3 define^ | ## grid 4 tfelthgir emos| | - {1: ~}| - {1: ~}| + {1: ~}|*2 ## grid 5 {s:define }{c: }| {n:jump }{s: }| - ]], float_pos={ - [5] = {{id = -1}, "SW", 1, 5, 0, false, 250}; - }} + ]], + float_pos = { + [5] = { -1, 'SW', 1, 5, 0, false, 250 }, + }, + } else screen:expect([[ tfelthgir emos│ tfelthgir emos| @@ -2842,10 +2597,10 @@ describe('builtin popupmenu', function() if not multigrid then it('with multiline messages', function() - screen:try_resize(40,8) + screen:try_resize(40, 8) feed('ixx<cr>') command('imap <f2> <cmd>echoerr "very"\\|echoerr "much"\\|echoerr "error"<cr>') - funcs.complete(1, {'word', 'choice', 'text', 'thing'}) + fn.complete(1, { 'word', 'choice', 'text', 'thing' }) screen:expect([[ xx | word^ | @@ -2893,7 +2648,7 @@ describe('builtin popupmenu', function() {2:-- INSERT --} | ]]) - command("split") + command('split') screen:expect([[ xx | choice^ | @@ -2905,8 +2660,9 @@ describe('builtin popupmenu', function() {2:-- INSERT --} | ]]) - meths.input_mouse('wheel', 'down', '', 0, 6, 15) - screen:expect{grid=[[ + api.nvim_input_mouse('wheel', 'down', '', 0, 6, 15) + screen:expect { + grid = [[ xx | choice^ | {n:word }{1: }| @@ -2915,21 +2671,25 @@ describe('builtin popupmenu', function() {n:thing }{1: }| {3:[No Name] [+] }| {2:-- INSERT --} | - ]], unchanged=true} + ]], + unchanged = true, + } end) it('with kind, menu and abbr attributes', function() - screen:try_resize(40,8) + screen:try_resize(40, 8) feed('ixx ') - funcs.complete(4, {{word='wordey', kind= 'x', menu='extrainfo'}, 'thing', {word='secret', abbr='sneaky', menu='bar'}}) + fn.complete(4, { + { word = 'wordey', kind = 'x', menu = 'extrainfo' }, + 'thing', + { word = 'secret', abbr = 'sneaky', menu = 'bar' }, + }) screen:expect([[ xx wordey^ | {1:~ }{s: wordey x extrainfo }{1: }| {1:~ }{n: thing }{1: }| {1:~ }{n: sneaky bar }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2:-- INSERT --} | ]]) @@ -2939,9 +2699,7 @@ describe('builtin popupmenu', function() {1:~ }{n: wordey x extrainfo }{1: }| {1:~ }{n: thing }{1: }| {1:~ }{n: sneaky bar }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2:-- INSERT --} | ]]) @@ -2951,51 +2709,36 @@ describe('builtin popupmenu', function() {1:~ }{n: wordey x extrainfo }{1: }| {1:~ }{n: thing }{1: }| {1:~ }{s: sneaky bar }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2:-- INSERT --} | ]]) feed('<esc>') screen:expect([[ xx secre^t | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 | ]]) end) it('wildoptions=pum', function() - screen:try_resize(32,10) + screen:try_resize(32, 10) command('set wildmenu') command('set wildoptions=pum') command('set shellslash') - command("cd test/functional/fixtures/wildpum") + command('cd test/functional/fixtures/wildpum') feed(':sign ') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 :sign ^ | ]]) feed('<Tab>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{s: define }{1: }| {1:~ }{n: jump }{1: }| {1:~ }{n: list }{1: }| @@ -3008,8 +2751,7 @@ describe('builtin popupmenu', function() feed('<Right><Right>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{n: define }{1: }| {1:~ }{n: jump }{1: }| {1:~ }{s: list }{1: }| @@ -3022,8 +2764,7 @@ describe('builtin popupmenu', function() feed('<C-N>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{n: define }{1: }| {1:~ }{n: jump }{1: }| {1:~ }{n: list }{1: }| @@ -3036,8 +2777,7 @@ describe('builtin popupmenu', function() feed('<C-P>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{n: define }{1: }| {1:~ }{n: jump }{1: }| {1:~ }{s: list }{1: }| @@ -3050,8 +2790,7 @@ describe('builtin popupmenu', function() feed('<Left>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{n: define }{1: }| {1:~ }{s: jump }{1: }| {1:~ }{n: list }{1: }| @@ -3065,14 +2804,7 @@ describe('builtin popupmenu', function() feed('<C-E>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 :sign ^ | ]]) @@ -3080,14 +2812,7 @@ describe('builtin popupmenu', function() feed('<Tab><C-P><C-P><C-Y>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 :sign unplace^ | ]]) @@ -3095,8 +2820,7 @@ describe('builtin popupmenu', function() feed('<C-U>sign define <Tab>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{s: culhl= }{1: }| {1:~ }{n: icon= }{1: }| {1:~ }{n: linehl= }{1: }| @@ -3109,8 +2833,7 @@ describe('builtin popupmenu', function() feed('<Space><Tab>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{s: culhl= }{1: }| {1:~ }{n: icon= }{1: }| {1:~ }{n: linehl= }{1: }| @@ -3123,12 +2846,7 @@ describe('builtin popupmenu', function() feed('<C-U>e Xnamedi<Tab><Tab>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 {1:~ }{s: XdirA/ }{1: }| {1:~ }{n: XfileA }{1: }| :e Xnamedir/XdirA/^ | @@ -3138,12 +2856,7 @@ describe('builtin popupmenu', function() feed('<Down>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 {1:~ }{s: XdirB/ }{1: }| {1:~ }{n: XfileB }{1: }| :e Xnamedir/XdirA/XdirB/^ | @@ -3153,12 +2866,7 @@ describe('builtin popupmenu', function() feed('<Up>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 {1:~ }{s: XdirA/ }{1: }| {1:~ }{n: XfileA }{1: }| :e Xnamedir/XdirA/^ | @@ -3169,12 +2877,7 @@ describe('builtin popupmenu', function() feed(':<C-U>sign <Tab><C-A>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 {4: }| :sign define jump list place und| efine unplace^ | @@ -3184,12 +2887,7 @@ describe('builtin popupmenu', function() feed('<Left>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 {4: }| :sign define jump list place und| efine unplac^e | @@ -3201,11 +2899,7 @@ describe('builtin popupmenu', function() feed('<C-U>sign <Tab><C-D>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4: }| :sign define | define | @@ -3216,8 +2910,7 @@ describe('builtin popupmenu', function() feed('<C-U><CR>:sign <S-Tab><C-P>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{n: define }{1: }| {1:~ }{n: jump }{1: }| {1:~ }{n: list }{1: }| @@ -3231,14 +2924,7 @@ describe('builtin popupmenu', function() feed('<C-U><CR>:sign <Tab><Esc>') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 | ]]) @@ -3246,14 +2932,7 @@ describe('builtin popupmenu', function() feed(':sign <Tab>x') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 :sign definex^ | ]]) @@ -3264,10 +2943,7 @@ describe('builtin popupmenu', function() {3:[No Name] }| {1::}sign define | {1::}sign defin^e | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {4:[Command Line] }| :sign define | ]]) @@ -3277,12 +2953,7 @@ describe('builtin popupmenu', function() feed(':sign u<Tab><C-N><C-N>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 {1:~ }{n: undefine }{1: }| {1:~ }{n: unplace }{1: }| :sign u^ | @@ -3292,10 +2963,7 @@ describe('builtin popupmenu', function() feed('<C-U>bu<Tab>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {s: bufdo }{1: }| {n: buffer }{1: }| {n: buffers }{1: }| @@ -3307,14 +2975,7 @@ describe('builtin popupmenu', function() feed('<C-E><C-U>sign <Tab><BS>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 :sign defin^ | ]]) @@ -3322,14 +2983,7 @@ describe('builtin popupmenu', function() feed('<C-E><C-U>sign <Tab><C-W>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 :sign ^ | ]]) @@ -3337,14 +2991,7 @@ describe('builtin popupmenu', function() feed('<C-E><C-U>sign <Tab><C-U>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 :^ | ]]) @@ -3353,14 +3000,7 @@ describe('builtin popupmenu', function() feed('sign xyz<Esc>:sign <Tab><C-E><Up>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 :sign xyz^ | ]]) @@ -3371,9 +3011,7 @@ describe('builtin popupmenu', function() feed(':cn<Tab>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {4: }| :cn | cnewer cnoreabbrev | @@ -3384,9 +3022,7 @@ describe('builtin popupmenu', function() feed('s') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {4: }| :cn | cnewer cnoreabbrev | @@ -3402,11 +3038,7 @@ describe('builtin popupmenu', function() feed(':e あいう/<Tab>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {1:~ }{s: 123 }{1: }| {1:~ }{n: abc }{1: }| {1:~ }{n: xyz }{1: }| @@ -3418,8 +3050,7 @@ describe('builtin popupmenu', function() feed(':sign <Tab><PageDown>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{n: define }{1: }| {1:~ }{n: jump }{1: }| {1:~ }{n: list }{1: }| @@ -3431,8 +3062,7 @@ describe('builtin popupmenu', function() feed('<PageDown>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{n: define }{1: }| {1:~ }{n: jump }{1: }| {1:~ }{n: list }{1: }| @@ -3444,8 +3074,7 @@ describe('builtin popupmenu', function() feed('<PageDown>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{n: define }{1: }| {1:~ }{n: jump }{1: }| {1:~ }{n: list }{1: }| @@ -3457,8 +3086,7 @@ describe('builtin popupmenu', function() feed('<PageDown>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{s: define }{1: }| {1:~ }{n: jump }{1: }| {1:~ }{n: list }{1: }| @@ -3470,8 +3098,7 @@ describe('builtin popupmenu', function() feed('<C-U>sign <Tab><Right><Right><PageDown>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{n: define }{1: }| {1:~ }{n: jump }{1: }| {1:~ }{n: list }{1: }| @@ -3485,8 +3112,7 @@ describe('builtin popupmenu', function() feed('<C-U>sign <Tab><PageUp>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{n: define }{1: }| {1:~ }{n: jump }{1: }| {1:~ }{n: list }{1: }| @@ -3498,8 +3124,7 @@ describe('builtin popupmenu', function() feed('<PageUp>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{n: define }{1: }| {1:~ }{n: jump }{1: }| {1:~ }{n: list }{1: }| @@ -3511,8 +3136,7 @@ describe('builtin popupmenu', function() feed('<PageUp>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{n: define }{1: }| {1:~ }{s: jump }{1: }| {1:~ }{n: list }{1: }| @@ -3524,8 +3148,7 @@ describe('builtin popupmenu', function() feed('<PageUp>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{s: define }{1: }| {1:~ }{n: jump }{1: }| {1:~ }{n: list }{1: }| @@ -3539,12 +3162,7 @@ describe('builtin popupmenu', function() feed('<Esc>:set wildchazz<Left><Left><Tab>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 {1:~ }{s: wildchar }{1: }| {1:~ }{n: wildcharm }{1: }| :set wildchar^zz | @@ -3552,14 +3170,7 @@ describe('builtin popupmenu', function() feed('<C-E>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 :set wildcha^zz | ]]) @@ -3567,28 +3178,19 @@ describe('builtin popupmenu', function() feed('<Esc>:set wildchazz<Left><Left><Tab><C-Y>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 :set wildchar^zz | ]]) feed('<Esc>') -- check positioning with multibyte char in pattern - command("e långfile1") - command("sp långfile2") + command('e långfile1') + command('sp långfile2') feed(':b lå<tab>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {4:långfile2 }| | {1:~ }| @@ -3598,7 +3200,7 @@ describe('builtin popupmenu', function() ]]) -- check doesn't crash on screen resize - screen:try_resize(20,6) + screen:try_resize(20, 6) screen:expect([[ | {1:~ }| @@ -3608,20 +3210,13 @@ describe('builtin popupmenu', function() :b långfile1^ | ]]) - screen:try_resize(50,15) + screen:try_resize(50, 15) screen:expect([[ | {1:~ }| {4:långfile2 }| | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 {1:~ }{s: långfile1 }{1: }| {3:lå}{n: långfile2 }{3: }| :b långfile1^ | @@ -3636,21 +3231,14 @@ describe('builtin popupmenu', function() {1:~ }| {4:långfile2 }| | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 {1:~ }{n: långfile1 }{1: }| {3:lå}{n: långfile2 }{3: }| :b långfile^ | ]]) feed('<esc>') - command("close") + command('close') command('set wildmode=full') -- special case: when patterns ends with "/", show menu items aligned @@ -3658,17 +3246,7 @@ describe('builtin popupmenu', function() feed(':e compdir/<tab>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 {1:~ }{s: file1 }{1: }| {1:~ }{n: file2 }{1: }| :e compdir/file1^ | @@ -3676,29 +3254,27 @@ describe('builtin popupmenu', function() end) it('wildoptions=pum with scrolled messages', function() - screen:try_resize(40,10) + screen:try_resize(40, 10) command('set wildmenu') command('set wildoptions=pum') feed(':echoerr "fail"|echoerr "error"<cr>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4: }| {6:fail} | {6:error} | {5:Press ENTER or type command to continue}^ | - ]]} + ]], + } feed(':sign <tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{s: define }{1: }| {1:~ }{n: jump }{1: }| {1:~ }{n: list }{1: }| @@ -3706,25 +3282,24 @@ describe('builtin popupmenu', function() {6:fail} {n: undefine } | {6:error}{n: unplace } | :sign define^ | - ]]} + ]], + } feed('d') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4: }| {6:fail} | {6:error} | :sign defined^ | - ]]} + ]], + } end) it('wildoptions=pum and wildmode=longest,full #11622', function() - screen:try_resize(30,8) + screen:try_resize(30, 8) command('set wildmenu') command('set wildoptions=pum') command('set wildmode=longest,full') @@ -3732,56 +3307,49 @@ describe('builtin popupmenu', function() -- With 'wildmode' set to 'longest,full', completing a match should display -- the longest match, the wildmenu should not be displayed. feed(':sign u<Tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 :sign un^ | - ]]} - eq(0, funcs.wildmenumode()) + ]], + } + eq(0, fn.wildmenumode()) -- pressing <Tab> should display the wildmenu feed('<Tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {1:~ }{s: undefine }{1: }| {1:~ }{n: unplace }{1: }| :sign undefine^ | - ]]} - eq(1, funcs.wildmenumode()) + ]], + } + eq(1, fn.wildmenumode()) -- pressing <Tab> second time should select the next entry in the menu feed('<Tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {1:~ }{n: undefine }{1: }| {1:~ }{s: unplace }{1: }| :sign unplace^ | - ]]} + ]], + } end) it('wildoptions=pum with a wrapped line in buffer vim-patch:8.2.4655', function() screen:try_resize(32, 10) - meths.buf_set_lines(0, 0, -1, true, { ('a'):rep(100) }) + api.nvim_buf_set_lines(0, 0, -1, true, { ('a'):rep(100) }) command('set wildoptions+=pum') feed('$') feed(':sign <Tab>') screen:expect([[ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|*3 aaaa {s: define } | {1:~ }{n: jump }{1: }| {1:~ }{n: list }{1: }| @@ -3805,8 +3373,7 @@ describe('builtin popupmenu', function() feed(':sign <C-E>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{s: define }{1: }| {1:~ }{n: jump }{1: }| {1:~ }{n: list }{1: }| @@ -3820,8 +3387,7 @@ describe('builtin popupmenu', function() feed('<C-E>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{n: define }{1: }| {1:~ }{s: jump }{1: }| {1:~ }{n: list }{1: }| @@ -3834,14 +3400,7 @@ describe('builtin popupmenu', function() feed('<Esc>') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 | ]]) @@ -3851,8 +3410,7 @@ describe('builtin popupmenu', function() feed(':sign <Esc>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{s: define }{1: }| {1:~ }{n: jump }{1: }| {1:~ }{n: list }{1: }| @@ -3865,14 +3423,7 @@ describe('builtin popupmenu', function() feed('<Esc>') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 | ]]) @@ -3882,8 +3433,7 @@ describe('builtin popupmenu', function() feed([[:sign <C-\><C-\>]]) screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{s: define }{1: }| {1:~ }{n: jump }{1: }| {1:~ }{n: list }{1: }| @@ -3896,93 +3446,65 @@ describe('builtin popupmenu', function() feed('<C-N>') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*8 | ]]) end) end it("'pumheight'", function() - screen:try_resize(32,8) + screen:try_resize(32, 8) feed('isome long prefix before the ') - command("set completeopt+=noinsert,noselect") - command("set linebreak") - command("set pumheight=2") - funcs.complete(29, {'word', 'choice', 'text', 'thing'}) + command('set completeopt+=noinsert,noselect') + command('set linebreak') + command('set pumheight=2') + fn.complete(29, { 'word', 'choice', 'text', 'thing' }) if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*7 [3:--------------------------------]| ## grid 2 some long prefix before the ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 ## grid 3 {2:-- INSERT --} | ## grid 4 {n: word }{c: }| {n: choice}{s: }| - ]], float_pos={ - [4] = {{id = -1}, "NW", 2, 1, 24, false, 100}; - }} + ]], + float_pos = { + [4] = { -1, 'NW', 2, 1, 24, false, 100 }, + }, + } else screen:expect([[ some long prefix before the ^ | {1:~ }{n: word }{c: }| {1:~ }{n: choice}{s: }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {2:-- INSERT --} | ]]) end end) it("'pumwidth'", function() - screen:try_resize(32,8) + screen:try_resize(32, 8) feed('isome long prefix before the ') - command("set completeopt+=noinsert,noselect") - command("set linebreak") - command("set pumwidth=8") - funcs.complete(29, {'word', 'choice', 'text', 'thing'}) + command('set completeopt+=noinsert,noselect') + command('set linebreak') + command('set pumwidth=8') + fn.complete(29, { 'word', 'choice', 'text', 'thing' }) if multigrid then - screen:expect{grid=[[ + screen:expect { + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*7 [3:--------------------------------]| ## grid 2 some long prefix before the ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 ## grid 3 {2:-- INSERT --} | ## grid 4 @@ -3990,9 +3512,11 @@ describe('builtin popupmenu', function() {n: choice}| {n: text }| {n: thing }| - ]], float_pos={ - [4] = {{id = -1}, "NW", 2, 1, 25, false, 100}; - }} + ]], + float_pos = { + [4] = { -1, 'NW', 2, 1, 25, false, 100 }, + }, + } else screen:expect([[ some long prefix before the ^ | @@ -4000,8 +3524,7 @@ describe('builtin popupmenu', function() {1:~ }{n: choice}| {1:~ }{n: text }| {1:~ }{n: thing }| - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:-- INSERT --} | ]]) end @@ -4009,16 +3532,16 @@ describe('builtin popupmenu', function() it('does not crash when displayed in the last column with rightleft #12032', function() local col = 30 - local items = {'word', 'choice', 'text', 'thing'} + local items = { 'word', 'choice', 'text', 'thing' } local max_len = 0 for _, v in ipairs(items) do max_len = max_len < #v and #v or max_len end screen:try_resize(col, 8) command('set rightleft') - command('call setline(1, repeat(" ", &columns - '..max_len..'))') + command('call setline(1, repeat(" ", &columns - ' .. max_len .. '))') feed('$i') - funcs.complete(col - max_len, items) + fn.complete(col - max_len, items) feed('<c-y>') assert_alive() end) @@ -4027,91 +3550,66 @@ describe('builtin popupmenu', function() screen:try_resize(32, 8) command('set completeopt+=menuone,noselect') feed('i' .. string.rep(' ', 13)) - funcs.complete(14, {'哦哦哦哦哦哦哦哦哦哦'}) + fn.complete(14, { '哦哦哦哦哦哦哦哦哦哦' }) if multigrid then - screen:expect({grid=[[ + screen:expect({ + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*7 [3:--------------------------------]| ## grid 2 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 ## grid 3 {2:-- INSERT --} | ## grid 4 {n: 哦哦哦哦哦哦哦哦哦>}| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 12, false, 100}}}) + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 12, false, 100 } }, + }) else screen:expect([[ ^ | {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {2:-- INSERT --} | ]]) end end) it('truncates double-width character correctly with scrollbar', function() - screen:try_resize(32,8) + screen:try_resize(32, 8) command('set completeopt+=noselect') command('set pumheight=4') feed('i' .. string.rep(' ', 12)) local items = {} for _ = 1, 8 do - table.insert(items, {word = '哦哦哦哦哦哦哦哦哦哦', equal = 1, dup = 1}) + table.insert(items, { word = '哦哦哦哦哦哦哦哦哦哦', equal = 1, dup = 1 }) end - funcs.complete(13, items) + fn.complete(13, items) if multigrid then - screen:expect({grid=[[ + screen:expect({ + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*7 [3:--------------------------------]| ## grid 2 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 ## grid 3 {2:-- INSERT --} | ## grid 4 - {n: 哦哦哦哦哦哦哦哦哦>}{c: }| - {n: 哦哦哦哦哦哦哦哦哦>}{c: }| - {n: 哦哦哦哦哦哦哦哦哦>}{s: }| - {n: 哦哦哦哦哦哦哦哦哦>}{s: }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 11, false, 100}}}) + {n: 哦哦哦哦哦哦哦哦哦>}{c: }|*2 + {n: 哦哦哦哦哦哦哦哦哦>}{s: }|*2 + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 11, false, 100 } }, + }) else screen:expect([[ ^ | - {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{c: }| - {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{c: }| - {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{s: }| - {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{s: }| - {1:~ }| - {1:~ }| + {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{c: }|*2 + {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{s: }|*2 + {1:~ }|*2 {2:-- INSERT --} | ]]) end @@ -4130,28 +3628,24 @@ describe('builtin popupmenu', function() ]]) if multigrid then - meths.input_mouse('right', 'press', '', 2, 0, 4) - screen:expect({grid=[[ + api.nvim_input_mouse('right', 'press', '', 2, 0, 4) + screen:expect({ + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*5 [3:--------------------------------]| ## grid 2 ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ## grid 4 {n: foo }| {n: bar }| {n: baz }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 3, false, 250 } }, + }) else feed('<RightMouse><4,0>') screen:expect([[ @@ -4165,27 +3659,23 @@ describe('builtin popupmenu', function() end feed('<Down>') if multigrid then - screen:expect({grid=[[ + screen:expect({ + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*5 [3:--------------------------------]| ## grid 2 ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ## grid 4 {s: foo }| {n: bar }| {n: baz }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 3, false, 250 } }, + }) else screen:expect([[ ^popup menu test | @@ -4198,27 +3688,23 @@ describe('builtin popupmenu', function() end feed('<Down>') if multigrid then - screen:expect({grid=[[ + screen:expect({ + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*5 [3:--------------------------------]| ## grid 2 ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 | ## grid 4 {n: foo }| {s: bar }| {n: baz }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 3, false, 250 } }, + }) else screen:expect([[ ^popup menu test | @@ -4231,124 +3717,158 @@ describe('builtin popupmenu', function() end feed('<CR>') if multigrid then - screen:expect({grid=[[ + screen:expect({ + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*5 [3:--------------------------------]| ## grid 2 ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 :let g:menustr = 'bar' | - ]]}) + ]], + }) else screen:expect([[ ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 :let g:menustr = 'bar' | ]]) end - eq('bar', meths.get_var('menustr')) + eq('bar', api.nvim_get_var('menustr')) if multigrid then - meths.input_mouse('right', 'press', '', 2, 2, 20) - screen:expect({grid=[[ + api.nvim_input_mouse('right', 'press', '', 2, 2, 20) + screen:expect({ + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*5 [3:--------------------------------]| ## grid 2 ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 :let g:menustr = 'bar' | ## grid 4 {n: foo }| {n: bar }| {n: baz }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 3, 19, false, 250}}}) + ]], + float_pos = { [4] = { -1, 'NW', 2, 3, 19, false, 250 } }, + }) else feed('<RightMouse><20,2>') screen:expect([[ ^popup menu test | - {1:~ }| - {1:~ }| + {1:~ }|*2 {1:~ }{n: foo }{1: }| {1:~ }{n: bar }{1: }| :let g:menustr = 'b{n: baz } | ]]) end if multigrid then - meths.input_mouse('left', 'press', '', 4, 2, 2) - screen:expect({grid=[[ + api.nvim_input_mouse('right', 'press', '', 2, 0, 18) + screen:expect { + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*5 [3:--------------------------------]| ## grid 2 ^popup menu test | + {1:~ }|*4 + ## grid 3 + :let g:menustr = 'bar' | + ## grid 4 + {n: foo }| + {n: bar }| + {n: baz }| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 17, false, 250 } }, + } + else + feed('<RightMouse><18,0>') + screen:expect([[ + ^popup menu test | + {1:~ }{n: foo }{1: }| + {1:~ }{n: bar }{1: }| + {1:~ }{n: baz }{1: }| {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + :let g:menustr = 'bar' | + ]]) + end + if multigrid then + api.nvim_input_mouse('right', 'press', '', 4, 1, 3) + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*5 + [3:--------------------------------]| + ## grid 2 + ^popup menu test | + {1:~ }|*4 + ## grid 3 + :let g:menustr = 'bar' | + ## grid 4 + {n: foo }| + {n: bar }| + {n: baz }| + ]], + float_pos = { [4] = { -1, 'NW', 2, 3, 19, false, 250 } }, + }) + else + feed('<RightMouse><20,2>') + screen:expect([[ + ^popup menu test | + {1:~ }|*2 + {1:~ }{n: foo }{1: }| + {1:~ }{n: bar }{1: }| + :let g:menustr = 'b{n: baz } | + ]]) + end + if multigrid then + api.nvim_input_mouse('left', 'press', '', 4, 2, 2) + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*5 + [3:--------------------------------]| + ## grid 2 + ^popup menu test | + {1:~ }|*4 ## grid 3 :let g:menustr = 'baz' | - ]]}) + ]], + }) else - feed('<LeftMouse><22,5>') + feed('<LeftMouse><21,5>') screen:expect([[ ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 :let g:menustr = 'baz' | ]]) end - eq('baz', meths.get_var('menustr')) + eq('baz', api.nvim_get_var('menustr')) if multigrid then - meths.input_mouse('right', 'press', '', 2, 0, 4) - screen:expect({grid=[[ + api.nvim_input_mouse('right', 'press', '', 2, 0, 4) + screen:expect({ + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*5 [3:--------------------------------]| ## grid 2 ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 :let g:menustr = 'baz' | ## grid 4 {n: foo }| {n: bar }| {n: baz }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 3, false, 250 } }, + }) else feed('<RightMouse><4,0>') screen:expect([[ @@ -4361,28 +3881,24 @@ describe('builtin popupmenu', function() ]]) end if multigrid then - meths.input_mouse('right', 'drag', '', 2, 3, 6) - screen:expect({grid=[[ + api.nvim_input_mouse('right', 'drag', '', 2, 3, 6) + screen:expect({ + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*5 [3:--------------------------------]| ## grid 2 ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 :let g:menustr = 'baz' | ## grid 4 {n: foo }| {n: bar }| {s: baz }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 3, false, 250 } }, + }) else feed('<RightDrag><6,3>') screen:expect([[ @@ -4395,61 +3911,49 @@ describe('builtin popupmenu', function() ]]) end if multigrid then - meths.input_mouse('right', 'release', '', 2, 1, 6) - screen:expect({grid=[[ + api.nvim_input_mouse('right', 'release', '', 2, 1, 6) + screen:expect({ + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*5 [3:--------------------------------]| ## grid 2 ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 :let g:menustr = 'foo' | - ]]}) + ]], + }) else feed('<RightRelease><6,1>') screen:expect([[ ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 :let g:menustr = 'foo' | ]]) end - eq('foo', meths.get_var('menustr')) + eq('foo', api.nvim_get_var('menustr')) eq(false, screen.options.mousemoveevent) if multigrid then - meths.input_mouse('right', 'press', '', 2, 0, 4) - screen:expect({grid=[[ + api.nvim_input_mouse('right', 'press', '', 2, 0, 4) + screen:expect({ + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*5 [3:--------------------------------]| ## grid 2 ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 ## grid 3 :let g:menustr = 'foo' | ## grid 4 {n: foo }| {n: bar }| {n: baz }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 3, false, 250 } }, + }) else feed('<RightMouse><4,0>') screen:expect([[ @@ -4463,28 +3967,55 @@ describe('builtin popupmenu', function() end eq(true, screen.options.mousemoveevent) if multigrid then - meths.input_mouse('move', '', '', 2, 3, 6) - screen:expect({grid=[[ + api.nvim_input_mouse('wheel', 'up', '', 2, 0, 4) + screen:expect({ + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*5 [3:--------------------------------]| ## grid 2 ^popup menu test | + {1:~ }|*4 + ## grid 3 + :let g:menustr = 'foo' | + ## grid 4 + {s: foo }| + {n: bar }| + {n: baz }| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 3, false, 250 } }, + }) + else + feed('<ScrollWheelUp><4,0>') + screen:expect([[ + ^popup menu test | + {1:~ }{s: foo }{1: }| + {1:~ }{n: bar }{1: }| + {1:~ }{n: baz }{1: }| {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + :let g:menustr = 'foo' | + ]]) + end + eq(true, screen.options.mousemoveevent) + if multigrid then + api.nvim_input_mouse('move', '', '', 4, 2, 3) + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*5 + [3:--------------------------------]| + ## grid 2 + ^popup menu test | + {1:~ }|*4 ## grid 3 :let g:menustr = 'foo' | ## grid 4 {n: foo }| {n: bar }| {s: baz }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 3, false, 250 } }, + }) else feed('<MouseMove><6,3>') screen:expect([[ @@ -4498,48 +4029,70 @@ describe('builtin popupmenu', function() end eq(true, screen.options.mousemoveevent) if multigrid then - meths.input_mouse('left', 'press', '', 2, 2, 6) - screen:expect({grid=[[ + api.nvim_input_mouse('wheel', 'down', '', 4, 2, 3) + screen:expect({ + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*5 [3:--------------------------------]| ## grid 2 ^popup menu test | + {1:~ }|*4 + ## grid 3 + :let g:menustr = 'foo' | + ## grid 4 + {n: foo }| + {s: bar }| + {n: baz }| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 3, false, 250 } }, + }) + else + feed('<ScrollWheelDown><6,3>') + screen:expect([[ + ^popup menu test | + {1:~ }{n: foo }{1: }| + {1:~ }{s: bar }{1: }| + {1:~ }{n: baz }{1: }| {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + :let g:menustr = 'foo' | + ]]) + end + eq(true, screen.options.mousemoveevent) + if multigrid then + api.nvim_input_mouse('left', 'press', '', 4, 1, 3) + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*5 + [3:--------------------------------]| + ## grid 2 + ^popup menu test | + {1:~ }|*4 ## grid 3 :let g:menustr = 'bar' | - ]]}) + ]], + }) else feed('<LeftMouse><6,2>') screen:expect([[ ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 :let g:menustr = 'bar' | ]]) end eq(false, screen.options.mousemoveevent) - eq('bar', meths.get_var('menustr')) + eq('bar', api.nvim_get_var('menustr')) command('set laststatus=0 | botright split') if multigrid then - meths.input_mouse('right', 'press', '', 5, 1, 20) - screen:expect({grid=[[ + api.nvim_input_mouse('right', 'press', '', 5, 1, 20) + screen:expect({ + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*2 {3:[No Name] [+] }| - [5:--------------------------------]| - [5:--------------------------------]| + [5:--------------------------------]|*2 [3:--------------------------------]| ## grid 2 popup menu test | @@ -4553,7 +4106,9 @@ describe('builtin popupmenu', function() ## grid 5 ^popup menu test | {1:~ }| - ]], float_pos={[4] = {{id = -1}, "SW", 5, 1, 19, false, 250}}}) + ]], + float_pos = { [4] = { -1, 'SW', 5, 1, 19, false, 250 } }, + }) else feed('<RightMouse><20,4>') screen:expect([[ @@ -4566,14 +4121,13 @@ describe('builtin popupmenu', function() ]]) end if multigrid then - meths.input_mouse('left', 'press', '', 4, 2, 2) - screen:expect({grid=[[ + api.nvim_input_mouse('left', 'press', '', 4, 2, 2) + screen:expect({ + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*2 {3:[No Name] [+] }| - [5:--------------------------------]| - [5:--------------------------------]| + [5:--------------------------------]|*2 [3:--------------------------------]| ## grid 2 popup menu test | @@ -4583,9 +4137,10 @@ describe('builtin popupmenu', function() ## grid 5 ^popup menu test | {1:~ }| - ]]}) + ]], + }) else - feed('<LeftMouse><22,3>') + feed('<LeftMouse><21,3>') screen:expect([[ popup menu test | {1:~ }| @@ -4595,18 +4150,17 @@ describe('builtin popupmenu', function() :let g:menustr = 'baz' | ]]) end - eq('baz', meths.get_var('menustr')) + eq('baz', api.nvim_get_var('menustr')) command('set winwidth=1 | rightbelow vsplit') if multigrid then - meths.input_mouse('right', 'press', '', 6, 1, 14) - screen:expect({grid=[[ + api.nvim_input_mouse('right', 'press', '', 6, 1, 14) + screen:expect({ + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*2 {3:[No Name] [+] }| - [5:---------------]│[6:----------------]| - [5:---------------]│[6:----------------]| + [5:---------------]│[6:----------------]|*2 [3:--------------------------------]| ## grid 2 popup menu test | @@ -4623,7 +4177,9 @@ describe('builtin popupmenu', function() ## grid 6 ^popup menu test | {1:~ }| - ]], float_pos={[4] = {{id = -1}, "SW", 6, 1, 12, false, 250}}}) + ]], + float_pos = { [4] = { -1, 'SW', 6, 1, 12, false, 250 } }, + }) else feed('<RightMouse><30,4>') screen:expect([[ @@ -4636,14 +4192,13 @@ describe('builtin popupmenu', function() ]]) end if multigrid then - meths.input_mouse('left', 'press', '', 4, 0, 2) - screen:expect({grid=[[ + api.nvim_input_mouse('left', 'press', '', 4, 0, 2) + screen:expect({ + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*2 {3:[No Name] [+] }| - [5:---------------]│[6:----------------]| - [5:---------------]│[6:----------------]| + [5:---------------]│[6:----------------]|*2 [3:--------------------------------]| ## grid 2 popup menu test | @@ -4656,7 +4211,8 @@ describe('builtin popupmenu', function() ## grid 6 ^popup menu test | {1:~ }| - ]]}) + ]], + }) else feed('<LeftMouse><31,1>') screen:expect([[ @@ -4668,18 +4224,17 @@ describe('builtin popupmenu', function() :let g:menustr = 'foo' | ]]) end - eq('foo', meths.get_var('menustr')) + eq('foo', api.nvim_get_var('menustr')) command('setlocal winbar=WINBAR') if multigrid then - meths.input_mouse('right', 'press', '', 6, 1, 14) - screen:expect({grid=[[ + api.nvim_input_mouse('right', 'press', '', 6, 1, 14) + screen:expect({ + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*2 {3:[No Name] [+] }| - [5:---------------]│[6:----------------]| - [5:---------------]│[6:----------------]| + [5:---------------]│[6:----------------]|*2 [3:--------------------------------]| ## grid 2 popup menu test | @@ -4696,7 +4251,9 @@ describe('builtin popupmenu', function() ## grid 6 {2:WINBAR }| ^popup menu test | - ]], float_pos={[4] = {{id = -1}, "SW", 6, 1, 12, false, 250}}}) + ]], + float_pos = { [4] = { -1, 'SW', 6, 1, 12, false, 250 } }, + }) else feed('<RightMouse><30,4>') screen:expect([[ @@ -4709,14 +4266,13 @@ describe('builtin popupmenu', function() ]]) end if multigrid then - meths.input_mouse('left', 'press', '', 4, 1, 2) - screen:expect({grid=[[ + api.nvim_input_mouse('left', 'press', '', 4, 1, 2) + screen:expect({ + grid = [[ ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| + [2:--------------------------------]|*2 {3:[No Name] [+] }| - [5:---------------]│[6:----------------]| - [5:---------------]│[6:----------------]| + [5:---------------]│[6:----------------]|*2 [3:--------------------------------]| ## grid 2 popup menu test | @@ -4729,7 +4285,8 @@ describe('builtin popupmenu', function() ## grid 6 {2:WINBAR }| ^popup menu test | - ]]}) + ]], + }) else feed('<LeftMouse><31,2>') screen:expect([[ @@ -4741,7 +4298,7 @@ describe('builtin popupmenu', function() :let g:menustr = 'bar' | ]]) end - eq('bar', meths.get_var('menustr')) + eq('bar', api.nvim_get_var('menustr')) end) if not multigrid then @@ -4779,13 +4336,7 @@ describe('builtin popupmenu', function() {1:~ }{n: Select Line }{1: }| {1:~ }{n: Select Block }{1: }| {1:~ }{n: Select All }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*7 :popup PopUp | ]]) @@ -4804,13 +4355,7 @@ describe('builtin popupmenu', function() {1:~ }{n: Select Line }{1: }| {1:~ }{n: Select Block }{1: }| {1:~ }{n: Select All }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*7 :popup PopUp | ]]) @@ -4829,13 +4374,7 @@ describe('builtin popupmenu', function() {1:~ }{n: Select Line }{1: }| {1:~ }{n: Select Block }{1: }| {1:~ }{n: Select All }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*7 :popup PopUp | ]]) @@ -4859,13 +4398,7 @@ describe('builtin popupmenu', function() {1:~ }{n: Select Line }{1: }| {1:~ }{n: Select Block }{1: }| {1:~ }{n: Select All }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*7 changed | ]]) @@ -4875,22 +4408,7 @@ describe('builtin popupmenu', function() one two three four five | and one two {7:^X}three four five | one more two three four five | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*16 pasted | ]]) @@ -4911,12 +4429,7 @@ describe('builtin popupmenu', function() {1:~ }{n: Select Line }{1: }| {1:~ }{n: Select Block }{1: }| {1:~ }{n: Select All }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*6 :popup PopUp | ]]) @@ -4951,9 +4464,7 @@ describe('builtin popupmenu', function() {s:aword1 W extra text 1 }{1: }| {n:aword2 W extra text 2 }{1: }| {n:aword3 W extra text 3 }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2:-- }{5:match 1 of 3} | ]]) end) @@ -4967,21 +4478,22 @@ describe('builtin popupmenu', function() hi PmenuExtraSel guifg=Black guibg=Grey ]]) local attrs = screen:get_default_attr_ids() - attrs.kn = {foreground = Screen.colors.Red, background = Screen.colors.Magenta} - attrs.ks = {foreground = Screen.colors.Red, background = Screen.colors.Grey} - attrs.xn = {foreground = Screen.colors.White, background = Screen.colors.Magenta} - attrs.xs = {foreground = Screen.colors.Black, background = Screen.colors.Grey} + attrs.kn = { foreground = Screen.colors.Red, background = Screen.colors.Magenta } + attrs.ks = { foreground = Screen.colors.Red, background = Screen.colors.Grey } + attrs.xn = { foreground = Screen.colors.White, background = Screen.colors.Magenta } + attrs.xs = { foreground = Screen.colors.Black, background = Screen.colors.Grey } feed('iaw<C-X><C-u>') - screen:expect([[ + screen:expect( + [[ aword1^ | {s:aword1 }{ks:W }{xs:extra text 1 }{1: }| {n:aword2 }{kn:W }{xn:extra text 2 }{1: }| {n:aword3 }{kn:W }{xn:extra text 3 }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 {2:-- }{5:match 1 of 3} | - ]], attrs) + ]], + attrs + ) end) end) end diff --git a/test/functional/ui/quickfix_spec.lua b/test/functional/ui/quickfix_spec.lua index df43871e60..40f8ef353a 100644 --- a/test/functional/ui/quickfix_spec.lua +++ b/test/functional/ui/quickfix_spec.lua @@ -1,9 +1,8 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local clear, feed, meths = helpers.clear, helpers.feed, helpers.meths +local clear, feed, api = helpers.clear, helpers.feed, helpers.api local insert, command = helpers.insert, helpers.command - describe('quickfix selection highlight', function() local screen @@ -14,20 +13,20 @@ describe('quickfix selection highlight', function() screen:attach() screen:set_default_attr_ids({ [1] = { bold = true, foreground = Screen.colors.Blue }, - [2] = {reverse = true}, - [3] = {foreground = Screen.colors.Brown}, - [4] = {bold = true, reverse = true}, - [5] = {background = Screen.colors.Green}, - [6] = {foreground = Screen.colors.Brown, background = Screen.colors.Green}, - [7] = {background = Screen.colors.Red}, - [8] = {foreground = Screen.colors.Brown, background = Screen.colors.Red}, - [9] = {background = Screen.colors.Fuchsia}, - [10] = {foreground = Screen.colors.Red, background = Screen.colors.Fuchsia}, - [11] = {foreground = Screen.colors.Red}, - [12] = {foreground = Screen.colors.Brown, background = Screen.colors.Fuchsia}, + [2] = { reverse = true }, + [3] = { foreground = Screen.colors.Brown }, + [4] = { bold = true, reverse = true }, + [5] = { background = Screen.colors.Green }, + [6] = { foreground = Screen.colors.Brown, background = Screen.colors.Green }, + [7] = { background = Screen.colors.Red }, + [8] = { foreground = Screen.colors.Brown, background = Screen.colors.Red }, + [9] = { background = Screen.colors.Fuchsia }, + [10] = { foreground = Screen.colors.Red, background = Screen.colors.Fuchsia }, + [11] = { foreground = Screen.colors.Red }, + [12] = { foreground = Screen.colors.Brown, background = Screen.colors.Fuchsia }, }) - meths.set_option_value('errorformat', '%m %l', {}) + api.nvim_set_option_value('errorformat', '%m %l', {}) command('syntax on') command('highlight Search guibg=Green') @@ -49,9 +48,7 @@ describe('quickfix selection highlight', function() Line 4 | Line 5 | | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]) end) @@ -89,7 +86,7 @@ describe('quickfix selection highlight', function() end) it('using QuickFixLine highlight group', function() - command('highlight QuickFixLine guibg=Red') + command('highlight QuickFixLine guibg=Red guifg=NONE gui=NONE') command('copen') @@ -124,7 +121,7 @@ describe('quickfix selection highlight', function() it('combines with CursorLine', function() command('set cursorline') - command('highlight QuickFixLine guifg=Red') + command('highlight QuickFixLine guifg=Red guibg=NONE gui=NONE') command('highlight CursorLine guibg=Fuchsia') command('copen') @@ -160,7 +157,7 @@ describe('quickfix selection highlight', function() it('QuickFixLine background takes precedence over CursorLine', function() command('set cursorline') - command('highlight QuickFixLine guibg=Red') + command('highlight QuickFixLine guibg=Red guifg=NONE gui=NONE') command('highlight CursorLine guibg=Fuchsia') command('copen') diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua index 810a68d387..e8d7d5c72d 100644 --- a/test/functional/ui/screen.lua +++ b/test/functional/ui/screen.lua @@ -72,23 +72,44 @@ local helpers = require('test.functional.helpers')(nil) local busted = require('busted') -local deepcopy = helpers.deepcopy +local deepcopy = vim.deepcopy local shallowcopy = helpers.shallowcopy local concat_tables = helpers.concat_tables -local pesc = helpers.pesc +local pesc = vim.pesc local run_session = helpers.run_session local eq = helpers.eq local dedent = helpers.dedent local get_session = helpers.get_session local create_callindex = helpers.create_callindex -local inspect = require('vim.inspect') +local inspect = vim.inspect local function isempty(v) return type(v) == 'table' and next(v) == nil end +--- @class test.functional.ui.screen.Grid +--- @field rows table[][] +--- @field width integer +--- @field height integer + --- @class test.functional.ui.screen +--- @field colors table<string,integer> +--- @field colornames table<integer,string> +--- @field uimeths table<string,function> +--- @field options? table<string,any> +--- @field timeout integer +--- @field win_position table<integer,table<string,integer>> +--- @field float_pos table<integer,table> +--- @field cmdline table<integer,table> +--- @field cmdline_block table[] +--- @field hl_groups table<string,integer> +--- @field messages table<integer,table> +--- @field private _cursor {grid:integer,row:integer,col:integer} +--- @field private _grids table<integer,test.functional.ui.screen.Grid> +--- @field private _grid_win_extmarks table<integer,table> +--- @field private _attr_table table<integer,table> +--- @field private _hl_info table<integer,table> local Screen = {} Screen.__index = Screen @@ -103,13 +124,14 @@ end local default_screen_timeout = default_timeout_factor * 3500 -function Screen._init_colors(session) +local function _init_colors() + local session = get_session() local status, rv = session:request('nvim_get_color_map') if not status then error('failed to get color map') end - local colors = rv - local colornames = {} + local colors = rv --- @type table<string,integer> + local colornames = {} --- @type table<integer,string> for name, rgb in pairs(colors) do -- we disregard the case that colornames might not be unique, as -- this is just a helper to get any canonical name of a color @@ -119,17 +141,14 @@ function Screen._init_colors(session) Screen.colornames = colornames end +--- @param width? integer +--- @param height? integer +--- @return test.functional.ui.screen function Screen.new(width, height) if not Screen.colors then - Screen._init_colors(get_session()) + _init_colors() end - if not width then - width = 53 - end - if not height then - height = 14 - end local self = setmetatable({ timeout = default_screen_timeout, title = '', @@ -140,6 +159,7 @@ function Screen.new(width, height) suspended = false, mode = 'normal', options = {}, + pwd = '', popupmenu = nil, cmdline = {}, cmdline_block = {}, @@ -161,30 +181,35 @@ function Screen.new(width, height) _default_attr_ids = nil, mouse_enabled = true, _attrs = {}, - _hl_info = {[0]={}}, - _attr_table = {[0]={{},{}}}, + _hl_info = { [0] = {} }, + _attr_table = { [0] = { {}, {} } }, _clear_attrs = nil, _new_attrs = false, - _width = width, - _height = height, + _width = width or 53, + _height = height or 14, _grids = {}, _grid_win_extmarks = {}, _cursor = { - grid = 1, row = 1, col = 1 + grid = 1, + row = 1, + col = 1, }, _busy = false, }, Screen) + local function ui(method, ...) if self.rpc_async then - self._session:notify('nvim_ui_'..method, ...) + self._session:notify('nvim_ui_' .. method, ...) else - local status, rv = self._session:request('nvim_ui_'..method, ...) + local status, rv = self._session:request('nvim_ui_' .. method, ...) if not status then error(rv[2]) end end end + self.uimeths = create_callindex(ui) + return self end @@ -200,13 +225,21 @@ function Screen:set_rgb_cterm(val) self._rgb_cterm = val end +--- @class test.functional.ui.screen.Opts +--- @field ext_linegrid? boolean +--- @field ext_multigrid? boolean +--- @field ext_newgrid? boolean +--- @field ext_popupmenu? boolean +--- @field ext_wildmenu? boolean +--- @field rgb? boolean +--- @field _debug_float? boolean + +--- @param options test.functional.ui.screen.Opts +--- @param session? test.Session function Screen:attach(options, session) - if session == nil then - session = get_session() - end - if options == nil then - options = {} - end + session = session or get_session() + options = options or {} + if options.ext_linegrid == nil then options.ext_linegrid = true end @@ -241,106 +274,178 @@ function Screen:try_resize_grid(grid, columns, rows) self.uimeths.try_resize_grid(grid, columns, rows) end +--- @param option 'ext_linegrid'|'ext_multigrid'|'ext_popupmenu'|'ext_wildmenu'|'rgb' +--- @param value boolean function Screen:set_option(option, value) self.uimeths.set_option(option, value) + --- @diagnostic disable-next-line:no-unknown self._options[option] = value end -- canonical order of ext keys, used to generate asserts local ext_keys = { - 'popupmenu', 'cmdline', 'cmdline_block', 'wildmenu_items', 'wildmenu_pos', - 'messages', 'msg_history', 'showmode', 'showcmd', 'ruler', 'float_pos', 'win_viewport' + 'popupmenu', + 'cmdline', + 'cmdline_block', + 'wildmenu_items', + 'wildmenu_pos', + 'messages', + 'msg_history', + 'showmode', + 'showcmd', + 'ruler', + 'float_pos', + 'win_viewport', } --- Asserts that the screen state eventually matches an expected state. --- --- Can be called with positional args: --- screen:expect(grid, [attr_ids]) --- screen:expect(condition) --- or keyword args (supports more options): --- screen:expect{grid=[[...]], cmdline={...}, condition=function() ... end} --- --- --- grid: Expected screen state (string). Each line represents a screen --- row. Last character of each row (typically "|") is stripped. --- Common indentation is stripped. --- "{MATCH:x}" in a line is matched against Lua pattern `x`. --- attr_ids: Expected text attributes. Screen rows are transformed according --- to this table, as follows: each substring S composed of --- characters having the same attributes will be substituted by --- "{K:S}", where K is a key in `attr_ids`. Any unexpected --- attributes in the final state are an error. --- Use screen:set_default_attr_ids() to define attributes for many --- expect() calls. --- extmarks: Expected win_extmarks accumulated for the grids. For each grid, --- the win_extmark messages are accumulated into an array. --- condition: Function asserting some arbitrary condition. Return value is --- ignored, throw an error (use eq() or similar) to signal failure. --- any: Lua pattern string expected to match a screen line. NB: the --- following chars are magic characters --- ( ) . % + - * ? [ ^ $ --- and must be escaped with a preceding % for a literal match. --- mode: Expected mode as signaled by "mode_change" event --- unchanged: Test that the screen state is unchanged since the previous --- expect(...). Any flush event resulting in a different state is --- considered an error. Not observing any events until timeout --- is acceptable. --- intermediate:Test that the final state is the same as the previous expect, --- but expect an intermediate state that is different. If possible --- it is better to use an explicit screen:expect(...) for this --- intermediate state. --- reset: Reset the state internal to the test Screen before starting to --- receive updates. This should be used after command("redraw!") --- or some other mechanism that will invoke "redraw!", to check --- that all screen state is transmitted again. This includes --- state related to ext_ features as mentioned below. --- timeout: maximum time that will be waited until the expected state is --- seen (or maximum time to observe an incorrect change when --- `unchanged` flag is used) --- --- The following keys should be used to expect the state of various ext_ --- features. Note that an absent key will assert that the item is currently --- NOT present on the screen, also when positional form is used. --- --- popupmenu: Expected ext_popupmenu state, --- cmdline: Expected ext_cmdline state, as an array of cmdlines of --- different level. --- cmdline_block: Expected ext_cmdline block (for function definitions) --- wildmenu_items: Expected items for ext_wildmenu --- wildmenu_pos: Expected position for ext_wildmenu +local expect_keys = { + grid = true, + attr_ids = true, + condition = true, + mouse_enabled = true, + any = true, + mode = true, + unchanged = true, + intermediate = true, + reset = true, + timeout = true, + request_cb = true, + hl_groups = true, + extmarks = true, +} + +for _, v in ipairs(ext_keys) do + expect_keys[v] = true +end + +--- @class test.function.ui.screen.Expect +--- +--- Expected screen state (string). Each line represents a screen +--- row. Last character of each row (typically "|") is stripped. +--- Common indentation is stripped. +--- "{MATCH:x}" in a line is matched against Lua pattern `x`. +--- "*n" at the end of a line means it repeats `n` times. +--- @field grid? string +--- +--- Expected text attributes. Screen rows are transformed according +--- to this table, as follows: each substring S composed of +--- characters having the same attributes will be substituted by +--- "{K:S}", where K is a key in `attr_ids`. Any unexpected +--- attributes in the final state are an error. +--- Use an empty table for a text-only (no attributes) expectation. +--- Use screen:set_default_attr_ids() to define attributes for many +--- expect() calls. +--- @field attr_ids? table<integer,table<string,any>> +--- +--- Expected win_extmarks accumulated for the grids. For each grid, +--- the win_extmark messages are accumulated into an array. +--- @field extmarks? table<integer,table> +--- +--- Function asserting some arbitrary condition. Return value is +--- ignored, throw an error (use eq() or similar) to signal failure. +--- @field condition? fun() +--- +--- Lua pattern string expected to match a screen line. NB: the +--- following chars are magic characters +--- ( ) . % + - * ? [ ^ $ +--- and must be escaped with a preceding % for a literal match. +--- @field any? string +--- +--- Expected mode as signaled by "mode_change" event +--- @field mode? string +--- +--- Test that the screen state is unchanged since the previous +--- expect(...). Any flush event resulting in a different state is +--- considered an error. Not observing any events until timeout +--- is acceptable. +--- @field unchanged? boolean +--- +--- Test that the final state is the same as the previous expect, +--- but expect an intermediate state that is different. If possible +--- it is better to use an explicit screen:expect(...) for this +--- intermediate state. +--- @field intermediate? boolean +--- +--- Reset the state internal to the test Screen before starting to +--- receive updates. This should be used after command("redraw!") +--- or some other mechanism that will invoke "redraw!", to check +--- that all screen state is transmitted again. This includes +--- state related to ext_ features as mentioned below. +--- @field reset? boolean +--- +--- maximum time that will be waited until the expected state is +--- seen (or maximum time to observe an incorrect change when +--- `unchanged` flag is used) +--- @field timeout? integer +--- +--- @field mouse_enabled? boolean +--- +--- @field win_viewport? table<integer,table<string,integer>> +--- @field float_pos? {[1]:integer,[2]:integer} +--- @field hl_groups? table<string,integer> +--- +--- The following keys should be used to expect the state of various ext_ +--- features. Note that an absent key will assert that the item is currently +--- NOT present on the screen, also when positional form is used. +--- +--- Expected ext_popupmenu state, +--- @field popupmenu? table +--- +--- Expected ext_cmdline state, as an array of cmdlines of +--- different level. +--- @field cmdline? table +--- +--- Expected ext_cmdline block (for function definitions) +--- @field cmdline_block? table +--- +--- items for ext_wildmenu +--- @field wildmenu_items? table +--- +--- position for ext_wildmenu +--- @field wildmenu_pos? table + +--- Asserts that the screen state eventually matches an expected state. +--- +--- Can be called with positional args: +--- screen:expect(grid, [attr_ids]) +--- screen:expect(condition) +--- or keyword args (supports more options): +--- screen:expect{grid=[[...]], cmdline={...}, condition=function() ... end} +--- +--- @param expected string|function|test.function.ui.screen.Expect +--- @param attr_ids? table<integer,table<string,any>> function Screen:expect(expected, attr_ids, ...) - local grid, condition = nil, nil - local expected_rows = {} - assert(next({...}) == nil, "invalid args to expect()") - if type(expected) == "table" then - assert(not (attr_ids ~= nil)) - local is_key = {grid=true, attr_ids=true, condition=true, mouse_enabled=true, - any=true, mode=true, unchanged=true, intermediate=true, - reset=true, timeout=true, request_cb=true, hl_groups=true, extmarks=true} - for _, v in ipairs(ext_keys) do - is_key[v] = true - end - for k, _ in pairs(expected) do - if not is_key[k] then - error("Screen:expect: Unknown keyword argument '"..k.."'") + --- @type string, fun() + local grid, condition + + assert(next({ ... }) == nil, 'invalid args to expect()') + + if type(expected) == 'table' then + assert(attr_ids == nil) + for k, _ in + pairs(expected --[[@as table<string,any>]]) + do + if not expect_keys[k] then + error("Screen:expect: Unknown keyword argument '" .. k .. "'") end end grid = expected.grid attr_ids = expected.attr_ids condition = expected.condition - assert(not (expected.any ~= nil and grid ~= nil)) - elseif type(expected) == "string" then + assert(expected.any == nil or grid == nil) + elseif type(expected) == 'string' then grid = expected expected = {} - elseif type(expected) == "function" then - assert(not (attr_ids ~= nil)) + elseif type(expected) == 'function' then + assert(attr_ids == nil) condition = expected expected = {} else assert(false) end - if grid ~= nil then + local expected_rows = {} --- @type string[] + if grid then -- Remove the last line and dedent. Note that gsub returns more then one -- value. grid = dedent(grid:gsub('\n[ ]+$', ''), 0) @@ -348,15 +453,23 @@ function Screen:expect(expected, attr_ids, ...) table.insert(expected_rows, row) end end + local attr_state = { - ids = attr_ids or self._default_attr_ids, + ids = attr_ids or self._default_attr_ids, } + + if isempty(attr_ids) then + attr_state.ids = nil + end + if self._options.ext_linegrid then attr_state.id_to_index = self:linegrid_check_attrs(attr_state.ids or {}) end + self._new_attrs = false self:_wait(function() - if condition ~= nil then + if condition then + --- @type boolean, string local status, res = pcall(condition) if not status then return tostring(res) @@ -369,27 +482,47 @@ function Screen:expect(expected, attr_ids, ...) local actual_rows = self:render(not expected.any, attr_state) - if expected.any ~= nil then + if expected.any then -- Search for `any` anywhere in the screen lines. local actual_screen_str = table.concat(actual_rows, '\n') - if nil == string.find(actual_screen_str, expected.any) then + if not actual_screen_str:find(expected.any) then return ( 'Failed to match any screen lines.\n' - .. 'Expected (anywhere): "' .. expected.any .. '"\n' - .. 'Actual:\n |' .. table.concat(actual_rows, '\n |') .. '\n\n') + .. 'Expected (anywhere): "' + .. expected.any + .. '"\n' + .. 'Actual:\n |' + .. table.concat(actual_rows, '\n |') + .. '\n\n' + ) end end - if grid ~= nil then - local err_msg, msg_expected_rows = nil, {} + if grid then + for i, row in ipairs(expected_rows) do + local count --- @type integer? + row, count = row:match('^(.*%|)%*(%d+)$') + if row then + count = tonumber(count) + table.remove(expected_rows, i) + for _ = 1, count do + table.insert(expected_rows, i, row) + end + end + end + local err_msg = nil -- `expected` must match the screen lines exactly. if #actual_rows ~= #expected_rows then - err_msg = "Expected screen height " .. #expected_rows - .. ' differs from actual height ' .. #actual_rows .. '.' + err_msg = 'Expected screen height ' + .. #expected_rows + .. ' differs from actual height ' + .. #actual_rows + .. '.' end + local msg_expected_rows = shallowcopy(expected_rows) + local msg_actual_rows = shallowcopy(actual_rows) for i, row in ipairs(expected_rows) do - msg_expected_rows[i] = row - local pat = nil + local pat = nil --- @type string? if actual_rows[i] and row ~= actual_rows[i] then local after = row while true do @@ -398,6 +531,7 @@ function Screen:expect(expected, attr_ids, ...) pat = pat and (pat .. pesc(after)) break end + --- @type string pat = (pat or '') .. pesc(after:sub(1, s - 1)) .. m after = after:sub(e + 1) end @@ -405,7 +539,7 @@ function Screen:expect(expected, attr_ids, ...) if row ~= actual_rows[i] and (not pat or not actual_rows[i]:match(pat)) then msg_expected_rows[i] = '*' .. msg_expected_rows[i] if i <= #actual_rows then - actual_rows[i] = '*' .. actual_rows[i] + msg_actual_rows[i] = '*' .. msg_actual_rows[i] end if err_msg == nil then err_msg = 'Row ' .. tostring(i) .. ' did not match.' @@ -414,11 +548,18 @@ function Screen:expect(expected, attr_ids, ...) end if err_msg ~= nil then return ( - err_msg..'\nExpected:\n |'..table.concat(msg_expected_rows, '\n |')..'\n' - ..'Actual:\n |'..table.concat(actual_rows, '\n |')..'\n\n'..[[ + err_msg + .. '\nExpected:\n |' + .. table.concat(msg_expected_rows, '\n |') + .. '\n' + .. 'Actual:\n |' + .. table.concat(msg_actual_rows, '\n |') + .. '\n\n' + .. [[ To print the expect() call that would assert the current screen state, use screen:snapshot_util(). In case of non-deterministic failures, use -screen:redraw_debug() to show all intermediate screen states. ]]) +screen:redraw_debug() to show all intermediate screen states.]] + ) end end @@ -447,12 +588,18 @@ screen:redraw_debug() to show all intermediate screen states. ]]) end -- Convert assertion errors into invalid screen state descriptions. - for _, k in ipairs(concat_tables(ext_keys, {'mode', 'mouse_enabled'})) do + for _, k in ipairs(concat_tables(ext_keys, { 'mode', 'mouse_enabled' })) do -- Empty states are considered the default and need not be mentioned. - if (not (expected[k] == nil and isempty(extstate[k]))) then + if not (expected[k] == nil and isempty(extstate[k])) then local status, res = pcall(eq, expected[k], extstate[k], k) if not status then - return (tostring(res)..'\nHint: full state of "'..k..'":\n '..inspect(extstate[k])) + return ( + tostring(res) + .. '\nHint: full state of "' + .. k + .. '":\n ' + .. inspect(extstate[k]) + ) end end end @@ -461,7 +608,7 @@ screen:redraw_debug() to show all intermediate screen states. ]]) for name, id in pairs(expected.hl_groups) do local expected_hl = attr_state.ids[id] local actual_hl = self._attr_table[self.hl_groups[name]][(self._options.rgb and 1) or 2] - local status, res = pcall(eq, expected_hl, actual_hl, "highlight "..name) + local status, res = pcall(eq, expected_hl, actual_hl, 'highlight ' .. name) if not status then return tostring(res) end @@ -472,9 +619,10 @@ screen:redraw_debug() to show all intermediate screen states. ]]) for gridid, expected_marks in pairs(expected.extmarks) do local stored_marks = self._grid_win_extmarks[gridid] if stored_marks == nil then - return 'no win_extmark for grid '..tostring(gridid) + return 'no win_extmark for grid ' .. tostring(gridid) end - local status, res = pcall(eq, expected_marks, stored_marks, "extmarks for grid "..tostring(gridid)) + local status, res = + pcall(eq, expected_marks, stored_marks, 'extmarks for grid ' .. tostring(gridid)) if not status then return tostring(res) end @@ -482,7 +630,7 @@ screen:redraw_debug() to show all intermediate screen states. ]]) for gridid, _ in pairs(self._grid_win_extmarks) do local expected_marks = expected.extmarks[gridid] if expected_marks == nil then - return 'unexpected win_extmark for grid '..tostring(gridid) + return 'unexpected win_extmark for grid ' .. tostring(gridid) end end end @@ -490,7 +638,6 @@ screen:redraw_debug() to show all intermediate screen states. ]]) end function Screen:expect_unchanged(intermediate, waittime_ms, ignore_attrs) - waittime_ms = waittime_ms and waittime_ms or 100 -- Collect the current screen state. local kwargs = self:get_snapshot(nil, ignore_attrs) @@ -505,8 +652,12 @@ function Screen:expect_unchanged(intermediate, waittime_ms, ignore_attrs) self:expect(kwargs) end +--- @private +--- @param check fun(): string +--- @param flags table<string,any> function Screen:_wait(check, flags) - local err, checked = false, false + local err --- @type string? + local checked = false local success_seen = false local failure_after_success = false local did_flush = true @@ -537,16 +688,18 @@ function Screen:_wait(check, flags) -- For an "unchanged" test, flags.timeout is the time during which the state -- must not change, so always wait this full time. - if (flags.unchanged or flags.intermediate) and flags.timeout ~= nil then - minimal_timeout = timeout + if flags.unchanged then + minimal_timeout = flags.timeout or default_timeout_factor * 20 end assert(timeout >= minimal_timeout) local did_minimal_timeout = false local function notification_cb(method, args) - assert(method == 'redraw', string.format( - 'notification_cb: unexpected method (%s, args=%s)', method, inspect(args))) + assert( + method == 'redraw', + string.format('notification_cb: unexpected method (%s, args=%s)', method, inspect(args)) + ) did_flush = self:_redraw(args) if not did_flush then return @@ -557,12 +710,12 @@ function Screen:_wait(check, flags) intermediate_seen = true end - if not err then + if not err and (not flags.intermediate or intermediate_seen) then success_seen = true if did_minimal_timeout then self._session:stop() end - elseif success_seen and #args > 0 then + elseif err and success_seen and #args > 0 then success_seen = false failure_after_success = true -- print(inspect(args)) @@ -572,7 +725,7 @@ function Screen:_wait(check, flags) end local eof = run_session(self._session, flags.request_cb, notification_cb, nil, minimal_timeout) if not did_flush then - err = "no flush received" + err = 'no flush received' elseif not checked then err = check() if not err and flags.unchanged then @@ -583,12 +736,13 @@ function Screen:_wait(check, flags) if not success_seen and not eof then did_minimal_timeout = true - eof = run_session(self._session, flags.request_cb, notification_cb, nil, timeout-minimal_timeout) + eof = + run_session(self._session, flags.request_cb, notification_cb, nil, timeout - minimal_timeout) end local did_warn = false if warn_immediate and immediate_seen then - print([[ + print([[ warning: Screen test succeeded immediately. Try to avoid this unless the purpose of the test really requires it.]]) @@ -622,21 +776,24 @@ between asynchronous (feed(), nvim_input()) and synchronous API calls. did_warn = true end - if err then - if eof then err = err..'\n\n'..eof[2] end - busted.fail(err, 3) + if eof then + err = err .. '\n\n' .. eof[2] + end + busted.fail(err .. '\n\nSnapshot:\n' .. self:_print_snapshot(), 3) elseif did_warn then - if eof then print(eof[2]) end + if eof then + print(eof[2]) + end local tb = debug.traceback() local index = string.find(tb, '\n%s*%[C]') - print(string.sub(tb,1,index)) + print(string.sub(tb, 1, index)) end if flags.intermediate then - assert(intermediate_seen, "expected intermediate screen state before final screen state") + assert(intermediate_seen, 'expected intermediate screen state before final screen state') elseif flags.unchanged then - assert(not intermediate_seen, "expected screen state to be unchanged") + assert(not intermediate_seen, 'expected screen state to be unchanged') end end @@ -648,23 +805,31 @@ function Screen:sleep(ms, request_cb) run_session(self._session, request_cb, notification_cb, nil, ms) end +--- @private +--- @param updates {[1]:string, [integer]:any[]}[] function Screen:_redraw(updates) local did_flush = false for k, update in ipairs(updates) do -- print('--', inspect(update)) local method = update[1] for i = 2, #update do - local handler_name = '_handle_'..method + local handler_name = '_handle_' .. method + --- @type function local handler = self[handler_name] - assert(handler ~= nil, "missing handler: Screen:"..handler_name) + assert(handler ~= nil, 'missing handler: Screen:' .. handler_name) local status, res = pcall(handler, self, unpack(update[i])) if not status then - error(handler_name..' failed' - ..'\n payload: '..inspect(update) - ..'\n error: '..tostring(res)) + error( + handler_name + .. ' failed' + .. '\n payload: ' + .. inspect(update) + .. '\n error: ' + .. tostring(res) + ) end end - if k == #updates and method == "flush" then + if k == #updates and method == 'flush' then did_flush = true end end @@ -674,12 +839,15 @@ end function Screen:_handle_resize(width, height) self:_handle_grid_resize(1, width, height) self._scroll_region = { - top = 1, bot = height, left = 1, right = width + top = 1, + bot = height, + left = 1, + right = width, } self._grid = self._grids[1] end -local function min(x,y) +local function min(x, y) if x < y then return x else @@ -692,14 +860,14 @@ function Screen:_handle_grid_resize(grid, width, height) for _ = 1, height do local cols = {} for _ = 1, width do - table.insert(cols, {text = ' ', attrs = self._clear_attrs, hl_id = 0}) + table.insert(cols, { text = ' ', attrs = self._clear_attrs, hl_id = 0 }) end table.insert(rows, cols) end if grid > 1 and self._grids[grid] ~= nil then local old = self._grids[grid] - for i = 1, min(height,old.height) do - for j = 1, min(width,old.width) do + for i = 1, min(height, old.height) do + for j = 1, min(width, old.width) do rows[i][j] = old.rows[i][j] end end @@ -710,13 +878,12 @@ function Screen:_handle_grid_resize(grid, width, height) self._cursor.col = 1 end self._grids[grid] = { - rows=rows, - width=width, - height=height, + rows = rows, + width = width, + height = height, } end - function Screen:_handle_msg_set_pos(grid, row, scrolled, char) self.msg_grid = grid self.msg_grid_pos = row @@ -724,8 +891,7 @@ function Screen:_handle_msg_set_pos(grid, row, scrolled, char) self.msg_sep_char = char end -function Screen:_handle_flush() -end +function Screen:_handle_flush() end function Screen:_reset() -- TODO: generalize to multigrid later @@ -740,18 +906,20 @@ function Screen:_reset() self._grid_win_extmarks = {} end +--- @param cursor_style_enabled boolean +--- @param mode_info table[] function Screen:_handle_mode_info_set(cursor_style_enabled, mode_info) self._cursor_style_enabled = cursor_style_enabled for _, item in pairs(mode_info) do - -- attr IDs are not stable, but their value should be - if item.attr_id ~= nil then - item.attr = self._attr_table[item.attr_id][1] - item.attr_id = nil - end - if item.attr_id_lm ~= nil then - item.attr_lm = self._attr_table[item.attr_id_lm][1] - item.attr_id_lm = nil - end + -- attr IDs are not stable, but their value should be + if item.attr_id ~= nil then + item.attr = self._attr_table[item.attr_id][1] + item.attr_id = nil + end + if item.attr_id_lm ~= nil then + item.attr_lm = self._attr_table[item.attr_id_lm][1] + item.attr_id_lm = nil + end end self._mode_info = mode_info end @@ -763,7 +931,10 @@ function Screen:_handle_clear() -- newer clients, to check we remain compatible with both kind of clients, -- ensure the scroll region is in a reset state. local expected_region = { - top = 1, bot = self._grid.height, left = 1, right = self._grid.width + top = 1, + bot = self._grid.height, + left = 1, + right = self._grid.width, } eq(expected_region, self._scroll_region) self:_handle_grid_clear(1) @@ -804,14 +975,24 @@ function Screen:_handle_win_pos(grid, win, startrow, startcol, width, height) startrow = startrow, startcol = startcol, width = width, - height = height + height = height, } self.float_pos[grid] = nil end -function Screen:_handle_win_viewport(grid, win, topline, botline, curline, curcol, linecount, scroll_delta) +function Screen:_handle_win_viewport( + grid, + win, + topline, + botline, + curline, + curcol, + linecount, + scroll_delta +) -- accumulate scroll delta - local last_scroll_delta = self.win_viewport[grid] and self.win_viewport[grid].sum_scroll_delta or 0 + local last_scroll_delta = self.win_viewport[grid] and self.win_viewport[grid].sum_scroll_delta + or 0 self.win_viewport[grid] = { win = win, topline = topline, @@ -819,18 +1000,18 @@ function Screen:_handle_win_viewport(grid, win, topline, botline, curline, curco curline = curline, curcol = curcol, linecount = linecount, - sum_scroll_delta = scroll_delta + last_scroll_delta + sum_scroll_delta = scroll_delta + last_scroll_delta, } end function Screen:_handle_win_float_pos(grid, ...) self.win_position[grid] = nil - self.float_pos[grid] = {...} + self.float_pos[grid] = { ... } end function Screen:_handle_win_external_pos(grid) self.win_position[grid] = nil - self.float_pos[grid] = {external=true} + self.float_pos[grid] = { external = true } end function Screen:_handle_win_hide(grid) @@ -846,7 +1027,7 @@ function Screen:_handle_win_extmark(grid, ...) if self._grid_win_extmarks[grid] == nil then self._grid_win_extmarks[grid] = {} end - table.insert(self._grid_win_extmarks[grid], {...}) + table.insert(self._grid_win_extmarks[grid], { ... }) end function Screen:_handle_busy_start() @@ -866,7 +1047,7 @@ function Screen:_handle_mouse_off() end function Screen:_handle_mode_change(mode, idx) - assert(mode == self._mode_info[idx+1].name) + assert(mode == self._mode_info[idx + 1].name) self.mode = mode end @@ -882,17 +1063,24 @@ function Screen:_handle_scroll(count) local bot = self._scroll_region.bot local left = self._scroll_region.left local right = self._scroll_region.right - self:_handle_grid_scroll(1, top-1, bot, left-1, right, count, 0) + self:_handle_grid_scroll(1, top - 1, bot, left - 1, right, count, 0) end +--- @param g any +--- @param top integer +--- @param bot integer +--- @param left integer +--- @param right integer +--- @param rows integer +--- @param cols integer function Screen:_handle_grid_scroll(g, top, bot, left, right, rows, cols) - top = top+1 - left = left+1 + top = top + 1 + left = left + 1 assert(cols == 0) local grid = self._grids[g] + --- @type integer, integer, integer local start, stop, step - if rows > 0 then start = top stop = bot - rows @@ -921,11 +1109,13 @@ function Screen:_handle_grid_scroll(g, top, bot, left, right, rows, cols) end function Screen:_handle_hl_attr_define(id, rgb_attrs, cterm_attrs, info) - self._attr_table[id] = {rgb_attrs, cterm_attrs} + self._attr_table[id] = { rgb_attrs, cterm_attrs } self._hl_info[id] = info self._new_attrs = true end +--- @param name string +--- @param id integer function Screen:_handle_hl_group_set(name, id) self.hl_groups[name] = id end @@ -933,9 +1123,8 @@ end function Screen:get_hl(val) if self._options.ext_newgrid then return self._attr_table[val][1] - else - return val end + return val end function Screen:_handle_highlight_set(attrs) @@ -951,14 +1140,18 @@ function Screen:_handle_put(str) self._cursor.col = self._cursor.col + 1 end +--- @param grid integer +--- @param row integer +--- @param col integer +--- @param items integer[][] function Screen:_handle_grid_line(grid, row, col, items) assert(self._options.ext_linegrid) assert(#items > 0) - local line = self._grids[grid].rows[row+1] - local colpos = col+1 + local line = self._grids[grid].rows[row + 1] + local colpos = col + 1 local hl_id = 0 - for _,item in ipairs(items) do - local text, hl_id_cell, count = unpack(item) + for _, item in ipairs(items) do + local text, hl_id_cell, count = item[1], item[2], item[3] if hl_id_cell ~= nil then hl_id = hl_id_cell end @@ -966,7 +1159,7 @@ function Screen:_handle_grid_line(grid, row, col, items) local cell = line[colpos] cell.text = text cell.hl_id = hl_id - colpos = colpos+1 + colpos = colpos + 1 end end end @@ -981,11 +1174,11 @@ end function Screen:_handle_default_colors_set(rgb_fg, rgb_bg, rgb_sp, cterm_fg, cterm_bg) self.default_colors = { - rgb_fg=rgb_fg, - rgb_bg=rgb_bg, - rgb_sp=rgb_sp, - cterm_fg=cterm_fg, - cterm_bg=cterm_bg + rgb_fg = rgb_fg, + rgb_bg = rgb_bg, + rgb_sp = rgb_sp, + cterm_fg = cterm_fg, + cterm_bg = cterm_bg, } end @@ -1021,8 +1214,12 @@ function Screen:_handle_option_set(name, value) self.options[name] = value end +function Screen:_handle_chdir(path) + self.pwd = vim.fs.normalize(path, { expand_env = false }) +end + function Screen:_handle_popupmenu_show(items, selected, row, col, grid) - self.popupmenu = {items=items, pos=selected, anchor={grid, row, col}} + self.popupmenu = { items = items, pos = selected, anchor = { grid, row, col } } end function Screen:_handle_popupmenu_select(selected) @@ -1034,9 +1231,15 @@ function Screen:_handle_popupmenu_hide() end function Screen:_handle_cmdline_show(content, pos, firstc, prompt, indent, level) - if firstc == '' then firstc = nil end - if prompt == '' then prompt = nil end - if indent == 0 then indent = nil end + if firstc == '' then + firstc = nil + end + if prompt == '' then + prompt = nil + end + if indent == 0 then + indent = nil + end -- check position is valid #10000 local len = 0 @@ -1045,8 +1248,13 @@ function Screen:_handle_cmdline_show(content, pos, firstc, prompt, indent, level end assert(pos <= len) - self.cmdline[level] = {content=content, pos=pos, firstc=firstc, - prompt=prompt, indent=indent} + self.cmdline[level] = { + content = content, + pos = pos, + firstc = firstc, + prompt = prompt, + indent = indent, + } end function Screen:_handle_cmdline_hide(level) @@ -1055,7 +1263,7 @@ end function Screen:_handle_cmdline_special_char(char, shift, level) -- cleared by next cmdline_show on the same level - self.cmdline[level].special = {char, shift} + self.cmdline[level].special = { char, shift } end function Screen:_handle_cmdline_pos(pos, level) @@ -1067,7 +1275,7 @@ function Screen:_handle_cmdline_block_show(block) end function Screen:_handle_cmdline_block_append(item) - self.cmdline_block[#self.cmdline_block+1] = item + self.cmdline_block[#self.cmdline_block + 1] = item end function Screen:_handle_cmdline_block_hide() @@ -1091,7 +1299,7 @@ function Screen:_handle_msg_show(kind, chunks, replace_last) if not replace_last or pos == 0 then pos = pos + 1 end - self.messages[pos] = {kind=kind, content=chunks} + self.messages[pos] = { kind = kind, content = chunks } end function Screen:_handle_msg_clear() @@ -1140,19 +1348,23 @@ function Screen:_row_repr(gridnr, rownr, attr_state, cursor) local has_windows = self._options.ext_multigrid and gridnr == 1 local row = self._grids[gridnr].rows[rownr] if has_windows and self.msg_grid and self.msg_grid_pos < rownr then - return '['..self.msg_grid..':'..string.rep('-',#row)..']' + return '[' .. self.msg_grid .. ':' .. string.rep('-', #row) .. ']' end while i <= #row do local did_window = false if has_windows then - for id,pos in pairs(self.win_position) do - if i-1 == pos.startcol and pos.startrow <= rownr-1 and rownr-1 < pos.startrow + pos.height then + for id, pos in pairs(self.win_position) do + if + i - 1 == pos.startcol + and pos.startrow <= rownr - 1 + and rownr - 1 < pos.startrow + pos.height + then if current_attr_id then -- close current attribute bracket table.insert(rv, '}') current_attr_id = nil end - table.insert(rv, '['..id..':'..string.rep('-',pos.width)..']') + table.insert(rv, '[' .. id .. ':' .. string.rep('-', pos.width) .. ']') i = i + pos.width did_window = true end @@ -1183,7 +1395,7 @@ function Screen:_row_repr(gridnr, rownr, attr_state, cursor) end -- return the line representation, but remove empty attribute brackets and -- trailing whitespace - return table.concat(rv, '')--:gsub('%s+$', '') + return table.concat(rv, '') --:gsub('%s+$', '') end function Screen:_extstate_repr(attr_state) @@ -1201,29 +1413,29 @@ function Screen:_extstate_repr(attr_state) local messages = {} for i, entry in ipairs(self.messages) do - messages[i] = {kind=entry.kind, content=self:_chunks_repr(entry.content, attr_state)} + messages[i] = { kind = entry.kind, content = self:_chunks_repr(entry.content, attr_state) } end local msg_history = {} for i, entry in ipairs(self.msg_history) do - msg_history[i] = {kind=entry[1], content=self:_chunks_repr(entry[2], attr_state)} + msg_history[i] = { kind = entry[1], content = self:_chunks_repr(entry[2], attr_state) } end local win_viewport = (next(self.win_viewport) and self.win_viewport) or nil return { - popupmenu=self.popupmenu, - cmdline=cmdline, - cmdline_block=cmdline_block, - wildmenu_items=self.wildmenu_items, - wildmenu_pos=self.wildmenu_pos, - messages=messages, - showmode=self:_chunks_repr(self.showmode, attr_state), - showcmd=self:_chunks_repr(self.showcmd, attr_state), - ruler=self:_chunks_repr(self.ruler, attr_state), - msg_history=msg_history, - float_pos=self.float_pos, - win_viewport=win_viewport, + popupmenu = self.popupmenu, + cmdline = cmdline, + cmdline_block = cmdline_block, + wildmenu_items = self.wildmenu_items, + wildmenu_pos = self.wildmenu_pos, + messages = messages, + showmode = self:_chunks_repr(self.showmode, attr_state), + showcmd = self:_chunks_repr(self.showcmd, attr_state), + ruler = self:_chunks_repr(self.ruler, attr_state), + msg_history = msg_history, + float_pos = self.float_pos, + win_viewport = win_viewport, } end @@ -1238,14 +1450,14 @@ function Screen:_chunks_repr(chunks, attr_state) attrs = hl end local attr_id = self:_get_attr_id(attr_state, attrs, hl) - repr_chunks[i] = {text, attr_id} + repr_chunks[i] = { text, attr_id } end return repr_chunks end -- Generates tests. Call it where Screen:expect() would be. Waits briefly, then -- dumps the current screen state in the form of Screen:expect(). --- Use snapshot_util({},true) to generate a text-only (no attributes) test. +-- Use snapshot_util({}) to generate a text-only (no attributes) test. -- -- @see Screen:redraw_debug() function Screen:snapshot_util(attrs, ignore, request_cb) @@ -1259,7 +1471,7 @@ function Screen:redraw_debug(attrs, ignore, timeout) assert(method == 'redraw') for _, update in ipairs(args) do -- mode_info_set is quite verbose, comment out the condition to debug it. - if update[1] ~= "mode_info_set" then + if update[1] ~= 'mode_info_set' then print(inspect(update)) end end @@ -1273,17 +1485,25 @@ function Screen:redraw_debug(attrs, ignore, timeout) run_session(self._session, nil, notification_cb, nil, timeout) end +--- @param headers boolean +--- @param attr_state any +--- @param preview? boolean +--- @return string[] function Screen:render(headers, attr_state, preview) headers = headers and (self._options.ext_multigrid or self._options._debug_float) local rv = {} - for igrid,grid in vim.spairs(self._grids) do + for igrid, grid in vim.spairs(self._grids) do if headers then - local suffix = "" - if igrid > 1 and self.win_position[igrid] == nil - and self.float_pos[igrid] == nil and self.msg_grid ~= igrid then - suffix = " (hidden)" + local suffix = '' + if + igrid > 1 + and self.win_position[igrid] == nil + and self.float_pos[igrid] == nil + and self.msg_grid ~= igrid + then + suffix = ' (hidden)' end - table.insert(rv, "## grid "..igrid..suffix) + table.insert(rv, '## grid ' .. igrid .. suffix) end local height = grid.height if igrid == self.msg_grid then @@ -1291,8 +1511,8 @@ function Screen:render(headers, attr_state, preview) end for i = 1, height do local cursor = self._cursor.grid == igrid and self._cursor.row == i - local prefix = (headers or preview) and " " or "" - table.insert(rv, prefix..self:_row_repr(igrid, i, attr_state, cursor).."|") + local prefix = (headers or preview) and ' ' or '' + table.insert(rv, prefix .. self:_row_repr(igrid, i, attr_state, cursor) .. '|') end end return rv @@ -1301,15 +1521,22 @@ end -- Returns the current screen state in the form of a screen:expect() -- keyword-args map. function Screen:get_snapshot(attrs, ignore) - attrs = attrs or self._default_attr_ids if ignore == nil then ignore = self._default_attr_ignore end local attr_state = { - ids = {}, - ignore = ignore, - mutable = true, -- allow _row_repr to add missing highlights + ids = {}, + ignore = ignore, + mutable = true, -- allow _row_repr to add missing highlights } + if attrs == nil then + attrs = self._default_attr_ids + elseif isempty(attrs) then + attrs = nil + attr_state.ids = nil + else + attr_state.modified = true + end if attrs ~= nil then for i, a in pairs(attrs) do @@ -1317,11 +1544,22 @@ function Screen:get_snapshot(attrs, ignore) end end if self._options.ext_linegrid then - attr_state.id_to_index = self:linegrid_check_attrs(attr_state.ids) + attr_state.id_to_index = self:linegrid_check_attrs(attr_state.ids or {}) end local lines = self:render(true, attr_state, true) + for i, row in ipairs(lines) do + local count = 1 + while i < #lines and lines[i + 1] == row do + count = count + 1 + table.remove(lines, i + 1) + end + if count > 1 then + lines[i] = lines[i] .. '*' .. count + end + end + local ext_state = self:_extstate_repr(attr_state) for k, v in pairs(ext_state) do if isempty(v) then @@ -1353,33 +1591,50 @@ local function fmt_ext_state(name, state) return item end end - if name == "win_viewport" then - local str = "{\n" - for k,v in pairs(state) do - str = (str.." ["..k.."] = {win = {id = "..v.win.id.."}, topline = " - ..v.topline..", botline = "..v.botline..", curline = "..v.curline - ..", curcol = "..v.curcol..", linecount = "..v.linecount..", sum_scroll_delta = "..v.sum_scroll_delta.."};\n") + if name == 'win_viewport' then + local str = '{\n' + for k, v in pairs(state) do + str = ( + str + .. ' [' + .. k + .. '] = {win = ' + .. v.win + .. ', topline = ' + .. v.topline + .. ', botline = ' + .. v.botline + .. ', curline = ' + .. v.curline + .. ', curcol = ' + .. v.curcol + .. ', linecount = ' + .. v.linecount + .. ', sum_scroll_delta = ' + .. v.sum_scroll_delta + .. '};\n' + ) end - return str .. "}" - elseif name == "float_pos" then - local str = "{\n" - for k,v in pairs(state) do - str = str.." ["..k.."] = {{id = "..v[1].id.."}" + return str .. '}' + elseif name == 'float_pos' then + local str = '{\n' + for k, v in pairs(state) do + str = str .. ' [' .. k .. '] = {' .. v[1] for i = 2, #v do - str = str..", "..inspect(v[i]) + str = str .. ', ' .. inspect(v[i]) end - str = str .. "};\n" + str = str .. '};\n' end - return str .. "}" + return str .. '}' else -- TODO(bfredl): improve formatting of more states - return inspect(state,{process=remove_all_metatables}) + return inspect(state, { process = remove_all_metatables }) end end -function Screen:print_snapshot(attrs, ignore) +function Screen:_print_snapshot(attrs, ignore) local kwargs, ext_state, attr_state = self:get_snapshot(attrs, ignore) - local attrstr = "" + local attrstr = '' if attr_state.modified then local attrstrs = {} for i, a in pairs(attr_state.ids) do @@ -1387,23 +1642,29 @@ function Screen:print_snapshot(attrs, ignore) if self._options.ext_linegrid then dict = self:_pprint_hlitem(a) else - dict = "{"..self:_pprint_attrs(a).."}" + dict = '{' .. self:_pprint_attrs(a) .. '}' end - local keyval = (type(i) == "number") and "["..tostring(i).."]" or i - table.insert(attrstrs, " "..keyval.." = "..dict..";") + local keyval = (type(i) == 'number') and '[' .. tostring(i) .. ']' or i + table.insert(attrstrs, ' ' .. keyval .. ' = ' .. dict .. ';') end - attrstr = (", attr_ids={\n"..table.concat(attrstrs, "\n").."\n}") + attrstr = (', attr_ids={\n' .. table.concat(attrstrs, '\n') .. '\n}') + elseif isempty(attrs) then + attrstr = ', attr_ids={}' end - print( "\nscreen:expect{grid=[[") - print(kwargs.grid) - io.stdout:write( "]]"..attrstr) + local result = 'screen:expect{grid=[[\n' .. kwargs.grid .. '\n]]' .. attrstr for _, k in ipairs(ext_keys) do - if ext_state[k] ~= nil and not (k == "win_viewport" and not self.options.ext_multigrid) then - io.stdout:write(", "..k.."="..fmt_ext_state(k, ext_state[k])) + if ext_state[k] ~= nil and not (k == 'win_viewport' and not self.options.ext_multigrid) then + result = result .. ', ' .. k .. '=' .. fmt_ext_state(k, ext_state[k]) end end - print("}\n") + result = result .. '}' + + return result +end + +function Screen:print_snapshot(attrs, ignore) + print('\n' .. self:_print_snapshot(attrs, ignore) .. '\n') io.stdout:flush() end @@ -1422,7 +1683,7 @@ function Screen:_insert_hl_id(attr_state, hl_id) else info[1] = {} for k, v in pairs(raw_info[1]) do - if k ~= "id" then + if k ~= 'id' then info[1][k] = v end end @@ -1432,9 +1693,9 @@ function Screen:_insert_hl_id(attr_state, hl_id) local entry = self._attr_table[hl_id] local attrval if self._rgb_cterm then - attrval = {entry[1], entry[2], info} -- unpack() doesn't work + attrval = { entry[1], entry[2], info } -- unpack() doesn't work elseif self._options.ext_hlstate then - attrval = {entry[1], info} + attrval = { entry[1], info } else attrval = self._options.rgb and entry[1] or entry[2] end @@ -1450,17 +1711,17 @@ function Screen:linegrid_check_attrs(attrs) local iinfo = self._hl_info[i] local matchinfo = {} if #iinfo > 1 then - for k,item in ipairs(iinfo) do + for k, item in ipairs(iinfo) do matchinfo[k] = id_to_index[item.id] end else matchinfo = iinfo end - for k,v in pairs(attrs) do + for k, v in pairs(attrs) do local attr, info, attr_rgb, attr_cterm if self._rgb_cterm then attr_rgb, attr_cterm, info = unpack(v) - attr = {attr_rgb, attr_cterm} + attr = { attr_rgb, attr_cterm } info = info or {} elseif self._options.ext_hlstate then attr, info = unpack(v) @@ -1472,12 +1733,12 @@ function Screen:linegrid_check_attrs(attrs) if #info == #matchinfo then local match = false if #info == 1 then - if self:_equal_info(info[1],matchinfo[1]) then + if self:_equal_info(info[1], matchinfo[1]) then match = true end else match = true - for j = 1,#info do + for j = 1, #info do if info[j] ~= matchinfo[j] then match = false end @@ -1489,32 +1750,34 @@ function Screen:linegrid_check_attrs(attrs) end end end - if self:_equal_attr_def(self._rgb_cterm and {{}, {}} or {}, def_attr) and #self._hl_info[i] == 0 then - id_to_index[i] = "" + if + self:_equal_attr_def(self._rgb_cterm and { {}, {} } or {}, def_attr) + and #self._hl_info[i] == 0 + then + id_to_index[i] = '' end end return id_to_index end - function Screen:_pprint_hlitem(item) - -- print(inspect(item)) - local multi = self._rgb_cterm or self._options.ext_hlstate - local cterm = (not self._rgb_cterm and not self._options.rgb) - local attrdict = "{"..self:_pprint_attrs(multi and item[1] or item, cterm).."}" - local attrdict2, hlinfo - local descdict = "" - if self._rgb_cterm then - attrdict2 = ", {"..self:_pprint_attrs(item[2], true).."}" - hlinfo = item[3] - else - attrdict2 = "" - hlinfo = item[2] - end - if self._options.ext_hlstate then - descdict = ", {"..self:_pprint_hlinfo(hlinfo).."}" - end - return (multi and "{" or "")..attrdict..attrdict2..descdict..(multi and "}" or "") + -- print(inspect(item)) + local multi = self._rgb_cterm or self._options.ext_hlstate + local cterm = (not self._rgb_cterm and not self._options.rgb) + local attrdict = '{' .. self:_pprint_attrs(multi and item[1] or item, cterm) .. '}' + local attrdict2, hlinfo + local descdict = '' + if self._rgb_cterm then + attrdict2 = ', {' .. self:_pprint_attrs(item[2], true) .. '}' + hlinfo = item[3] + else + attrdict2 = '' + hlinfo = item[2] + end + if self._options.ext_hlstate then + descdict = ', {' .. self:_pprint_hlinfo(hlinfo) .. '}' + end + return (multi and '{' or '') .. attrdict .. attrdict2 .. descdict .. (multi and '}' or '') end function Screen:_pprint_hlinfo(states) @@ -1522,37 +1785,37 @@ function Screen:_pprint_hlinfo(states) local items = {} for f, v in pairs(states[1]) do local desc = tostring(v) - if type(v) == type("") then - desc = '"'..desc..'"' + if type(v) == type('') then + desc = '"' .. desc .. '"' end - table.insert(items, f.." = "..desc) + table.insert(items, f .. ' = ' .. desc) end - return "{"..table.concat(items, ", ").."}" + return '{' .. table.concat(items, ', ') .. '}' else - return table.concat(states, ", ") + return table.concat(states, ', ') end end - function Screen:_pprint_attrs(attrs, cterm) - local items = {} - for f, v in pairs(attrs) do - local desc = tostring(v) - if f == "foreground" or f == "background" or f == "special" then - if Screen.colornames[v] ~= nil then - desc = "Screen.colors."..Screen.colornames[v] - elseif cterm then - desc = tostring(v) - else - desc = string.format("tonumber('0x%06x')",v) - end + local items = {} + for f, v in pairs(attrs) do + local desc = tostring(v) + if f == 'foreground' or f == 'background' or f == 'special' then + if Screen.colornames[v] ~= nil then + desc = 'Screen.colors.' .. Screen.colornames[v] + elseif cterm then + desc = tostring(v) + else + desc = string.format("tonumber('0x%06x')", v) end - table.insert(items, f.." = "..desc) end - return table.concat(items, ", ") + table.insert(items, f .. ' = ' .. desc) + end + return table.concat(items, ', ') end -local function backward_find_meaningful(tbl, from) -- luacheck: no unused +---@diagnostic disable-next-line: unused-local, unused-function +local function backward_find_meaningful(tbl, from) -- luacheck: no unused for i = from or #tbl, 1, -1 do if tbl[i] ~= ' ' then return i + 1 @@ -1568,7 +1831,7 @@ function Screen:_get_attr_id(attr_state, attrs, hl_id) if self._options.ext_linegrid then local id = attr_state.id_to_index[hl_id] - if id == "" then -- sentinel for empty it + if id == '' then -- sentinel for empty it return nil elseif id ~= nil then return id @@ -1579,7 +1842,7 @@ function Screen:_get_attr_id(attr_state, attrs, hl_id) return id end local kind = self._options.rgb and 1 or 2 - return "UNEXPECTED "..self:_pprint_attrs(self._attr_table[hl_id][kind]) + return 'UNEXPECTED ' .. self:_pprint_attrs(self._attr_table[hl_id][kind]) else if self:_equal_attrs(attrs, {}) then -- ignore this attrs @@ -1587,49 +1850,57 @@ function Screen:_get_attr_id(attr_state, attrs, hl_id) end for id, a in pairs(attr_state.ids) do if self:_equal_attrs(a, attrs) then - return id - end + return id + end end if attr_state.mutable then table.insert(attr_state.ids, attrs) attr_state.modified = true return #attr_state.ids end - return "UNEXPECTED "..self:_pprint_attrs(attrs) + return 'UNEXPECTED ' .. self:_pprint_attrs(attrs) end end function Screen:_equal_attr_def(a, b) if self._rgb_cterm then - return self:_equal_attrs(a[1],b[1]) and self:_equal_attrs(a[2],b[2]) + return self:_equal_attrs(a[1], b[1]) and self:_equal_attrs(a[2], b[2]) elseif self._options.rgb then - return self:_equal_attrs(a,b[1]) + return self:_equal_attrs(a, b[1]) else - return self:_equal_attrs(a,b[2]) + return self:_equal_attrs(a, b[2]) end end function Screen:_equal_attrs(a, b) - return a.bold == b.bold and a.standout == b.standout and - a.underline == b.underline and a.undercurl == b.undercurl and - a.underdouble == b.underdouble and a.underdotted == b.underdotted and - a.underdashed == b.underdashed and a.italic == b.italic and - a.reverse == b.reverse and a.foreground == b.foreground and - a.background == b.background and a.special == b.special and a.blend == b.blend and - a.strikethrough == b.strikethrough and - a.fg_indexed == b.fg_indexed and a.bg_indexed == b.bg_indexed + return a.bold == b.bold + and a.standout == b.standout + and a.underline == b.underline + and a.undercurl == b.undercurl + and a.underdouble == b.underdouble + and a.underdotted == b.underdotted + and a.underdashed == b.underdashed + and a.italic == b.italic + and a.reverse == b.reverse + and a.foreground == b.foreground + and a.background == b.background + and a.special == b.special + and a.blend == b.blend + and a.strikethrough == b.strikethrough + and a.fg_indexed == b.fg_indexed + and a.bg_indexed == b.bg_indexed + and a.url == b.url end function Screen:_equal_info(a, b) - return a.kind == b.kind and a.hi_name == b.hi_name and - a.ui_name == b.ui_name + return a.kind == b.kind and a.hi_name == b.hi_name and a.ui_name == b.ui_name end function Screen:_attr_index(attrs, attr) if not attrs then return nil end - for i,a in pairs(attrs) do + for i, a in pairs(attrs) do if self:_equal_attrs(a, attr) then return i end diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua index 7cc1accd3f..42e2b4d4b5 100644 --- a/test/functional/ui/screen_basic_spec.lua +++ b/test/functional/ui/screen_basic_spec.lua @@ -4,39 +4,39 @@ local spawn, set_session, clear = helpers.spawn, helpers.set_session, helpers.cl local feed, command = helpers.feed, helpers.command local insert = helpers.insert local eq = helpers.eq -local funcs, meths = helpers.funcs, helpers.meths +local fn, api = helpers.fn, helpers.api describe('screen', function() local screen - local nvim_argv = {helpers.nvim_prog, '-u', 'NONE', '-i', 'NONE', '-N', - '--cmd', 'set shortmess+=I background=light noswapfile belloff= noshowcmd noruler', - '--embed'} + local nvim_argv = { + helpers.nvim_prog, + '-u', + 'NONE', + '-i', + 'NONE', + '-n', + '--cmd', + 'set shortmess+=I background=light noswapfile belloff= noshowcmd noruler', + '--cmd', + 'colorscheme vim', + '--embed', + } before_each(function() local screen_nvim = spawn(nvim_argv) set_session(screen_nvim) screen = Screen.new() screen:attach() - screen:set_default_attr_ids( { - [0] = {bold=true, foreground=255}, - [1] = {bold=true, reverse=true}, - } ) + screen:set_default_attr_ids({ + [0] = { bold = true, foreground = 255 }, + [1] = { bold = true, reverse = true }, + }) end) it('default initial screen', function() - screen:expect([[ + screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*11 {1:[No Name] }| | ]]) @@ -49,18 +49,23 @@ local function screen_tests(linegrid) before_each(function() clear() screen = Screen.new() - screen:attach({rgb=true,ext_linegrid=linegrid}) - screen:set_default_attr_ids( { - [0] = {bold=true, foreground=255}, - [1] = {bold=true, reverse=true}, - [2] = {bold=true}, - [3] = {reverse=true}, - [4] = {background = Screen.colors.LightGrey, underline = true}, - [5] = {background = Screen.colors.LightGrey, underline = true, bold = true, foreground = Screen.colors.Fuchsia}, - [6] = {bold = true, foreground = Screen.colors.Fuchsia}, - [7] = {bold = true, foreground = Screen.colors.SeaGreen}, - [8] = {foreground = Screen.colors.White, background = Screen.colors.Red}, - } ) + screen:attach({ rgb = true, ext_linegrid = linegrid }) + screen:set_default_attr_ids({ + [0] = { bold = true, foreground = 255 }, + [1] = { bold = true, reverse = true }, + [2] = { bold = true }, + [3] = { reverse = true }, + [4] = { background = Screen.colors.LightGrey, underline = true }, + [5] = { + background = Screen.colors.LightGrey, + underline = true, + bold = true, + foreground = Screen.colors.Fuchsia, + }, + [6] = { bold = true, foreground = Screen.colors.Fuchsia }, + [7] = { bold = true, foreground = Screen.colors.SeaGreen }, + [8] = { foreground = Screen.colors.White, background = Screen.colors.Red }, + }) end) describe('bell/visual bell', function() @@ -83,7 +88,7 @@ local function screen_tests(linegrid) describe(':set title', function() it('is forwarded to the UI', function() local expected = 'test-title' - command('set titlestring='..expected) + command('set titlestring=' .. expected) command('set title') screen:expect(function() eq(expected, screen.title) @@ -100,7 +105,7 @@ local function screen_tests(linegrid) describe(':set icon', function() it('is forwarded to the UI', function() local expected = 'test-icon' - command('set iconstring='..expected) + command('set iconstring=' .. expected) command('set icon') screen:expect(function() eq(expected, screen.icon) @@ -119,74 +124,46 @@ local function screen_tests(linegrid) command('set laststatus=2') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*11 {1:[No Name] }| | ]]) feed('<c-l>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*11 {1:[No Name] }| | - ]], reset=true} + ]], + reset = true, + } command('split') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {1:[No Name] }| | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:[No Name] }| | ]]) feed('<c-l>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {1:[No Name] }| | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:[No Name] }| | - ]], reset=true} + ]], + reset = true, + } end) end) @@ -196,17 +173,10 @@ local function screen_tests(linegrid) command('sp') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {1:[No Name] }| | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:[No Name] }| | ]]) @@ -217,17 +187,10 @@ local function screen_tests(linegrid) command('resize 8') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*7 {1:[No Name] }| | - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:[No Name] }| | ]]) @@ -239,34 +202,20 @@ local function screen_tests(linegrid) command('vsp') screen:expect([[ ^ │ │ | - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| + {0:~ }│{0:~ }│{0:~ }|*5 {1:[No Name] }{3:[No Name] [No Name] }| | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:[No Name] }| | ]]) insert('hello') screen:expect([[ hell^o │hello │hello | - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| + {0:~ }│{0:~ }│{0:~ }|*5 {1:[No Name] [+] }{3:[No Name] [+] [No Name] [+] }| hello | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:[No Name] [+] }| | ]]) @@ -282,17 +231,10 @@ local function screen_tests(linegrid) insert('hello') screen:expect([[ hell^o │hello │hello | - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| + {0:~ }│{0:~ }│{0:~ }|*5 {1:[No Name] [+] }{3:[No Name] [+] [No Name] [+] }| hello | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:[No Name] [+] }| | ]]) @@ -302,33 +244,17 @@ local function screen_tests(linegrid) screen:expect([[ {4: }{5:4}{4:+ [No Name] }{2: + [No Name] }{3: }{4:X}| hell^o2 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*11 | ]]) command('tabprevious') screen:expect([[ {2: }{6:4}{2:+ [No Name] }{4: + [No Name] }{3: }{4:X}| hell^o │hello │hello | - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| - {0:~ }│{0:~ }│{0:~ }| + {0:~ }│{0:~ }│{0:~ }|*5 {1:[No Name] [+] }{3:[No Name] [+] [No Name] [+] }| hello | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:[No Name] [+] }| | ]]) @@ -339,34 +265,14 @@ local function screen_tests(linegrid) screen:expect([[ {4: [No Name] }{2: [No Name] }{3: }{4:X}| ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*11 | ]]) - feed(':echo "'..string.rep('x\\n', 11)..'"<cr>') + feed(':echo "' .. string.rep('x\\n', 11) .. '"<cr>') screen:expect([[ {1: }| - x | - x | - x | - x | - x | - x | - x | - x | - x | - x | - x | + x |*11 | {7:Press ENTER or type command to continue}^ | ]]) @@ -375,34 +281,13 @@ local function screen_tests(linegrid) screen:expect([[ {4: [No Name] }{2: [No Name] }{3: }{4:X}| ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*11 | ]]) - feed(':echo "'..string.rep('x\\n', 12)..'"<cr>') + feed(':echo "' .. string.rep('x\\n', 12) .. '"<cr>') screen:expect([[ - x | - x | - x | - x | - x | - x | - x | - x | - x | - x | - x | - x | + x |*12 | {7:Press ENTER or type command to continue}^ | ]]) @@ -411,20 +296,9 @@ local function screen_tests(linegrid) screen:expect([[ {4: [No Name] }{2: [No Name] }{3: }{4:X}| ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*11 | ]]) - end) it('redraws properly with :tab split right after scroll', function() @@ -433,17 +307,7 @@ local function screen_tests(linegrid) command('vsplit') screen:expect([[ ^foo │foo | - foo │foo | - foo │foo | - foo │foo | - foo │foo | - foo │foo | - foo │foo | - foo │foo | - foo │foo | - foo │foo | - foo │foo | - foo │foo | + foo │foo |*11 {1:[No Name] [+] }{3:[No Name] [+] }| | ]]) @@ -451,17 +315,8 @@ local function screen_tests(linegrid) feed('<PageDown>') screen:expect([[ ^foo │foo | - foo │foo | - foo │foo | - foo │foo | - bar │foo | - bar │foo | - bar │foo | - bar │foo | - bar │foo | - bar │foo | - bar │foo | - bar │foo | + foo │foo |*3 + bar │foo |*8 {1:[No Name] [+] }{3:[No Name] [+] }| | ]]) @@ -469,17 +324,8 @@ local function screen_tests(linegrid) screen:expect([[ {4: }{5:2}{4:+ [No Name] }{2: + [No Name] }{3: }{4:X}| ^foo | - foo | - foo | - foo | - bar | - bar | - bar | - bar | - bar | - bar | - bar | - bar | + foo |*3 + bar |*8 | ]]) end) @@ -491,17 +337,7 @@ local function screen_tests(linegrid) screen:expect([[ {2: + [No Name] }{4: [No Name] }{3: }{4:X}| hell^o | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*11 | ]]) @@ -509,17 +345,7 @@ local function screen_tests(linegrid) screen:expect([[ {4: + [No Name] }{2: [No Name] }{3: }{4:X}| ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*11 | ]]) end) @@ -532,16 +358,7 @@ local function screen_tests(linegrid) line 1 | line 2 | ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*10 {2:-- INSERT --} | ]]) end) @@ -557,17 +374,7 @@ local function screen_tests(linegrid) screen:expect([[ 0123^456 | 789 | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*11 1,5 All | ]]) end) @@ -578,18 +385,7 @@ local function screen_tests(linegrid) feed(':ls') screen:expect([[ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*12 :ls^ | ]]) end) @@ -598,15 +394,7 @@ local function screen_tests(linegrid) feed(':ls<cr>') screen:expect([[ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 {1: }| :ls | 1 %a "[No Name]" line 1 | @@ -783,9 +571,7 @@ local function screen_tests(linegrid) feed('iresize') screen:expect([[ resize^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {2:-- INSERT --} | ]]) end) @@ -811,38 +597,27 @@ local function screen_tests(linegrid) command([[autocmd VimResized * redrawtabline]]) command([[autocmd VimResized * lua vim.api.nvim_echo({ { 'Hello' } }, false, {})]]) command([[autocmd VimResized * let g:echospace = v:echospace]]) - meths.set_option_value('showtabline', 2, {}) + api.nvim_set_option_value('showtabline', 2, {}) screen:expect([[ {2: + [No Name] }{3: }| resiz^e | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) screen:try_resize(30, 6) screen:expect([[ {2: + [No Name] }{3: }| resiz^e | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) - eq(29, meths.get_var('echospace')) + eq(29, api.nvim_get_var('echospace')) end) it('messages from the same Ex command as resize are visible #22225', function() feed(':set columns=20 | call<CR>') screen:expect([[ - | - | - | - | - | - | - | - | - | + |*9 {1: }| {8:E471: Argument requi}| {8:red} | @@ -852,53 +627,25 @@ local function screen_tests(linegrid) feed('<CR>') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*12 | ]]) feed(':set columns=0<CR>') screen:expect([[ - | - | - | - | - | - {1: }| - {8:E594: Need a}| - {8:t least 12 c}| - {8:olumns: colu}| - {8:mns=0} | - {7:Press ENTER }| - {7:or type comm}| - {7:and to conti}| - {7:nue}^ | + | + {0:~ }|*7 + {1: }| + {8:E594: Need at least }| + {8:12 columns: columns=}| + {8:0} | + {7:Press ENTER or type }| + {7:command to continue}^ | ]]) feed('<CR>') screen:expect([[ - ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - | + ^ | + {0:~ }|*12 + | ]]) end) end) @@ -909,15 +656,7 @@ local function screen_tests(linegrid) feed(':ls<CR>') screen:expect([[ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 {1: }| :ls | 1 %a "[No Name]" line 1 | @@ -926,18 +665,7 @@ local function screen_tests(linegrid) feed('<F1>') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*12 TEST | ]]) end) @@ -950,45 +678,23 @@ local function screen_tests(linegrid) feed('ifooj') screen:expect([[ foo^j | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*12 {2:-- INSERT --} | ]]) feed('k') screen:expect([[ fo^o | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*12 | ]]) end) end -describe("Screen (char-based)", function() +describe('Screen (char-based)', function() screen_tests(false) end) -describe("Screen (line-based)", function() +describe('Screen (line-based)', function() screen_tests(true) end) @@ -997,41 +703,75 @@ describe('Screen default colors', function() local function startup(light, termcolors) local extra = (light and ' background=light') or '' - local nvim_argv = {helpers.nvim_prog, '-u', 'NONE', '-i', 'NONE', '-N', - '--cmd', 'set shortmess+=I noswapfile belloff= noshowcmd noruler'..extra, - '--embed'} + local nvim_argv = { + helpers.nvim_prog, + '-u', + 'NONE', + '-i', + 'NONE', + '-N', + '--cmd', + 'set shortmess+=I noswapfile belloff= noshowcmd noruler' .. extra, + '--cmd', + 'colorscheme vim', + '--embed', + } local screen_nvim = spawn(nvim_argv) set_session(screen_nvim) screen = Screen.new() - screen:attach(termcolors and {rgb=true,ext_termcolors=true} or {rgb=true}) + screen:attach(termcolors and { rgb = true, ext_termcolors = true } or { rgb = true }) end it('are dark per default', function() startup(false, false) - screen:expect{condition=function() - eq({rgb_bg=0, rgb_fg=Screen.colors.White, rgb_sp=Screen.colors.Red, - cterm_bg=0, cterm_fg=0}, screen.default_colors) - end} + screen:expect { + condition = function() + eq({ + rgb_bg = 0, + rgb_fg = Screen.colors.White, + rgb_sp = Screen.colors.Red, + cterm_bg = 0, + cterm_fg = 0, + }, screen.default_colors) + end, + } end) it('can be set to light', function() startup(true, false) - screen:expect{condition=function() - eq({rgb_fg=Screen.colors.White, rgb_bg=0, rgb_sp=Screen.colors.Red, - cterm_bg=0, cterm_fg=0}, screen.default_colors) - end} + screen:expect { + condition = function() + eq({ + rgb_bg = Screen.colors.White, + rgb_fg = 0, + rgb_sp = Screen.colors.Red, + cterm_bg = 0, + cterm_fg = 0, + }, screen.default_colors) + end, + } end) it('can be handled by external terminal', function() startup(false, true) - screen:expect{condition=function() - eq({rgb_bg=-1, rgb_fg=-1, rgb_sp=-1, cterm_bg=0, cterm_fg=0}, screen.default_colors) - end} + screen:expect { + condition = function() + eq( + { rgb_bg = -1, rgb_fg = -1, rgb_sp = -1, cterm_bg = 0, cterm_fg = 0 }, + screen.default_colors + ) + end, + } startup(true, true) - screen:expect{condition=function() - eq({rgb_bg=-1, rgb_fg=-1, rgb_sp=-1, cterm_bg=0, cterm_fg=0}, screen.default_colors) - end} + screen:expect { + condition = function() + eq( + { rgb_bg = -1, rgb_fg = -1, rgb_sp = -1, cterm_bg = 0, cterm_fg = 0 }, + screen.default_colors + ) + end, + } end) end) @@ -1039,46 +779,48 @@ it('CTRL-F or CTRL-B scrolls a page after UI attach/resize #20605', function() clear() local screen = Screen.new(100, 100) screen:attach() - eq(100, meths.get_option_value('lines', {})) - eq(99, meths.get_option_value('window', {})) - eq(99, meths.win_get_height(0)) + eq(100, api.nvim_get_option_value('lines', {})) + eq(99, api.nvim_get_option_value('window', {})) + eq(99, api.nvim_win_get_height(0)) feed('1000o<Esc>') - eq(903, funcs.line('w0')) + eq(903, fn.line('w0')) feed('<C-B>') - eq(806, funcs.line('w0')) + eq(806, fn.line('w0')) feed('<C-B>') - eq(709, funcs.line('w0')) + eq(709, fn.line('w0')) feed('<C-F>') - eq(806, funcs.line('w0')) + eq(806, fn.line('w0')) feed('<C-F>') - eq(903, funcs.line('w0')) + eq(903, fn.line('w0')) feed('G') screen:try_resize(50, 50) - eq(50, meths.get_option_value('lines', {})) - eq(49, meths.get_option_value('window', {})) - eq(49, meths.win_get_height(0)) - eq(953, funcs.line('w0')) + eq(50, api.nvim_get_option_value('lines', {})) + eq(49, api.nvim_get_option_value('window', {})) + eq(49, api.nvim_win_get_height(0)) + eq(953, fn.line('w0')) feed('<C-B>') - eq(906, funcs.line('w0')) + eq(906, fn.line('w0')) feed('<C-B>') - eq(859, funcs.line('w0')) + eq(859, fn.line('w0')) feed('<C-F>') - eq(906, funcs.line('w0')) + eq(906, fn.line('w0')) feed('<C-F>') - eq(953, funcs.line('w0')) + eq(953, fn.line('w0')) end) it("showcmd doesn't cause empty grid_line with redrawdebug=compositor #22593", function() clear() local screen = Screen.new(30, 2) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, + [0] = { bold = true, foreground = Screen.colors.Blue }, }) screen:attach() command('set showcmd redrawdebug=compositor') feed('d') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | d | - ]]} + ]], + } end) diff --git a/test/functional/ui/searchhl_spec.lua b/test/functional/ui/searchhl_spec.lua index dc7ef666bd..a05436cf55 100644 --- a/test/functional/ui/searchhl_spec.lua +++ b/test/functional/ui/searchhl_spec.lua @@ -5,7 +5,7 @@ local command = helpers.command local feed_command = helpers.feed_command local eq = helpers.eq local eval = helpers.eval -local funcs = helpers.funcs +local fn = helpers.fn local testprg = helpers.testprg describe('search highlighting', function() @@ -15,46 +15,50 @@ describe('search highlighting', function() clear() screen = Screen.new(40, 7) screen:attach() - screen:set_default_attr_ids( { - [1] = {bold=true, foreground=Screen.colors.Blue}, - [2] = {background = Screen.colors.Yellow}, -- Search - [3] = {reverse = true}, - [4] = {foreground = Screen.colors.Red}, -- WarningMsg - [5] = {bold = true, reverse = true}, -- StatusLine - [6] = {foreground = Screen.colors.Blue4, background = Screen.colors.LightGrey}, -- Folded + screen:set_default_attr_ids({ + [1] = { bold = true, foreground = Screen.colors.Blue }, + [2] = { background = Screen.colors.Yellow }, -- Search + [3] = { reverse = true }, + [4] = { foreground = Screen.colors.Red }, -- WarningMsg + [5] = { bold = true, reverse = true }, -- StatusLine + [6] = { foreground = Screen.colors.Blue4, background = Screen.colors.LightGrey }, -- Folded }) end) it('is disabled by ":set nohlsearch"', function() feed_command('set nohlsearch') - insert("some text\nmore text") - feed("gg/text<cr>") + insert('some text\nmore text') + feed('gg/text<cr>') screen:expect([[ some ^text | more text | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 /text | ]]) end) it('is disabled in folded text', function() - insert("some text\nmore text") + insert('some text\nmore text') feed_command('1,2fold') - feed("gg/text") - screen:expect{grid=[[ + feed('gg/text') + screen:expect { + grid = [[ {6:+-- 2 lines: some text·················}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 /text^ | - ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 3, curline = 0, curcol = 8, linecount = 2, sum_scroll_delta = 0}; - }} + ]], + win_viewport = { + [2] = { + win = 1000, + topline = 0, + botline = 3, + curline = 0, + curcol = 8, + linecount = 2, + sum_scroll_delta = 0, + }, + }, + } end) local function test_search_hl() @@ -66,7 +70,7 @@ describe('search highlighting', function() ]]) -- 'hlsearch' is enabled by default. #2859 - feed("gg/text<cr>") + feed('gg/text<cr>') screen:expect([[ some {2:^text} | more {2:text}stuff | @@ -78,7 +82,7 @@ describe('search highlighting', function() ]]) -- overlapping matches not allowed - feed("3nx") + feed('3nx') screen:expect([[ some {2:text} | more {2:text}stuff | @@ -89,7 +93,7 @@ describe('search highlighting', function() /text | ]]) - feed("ggn*") -- search for entire word + feed('ggn*') -- search for entire word screen:expect([[ some {2:text} | more textstuff | @@ -100,7 +104,7 @@ describe('search highlighting', function() /\<text\> | ]]) - feed_command("nohlsearch") + feed_command('nohlsearch') screen:expect([[ some text | more textstuff | @@ -119,7 +123,7 @@ describe('search highlighting', function() it("works when 'winhighlight' doesn't change Search highlight", function() command('setlocal winhl=NonText:Underlined') local attrs = screen:get_default_attr_ids() - attrs[1] = {foreground = Screen.colors.SlateBlue, underline = true} + attrs[1] = { foreground = Screen.colors.SlateBlue, underline = true } screen:set_default_attr_ids(attrs) test_search_hl() end) @@ -127,7 +131,7 @@ describe('search highlighting', function() it("works when 'winhighlight' changes Search highlight", function() command('setlocal winhl=Search:Underlined') local attrs = screen:get_default_attr_ids() - attrs[2] = {foreground = Screen.colors.SlateBlue, underline = true} + attrs[2] = { foreground = Screen.colors.SlateBlue, underline = true } screen:set_default_attr_ids(attrs) test_search_hl() end) @@ -135,9 +139,9 @@ describe('search highlighting', function() describe('CurSearch highlight', function() before_each(function() screen:set_default_attr_ids({ - [1] = {background = Screen.colors.Yellow}, -- Search - [2] = {foreground = Screen.colors.White, background = Screen.colors.Black}, -- CurSearch - [3] = {foreground = Screen.colors.Red}, -- WarningMsg + [1] = { background = Screen.colors.Yellow }, -- Search + [2] = { foreground = Screen.colors.White, background = Screen.colors.Black }, -- CurSearch + [3] = { foreground = Screen.colors.Red }, -- WarningMsg }) command('highlight CurSearch guibg=Black guifg=White') end) @@ -152,7 +156,8 @@ describe('search highlighting', function() humans think is impossible.]]) feed('/bee<CR>') - screen:expect{grid=[[ + screen:expect { + grid = [[ There is no way that a {2:^bee} should be | able to fly. Its wings are too small | to get its fat little body off the | @@ -160,10 +165,12 @@ describe('search highlighting', function() anyway because {1:bee}s don't care what | humans think is impossible. | {3:search hit BOTTOM, continuing at TOP} | - ]]} + ]], + } feed('nn') - screen:expect{grid=[[ + screen:expect { + grid = [[ There is no way that a {1:bee} should be | able to fly. Its wings are too small | to get its fat little body off the | @@ -171,10 +178,12 @@ describe('search highlighting', function() anyway because {2:^bee}s don't care what | humans think is impossible. | /bee | - ]]} + ]], + } feed('N') - screen:expect{grid=[[ + screen:expect { + grid = [[ There is no way that a {1:bee} should be | able to fly. Its wings are too small | to get its fat little body off the | @@ -182,7 +191,8 @@ describe('search highlighting', function() anyway because {1:bee}s don't care what | humans think is impossible. | ?bee | - ]]} + ]], + } end) it('works for multiline match', function() @@ -273,54 +283,42 @@ describe('search highlighting', function() end) it('highlights after EOL', function() - insert("\n\n\n\n\n\n") + insert('\n\n\n\n\n\n') - feed("gg/^<cr>") + feed('gg/^<cr>') screen:expect([[ {2: } | {2:^ } | - {2: } | - {2: } | - {2: } | - {2: } | + {2: } |*4 /^ | ]]) -- Test that highlights are preserved after moving the cursor. - feed("j") + feed('j') screen:expect([[ - {2: } | - {2: } | + {2: } |*2 {2:^ } | - {2: } | - {2: } | - {2: } | + {2: } |*3 /^ | ]]) -- Repeat the test in rightleft mode. - command("nohlsearch") - command("set rightleft") - feed("gg/^<cr>") + command('nohlsearch') + command('set rightleft') + feed('gg/^<cr>') screen:expect([[ {2: }| {2:^ }| - {2: }| - {2: }| - {2: }| - {2: }| + {2: }|*4 ^/ | ]]) - feed("j") + feed('j') screen:expect([[ - {2: }| - {2: }| + {2: }|*2 {2:^ }| - {2: }| - {2: }| - {2: }| + {2: }|*3 ^/ | ]]) end) @@ -338,7 +336,7 @@ describe('search highlighting', function() :file term | ]]) - feed('G') -- Follow :terminal output. + feed('G') -- Follow :terminal output. feed(':vnew<CR>') insert([[ foo bar baz @@ -349,8 +347,7 @@ describe('search highlighting', function() {3:foo} bar baz │{MATCH:%d+}: {2:foo}{MATCH:%s+}| bar baz {2:foo} │{MATCH:%d+}: {2:foo}{MATCH:%s+}| bar {2:foo} baz │{MATCH:%d+}: {2:foo}{MATCH:%s+}| - {1:~ }│{MATCH:.*}| - {1:~ }│{MATCH:.*}| + {1:~ }│{MATCH:.*}|*2 {5:[No Name] [+] }{3:term }| /foo^ | ]]) @@ -364,82 +361,61 @@ describe('search highlighting', function() the first line in a little file]]) command('vsplit') - feed("gg/li") + feed('gg/li') screen:expect([[ the first {3:li}ne │the first {2:li}ne | in a {2:li}ttle file │in a {2:li}ttle file | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*4 /li^ | ]]) -- check that consecutive matches are caught by C-g/C-t - feed("<C-g>") + feed('<C-g>') screen:expect([[ the first {2:li}ne │the first {2:li}ne | in a {3:li}ttle file │in a {2:li}ttle file | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*4 /li^ | ]]) - feed("<C-t>") + feed('<C-t>') screen:expect([[ the first {3:li}ne │the first {2:li}ne | in a {2:li}ttle file │in a {2:li}ttle file | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*4 /li^ | ]]) - feed("t") + feed('t') screen:expect([[ the first line │the first line | in a {3:lit}tle file │in a {2:lit}tle file | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*4 /lit^ | ]]) - feed("<cr>") + feed('<cr>') screen:expect([[ the first line │the first line | in a {2:^lit}tle file │in a {2:lit}tle file | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*4 /lit | ]]) - feed("/fir") + feed('/fir') screen:expect([[ the {3:fir}st line │the {2:fir}st line | in a little file │in a little file | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*4 /fir^ | ]]) -- incsearch have priority over hlsearch - feed("<esc>/ttle") + feed('<esc>/ttle') screen:expect([[ the first line │the first line | in a li{3:ttle} file │in a li{2:ttle} file | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*4 /ttle^ | ]]) @@ -448,10 +424,7 @@ describe('search highlighting', function() screen:expect([[ the first line │the first line | in a {2:^lit}tle file │in a {2:lit}tle file | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*4 | ]]) eq('lit', eval('@/')) @@ -461,10 +434,7 @@ describe('search highlighting', function() screen:expect([[ the first line │the first line | in a ^little file │in a little file | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*4 :noh | ]]) @@ -472,20 +442,14 @@ describe('search highlighting', function() screen:expect([[ the {3:first} line │the {2:first} line | in a little file │in a little file | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*4 /first^ | ]]) feed('<esc>') screen:expect([[ the first line │the first line | in a ^little file │in a little file | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*4 | ]]) @@ -494,43 +458,34 @@ describe('search highlighting', function() command([[let @/ = 'i']]) -- moves to next match of previous search pattern, just like /<cr> feed('/<c-g><cr>') - eq({0, 1, 6, 0}, funcs.getpos('.')) + eq({ 0, 1, 6, 0 }, fn.getpos('.')) -- moves to next match of previous search pattern, just like /<cr> feed('/<cr>') - eq({0, 1, 12, 0}, funcs.getpos('.')) + eq({ 0, 1, 12, 0 }, fn.getpos('.')) -- moves to next match of previous search pattern, just like /<cr> feed('/<c-t><cr>') - eq({0, 2, 1, 0}, funcs.getpos('.')) + eq({ 0, 2, 1, 0 }, fn.getpos('.')) -- 8.0.1304, test that C-g and C-t works with incsearch and empty pattern feed('<esc>/fi<CR>') screen:expect([[ the {2:fi}rst line │the {2:fi}rst line | in a little {2:^fi}le │in a little {2:fi}le | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*4 /fi | ]]) feed('//') screen:expect([[ the {3:fi}rst line │the {2:fi}rst line | in a little {2:fi}le │in a little {2:fi}le | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*4 //^ | ]]) feed('<C-g>') screen:expect([[ the {2:fi}rst line │the {2:fi}rst line | in a little {3:fi}le │in a little {2:fi}le | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*4 //^ | ]]) feed('<Esc>') @@ -541,10 +496,7 @@ describe('search highlighting', function() screen:expect([[ the first line │the first line | in a little {3:file} │in a little {2:file} | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*4 /file^ | ]]) feed('<Esc>') @@ -557,10 +509,7 @@ describe('search highlighting', function() screen:expect([[ the {3:first} line │the {2:first} line | in a little file │in a little file | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*4 /first^ | ]]) feed('<Esc>') @@ -570,10 +519,7 @@ describe('search highlighting', function() screen:expect([[ the first line │the first line | in a {3:little} file │in a {2:little} file | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*4 /little^ | ]]) feed('<Esc>') @@ -586,37 +532,28 @@ describe('search highlighting', function() not the match you're looking for the match is here]]) - feed("gg/mat/e") + feed('gg/mat/e') screen:expect([[ not the {3:mat}ch you're looking for | the {2:mat}ch is here | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 /mat/e^ | ]]) -- Search with count and /e offset fixed in Vim patch 7.4.532. - feed("<esc>2/mat/e") + feed('<esc>2/mat/e') screen:expect([[ not the {2:mat}ch you're looking for | the {3:mat}ch is here | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 /mat/e^ | ]]) - feed("<cr>") + feed('<cr>') screen:expect([[ not the {2:mat}ch you're looking for | the {2:ma^t}ch is here | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 /mat/e | ]]) end) @@ -628,8 +565,7 @@ describe('search highlighting', function() screen:expect([[ | a repeated {2:^line } | - {2:a} repeated {2:line } | - {2:a} repeated {2:line } | + {2:a} repeated {2:line } |*2 {2:a} repeated line | {1:~ }| {4:search hit BOTTOM, continuing at TOP} | @@ -650,83 +586,80 @@ describe('search highlighting', function() it('works with matchadd and syntax', function() screen:set_default_attr_ids { - [1] = {bold=true, foreground=Screen.colors.Blue}; - [2] = {background = Screen.colors.Yellow}; - [3] = {reverse = true}; - [4] = {foreground = Screen.colors.Red}; - [5] = {bold = true, background = Screen.colors.Green}; - [6] = {italic = true, background = Screen.colors.Magenta}; - [7] = {bold = true, background = Screen.colors.Yellow}; - [8] = {foreground = Screen.colors.Blue4, background = Screen.colors.LightGray}; + [1] = { bold = true, foreground = Screen.colors.Blue }, + [2] = { background = Screen.colors.Yellow }, + [3] = { reverse = true }, + [4] = { foreground = Screen.colors.Red }, + [5] = { bold = true, background = Screen.colors.Green }, + [6] = { italic = true, background = Screen.colors.Magenta }, + [7] = { bold = true, background = Screen.colors.Yellow }, + [8] = { foreground = Screen.colors.Blue4, background = Screen.colors.LightGray }, } feed_command('set hlsearch') insert [[ very special text ]] - feed_command("syntax on") - feed_command("highlight MyGroup guibg=Green gui=bold") - feed_command("highlight MyGroup2 guibg=Magenta gui=italic") + feed_command('syntax on') + feed_command('highlight MyGroup guibg=Green gui=bold') + feed_command('highlight MyGroup2 guibg=Magenta gui=italic') feed_command("call matchadd('MyGroup', 'special')") feed_command("call matchadd('MyGroup2', 'text', 0)") -- searchhl and matchadd matches are exclusive, only the highest priority -- is used (and matches with lower priorities are not combined) - feed_command("/ial te") - screen:expect{grid=[[ + feed_command('/ial te') + screen:expect { + grid = [[ very {5:spec^ial}{2: te}{6:xt} | | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {4:search hit BOTTOM, continuing at TOP} | - ]], win_viewport={ - [2] = {win = {id = 1000}, topline = 0, botline = 3, curline = 0, curcol = 11, linecount = 2, sum_scroll_delta = 0}; - }} + ]], + win_viewport = { + [2] = { + win = 1000, + topline = 0, + botline = 3, + curline = 0, + curcol = 11, + linecount = 2, + sum_scroll_delta = 0, + }, + }, + } -- check highlights work also in folds - feed("zf4j") - screen:expect{grid=[[ + feed('zf4j') + screen:expect { + grid = [[ {8:^+-- 2 lines: very special text·········}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 {4:search hit BOTTOM, continuing at TOP} | - ]]} - command("%foldopen") + ]], + } + command('%foldopen') screen:expect([[ very {5:spec^ial}{2: te}{6:xt} | | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 {4:search hit BOTTOM, continuing at TOP} | ]]) - feed_command("call clearmatches()") + feed_command('call clearmatches()') screen:expect([[ very spec{2:^ial te}xt | | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 :call clearmatches() | ]]) -- searchhl has priority over syntax, but in this case -- nonconflicting attributes are combined - feed_command("syntax keyword MyGroup special") + feed_command('syntax keyword MyGroup special') screen:expect([[ very {5:spec}{7:^ial}{2: te}xt | | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 :syntax keyword MyGroup special | ]]) end) @@ -737,13 +670,8 @@ describe('search highlighting', function() feed(':%g@a/b') screen:expect([[ {3:a/b}/c | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 :%g@a/b^ | ]]) end) end) - diff --git a/test/functional/ui/sign_spec.lua b/test/functional/ui/sign_spec.lua index b12e79bd42..847a918dc9 100644 --- a/test/functional/ui/sign_spec.lua +++ b/test/functional/ui/sign_spec.lua @@ -1,8 +1,7 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local clear, feed, command = helpers.clear, helpers.feed, helpers.command -local source = helpers.source -local meths = helpers.meths +local api, clear, eq = helpers.api, helpers.clear, helpers.eq +local eval, exec, feed = helpers.eval, helpers.exec, helpers.feed describe('Signs', function() local screen @@ -11,90 +10,68 @@ describe('Signs', function() clear() screen = Screen.new() screen:attach() - screen:set_default_attr_ids( { - [0] = {bold=true, foreground=255}, - [1] = {background = Screen.colors.Yellow}, - [2] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.Grey}, - [3] = {background = Screen.colors.Gray90}, - [4] = {bold = true, reverse = true}, - [5] = {reverse = true}, - [6] = {foreground = Screen.colors.Brown}, - [7] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey}, - [8] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [9] = {bold = true, foreground = Screen.colors.Magenta}, - [10] = {foreground = Screen.colors.Blue1}, - [11] = {bold = true, foreground = Screen.colors.SeaGreen4}, - } ) + screen:set_default_attr_ids({ + [0] = { bold = true, foreground = 255 }, + [1] = { background = Screen.colors.Yellow }, + [2] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.Grey }, + [3] = { background = Screen.colors.Gray90 }, + [4] = { bold = true, reverse = true }, + [5] = { reverse = true }, + [6] = { foreground = Screen.colors.Brown }, + [7] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey }, + [8] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [9] = { bold = true, foreground = Screen.colors.Magenta }, + [10] = { foreground = Screen.colors.Blue1 }, + [11] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + }) end) describe(':sign place', function() it('allows signs with combining characters', function() feed('ia<cr>b<cr><esc>') - command('sign define piet1 text=𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄ texthl=Search') - command('sign define piet2 text=𠜎̀́̂̃̄̅ texthl=Search') - command('sign place 1 line=1 name=piet1 buffer=1') - command('sign place 2 line=2 name=piet2 buffer=1') + exec([[ + sign define piet1 text=𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄ texthl=Search + sign define piet2 text=𠜎̀́̂̃̄̅ texthl=Search + sign place 1 line=1 name=piet1 buffer=1 + sign place 2 line=2 name=piet2 buffer=1 + ]]) screen:expect([[ {1:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}a | {1:𠜎̀́̂̃̄̅}b | {2: }^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*10 | ]]) end) it('shadows previously placed signs', function() feed('ia<cr>b<cr>c<cr><esc>') - command('sign define piet text=>> texthl=Search') - command('sign define pietx text=>! texthl=Search') - command('sign place 1 line=1 name=piet buffer=1') - command('sign place 2 line=3 name=piet buffer=1') - command('sign place 3 line=1 name=pietx buffer=1') + exec([[ + sign define piet text=>> texthl=Search + sign define pietx text=>! texthl=Search + sign place 1 line=1 name=piet buffer=1 + sign place 2 line=3 name=piet buffer=1 + sign place 3 line=1 name=pietx buffer=1 + ]]) screen:expect([[ {1:>!}a | {2: }b | {1:>>}c | {2: }^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 | ]]) end) it('allows signs with no text', function() feed('ia<cr>b<cr><esc>') - command('sign define piet1 text= texthl=Search') - command('sign place 1 line=1 name=piet1 buffer=1') + exec('sign define piet1 text= texthl=Search') + exec('sign place 1 line=1 name=piet1 buffer=1') screen:expect([[ a | b | ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*10 | ]]) end) @@ -104,7 +81,7 @@ describe('Signs', function() -- This used to cause a crash due to :sign using a special redraw -- (not updating nvim's specific highlight data structures) -- without proper redraw first, as split just flags for redraw later. - source([[ + exec([[ set cursorline sign define piet text=>> texthl=Search split @@ -115,8 +92,7 @@ describe('Signs', function() {1:>>}b | {2: }c | {2: } | - {0:~ }| - {0:~ }| + {0:~ }|*2 {4:[No Name] [+] }| {2: }{3:a }| {1:>>}b | @@ -130,58 +106,45 @@ describe('Signs', function() it('can combine text, linehl and numhl', function() feed('ia<cr>b<cr>c<cr><esc>') - command('set number') - command('sign define piet text=>> texthl=Search') - command('sign define pietx linehl=ErrorMsg') - command('sign define pietxx numhl=Folded') - command('sign place 1 line=1 name=piet buffer=1') - command('sign place 2 line=2 name=pietx buffer=1') - command('sign place 3 line=3 name=pietxx buffer=1') - command('sign place 4 line=4 name=piet buffer=1') - command('sign place 5 line=4 name=pietx buffer=1') - command('sign place 6 line=4 name=pietxx buffer=1') + exec([[ + set number + sign define piet text=>> texthl=Search + sign define pietx linehl=ErrorMsg + sign define pietxx numhl=Folded + sign place 1 line=1 name=piet buffer=1 + sign place 2 line=2 name=pietx buffer=1 + sign place 3 line=3 name=pietxx buffer=1 + sign place 4 line=4 name=piet buffer=1 + sign place 5 line=4 name=pietx buffer=1 + sign place 6 line=4 name=pietxx buffer=1 + ]]) screen:expect([[ {1:>>}{6: 1 }a | {2: }{6: 2 }{8:b }| {2: }{7: 3 }c | {1:>>}{7: 4 }{8:^ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 | ]]) -- Check that 'statuscolumn' correctly applies numhl - command('set statuscolumn=%s%=%l\\ ') + exec('set statuscolumn=%s%=%l\\ ') screen:expect_unchanged() end) it('highlights the cursorline sign with culhl', function() feed('ia<cr>b<cr>c<esc>') - command('sign define piet text=>> texthl=Search culhl=ErrorMsg') - command('sign place 1 line=1 name=piet buffer=1') - command('sign place 2 line=2 name=piet buffer=1') - command('sign place 3 line=3 name=piet buffer=1') - command('set cursorline') + exec([[ + sign define piet text=>> texthl=Search culhl=ErrorMsg + sign place 1 line=1 name=piet buffer=1 + sign place 2 line=2 name=piet buffer=1 + sign place 3 line=3 name=piet buffer=1 + set cursorline + ]]) screen:expect([[ {1:>>}a | {1:>>}b | {8:>>}{3:^c }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*10 | ]]) feed('k') @@ -189,411 +152,304 @@ describe('Signs', function() {1:>>}a | {8:>>}{3:^b }| {1:>>}c | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*10 | ]]) - command('set nocursorline') + exec('set nocursorline') screen:expect([[ {1:>>}a | {1:>>}^b | {1:>>}c | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*10 | ]]) - command('set cursorline cursorlineopt=line') + exec('set cursorline cursorlineopt=line') screen:expect([[ {1:>>}a | {1:>>}{3:^b }| {1:>>}c | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*10 | ]]) - command('set cursorlineopt=number') - command('hi! link SignColumn IncSearch') + exec('set cursorlineopt=number') + exec('hi! link SignColumn IncSearch') feed('Go<esc>2G') screen:expect([[ {1:>>}a | {8:>>}^b | {1:>>}c | {5: } | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 | ]]) -- Check that 'statuscolumn' cursorline/signcolumn highlights are the same (#21726) - command('set statuscolumn=%s') + exec('set statuscolumn=%s') screen:expect_unchanged() end) it('multiple signs #9295', function() feed('ia<cr>b<cr>c<cr><esc>') - command('set number') - command('set signcolumn=yes:2') - command('sign define pietSearch text=>> texthl=Search') - command('sign define pietError text=XX texthl=Error') - command('sign define pietWarn text=WW texthl=Warning') - command('sign place 1 line=1 name=pietSearch buffer=1') - command('sign place 2 line=1 name=pietError buffer=1') - -- Line 2 helps checking that signs in the same line are ordered by Id. - command('sign place 4 line=2 name=pietSearch buffer=1') - command('sign place 3 line=2 name=pietError buffer=1') + exec([[ + set number + set signcolumn=yes:2 + sign define pietSearch text=>> texthl=Search + sign define pietError text=XX texthl=Error + sign define pietWarn text=WW texthl=Warning + sign place 6 line=3 name=pietSearch buffer=1 + sign place 7 line=3 name=pietWarn buffer=1 + sign place 5 line=3 name=pietError buffer=1 + ]]) -- Line 3 checks that with a limit over the maximum number -- of signs, the ones with the highest Ids are being picked, -- and presented by their sorted Id order. - command('sign place 6 line=3 name=pietSearch buffer=1') - command('sign place 7 line=3 name=pietWarn buffer=1') - command('sign place 5 line=3 name=pietError buffer=1') + screen:expect([[ + {2: }{6: 1 }a | + {2: }{6: 2 }b | + {1:>>}WW{6: 3 }c | + {2: }{6: 4 }^ | + {0:~ }|*9 + | + ]]) + exec([[ + sign place 1 line=1 name=pietSearch buffer=1 + sign place 2 line=1 name=pietError buffer=1 + " Line 2 helps checking that signs in the same line are ordered by Id. + sign place 4 line=2 name=pietSearch buffer=1 + sign place 3 line=2 name=pietError buffer=1 + ]]) screen:expect([[ {1:>>}{8:XX}{6: 1 }a | {8:XX}{1:>>}{6: 2 }b | {1:>>}WW{6: 3 }c | {2: }{6: 4 }^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 | ]]) -- With the default setting, we get the sign with the top id. - command('set signcolumn=yes:1') + exec('set signcolumn=yes:1') screen:expect([[ {8:XX}{6: 1 }a | {1:>>}{6: 2 }b | WW{6: 3 }c | {2: }{6: 4 }^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 | ]]) -- "auto:3" accommodates all the signs we defined so far. - command('set signcolumn=auto:3') - screen:expect([[ + exec('set signcolumn=auto:3') + local s3 = [[ {1:>>}{8:XX}{2: }{6: 1 }a | {8:XX}{1:>>}{2: }{6: 2 }b | {8:XX}{1:>>}WW{6: 3 }c | {2: }{6: 4 }^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 | - ]]) + ]] + screen:expect(s3) -- Check "yes:9". - command('set signcolumn=yes:9') + exec('set signcolumn=yes:9') screen:expect([[ {1:>>}{8:XX}{2: }{6: 1 }a | {8:XX}{1:>>}{2: }{6: 2 }b | {8:XX}{1:>>}WW{2: }{6: 3 }c | {2: }{6: 4 }^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 | ]]) -- Check "auto:N" larger than the maximum number of signs defined in -- a single line (same result as "auto:3"). - command('set signcolumn=auto:4') - screen:expect{grid=[[ - {1:>>}{8:XX}{2: }{6: 1 }a | - {8:XX}{1:>>}{2: }{6: 2 }b | - {8:XX}{1:>>}WW{6: 3 }c | - {2: }{6: 4 }^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - | - ]]} + exec('set signcolumn=auto:4') + screen:expect(s3) -- line deletion deletes signs. - command('2d') + exec('3move1') + exec('2d') screen:expect([[ - {1:>>}{8:XX}{2: }{6: 1 }a | - {8:XX}{1:>>}WW{6: 2 }^c | - {2: }{6: 3 } | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {1:>>}{8:XX}{6: 1 }a | + {8:XX}{1:>>}{6: 2 }^b | + {2: }{6: 3 } | + {0:~ }|*10 + | + ]]) + -- character deletion does not delete signs. + feed('x') + screen:expect([[ + {1:>>}{8:XX}{6: 1 }a | + {8:XX}{1:>>}{6: 2 }^ | + {2: }{6: 3 } | + {0:~ }|*10 | ]]) end) it('auto-resize sign column with minimum size (#13783)', function() feed('ia<cr>b<cr>c<cr><esc>') - command('set number') + exec('set number') -- sign column should always accommodate at the minimum size - command('set signcolumn=auto:1-3') + exec('set signcolumn=auto:1-3') screen:expect([[ {2: }{6: 1 }a | {2: }{6: 2 }b | {2: }{6: 3 }c | {2: }{6: 4 }^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 | ]]) -- should support up to 8 signs at minimum - command('set signcolumn=auto:8-9') + exec('set signcolumn=auto:8-9') screen:expect([[ {2: }{6: 1 }a | {2: }{6: 2 }b | {2: }{6: 3 }c | {2: }{6: 4 }^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 | ]]) -- should keep the same sign size when signs are not exceeding -- the minimum - command('set signcolumn=auto:2-5') - command('sign define pietSearch text=>> texthl=Search') - command('sign place 1 line=1 name=pietSearch buffer=1') + exec('set signcolumn=auto:2-5') + exec('sign define pietSearch text=>> texthl=Search') + exec('sign place 1 line=1 name=pietSearch buffer=1') screen:expect([[ {1:>>}{2: }{6: 1 }a | {2: }{6: 2 }b | {2: }{6: 3 }c | {2: }{6: 4 }^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 | ]]) -- should resize itself when signs are exceeding minimum but -- not over the maximum - command('sign place 2 line=1 name=pietSearch buffer=1') - command('sign place 3 line=1 name=pietSearch buffer=1') - command('sign place 4 line=1 name=pietSearch buffer=1') + exec([[ + sign place 2 line=1 name=pietSearch buffer=1 + sign place 3 line=1 name=pietSearch buffer=1 + sign place 4 line=1 name=pietSearch buffer=1 + ]]) screen:expect([[ {1:>>>>>>>>}{6: 1 }a | {2: }{6: 2 }b | {2: }{6: 3 }c | {2: }{6: 4 }^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 | ]]) -- should not increase size because sign with existing id is moved - command('sign place 4 line=1 name=pietSearch buffer=1') + exec('sign place 4 line=1 name=pietSearch buffer=1') screen:expect_unchanged() - command('sign unplace 4') + exec('sign unplace 4') screen:expect([[ {1:>>>>>>}{6: 1 }a | {2: }{6: 2 }b | {2: }{6: 3 }c | {2: }{6: 4 }^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 | ]]) - command('sign place 4 line=1 name=pietSearch buffer=1') + exec('sign place 4 line=1 name=pietSearch buffer=1') -- should keep the column at maximum size when signs are -- exceeding the maximum - command('sign place 5 line=1 name=pietSearch buffer=1') - command('sign place 6 line=1 name=pietSearch buffer=1') - command('sign place 7 line=1 name=pietSearch buffer=1') - command('sign place 8 line=1 name=pietSearch buffer=1') + exec([[ + sign place 5 line=1 name=pietSearch buffer=1 + sign place 6 line=1 name=pietSearch buffer=1 + sign place 7 line=1 name=pietSearch buffer=1 + sign place 8 line=1 name=pietSearch buffer=1 + ]]) screen:expect([[ {1:>>>>>>>>>>}{6: 1 }a | {2: }{6: 2 }b | {2: }{6: 3 }c | {2: }{6: 4 }^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 | ]]) end) it('ignores signs with no icon and text when calculating the signcolumn width', function() feed('ia<cr>b<cr>c<cr><esc>') - command('set number') - command('set signcolumn=auto:2') - command('sign define pietSearch text=>> texthl=Search') - command('sign define pietError text= texthl=Error') - command('sign place 2 line=1 name=pietError buffer=1') + exec([[ + set number + set signcolumn=auto:2 + sign define pietSearch text=>> texthl=Search + sign define pietError text= texthl=Error + sign place 2 line=1 name=pietError buffer=1 + ]]) -- no signcolumn with only empty sign screen:expect([[ {6: 1 }a | {6: 2 }b | {6: 3 }c | {6: 4 }^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 | ]]) -- single column with 1 sign with text and one sign without - command('sign place 1 line=1 name=pietSearch buffer=1') + exec('sign place 1 line=1 name=pietSearch buffer=1') screen:expect([[ {1:>>}{6: 1 }a | {2: }{6: 2 }b | {2: }{6: 3 }c | {2: }{6: 4 }^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 | ]]) end) - it('shows the line number when signcolumn=number but no marks on a line have text', function() + it('signcolumn=number', function() feed('ia<cr>b<cr>c<cr><esc>') - command('set number signcolumn=number') - command('sign define pietSearch text=>> texthl=Search numhl=Error') - command('sign define pietError text= texthl=Search numhl=Error') - command('sign place 1 line=1 name=pietSearch buffer=1') - command('sign place 2 line=2 name=pietError buffer=1') + exec([[ + set number signcolumn=number + sign define pietSearch text=>> texthl=Search numhl=Error + sign define pietError text= texthl=Search numhl=Error + sign place 1 line=1 name=pietSearch buffer=1 + sign place 2 line=2 name=pietError buffer=1 + ]]) + -- line number should be drawn if sign has no text -- no signcolumn, line number for "a" is Search, for "b" is Error, for "c" is LineNr screen:expect([[ {1: >> }a | {8: 2 }b | {6: 3 }c | {6: 4 }^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 + | + ]]) + -- number column on wrapped part of a line should be empty + feed('gg100aa<Esc>') + screen:expect([[ + {1: >> }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + {8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + {8: }aa^a | + {8: 2 }b | + {6: 3 }c | + {6: 4 } | + {0:~ }|*7 + | + ]]) + api.nvim_buf_set_extmark(0, api.nvim_create_namespace('test'), 0, 0, { + virt_lines = { { { 'VIRT LINES' } } }, + virt_lines_above = true, + }) + feed('<C-Y>') + -- number column on virtual lines should be empty + screen:expect([[ + {6: }VIRT LINES | + {1: >> }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + {8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + {8: }aa^a | + {8: 2 }b | + {6: 3 }c | + {6: 4 } | + {0:~ }|*6 | ]]) end) it('can have 32bit sign IDs', function() - command('sign define piet text=>> texthl=Search') - command('sign place 100000 line=1 name=piet buffer=1') + exec('sign define piet text=>> texthl=Search') + exec('sign place 100000 line=1 name=piet buffer=1') feed(':sign place<cr>') screen:expect([[ {1:>>} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 {4: }| :sign place | {9:--- Signs ---} | @@ -606,72 +462,45 @@ describe('Signs', function() feed('<cr>') screen:expect([[ {1:>>}^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*12 | ]]) end) end) it('signcolumn width is updated when removing all signs after deleting lines', function() - meths.buf_set_lines(0, 0, 1, true, {'a', 'b', 'c', 'd', 'e'}) - command('sign define piet text=>>') - command('sign place 10001 line=1 name=piet') - command('sign place 10002 line=5 name=piet') - command('2delete') - command('sign unplace 10001') + api.nvim_buf_set_lines(0, 0, 1, true, { 'a', 'b', 'c', 'd', 'e' }) + exec('sign define piet text=>>') + exec('sign place 10001 line=1 name=piet') + exec('sign place 10002 line=5 name=piet') + exec('2delete') + exec('sign unplace 10001') screen:expect([[ {2: }a | {2: }^c | {2: }d | >>e | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 | ]]) - command('sign unplace 10002') + exec('sign unplace 10002') screen:expect([[ a | ^c | d | e | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 | ]]) end) it('signcolumn width is updated when removing all signs after inserting lines', function() - meths.buf_set_lines(0, 0, 1, true, {'a', 'b', 'c', 'd', 'e'}) - command('sign define piet text=>>') - command('sign place 10001 line=1 name=piet') - command('sign place 10002 line=5 name=piet') - command('copy .') - command('sign unplace 10001') + api.nvim_buf_set_lines(0, 0, 1, true, { 'a', 'b', 'c', 'd', 'e' }) + exec('sign define piet text=>>') + exec('sign place 10001 line=1 name=piet') + exec('sign place 10002 line=5 name=piet') + exec('copy .') + exec('sign unplace 10001') screen:expect([[ {2: }a | {2: }^a | @@ -679,16 +508,10 @@ describe('Signs', function() {2: }c | {2: }d | >>e | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*7 | ]]) - command('sign unplace 10002') + exec('sign unplace 10002') screen:expect([[ a | ^a | @@ -696,20 +519,14 @@ describe('Signs', function() c | d | e | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*7 | ]]) end) it('numhl highlight is applied when signcolumn=no', function() screen:try_resize(screen._width, 4) - command([[ + exec([[ set nu scl=no call setline(1, ['line1', 'line2', 'line3']) call nvim_buf_set_extmark(0, nvim_create_namespace('test'), 0, 0, {'number_hl_group':'Error'}) @@ -723,4 +540,39 @@ describe('Signs', function() | ]]) end) + + it('no negative b_signcols.count with undo after initializing', function() + exec([[ + set signcolumn=auto:2 + call setline(1, 'a') + call nvim_buf_set_extmark(0, nvim_create_namespace(''), 0, 0, {'sign_text':'S1'}) + delete | redraw | undo + ]]) + end) + + it('sign not shown on line it was previously on after undo', function() + exec([[ + call setline(1, range(1, 4)) + call nvim_buf_set_extmark(0, nvim_create_namespace(''), 1, 0, {'sign_text':'S1'}) + ]]) + exec('norm 2Gdd') + exec('silent undo') + screen:expect([[ + {2: }1 | + S1^2 | + {2: }3 | + {2: }4 | + {0:~ }|*9 + | + ]]) + end) + + it('sign_undefine() frees all signs', function() + exec([[ + sign define 1 text=1 + sign define 2 text=2 + call sign_undefine() + ]]) + eq({}, eval('sign_getdefined()')) + end) end) diff --git a/test/functional/ui/spell_spec.lua b/test/functional/ui/spell_spec.lua index d18e19e5b2..8b5644ee42 100644 --- a/test/functional/ui/spell_spec.lua +++ b/test/functional/ui/spell_spec.lua @@ -6,8 +6,7 @@ local clear = helpers.clear local exec = helpers.exec local feed = helpers.feed local insert = helpers.insert -local meths = helpers.meths -local curbufmeths = helpers.curbufmeths +local api = helpers.api local is_os = helpers.is_os describe("'spell'", function() @@ -17,23 +16,26 @@ describe("'spell'", function() clear() screen = Screen.new(80, 8) screen:attach() - screen:set_default_attr_ids( { - [0] = {bold=true, foreground=Screen.colors.Blue}, - [1] = {special = Screen.colors.Red, undercurl = true}, - [2] = {special = Screen.colors.Blue, undercurl = true}, - [3] = {foreground = tonumber('0x6a0dad')}, - [4] = {foreground = Screen.colors.Magenta}, - [5] = {bold = true, foreground = Screen.colors.SeaGreen}, - [6] = {foreground = Screen.colors.Red}, - [7] = {foreground = Screen.colors.Blue}, - [8] = {foreground = Screen.colors.Blue, special = Screen.colors.Red, undercurl = true}, - [9] = {bold = true}, - [10] = {background = Screen.colors.LightGrey, foreground = Screen.colors.DarkBlue}, + screen:set_default_attr_ids({ + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { special = Screen.colors.Red, undercurl = true }, + [2] = { special = Screen.colors.Blue, undercurl = true }, + [3] = { foreground = tonumber('0x6a0dad') }, + [4] = { foreground = Screen.colors.Magenta }, + [5] = { bold = true, foreground = Screen.colors.SeaGreen }, + [6] = { foreground = Screen.colors.Red }, + [7] = { foreground = Screen.colors.Blue }, + [8] = { foreground = Screen.colors.Blue, special = Screen.colors.Red, undercurl = true }, + [9] = { bold = true }, + [10] = { background = Screen.colors.LightGrey, foreground = Screen.colors.DarkBlue }, }) end) it('joins long lines #7937', function() - if is_os('openbsd') then pending('FIXME #12104', function() end) return end + if is_os('openbsd') then + pending('FIXME #12104', function() end) + return + end exec('set spell') insert([[ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod @@ -54,7 +56,6 @@ describe("'spell'", function() {0:~ }| | ]]) - end) -- oldtest: Test_spell_screendump() @@ -125,8 +126,7 @@ describe("'spell'", function() Not | and her^e | and here. | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) -- Undo also updates the next line (go to command line to remove message) @@ -137,8 +137,7 @@ describe("'spell'", function() Not | and here^. | {2:and} here. | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) -- Folding an empty line does not remove Cap in next line @@ -149,8 +148,7 @@ describe("'spell'", function() Not | {10:^+-- 2 lines: and here.·························································}| {2:and} here. | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) -- Folding the end of a sentence does not remove Cap in next line @@ -161,9 +159,7 @@ describe("'spell'", function() {2:another} missing cap her^e | {10:+-- 2 lines: Not·······························································}| {2:and} here. | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) -- Cap is correctly applied in the first row of a window @@ -172,10 +168,7 @@ describe("'spell'", function() {2:another} missing cap her^e | {10:+-- 2 lines: Not·······························································}| {2:and} here. | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) -- Adding an empty line does not remove Cap in "mod_bot" area @@ -186,8 +179,7 @@ describe("'spell'", function() {2:another} missing cap here | {10:+-- 2 lines: Not·······························································}| {2:and} here. | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) -- Multiple empty lines does not remove Cap in the line after @@ -220,9 +212,7 @@ describe("'spell'", function() test test test test$ | | {2:end} | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {9:-- INSERT --} | ]]) feed('x') @@ -231,9 +221,7 @@ describe("'spell'", function() test test test test$ | | {2:end} | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {9:-- INSERT --} | ]]) end) @@ -251,10 +239,7 @@ describe("'spell'", function() {3:#include }{4:<stdbool.h>} | {5:bool} func({5:void}); | {7:// I am a }{8:spelin^g}{7: }{8:mistakke} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) feed(']s') @@ -262,10 +247,7 @@ describe("'spell'", function() {3:#include }{4:<stdbool.h>} | {5:bool} func({5:void}); | {7:// I am a }{8:speling}{7: }{8:^mistakke} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) feed(']s') @@ -273,24 +255,18 @@ describe("'spell'", function() {3:#include }{4:<stdbool.h>} | {5:bool} func({5:void}); | {7:// I am a }{8:^speling}{7: }{8:mistakke} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {6:search hit BOTTOM, continuing at TOP} | ]]) exec('echo ""') - local ns = meths.create_namespace("spell") + local ns = api.nvim_create_namespace('spell') -- extmark with spell=true enables spell - local id = curbufmeths.set_extmark(ns, 1, 4, { end_row = 1, end_col = 10, spell = true }) + local id = api.nvim_buf_set_extmark(0, ns, 1, 4, { end_row = 1, end_col = 10, spell = true }) screen:expect([[ {3:#include }{4:<stdbool.h>} | {5:bool} {1:func}({5:void}); | {7:// I am a }{8:^speling}{7: }{8:mistakke} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) feed('[s') @@ -298,23 +274,17 @@ describe("'spell'", function() {3:#include }{4:<stdbool.h>} | {5:bool} {1:^func}({5:void}); | {7:// I am a }{8:speling}{7: }{8:mistakke} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) - curbufmeths.del_extmark(ns, id) + api.nvim_buf_del_extmark(0, ns, id) -- extmark with spell=false disables spell - id = curbufmeths.set_extmark(ns, 2, 18, { end_row = 2, end_col = 26, spell = false }) + id = api.nvim_buf_set_extmark(0, ns, 2, 18, { end_row = 2, end_col = 26, spell = false }) screen:expect([[ {3:#include }{4:<stdbool.h>} | {5:bool} ^func({5:void}); | {7:// I am a }{8:speling}{7: mistakke} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) feed('[s') @@ -322,22 +292,16 @@ describe("'spell'", function() {3:#include }{4:<stdbool.h>} | {5:bool} func({5:void}); | {7:// I am a }{8:^speling}{7: mistakke} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {6:search hit TOP, continuing at BOTTOM} | ]]) exec('echo ""') - curbufmeths.del_extmark(ns, id) + api.nvim_buf_del_extmark(0, ns, id) screen:expect([[ {3:#include }{4:<stdbool.h>} | {5:bool} func({5:void}); | {7:// I am a }{8:^speling}{7: }{8:mistakke} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) feed(']s') @@ -345,10 +309,7 @@ describe("'spell'", function() {3:#include }{4:<stdbool.h>} | {5:bool} func({5:void}); | {7:// I am a }{8:speling}{7: }{8:^mistakke} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) -- "noplainbuffer" shouldn't change spellchecking behavior with syntax enabled @@ -359,10 +320,7 @@ describe("'spell'", function() {3:#include }{4:<stdbool.h>} | {5:bool} func({5:void}); | {7:// I am a }{8:^speling}{7: }{8:mistakke} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) -- no spellchecking with "noplainbuffer" and syntax disabled @@ -371,10 +329,7 @@ describe("'spell'", function() #include <stdbool.h> | bool func(void); | // I am a ^speling mistakke | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) feed(']s') @@ -382,10 +337,7 @@ describe("'spell'", function() #include <stdbool.h> | bool func(void); | // I am a ^speling mistakke | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {6:search hit BOTTOM, continuing at TOP} | ]]) exec('echo ""') @@ -395,10 +347,7 @@ describe("'spell'", function() #include <{1:stdbool}.h> | {1:bool} {1:func}(void); | // I am a {1:^speling} {1:mistakke} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) feed('[s') @@ -406,10 +355,7 @@ describe("'spell'", function() #include <{1:stdbool}.h> | {1:bool} {1:^func}(void); | // I am a {1:speling} {1:mistakke} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) end) @@ -421,8 +367,8 @@ describe("'spell'", function() syntax match Constant "^.*$" call setline(1, "This is some text without any spell errors.") ]]) - local ns = meths.create_namespace("spell") - curbufmeths.set_extmark(ns, 0, 0, { hl_group = 'WarningMsg', end_col = 43 }) + local ns = api.nvim_create_namespace('spell') + api.nvim_buf_set_extmark(0, ns, 0, 0, { hl_group = 'WarningMsg', end_col = 43 }) screen:expect([[ {6:^This is some text without any spell errors.}| {0:~ }| diff --git a/test/functional/ui/statuscolumn_spec.lua b/test/functional/ui/statuscolumn_spec.lua index 6eaf15cfad..41406a5860 100644 --- a/test/functional/ui/statuscolumn_spec.lua +++ b/test/functional/ui/statuscolumn_spec.lua @@ -7,11 +7,11 @@ local exec = helpers.exec local eval = helpers.eval local exec_lua = helpers.exec_lua local feed = helpers.feed -local meths = helpers.meths +local api = helpers.api local pcall_err = helpers.pcall_err local assert_alive = helpers.assert_alive -local mousemodels = { "extend", "popup", "popup_setpos" } +local mousemodels = { 'extend', 'popup', 'popup_setpos' } describe('statuscolumn', function() local screen @@ -23,7 +23,9 @@ describe('statuscolumn', function() end) it("fails with invalid 'statuscolumn'", function() - command([[set stc=%{v:relnum?v:relnum:(v:lnum==5?invalid:v:lnum)}\ ]]) + command( + [[set stc=%{v:relnum?v:relnum:(v:lnum==5?'truncate':v:lnum)}%{!v:relnum&&v:lnum==5?invalid:''}\ ]] + ) screen:expect([[ 4 aaaaa | 3 aaaaa | @@ -43,6 +45,22 @@ describe('statuscolumn', function() command('norm 5G') eq('Vim(redraw):E121: Undefined variable: invalid', pcall_err(command, 'redraw!')) eq('', eval('&statuscolumn')) + screen:expect([[ + 4 aaaaa | + 5 ^aaaaa | + 6 aaaaa | + 7 aaaaa | + 8 aaaaa | + 9 aaaaa | + 10 aaaaa | + 11 aaaaa | + 12 aaaaa | + 13 aaaaa | + 14 aaaaa | + 15 aaaaa | + 16 aaaaa | + | + ]]) end) it("widens with irregular 'statuscolumn' width", function() @@ -59,6 +77,18 @@ describe('statuscolumn', function() 1 aaaaa | | ]]) + -- Doesn't crash when trying to fill click defs that do not fit (#26845) + command('norm gg') + command([=[ + set stc=%@Click@%{v:relnum?v:relnum:(v:lnum==5?'bbbbb':v:lnum)}%T + norm 5Gzt | redraw! + ]=]) + screen:expect([[ + bbbbba^eaaa | + 1 aaaaa | + 2 aaaaa | + | + ]]) end) it("works with 'number' and 'relativenumber'", function() @@ -125,12 +155,14 @@ describe('statuscolumn', function() end) it("works with highlighted 'statuscolumn'", function() - command([[set stc=%#NonText#%{&nu?v:lnum:''}]] .. - [[%=%{&rnu&&(v:lnum%2)?'\ '.v:relnum:''}]] .. - [[%#LineNr#%{&rnu&&!(v:lnum%2)?'\ '.v:relnum:''}│]]) + command( + [[set stc=%#NonText#%{&nu?v:lnum:''}]] + .. [[%=%{&rnu&&(v:lnum%2)?'\ '.v:relnum:''}]] + .. [[%#LineNr#%{&rnu&&!(v:lnum%2)?'\ '.v:relnum:''}│]] + ) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, - [1] = {foreground = Screen.colors.Brown}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { foreground = Screen.colors.Brown }, }) screen:expect([[ {0:4 }{1:│}aaaaa | @@ -188,13 +220,13 @@ describe('statuscolumn', function() command([[set stc=%C%s%=%{v:virtnum?'':v:lnum}│\ ]]) command("call setline(1,repeat([repeat('aaaaa',10)],16))") screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, - [1] = {foreground = Screen.colors.Brown}, - [2] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGrey}, - [3] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey}, - [4] = {bold = true, foreground = Screen.colors.Brown}, - [5] = {foreground = Screen.colors.Red}, - [6] = {foreground = Screen.colors.Red, background = Screen.colors.LightGrey}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { foreground = Screen.colors.Brown }, + [2] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGrey }, + [3] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey }, + [4] = { bold = true, foreground = Screen.colors.Brown }, + [5] = { foreground = Screen.colors.Red }, + [6] = { foreground = Screen.colors.Red, background = Screen.colors.LightGrey }, }) command('hi! CursorLine guifg=Red guibg=NONE') screen:expect([[ @@ -418,7 +450,9 @@ describe('statuscolumn', function() vim.api.nvim_buf_set_extmark(0, ns, 4, 0, { virt_lines = {{{"virt_line", ""}}} }) ]]) command('set foldcolumn=0 signcolumn=no') - command([[set stc=%{v:virtnum<0?'virtual':(!v:virtnum?'buffer':'wrapped')}%=%{'\ '.v:virtnum.'\ '.v:lnum}]]) + command( + [[set stc=%{v:virtnum<0?'virtual':(!v:virtnum?'buffer':'wrapped')}%=%{'\ '.v:virtnum.'\ '.v:lnum}]] + ) screen:expect([[ {1:buffer 0 4}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| {1:wrapped 1 4}aaaaaaaa | @@ -451,9 +485,7 @@ describe('statuscolumn', function() {4:wrapped 1 15}{5:aaaaaaaaa^ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}| {4:wrapped 2 15}{5:aaaaaaaaaaaaaaaaaaa }| {1:virtual-1 15}END | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) -- Also test virt_lines when 'cpoptions' includes "n" @@ -478,19 +510,57 @@ describe('statuscolumn', function() {0:~ }| | ]]) + -- Also test "col_rows" code path for 'relativenumber' cursor movement + command([[ + set cpoptions-=n nocursorline relativenumber + set stc=%{v:virtnum<0?'virtual':(!v:virtnum?'buffer':'wrapped')}%=%{'\ '.v:virtnum.'\ '.v:lnum.'\ '.v:relnum} + ]]) + screen:expect([[ + {1:buffer 0 12 3}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + {1:wrapped 1 12 3}aaaaaaaaaaa | + {1:buffer 0 13 2}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + {1:wrapped 1 13 2}aaaaaaaaaaa | + {1:buffer 0 14 1}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + {1:wrapped 1 14 1}aaaaaaaaaaa | + {1:buffer 0 15 0}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + {1:wrapped 1 15 0}aaaaaaaaaaa^ aaaaaaaaaaaaaaaaaaaaaaaaaaa| + {1:wrapped 2 15 0}aaaaaaaaaaaaaaaaaaaaaaa | + {1:virtual-3 15 0}virt_line1 | + {1:virtual-2 15 0}virt_line2 | + {1:virtual-1 15 0}END | + {0:~ }| + | + ]]) + feed('kk') + screen:expect([[ + {1:buffer 0 12 1}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + {1:wrapped 1 12 1}aaaaaaaaaaa | + {1:buffer 0 13 0}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + {1:wrapped 1 13 0}aaaaaaaaaa^a | + {1:buffer 0 14 1}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + {1:wrapped 1 14 1}aaaaaaaaaaa | + {1:buffer 0 15 2}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + {1:wrapped 1 15 2}aaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaa| + {1:wrapped 2 15 2}aaaaaaaaaaaaaaaaaaaaaaa | + {1:virtual-3 15 2}virt_line1 | + {1:virtual-2 15 2}virt_line2 | + {1:virtual-1 15 2}END | + {0:~ }| + | + ]]) end) it('does not corrupt the screen with minwid sign item', function() screen:try_resize(screen._width, 3) screen:set_default_attr_ids({ - [0] = {foreground = Screen.colors.Brown}, - [1] = {foreground = Screen.colors.Blue4, background = Screen.colors.Gray}, + [0] = { foreground = Screen.colors.Brown }, + [1] = { foreground = Screen.colors.Blue4, background = Screen.colors.Gray }, }) command([[set stc=%6s\ %l]]) exec_lua('vim.api.nvim_buf_set_extmark(0, ns, 7, 0, {sign_text = "𒀀"})') screen:expect([[ - {0: 𒀀 8}^aaaaa | - {0: }{1: }{0: 9}aaaaa | + {0: 𒀀 8 }^aaaaa | + {0: }{1: }{0: 9 }aaaaa | | ]]) end) @@ -511,92 +581,85 @@ describe('statuscolumn', function() end) it('clicks work with mousemodel=' .. model, function() - meths.set_option_value('statuscolumn', '%0@MyClickFunc@%=%l%T', {}) - meths.input_mouse('left', 'press', '', 0, 0, 0) - eq('0 1 l 4', eval("g:testvar")) - meths.input_mouse('left', 'press', '', 0, 0, 0) - eq('0 2 l 4', eval("g:testvar")) - meths.input_mouse('left', 'press', '', 0, 0, 0) - eq('0 3 l 4', eval("g:testvar")) - meths.input_mouse('left', 'press', '', 0, 0, 0) - eq('0 4 l 4', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 3, 0) - eq('0 1 r 7', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 3, 0) - eq('0 2 r 7', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 3, 0) - eq('0 3 r 7', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 3, 0) - eq('0 4 r 7', eval("g:testvar")) + api.nvim_set_option_value('statuscolumn', '%0@MyClickFunc@%=%l%T', {}) + api.nvim_input_mouse('left', 'press', '', 0, 0, 0) + eq('0 1 l 4', eval('g:testvar')) + api.nvim_input_mouse('left', 'press', '', 0, 0, 0) + eq('0 2 l 4', eval('g:testvar')) + api.nvim_input_mouse('left', 'press', '', 0, 0, 0) + eq('0 3 l 4', eval('g:testvar')) + api.nvim_input_mouse('left', 'press', '', 0, 0, 0) + eq('0 4 l 4', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 3, 0) + eq('0 1 r 7', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 3, 0) + eq('0 2 r 7', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 3, 0) + eq('0 3 r 7', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 3, 0) + eq('0 4 r 7', eval('g:testvar')) command('rightbelow vsplit') - meths.input_mouse('left', 'press', '', 0, 0, 27) - eq('0 1 l 4', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 3, 27) - eq('0 1 r 7', eval("g:testvar")) + api.nvim_input_mouse('left', 'press', '', 0, 0, 27) + eq('0 1 l 4', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 3, 27) + eq('0 1 r 7', eval('g:testvar')) command('setlocal rightleft') - meths.input_mouse('left', 'press', '', 0, 0, 52) - eq('0 1 l 4', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 3, 52) - eq('0 1 r 7', eval("g:testvar")) + api.nvim_input_mouse('left', 'press', '', 0, 0, 52) + eq('0 1 l 4', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 3, 52) + eq('0 1 r 7', eval('g:testvar')) command('wincmd H') - meths.input_mouse('left', 'press', '', 0, 0, 25) - eq('0 1 l 4', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 3, 25) - eq('0 1 r 7', eval("g:testvar")) + api.nvim_input_mouse('left', 'press', '', 0, 0, 25) + eq('0 1 l 4', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 3, 25) + eq('0 1 r 7', eval('g:testvar')) command('close') command('set laststatus=2 winbar=%f') command('let g:testvar = ""') -- Check that winbar click doesn't register as statuscolumn click - meths.input_mouse('right', 'press', '', 0, 0, 0) - eq('', eval("g:testvar")) + api.nvim_input_mouse('right', 'press', '', 0, 0, 0) + eq('', eval('g:testvar')) -- Check that statusline click doesn't register as statuscolumn click - meths.input_mouse('right', 'press', '', 0, 12, 0) - eq('', eval("g:testvar")) + api.nvim_input_mouse('right', 'press', '', 0, 12, 0) + eq('', eval('g:testvar')) -- Check that cmdline click doesn't register as statuscolumn click - meths.input_mouse('right', 'press', '', 0, 13, 0) - eq('', eval("g:testvar")) + api.nvim_input_mouse('right', 'press', '', 0, 13, 0) + eq('', eval('g:testvar')) end) it('clicks and highlights work with control characters', function() - meths.set_option_value('statuscolumn', '\t%#NonText#\1%0@MyClickFunc@\t\1%T\t%##\1', {}) - screen:expect{grid=[[ - {1:^I}{0:^A^I^A^I}{1:^A}aaaaa | - {1:^I}{0:^A^I^A^I}{1:^A}aaaaa | - {1:^I}{0:^A^I^A^I}{1:^A}aaaaa | - {1:^I}{0:^A^I^A^I}{1:^A}aaaaa | + api.nvim_set_option_value('statuscolumn', '\t%#NonText#\1%0@MyClickFunc@\t\1%T\t%##\1', {}) + screen:expect { + grid = [[ + {1:^I}{0:^A^I^A^I}{1:^A}aaaaa |*4 {1:^I}{0:^A^I^A^I}{1:^A}^aaaaa | - {1:^I}{0:^A^I^A^I}{1:^A}aaaaa | - {1:^I}{0:^A^I^A^I}{1:^A}aaaaa | - {1:^I}{0:^A^I^A^I}{1:^A}aaaaa | - {1:^I}{0:^A^I^A^I}{1:^A}aaaaa | - {1:^I}{0:^A^I^A^I}{1:^A}aaaaa | - {1:^I}{0:^A^I^A^I}{1:^A}aaaaa | - {1:^I}{0:^A^I^A^I}{1:^A}aaaaa | - {1:^I}{0:^A^I^A^I}{1:^A}aaaaa | + {1:^I}{0:^A^I^A^I}{1:^A}aaaaa |*8 | - ]], attr_ids={ - [0] = {foreground = Screen.colors.Blue, bold = true}; -- NonText - [1] = {foreground = Screen.colors.Brown}; -- LineNr - }} - meths.input_mouse('right', 'press', '', 0, 4, 3) - eq('', eval("g:testvar")) - meths.input_mouse('left', 'press', '', 0, 5, 8) - eq('', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 6, 4) - eq('0 1 r 10', eval("g:testvar")) - meths.input_mouse('left', 'press', '', 0, 7, 7) - eq('0 1 l 11', eval("g:testvar")) + ]], + attr_ids = { + [0] = { foreground = Screen.colors.Blue, bold = true }, -- NonText + [1] = { foreground = Screen.colors.Brown }, -- LineNr + }, + } + api.nvim_input_mouse('right', 'press', '', 0, 4, 3) + eq('', eval('g:testvar')) + api.nvim_input_mouse('left', 'press', '', 0, 5, 8) + eq('', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 6, 4) + eq('0 1 r 10', eval('g:testvar')) + api.nvim_input_mouse('left', 'press', '', 0, 7, 7) + eq('0 1 l 11', eval('g:testvar')) end) it('popupmenu callback does not drag mouse on close', function() screen:try_resize(screen._width, 2) screen:set_default_attr_ids({ - [0] = {foreground = Screen.colors.Brown}, - [1] = {background = Screen.colors.Plum1}, + [0] = { foreground = Screen.colors.Brown }, + [1] = { background = Screen.colors.Plum1 }, }) - meths.set_option_value('statuscolumn', '%0@MyClickFunc@%l%T', {}) + api.nvim_set_option_value('statuscolumn', '%0@MyClickFunc@%l%T', {}) exec([[ function! MyClickFunc(minwid, clicks, button, mods) let g:testvar = printf("%d %d %s %d", a:minwid, a:clicks, a:button, getmousepos().line) @@ -605,26 +668,26 @@ describe('statuscolumn', function() endfunction ]]) -- clicking an item does not drag mouse - meths.input_mouse('left', 'press', '', 0, 0, 0) + api.nvim_input_mouse('left', 'press', '', 0, 0, 0) screen:expect([[ {0:8 }^aaaaa | {1: Echo } | ]]) - meths.input_mouse('left', 'press', '', 0, 1, 5) - meths.input_mouse('left', 'release', '', 0, 1, 5) + api.nvim_input_mouse('left', 'press', '', 0, 1, 5) + api.nvim_input_mouse('left', 'release', '', 0, 1, 5) screen:expect([[ {0:8 }^aaaaa | 0 1 l 8 | ]]) command('echo') -- clicking outside to close the menu does not drag mouse - meths.input_mouse('left', 'press', '', 0, 0, 0) + api.nvim_input_mouse('left', 'press', '', 0, 0, 0) screen:expect([[ {0:8 }^aaaaa | {1: Echo } | ]]) - meths.input_mouse('left', 'press', '', 0, 0, 10) - meths.input_mouse('left', 'release', '', 0, 0, 10) + api.nvim_input_mouse('left', 'press', '', 0, 0, 10) + api.nvim_input_mouse('left', 'release', '', 0, 0, 10) screen:expect([[ {0:8 }^aaaaa | | @@ -661,7 +724,9 @@ describe('statuscolumn', function() it('works with foldcolumn', function() -- Fits maximum multibyte foldcolumn #21759 command([[set stc=%C%=%l\ fdc=9 fillchars=foldsep:𒀀]]) - for _ = 0,8 do command('norm zfjzo') end + for _ = 0, 8 do + command('norm zfjzo') + end -- 'statuscolumn' is not drawn for `virt_lines_leftcol` lines exec_lua([[ vim.api.nvim_buf_set_extmark(0, ns, 6, 0, { @@ -685,7 +750,7 @@ describe('statuscolumn', function() 14 aaaaa | | ]]) - command('set stc=') -- also for the default fold column + command('set stc=') -- also for the default fold column screen:expect_unchanged() -- 'statuscolumn' is not too wide with custom (bogus) fold column command([[set stc=%{foldlevel(v:lnum)>0?repeat('-',foldlevel(v:lnum)):''}%=%l\ ]]) @@ -702,8 +767,7 @@ describe('statuscolumn', function() ---------8 aaaaa | virt | ---------9 aaaaa | - ~ | - ~ | + ~ |*2 | ]]) end) @@ -718,11 +782,7 @@ describe('statuscolumn', function() [No Name] [+] | :1set stc=%^l | :2 | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*5 [Command Line] | : | ]]) @@ -749,9 +809,7 @@ describe('statuscolumn', function() screen:expect([[ aaaaa | ^aaaaa | - aaaaa | - aaaaa | - aaaaa | + aaaaa |*3 | ]]) -- width correctly estimated with "w_nrwidth_line_count" when setting 'nu' @@ -766,7 +824,7 @@ describe('statuscolumn', function() ]]) end) - it("has correct width with custom sign column when (un)placing signs", function() + it('has correct width with custom sign column when (un)placing signs', function() screen:try_resize(screen._width, 3) exec_lua([[ vim.cmd.norm('gg') @@ -823,13 +881,13 @@ describe('statuscolumn', function() 2 ssssaaaaa | | ]]) - exec_lua("vim.api.nvim_buf_del_extmark(0, ns, id1)") + exec_lua('vim.api.nvim_buf_del_extmark(0, ns, id1)') screen:expect([[ 1 ^aaaaa | 2 ssaaaaa | | ]]) - exec_lua("vim.api.nvim_buf_del_extmark(0, ns, id2)") + exec_lua('vim.api.nvim_buf_del_extmark(0, ns, id2)') screen:expect([[ 1 ^aaaaa | 2 aaaaa | @@ -845,7 +903,7 @@ describe('statuscolumn', function() ]]) end) - it("is only evaluated twice, once to estimate and once to draw", function() + it('is only evaluated twice, once to estimate and once to draw', function() command([[ let g:stcnr = 0 func! Stc() @@ -869,4 +927,17 @@ describe('statuscolumn', function() | ]]) end) + + it('line increase properly redraws buffer text with relativenumber #27709', function() + screen:try_resize(33, 4) + command([[set rnu nuw=3 stc=%l\ ]]) + command('call setline(1, range(1, 99))') + feed('Gyyp') + screen:expect([[ + 98 98 | + 99 99 | + 100 ^99 | + | + ]]) + end) end) diff --git a/test/functional/ui/statusline_spec.lua b/test/functional/ui/statusline_spec.lua index 182e0cdadf..fee4b64d44 100644 --- a/test/functional/ui/statusline_spec.lua +++ b/test/functional/ui/statusline_spec.lua @@ -5,14 +5,14 @@ local clear = helpers.clear local command = helpers.command local feed = helpers.feed local eq = helpers.eq -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local exec = helpers.exec local exec_lua = helpers.exec_lua local eval = helpers.eval -local sleep = helpers.sleep +local sleep = vim.uv.sleep -local mousemodels = { "extend", "popup", "popup_setpos" } +local mousemodels = { 'extend', 'popup', 'popup_setpos' } for _, model in ipairs(mousemodels) do describe('statusline clicks with mousemodel=' .. model, function() @@ -22,8 +22,8 @@ for _, model in ipairs(mousemodels) do clear() screen = Screen.new(40, 8) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}; -- NonText - [1] = {bold = true, reverse = true}; -- StatusLine + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { bold = true, reverse = true }, -- StatusLine }) screen:attach() command('set laststatus=2 mousemodel=' .. model) @@ -39,80 +39,84 @@ for _, model in ipairs(mousemodels) do end) it('works', function() - meths.set_option_value('statusline', 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T', {}) - meths.input_mouse('left', 'press', '', 0, 6, 16) - eq('', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 6, 29) - eq('', eval("g:testvar")) - meths.input_mouse('left', 'press', '', 0, 6, 17) - eq('0 1 l', eval("g:testvar")) - meths.input_mouse('left', 'press', '', 0, 6, 17) - eq('0 2 l', eval("g:testvar")) - meths.input_mouse('left', 'press', '', 0, 6, 17) - eq('0 3 l', eval("g:testvar")) - meths.input_mouse('left', 'press', '', 0, 6, 17) - eq('0 4 l', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 6, 28) - eq('0 1 r', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 6, 28) - eq('0 2 r', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 6, 28) - eq('0 3 r', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 6, 28) - eq('0 4 r', eval("g:testvar")) + api.nvim_set_option_value('statusline', 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T', {}) + api.nvim_input_mouse('left', 'press', '', 0, 6, 16) + eq('', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 6, 29) + eq('', eval('g:testvar')) + api.nvim_input_mouse('left', 'press', '', 0, 6, 17) + eq('0 1 l', eval('g:testvar')) + api.nvim_input_mouse('left', 'press', '', 0, 6, 17) + eq('0 2 l', eval('g:testvar')) + api.nvim_input_mouse('left', 'press', '', 0, 6, 17) + eq('0 3 l', eval('g:testvar')) + api.nvim_input_mouse('left', 'press', '', 0, 6, 17) + eq('0 4 l', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 6, 28) + eq('0 1 r', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 6, 28) + eq('0 2 r', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 6, 28) + eq('0 3 r', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 6, 28) + eq('0 4 r', eval('g:testvar')) end) it('works with control characters and highlight', function() - meths.set_option_value('statusline', '\t%#NonText#\1%0@MyClickFunc@\t\1%T\t%##\1', {}) - screen:expect{grid=[[ + api.nvim_set_option_value('statusline', '\t%#NonText#\1%0@MyClickFunc@\t\1%T\t%##\1', {}) + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {1:^I}{0:^A^I^A^I}{1:^A }| | - ]]} - meths.input_mouse('right', 'press', '', 0, 6, 3) - eq('', eval("g:testvar")) - meths.input_mouse('left', 'press', '', 0, 6, 8) - eq('', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 6, 4) - eq('0 1 r', eval("g:testvar")) - meths.input_mouse('left', 'press', '', 0, 6, 7) - eq('0 1 l', eval("g:testvar")) + ]], + } + api.nvim_input_mouse('right', 'press', '', 0, 6, 3) + eq('', eval('g:testvar')) + api.nvim_input_mouse('left', 'press', '', 0, 6, 8) + eq('', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 6, 4) + eq('0 1 r', eval('g:testvar')) + api.nvim_input_mouse('left', 'press', '', 0, 6, 7) + eq('0 1 l', eval('g:testvar')) end) it('works for winbar', function() - meths.set_option_value('winbar', 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T', {}) - meths.input_mouse('left', 'press', '', 0, 0, 17) - eq('0 1 l', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 0, 17) - eq('0 1 r', eval("g:testvar")) + api.nvim_set_option_value('winbar', 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T', {}) + api.nvim_input_mouse('left', 'press', '', 0, 0, 17) + eq('0 1 l', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 0, 17) + eq('0 1 r', eval('g:testvar')) end) it('works for winbar in floating window', function() - meths.open_win(0, true, { width=30, height=4, relative='editor', row=1, col=5, - border = "single" }) - meths.set_option_value('winbar', 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T', - { scope = 'local' }) - meths.input_mouse('left', 'press', '', 0, 2, 23) - eq('0 1 l', eval("g:testvar")) + api.nvim_open_win( + 0, + true, + { width = 30, height = 4, relative = 'editor', row = 1, col = 5, border = 'single' } + ) + api.nvim_set_option_value( + 'winbar', + 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T', + { scope = 'local' } + ) + api.nvim_input_mouse('left', 'press', '', 0, 2, 23) + eq('0 1 l', eval('g:testvar')) end) it('works when there are multiple windows', function() command('split') - meths.set_option_value('statusline', 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T', {}) - meths.set_option_value('winbar', 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T', {}) - meths.input_mouse('left', 'press', '', 0, 0, 17) - eq('0 1 l', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 4, 17) - eq('0 1 r', eval("g:testvar")) - meths.input_mouse('middle', 'press', '', 0, 3, 17) - eq('0 1 m', eval("g:testvar")) - meths.input_mouse('left', 'press', '', 0, 6, 17) - eq('0 1 l', eval("g:testvar")) + api.nvim_set_option_value('statusline', 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T', {}) + api.nvim_set_option_value('winbar', 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T', {}) + api.nvim_input_mouse('left', 'press', '', 0, 0, 17) + eq('0 1 l', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 4, 17) + eq('0 1 r', eval('g:testvar')) + api.nvim_input_mouse('middle', 'press', '', 0, 3, 17) + eq('0 1 m', eval('g:testvar')) + api.nvim_input_mouse('left', 'press', '', 0, 6, 17) + eq('0 1 l', eval('g:testvar')) end) it('works with Lua function', function() @@ -121,101 +125,107 @@ for _, model in ipairs(mousemodels) do vim.g.testvar = string.format("%d %d %s", minwid, clicks, button) end ]]) - meths.set_option_value('statusline', 'Not clicky stuff %0@v:lua.clicky_func@Clicky stuff%T', {}) - meths.input_mouse('left', 'press', '', 0, 6, 17) - eq('0 1 l', eval("g:testvar")) + api.nvim_set_option_value( + 'statusline', + 'Not clicky stuff %0@v:lua.clicky_func@Clicky stuff%T', + {} + ) + api.nvim_input_mouse('left', 'press', '', 0, 6, 17) + eq('0 1 l', eval('g:testvar')) end) it('ignores unsupported click items', function() command('tabnew | tabprevious') - meths.set_option_value('statusline', '%2TNot clicky stuff%T', {}) - meths.input_mouse('left', 'press', '', 0, 6, 0) - eq(1, meths.get_current_tabpage().id) - meths.set_option_value('statusline', '%2XNot clicky stuff%X', {}) - meths.input_mouse('left', 'press', '', 0, 6, 0) - eq(2, #meths.list_tabpages()) + api.nvim_set_option_value('statusline', '%2TNot clicky stuff%T', {}) + api.nvim_input_mouse('left', 'press', '', 0, 6, 0) + eq(1, api.nvim_get_current_tabpage()) + api.nvim_set_option_value('statusline', '%2XNot clicky stuff%X', {}) + api.nvim_input_mouse('left', 'press', '', 0, 6, 0) + eq(2, #api.nvim_list_tabpages()) end) it("right click works when statusline isn't focused #18994", function() - meths.set_option_value('statusline', 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T', {}) - meths.input_mouse('right', 'press', '', 0, 6, 17) - eq('0 1 r', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 6, 17) - eq('0 2 r', eval("g:testvar")) + api.nvim_set_option_value('statusline', 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T', {}) + api.nvim_input_mouse('right', 'press', '', 0, 6, 17) + eq('0 1 r', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 6, 17) + eq('0 2 r', eval('g:testvar')) end) - it("works with modifiers #18994", function() - meths.set_option_value('statusline', 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T', {}) + it('works with modifiers #18994', function() + api.nvim_set_option_value('statusline', 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T', {}) -- Note: alternate between left and right mouse buttons to avoid triggering multiclicks - meths.input_mouse('left', 'press', 'S', 0, 6, 17) - eq('0 1 l(s )', eval("g:testvar")) - meths.input_mouse('right', 'press', 'S', 0, 6, 17) - eq('0 1 r(s )', eval("g:testvar")) - meths.input_mouse('left', 'press', 'A', 0, 6, 17) - eq('0 1 l( a )', eval("g:testvar")) - meths.input_mouse('right', 'press', 'A', 0, 6, 17) - eq('0 1 r( a )', eval("g:testvar")) - meths.input_mouse('left', 'press', 'AS', 0, 6, 17) - eq('0 1 l(s a )', eval("g:testvar")) - meths.input_mouse('right', 'press', 'AS', 0, 6, 17) - eq('0 1 r(s a )', eval("g:testvar")) - meths.input_mouse('left', 'press', 'T', 0, 6, 17) - eq('0 1 l( m)', eval("g:testvar")) - meths.input_mouse('right', 'press', 'T', 0, 6, 17) - eq('0 1 r( m)', eval("g:testvar")) - meths.input_mouse('left', 'press', 'TS', 0, 6, 17) - eq('0 1 l(s m)', eval("g:testvar")) - meths.input_mouse('right', 'press', 'TS', 0, 6, 17) - eq('0 1 r(s m)', eval("g:testvar")) - meths.input_mouse('left', 'press', 'C', 0, 6, 17) - eq('0 1 l( c )', eval("g:testvar")) + api.nvim_input_mouse('left', 'press', 'S', 0, 6, 17) + eq('0 1 l(s )', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', 'S', 0, 6, 17) + eq('0 1 r(s )', eval('g:testvar')) + api.nvim_input_mouse('left', 'press', 'A', 0, 6, 17) + eq('0 1 l( a )', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', 'A', 0, 6, 17) + eq('0 1 r( a )', eval('g:testvar')) + api.nvim_input_mouse('left', 'press', 'AS', 0, 6, 17) + eq('0 1 l(s a )', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', 'AS', 0, 6, 17) + eq('0 1 r(s a )', eval('g:testvar')) + api.nvim_input_mouse('left', 'press', 'T', 0, 6, 17) + eq('0 1 l( m)', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', 'T', 0, 6, 17) + eq('0 1 r( m)', eval('g:testvar')) + api.nvim_input_mouse('left', 'press', 'TS', 0, 6, 17) + eq('0 1 l(s m)', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', 'TS', 0, 6, 17) + eq('0 1 r(s m)', eval('g:testvar')) + api.nvim_input_mouse('left', 'press', 'C', 0, 6, 17) + eq('0 1 l( c )', eval('g:testvar')) -- <C-RightMouse> is for tag jump end) - it("works for global statusline with vertical splits #19186", function() + it('works for global statusline with vertical splits #19186', function() command('set laststatus=3') - meths.set_option_value('statusline', '%0@MyClickFunc@Clicky stuff%T %= %0@MyClickFunc@Clicky stuff%T', {}) + api.nvim_set_option_value( + 'statusline', + '%0@MyClickFunc@Clicky stuff%T %= %0@MyClickFunc@Clicky stuff%T', + {} + ) command('vsplit') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ │ | - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| + {0:~ }│{0:~ }|*5 {1:Clicky stuff Clicky stuff}| | - ]]} + ]], + } -- clickable area on the right - meths.input_mouse('left', 'press', '', 0, 6, 35) - eq('0 1 l', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 6, 35) - eq('0 1 r', eval("g:testvar")) + api.nvim_input_mouse('left', 'press', '', 0, 6, 35) + eq('0 1 l', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 6, 35) + eq('0 1 r', eval('g:testvar')) -- clickable area on the left - meths.input_mouse('left', 'press', '', 0, 6, 5) - eq('0 1 l', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 6, 5) - eq('0 1 r', eval("g:testvar")) + api.nvim_input_mouse('left', 'press', '', 0, 6, 5) + eq('0 1 l', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 6, 5) + eq('0 1 r', eval('g:testvar')) end) it('no memory leak with zero-width click labels', function() command([[ let &stl = '%@Test@%T%@MyClickFunc@%=%T%@Test@' ]]) - meths.input_mouse('left', 'press', '', 0, 6, 0) - eq('0 1 l', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 6, 39) - eq('0 1 r', eval("g:testvar")) + api.nvim_input_mouse('left', 'press', '', 0, 6, 0) + eq('0 1 l', eval('g:testvar')) + api.nvim_input_mouse('right', 'press', '', 0, 6, 39) + eq('0 1 r', eval('g:testvar')) end) it('no memory leak with truncated click labels', function() command([[ let &stl = '%@MyClickFunc@foo%X' .. repeat('a', 40) .. '%<t%@Test@bar%X%@Test@baz' ]]) - meths.input_mouse('left', 'press', '', 0, 6, 2) - eq('0 1 l', eval("g:testvar")) + api.nvim_input_mouse('left', 'press', '', 0, 6, 2) + eq('0 1 l', eval('g:testvar')) end) end) end @@ -228,11 +238,11 @@ describe('global statusline', function() screen = Screen.new(60, 16) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue}; - [2] = {bold = true, reverse = true}; - [3] = {bold = true}; - [4] = {reverse = true}; - [5] = {bold = true, foreground = Screen.colors.Fuchsia}; + [1] = { bold = true, foreground = Screen.colors.Blue }, + [2] = { bold = true, reverse = true }, + [3] = { bold = true }, + [4] = { reverse = true }, + [5] = { bold = true, foreground = Screen.colors.Fuchsia }, }) command('set laststatus=3') command('set ruler') @@ -241,39 +251,16 @@ describe('global statusline', function() it('works', function() screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*13 {2:[No Name] 0,0-1 All}| | ]]) feed('i<CR><CR>') screen:expect([[ - | - | + |*2 ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*11 {2:[No Name] [+] 3,1 All}| {3:-- INSERT --} | ]]) @@ -283,9 +270,7 @@ describe('global statusline', function() command('vsplit | split | vsplit | vsplit | wincmd l | split | 2wincmd l | split') screen:expect([[ │ │ │^ | - {1:~ }│{1:~ }│{1:~}│{1:~ }| - {1:~ }│{1:~ }│{1:~}│{1:~ }| - {1:~ }│{1:~ }│{1:~}│{1:~ }| + {1:~ }│{1:~ }│{1:~}│{1:~ }|*3 {1:~ }├────────────────┤{1:~}│{1:~ }| {1:~ }│ │{1:~}│{1:~ }| {1:~ }│{1:~ }│{1:~}│{1:~ }| @@ -293,9 +278,7 @@ describe('global statusline', function() {1:~ }│{1:~ }│{1:~}│ | ────────────────────┴────────────────┴─┤{1:~ }| │{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*3 {2:[No Name] 0,0-1 All}| | ]]) @@ -305,39 +288,14 @@ describe('global statusline', function() command('set laststatus=1') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*14 0,0-1 All | ]]) command('set laststatus=3') screen:expect([[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*13 {2:[No Name] 0,0-1 All}| | ]]) @@ -346,9 +304,7 @@ describe('global statusline', function() command('set laststatus=2') screen:expect([[ │ │ │^ | - {1:~ }│{1:~ }│{1:~}│{1:~ }| - {1:~ }│{1:~ }│{1:~}│{1:~ }| - {1:~ }│{1:~ }│{1:~}│{1:~ }| + {1:~ }│{1:~ }│{1:~}│{1:~ }|*3 {1:~ }│{4:< Name] 0,0-1 }│{1:~}│{1:~ }| {1:~ }│ │{1:~}│{1:~ }| {1:~ }│{1:~ }│{1:~}│{1:~ }| @@ -356,9 +312,7 @@ describe('global statusline', function() {1:~ }│{1:~ }│{1:~}│ | {4:<No Name] 0,0-1 All < Name] 0,0-1 <}│{1:~ }| │{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*3 {4:[No Name] 0,0-1 All <No Name] 0,0-1 All}| | ]]) @@ -366,9 +320,7 @@ describe('global statusline', function() command('set laststatus=3') screen:expect([[ │ │ │^ | - {1:~ }│{1:~ }│{1:~}│{1:~ }| - {1:~ }│{1:~ }│{1:~}│{1:~ }| - {1:~ }│{1:~ }│{1:~}│{1:~ }| + {1:~ }│{1:~ }│{1:~}│{1:~ }|*3 {1:~ }├────────────────┤{1:~}│{1:~ }| {1:~ }│ │{1:~}│{1:~ }| {1:~ }│{1:~ }│{1:~}│{1:~ }| @@ -376,9 +328,7 @@ describe('global statusline', function() {1:~ }│{1:~ }│{1:~}│ | ────────────────────┴────────────────┴─┤{1:~ }| │{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*3 {2:[No Name] 0,0-1 All}| | ]]) @@ -386,9 +336,7 @@ describe('global statusline', function() command('set laststatus=0') screen:expect([[ │ │ │^ | - {1:~ }│{1:~ }│{1:~}│{1:~ }| - {1:~ }│{1:~ }│{1:~}│{1:~ }| - {1:~ }│{1:~ }│{1:~}│{1:~ }| + {1:~ }│{1:~ }│{1:~}│{1:~ }|*3 {1:~ }│{4:< Name] 0,0-1 }│{1:~}│{1:~ }| {1:~ }│ │{1:~}│{1:~ }| {1:~ }│{1:~ }│{1:~}│{1:~ }| @@ -396,19 +344,14 @@ describe('global statusline', function() {1:~ }│{1:~ }│{1:~}│ | {4:<No Name] 0,0-1 All < Name] 0,0-1 <}│{1:~ }| │{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*4 0,0-1 All | ]]) command('set laststatus=3') screen:expect([[ │ │ │^ | - {1:~ }│{1:~ }│{1:~}│{1:~ }| - {1:~ }│{1:~ }│{1:~}│{1:~ }| - {1:~ }│{1:~ }│{1:~}│{1:~ }| + {1:~ }│{1:~ }│{1:~}│{1:~ }|*3 {1:~ }├────────────────┤{1:~}│{1:~ }| {1:~ }│ │{1:~}│{1:~ }| {1:~ }│{1:~ }│{1:~}│{1:~ }| @@ -416,55 +359,49 @@ describe('global statusline', function() {1:~ }│{1:~ }│{1:~}│ | ────────────────────┴────────────────┴─┤{1:~ }| │{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*3 {2:[No Name] 0,0-1 All}| | ]]) end) it('win_move_statusline() can reduce cmdheight to 1', function() - eq(1, meths.get_option_value('cmdheight', {})) - funcs.win_move_statusline(0, -1) - eq(2, meths.get_option_value('cmdheight', {})) - funcs.win_move_statusline(0, -1) - eq(3, meths.get_option_value('cmdheight', {})) - funcs.win_move_statusline(0, 1) - eq(2, meths.get_option_value('cmdheight', {})) - funcs.win_move_statusline(0, 1) - eq(1, meths.get_option_value('cmdheight', {})) + eq(1, api.nvim_get_option_value('cmdheight', {})) + fn.win_move_statusline(0, -1) + eq(2, api.nvim_get_option_value('cmdheight', {})) + fn.win_move_statusline(0, -1) + eq(3, api.nvim_get_option_value('cmdheight', {})) + fn.win_move_statusline(0, 1) + eq(2, api.nvim_get_option_value('cmdheight', {})) + fn.win_move_statusline(0, 1) + eq(1, api.nvim_get_option_value('cmdheight', {})) end) it('mouse dragging can reduce cmdheight to 1', function() command('set mouse=a') - meths.input_mouse('left', 'press', '', 0, 14, 10) - eq(1, meths.get_option_value('cmdheight', {})) - meths.input_mouse('left', 'drag', '', 0, 13, 10) - eq(2, meths.get_option_value('cmdheight', {})) - meths.input_mouse('left', 'drag', '', 0, 12, 10) - eq(3, meths.get_option_value('cmdheight', {})) - meths.input_mouse('left', 'drag', '', 0, 13, 10) - eq(2, meths.get_option_value('cmdheight', {})) - meths.input_mouse('left', 'drag', '', 0, 14, 10) - eq(1, meths.get_option_value('cmdheight', {})) - meths.input_mouse('left', 'drag', '', 0, 15, 10) - eq(1, meths.get_option_value('cmdheight', {})) - meths.input_mouse('left', 'drag', '', 0, 14, 10) - eq(1, meths.get_option_value('cmdheight', {})) + api.nvim_input_mouse('left', 'press', '', 0, 14, 10) + eq(1, api.nvim_get_option_value('cmdheight', {})) + api.nvim_input_mouse('left', 'drag', '', 0, 13, 10) + eq(2, api.nvim_get_option_value('cmdheight', {})) + api.nvim_input_mouse('left', 'drag', '', 0, 12, 10) + eq(3, api.nvim_get_option_value('cmdheight', {})) + api.nvim_input_mouse('left', 'drag', '', 0, 13, 10) + eq(2, api.nvim_get_option_value('cmdheight', {})) + api.nvim_input_mouse('left', 'drag', '', 0, 14, 10) + eq(1, api.nvim_get_option_value('cmdheight', {})) + api.nvim_input_mouse('left', 'drag', '', 0, 15, 10) + eq(1, api.nvim_get_option_value('cmdheight', {})) + api.nvim_input_mouse('left', 'drag', '', 0, 14, 10) + eq(1, api.nvim_get_option_value('cmdheight', {})) end) it('cmdline row is correct after setting cmdheight #20514', function() command('botright split test/functional/fixtures/bigfile.txt') - meths.set_option_value('cmdheight', 1, {}) + api.nvim_set_option_value('cmdheight', 1, {}) feed('L') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ────────────────────────────────────────────────────────────| 0000;<control>;Cc;0;BN;;;;;N;NULL;;;; | 0001;<control>;Cc;0;BN;;;;;N;START OF HEADING;;;; | @@ -479,11 +416,7 @@ describe('global statusline', function() feed('j') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ────────────────────────────────────────────────────────────| 0001;<control>;Cc;0;BN;;;;;N;START OF HEADING;;;; | 0002;<control>;Cc;0;BN;;;;;N;START OF TEXT;;;; | @@ -495,15 +428,11 @@ describe('global statusline', function() {2:test/functional/fixtures/bigfile.txt 8,1 0%}| | ]]) - meths.set_option_value('showtabline', 2, {}) + api.nvim_set_option_value('showtabline', 2, {}) screen:expect([[ {3: }{5:2}{3: t/f/f/bigfile.txt }{4: }| | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ────────────────────────────────────────────────────────────| 0002;<control>;Cc;0;BN;;;;;N;START OF TEXT;;;; | 0003;<control>;Cc;0;BN;;;;;N;END OF TEXT;;;; | @@ -514,15 +443,11 @@ describe('global statusline', function() {2:test/functional/fixtures/bigfile.txt 8,1 0%}| | ]]) - meths.set_option_value('cmdheight', 0, {}) + api.nvim_set_option_value('cmdheight', 0, {}) screen:expect([[ {3: }{5:2}{3: t/f/f/bigfile.txt }{4: }| | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ────────────────────────────────────────────────────────────| 0001;<control>;Cc;0;BN;;;;;N;START OF HEADING;;;; | 0002;<control>;Cc;0;BN;;;;;N;START OF TEXT;;;; | @@ -533,15 +458,11 @@ describe('global statusline', function() ^0007;<control>;Cc;0;BN;;;;;N;BELL;;;; | {2:test/functional/fixtures/bigfile.txt 8,1 0%}| ]]) - meths.set_option_value('cmdheight', 1, {}) + api.nvim_set_option_value('cmdheight', 1, {}) screen:expect([[ {3: }{5:2}{3: t/f/f/bigfile.txt }{4: }| | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 ────────────────────────────────────────────────────────────| 0002;<control>;Cc;0;BN;;;;;N;START OF TEXT;;;; | 0003;<control>;Cc;0;BN;;;;;N;END OF TEXT;;;; | @@ -557,8 +478,8 @@ end) it('statusline does not crash if it has Arabic characters #19447', function() clear() - meths.set_option_value('statusline', 'غً', {}) - meths.set_option_value('laststatus', 2, {}) + api.nvim_set_option_value('statusline', 'غً', {}) + api.nvim_set_option_value('laststatus', 2, {}) command('redraw!') assert_alive() end) @@ -567,8 +488,8 @@ it('statusline is redrawn with :resize from <Cmd> mapping #19629', function() clear() local screen = Screen.new(40, 8) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {bold = true, reverse = true}, -- StatusLine + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { bold = true, reverse = true }, -- StatusLine }) screen:attach() exec([[ @@ -579,22 +500,14 @@ it('statusline is redrawn with :resize from <Cmd> mapping #19629', function() feed('<Up>') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {1:[No Name] }| - | - | + |*2 ]]) feed('<Down>') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {1:[No Name] }| | ]]) @@ -604,9 +517,9 @@ it('showcmdloc=statusline does not show if statusline is too narrow', function() clear() local screen = Screen.new(40, 8) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {bold = true, reverse = true}, -- StatusLine - [2] = {reverse = true}, -- StatusLineNC + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { bold = true, reverse = true }, -- StatusLine + [2] = { reverse = true }, -- StatusLineNC }) screen:attach() command('set showcmd') @@ -614,11 +527,7 @@ it('showcmdloc=statusline does not show if statusline is too narrow', function() command('1vsplit') screen:expect([[ ^ │ | - {0:~}│{0:~ }| - {0:~}│{0:~ }| - {0:~}│{0:~ }| - {0:~}│{0:~ }| - {0:~}│{0:~ }| + {0:~}│{0:~ }|*5 {1:< }{2:[No Name] }| | ]]) @@ -668,8 +577,7 @@ it('statusline is redrawn on various state changes', function() screen:expect([[ ^ | ~ | - | - | + |*2 ]]) feed('qQ') screen:expect([[ @@ -682,8 +590,7 @@ it('statusline is redrawn on various state changes', function() screen:expect([[ ^ | ~ | - | - | + |*2 ]]) -- Visual mode change #23932 @@ -741,13 +648,13 @@ it('ruler is redrawn in cmdline with redrawstatus #22804', function() ]]) end) -it("shows correct ruler in cmdline with no statusline", function() +it('shows correct ruler in cmdline with no statusline', function() clear() local screen = Screen.new(30, 8) screen:set_default_attr_ids { - [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [2] = {bold = true, reverse = true}, -- StatusLine - [3] = {reverse = true}, -- StatusLineNC + [1] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [2] = { bold = true, reverse = true }, -- StatusLine + [3] = { reverse = true }, -- StatusLineNC } screen:attach() -- Use long ruler to check 'ruler' with 'rulerformat' set has correct width. @@ -765,12 +672,10 @@ it("shows correct ruler in cmdline with no statusline", function() command '1wincmd w' screen:expect [[ ^ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:[No Name] 1longlonglong }| │ | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*2 3longlonglong | ]] -- Window 2 is current. It has no statusline, so cmdline should show its @@ -778,24 +683,20 @@ it("shows correct ruler in cmdline with no statusline", function() command '2wincmd w' screen:expect [[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {3:[No Name] 1longlonglong }| ^ │ | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*2 2longlonglong | ]] -- Window 3 is current. Cmdline should again show its ruler. command '3wincmd w' screen:expect [[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {3:[No Name] 1longlonglong }| │^ | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| + {1:~ }│{1:~ }|*2 3longlonglong | ]] end) @@ -805,15 +706,72 @@ it('uses "stl" and "stlnc" fillchars even if they are the same #19803', function local screen = Screen.new(53, 4) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText + [1] = { bold = true, foreground = Screen.colors.Blue }, -- NonText }) command('hi clear StatusLine') command('hi clear StatusLineNC') command('vsplit') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ │ | {1:~ }│{1:~ }| [No Name] [No Name] | | - ]]} + ]], + } +end) + +it('showcmdloc=statusline works with vertical splits', function() + clear() + local screen = Screen.new(53, 4) + screen:set_default_attr_ids { + [1] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [2] = { bold = true, reverse = true }, -- StatusLine + [3] = { reverse = true }, -- StatusLineNC + } + screen:attach() + command('rightbelow vsplit') + command('set showcmd showcmdloc=statusline') + feed('1234') + screen:expect([[ + │^ | + {1:~ }│{1:~ }| + {3:[No Name] }{2:[No Name] 1234 }| + | + ]]) + feed('<Esc>') + command('set laststatus=3') + feed('1234') + screen:expect([[ + │^ | + {1:~ }│{1:~ }| + {2:[No Name] 1234 }| + | + ]]) +end) + +it('keymap is shown with vertical splits #27269', function() + clear() + local screen = Screen.new(53, 4) + screen:set_default_attr_ids { + [1] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [2] = { bold = true, reverse = true }, -- StatusLine + [3] = { reverse = true }, -- StatusLineNC + } + screen:attach() + command('setlocal keymap=dvorak') + command('rightbelow vsplit') + screen:expect([[ + │^ | + {1:~ }│{1:~ }| + {3:[No Name] <en-dv> }{2:[No Name] <en-dv> }| + | + ]]) + command('set laststatus=3') + screen:expect([[ + │^ | + {1:~ }│{1:~ }| + {2:[No Name] <en-dv> }| + | + ]]) end) diff --git a/test/functional/ui/syntax_conceal_spec.lua b/test/functional/ui/syntax_conceal_spec.lua index 1391985823..5afc7dfe6c 100644 --- a/test/functional/ui/syntax_conceal_spec.lua +++ b/test/functional/ui/syntax_conceal_spec.lua @@ -11,26 +11,25 @@ describe('Screen', function() before_each(function() clear() - screen = Screen.new(nil,10) + screen = Screen.new(nil, 10) screen:attach() - screen:set_default_attr_ids( { - [0] = {bold=true, foreground=Screen.colors.Blue}, - [1] = {foreground = Screen.colors.LightGrey, background = Screen.colors.DarkGray}, - [2] = {bold = true, reverse = true}, - [3] = {reverse = true}, - [4] = {bold = true}, - [5] = {background = Screen.colors.Yellow}, - [6] = {background = Screen.colors.LightGrey}, - } ) + screen:set_default_attr_ids({ + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { foreground = Screen.colors.LightGrey, background = Screen.colors.DarkGray }, + [2] = { bold = true, reverse = true }, + [3] = { reverse = true }, + [4] = { bold = true }, + [5] = { background = Screen.colors.Yellow }, + [6] = { foreground = Screen.colors.Black, background = Screen.colors.LightGrey }, + }) end) - describe("match and conceal", function() - + describe('match and conceal', function() before_each(function() - command("let &conceallevel=1") + command('let &conceallevel=1') end) - describe("multiple", function() + describe('multiple', function() before_each(function() insert([[ && @@ -43,124 +42,88 @@ describe('Screen', function() command("syn match dAmpersand '[&][&]' conceal cchar=∧") end) - it("double characters.", function() + it('double characters.', function() screen:expect([[ - {1:∧} | - {1:∧} | - {1:∧} | - {1:∧} | - {1:∧} | - {1:∧} | + {1:∧} |*6 ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end) it('double characters and move the cursor one line up.', function() - feed("k") + feed('k') screen:expect([[ - {1:∧} | - {1:∧} | - {1:∧} | - {1:∧} | - {1:∧} | + {1:∧} |*5 ^&& | | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end) it('double characters and move the cursor to the beginning of the file.', function() - feed("gg") + feed('gg') screen:expect([[ ^&& | - {1:∧} | - {1:∧} | - {1:∧} | - {1:∧} | - {1:∧} | + {1:∧} |*5 | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end) it('double characters and move the cursor to the second line in the file.', function() - feed("ggj") + feed('ggj') screen:expect([[ {1:∧} | ^&& | - {1:∧} | - {1:∧} | - {1:∧} | - {1:∧} | + {1:∧} |*4 | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) end) - it('double characters and then move the cursor to the beginning of the file and back to the end of the file.', function() - feed("ggG") - screen:expect([[ - {1:∧} | - {1:∧} | - {1:∧} | - {1:∧} | - {1:∧} | - {1:∧} | + it( + 'double characters and then move the cursor to the beginning of the file and back to the end of the file.', + function() + feed('ggG') + screen:expect([[ + {1:∧} |*6 ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | ]]) - end) + end + ) end) -- multiple - it("keyword instances in initially in the document.", function() - feed("2ilambda<cr><ESC>") - command("let &conceallevel=1") - command("syn keyword kLambda lambda conceal cchar=λ") + it('keyword instances in initially in the document.', function() + feed('2ilambda<cr><ESC>') + command('let &conceallevel=1') + command('syn keyword kLambda lambda conceal cchar=λ') screen:expect([[ - {1:λ} | - {1:λ} | + {1:λ} |*2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 | ]]) end) -- Keyword - describe("regions in the document", function() - + describe('regions in the document', function() before_each(function() - feed("2") - insert("<r> a region of text </r>\n") - command("let &conceallevel=1") + feed('2') + insert('<r> a region of text </r>\n') + command('let &conceallevel=1') end) it('initially and conceal it.', function() command("syn region rText start='<r>' end='</r>' conceal cchar=R") screen:expect([[ - {1:R} | - {1:R} | + {1:R} |*2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 | ]]) end) @@ -170,246 +133,183 @@ describe('Screen', function() -- be replaced with cchar. command("syn region rText matchgroup=rMatch start='<r>' end='</r>' concealends cchar=-") screen:expect([[ - {1: } a region of text {1:-} | - {1: } a region of text {1:-} | + {1: } a region of text {1:-} |*2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 | ]]) end) - it('that are nested and conceal the nested region\'s start and end tags.', function() - command("syn region rText contains=rText matchgroup=rMatch start='<r>' end='</r>' concealends cchar=-") - insert("<r> A region with <r> a nested <r> nested region.</r> </r> </r>\n") + it("that are nested and conceal the nested region's start and end tags.", function() + command( + "syn region rText contains=rText matchgroup=rMatch start='<r>' end='</r>' concealends cchar=-" + ) + insert('<r> A region with <r> a nested <r> nested region.</r> </r> </r>\n') screen:expect([[ - {1: } a region of text {1:-} | - {1: } a region of text {1:-} | + {1: } a region of text {1:-} |*2 {1: } A region with {1: } a nested {1: } nested region.{1:-} | {1:-} {1:-} | ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) end) end) -- regions in the document - describe("a region of text", function() + describe('a region of text', function() before_each(function() - command("syntax conceal on") - feed("2") - insert("<r> a region of text </r>\n") + command('syntax conceal on') + feed('2') + insert('<r> a region of text </r>\n') command("syn region rText start='<r>' end='</r>' cchar=-") end) - it("and turn on implicit concealing", function() + it('and turn on implicit concealing', function() screen:expect([[ - {1:-} | - {1:-} | + {1:-} |*2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 | ]]) end) - it("and then turn on, then off, and then back on implicit concealing.", function() - command("syntax conceal off") - feed("2") - insert("<i> italian text </i>\n") + it('and then turn on, then off, and then back on implicit concealing.', function() + command('syntax conceal off') + feed('2') + insert('<i> italian text </i>\n') command("syn region iText start='<i>' end='</i>' cchar=*") screen:expect([[ - {1:-} | - {1:-} | - <i> italian text </i> | - <i> italian text </i> | + {1:-} |*2 + <i> italian text </i> |*2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) - command("syntax conceal on") + command('syntax conceal on') command("syn region iText start='<i>' end='</i>' cchar=*") screen:expect([[ - {1:-} | - {1:-} | - {1:*} | - {1:*} | + {1:-} |*2 + {1:*} |*2 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) end) end) -- a region of text (implicit concealing) - it("cursor position is correct when entering Insert mode with cocu=ni #13916", function() + it('cursor position is correct when entering Insert mode with cocu=ni #13916', function() insert([[foobarfoobarfoobar]]) -- move to end of line - feed("$") - command("set concealcursor=ni") - command("syn match Foo /foobar/ conceal cchar=&") + feed('$') + command('set concealcursor=ni') + command('syn match Foo /foobar/ conceal cchar=&') screen:expect([[ {1:&&&}^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*8 | ]]) - feed("i") + feed('i') -- cursor should stay in place, not jump to column 16 screen:expect([[ {1:&&&}^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*8 {4:-- INSERT --} | ]]) end) end) -- match and conceal - describe("let the conceal level be", function() + describe('let the conceal level be', function() before_each(function() - insert("// No Conceal\n") + insert('// No Conceal\n') insert('"Conceal without a cchar"\n') - insert("+ With cchar\n\n") + insert('+ With cchar\n\n') command("syn match noConceal '^//.*$'") - command("syn match concealNoCchar '\".\\{-}\"$' conceal") + command('syn match concealNoCchar \'".\\{-}"$\' conceal') command("syn match concealWCchar '^+.\\{-}$' conceal cchar=C") end) - it("0. No concealing.", function() - command("let &conceallevel=0") + it('0. No concealing.', function() + command('let &conceallevel=0') screen:expect([[ // No Conceal | "Conceal without a cchar" | + With cchar | | ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) end) - it("1. Conceal using cchar or reference listchars.", function() - command("let &conceallevel=1") + it('1. Conceal using cchar or reference listchars.', function() + command('let &conceallevel=1') screen:expect([[ // No Conceal | {1: } | {1:C} | | ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) end) - it("2. Hidden unless cchar is set.", function() - command("let &conceallevel=2") + it('2. Hidden unless cchar is set.', function() + command('let &conceallevel=2') screen:expect([[ // No Conceal | | {1:C} | | ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) end) - it("3. Hide all concealed text.", function() - command("let &conceallevel=3") + it('3. Hide all concealed text.', function() + command('let &conceallevel=3') screen:expect([[ // No Conceal | - | - | - | + |*3 ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) end) end) -- conceallevel - - describe("cursor movement", function() + describe('cursor movement', function() before_each(function() - command("syn keyword concealy barf conceal cchar=b") - command("set cole=2") + command('syn keyword concealy barf conceal cchar=b') + command('set cole=2') feed('5Ofoo barf bar barf eggs<esc>') screen:expect([[ - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*4 foo barf bar barf egg^s | | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) - end) it('between windows', function() feed('k') - command("split") + command('split') screen:expect([[ foo {1:b} bar {1:b} eggs | foo barf bar barf egg^s | foo {1:b} bar {1:b} eggs | | {2:[No Name] [+] }| - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*3 {3:[No Name] [+] }| | ]]) feed('<c-w>w') screen:expect([[ - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*3 | {3:[No Name] [+] }| foo {1:b} bar {1:b} eggs | @@ -423,29 +323,20 @@ describe('Screen', function() it('in insert mode', function() feed('i') screen:expect([[ - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*4 foo barf bar barf egg^s | | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {4:-- INSERT --} | ]]) feed('<up>') screen:expect([[ - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*3 foo barf bar barf egg^s | foo {1:b} bar {1:b} eggs | | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {4:-- INSERT --} | ]]) end) @@ -455,73 +346,47 @@ describe('Screen', function() feed('gg') screen:expect([[ ^foo barf bar barf eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*4 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) feed('i') screen:expect([[ ^foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*4 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {4:-- INSERT --} | ]]) feed('<esc>') screen:expect([[ ^foo barf bar barf eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*4 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) feed('v') screen:expect([[ ^foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*4 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {4:-- VISUAL --} | ]]) feed('<esc>') screen:expect([[ ^foo barf bar barf eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*4 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) - end) it('between modes cocu=n', function() @@ -529,71 +394,45 @@ describe('Screen', function() feed('gg') screen:expect([[ ^foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*4 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) feed('i') screen:expect([[ ^foo barf bar barf eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*4 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {4:-- INSERT --} | ]]) feed('<esc>') screen:expect([[ ^foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*4 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) - feed('v') screen:expect([[ ^foo barf bar barf eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*4 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {4:-- VISUAL --} | ]]) feed('<esc>') screen:expect([[ ^foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*4 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) end) @@ -601,15 +440,10 @@ describe('Screen', function() it('and open line', function() feed('o') screen:expect([[ - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*5 ^ | | - {0:~ }| - {0:~ }| + {0:~ }|*2 {4:-- INSERT --} | ]]) end) @@ -618,15 +452,10 @@ describe('Screen', function() command('set cocu=i') feed('o') screen:expect([[ - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*5 ^ | | - {0:~ }| - {0:~ }| + {0:~ }|*2 {4:-- INSERT --} | ]]) end) @@ -639,12 +468,9 @@ describe('Screen', function() ^foo barf bar barf eggs | foo {1:b} bar {1:b} eggs x | foo {1:b} bar {1:b} eggs xy | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) end) @@ -655,12 +481,9 @@ describe('Screen', function() foo barf bar barf eggs | foo {1:b} bar {1:b} eggs x | foo {1:b} bar {1:b} eggs xy | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 /^ | ]]) @@ -669,12 +492,9 @@ describe('Screen', function() foo {1:b} bar {1:b} eggs | foo barf bar barf eggs {3:x} | foo {1:b} bar {1:b} eggs {5:x}y | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 /x^ | ]]) @@ -683,12 +503,9 @@ describe('Screen', function() foo {1:b} bar {1:b} eggs | foo {1:b} bar {1:b} eggs x | foo barf bar barf eggs {3:xy} | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 /xy^ | ]]) @@ -697,12 +514,9 @@ describe('Screen', function() foo barf bar barf eggs | foo {1:b} bar {1:b} eggs x | foo {1:b} bar {1:b} eggs xy | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 /^ | ]]) end) @@ -717,12 +531,9 @@ describe('Screen', function() foo barf bar barf eggs | foo {1:b} bar {1:b} eggs x | foo {1:b} bar {1:b} eggs xy | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 /^ | ]]) @@ -731,12 +542,9 @@ describe('Screen', function() foo {1:b} bar {1:b} eggs | foo {1:b} bar {1:b} eggs {3:x} | foo {1:b} bar {1:b} eggs {5:x}y | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 /x^ | ]]) @@ -745,12 +553,9 @@ describe('Screen', function() foo {1:b} bar {1:b} eggs | foo {1:b} bar {1:b} eggs x | foo {1:b} bar {1:b} eggs {3:xy} | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 /xy^ | ]]) @@ -759,12 +564,9 @@ describe('Screen', function() foo {1:b} bar {1:b} eggs | foo {1:b} bar {1:b} eggs x | foo {1:b} bar {1:b} eggs xy | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 /^ | ]]) @@ -773,12 +575,9 @@ describe('Screen', function() ^foo barf bar barf eggs | foo {1:b} bar {1:b} eggs x | foo {1:b} bar {1:b} eggs xy | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) end) @@ -789,12 +588,9 @@ describe('Screen', function() ^foo {1:b} bar {1:b} eggs | foo {1:b} bar {1:b} eggs x | foo {1:b} bar {1:b} eggs xy | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) @@ -805,12 +601,9 @@ describe('Screen', function() foo {1:b} bar {1:b} eggs | foo {1:b} bar {1:b} eggs x | foo {1:b} bar {1:b} eggs xy | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 /^ | ]]) @@ -819,12 +612,9 @@ describe('Screen', function() foo {1:b} bar {1:b} eggs | foo barf bar barf eggs {3:x} | foo {1:b} bar {1:b} eggs {5:x}y | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 /x^ | ]]) @@ -833,12 +623,9 @@ describe('Screen', function() foo barf bar barf eggs | foo {1:b} bar {1:b} eggs x | foo {1:b} bar {1:b} eggs xy | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 /^ | ]]) @@ -847,12 +634,9 @@ describe('Screen', function() ^foo {1:b} bar {1:b} eggs | foo {1:b} bar {1:b} eggs x | foo {1:b} bar {1:b} eggs xy | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*2 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) end) @@ -863,44 +647,33 @@ describe('Screen', function() feed('10Ofoo barf bar barf eggs<esc>') feed(':3<cr>o a<Esc>ggV') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^f{6:oo }{1:b}{6: bar }{1:b}{6: eggs} | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*2 a | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*5 {4:-- VISUAL LINE --} | - ]]} + ]], + } feed(string.rep('j', 15)) - screen:expect{grid=[[ - {6:foo }{1:b}{6: bar }{1:b}{6: eggs} | - {6:foo }{1:b}{6: bar }{1:b}{6: eggs} | - {6:foo }{1:b}{6: bar }{1:b}{6: eggs} | - {6:foo }{1:b}{6: bar }{1:b}{6: eggs} | - {6:foo }{1:b}{6: bar }{1:b}{6: eggs} | - {6:foo }{1:b}{6: bar }{1:b}{6: eggs} | - {6:foo }{1:b}{6: bar }{1:b}{6: eggs} | - {6:foo }{1:b}{6: bar }{1:b}{6: eggs} | + screen:expect { + grid = [[ + {6:foo }{1:b}{6: bar }{1:b}{6: eggs} |*8 ^f{6:oo }{1:b}{6: bar }{1:b}{6: eggs} | {4:-- VISUAL LINE --} | - ]]} + ]], + } feed(string.rep('k', 15)) - screen:expect{grid=[[ + screen:expect { + grid = [[ ^f{6:oo }{1:b}{6: bar }{1:b}{6: eggs} | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*2 a | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | - foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs |*5 {4:-- VISUAL LINE --} | - ]]} + ]], + } end) end) @@ -913,41 +686,37 @@ describe('Screen', function() bbb ccc ]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ aaa | bbb | ccc | ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | - ]]} + ]], + } -- XXX: hack to get notifications, and check only a single line is -- updated. Could use next_msg() also. local orig_handle_grid_line = screen._handle_grid_line local grid_lines = {} function screen._handle_grid_line(self, grid, row, col, items) - table.insert(grid_lines, {row, col, items}) + table.insert(grid_lines, { row, col, items }) orig_handle_grid_line(self, grid, row, col, items) end feed('k') - screen:expect{grid=[[ + screen:expect { + grid = [[ aaa | bbb | ^ccc | | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | - ]]} - eq({{2, 0, {{'c', 0, 3}, {' ', 0, 50}}}, {3, 0, {{' ', 0, 53}}}}, grid_lines) + ]], + } + eq({ { 2, 0, { { 'c', 0, 3 }, { ' ', 0, 50 } } }, { 3, 0, { { ' ', 0, 53 } } } }, grid_lines) end) it('K_EVENT should not cause extra redraws with concealcursor #13196', function() @@ -960,43 +729,39 @@ describe('Screen', function() bbb ccc ]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ aaa | bbb | ccc | ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | - ]]} + ]], + } -- XXX: hack to get notifications, and check only a single line is -- updated. Could use next_msg() also. local orig_handle_grid_line = screen._handle_grid_line local grid_lines = {} function screen._handle_grid_line(self, grid, row, col, items) - table.insert(grid_lines, {row, col, items}) + table.insert(grid_lines, { row, col, items }) orig_handle_grid_line(self, grid, row, col, items) end feed('k') - screen:expect{grid=[[ + screen:expect { + grid = [[ aaa | bbb | ^ccc | | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | - ]]} - eq({{2, 0, {{'c', 0, 3}, {' ', 0, 50}}}}, grid_lines) + ]], + } + eq({ { 2, 0, { { 'c', 0, 3 }, { ' ', 0, 50 } } } }, grid_lines) grid_lines = {} - poke_eventloop() -- causes K_EVENT key + poke_eventloop() -- causes K_EVENT key screen:expect_unchanged() eq({}, grid_lines) -- no redraw was done end) @@ -1015,7 +780,8 @@ describe('Screen', function() command('set nomodified') command('so') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^3split | let m matchadd('Conceal', '') | setl conceallevel2 concealcursornc | @@ -1026,16 +792,18 @@ describe('Screen', function() normal gg | {3:Xcolesearch }| | - ]]} + ]], + } -- Jump to something that is beyond the bottom of the window, -- so there's a scroll down. - feed("/expr<CR>") + feed('/expr<CR>') -- Are the concealed parts of the current line really hidden? -- Is the window's cursor column properly updated for hidden -- parts of the current line? - screen:expect{grid=[[ + screen:expect { + grid = [[ setl conceallevel2 concealcursornc | normal gg | "{5:^expr} | @@ -1046,7 +814,8 @@ describe('Screen', function() normal gg | {3:Xcolesearch }| /expr | - ]]} + ]], + } end) -- oldtest: Test_cursor_column_in_concealed_line_after_leftcol_change() @@ -1064,18 +833,14 @@ describe('Screen', function() -- Are the concealed parts of the current line really hidden? -- Is the window's cursor column properly updated for conceal? - screen:expect{grid=[[ + screen:expect { + grid = [[ ^c | | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*7 | - ]]} + ]], + } end) end) end) diff --git a/test/functional/ui/tabline_spec.lua b/test/functional/ui/tabline_spec.lua index befdb7c5d1..1c90b17e57 100644 --- a/test/functional/ui/tabline_spec.lua +++ b/test/functional/ui/tabline_spec.lua @@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local clear, command, eq = helpers.clear, helpers.command, helpers.eq local insert = helpers.insert -local meths = helpers.meths +local api = helpers.api local assert_alive = helpers.assert_alive describe('ui/ext_tabline', function() @@ -12,7 +12,7 @@ describe('ui/ext_tabline', function() before_each(function() clear() screen = Screen.new(25, 5) - screen:attach({rgb=true, ext_tabline=true}) + screen:attach({ rgb = true, ext_tabline = true }) function screen:_handle_tabline_update(curtab, tabs, curbuf, buffers) event_curtab = curtab event_tabs = tabs @@ -22,73 +22,77 @@ describe('ui/ext_tabline', function() end) it('publishes UI events', function() - command("tabedit another-tab") + command('tabedit another-tab') local expected_tabs = { - {tab = { id = 1 }, name = '[No Name]'}, - {tab = { id = 2 }, name = 'another-tab'}, + { tab = 1, name = '[No Name]' }, + { tab = 2, name = 'another-tab' }, } - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - ~ | - ~ | - ~ | + ~ |*3 | - ]], condition=function() - eq({ id = 2 }, event_curtab) - eq(expected_tabs, event_tabs) - end} + ]], + condition = function() + eq(2, event_curtab) + eq(expected_tabs, event_tabs) + end, + } - command("tabNext") - screen:expect{grid=[[ + command('tabNext') + screen:expect { + grid = [[ ^ | - ~ | - ~ | - ~ | + ~ |*3 | - ]], condition=function() - eq({ id = 1 }, event_curtab) - eq(expected_tabs, event_tabs) - end} + ]], + condition = function() + eq(1, event_curtab) + eq(expected_tabs, event_tabs) + end, + } end) it('buffer UI events', function() - local expected_buffers_initial= { - {buffer = { id = 1 }, name = '[No Name]'}, + local expected_buffers_initial = { + { buffer = 1, name = '[No Name]' }, } - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - ~ | - ~ | - ~ | + ~ |*3 | - ]], condition=function() - eq({ id = 1}, event_curbuf) - eq(expected_buffers_initial, event_buffers) - end} + ]], + condition = function() + eq(1, event_curbuf) + eq(expected_buffers_initial, event_buffers) + end, + } - command("badd another-buffer") - command("bnext") + command('badd another-buffer') + command('bnext') local expected_buffers = { - {buffer = { id = 1 }, name = '[No Name]'}, - {buffer = { id = 2 }, name = 'another-buffer'}, + { buffer = 1, name = '[No Name]' }, + { buffer = 2, name = 'another-buffer' }, } - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - ~ | - ~ | - ~ | + ~ |*3 | - ]], condition=function() - eq({ id = 2 }, event_curbuf) - eq(expected_buffers, event_buffers) - end} + ]], + condition = function() + eq(2, event_curbuf) + eq(expected_buffers, event_buffers) + end, + } end) end) -describe("tabline", function() +describe('tabline', function() local screen before_each(function() @@ -96,29 +100,31 @@ describe("tabline", function() screen = Screen.new(42, 5) screen:attach() screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}; -- NonText - [1] = {reverse = true}; -- TabLineFill + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { reverse = true }, -- TabLineFill }) end) it('redraws when tabline option is set', function() command('set tabline=asdf') command('set showtabline=2') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:asdf }| ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]]} + ]], + } command('set tabline=jkl') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:jkl }| ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]]} + ]], + } end) it('click definitions do not leak memory #21765', function() @@ -132,46 +138,64 @@ describe("tabline", function() command('tabnew') insert('tab2') command('tabprev') - meths.set_option_value('tabline', '%1T口口%2Ta' .. ('b'):rep(38) .. '%999Xc', {}) - screen:expect{grid=[[ + api.nvim_set_option_value('tabline', '%1T口口%2Ta' .. ('b'):rep(38) .. '%999Xc', {}) + screen:expect { + grid = [[ {1:<abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc }| tab^1 | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]]} + ]], + } assert_alive() - meths.input_mouse('left', 'press', '', 0, 0, 1) - screen:expect{grid=[[ + api.nvim_input_mouse('left', 'press', '', 0, 0, 1) + screen:expect { + grid = [[ {1:<abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc }| tab^2 | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]]} - meths.input_mouse('left', 'press', '', 0, 0, 0) - screen:expect{grid=[[ + ]], + } + api.nvim_input_mouse('left', 'press', '', 0, 0, 0) + screen:expect { + grid = [[ {1:<abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc }| tab^1 | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]]} - meths.input_mouse('left', 'press', '', 0, 0, 39) - screen:expect{grid=[[ + ]], + } + api.nvim_input_mouse('left', 'press', '', 0, 0, 39) + screen:expect { + grid = [[ {1:<abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc }| tab^2 | - {0:~ }| - {0:~ }| + {0:~ }|*2 | - ]]} - meths.input_mouse('left', 'press', '', 0, 0, 40) - screen:expect{grid=[[ + ]], + } + api.nvim_input_mouse('left', 'press', '', 0, 0, 40) + screen:expect { + grid = [[ tab^1 | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | - ]]} + ]], + } + end) + + it('middle-click closes tab', function() + command('tabnew') + command('tabnew') + command('tabnew') + command('tabprev') + eq({ 3, 4 }, api.nvim_eval('[tabpagenr(), tabpagenr("$")]')) + api.nvim_input_mouse('middle', 'press', '', 0, 0, 1) + eq({ 2, 3 }, api.nvim_eval('[tabpagenr(), tabpagenr("$")]')) + api.nvim_input_mouse('middle', 'press', '', 0, 0, 20) + eq({ 2, 2 }, api.nvim_eval('[tabpagenr(), tabpagenr("$")]')) + api.nvim_input_mouse('middle', 'press', '', 0, 0, 1) + eq({ 1, 1 }, api.nvim_eval('[tabpagenr(), tabpagenr("$")]')) end) end) diff --git a/test/functional/ui/title_spec.lua b/test/functional/ui/title_spec.lua index 66c0ff5c9c..8060d3a460 100644 --- a/test/functional/ui/title_spec.lua +++ b/test/functional/ui/title_spec.lua @@ -2,12 +2,12 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local clear = helpers.clear local command = helpers.command -local curwin = helpers.curwin +local curwin = helpers.api.nvim_get_current_win local eq = helpers.eq local exec_lua = helpers.exec_lua local feed = helpers.feed -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local is_os = helpers.is_os describe('title', function() @@ -43,13 +43,13 @@ describe('title', function() local buf2 before_each(function() - command('edit '..file1) - buf2 = funcs.bufadd(file2) + command('edit ' .. file1) + buf2 = fn.bufadd(file2) command('set title') end) it('calling setbufvar() to set an option in a hidden buffer from i_CTRL-R', function() - command([[inoremap <F2> <C-R>=setbufvar(]]..buf2..[[, '&autoindent', 1) ?? ''<CR>]]) + command([[inoremap <F2> <C-R>=setbufvar(]] .. buf2 .. [[, '&autoindent', 1) ?? ''<CR>]]) feed('i<F2><Esc>') command('redraw!') screen:expect(function() @@ -58,7 +58,7 @@ describe('title', function() end) it('an RPC call to nvim_set_option_value in a hidden buffer', function() - meths.set_option_value('autoindent', true, { buf = buf2 }) + api.nvim_set_option_value('autoindent', true, { buf = buf2 }) command('redraw!') screen:expect(function() eq(expected, screen.title) @@ -66,11 +66,14 @@ describe('title', function() end) it('a Lua callback calling nvim_set_option_value in a hidden buffer', function() - exec_lua(string.format([[ + exec_lua(string.format( + [[ vim.schedule(function() vim.api.nvim_set_option_value('autoindent', true, { buf = %d }) end) - ]], buf2)) + ]], + buf2 + )) command('redraw!') screen:expect(function() eq(expected, screen.title) @@ -78,11 +81,14 @@ describe('title', function() end) it('a Lua callback calling nvim_buf_call in a hidden buffer', function() - exec_lua(string.format([[ + exec_lua(string.format( + [[ vim.schedule(function() vim.api.nvim_buf_call(%d, function() end) end) - ]], buf2)) + ]], + buf2 + )) command('redraw!') screen:expect(function() eq(expected, screen.title) @@ -90,9 +96,9 @@ describe('title', function() end) it('setting the buffer of another window using RPC', function() - local oldwin = curwin().id + local oldwin = curwin() command('split') - meths.win_set_buf(oldwin, buf2) + api.nvim_win_set_buf(oldwin, buf2) command('redraw!') screen:expect(function() eq(expected, screen.title) @@ -100,13 +106,17 @@ describe('title', function() end) it('setting the buffer of another window using Lua callback', function() - local oldwin = curwin().id + local oldwin = curwin() command('split') - exec_lua(string.format([[ + exec_lua(string.format( + [[ vim.schedule(function() vim.api.nvim_win_set_buf(%d, %d) end) - ]], oldwin, buf2)) + ]], + oldwin, + buf2 + )) command('redraw!') screen:expect(function() eq(expected, screen.title) @@ -114,8 +124,12 @@ describe('title', function() end) it('creating a floating window using RPC', function() - meths.open_win(buf2, false, { - relative = 'editor', width = 5, height = 5, row = 0, col = 0, + api.nvim_open_win(buf2, false, { + relative = 'editor', + width = 5, + height = 5, + row = 0, + col = 0, }) command('redraw!') screen:expect(function() @@ -124,11 +138,14 @@ describe('title', function() end) it('creating a floating window using Lua callback', function() - exec_lua(string.format([[ + exec_lua(string.format( + [[ vim.api.nvim_open_win(%d, false, { relative = 'editor', width = 5, height = 5, row = 0, col = 0, }) - ]], buf2)) + ]], + buf2 + )) command('redraw!') screen:expect(function() eq(expected, screen.title) diff --git a/test/functional/ui/wildmode_spec.lua b/test/functional/ui/wildmode_spec.lua index 3201135b67..667dd64d62 100644 --- a/test/functional/ui/wildmode_spec.lua +++ b/test/functional/ui/wildmode_spec.lua @@ -1,8 +1,8 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local clear, feed, command = helpers.clear, helpers.feed, helpers.command -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local eq = helpers.eq local eval = helpers.eval local retry = helpers.retry @@ -20,97 +20,99 @@ describe("'wildmenu'", function() -- oldtest: Test_wildmenu_screendump() it('works', function() screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}; -- NonText - [1] = {foreground = Screen.colors.Black, background = Screen.colors.Yellow}; -- WildMenu - [2] = {bold = true, reverse = true}; -- StatusLine + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { foreground = Screen.colors.Black, background = Screen.colors.Yellow }, -- WildMenu + [2] = { bold = true, reverse = true }, -- StatusLine }) -- Test simple wildmenu feed(':sign <Tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {1:define}{2: jump list > }| :sign define^ | - ]]} + ]], + } feed('<Tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {2:define }{1:jump}{2: list > }| :sign jump^ | - ]]} + ]], + } feed('<Tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {2:define jump }{1:list}{2: > }| :sign list^ | - ]]} + ]], + } -- Looped back to the original value feed('<Tab><Tab><Tab><Tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {2:define jump list > }| :sign ^ | - ]]} + ]], + } -- Test that the wild menu is cleared properly feed('<Space>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 :sign ^ | - ]]} + ]], + } -- Test that a different wildchar still works feed('<Esc>') command('set wildchar=<Esc>') feed(':sign <Esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {1:define}{2: jump list > }| :sign define^ | - ]]} + ]], + } -- Double-<Esc> is a hard-coded method to escape while wildchar=<Esc>. Make -- sure clean up is properly done in edge case like this. feed('<Esc>') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | - ]]} + ]], + } end) it('C-E to cancel wildmenu completion restore original input', function() feed(':sign <tab>') screen:expect([[ | - ~ | - ~ | + ~ |*2 define jump list > | :sign define^ | ]]) feed('<C-E>') screen:expect([[ | - ~ | - ~ | - ~ | + ~ |*3 :sign ^ | ]]) end) @@ -119,17 +121,14 @@ describe("'wildmenu'", function() feed(':sign <tab>') screen:expect([[ | - ~ | - ~ | + ~ |*2 define jump list > | :sign define^ | ]]) feed('<tab><C-Y>') screen:expect([[ | - ~ | - ~ | - ~ | + ~ |*3 :sign jump^ | ]]) end) @@ -139,8 +138,7 @@ describe("'wildmenu'", function() feed(':sign <tab>') screen:expect([[ | - ~ | - ~ | + ~ |*2 define jump list > | :sign define^ | ]]) @@ -154,16 +152,14 @@ describe("'wildmenu'", function() feed(':sign <tab>') screen:expect([[ | - ~ | - ~ | + ~ |*2 define jump list > | :sign define^ | ]]) feed('<space>') screen:expect([[ | - ~ | - ~ | + ~ |*2 [No Name] | :sign define ^ | ]]) @@ -174,8 +170,7 @@ describe("'wildmenu'", function() feed(':j<Tab><Tab><Tab>') screen:expect([[ | - ~ | - ~ | + ~ |*2 join jumps | :j^ | ]]) @@ -183,8 +178,7 @@ describe("'wildmenu'", function() feed('<BS><Tab>') screen:expect([[ | - ~ | - ~ | + ~ |*2 ! # & < = > @ > | :!^ | ]]) @@ -194,52 +188,51 @@ describe("'wildmenu'", function() command('set wildmenu wildmode=full') command('set scrollback=4') feed((':terminal "%s" REP 5000 !terminal_output!<cr>'):format(testprg('shell-test'))) - feed('G') -- Follow :terminal output. - feed([[:sign <Tab>]]) -- Invoke wildmenu. + feed('G') -- Follow :terminal output. + feed([[:sign <Tab>]]) -- Invoke wildmenu. -- NB: in earlier versions terminal output was redrawn during cmdline mode. -- For now just assert that the screen remains unchanged. - screen:expect{any='define jump list > |\n:sign define^ |'} + screen:expect { any = 'define jump list > |\n:sign define^ |' } screen:expect_unchanged() -- cmdline CTRL-D display should also be preserved. feed([[<C-U>]]) - feed([[sign <C-D>]]) -- Invoke cmdline CTRL-D. - screen:expect{grid=[[ + feed([[sign <C-D>]]) -- Invoke cmdline CTRL-D. + screen:expect { + grid = [[ :sign | define place | jump undefine | list unplace | :sign ^ | - ]]} + ]], + } screen:expect_unchanged() -- Exiting cmdline should show the buffer. feed([[<C-\><C-N>]]) - screen:expect{any=[[!terminal_output!]]} + screen:expect { any = [[!terminal_output!]] } end) it('ignores :redrawstatus called from a timer #7108', function() command('set wildmenu wildmode=full') command([[call timer_start(10, {->execute('redrawstatus')}, {'repeat':-1})]]) feed([[<C-\><C-N>]]) - feed([[:sign <Tab>]]) -- Invoke wildmenu. - screen:expect{grid=[[ + feed([[:sign <Tab>]]) -- Invoke wildmenu. + screen:expect { + grid = [[ | - ~ | - ~ | + ~ |*2 define jump list > | :sign define^ | - ]]} + ]], + } screen:expect_unchanged() end) it('with laststatus=0, :vsplit, :term #2255', function() - -- Because this test verifies a _lack_ of activity after screen:sleep(), we - -- must wait the full timeout. So make it reasonable. - screen.timeout = 1000 - if not is_os('win') then - command('set shell=sh') -- Need a predictable "$" prompt. + command('set shell=sh') -- Need a predictable "$" prompt. command('let $PS1 = "$"') end command('set laststatus=0') @@ -256,11 +249,13 @@ describe("'wildmenu'", function() end) feed([[<C-\><C-N>]]) - feed([[:<Tab>]]) -- Invoke wildmenu. + feed([[:<Tab>]]) -- Invoke wildmenu. -- Check only the last 2 lines, because the shell output is -- system-dependent. - screen:expect{any='! # & < = > @ > |\n:!^'} - screen:expect_unchanged() + screen:expect { any = '! # & < = > @ > |\n:!^' } + -- Because this test verifies a _lack_ of activity, we must wait the full timeout. + -- So make it reasonable. + screen:expect_unchanged(false, 1000) end) it('wildmode=list,full and messages interaction #10092', function() @@ -282,21 +277,16 @@ describe("'wildmenu'", function() feed('<tab>') -- trigger wildmode full screen:expect([[ [No Name] | - | - | + |*2 :set wildm | - wildmenu wildmode | - wildmenu wildmode | + wildmenu wildmode |*2 :set wildmenu^ | ]]) feed('<Esc>') screen:expect([[ [No Name] | ^ | - ~ | - ~ | - ~ | - ~ | + ~ |*4 | ]]) end) @@ -311,18 +301,13 @@ describe("'wildmenu'", function() feed(':sign u<tab>') screen:expect([[ | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*5 :sign un^ | ]]) feed('<tab>') -- trigger wildmode list screen:expect([[ | - ~ | - ~ | + ~ |*2 | :sign un | undefine unplace | @@ -331,11 +316,7 @@ describe("'wildmenu'", function() feed('<Esc>') screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*5 | ]]) @@ -343,8 +324,7 @@ describe("'wildmenu'", function() feed(':sign un<tab>') screen:expect([[ | - ~ | - ~ | + ~ |*2 | :sign un | undefine unplace | @@ -355,11 +335,7 @@ describe("'wildmenu'", function() feed('<Esc>') screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*5 | ]]) end) @@ -372,8 +348,7 @@ describe("'wildmenu'", function() feed(':sign u<tab>') screen:expect([[ | - ~ | - ~ | + ~ |*2 | :sign u | undefine unplace | @@ -382,8 +357,7 @@ describe("'wildmenu'", function() feed('<tab>') -- trigger wildmode longest screen:expect([[ | - ~ | - ~ | + ~ |*2 | :sign u | undefine unplace | @@ -392,11 +366,7 @@ describe("'wildmenu'", function() feed('<Esc>') screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*5 | ]]) end) @@ -409,8 +379,7 @@ describe("'wildmenu'", function() feed('<c-d>') screen:expect([[ | - ~ | - ~ | + ~ |*2 | :set wildm | wildmenu wildmode | @@ -418,8 +387,7 @@ describe("'wildmenu'", function() ]]) feed('<c-d>') screen:expect([[ - | - | + |*2 :set wildm | wildmenu wildmode | :set wildm | @@ -429,10 +397,7 @@ describe("'wildmenu'", function() feed('<Esc>') screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | + ~ |*4 [No Name] | | ]]) @@ -440,28 +405,29 @@ describe("'wildmenu'", function() it('works with c_CTRL_Z standard mapping', function() screen:set_default_attr_ids { - [1] = {bold = true, foreground = Screen.colors.Blue1}; - [2] = {foreground = Screen.colors.Grey0, background = Screen.colors.Yellow}; - [3] = {bold = true, reverse = true}; + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.Grey0, background = Screen.colors.Yellow }, + [3] = { bold = true, reverse = true }, } -- Wildcharm? where we are going we aint't no need no wildcharm. - eq(0, meths.get_option_value('wildcharm', {})) + eq(0, api.nvim_get_option_value('wildcharm', {})) -- Don't mess the defaults yet (neovim is about backwards compatibility) - eq(9, meths.get_option_value('wildchar', {})) + eq(9, api.nvim_get_option_value('wildchar', {})) -- Lol what is cnoremap? Some say it can define mappings. command 'set wildchar=0' - eq(0, meths.get_option_value('wildchar', {})) + eq(0, api.nvim_get_option_value('wildchar', {})) command 'cnoremap <f2> <c-z>' feed(':syntax <f2>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:case}{3: clear cluster > }| :syntax case^ | - ]]} + ]], + } feed '<esc>' command 'set wildmode=longest:full,full' @@ -469,31 +435,32 @@ describe("'wildmenu'", function() command [[cnoremap <expr> <tab> luaeval("not rawset(_G, 'coin', not coin).coin") ? "<c-z>" : "c"]] feed ':syntax <tab>' - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 :syntax c^ | - ]]} + ]], + } feed '<tab>' - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {3:case clear cluster > }| :syntax c^ | - ]]} + ]], + } feed '<tab>' - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 :syntax cc^ | - ]]} + ]], + } end) end) @@ -503,9 +470,9 @@ describe('command line completion', function() clear() screen = Screen.new(40, 5) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {foreground = Screen.colors.Grey0, background = Screen.colors.Yellow}, - [3] = {bold = true, reverse = true}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.Grey0, background = Screen.colors.Yellow }, + [3] = { bold = true, reverse = true }, }) screen:attach() end) @@ -514,17 +481,15 @@ describe('command line completion', function() end) it('lists directories with empty PATH', function() - local tmp = funcs.tempname() - command('e '.. tmp) + local tmp = fn.tempname() + command('e ' .. tmp) command('cd %:h') command("call mkdir('Xtest-functional-viml-compl-dir')") command('let $PATH=""') feed(':!<tab><bs>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 :!Xtest-functional-viml-compl-dir^ | ]]) end) @@ -535,71 +500,63 @@ describe('command line completion', function() feed(':!echo $XTEST_<tab>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:XTEST_1}{3: XTEST_2 }| :!echo $XTEST_1^ | ]]) end) it('completes (multibyte) env var names #9655', function() - clear({env={ - ['XTEST_1AaあB']='foo', - ['XTEST_2']='bar', - }}) + clear({ env = { + ['XTEST_1AaあB'] = 'foo', + ['XTEST_2'] = 'bar', + } }) screen:attach() command('set wildmenu wildmode=full') feed(':!echo $XTEST_<tab>') screen:expect([[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {2:XTEST_1AaあB}{3: XTEST_2 }| :!echo $XTEST_1AaあB^ | ]]) end) it('does not leak memory with <S-Tab> with wildmenu and only one match #19874', function() - meths.set_option_value('wildmenu', true, {}) - meths.set_option_value('wildmode', 'full', {}) - meths.set_option_value('wildoptions', 'pum', {}) + api.nvim_set_option_value('wildmenu', true, {}) + api.nvim_set_option_value('wildmode', 'full', {}) + api.nvim_set_option_value('wildoptions', 'pum', {}) feed(':sign unpla<S-Tab>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 :sign unplace^ | ]]) feed('<Space>buff<Tab>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 :sign unplace buffer=^ | ]]) end) it('does not show matches with <S-Tab> without wildmenu with wildmode=full', function() - meths.set_option_value('wildmenu', false, {}) - meths.set_option_value('wildmode', 'full', {}) + api.nvim_set_option_value('wildmenu', false, {}) + api.nvim_set_option_value('wildmode', 'full', {}) feed(':sign <S-Tab>') screen:expect([[ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 :sign unplace^ | ]]) end) it('shows matches with <S-Tab> without wildmenu with wildmode=list', function() - meths.set_option_value('wildmenu', false, {}) - meths.set_option_value('wildmode', 'list', {}) + api.nvim_set_option_value('wildmenu', false, {}) + api.nvim_set_option_value('wildmode', 'list', {}) feed(':sign <S-Tab>') screen:expect([[ @@ -618,64 +575,72 @@ describe('ui/ext_wildmenu', function() before_each(function() clear() screen = Screen.new(25, 5) - screen:attach({rgb=true, ext_wildmenu=true}) + screen:attach({ rgb = true, ext_wildmenu = true }) end) it('works with :sign <tab>', function() local expected = { - 'define', - 'jump', - 'list', - 'place', - 'undefine', - 'unplace', + 'define', + 'jump', + 'list', + 'place', + 'undefine', + 'unplace', } command('set wildmode=full') command('set wildmenu') feed(':sign <tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - ~ | - ~ | - ~ | + ~ |*3 :sign define^ | - ]], wildmenu_items=expected, wildmenu_pos=0} + ]], + wildmenu_items = expected, + wildmenu_pos = 0, + } feed('<tab>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - ~ | - ~ | - ~ | + ~ |*3 :sign jump^ | - ]], wildmenu_items=expected, wildmenu_pos=1} + ]], + wildmenu_items = expected, + wildmenu_pos = 1, + } feed('<left><left>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - ~ | - ~ | - ~ | + ~ |*3 :sign ^ | - ]], wildmenu_items=expected, wildmenu_pos=-1} + ]], + wildmenu_items = expected, + wildmenu_pos = -1, + } feed('<right>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - ~ | - ~ | - ~ | + ~ |*3 :sign define^ | - ]], wildmenu_items=expected, wildmenu_pos=0} + ]], + wildmenu_items = expected, + wildmenu_pos = 0, + } feed('a') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - ~ | - ~ | - ~ | + ~ |*3 :sign definea^ | - ]]} + ]], + } end) end) diff --git a/test/functional/ui/winbar_spec.lua b/test/functional/ui/winbar_spec.lua index 78bbcd3a63..c2a52c0f21 100644 --- a/test/functional/ui/winbar_spec.lua +++ b/test/functional/ui/winbar_spec.lua @@ -3,12 +3,11 @@ local Screen = require('test.functional.ui.screen') local clear = helpers.clear local command = helpers.command local insert = helpers.insert -local meths = helpers.meths +local api = helpers.api local eq = helpers.eq local poke_eventloop = helpers.poke_eventloop local feed = helpers.feed -local funcs = helpers.funcs -local curwin = helpers.curwin +local fn = helpers.fn local pcall_err = helpers.pcall_err describe('winbar', function() @@ -19,59 +18,50 @@ describe('winbar', function() screen = Screen.new(60, 13) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true}, - [2] = {reverse = true}, - [3] = {bold = true, foreground = Screen.colors.Blue}, - [4] = {bold = true, reverse = true}, - [5] = {bold = true, foreground = Screen.colors.Red}, - [6] = {foreground = Screen.colors.Blue}, - [7] = {background = Screen.colors.LightGrey}, - [8] = {background = Screen.colors.LightMagenta}, - [9] = {bold = true, foreground = Screen.colors.Blue, background = Screen.colors.LightMagenta}, - [10] = {background = Screen.colors.LightGrey, underline = true}, - [11] = {background = Screen.colors.LightGrey, underline = true, bold = true, foreground = Screen.colors.Magenta}, + [1] = { bold = true }, + [2] = { reverse = true }, + [3] = { bold = true, foreground = Screen.colors.Blue }, + [4] = { bold = true, reverse = true }, + [5] = { bold = true, foreground = Screen.colors.Red }, + [6] = { foreground = Screen.colors.Blue }, + [7] = { foreground = Screen.colors.Black, background = Screen.colors.LightGrey }, + [8] = { background = Screen.colors.LightMagenta }, + [9] = { + bold = true, + foreground = Screen.colors.Blue, + background = Screen.colors.LightMagenta, + }, + [10] = { background = Screen.colors.LightGrey, underline = true }, + [11] = { + background = Screen.colors.LightGrey, + underline = true, + bold = true, + foreground = Screen.colors.Magenta, + }, }) - meths.set_option_value('winbar', 'Set Up The Bars', {}) + api.nvim_set_option_value('winbar', 'Set Up The Bars', {}) end) it('works', function() screen:expect([[ {1:Set Up The Bars }| ^ | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*10 | ]]) -- winbar is excluded from the heights returned by winheight() and getwininfo() - eq(11, funcs.winheight(0)) - local win_info = funcs.getwininfo(curwin().id)[1] + eq(11, fn.winheight(0)) + local win_info = fn.getwininfo(api.nvim_get_current_win())[1] eq(11, win_info.height) eq(1, win_info.winbar) end) - it('works with custom \'fillchars\' value', function() + it("works with custom 'fillchars' value", function() command('set fillchars=wbr:+') screen:expect([[ {1:Set Up The Bars+++++++++++++++++++++++++++++++++++++++++++++}| ^ | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*10 | ]]) end) @@ -81,16 +71,7 @@ describe('winbar', function() screen:expect([[ {5:Set Up The Bars }| ^ | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*10 | ]]) end) @@ -151,20 +132,17 @@ describe('winbar', function() ]]) end) - it('works when switching value of \'winbar\'', function() + it("works when switching value of 'winbar'", function() command('belowright vsplit | split | split | set winbar=') screen:expect([[ │^ | - {3:~ }│{3:~ }| - {3:~ }│{3:~ }| + {3:~ }│{3:~ }|*2 {3:~ }│{4:[No Name] }| {3:~ }│ | - {3:~ }│{3:~ }| - {3:~ }│{3:~ }| + {3:~ }│{3:~ }|*2 {3:~ }│{2:[No Name] }| {3:~ }│ | - {3:~ }│{3:~ }| - {3:~ }│{3:~ }| + {3:~ }│{3:~ }|*2 {2:[No Name] [No Name] }| | ]]) @@ -206,54 +184,36 @@ describe('winbar', function() insert [[ just some random text]] - meths.set_option_value('winbar', 'Hello, I am a ruler: %l,%c', {}) - screen:expect{grid=[[ + api.nvim_set_option_value('winbar', 'Hello, I am a ruler: %l,%c', {}) + screen:expect { + grid = [[ {1:Hello, I am a ruler: 2,11 }| just some | random tex^t | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*9 | - ]]} + ]], + } feed 'b' - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:Hello, I am a ruler: 2,8 }| just some | random ^text | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*9 | - ]]} + ]], + } feed 'k' - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:Hello, I am a ruler: 1,8 }| just so^me | random text | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*9 | - ]]} + ]], + } end) it('works with laststatus=3', function() @@ -261,15 +221,7 @@ describe('winbar', function() screen:expect([[ {1:Set Up The Bars }| ^ | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*9 {4:[No Name] }| | ]]) @@ -295,14 +247,7 @@ describe('winbar', function() {10: }{11:4}{10: [No Name] }{1: [No Name] }{2: }{10:X}| {1:Set Up The Bars }| ^ | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*8 {4:[No Name] }| | ]]) @@ -319,7 +264,7 @@ describe('winbar', function() line sin(theta) line 8]]) - meths.input_mouse('left', 'press', '', 0, 5, 1) + api.nvim_input_mouse('left', 'press', '', 0, 5, 1) screen:expect([[ {1:Set Up The Bars }| line 1 | @@ -330,14 +275,12 @@ describe('winbar', function() line i | line sin(theta) | line 8 | - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*3 | ]]) - eq({5, 1}, meths.win_get_cursor(0)) + eq({ 5, 1 }, api.nvim_win_get_cursor(0)) - meths.input_mouse('left', 'drag', '', 0, 6, 2) + api.nvim_input_mouse('left', 'drag', '', 0, 6, 2) screen:expect([[ {1:Set Up The Bars }| line 1 | @@ -348,14 +291,12 @@ describe('winbar', function() {7:li}^ne i | line sin(theta) | line 8 | - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*3 {1:-- VISUAL --} | ]]) - eq({6, 2}, meths.win_get_cursor(0)) + eq({ 6, 2 }, api.nvim_win_get_cursor(0)) - meths.input_mouse('left', 'drag', '', 0, 1, 2) + api.nvim_input_mouse('left', 'drag', '', 0, 1, 2) screen:expect([[ {1:Set Up The Bars }| li^n{7:e 1} | @@ -366,16 +307,14 @@ describe('winbar', function() line i | line sin(theta) | line 8 | - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*3 {1:-- VISUAL --} | ]]) - eq({1, 2}, meths.win_get_cursor(0)) + eq({ 1, 2 }, api.nvim_win_get_cursor(0)) - meths.input_mouse('left', 'drag', '', 0, 0, 2) + api.nvim_input_mouse('left', 'drag', '', 0, 0, 2) screen:expect_unchanged() - eq({1, 2}, meths.win_get_cursor(0)) + eq({ 1, 2 }, api.nvim_win_get_cursor(0)) end) it('dragging statusline with mouse works correctly', function() @@ -383,92 +322,72 @@ describe('winbar', function() screen:expect([[ {1:Set Up The Bars }| ^ | - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*3 {4:[No Name] }| {1:Set Up The Bars }| | - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*3 {2:[No Name] }| | ]]) - meths.input_mouse('left', 'press', '', 1, 5, 10) + api.nvim_input_mouse('left', 'press', '', 1, 5, 10) poke_eventloop() - meths.input_mouse('left', 'drag', '', 1, 6, 10) + api.nvim_input_mouse('left', 'drag', '', 1, 6, 10) screen:expect([[ {1:Set Up The Bars }| ^ | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*4 {4:[No Name] }| {1:Set Up The Bars }| | - {3:~ }| - {3:~ }| + {3:~ }|*2 {2:[No Name] }| | ]]) - meths.input_mouse('left', 'drag', '', 1, 4, 10) + api.nvim_input_mouse('left', 'drag', '', 1, 4, 10) screen:expect([[ {1:Set Up The Bars }| ^ | - {3:~ }| - {3:~ }| + {3:~ }|*2 {4:[No Name] }| {1:Set Up The Bars }| | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*4 {2:[No Name] }| | ]]) - meths.input_mouse('left', 'press', '', 1, 11, 10) + api.nvim_input_mouse('left', 'press', '', 1, 11, 10) poke_eventloop() - meths.input_mouse('left', 'drag', '', 1, 9, 10) + api.nvim_input_mouse('left', 'drag', '', 1, 9, 10) screen:expect([[ {1:Set Up The Bars }| ^ | - {3:~ }| - {3:~ }| + {3:~ }|*2 {4:[No Name] }| {1:Set Up The Bars }| | - {3:~ }| - {3:~ }| + {3:~ }|*2 {2:[No Name] }| - | - | - | + |*3 ]]) - eq(3, meths.get_option_value('cmdheight', {})) + eq(3, api.nvim_get_option_value('cmdheight', {})) - meths.input_mouse('left', 'drag', '', 1, 11, 10) + api.nvim_input_mouse('left', 'drag', '', 1, 11, 10) screen:expect([[ {1:Set Up The Bars }| ^ | - {3:~ }| - {3:~ }| + {3:~ }|*2 {4:[No Name] }| {1:Set Up The Bars }| | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*4 {2:[No Name] }| | ]]) - eq(1, meths.get_option_value('cmdheight', {})) + eq(1, api.nvim_get_option_value('cmdheight', {})) end) it('properly equalizes window height for window-local value', function() @@ -493,40 +412,34 @@ describe('winbar', function() end) it('requires window-local value for floating windows', function() - local win = meths.open_win(0, false, { relative = 'editor', row = 2, col = 10, height = 7, - width = 30 }) - meths.set_option_value('winbar', 'bar', {}) - screen:expect{grid=[[ + local win = api.nvim_open_win( + 0, + false, + { relative = 'editor', row = 2, col = 10, height = 7, width = 30 } + ) + api.nvim_set_option_value('winbar', 'bar', {}) + screen:expect { + grid = [[ {1:bar }| ^ | {3:~ }{8: }{3: }| - {3:~ }{9:~ }{3: }| - {3:~ }{9:~ }{3: }| - {3:~ }{9:~ }{3: }| - {3:~ }{9:~ }{3: }| - {3:~ }{9:~ }{3: }| - {3:~ }{9:~ }{3: }| - {3:~ }| - {3:~ }| - {3:~ }| - | - ]]} - meths.set_option_value('winbar', 'floaty bar', { scope = 'local', win = win.id }) - screen:expect{grid=[[ + {3:~ }{9:~ }{3: }|*6 + {3:~ }|*3 + | + ]], + } + api.nvim_set_option_value('winbar', 'floaty bar', { scope = 'local', win = win }) + screen:expect { + grid = [[ {1:bar }| ^ | {3:~ }{1:floaty bar }{3: }| {3:~ }{8: }{3: }| - {3:~ }{9:~ }{3: }| - {3:~ }{9:~ }{3: }| - {3:~ }{9:~ }{3: }| - {3:~ }{9:~ }{3: }| - {3:~ }{9:~ }{3: }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }{9:~ }{3: }|*5 + {3:~ }|*3 | - ]]} + ]], + } end) it('works correctly when moving a split', function() @@ -537,8 +450,7 @@ describe('winbar', function() screen:expect([[ {1:foo }│ | ^ │{3:~ }| - {3:~ }│{3:~ }| - {3:~ }│{3:~ }| + {3:~ }│{3:~ }|*2 {4:[No Name] }{2:[No Name] }| | ]]) @@ -547,8 +459,7 @@ describe('winbar', function() screen:expect([[ │{1:foo }| {3:~ }│^ | - {3:~ }│{3:~ }| - {3:~ }│{3:~ }| + {3:~ }│{3:~ }|*2 {2:[No Name] }{4:[No Name] }| | ]]) @@ -558,8 +469,7 @@ describe('winbar', function() screen:expect([[ {1:foo }│^ | │{3:~ }| - {3:~ }│{3:~ }| - {3:~ }│{3:~ }| + {3:~ }│{3:~ }|*2 {2:[No Name] }{4:[No Name] }| | ]]) @@ -571,14 +481,7 @@ describe('winbar', function() ^ | {4:[No Name] }| | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*8 {2:[No Name] }| | ]]) @@ -589,12 +492,7 @@ describe('winbar', function() {4:[No Name] }| {1:a }| | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*6 {2:[No Name] }| | ]]) @@ -628,12 +526,12 @@ describe('local winbar with tabs', function() screen = Screen.new(60, 10) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true}, - [2] = {reverse = true}, - [3] = {bold = true, foreground = Screen.colors.Blue}, - [4] = {underline = true, background = Screen.colors.LightGray} + [1] = { bold = true }, + [2] = { reverse = true }, + [3] = { bold = true, foreground = Screen.colors.Blue }, + [4] = { underline = true, background = Screen.colors.LightGray }, }) - meths.set_option_value('winbar', 'foo', { scope = 'local', win = 0 }) + api.nvim_set_option_value('winbar', 'foo', { scope = 'local', win = 0 }) end) it('works', function() @@ -641,28 +539,19 @@ describe('local winbar with tabs', function() screen:expect([[ {4: [No Name] }{1: [No Name] }{2: }{4:X}| ^ | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*7 | ]]) command('tabnext') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: [No Name] }{4: [No Name] }{2: }{4:X}| {1:foo }| ^ | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*6 | - ]]} + ]], + } end) it('can edit new empty buffer #19458', function() @@ -670,68 +559,65 @@ describe('local winbar with tabs', function() some goofy text]] - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:foo }| some | goofy | tex^t | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*5 | - ]]} + ]], + } -- this used to throw an E315 ml_get error command 'tabedit' - screen:expect{grid=[[ + screen:expect { + grid = [[ {4: + [No Name] }{1: [No Name] }{2: }{4:X}| ^ | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*7 | - ]]} + ]], + } command 'tabprev' - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: + [No Name] }{4: [No Name] }{2: }{4:X}| {1:foo }| some | goofy | tex^t | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| + {3:~ }|*4 | - ]]} + ]], + } end) end) it('winbar works properly when redrawing is postponed #23534', function() - clear({args = { - '-c', 'set laststatus=2 lazyredraw', - '-c', 'setlocal statusline=(statusline) winbar=(winbar)', - '-c', 'call nvim_input(":<Esc>")', - }}) + clear({ + args = { + '-c', + 'set laststatus=2 lazyredraw', + '-c', + 'setlocal statusline=(statusline) winbar=(winbar)', + '-c', + 'call nvim_input(":<Esc>")', + }, + }) local screen = Screen.new(60, 6) screen:attach() screen:set_default_attr_ids({ - [0] = {foreground = Screen.colors.Blue, bold = true}, - [1] = {bold = true}, - [2] = {bold = true, reverse = true}, + [0] = { foreground = Screen.colors.Blue, bold = true }, + [1] = { bold = true }, + [2] = { bold = true, reverse = true }, }) screen:expect([[ {1:(winbar) }| ^ | - {0:~ }| - {0:~ }| + {0:~ }|*2 {2:(statusline) }| | ]]) diff --git a/test/functional/vimscript/api_functions_spec.lua b/test/functional/vimscript/api_functions_spec.lua index 0a7e7c1137..4985768bb0 100644 --- a/test/functional/vimscript/api_functions_spec.lua +++ b/test/functional/vimscript/api_functions_spec.lua @@ -1,35 +1,35 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local luv = require('luv') local neq, eq, command = helpers.neq, helpers.eq, helpers.command -local clear, curbufmeths = helpers.clear, helpers.curbufmeths +local clear = helpers.clear local exc_exec, expect, eval = helpers.exc_exec, helpers.expect, helpers.eval +local exec_lua = helpers.exec_lua local insert, pcall_err = helpers.insert, helpers.pcall_err local matches = helpers.matches -local meths = helpers.meths +local api = helpers.api local feed = helpers.feed describe('eval-API', function() before_each(clear) - it("work", function() + it('work', function() command("call nvim_command('let g:test = 1')") eq(1, eval("nvim_get_var('test')")) - local buf = eval("nvim_get_current_buf()") - command("call nvim_buf_set_lines("..buf..", 0, -1, v:true, ['aa', 'bb'])") + local buf = eval('nvim_get_current_buf()') + command('call nvim_buf_set_lines(' .. buf .. ", 0, -1, v:true, ['aa', 'bb'])") expect([[ aa bb]]) - command("call nvim_win_set_cursor(0, [1, 1])") + command('call nvim_win_set_cursor(0, [1, 1])') command("call nvim_input('ax<esc>')") expect([[ aax bb]]) end) - it("throw errors for invalid arguments", function() + it('throw errors for invalid arguments', function() local err = exc_exec('call nvim_get_current_buf("foo")') eq('Vim(call):E118: Too many arguments for function: nvim_get_current_buf', err) @@ -37,100 +37,134 @@ describe('eval-API', function() eq('Vim(call):E119: Not enough arguments for function: nvim_set_option_value', err) err = exc_exec('call nvim_buf_set_lines(1, 0, -1, [], ["list"])') - eq('Vim(call):E5555: API call: Wrong type for argument 4 when calling nvim_buf_set_lines, expecting Boolean', err) + eq( + 'Vim(call):E5555: API call: Wrong type for argument 4 when calling nvim_buf_set_lines, expecting Boolean', + err + ) err = exc_exec('call nvim_buf_set_lines(0, 0, -1, v:true, "string")') - eq('Vim(call):E5555: API call: Wrong type for argument 5 when calling nvim_buf_set_lines, expecting ArrayOf(String)', err) + eq( + 'Vim(call):E5555: API call: Wrong type for argument 5 when calling nvim_buf_set_lines, expecting ArrayOf(String)', + err + ) err = exc_exec('call nvim_buf_get_number("0")') - eq('Vim(call):E5555: API call: Wrong type for argument 1 when calling nvim_buf_get_number, expecting Buffer', err) + eq( + 'Vim(call):E5555: API call: Wrong type for argument 1 when calling nvim_buf_get_number, expecting Buffer', + err + ) err = exc_exec('call nvim_buf_line_count(17)') eq('Vim(call):E5555: API call: Invalid buffer id: 17', err) end) it('cannot change text or window if textlocked', function() - command("autocmd TextYankPost <buffer> ++once call nvim_buf_set_lines(0, 0, -1, v:false, [])") - matches('Vim%(call%):E5555: API call: E565: Not allowed to change text or change window$', - pcall_err(command, "normal! yy")) - - command("autocmd TextYankPost <buffer> ++once call nvim_open_term(0, {})") - matches('Vim%(call%):E5555: API call: E565: Not allowed to change text or change window$', - pcall_err(command, "normal! yy")) + command('autocmd TextYankPost <buffer> ++once call nvim_buf_set_lines(0, 0, -1, v:false, [])') + matches( + 'Vim%(call%):E5555: API call: E565: Not allowed to change text or change window$', + pcall_err(command, 'normal! yy') + ) + + command('autocmd TextYankPost <buffer> ++once call nvim_open_term(0, {})') + matches( + 'Vim%(call%):E5555: API call: E565: Not allowed to change text or change window$', + pcall_err(command, 'normal! yy') + ) -- Functions checking textlock should also not be usable from <expr> mappings. - command("inoremap <expr> <f2> nvim_win_close(0, 1)") - eq('Vim(normal):E5555: API call: E565: Not allowed to change text or change window', - pcall_err(command, [[execute "normal i\<f2>"]])) + command('inoremap <expr> <f2> nvim_win_close(0, 1)') + eq( + 'Vim(normal):E5555: API call: E565: Not allowed to change text or change window', + pcall_err(command, [[execute "normal i\<f2>"]]) + ) -- Text-changing functions gave a "Failed to save undo information" error when called from an -- <expr> mapping outside do_cmdline() (msg_list == NULL), so use feed() to test this. command("inoremap <expr> <f2> nvim_buf_set_text(0, 0, 0, 0, 0, ['hi'])") - meths.set_vvar('errmsg', '') - feed("i<f2><esc>") - eq('E5555: API call: E565: Not allowed to change text or change window', - meths.get_vvar('errmsg')) + api.nvim_set_vvar('errmsg', '') + feed('i<f2><esc>') + eq( + 'E5555: API call: E565: Not allowed to change text or change window', + api.nvim_get_vvar('errmsg') + ) -- Some functions checking textlock (usually those that may change the current window or buffer) -- also ought to not be usable in the cmdwin. - local old_win = meths.get_current_win() - feed("q:") - eq('E11: Invalid in command-line window; <CR> executes, CTRL-C quits', - pcall_err(meths.set_current_win, old_win)) + local old_win = api.nvim_get_current_win() + feed('q:') + eq( + 'E11: Invalid in command-line window; <CR> executes, CTRL-C quits', + pcall_err(api.nvim_set_current_win, old_win) + ) -- But others, like nvim_buf_set_lines(), which just changes text, is OK. - curbufmeths.set_lines(0, -1, 1, {"wow!"}) - eq({'wow!'}, curbufmeths.get_lines(0, -1, 1)) + api.nvim_buf_set_lines(0, 0, -1, 1, { 'wow!' }) + eq({ 'wow!' }, api.nvim_buf_get_lines(0, 0, -1, 1)) -- Turning the cmdwin buffer into a terminal buffer would be pretty weird. - eq('E11: Invalid in command-line window; <CR> executes, CTRL-C quits', - pcall_err(meths.open_term, 0, {})) + eq( + 'E11: Invalid in command-line window; <CR> executes, CTRL-C quits', + pcall_err(api.nvim_open_term, 0, {}) + ) + + matches( + 'E11: Invalid in command%-line window; <CR> executes, CTRL%-C quits$', + pcall_err( + exec_lua, + [[ + local cmdwin_buf = vim.api.nvim_get_current_buf() + vim.api.nvim_buf_call(vim.api.nvim_create_buf(false, true), function() + vim.api.nvim_open_term(cmdwin_buf, {}) + end) + ]] + ) + ) -- But turning a different buffer into a terminal from the cmdwin is OK. - local term_buf = meths.create_buf(false, true) - meths.open_term(term_buf, {}) - eq('terminal', meths.get_option_value("buftype", {buf = term_buf})) + local term_buf = api.nvim_create_buf(false, true) + api.nvim_open_term(term_buf, {}) + eq('terminal', api.nvim_get_option_value('buftype', { buf = term_buf })) end) - it("use buffer numbers and windows ids as handles", function() + it('use buffer numbers and windows ids as handles', function() local screen = Screen.new(40, 8) screen:attach() local bnr = eval("bufnr('')") - local bhnd = eval("nvim_get_current_buf()") - local wid = eval("win_getid()") - local whnd = eval("nvim_get_current_win()") + local bhnd = eval('nvim_get_current_buf()') + local wid = eval('win_getid()') + local whnd = eval('nvim_get_current_win()') eq(bnr, bhnd) eq(wid, whnd) - command("new") -- creates new buffer and new window + command('new') -- creates new buffer and new window local bnr2 = eval("bufnr('')") - local bhnd2 = eval("nvim_get_current_buf()") - local wid2 = eval("win_getid()") - local whnd2 = eval("nvim_get_current_win()") + local bhnd2 = eval('nvim_get_current_buf()') + local wid2 = eval('win_getid()') + local whnd2 = eval('nvim_get_current_win()') eq(bnr2, bhnd2) eq(wid2, whnd2) neq(bnr, bnr2) neq(wid, wid2) -- 0 is synonymous to the current buffer - eq(bnr2, eval("nvim_buf_get_number(0)")) + eq(bnr2, eval('nvim_buf_get_number(0)')) - command("bn") -- show old buffer in new window - eq(bnr, eval("nvim_get_current_buf()")) + command('bn') -- show old buffer in new window + eq(bnr, eval('nvim_get_current_buf()')) eq(bnr, eval("bufnr('')")) - eq(bnr, eval("nvim_buf_get_number(0)")) - eq(wid2, eval("win_getid()")) - eq(whnd2, eval("nvim_get_current_win()")) + eq(bnr, eval('nvim_buf_get_number(0)')) + eq(wid2, eval('win_getid()')) + eq(whnd2, eval('nvim_get_current_win()')) end) - it("get_lines and set_lines use NL to represent NUL", function() - curbufmeths.set_lines(0, -1, true, {"aa\0", "b\0b"}) - eq({'aa\n', 'b\nb'}, eval("nvim_buf_get_lines(0, 0, -1, 1)")) + it('get_lines and set_lines use NL to represent NUL', function() + api.nvim_buf_set_lines(0, 0, -1, true, { 'aa\0', 'b\0b' }) + eq({ 'aa\n', 'b\nb' }, eval('nvim_buf_get_lines(0, 0, -1, 1)')) command('call nvim_buf_set_lines(0, 1, 2, v:true, ["xx", "\\nyy"])') - eq({'aa\0', 'xx', '\0yy'}, curbufmeths.get_lines(0, -1, 1)) + eq({ 'aa\0', 'xx', '\0yy' }, api.nvim_buf_get_lines(0, 0, -1, 1)) end) - it("that are FUNC_ATTR_NOEVAL cannot be called", function() + it('that are FUNC_ATTR_NOEVAL cannot be called', function() -- Deprecated vim_ prefix is not exported. local err = exc_exec('call vim_get_current_buffer("foo")') eq('Vim(call):E117: Unknown function: vim_get_current_buffer', err) @@ -150,29 +184,24 @@ describe('eval-API', function() end) it('have metadata accessible with api_info()', function() - local api_keys = eval("sort(keys(api_info()))") - eq({'error_types', 'functions', 'types', - 'ui_events', 'ui_options', 'version'}, api_keys) + local api_keys = eval('sort(keys(api_info()))') + eq({ 'error_types', 'functions', 'types', 'ui_events', 'ui_options', 'version' }, api_keys) end) it('are highlighted by vim.vim syntax file', function() - if luv.fs_stat("build/runtime/syntax/vim/generated.vim").uid == nil then - pending("runtime was not built, skipping test") - return - end local screen = Screen.new(40, 8) screen:attach() screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Brown}, - [2] = {foreground = Screen.colors.DarkCyan}, - [3] = {foreground = Screen.colors.SlateBlue}, - [4] = {foreground = Screen.colors.Fuchsia}, - [5] = {bold = true, foreground = Screen.colors.Blue}, + [1] = { bold = true, foreground = Screen.colors.Brown }, + [2] = { foreground = Screen.colors.DarkCyan }, + [3] = { foreground = Screen.colors.SlateBlue }, + [4] = { foreground = Screen.colors.Fuchsia }, + [5] = { bold = true, foreground = Screen.colors.Blue }, }) - command("set ft=vim") - command("set rtp^=build/runtime/") - command("syntax on") + command('set ft=vim') + command('set rtp^=build/runtime/') + command('syntax on') insert([[ call bufnr('%') call nvim_input('typing...') @@ -182,18 +211,17 @@ describe('eval-API', function() {1:call} {2:bufnr}{3:(}{4:'%'}{3:)} | {1:call} {2:nvim_input}{3:(}{4:'typing...'}{3:)} | {1:call} not_a_function{3:(}{4:42}{3:^)} | - {5:~ }| - {5:~ }| - {5:~ }| - {5:~ }| + {5:~ }|*4 | ]]) end) it('cannot be called from sandbox', function() - eq('Vim(call):E48: Not allowed in sandbox', - pcall_err(command, "sandbox call nvim_input('ievil')")) - eq({''}, meths.buf_get_lines(0, 0, -1, true)) + eq( + 'Vim(call):E48: Not allowed in sandbox', + pcall_err(command, "sandbox call nvim_input('ievil')") + ) + eq({ '' }, api.nvim_buf_get_lines(0, 0, -1, true)) end) it('converts blobs to API strings', function() diff --git a/test/functional/vimscript/buf_functions_spec.lua b/test/functional/vimscript/buf_functions_spec.lua index 2a5720fbd7..931fe640a9 100644 --- a/test/functional/vimscript/buf_functions_spec.lua +++ b/test/functional/vimscript/buf_functions_spec.lua @@ -1,17 +1,11 @@ local helpers = require('test.functional.helpers')(after_each) -local luv = require('luv') - local eq = helpers.eq local clear = helpers.clear -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local command = helpers.command local exc_exec = helpers.exc_exec -local bufmeths = helpers.bufmeths -local curbufmeths = helpers.curbufmeths -local curwinmeths = helpers.curwinmeths -local curtabmeths = helpers.curtabmeths local get_pathsep = helpers.get_pathsep local rmdir = helpers.rmdir local pcall_err = helpers.pcall_err @@ -23,30 +17,47 @@ local dirname = fname .. '.d' before_each(clear) -for _, func in ipairs({'bufname(%s)', 'bufnr(%s)', 'bufwinnr(%s)', - 'getbufline(%s, 1)', 'getbufvar(%s, "changedtick")', - 'setbufvar(%s, "f", 0)'}) do +for _, func in ipairs({ + 'bufname(%s)', + 'bufnr(%s)', + 'bufwinnr(%s)', + 'getbufline(%s, 1)', + 'getbufvar(%s, "changedtick")', + 'setbufvar(%s, "f", 0)', +}) do local funcname = func:match('%w+') describe(funcname .. '() function', function() it('errors out when receives v:true/v:false/v:null', function() -- Not compatible with Vim: in Vim it always results in buffer not found -- without any error messages. - for _, var in ipairs({'v:true', 'v:false'}) do - eq('Vim(call):E5299: Expected a Number or a String, Boolean found', - exc_exec('call ' .. func:format(var))) + for _, var in ipairs({ 'v:true', 'v:false' }) do + eq( + 'Vim(call):E5299: Expected a Number or a String, Boolean found', + exc_exec('call ' .. func:format(var)) + ) end - eq('Vim(call):E5300: Expected a Number or a String', - exc_exec('call ' .. func:format('v:null'))) + eq( + 'Vim(call):E5300: Expected a Number or a String', + exc_exec('call ' .. func:format('v:null')) + ) end) it('errors out when receives invalid argument', function() - eq('Vim(call):E745: Expected a Number or a String, List found', - exc_exec('call ' .. func:format('[]'))) - eq('Vim(call):E728: Expected a Number or a String, Dictionary found', - exc_exec('call ' .. func:format('{}'))) - eq('Vim(call):E805: Expected a Number or a String, Float found', - exc_exec('call ' .. func:format('0.0'))) - eq('Vim(call):E703: Expected a Number or a String, Funcref found', - exc_exec('call ' .. func:format('function("tr")'))) + eq( + 'Vim(call):E745: Expected a Number or a String, List found', + exc_exec('call ' .. func:format('[]')) + ) + eq( + 'Vim(call):E728: Expected a Number or a String, Dictionary found', + exc_exec('call ' .. func:format('{}')) + ) + eq( + 'Vim(call):E805: Expected a Number or a String, Float found', + exc_exec('call ' .. func:format('0.0')) + ) + eq( + 'Vim(call):E703: Expected a Number or a String, Funcref found', + exc_exec('call ' .. func:format('function("tr")')) + ) end) end) end @@ -54,12 +65,12 @@ end describe('bufname() function', function() it('returns empty string when buffer was not found', function() command('file ' .. fname) - eq('', funcs.bufname(2)) - eq('', funcs.bufname('non-existent-buffer')) - eq('', funcs.bufname('#')) + eq('', fn.bufname(2)) + eq('', fn.bufname('non-existent-buffer')) + eq('', fn.bufname('#')) command('edit ' .. fname2) - eq(2, funcs.bufnr('%')) - eq('', funcs.bufname('X')) + eq(2, fn.bufnr('%')) + eq('', fn.bufname('X')) end) before_each(function() mkdir(dirname) @@ -68,80 +79,80 @@ describe('bufname() function', function() rmdir(dirname) end) it('returns expected buffer name', function() - eq('', funcs.bufname('%')) -- Buffer has no name yet + eq('', fn.bufname('%')) -- Buffer has no name yet command('file ' .. fname) - local wd = luv.cwd() + local wd = vim.uv.cwd() local sep = get_pathsep() - local curdirname = funcs.fnamemodify(wd, ':t') - for _, arg in ipairs({'%', 1, 'X', wd}) do - eq(fname, funcs.bufname(arg)) - meths.set_current_dir('..') - eq(curdirname .. sep .. fname, funcs.bufname(arg)) - meths.set_current_dir(curdirname) - meths.set_current_dir(dirname) - eq(wd .. sep .. fname, funcs.bufname(arg)) - meths.set_current_dir('..') - eq(fname, funcs.bufname(arg)) + local curdirname = fn.fnamemodify(wd, ':t') + for _, arg in ipairs({ '%', 1, 'X', wd }) do + eq(fname, fn.bufname(arg)) + api.nvim_set_current_dir('..') + eq(curdirname .. sep .. fname, fn.bufname(arg)) + api.nvim_set_current_dir(curdirname) + api.nvim_set_current_dir(dirname) + eq(wd .. sep .. fname, fn.bufname(arg)) + api.nvim_set_current_dir('..') + eq(fname, fn.bufname(arg)) command('enew') end - eq('', funcs.bufname('%')) - eq('', funcs.bufname('$')) - eq(2, funcs.bufnr('%')) + eq('', fn.bufname('%')) + eq('', fn.bufname('$')) + eq(2, fn.bufnr('%')) end) end) describe('bufnr() function', function() it('returns -1 when buffer was not found', function() command('file ' .. fname) - eq(-1, funcs.bufnr(2)) - eq(-1, funcs.bufnr('non-existent-buffer')) - eq(-1, funcs.bufnr('#')) + eq(-1, fn.bufnr(2)) + eq(-1, fn.bufnr('non-existent-buffer')) + eq(-1, fn.bufnr('#')) command('edit ' .. fname2) - eq(2, funcs.bufnr('%')) - eq(-1, funcs.bufnr('X')) + eq(2, fn.bufnr('%')) + eq(-1, fn.bufnr('X')) end) it('returns expected buffer number', function() - eq(1, funcs.bufnr('%')) + eq(1, fn.bufnr('%')) command('file ' .. fname) - local wd = luv.cwd() - local curdirname = funcs.fnamemodify(wd, ':t') - eq(1, funcs.bufnr(fname)) - eq(1, funcs.bufnr(wd)) - eq(1, funcs.bufnr(curdirname)) - eq(1, funcs.bufnr('X')) + local wd = vim.uv.cwd() + local curdirname = fn.fnamemodify(wd, ':t') + eq(1, fn.bufnr(fname)) + eq(1, fn.bufnr(wd)) + eq(1, fn.bufnr(curdirname)) + eq(1, fn.bufnr('X')) end) it('returns number of last buffer with "$"', function() - eq(1, funcs.bufnr('$')) + eq(1, fn.bufnr('$')) command('new') - eq(2, funcs.bufnr('$')) + eq(2, fn.bufnr('$')) command('new') - eq(3, funcs.bufnr('$')) + eq(3, fn.bufnr('$')) command('only') - eq(3, funcs.bufnr('$')) - eq(3, funcs.bufnr('%')) + eq(3, fn.bufnr('$')) + eq(3, fn.bufnr('%')) command('buffer 1') - eq(3, funcs.bufnr('$')) - eq(1, funcs.bufnr('%')) + eq(3, fn.bufnr('$')) + eq(1, fn.bufnr('%')) command('bwipeout 2') - eq(3, funcs.bufnr('$')) - eq(1, funcs.bufnr('%')) + eq(3, fn.bufnr('$')) + eq(1, fn.bufnr('%')) command('bwipeout 3') - eq(1, funcs.bufnr('$')) - eq(1, funcs.bufnr('%')) + eq(1, fn.bufnr('$')) + eq(1, fn.bufnr('%')) command('new') - eq(4, funcs.bufnr('$')) + eq(4, fn.bufnr('$')) end) end) describe('bufwinnr() function', function() it('returns -1 when buffer was not found', function() command('file ' .. fname) - eq(-1, funcs.bufwinnr(2)) - eq(-1, funcs.bufwinnr('non-existent-buffer')) - eq(-1, funcs.bufwinnr('#')) - command('split ' .. fname2) -- It would be OK if there was one window - eq(2, funcs.bufnr('%')) - eq(-1, funcs.bufwinnr('X')) + eq(-1, fn.bufwinnr(2)) + eq(-1, fn.bufwinnr('non-existent-buffer')) + eq(-1, fn.bufwinnr('#')) + command('split ' .. fname2) -- It would be OK if there was one window + eq(2, fn.bufnr('%')) + eq(-1, fn.bufwinnr('X')) end) before_each(function() mkdir(dirname) @@ -150,162 +161,162 @@ describe('bufwinnr() function', function() rmdir(dirname) end) it('returns expected window number', function() - eq(1, funcs.bufwinnr('%')) + eq(1, fn.bufwinnr('%')) command('file ' .. fname) command('vsplit') command('split ' .. fname2) - eq(2, funcs.bufwinnr(fname)) - eq(1, funcs.bufwinnr(fname2)) - eq(-1, funcs.bufwinnr(fname:sub(1, #fname - 1))) - meths.set_current_dir(dirname) - eq(2, funcs.bufwinnr(fname)) - eq(1, funcs.bufwinnr(fname2)) - eq(-1, funcs.bufwinnr(fname:sub(1, #fname - 1))) - eq(1, funcs.bufwinnr('%')) - eq(2, funcs.bufwinnr(1)) - eq(1, funcs.bufwinnr(2)) - eq(-1, funcs.bufwinnr(3)) - eq(1, funcs.bufwinnr('$')) + eq(2, fn.bufwinnr(fname)) + eq(1, fn.bufwinnr(fname2)) + eq(-1, fn.bufwinnr(fname:sub(1, #fname - 1))) + api.nvim_set_current_dir(dirname) + eq(2, fn.bufwinnr(fname)) + eq(1, fn.bufwinnr(fname2)) + eq(-1, fn.bufwinnr(fname:sub(1, #fname - 1))) + eq(1, fn.bufwinnr('%')) + eq(2, fn.bufwinnr(1)) + eq(1, fn.bufwinnr(2)) + eq(-1, fn.bufwinnr(3)) + eq(1, fn.bufwinnr('$')) end) end) describe('getbufline() function', function() it('returns empty list when buffer was not found', function() command('file ' .. fname) - eq({}, funcs.getbufline(2, 1)) - eq({}, funcs.getbufline('non-existent-buffer', 1)) - eq({}, funcs.getbufline('#', 1)) + eq({}, fn.getbufline(2, 1)) + eq({}, fn.getbufline('non-existent-buffer', 1)) + eq({}, fn.getbufline('#', 1)) command('edit ' .. fname2) - eq(2, funcs.bufnr('%')) - eq({}, funcs.getbufline('X', 1)) + eq(2, fn.bufnr('%')) + eq({}, fn.getbufline('X', 1)) end) it('returns empty list when range is invalid', function() - eq({}, funcs.getbufline(1, 0)) - curbufmeths.set_lines(0, 1, false, {'foo', 'bar', 'baz'}) - eq({}, funcs.getbufline(1, 2, 1)) - eq({}, funcs.getbufline(1, -10, -20)) - eq({}, funcs.getbufline(1, -2, -1)) - eq({}, funcs.getbufline(1, -1, 9999)) + eq({}, fn.getbufline(1, 0)) + api.nvim_buf_set_lines(0, 0, 1, false, { 'foo', 'bar', 'baz' }) + eq({}, fn.getbufline(1, 2, 1)) + eq({}, fn.getbufline(1, -10, -20)) + eq({}, fn.getbufline(1, -2, -1)) + eq({}, fn.getbufline(1, -1, 9999)) end) it('returns expected lines', function() - meths.set_option_value('hidden', true, {}) + api.nvim_set_option_value('hidden', true, {}) command('file ' .. fname) - curbufmeths.set_lines(0, 1, false, {'foo\0', '\0bar', 'baz'}) + api.nvim_buf_set_lines(0, 0, 1, false, { 'foo\0', '\0bar', 'baz' }) command('edit ' .. fname2) - curbufmeths.set_lines(0, 1, false, {'abc\0', '\0def', 'ghi'}) - eq({'foo\n', '\nbar', 'baz'}, funcs.getbufline(1, 1, 9999)) - eq({'abc\n', '\ndef', 'ghi'}, funcs.getbufline(2, 1, 9999)) - eq({'foo\n', '\nbar', 'baz'}, funcs.getbufline(1, 1, '$')) - eq({'baz'}, funcs.getbufline(1, '$', '$')) - eq({'baz'}, funcs.getbufline(1, '$', 9999)) + api.nvim_buf_set_lines(0, 0, 1, false, { 'abc\0', '\0def', 'ghi' }) + eq({ 'foo\n', '\nbar', 'baz' }, fn.getbufline(1, 1, 9999)) + eq({ 'abc\n', '\ndef', 'ghi' }, fn.getbufline(2, 1, 9999)) + eq({ 'foo\n', '\nbar', 'baz' }, fn.getbufline(1, 1, '$')) + eq({ 'baz' }, fn.getbufline(1, '$', '$')) + eq({ 'baz' }, fn.getbufline(1, '$', 9999)) end) end) describe('getbufvar() function', function() it('returns empty list when buffer was not found', function() command('file ' .. fname) - eq('', funcs.getbufvar(2, '&autoindent')) - eq('', funcs.getbufvar('non-existent-buffer', '&autoindent')) - eq('', funcs.getbufvar('#', '&autoindent')) + eq('', fn.getbufvar(2, '&autoindent')) + eq('', fn.getbufvar('non-existent-buffer', '&autoindent')) + eq('', fn.getbufvar('#', '&autoindent')) command('edit ' .. fname2) - eq(2, funcs.bufnr('%')) - eq('', funcs.getbufvar('X', '&autoindent')) + eq(2, fn.bufnr('%')) + eq('', fn.getbufvar('X', '&autoindent')) end) it('returns empty list when variable/option/etc was not found', function() command('file ' .. fname) - eq('', funcs.getbufvar(1, '&autondent')) - eq('', funcs.getbufvar(1, 'changedtic')) + eq('', fn.getbufvar(1, '&autondent')) + eq('', fn.getbufvar(1, 'changedtic')) end) it('returns expected option value', function() - eq(0, funcs.getbufvar(1, '&autoindent')) - eq(0, funcs.getbufvar(1, '&l:autoindent')) - eq(0, funcs.getbufvar(1, '&g:autoindent')) + eq(0, fn.getbufvar(1, '&autoindent')) + eq(0, fn.getbufvar(1, '&l:autoindent')) + eq(0, fn.getbufvar(1, '&g:autoindent')) -- Also works with global-only options - eq(1, funcs.getbufvar(1, '&hidden')) - eq(1, funcs.getbufvar(1, '&l:hidden')) - eq(1, funcs.getbufvar(1, '&g:hidden')) + eq(1, fn.getbufvar(1, '&hidden')) + eq(1, fn.getbufvar(1, '&l:hidden')) + eq(1, fn.getbufvar(1, '&g:hidden')) -- Also works with window-local options - eq(0, funcs.getbufvar(1, '&number')) - eq(0, funcs.getbufvar(1, '&l:number')) - eq(0, funcs.getbufvar(1, '&g:number')) + eq(0, fn.getbufvar(1, '&number')) + eq(0, fn.getbufvar(1, '&l:number')) + eq(0, fn.getbufvar(1, '&g:number')) command('new') -- But with window-local options it probably does not what you expect - command("setl number") + command('setl number') -- (note that current window’s buffer is 2, but getbufvar() receives 1) - eq({id=2}, curwinmeths.get_buf()) - eq(1, funcs.getbufvar(1, '&number')) - eq(1, funcs.getbufvar(1, '&l:number')) + eq(2, api.nvim_win_get_buf(0)) + eq(1, fn.getbufvar(1, '&number')) + eq(1, fn.getbufvar(1, '&l:number')) -- You can get global value though, if you find this useful. - eq(0, funcs.getbufvar(1, '&g:number')) + eq(0, fn.getbufvar(1, '&g:number')) end) it('returns expected variable value', function() - eq(2, funcs.getbufvar(1, 'changedtick')) - curbufmeths.set_lines(0, 1, false, {'abc\0', '\0def', 'ghi'}) - eq(3, funcs.getbufvar(1, 'changedtick')) - curbufmeths.set_var('test', true) - eq(true, funcs.getbufvar(1, 'test')) - eq({test=true, changedtick=3}, funcs.getbufvar(1, '')) + eq(2, fn.getbufvar(1, 'changedtick')) + api.nvim_buf_set_lines(0, 0, 1, false, { 'abc\0', '\0def', 'ghi' }) + eq(3, fn.getbufvar(1, 'changedtick')) + api.nvim_buf_set_var(0, 'test', true) + eq(true, fn.getbufvar(1, 'test')) + eq({ test = true, changedtick = 3 }, fn.getbufvar(1, '')) command('new') - eq(3, funcs.getbufvar(1, 'changedtick')) - eq(true, funcs.getbufvar(1, 'test')) - eq({test=true, changedtick=3}, funcs.getbufvar(1, '')) + eq(3, fn.getbufvar(1, 'changedtick')) + eq(true, fn.getbufvar(1, 'test')) + eq({ test = true, changedtick = 3 }, fn.getbufvar(1, '')) end) end) describe('setbufvar() function', function() it('throws the error or ignores the input when buffer was not found', function() command('file ' .. fname) - eq(0, - exc_exec('call setbufvar(2, "&autoindent", 0)')) - eq('Vim(call):E94: No matching buffer for non-existent-buffer', - exc_exec('call setbufvar("non-existent-buffer", "&autoindent", 0)')) - eq(0, - exc_exec('call setbufvar("#", "&autoindent", 0)')) + eq(0, exc_exec('call setbufvar(2, "&autoindent", 0)')) + eq( + 'Vim(call):E94: No matching buffer for non-existent-buffer', + exc_exec('call setbufvar("non-existent-buffer", "&autoindent", 0)') + ) + eq(0, exc_exec('call setbufvar("#", "&autoindent", 0)')) command('edit ' .. fname2) - eq(2, funcs.bufnr('%')) - eq('Vim(call):E93: More than one match for X', - exc_exec('call setbufvar("X", "&autoindent", 0)')) + eq(2, fn.bufnr('%')) + eq( + 'Vim(call):E93: More than one match for X', + exc_exec('call setbufvar("X", "&autoindent", 0)') + ) end) it('may set options, including window-local and global values', function() - local buf1 = meths.get_current_buf() - eq(false, meths.get_option_value('number', {})) + local buf1 = api.nvim_get_current_buf() + eq(false, api.nvim_get_option_value('number', {})) command('split') command('new') - eq(2, bufmeths.get_number(curwinmeths.get_buf())) - funcs.setbufvar(1, '&number', true) - local windows = curtabmeths.list_wins() - eq(false, meths.get_option_value('number', {win=windows[1].id})) - eq(true, meths.get_option_value('number', {win=windows[2].id})) - eq(false, meths.get_option_value('number', {win=windows[3].id})) - eq(false, meths.get_option_value('number', {win=meths.get_current_win().id})) - + eq(2, api.nvim_buf_get_number(api.nvim_win_get_buf(0))) + fn.setbufvar(1, '&number', true) + local windows = api.nvim_tabpage_list_wins(0) + eq(false, api.nvim_get_option_value('number', { win = windows[1] })) + eq(true, api.nvim_get_option_value('number', { win = windows[2] })) + eq(false, api.nvim_get_option_value('number', { win = windows[3] })) + eq(false, api.nvim_get_option_value('number', { win = api.nvim_get_current_win() })) - eq(true, meths.get_option_value('hidden', {})) - funcs.setbufvar(1, '&hidden', 0) - eq(false, meths.get_option_value('hidden', {})) + eq(true, api.nvim_get_option_value('hidden', {})) + fn.setbufvar(1, '&hidden', 0) + eq(false, api.nvim_get_option_value('hidden', {})) - eq(false, meths.get_option_value('autoindent', {buf=buf1.id})) - funcs.setbufvar(1, '&autoindent', true) - eq(true, meths.get_option_value('autoindent', {buf=buf1.id})) - eq('Vim(call):E355: Unknown option: xxx', - exc_exec('call setbufvar(1, "&xxx", 0)')) + eq(false, api.nvim_get_option_value('autoindent', { buf = buf1 })) + fn.setbufvar(1, '&autoindent', true) + eq(true, api.nvim_get_option_value('autoindent', { buf = buf1 })) + eq('Vim(call):E355: Unknown option: xxx', exc_exec('call setbufvar(1, "&xxx", 0)')) end) it('may set variables', function() - local buf1 = meths.get_current_buf() + local buf1 = api.nvim_get_current_buf() command('split') command('new') - eq(2, curbufmeths.get_number()) - funcs.setbufvar(1, 'number', true) - eq(true, bufmeths.get_var(buf1, 'number')) - eq('Vim(call):E461: Illegal variable name: b:', - exc_exec('call setbufvar(1, "", 0)')) - eq(true, bufmeths.get_var(buf1, 'number')) - eq('Vim:E46: Cannot change read-only variable "b:changedtick"', - pcall_err(funcs.setbufvar, 1, 'changedtick', true)) - eq(2, funcs.getbufvar(1, 'changedtick')) + eq(2, api.nvim_buf_get_number(0)) + fn.setbufvar(1, 'number', true) + eq(true, api.nvim_buf_get_var(buf1, 'number')) + eq('Vim(call):E461: Illegal variable name: b:', exc_exec('call setbufvar(1, "", 0)')) + eq(true, api.nvim_buf_get_var(buf1, 'number')) + eq( + 'Vim:E46: Cannot change read-only variable "b:changedtick"', + pcall_err(fn.setbufvar, 1, 'changedtick', true) + ) + eq(2, fn.getbufvar(1, 'changedtick')) end) it('throws error when setting a string option to a boolean value vim-patch:9.0.0090', function() - eq('Vim:E928: String required', - pcall_err(funcs.setbufvar, '', '&errorformat', true)) + eq('Vim:E928: String required', pcall_err(fn.setbufvar, '', '&errorformat', true)) end) end) diff --git a/test/functional/vimscript/changedtick_spec.lua b/test/functional/vimscript/changedtick_spec.lua index 8533fac9ec..85928921c5 100644 --- a/test/functional/vimscript/changedtick_spec.lua +++ b/test/functional/vimscript/changedtick_spec.lua @@ -4,35 +4,34 @@ local eq = helpers.eq local eval = helpers.eval local feed = helpers.feed local clear = helpers.clear -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local command = helpers.command local exc_exec = helpers.exc_exec local pcall_err = helpers.pcall_err local exec_capture = helpers.exec_capture -local curbufmeths = helpers.curbufmeths before_each(clear) local function changedtick() - local ct = curbufmeths.get_changedtick() - eq(ct, curbufmeths.get_var('changedtick')) - eq(ct, curbufmeths.get_var('changedtick')) + local ct = api.nvim_buf_get_changedtick(0) + eq(ct, api.nvim_buf_get_var(0, 'changedtick')) + eq(ct, api.nvim_buf_get_var(0, 'changedtick')) eq(ct, eval('b:changedtick')) eq(ct, eval('b:["changedtick"]')) eq(ct, eval('b:.changedtick')) - eq(ct, funcs.getbufvar('%', 'changedtick')) - eq(ct, funcs.getbufvar('%', '').changedtick) + eq(ct, fn.getbufvar('%', 'changedtick')) + eq(ct, fn.getbufvar('%', '').changedtick) eq(ct, eval('b:').changedtick) return ct end describe('b:changedtick', function() -- Ported tests from Vim-8.0.333 - it('increments', function() -- Test_changedtick_increments + it('increments', function() -- Test_changedtick_increments -- New buffer has an empty line, tick starts at 2 eq(2, changedtick()) - funcs.setline(1, 'hello') + fn.setline(1, 'hello') eq(3, changedtick()) eq(0, exc_exec('undo')) -- Somehow undo counts as two changes @@ -41,54 +40,74 @@ describe('b:changedtick', function() it('is present in b: dictionary', function() eq(2, changedtick()) command('let d = b:') - eq(2, meths.get_var('d').changedtick) + eq(2, api.nvim_get_var('d').changedtick) end) it('increments at bdel', function() command('new') eq(2, changedtick()) - local bnr = curbufmeths.get_number() + local bnr = api.nvim_buf_get_number(0) eq(2, bnr) command('bdel') - eq(3, funcs.getbufvar(bnr, 'changedtick')) - eq(1, curbufmeths.get_number()) + eq(3, fn.getbufvar(bnr, 'changedtick')) + eq(1, api.nvim_buf_get_number(0)) end) it('fails to be changed by user', function() local ct = changedtick() local ctn = ct + 100500 eq(0, exc_exec('let d = b:')) - eq('Vim(let):E46: Cannot change read-only variable "b:changedtick"', - pcall_err(command, 'let b:changedtick = ' .. ctn)) - eq('Vim(let):E46: Cannot change read-only variable "b:["changedtick"]"', - pcall_err(command, 'let b:["changedtick"] = ' .. ctn)) - eq('Vim(let):E46: Cannot change read-only variable "b:.changedtick"', - pcall_err(command, 'let b:.changedtick = ' .. ctn)) - eq('Vim(let):E46: Cannot change read-only variable "d.changedtick"', - pcall_err(command, 'let d.changedtick = ' .. ctn)) - eq('Key is read-only: changedtick', - pcall_err(curbufmeths.set_var, 'changedtick', ctn)) + eq( + 'Vim(let):E46: Cannot change read-only variable "b:changedtick"', + pcall_err(command, 'let b:changedtick = ' .. ctn) + ) + eq( + 'Vim(let):E46: Cannot change read-only variable "b:["changedtick"]"', + pcall_err(command, 'let b:["changedtick"] = ' .. ctn) + ) + eq( + 'Vim(let):E46: Cannot change read-only variable "b:.changedtick"', + pcall_err(command, 'let b:.changedtick = ' .. ctn) + ) + eq( + 'Vim(let):E46: Cannot change read-only variable "d.changedtick"', + pcall_err(command, 'let d.changedtick = ' .. ctn) + ) + eq('Key is read-only: changedtick', pcall_err(api.nvim_buf_set_var, 0, 'changedtick', ctn)) - eq('Vim(unlet):E795: Cannot delete variable b:changedtick', - pcall_err(command, 'unlet b:changedtick')) - eq('Vim(unlet):E46: Cannot change read-only variable "b:.changedtick"', - pcall_err(command, 'unlet b:.changedtick')) - eq('Vim(unlet):E46: Cannot change read-only variable "b:["changedtick"]"', - pcall_err(command, 'unlet b:["changedtick"]')) - eq('Vim(unlet):E46: Cannot change read-only variable "d.changedtick"', - pcall_err(command, 'unlet d.changedtick')) - eq('Key is read-only: changedtick', - pcall_err(curbufmeths.del_var, 'changedtick')) + eq( + 'Vim(unlet):E795: Cannot delete variable b:changedtick', + pcall_err(command, 'unlet b:changedtick') + ) + eq( + 'Vim(unlet):E46: Cannot change read-only variable "b:.changedtick"', + pcall_err(command, 'unlet b:.changedtick') + ) + eq( + 'Vim(unlet):E46: Cannot change read-only variable "b:["changedtick"]"', + pcall_err(command, 'unlet b:["changedtick"]') + ) + eq( + 'Vim(unlet):E46: Cannot change read-only variable "d.changedtick"', + pcall_err(command, 'unlet d.changedtick') + ) + eq('Key is read-only: changedtick', pcall_err(api.nvim_buf_del_var, 0, 'changedtick')) eq(ct, changedtick()) - eq('Vim(let):E46: Cannot change read-only variable "b:["changedtick"]"', - pcall_err(command, 'let b:["changedtick"] += ' .. ctn)) - eq('Vim(let):E46: Cannot change read-only variable "b:["changedtick"]"', - pcall_err(command, 'let b:["changedtick"] -= ' .. ctn)) - eq('Vim(let):E46: Cannot change read-only variable "b:["changedtick"]"', - pcall_err(command, 'let b:["changedtick"] .= ' .. ctn)) + eq( + 'Vim(let):E46: Cannot change read-only variable "b:["changedtick"]"', + pcall_err(command, 'let b:["changedtick"] += ' .. ctn) + ) + eq( + 'Vim(let):E46: Cannot change read-only variable "b:["changedtick"]"', + pcall_err(command, 'let b:["changedtick"] -= ' .. ctn) + ) + eq( + 'Vim(let):E46: Cannot change read-only variable "b:["changedtick"]"', + pcall_err(command, 'let b:["changedtick"] .= ' .. ctn) + ) eq(ct, changedtick()) - funcs.setline(1, 'hello') + fn.setline(1, 'hello') eq(ct + 1, changedtick()) end) @@ -97,39 +116,55 @@ describe('b:changedtick', function() end) it('fails to unlock b:changedtick', function() eq(0, exc_exec('let d = b:')) - eq(0, funcs.islocked('b:changedtick')) - eq(0, funcs.islocked('d.changedtick')) - eq('Vim(unlockvar):E940: Cannot lock or unlock variable b:changedtick', - pcall_err(command, 'unlockvar b:changedtick')) - eq('Vim(unlockvar):E46: Cannot change read-only variable "d.changedtick"', - pcall_err(command, 'unlockvar d.changedtick')) - eq(0, funcs.islocked('b:changedtick')) - eq(0, funcs.islocked('d.changedtick')) - eq('Vim(lockvar):E940: Cannot lock or unlock variable b:changedtick', - pcall_err(command, 'lockvar b:changedtick')) - eq('Vim(lockvar):E46: Cannot change read-only variable "d.changedtick"', - pcall_err(command, 'lockvar d.changedtick')) - eq(0, funcs.islocked('b:changedtick')) - eq(0, funcs.islocked('d.changedtick')) + eq(0, fn.islocked('b:changedtick')) + eq(0, fn.islocked('d.changedtick')) + eq( + 'Vim(unlockvar):E940: Cannot lock or unlock variable b:changedtick', + pcall_err(command, 'unlockvar b:changedtick') + ) + eq( + 'Vim(unlockvar):E46: Cannot change read-only variable "d.changedtick"', + pcall_err(command, 'unlockvar d.changedtick') + ) + eq(0, fn.islocked('b:changedtick')) + eq(0, fn.islocked('d.changedtick')) + eq( + 'Vim(lockvar):E940: Cannot lock or unlock variable b:changedtick', + pcall_err(command, 'lockvar b:changedtick') + ) + eq( + 'Vim(lockvar):E46: Cannot change read-only variable "d.changedtick"', + pcall_err(command, 'lockvar d.changedtick') + ) + eq(0, fn.islocked('b:changedtick')) + eq(0, fn.islocked('d.changedtick')) end) it('is being completed', function() feed(':echo b:<Tab><Home>let cmdline="<End>"<CR>') - eq('echo b:changedtick', meths.get_var('cmdline')) + eq('echo b:changedtick', api.nvim_get_var('cmdline')) end) it('cannot be changed by filter() or map()', function() eq(2, changedtick()) - eq('Vim(call):E795: Cannot delete variable filter() argument', - pcall_err(command, 'call filter(b:, 0)')) - eq('Vim(call):E742: Cannot change value of map() argument', - pcall_err(command, 'call map(b:, 0)')) - eq('Vim(call):E742: Cannot change value of map() argument', - pcall_err(command, 'call map(b:, "v:val")')) + eq( + 'Vim(call):E795: Cannot delete variable filter() argument', + pcall_err(command, 'call filter(b:, 0)') + ) + eq( + 'Vim(call):E742: Cannot change value of map() argument', + pcall_err(command, 'call map(b:, 0)') + ) + eq( + 'Vim(call):E742: Cannot change value of map() argument', + pcall_err(command, 'call map(b:, "v:val")') + ) eq(2, changedtick()) end) it('cannot be remove()d', function() eq(2, changedtick()) - eq('Vim(call):E795: Cannot delete variable remove() argument', - pcall_err(command, 'call remove(b:, "changedtick")')) + eq( + 'Vim(call):E795: Cannot delete variable remove() argument', + pcall_err(command, 'call remove(b:, "changedtick")') + ) eq(2, changedtick()) end) it('does not inherit VAR_FIXED when copying dictionary over', function() diff --git a/test/functional/vimscript/container_functions_spec.lua b/test/functional/vimscript/container_functions_spec.lua index 5bef3fce05..1b34ea0165 100644 --- a/test/functional/vimscript/container_functions_spec.lua +++ b/test/functional/vimscript/container_functions_spec.lua @@ -2,23 +2,23 @@ local helpers = require('test.functional.helpers')(after_each) local eq = helpers.eq local eval = helpers.eval -local meths = helpers.meths +local api = helpers.api local clear = helpers.clear before_each(clear) describe('extend()', function() it('succeeds to extend list with itself', function() - meths.set_var('l', {1, {}}) - eq({1, {}, 1, {}}, eval('extend(l, l)')) - eq({1, {}, 1, {}}, meths.get_var('l')) + api.nvim_set_var('l', { 1, {} }) + eq({ 1, {}, 1, {} }, eval('extend(l, l)')) + eq({ 1, {}, 1, {} }, api.nvim_get_var('l')) - meths.set_var('l', {1, {}}) - eq({1, {}, 1, {}}, eval('extend(l, l, 0)')) - eq({1, {}, 1, {}}, meths.get_var('l')) + api.nvim_set_var('l', { 1, {} }) + eq({ 1, {}, 1, {} }, eval('extend(l, l, 0)')) + eq({ 1, {}, 1, {} }, api.nvim_get_var('l')) - meths.set_var('l', {1, {}}) - eq({1, 1, {}, {}}, eval('extend(l, l, 1)')) - eq({1, 1, {}, {}}, meths.get_var('l')) + api.nvim_set_var('l', { 1, {} }) + eq({ 1, 1, {}, {} }, eval('extend(l, l, 1)')) + eq({ 1, 1, {}, {} }, api.nvim_get_var('l')) end) end) diff --git a/test/functional/vimscript/ctx_functions_spec.lua b/test/functional/vimscript/ctx_functions_spec.lua index 17607f0794..dc60a474f3 100644 --- a/test/functional/vimscript/ctx_functions_spec.lua +++ b/test/functional/vimscript/ctx_functions_spec.lua @@ -6,25 +6,24 @@ local command = helpers.command local eq = helpers.eq local eval = helpers.eval local feed = helpers.feed -local map = helpers.tbl_map -local nvim = helpers.nvim +local map = vim.tbl_map +local api = helpers.api local parse_context = helpers.parse_context local exec_capture = helpers.exec_capture local source = helpers.source -local trim = helpers.trim +local trim = vim.trim local write_file = helpers.write_file local pcall_err = helpers.pcall_err describe('context functions', function() local fname1 = 'Xtest-functional-eval-ctx1' local fname2 = 'Xtest-functional-eval-ctx2' - local outofbounds = - 'Vim:E475: Invalid value for argument index: out of bounds' + local outofbounds = 'Vim:E475: Invalid value for argument index: out of bounds' before_each(function() clear() - write_file(fname1, "1\n2\n3") - write_file(fname2, "a\nb\nc") + write_file(fname1, '1\n2\n3') + write_file(fname2, 'a\nb\nc') end) after_each(function() @@ -34,98 +33,125 @@ describe('context functions', function() describe('ctxpush/ctxpop', function() it('saves and restores registers properly', function() - local regs = {'1', '2', '3', 'a'} - local vals = {'1', '2', '3', 'hjkl'} + local regs = { '1', '2', '3', 'a' } + local vals = { '1', '2', '3', 'hjkl' } feed('i1<cr>2<cr>3<c-[>ddddddqahjklq') - eq(vals, map(function(r) return trim(call('getreg', r)) end, regs)) + eq( + vals, + map(function(r) + return trim(call('getreg', r)) + end, regs) + ) call('ctxpush') - call('ctxpush', {'regs'}) - - map(function(r) call('setreg', r, {}) end, regs) - eq({'', '', '', ''}, - map(function(r) return trim(call('getreg', r)) end, regs)) + call('ctxpush', { 'regs' }) + + map(function(r) + call('setreg', r, {}) + end, regs) + eq( + { '', '', '', '' }, + map(function(r) + return trim(call('getreg', r)) + end, regs) + ) call('ctxpop') - eq(vals, map(function(r) return trim(call('getreg', r)) end, regs)) - - map(function(r) call('setreg', r, {}) end, regs) - eq({'', '', '', ''}, - map(function(r) return trim(call('getreg', r)) end, regs)) + eq( + vals, + map(function(r) + return trim(call('getreg', r)) + end, regs) + ) + + map(function(r) + call('setreg', r, {}) + end, regs) + eq( + { '', '', '', '' }, + map(function(r) + return trim(call('getreg', r)) + end, regs) + ) call('ctxpop') - eq(vals, map(function(r) return trim(call('getreg', r)) end, regs)) + eq( + vals, + map(function(r) + return trim(call('getreg', r)) + end, regs) + ) end) it('saves and restores jumplist properly', function() - command('edit '..fname1) + command('edit ' .. fname1) feed('G') feed('gg') - command('edit '..fname2) + command('edit ' .. fname2) local jumplist = call('getjumplist') call('ctxpush') - call('ctxpush', {'jumps'}) + call('ctxpush', { 'jumps' }) command('clearjumps') - eq({{}, 0}, call('getjumplist')) + eq({ {}, 0 }, call('getjumplist')) call('ctxpop') eq(jumplist, call('getjumplist')) command('clearjumps') - eq({{}, 0}, call('getjumplist')) + eq({ {}, 0 }, call('getjumplist')) call('ctxpop') eq(jumplist, call('getjumplist')) end) it('saves and restores buffer list properly', function() - command('edit '..fname1) - command('edit '..fname2) + command('edit ' .. fname1) + command('edit ' .. fname2) command('edit TEST') local bufs = call('map', call('getbufinfo'), 'v:val.name') call('ctxpush') - call('ctxpush', {'bufs'}) + call('ctxpush', { 'bufs' }) command('%bwipeout') - eq({''}, call('map', call('getbufinfo'), 'v:val.name')) + eq({ '' }, call('map', call('getbufinfo'), 'v:val.name')) call('ctxpop') - eq({'', unpack(bufs)}, call('map', call('getbufinfo'), 'v:val.name')) + eq({ '', unpack(bufs) }, call('map', call('getbufinfo'), 'v:val.name')) command('%bwipeout') - eq({''}, call('map', call('getbufinfo'), 'v:val.name')) + eq({ '' }, call('map', call('getbufinfo'), 'v:val.name')) call('ctxpop') - eq({'', unpack(bufs)}, call('map', call('getbufinfo'), 'v:val.name')) + eq({ '', unpack(bufs) }, call('map', call('getbufinfo'), 'v:val.name')) end) it('saves and restores global variables properly', function() - nvim('set_var', 'one', 1) - nvim('set_var', 'Two', 2) - nvim('set_var', 'THREE', 3) - eq({1, 2 ,3}, eval('[g:one, g:Two, g:THREE]')) + api.nvim_set_var('one', 1) + api.nvim_set_var('Two', 2) + api.nvim_set_var('THREE', 3) + eq({ 1, 2, 3 }, eval('[g:one, g:Two, g:THREE]')) call('ctxpush') - call('ctxpush', {'gvars'}) + call('ctxpush', { 'gvars' }) - nvim('del_var', 'one') - nvim('del_var', 'Two') - nvim('del_var', 'THREE') + api.nvim_del_var('one') + api.nvim_del_var('Two') + api.nvim_del_var('THREE') eq('Vim:E121: Undefined variable: g:one', pcall_err(eval, 'g:one')) eq('Vim:E121: Undefined variable: g:Two', pcall_err(eval, 'g:Two')) eq('Vim:E121: Undefined variable: g:THREE', pcall_err(eval, 'g:THREE')) call('ctxpop') - eq({1, 2 ,3}, eval('[g:one, g:Two, g:THREE]')) + eq({ 1, 2, 3 }, eval('[g:one, g:Two, g:THREE]')) - nvim('del_var', 'one') - nvim('del_var', 'Two') - nvim('del_var', 'THREE') + api.nvim_del_var('one') + api.nvim_del_var('Two') + api.nvim_del_var('THREE') eq('Vim:E121: Undefined variable: g:one', pcall_err(eval, 'g:one')) eq('Vim:E121: Undefined variable: g:Two', pcall_err(eval, 'g:Two')) eq('Vim:E121: Undefined variable: g:THREE', pcall_err(eval, 'g:THREE')) call('ctxpop') - eq({1, 2 ,3}, eval('[g:one, g:Two, g:THREE]')) + eq({ 1, 2, 3 }, eval('[g:one, g:Two, g:THREE]')) end) it('saves and restores script functions properly', function() @@ -164,28 +190,30 @@ describe('context functions', function() ]]) eq('Hello, World!', exec_capture([[call Greet('World')]])) - eq('Hello, World!'.. - '\nHello, One!'.. - '\nHello, Two!'.. - '\nHello, Three!', - exec_capture([[call GreetAll('World', 'One', 'Two', 'Three')]])) + eq( + 'Hello, World!' .. '\nHello, One!' .. '\nHello, Two!' .. '\nHello, Three!', + exec_capture([[call GreetAll('World', 'One', 'Two', 'Three')]]) + ) call('SaveSFuncs') call('DeleteSFuncs') - eq('function Greet, line 1: Vim(call):E117: Unknown function: s:greet', - pcall_err(command, [[call Greet('World')]])) - eq('function GreetAll, line 1: Vim(call):E117: Unknown function: s:greet_all', - pcall_err(command, [[call GreetAll('World', 'One', 'Two', 'Three')]])) + eq( + 'function Greet, line 1: Vim(call):E117: Unknown function: s:greet', + pcall_err(command, [[call Greet('World')]]) + ) + eq( + 'function GreetAll, line 1: Vim(call):E117: Unknown function: s:greet_all', + pcall_err(command, [[call GreetAll('World', 'One', 'Two', 'Three')]]) + ) call('RestoreFuncs') eq('Hello, World!', exec_capture([[call Greet('World')]])) - eq('Hello, World!'.. - '\nHello, One!'.. - '\nHello, Two!'.. - '\nHello, Three!', - exec_capture([[call GreetAll('World', 'One', 'Two', 'Three')]])) + eq( + 'Hello, World!' .. '\nHello, One!' .. '\nHello, Two!' .. '\nHello, Three!', + exec_capture([[call GreetAll('World', 'One', 'Two', 'Three')]]) + ) end) it('saves and restores functions properly', function() @@ -203,28 +231,28 @@ describe('context functions', function() ]]) eq('Hello, World!', exec_capture([[call Greet('World')]])) - eq('Hello, World!'.. - '\nHello, One!'.. - '\nHello, Two!'.. - '\nHello, Three!', - exec_capture([[call GreetAll('World', 'One', 'Two', 'Three')]])) + eq( + 'Hello, World!' .. '\nHello, One!' .. '\nHello, Two!' .. '\nHello, Three!', + exec_capture([[call GreetAll('World', 'One', 'Two', 'Three')]]) + ) - call('ctxpush', {'funcs'}) + call('ctxpush', { 'funcs' }) command('delfunction Greet') command('delfunction GreetAll') eq('Vim:E117: Unknown function: Greet', pcall_err(call, 'Greet', 'World')) - eq('Vim:E117: Unknown function: GreetAll', - pcall_err(call, 'GreetAll', 'World', 'One', 'Two', 'Three')) + eq( + 'Vim:E117: Unknown function: GreetAll', + pcall_err(call, 'GreetAll', 'World', 'One', 'Two', 'Three') + ) call('ctxpop') eq('Hello, World!', exec_capture([[call Greet('World')]])) - eq('Hello, World!'.. - '\nHello, One!'.. - '\nHello, Two!'.. - '\nHello, Three!', - exec_capture([[call GreetAll('World', 'One', 'Two', 'Three')]])) + eq( + 'Hello, World!' .. '\nHello, One!' .. '\nHello, Two!' .. '\nHello, Three!', + exec_capture([[call GreetAll('World', 'One', 'Two', 'Three')]]) + ) end) it('errors out when context stack is empty', function() @@ -268,41 +296,41 @@ describe('context functions', function() it('returns context dictionary at index in context stack', function() feed('i1<cr>2<cr>3<c-[>ddddddqahjklq') - command('edit! '..fname1) + command('edit! ' .. fname1) feed('G') feed('gg') - command('edit '..fname2) - nvim('set_var', 'one', 1) - nvim('set_var', 'Two', 2) - nvim('set_var', 'THREE', 3) + command('edit ' .. fname2) + api.nvim_set_var('one', 1) + api.nvim_set_var('Two', 2) + api.nvim_set_var('THREE', 3) local with_regs = { ['regs'] = { - {['rt'] = 1, ['rc'] = {'1'}, ['n'] = 49, ['ru'] = true}, - {['rt'] = 1, ['rc'] = {'2'}, ['n'] = 50}, - {['rt'] = 1, ['rc'] = {'3'}, ['n'] = 51}, - {['rc'] = {'hjkl'}, ['n'] = 97}, - } + { ['rt'] = 1, ['rc'] = { '1' }, ['n'] = 49, ['ru'] = true }, + { ['rt'] = 1, ['rc'] = { '2' }, ['n'] = 50 }, + { ['rt'] = 1, ['rc'] = { '3' }, ['n'] = 51 }, + { ['rc'] = { 'hjkl' }, ['n'] = 97 }, + }, } local with_jumps = { - ['jumps'] = eval(([[ + ['jumps'] = eval((([[ filter(map(add( getjumplist()[0], { 'bufnr': bufnr('%'), 'lnum': getcurpos()[1] }), 'filter( { "f": expand("#".v:val.bufnr.":p"), "l": v:val.lnum }, { k, v -> k != "l" || v != 1 })'), '!empty(v:val.f)') - ]]):gsub('\n', '')) + ]]):gsub('\n', ''))), } local with_bufs = { ['bufs'] = eval([[ filter(map(getbufinfo(), '{ "f": v:val.name }'), '!empty(v:val.f)') - ]]) + ]]), } local with_gvars = { - ['gvars'] = {{'one', 1}, {'Two', 2}, {'THREE', 3}} + ['gvars'] = { { 'one', 1 }, { 'Two', 2 }, { 'THREE', 3 } }, } local with_all = { @@ -316,25 +344,25 @@ describe('context functions', function() eq(with_all, parse_context(call('ctxget'))) eq(with_all, parse_context(call('ctxget', 0))) - call('ctxpush', {'gvars'}) + call('ctxpush', { 'gvars' }) eq(with_gvars, parse_context(call('ctxget'))) eq(with_gvars, parse_context(call('ctxget', 0))) eq(with_all, parse_context(call('ctxget', 1))) - call('ctxpush', {'bufs'}) + call('ctxpush', { 'bufs' }) eq(with_bufs, parse_context(call('ctxget'))) eq(with_bufs, parse_context(call('ctxget', 0))) eq(with_gvars, parse_context(call('ctxget', 1))) eq(with_all, parse_context(call('ctxget', 2))) - call('ctxpush', {'jumps'}) + call('ctxpush', { 'jumps' }) eq(with_jumps, parse_context(call('ctxget'))) eq(with_jumps, parse_context(call('ctxget', 0))) eq(with_bufs, parse_context(call('ctxget', 1))) eq(with_gvars, parse_context(call('ctxget', 2))) eq(with_all, parse_context(call('ctxget', 3))) - call('ctxpush', {'regs'}) + call('ctxpush', { 'regs' }) eq(with_regs, parse_context(call('ctxget'))) eq(with_regs, parse_context(call('ctxget', 0))) eq(with_jumps, parse_context(call('ctxget', 1))) @@ -368,43 +396,45 @@ describe('context functions', function() describe('ctxset()', function() it('errors out when index is out of bounds', function() - eq(outofbounds, pcall_err(call, 'ctxset', {dummy = 1})) + eq(outofbounds, pcall_err(call, 'ctxset', { dummy = 1 })) call('ctxpush') - eq(outofbounds, pcall_err(call, 'ctxset', {dummy = 1}, 1)) + eq(outofbounds, pcall_err(call, 'ctxset', { dummy = 1 }, 1)) call('ctxpop') - eq(outofbounds, pcall_err(call, 'ctxset', {dummy = 1}, 0)) + eq(outofbounds, pcall_err(call, 'ctxset', { dummy = 1 }, 0)) end) it('errors when context dictionary is invalid', function() call('ctxpush') - eq('Vim:E474: Failed to convert list to msgpack string buffer', - pcall_err(call, 'ctxset', { regs = { {} }, jumps = { {} } })) + eq( + 'Vim:E474: Failed to convert list to msgpack string buffer', + pcall_err(call, 'ctxset', { regs = { {} }, jumps = { {} } }) + ) end) it('sets context dictionary at index in context stack', function() - nvim('set_var', 'one', 1) - nvim('set_var', 'Two', 2) - nvim('set_var', 'THREE', 3) + api.nvim_set_var('one', 1) + api.nvim_set_var('Two', 2) + api.nvim_set_var('THREE', 3) call('ctxpush') local ctx1 = call('ctxget') - nvim('set_var', 'one', 'a') - nvim('set_var', 'Two', 'b') - nvim('set_var', 'THREE', 'c') + api.nvim_set_var('one', 'a') + api.nvim_set_var('Two', 'b') + api.nvim_set_var('THREE', 'c') call('ctxpush') call('ctxpush') local ctx2 = call('ctxget') - eq({'a', 'b' ,'c'}, eval('[g:one, g:Two, g:THREE]')) + eq({ 'a', 'b', 'c' }, eval('[g:one, g:Two, g:THREE]')) call('ctxset', ctx1) call('ctxset', ctx2, 2) call('ctxpop') - eq({1, 2 ,3}, eval('[g:one, g:Two, g:THREE]')) + eq({ 1, 2, 3 }, eval('[g:one, g:Two, g:THREE]')) call('ctxpop') - eq({'a', 'b' ,'c'}, eval('[g:one, g:Two, g:THREE]')) - nvim('set_var', 'one', 1.5) - eq({1.5, 'b' ,'c'}, eval('[g:one, g:Two, g:THREE]')) + eq({ 'a', 'b', 'c' }, eval('[g:one, g:Two, g:THREE]')) + api.nvim_set_var('one', 1.5) + eq({ 1.5, 'b', 'c' }, eval('[g:one, g:Two, g:THREE]')) call('ctxpop') - eq({'a', 'b' ,'c'}, eval('[g:one, g:Two, g:THREE]')) + eq({ 'a', 'b', 'c' }, eval('[g:one, g:Two, g:THREE]')) end) end) end) diff --git a/test/functional/vimscript/environ_spec.lua b/test/functional/vimscript/environ_spec.lua index 52218d3cc9..0763def84e 100644 --- a/test/functional/vimscript/environ_spec.lua +++ b/test/functional/vimscript/environ_spec.lua @@ -1,23 +1,23 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local eq = helpers.eq -local environ = helpers.funcs.environ -local exists = helpers.funcs.exists -local system = helpers.funcs.system +local environ = helpers.fn.environ +local exists = helpers.fn.exists +local system = helpers.fn.system local nvim_prog = helpers.nvim_prog local command = helpers.command local eval = helpers.eval -local setenv = helpers.funcs.setenv +local setenv = helpers.fn.setenv describe('environment variables', function() it('environ() handles empty env variable', function() - clear({env={EMPTY_VAR=""}}) - eq("", environ()['EMPTY_VAR']) + clear({ env = { EMPTY_VAR = '' } }) + eq('', environ()['EMPTY_VAR']) eq(nil, environ()['DOES_NOT_EXIST']) end) it('exists() handles empty env variable', function() - clear({env={EMPTY_VAR=""}}) + clear({ env = { EMPTY_VAR = '' } }) eq(1, exists('$EMPTY_VAR')) eq(0, exists('$DOES_NOT_EXIST')) end) @@ -46,23 +46,32 @@ describe('empty $HOME', function() end local function write_and_test_tilde() - system({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless', - '-c', 'write test_empty_home', '+q'}) + system({ + nvim_prog, + '-u', + 'NONE', + '-i', + 'NONE', + '--headless', + '-c', + 'write test_empty_home', + '+q', + }) eq(false, tilde_in_cwd()) end it("'~' folder not created in cwd if $HOME and related env not defined", function() - command("unlet $HOME") + command('unlet $HOME') write_and_test_tilde() command("let $HOMEDRIVE='C:'") command("let $USERPROFILE='C:\\'") write_and_test_tilde() - command("unlet $HOMEDRIVE") + command('unlet $HOMEDRIVE') write_and_test_tilde() - command("unlet $USERPROFILE") + command('unlet $USERPROFILE') write_and_test_tilde() command("let $HOME='%USERPROFILE%'") diff --git a/test/functional/vimscript/errorlist_spec.lua b/test/functional/vimscript/errorlist_spec.lua index 077d816903..1e405e7e64 100644 --- a/test/functional/vimscript/errorlist_spec.lua +++ b/test/functional/vimscript/errorlist_spec.lua @@ -4,10 +4,10 @@ local clear = helpers.clear local command = helpers.command local eq = helpers.eq local exc_exec = helpers.exc_exec -local get_cur_win_var = helpers.curwinmeths.get_var +local get_win_var = helpers.api.nvim_win_get_var describe('setqflist()', function() - local setqflist = helpers.funcs.setqflist + local setqflist = helpers.fn.setqflist before_each(clear) @@ -24,26 +24,29 @@ describe('setqflist()', function() end) it('sets w:quickfix_title', function() - setqflist({''}, 'r', 'foo') + setqflist({ '' }, 'r', 'foo') command('copen') - eq('foo', get_cur_win_var('quickfix_title')) - setqflist({}, 'r', {['title'] = 'qf_title'}) - eq('qf_title', get_cur_win_var('quickfix_title')) + eq('foo', get_win_var(0, 'quickfix_title')) + setqflist({}, 'r', { ['title'] = 'qf_title' }) + eq('qf_title', get_win_var(0, 'quickfix_title')) end) it('allows string {what} for backwards compatibility', function() setqflist({}, 'r', '5') command('copen') - eq('5', get_cur_win_var('quickfix_title')) + eq('5', get_win_var(0, 'quickfix_title')) end) it('requires a dict for {what}', function() - eq('Vim(call):E715: Dictionary required', exc_exec('call setqflist([], "r", function("function"))')) + eq( + 'Vim(call):E715: Dictionary required', + exc_exec('call setqflist([], "r", function("function"))') + ) end) end) describe('setloclist()', function() - local setloclist = helpers.funcs.setloclist + local setloclist = helpers.fn.setloclist before_each(clear) @@ -64,20 +67,20 @@ describe('setloclist()', function() setloclist(1, {}, 'r', 'foo') setloclist(2, {}, 'r', 'bar') command('lopen') - eq('bar', get_cur_win_var('quickfix_title')) + eq('bar', get_win_var(0, 'quickfix_title')) command('lclose | wincmd w | lopen') - eq('foo', get_cur_win_var('quickfix_title')) + eq('foo', get_win_var(0, 'quickfix_title')) end) it("doesn't crash when when window is closed in the middle #13721", function() helpers.insert([[ hello world]]) - command("vsplit") - command("autocmd WinLeave * :call nvim_win_close(0, v:true)") + command('vsplit') + command('autocmd WinLeave * :call nvim_win_close(0, v:true)') - command("call setloclist(0, [])") - command("lopen") + command('call setloclist(0, [])') + command('lopen') helpers.assert_alive() end) diff --git a/test/functional/vimscript/eval_spec.lua b/test/functional/vimscript/eval_spec.lua index ab0ffccd4d..e337959810 100644 --- a/test/functional/vimscript/eval_spec.lua +++ b/test/functional/vimscript/eval_spec.lua @@ -15,37 +15,39 @@ local Screen = require('test.functional.ui.screen') local mkdir = helpers.mkdir local clear = helpers.clear local eq = helpers.eq +local exec = helpers.exec local exc_exec = helpers.exc_exec local exec_lua = helpers.exec_lua local exec_capture = helpers.exec_capture local eval = helpers.eval local command = helpers.command local write_file = helpers.write_file -local meths = helpers.meths -local sleep = helpers.sleep +local api = helpers.api +local sleep = vim.uv.sleep local matches = helpers.matches local pcall_err = helpers.pcall_err local assert_alive = helpers.assert_alive local poke_eventloop = helpers.poke_eventloop local feed = helpers.feed +local expect_exit = helpers.expect_exit describe('Up to MAX_FUNC_ARGS arguments are handled by', function() - local max_func_args = 20 -- from eval.h - local range = helpers.funcs.range + local max_func_args = 20 -- from eval.h + local range = helpers.fn.range before_each(clear) it('printf()', function() - local printf = helpers.funcs.printf - local rep = helpers.funcs['repeat'] + local printf = helpers.fn.printf + local rep = helpers.fn['repeat'] local expected = '2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,' - eq(expected, printf(rep('%d,', max_func_args-1), unpack(range(2, max_func_args)))) + eq(expected, printf(rep('%d,', max_func_args - 1), unpack(range(2, max_func_args)))) local ret = exc_exec('call printf("", 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)') eq('Vim(call):E740: Too many arguments for function printf', ret) end) it('rpcnotify()', function() - local rpcnotify = helpers.funcs.rpcnotify + local rpcnotify = helpers.fn.rpcnotify local ret = rpcnotify(0, 'foo', unpack(range(3, max_func_args))) eq(1, ret) ret = exc_exec('call rpcnotify(0, "foo", 3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)') @@ -53,15 +55,15 @@ describe('Up to MAX_FUNC_ARGS arguments are handled by', function() end) end) -describe("backtick expansion", function() +describe('backtick expansion', function() setup(function() clear() - mkdir("test-backticks") - write_file("test-backticks/file1", "test file 1") - write_file("test-backticks/file2", "test file 2") - write_file("test-backticks/file3", "test file 3") - mkdir("test-backticks/subdir") - write_file("test-backticks/subdir/file4", "test file 4") + mkdir('test-backticks') + write_file('test-backticks/file1', 'test file 1') + write_file('test-backticks/file2', 'test file 2') + write_file('test-backticks/file3', 'test file 3') + mkdir('test-backticks/subdir') + write_file('test-backticks/subdir/file4', 'test file 4') -- Long path might cause "Press ENTER" prompt; use :silent to avoid it. command('silent cd test-backticks') end) @@ -72,30 +74,30 @@ describe("backtick expansion", function() it("with default 'shell'", function() if helpers.is_os('win') then - command(":silent args `dir /b *2`") + command(':silent args `dir /b *2`') else - command(":silent args `echo ***2`") + command(':silent args `echo ***2`') end - eq({ "file2", }, eval("argv()")) + eq({ 'file2' }, eval('argv()')) if helpers.is_os('win') then - command(":silent args `dir /s/b *4`") - eq({ "subdir\\file4", }, eval("map(argv(), 'fnamemodify(v:val, \":.\")')")) + command(':silent args `dir /s/b *4`') + eq({ 'subdir\\file4' }, eval('map(argv(), \'fnamemodify(v:val, ":.")\')')) else - command(":silent args `echo */*4`") - eq({ "subdir/file4", }, eval("argv()")) + command(':silent args `echo */*4`') + eq({ 'subdir/file4' }, eval('argv()')) end end) - it("with shell=fish", function() + it('with shell=fish', function() if eval("executable('fish')") == 0 then pending('missing "fish" command') return end - command("set shell=fish") - command(":silent args `echo ***2`") - eq({ "file2", }, eval("argv()")) - command(":silent args `echo */*4`") - eq({ "subdir/file4", }, eval("argv()")) + command('set shell=fish') + command(':silent args `echo ***2`') + eq({ 'file2' }, eval('argv()')) + command(':silent args `echo */*4`') + eq({ 'subdir/file4' }, eval('argv()')) end) end) @@ -104,7 +106,9 @@ describe('List support code', function() local min_dur = 8 local len = 131072 - if not pending('does not actually allows interrupting with just got_int', function() end) then return end + if not pending('does not actually allows interrupting with just got_int', function() end) then + return + end -- The following tests are confirmed to work with os_breakcheck() just before -- `if (got_int) {break;}` in tv_list_copy and list_join_inner() and not to -- work without. @@ -117,7 +121,7 @@ describe('List support code', function() let bl = range(%u) let dur = reltimestr(reltime(rt)) ]]):format(len)) - dur = tonumber(meths.get_var('dur')) + dur = tonumber(api.nvim_get_var('dur')) if dur >= min_dur then -- print(('Using len %u, dur %g'):format(len, dur)) break @@ -132,7 +136,7 @@ describe('List support code', function() feed('<C-c>') poke_eventloop() command('let t_dur = reltimestr(reltime(t_rt))') - local t_dur = tonumber(meths.get_var('t_dur')) + local t_dur = tonumber(api.nvim_get_var('t_dur')) if t_dur >= dur / 8 then eq(nil, ('Took too long to cancel: %g >= %g'):format(t_dur, dur / 8)) end @@ -143,7 +147,7 @@ describe('List support code', function() feed('<C-c>') poke_eventloop() command('let t_dur = reltimestr(reltime(t_rt))') - local t_dur = tonumber(meths.get_var('t_dur')) + local t_dur = tonumber(api.nvim_get_var('t_dur')) print(('t_dur: %g'):format(t_dur)) if t_dur >= dur / 8 then eq(nil, ('Took too long to cancel: %g >= %g'):format(t_dur, dur / 8)) @@ -151,7 +155,7 @@ describe('List support code', function() end) end) -describe("uncaught exception", function() +describe('uncaught exception', function() before_each(clear) it('is not forgotten #13490', function() @@ -162,11 +166,14 @@ describe("uncaught exception", function() -- from processing the others. -- Only the first thrown exception should be rethrown from the :try below, though. for i = 1, 3 do - write_file('throw' .. i .. '.vim', ([[ + write_file( + 'throw' .. i .. '.vim', + ([[ let result ..= '%d' throw 'throw%d' let result ..= 'X' - ]]):format(i, i)) + ]]):format(i, i) + ) end finally(function() for i = 1, 3 do @@ -182,9 +189,9 @@ describe("uncaught exception", function() it('multiline exception remains multiline #25350', function() local screen = Screen.new(80, 11) screen:set_default_attr_ids({ - [1] = {bold = true, reverse = true}; -- MsgSeparator - [2] = {foreground = Screen.colors.White, background = Screen.colors.Red}; -- ErrorMsg - [3] = {bold = true, foreground = Screen.colors.SeaGreen}; -- MoreMsg + [1] = { bold = true, reverse = true }, -- MsgSeparator + [2] = { foreground = Screen.colors.White, background = Screen.colors.Red }, -- ErrorMsg + [3] = { bold = true, foreground = Screen.colors.SeaGreen }, -- MoreMsg }) screen:attach() exec_lua([[ @@ -193,7 +200,8 @@ describe("uncaught exception", function() end ]]) feed(':try\rlua _G.Oops()\rendtry\r') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: }| :try | : lua _G.Oops() | @@ -205,7 +213,8 @@ describe("uncaught exception", function() {2: [string "<nvim>"]:2: in function 'Oops'} | {2: [string ":lua"]:1: in main chunk} | {3:Press ENTER or type command to continue}^ | - ]]} + ]], + } end) end) @@ -215,16 +224,23 @@ describe('listing functions using :function', function() it('works for lambda functions with <lambda> #20466', function() command('let A = {-> 1}') local num = exec_capture('echo A'):match("function%('<lambda>(%d+)'%)") - eq(([[ + eq( + ([[ function <lambda>%s(...) 1 return 1 - endfunction]]):format(num), exec_capture(('function <lambda>%s'):format(num))) + endfunction]]):format(num), + exec_capture(('function <lambda>%s'):format(num)) + ) end) it('does not crash if another function is deleted while listing', function() local screen = Screen.new(80, 24) screen:attach() - matches('Vim%(function%):E454: Function list was modified$', pcall_err(exec_lua, [=[ + matches( + 'Vim%(function%):E454: Function list was modified$', + pcall_err( + exec_lua, + [=[ vim.cmd([[ func Func1() endfunc @@ -245,14 +261,20 @@ describe('listing functions using :function', function() vim.cmd('function') vim.ui_detach(ns) - ]=])) + ]=] + ) + ) assert_alive() end) it('does not crash if the same function is deleted while listing', function() local screen = Screen.new(80, 24) screen:attach() - matches('Vim%(function%):E454: Function list was modified$', pcall_err(exec_lua, [=[ + matches( + 'Vim%(function%):E454: Function list was modified$', + pcall_err( + exec_lua, + [=[ vim.cmd([[ func Func1() endfunc @@ -273,7 +295,9 @@ describe('listing functions using :function', function() vim.cmd('function') vim.ui_detach(ns) - ]=])) + ]=] + ) + ) assert_alive() end) end) @@ -281,7 +305,9 @@ end) it('no double-free in garbage collection #16287', function() clear() -- Don't use exec() here as using a named script reproduces the issue better. - write_file('Xgarbagecollect.vim', [[ + write_file( + 'Xgarbagecollect.vim', + [[ func Foo() abort let s:args = [a:000] let foo0 = "" @@ -304,7 +330,8 @@ it('no double-free in garbage collection #16287', function() set updatetime=1 call Foo() call Foo() - ]]) + ]] + ) finally(function() os.remove('Xgarbagecollect.vim') end) @@ -312,3 +339,14 @@ it('no double-free in garbage collection #16287', function() sleep(10) assert_alive() end) + +it('no heap-use-after-free with EXITFREE and partial as prompt callback', function() + clear() + exec([[ + func PromptCallback(text) + endfunc + setlocal buftype=prompt + call prompt_setcallback('', funcref('PromptCallback')) + ]]) + expect_exit(command, 'qall!') +end) diff --git a/test/functional/vimscript/executable_spec.lua b/test/functional/vimscript/executable_spec.lua index 2b8e3f6218..1d95f6088e 100644 --- a/test/functional/vimscript/executable_spec.lua +++ b/test/functional/vimscript/executable_spec.lua @@ -1,7 +1,6 @@ local helpers = require('test.functional.helpers')(after_each) local eq, clear, call, write_file, command = - helpers.eq, helpers.clear, helpers.call, helpers.write_file, - helpers.command + helpers.eq, helpers.clear, helpers.call, helpers.write_file, helpers.command local exc_exec = helpers.exc_exec local eval = helpers.eval local is_os = helpers.is_os @@ -21,9 +20,15 @@ describe('executable()', function() if is_os('win') then it('exepath respects shellslash', function() command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")') - eq([[test\functional\fixtures\bin\null.CMD]], call('fnamemodify', call('exepath', 'null'), ':.')) + eq( + [[test\functional\fixtures\bin\null.CMD]], + call('fnamemodify', call('exepath', 'null'), ':.') + ) command('set shellslash') - eq('test/functional/fixtures/bin/null.CMD', call('fnamemodify', call('exepath', 'null'), ':.')) + eq( + 'test/functional/fixtures/bin/null.CMD', + call('fnamemodify', call('exepath', 'null'), ':.') + ) end) it('stdpath respects shellslash', function() @@ -34,14 +39,18 @@ describe('executable()', function() end it('fails for invalid values', function() - for _, input in ipairs({'v:null', 'v:true', 'v:false', '{}', '[]'}) do - eq('Vim(call):E1174: String required for argument 1', - exc_exec('call executable('..input..')')) + for _, input in ipairs({ 'v:null', 'v:true', 'v:false', '{}', '[]' }) do + eq( + 'Vim(call):E1174: String required for argument 1', + exc_exec('call executable(' .. input .. ')') + ) end command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")') - for _, input in ipairs({'v:null', 'v:true', 'v:false'}) do - eq('Vim(call):E1174: String required for argument 1', - exc_exec('call executable('..input..')')) + for _, input in ipairs({ 'v:null', 'v:true', 'v:false' }) do + eq( + 'Vim(call):E1174: String required for argument 1', + exc_exec('call executable(' .. input .. ')') + ) end end) @@ -59,8 +68,7 @@ describe('executable()', function() -- Windows: siblings are in Nvim's "pseudo-$PATH". local expected = is_os('win') and 1 or 0 if is_os('win') then - eq('arg1=lemon;arg2=sky;arg3=tree;', - call('system', sibling_exe..' lemon sky tree')) + eq('arg1=lemon;arg2=sky;arg3=tree;', call('system', sibling_exe .. ' lemon sky tree')) end eq(expected, call('executable', sibling_exe)) end) @@ -70,9 +78,9 @@ describe('executable()', function() clear() write_file('Xtest_not_executable', 'non-executable file') write_file('Xtest_executable', 'executable file (exec-bit set)') - if not is_os('win') then -- N/A for Windows. - call('system', {'chmod', '-x', 'Xtest_not_executable'}) - call('system', {'chmod', '+x', 'Xtest_executable'}) + if not is_os('win') then -- N/A for Windows. + call('system', { 'chmod', '-x', 'Xtest_not_executable' }) + call('system', { 'chmod', '+x', 'Xtest_executable' }) end end) @@ -103,144 +111,142 @@ describe('executable() (Windows)', function() return end - local exts = {'bat', 'exe', 'com', 'cmd'} + local exts = { 'bat', 'exe', 'com', 'cmd' } setup(function() for _, ext in ipairs(exts) do - write_file('test_executable_'..ext..'.'..ext, '') + write_file('test_executable_' .. ext .. '.' .. ext, '') end write_file('test_executable_zzz.zzz', '') end) teardown(function() for _, ext in ipairs(exts) do - os.remove('test_executable_'..ext..'.'..ext) + os.remove('test_executable_' .. ext .. '.' .. ext) end os.remove('test_executable_zzz.zzz') end) it('tries default extensions on a filename if $PATHEXT is empty', function() -- Empty $PATHEXT defaults to ".com;.exe;.bat;.cmd". - clear({env={PATHEXT=''}}) - for _,ext in ipairs(exts) do - eq(1, call('executable', 'test_executable_'..ext)) + clear({ env = { PATHEXT = '' } }) + for _, ext in ipairs(exts) do + eq(1, call('executable', 'test_executable_' .. ext)) end eq(0, call('executable', 'test_executable_zzz')) end) it('tries default extensions on a filepath if $PATHEXT is empty', function() -- Empty $PATHEXT defaults to ".com;.exe;.bat;.cmd". - clear({env={PATHEXT=''}}) - for _,ext in ipairs(exts) do - eq(1, call('executable', '.\\test_executable_'..ext)) + clear({ env = { PATHEXT = '' } }) + for _, ext in ipairs(exts) do + eq(1, call('executable', '.\\test_executable_' .. ext)) end eq(0, call('executable', '.\\test_executable_zzz')) end) it('system([…]), jobstart([…]) use $PATHEXT #9569', function() -- Empty $PATHEXT defaults to ".com;.exe;.bat;.cmd". - clear({env={PATHEXT=''}}) + clear({ env = { PATHEXT = '' } }) -- Invoking `cmdscript` should find/execute `cmdscript.cmd`. - eq('much success\n', call('system', {'test/functional/fixtures/cmdscript'})) - assert(0 < call('jobstart', {'test/functional/fixtures/cmdscript'})) + eq('much success\n', call('system', { 'test/functional/fixtures/cmdscript' })) + assert(0 < call('jobstart', { 'test/functional/fixtures/cmdscript' })) end) it('full path with extension', function() -- Empty $PATHEXT defaults to ".com;.exe;.bat;.cmd". - clear({env={PATHEXT=''}}) + clear({ env = { PATHEXT = '' } }) -- Some executable we can expect in the test env. local exe = 'printargs-test' local exedir = eval("fnamemodify(v:progpath, ':h')") - local exepath = exedir..'/'..exe..'.exe' + local exepath = exedir .. '/' .. exe .. '.exe' eq(1, call('executable', exepath)) - eq('arg1=lemon;arg2=sky;arg3=tree;', - call('system', exepath..' lemon sky tree')) + eq('arg1=lemon;arg2=sky;arg3=tree;', call('system', exepath .. ' lemon sky tree')) end) it('full path without extension', function() -- Empty $PATHEXT defaults to ".com;.exe;.bat;.cmd". - clear({env={PATHEXT=''}}) + clear({ env = { PATHEXT = '' } }) -- Some executable we can expect in the test env. local exe = 'printargs-test' local exedir = eval("fnamemodify(v:progpath, ':h')") - local exepath = exedir..'/'..exe - eq('arg1=lemon;arg2=sky;arg3=tree;', - call('system', exepath..' lemon sky tree')) - eq(1, call('executable', exepath)) + local exepath = exedir .. '/' .. exe + eq('arg1=lemon;arg2=sky;arg3=tree;', call('system', exepath .. ' lemon sky tree')) + eq(1, call('executable', exepath)) end) it('respects $PATHEXT when trying extensions on a filename', function() - clear({env={PATHEXT='.zzz'}}) - for _,ext in ipairs(exts) do - eq(0, call('executable', 'test_executable_'..ext)) + clear({ env = { PATHEXT = '.zzz' } }) + for _, ext in ipairs(exts) do + eq(0, call('executable', 'test_executable_' .. ext)) end eq(1, call('executable', 'test_executable_zzz')) end) it('respects $PATHEXT when trying extensions on a filepath', function() - clear({env={PATHEXT='.zzz'}}) - for _,ext in ipairs(exts) do - eq(0, call('executable', '.\\test_executable_'..ext)) + clear({ env = { PATHEXT = '.zzz' } }) + for _, ext in ipairs(exts) do + eq(0, call('executable', '.\\test_executable_' .. ext)) end eq(1, call('executable', '.\\test_executable_zzz')) end) - it("with weird $PATHEXT", function() - clear({env={PATHEXT=';'}}) + it('with weird $PATHEXT', function() + clear({ env = { PATHEXT = ';' } }) eq(0, call('executable', '.\\test_executable_zzz')) - clear({env={PATHEXT=';;;.zzz;;'}}) + clear({ env = { PATHEXT = ';;;.zzz;;' } }) eq(1, call('executable', '.\\test_executable_zzz')) end) it("unqualified filename, Unix-style 'shell'", function() - clear({env={PATHEXT=''}}) + clear({ env = { PATHEXT = '' } }) command('set shell=sh') - for _,ext in ipairs(exts) do - eq(1, call('executable', 'test_executable_'..ext..'.'..ext)) + for _, ext in ipairs(exts) do + eq(1, call('executable', 'test_executable_' .. ext .. '.' .. ext)) end eq(1, call('executable', 'test_executable_zzz.zzz')) end) it("relative path, Unix-style 'shell' (backslashes)", function() - clear({env={PATHEXT=''}}) + clear({ env = { PATHEXT = '' } }) command('set shell=bash.exe') - for _,ext in ipairs(exts) do - eq(1, call('executable', '.\\test_executable_'..ext..'.'..ext)) - eq(1, call('executable', './test_executable_'..ext..'.'..ext)) + for _, ext in ipairs(exts) do + eq(1, call('executable', '.\\test_executable_' .. ext .. '.' .. ext)) + eq(1, call('executable', './test_executable_' .. ext .. '.' .. ext)) end eq(1, call('executable', '.\\test_executable_zzz.zzz')) eq(1, call('executable', './test_executable_zzz.zzz')) end) it('unqualified filename, $PATHEXT contains dot', function() - clear({env={PATHEXT='.;.zzz'}}) - for _,ext in ipairs(exts) do - eq(1, call('executable', 'test_executable_'..ext..'.'..ext)) + clear({ env = { PATHEXT = '.;.zzz' } }) + for _, ext in ipairs(exts) do + eq(1, call('executable', 'test_executable_' .. ext .. '.' .. ext)) end eq(1, call('executable', 'test_executable_zzz.zzz')) - clear({env={PATHEXT='.zzz;.'}}) - for _,ext in ipairs(exts) do - eq(1, call('executable', 'test_executable_'..ext..'.'..ext)) + clear({ env = { PATHEXT = '.zzz;.' } }) + for _, ext in ipairs(exts) do + eq(1, call('executable', 'test_executable_' .. ext .. '.' .. ext)) end eq(1, call('executable', 'test_executable_zzz.zzz')) end) it('relative path, $PATHEXT contains dot (backslashes)', function() - clear({env={PATHEXT='.;.zzz'}}) - for _,ext in ipairs(exts) do - eq(1, call('executable', '.\\test_executable_'..ext..'.'..ext)) - eq(1, call('executable', './test_executable_'..ext..'.'..ext)) + clear({ env = { PATHEXT = '.;.zzz' } }) + for _, ext in ipairs(exts) do + eq(1, call('executable', '.\\test_executable_' .. ext .. '.' .. ext)) + eq(1, call('executable', './test_executable_' .. ext .. '.' .. ext)) end eq(1, call('executable', '.\\test_executable_zzz.zzz')) eq(1, call('executable', './test_executable_zzz.zzz')) end) it('ignores case of extension', function() - clear({env={PATHEXT='.ZZZ'}}) + clear({ env = { PATHEXT = '.ZZZ' } }) eq(1, call('executable', 'test_executable_zzz.zzz')) end) it('relative path does not search $PATH', function() - clear({env={PATHEXT=''}}) + clear({ env = { PATHEXT = '' } }) eq(0, call('executable', './System32/notepad.exe')) eq(0, call('executable', '.\\System32\\notepad.exe')) eq(0, call('executable', '../notepad.exe')) diff --git a/test/functional/vimscript/execute_spec.lua b/test/functional/vimscript/execute_spec.lua index bb28938708..29488ed31c 100644 --- a/test/functional/vimscript/execute_spec.lua +++ b/test/functional/vimscript/execute_spec.lua @@ -5,7 +5,7 @@ local clear = helpers.clear local source = helpers.source local exc_exec = helpers.exc_exec local pcall_err = helpers.pcall_err -local funcs = helpers.funcs +local fn = helpers.fn local Screen = require('test.functional.ui.screen') local command = helpers.command local feed = helpers.feed @@ -22,16 +22,16 @@ describe('execute()', function() silent! messages redir END ]]) - eq(eval('g:__redir_output'), funcs.execute('messages')) + eq(eval('g:__redir_output'), fn.execute('messages')) end) it('captures the concatenated outputs of a List of commands', function() - eq("foobar", funcs.execute({'echon "foo"', 'echon "bar"'})) - eq("\nfoo\nbar", funcs.execute({'echo "foo"', 'echo "bar"'})) + eq('foobar', fn.execute({ 'echon "foo"', 'echon "bar"' })) + eq('\nfoo\nbar', fn.execute({ 'echo "foo"', 'echo "bar"' })) end) it('supports nested execute("execute(...)")', function() - eq('42', funcs.execute([[echon execute("echon execute('echon 42')")]])) + eq('42', fn.execute([[echon execute("echon execute('echon 42')")]])) end) it('supports nested :redir to a variable', function() @@ -54,7 +54,7 @@ describe('execute()', function() return a endfunction ]]) - eq('top1bar1foobar2bar3', funcs.execute('echon "top1"|call g:Bar()')) + eq('top1bar1foobar2bar3', fn.execute('echon "top1"|call g:Bar()')) end) it('supports nested :redir to a register', function() @@ -76,17 +76,17 @@ describe('execute()', function() return @a endfunction ]]) - eq('top1bar1foobar2bar3', funcs.execute('echon "top1"|call g:Bar()')) + eq('top1bar1foobar2bar3', fn.execute('echon "top1"|call g:Bar()')) -- :redir itself doesn't nest, so the redirection ends in g:Foo eq('bar1foo', eval('@a')) end) it('captures a transformed string', function() - eq('^A', funcs.execute('echon "\\<C-a>"')) + eq('^A', fn.execute('echon "\\<C-a>"')) end) it('returns empty string if the argument list is empty', function() - eq('', funcs.execute({})) + eq('', fn.execute({})) eq(0, exc_exec('let g:ret = execute(v:_null_list)')) eq('', eval('g:ret')) end) @@ -104,27 +104,31 @@ describe('execute()', function() end) it('captures output with highlights', function() - eq('\nErrorMsg xxx ctermfg=15 ctermbg=1 guifg=White guibg=Red', - eval('execute("hi ErrorMsg")')) + eq( + '\nErrorMsg xxx ctermfg=15 ctermbg=1 guifg=White guibg=Red', + eval('execute("hi ErrorMsg")') + ) end) it('does not corrupt the command display #5422', function() local screen = Screen.new(70, 7) screen:attach() feed(':echo execute("hi ErrorMsg")<CR>') - screen:expect([[ + screen:expect( + [[ | - {1:~ }| - {1:~ }| + {1:~ }|*2 {2: }| | ErrorMsg xxx ctermfg=15 ctermbg=1 guifg=White guibg=Red | {3:Press ENTER or type command to continue}^ | - ]], { - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {bold = true, reverse = true}, - [3] = {bold = true, foreground = Screen.colors.SeaGreen4}, - }) + ]], + { + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { bold = true, reverse = true }, + [3] = { bold = true, foreground = Screen.colors.SeaGreen4 }, + } + ) feed('<CR>') end) @@ -187,30 +191,21 @@ describe('execute()', function() feed([[:call Test1()<cr>]]) screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | + ~ |*4 ABCD | ]]) feed([[:call Test2()<cr>]]) screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | + ~ |*4 1234ABCD | ]]) feed([[:call Test3()<cr>]]) screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | + ~ |*4 1234ABCDXZYZ | ]]) @@ -231,10 +226,7 @@ describe('execute()', function() feed([[:call Test5()<cr>]]) screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | + ~ |*4 1234ABCD | ]]) @@ -263,7 +255,7 @@ describe('execute()', function() -- with how nvim currently displays the output. it('captures shell-command output', function() local win_lf = is_os('win') and '\13' or '' - eq('\n:!echo foo\r\n\nfoo'..win_lf..'\n', funcs.execute('!echo foo')) + eq('\n:!echo foo\r\n\nfoo' .. win_lf .. '\n', fn.execute('!echo foo')) end) describe('{silent} argument', function() @@ -273,9 +265,7 @@ describe('execute()', function() command('let g:mes = execute("echon 42", "")') screen:expect([[ ^ | - ~ | - ~ | - ~ | + ~ |*3 42 | ]]) eq('42', eval('g:mes')) @@ -283,10 +273,14 @@ describe('execute()', function() it('gives E493 instead of prompting on backwards range for ""', function() command('split') - eq('Vim(windo):E493: Backwards range given: 2,1windo echo', - pcall_err(funcs.execute, '2,1windo echo', '')) - eq('Vim(windo):E493: Backwards range given: 2,1windo echo', - pcall_err(funcs.execute, {'2,1windo echo'}, '')) + eq( + 'Vim(windo):E493: Backwards range given: 2,1windo echo', + pcall_err(fn.execute, '2,1windo echo', '') + ) + eq( + 'Vim(windo):E493: Backwards range given: 2,1windo echo', + pcall_err(fn.execute, { '2,1windo echo' }, '') + ) end) it('captures but does not display output for "silent"', function() @@ -295,21 +289,20 @@ describe('execute()', function() command('let g:mes = execute("echon 42")') screen:expect([[ ^ | - ~ | - ~ | - ~ | + ~ |*3 | ]]) eq('42', eval('g:mes')) command('let g:mes = execute("echon 13", "silent")') - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - ~ | - ~ | - ~ | + ~ |*3 | - ]], unchanged=true} + ]], + unchanged = true, + } eq('13', eval('g:mes')) end) diff --git a/test/functional/vimscript/exepath_spec.lua b/test/functional/vimscript/exepath_spec.lua index da3d61cbe0..01033a2140 100644 --- a/test/functional/vimscript/exepath_spec.lua +++ b/test/functional/vimscript/exepath_spec.lua @@ -1,6 +1,5 @@ local helpers = require('test.functional.helpers')(after_each) -local eq, clear, call = - helpers.eq, helpers.clear, helpers.call +local eq, clear, call = helpers.eq, helpers.clear, helpers.call local command = helpers.command local exc_exec = helpers.exc_exec local matches = helpers.matches @@ -14,20 +13,26 @@ local find_dummies = function(ext_pat) matches('null' .. ext_pat, call('exepath', 'null')) matches('true' .. ext_pat, call('exepath', 'true')) matches('false' .. ext_pat, call('exepath', 'false')) - command("let $PATH = '"..tmp_path.."'") + command("let $PATH = '" .. tmp_path .. "'") end describe('exepath()', function() before_each(clear) it('fails for invalid values', function() - for _, input in ipairs({'v:null', 'v:true', 'v:false', '{}', '[]'}) do - eq('Vim(call):E1174: String required for argument 1', exc_exec('call exepath('..input..')')) + for _, input in ipairs({ 'v:null', 'v:true', 'v:false', '{}', '[]' }) do + eq( + 'Vim(call):E1174: String required for argument 1', + exc_exec('call exepath(' .. input .. ')') + ) end eq('Vim(call):E1175: Non-empty string required for argument 1', exc_exec('call exepath("")')) command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")') - for _, input in ipairs({'v:null', 'v:true', 'v:false'}) do - eq('Vim(call):E1174: String required for argument 1', exc_exec('call exepath('..input..')')) + for _, input in ipairs({ 'v:null', 'v:true', 'v:false' }) do + eq( + 'Vim(call):E1174: String required for argument 1', + exc_exec('call exepath(' .. input .. ')') + ) end end) @@ -40,24 +45,30 @@ describe('exepath()', function() it('append extension if omitted', function() local filename = 'cmd' local pathext = '.exe' - clear({env={PATHEXT=pathext}}) - eq(call('exepath', filename..pathext), call('exepath', filename)) + clear({ env = { PATHEXT = pathext } }) + eq(call('exepath', filename .. pathext), call('exepath', filename)) end) - it('returns file WITH extension if files both with and without extension exist in $PATH', function() - local ext_pat = '%.CMD$' - find_dummies(ext_pat) - set_shell_powershell() - find_dummies(ext_pat) - end) + it( + 'returns file WITH extension if files both with and without extension exist in $PATH', + function() + local ext_pat = '%.CMD$' + find_dummies(ext_pat) + set_shell_powershell() + find_dummies(ext_pat) + end + ) else it('returns 1 for commands in $PATH (not Windows)', function() local exe = 'ls' matches(exe .. '$', call('exepath', exe)) end) - it('returns file WITHOUT extension if files both with and without extension exist in $PATH', function() - find_dummies('$') - end) + it( + 'returns file WITHOUT extension if files both with and without extension exist in $PATH', + function() + find_dummies('$') + end + ) end end) diff --git a/test/functional/vimscript/fnamemodify_spec.lua b/test/functional/vimscript/fnamemodify_spec.lua index c3ecdd853c..4a134fe23c 100644 --- a/test/functional/vimscript/fnamemodify_spec.lua +++ b/test/functional/vimscript/fnamemodify_spec.lua @@ -1,8 +1,8 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local eq = helpers.eq -local fnamemodify = helpers.funcs.fnamemodify -local getcwd = helpers.funcs.getcwd +local fnamemodify = helpers.fn.fnamemodify +local getcwd = helpers.fn.getcwd local command = helpers.command local write_file = helpers.write_file local alter_slashes = helpers.alter_slashes @@ -31,7 +31,7 @@ describe('fnamemodify()', function() eq(root, fnamemodify([[\]], ':p:h')) eq(root, fnamemodify([[\]], ':p')) command('set shellslash') - root = string.sub(root, 1, -2)..'/' + root = string.sub(root, 1, -2) .. '/' eq(root, fnamemodify([[\]], ':p:h')) eq(root, fnamemodify([[\]], ':p')) eq(root, fnamemodify([[/]], ':p:h')) @@ -44,7 +44,7 @@ describe('fnamemodify()', function() end) it('handles examples from ":help filename-modifiers"', function() - local filename = "src/version.c" + local filename = 'src/version.c' local cwd = getcwd() eq_slashconvert(cwd .. '/src/version.c', fnamemodify(filename, ':p')) @@ -70,7 +70,7 @@ describe('fnamemodify()', function() end) it('handles advanced examples from ":help filename-modifiers"', function() - local filename = "src/version.c.gz" + local filename = 'src/version.c.gz' eq('gz', fnamemodify(filename, ':e')) eq('c.gz', fnamemodify(filename, ':e:e')) diff --git a/test/functional/vimscript/getline_spec.lua b/test/functional/vimscript/getline_spec.lua index 3c56bde094..08e7711b8c 100644 --- a/test/functional/vimscript/getline_spec.lua +++ b/test/functional/vimscript/getline_spec.lua @@ -8,7 +8,7 @@ local expect = helpers.expect describe('getline()', function() before_each(function() clear() - call('setline', 1, {'a', 'b', 'c'}) + call('setline', 1, { 'a', 'b', 'c' }) expect([[ a b @@ -33,7 +33,7 @@ describe('getline()', function() end) it('returns value of valid range', function() - eq({'a', 'b'}, call('getline', 1, 2)) - eq({'a', 'b', 'c'}, call('getline', 1, 4)) + eq({ 'a', 'b' }, call('getline', 1, 2)) + eq({ 'a', 'b', 'c' }, call('getline', 1, 4)) end) end) diff --git a/test/functional/vimscript/glob_spec.lua b/test/functional/vimscript/glob_spec.lua index 948a63f050..77351f95fa 100644 --- a/test/functional/vimscript/glob_spec.lua +++ b/test/functional/vimscript/glob_spec.lua @@ -1,4 +1,3 @@ -local luv = require('luv') local helpers = require('test.functional.helpers')(after_each) local clear, command, eval, eq = helpers.clear, helpers.command, helpers.eval, helpers.eq local mkdir = helpers.mkdir @@ -12,14 +11,14 @@ before_each(function() end) after_each(function() - luv.fs_rmdir('test-glob') + vim.uv.fs_rmdir('test-glob') end) describe('glob()', function() it("glob('.*') returns . and .. ", function() - eq({'.', '..'}, eval("glob('.*', 0, 1)")) + eq({ '.', '..' }, eval("glob('.*', 0, 1)")) -- Do it again to verify scandir_next_with_dots() internal state. - eq({'.', '..'}, eval("glob('.*', 0, 1)")) + eq({ '.', '..' }, eval("glob('.*', 0, 1)")) end) it("glob('*') returns an empty list ", function() eq({}, eval("glob('*', 0, 1)")) diff --git a/test/functional/vimscript/has_spec.lua b/test/functional/vimscript/has_spec.lua index 78a761d370..82b3db5b67 100644 --- a/test/functional/vimscript/has_spec.lua +++ b/test/functional/vimscript/has_spec.lua @@ -3,7 +3,7 @@ local Screen = require('test.functional.ui.screen') local clear = helpers.clear local connect = helpers.connect local eq = helpers.eq -local funcs = helpers.funcs +local fn = helpers.fn local is_os = helpers.is_os local nvim_prog = helpers.nvim_prog @@ -11,85 +11,83 @@ describe('has()', function() before_each(clear) it('"nvim-x.y.z"', function() - eq(0, funcs.has("nvim-")) - eq(0, funcs.has("nvim- ")) - eq(0, funcs.has("nvim- \t ")) - eq(0, funcs.has("nvim-0. 1. 1")) - eq(0, funcs.has("nvim-0. 1.1")) - eq(0, funcs.has("nvim-0.1. 1")) - eq(0, funcs.has("nvim-a")) - eq(0, funcs.has("nvim-a.b.c")) - eq(0, funcs.has("nvim-0.b.c")) - eq(0, funcs.has("nvim-0.0.c")) - eq(0, funcs.has("nvim-0.b.0")) - eq(0, funcs.has("nvim-a.b.0")) - eq(0, funcs.has("nvim-.0.0.0")) - eq(0, funcs.has("nvim-.0")) - eq(0, funcs.has("nvim-0.")) - eq(0, funcs.has("nvim-0..")) - eq(0, funcs.has("nvim-.")) - eq(0, funcs.has("nvim-..")) - eq(0, funcs.has("nvim-...")) - eq(0, funcs.has("nvim-42")) - eq(0, funcs.has("nvim-9999")) - eq(0, funcs.has("nvim-99.001.05")) + eq(0, fn.has('nvim-')) + eq(0, fn.has('nvim- ')) + eq(0, fn.has('nvim- \t ')) + eq(0, fn.has('nvim-0. 1. 1')) + eq(0, fn.has('nvim-0. 1.1')) + eq(0, fn.has('nvim-0.1. 1')) + eq(0, fn.has('nvim-a')) + eq(0, fn.has('nvim-a.b.c')) + eq(0, fn.has('nvim-0.b.c')) + eq(0, fn.has('nvim-0.0.c')) + eq(0, fn.has('nvim-0.b.0')) + eq(0, fn.has('nvim-a.b.0')) + eq(0, fn.has('nvim-.0.0.0')) + eq(0, fn.has('nvim-.0')) + eq(0, fn.has('nvim-0.')) + eq(0, fn.has('nvim-0..')) + eq(0, fn.has('nvim-.')) + eq(0, fn.has('nvim-..')) + eq(0, fn.has('nvim-...')) + eq(0, fn.has('nvim-42')) + eq(0, fn.has('nvim-9999')) + eq(0, fn.has('nvim-99.001.05')) - eq(1, funcs.has("nvim")) - eq(1, funcs.has("nvim-0")) - eq(1, funcs.has("nvim-0.1")) - eq(1, funcs.has("nvim-0.0.0")) - eq(1, funcs.has("nvim-0.1.1.")) - eq(1, funcs.has("nvim-0.1.1.abc")) - eq(1, funcs.has("nvim-0.1.1..")) - eq(1, funcs.has("nvim-0.1.1.. ..")) - eq(1, funcs.has("nvim-0.1.1.... ")) - eq(1, funcs.has("nvim-0.0.0")) - eq(1, funcs.has("nvim-0.0.1")) - eq(1, funcs.has("nvim-0.1.0")) - eq(1, funcs.has("nvim-0.1.1")) - eq(1, funcs.has("nvim-0.1.5")) - eq(1, funcs.has("nvim-0000.001.05")) - eq(1, funcs.has("nvim-0.01.005")) - eq(1, funcs.has("nvim-00.001.05")) + eq(1, fn.has('nvim')) + eq(1, fn.has('nvim-0')) + eq(1, fn.has('nvim-0.1')) + eq(1, fn.has('nvim-0.0.0')) + eq(1, fn.has('nvim-0.1.1.')) + eq(1, fn.has('nvim-0.1.1.abc')) + eq(1, fn.has('nvim-0.1.1..')) + eq(1, fn.has('nvim-0.1.1.. ..')) + eq(1, fn.has('nvim-0.1.1.... ')) + eq(1, fn.has('nvim-0.0.0')) + eq(1, fn.has('nvim-0.0.1')) + eq(1, fn.has('nvim-0.1.0')) + eq(1, fn.has('nvim-0.1.1')) + eq(1, fn.has('nvim-0.1.5')) + eq(1, fn.has('nvim-0000.001.05')) + eq(1, fn.has('nvim-0.01.005')) + eq(1, fn.has('nvim-00.001.05')) end) it('"unnamedplus"', function() - if (not is_os('win')) and funcs.has("clipboard") == 1 then - eq(1, funcs.has("unnamedplus")) + if (not is_os('win')) and fn.has('clipboard') == 1 then + eq(1, fn.has('unnamedplus')) else - eq(0, funcs.has("unnamedplus")) + eq(0, fn.has('unnamedplus')) end end) it('"wsl"', function() - local luv = require('luv') - local is_wsl = - luv.os_uname()['release']:lower():match('microsoft') and true or false + local is_wsl = vim.uv.os_uname()['release']:lower():match('microsoft') and true or false if is_wsl then - eq(1, funcs.has('wsl')) + eq(1, fn.has('wsl')) else - eq(0, funcs.has('wsl')) + eq(0, fn.has('wsl')) end end) it('"gui_running"', function() - eq(0, funcs.has('gui_running')) - local tui = Screen.new(50,15) - local gui_session = connect(funcs.serverstart()) - local gui = Screen.new(50,15) - eq(0, funcs.has('gui_running')) - tui:attach({ext_linegrid=true, rgb=true, stdin_tty=true, stdout_tty=true}) - gui:attach({ext_multigrid=true, rgb=true}, gui_session) - eq(1, funcs.has('gui_running')) + eq(0, fn.has('gui_running')) + local tui = Screen.new(50, 15) + local gui_session = connect(fn.serverstart()) + local gui = Screen.new(50, 15) + eq(0, fn.has('gui_running')) + tui:attach({ ext_linegrid = true, rgb = true, stdin_tty = true, stdout_tty = true }) + gui:attach({ ext_multigrid = true, rgb = true }, gui_session) + eq(1, fn.has('gui_running')) tui:detach() - eq(1, funcs.has('gui_running')) + eq(1, fn.has('gui_running')) gui:detach() - eq(0, funcs.has('gui_running')) + eq(0, fn.has('gui_running')) end) it('does not change v:shell_error', function() - funcs.system({nvim_prog, '-es', '+73cquit'}) - funcs.has('python3') -- use a call whose implementation shells out - eq(73, funcs.eval('v:shell_error')) + fn.system({ nvim_prog, '-es', '+73cquit' }) + fn.has('python3') -- use a call whose implementation shells out + eq(73, fn.eval('v:shell_error')) end) end) diff --git a/test/functional/vimscript/hostname_spec.lua b/test/functional/vimscript/hostname_spec.lua index 7d4baa7213..62520e8222 100644 --- a/test/functional/vimscript/hostname_spec.lua +++ b/test/functional/vimscript/hostname_spec.lua @@ -13,8 +13,10 @@ describe('hostname()', function() ok(string.len(actual) > 0) if call('executable', 'hostname') == 1 then local expected = string.gsub(call('system', 'hostname'), '[\n\r]', '') - eq((is_os('win') and expected:upper() or expected), - (is_os('win') and actual:upper() or actual)) + eq( + (is_os('win') and expected:upper() or expected), + (is_os('win') and actual:upper() or actual) + ) end end) end) diff --git a/test/functional/vimscript/input_spec.lua b/test/functional/vimscript/input_spec.lua index e1179d29cc..b749d5a7f0 100644 --- a/test/functional/vimscript/input_spec.lua +++ b/test/functional/vimscript/input_spec.lua @@ -3,14 +3,14 @@ local Screen = require('test.functional.ui.screen') local eq = helpers.eq local feed = helpers.feed -local meths = helpers.meths +local api = helpers.api local clear = helpers.clear local source = helpers.source local command = helpers.command local exc_exec = helpers.exc_exec local pcall_err = helpers.pcall_err local async_meths = helpers.async_meths -local NIL = helpers.NIL +local NIL = vim.NIL local screen @@ -55,14 +55,14 @@ before_each(function() endfunction ]]) screen:set_default_attr_ids({ - EOB={bold = true, foreground = Screen.colors.Blue1}, - T={foreground=Screen.colors.Red}, - RBP1={background=Screen.colors.Red}, - RBP2={background=Screen.colors.Yellow}, - RBP3={background=Screen.colors.Green}, - RBP4={background=Screen.colors.Blue}, - SEP={bold = true, reverse = true}, - CONFIRM={bold = true, foreground = Screen.colors.SeaGreen4}, + EOB = { bold = true, foreground = Screen.colors.Blue1 }, + T = { foreground = Screen.colors.Red }, + RBP1 = { background = Screen.colors.Red }, + RBP2 = { background = Screen.colors.Yellow }, + RBP3 = { background = Screen.colors.Green }, + RBP4 = { background = Screen.colors.Blue }, + SEP = { bold = true, reverse = true }, + CONFIRM = { bold = true, foreground = Screen.colors.SeaGreen4 }, }) end) @@ -89,9 +89,7 @@ describe('input()', function() command('redraw!') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:Foo}^ | ]]) end) @@ -100,144 +98,125 @@ describe('input()', function() feed([[:call input(1, 2)<CR>]]) screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:1}2^ | ]]) feed('<BS>') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:1}^ | ]]) end) it('allows unequal numeric values when using {opts} dictionary', function() command('echohl Test') - meths.set_var('opts', {prompt=1, default=2, cancelreturn=3}) + api.nvim_set_var('opts', { prompt = 1, default = 2, cancelreturn = 3 }) feed([[:echo input(opts)<CR>]]) screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:1}2^ | ]]) feed('<BS>') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:1}^ | ]]) feed('<Esc>') screen:expect([[ ^ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:3} | ]]) end) it('works with redraw', function() command('echohl Test') - meths.set_var('opts', {prompt='Foo>', default='Bar'}) + api.nvim_set_var('opts', { prompt = 'Foo>', default = 'Bar' }) feed([[:echo inputdialog(opts)<CR>]]) screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:Foo>}Bar^ | ]]) command('mode') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:Foo>}Bar^ | - ]], reset=true} + ]], + reset = true, + } feed('<BS>') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:Foo>}Ba^ | ]]) command('mode') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:Foo>}Ba^ | - ]], reset=true} + ]], + reset = true, + } end) it('allows omitting everything with dictionary argument', function() command('echohl Test') feed([[:call input({})<CR>]]) screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 ^ | ]]) end) it('supports completion', function() feed(':let var = input("", "", "custom,CustomCompl")<CR>') feed('<Tab><CR>') - eq('TEST', meths.get_var('var')) + eq('TEST', api.nvim_get_var('var')) feed(':let var = input({"completion": "customlist,CustomListCompl"})<CR>') feed('<Tab><CR>') - eq('FOO', meths.get_var('var')) + eq('FOO', api.nvim_get_var('var')) end) it('supports cancelreturn', function() feed(':let var = input({"cancelreturn": "BAR"})<CR>') feed('<Esc>') - eq('BAR', meths.get_var('var')) + eq('BAR', api.nvim_get_var('var')) feed(':let var = input({"cancelreturn": []})<CR>') feed('<Esc>') - eq({}, meths.get_var('var')) + eq({}, api.nvim_get_var('var')) feed(':let var = input({"cancelreturn": v:false})<CR>') feed('<Esc>') - eq(false, meths.get_var('var')) + eq(false, api.nvim_get_var('var')) feed(':let var = input({"cancelreturn": v:null})<CR>') feed('<Esc>') - eq(NIL, meths.get_var('var')) + eq(NIL, api.nvim_get_var('var')) end) it('supports default string', function() feed(':let var = input("", "DEF1")<CR>') feed('<CR>') - eq('DEF1', meths.get_var('var')) + eq('DEF1', api.nvim_get_var('var')) feed(':let var = input({"default": "DEF2"})<CR>') feed('<CR>') - eq('DEF2', meths.get_var('var')) + eq('DEF2', api.nvim_get_var('var')) end) it('errors out on invalid inputs', function() - eq('Vim(call):E730: Using a List as a String', - exc_exec('call input([])')) - eq('Vim(call):E730: Using a List as a String', - exc_exec('call input("", [])')) - eq('Vim(call):E730: Using a List as a String', - exc_exec('call input("", "", [])')) - eq('Vim(call):E730: Using a List as a String', - exc_exec('call input({"prompt": []})')) - eq('Vim(call):E730: Using a List as a String', - exc_exec('call input({"default": []})')) - eq('Vim(call):E730: Using a List as a String', - exc_exec('call input({"completion": []})')) - eq('Vim(call):E5050: {opts} must be the only argument', - exc_exec('call input({}, "default")')) - eq('Vim(call):E118: Too many arguments for function: input', - exc_exec('call input("prompt> ", "default", "file", "extra")')) + eq('Vim(call):E730: Using a List as a String', exc_exec('call input([])')) + eq('Vim(call):E730: Using a List as a String', exc_exec('call input("", [])')) + eq('Vim(call):E730: Using a List as a String', exc_exec('call input("", "", [])')) + eq('Vim(call):E730: Using a List as a String', exc_exec('call input({"prompt": []})')) + eq('Vim(call):E730: Using a List as a String', exc_exec('call input({"default": []})')) + eq('Vim(call):E730: Using a List as a String', exc_exec('call input({"completion": []})')) + eq('Vim(call):E5050: {opts} must be the only argument', exc_exec('call input({}, "default")')) + eq( + 'Vim(call):E118: Too many arguments for function: input', + exc_exec('call input("prompt> ", "default", "file", "extra")') + ) end) it('supports highlighting', function() command('nnoremap <expr> X input({"highlight": "RainBowParens"})[-1]') @@ -245,9 +224,7 @@ describe('input()', function() feed('(())') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {RBP1:(}{RBP2:()}{RBP1:)}^ | ]]) end) @@ -294,9 +271,7 @@ describe('inputdialog()', function() command('redraw!') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:Foo}^ | ]]) end) @@ -305,135 +280,119 @@ describe('inputdialog()', function() feed([[:call inputdialog(1, 2)<CR>]]) screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:1}2^ | ]]) feed('<BS>') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:1}^ | ]]) end) it('allows unequal numeric values when using {opts} dictionary', function() command('echohl Test') - meths.set_var('opts', {prompt=1, default=2, cancelreturn=3}) + api.nvim_set_var('opts', { prompt = 1, default = 2, cancelreturn = 3 }) feed([[:echo input(opts)<CR>]]) screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:1}2^ | ]]) feed('<BS>') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:1}^ | ]]) feed('<Esc>') screen:expect([[ ^ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:3} | ]]) end) it('works with redraw', function() command('echohl Test') - meths.set_var('opts', {prompt='Foo>', default='Bar'}) + api.nvim_set_var('opts', { prompt = 'Foo>', default = 'Bar' }) feed([[:echo input(opts)<CR>]]) screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:Foo>}Bar^ | ]]) command('mode') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:Foo>}Bar^ | - ]], reset=true} + ]], + reset = true, + } feed('<BS>') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:Foo>}Ba^ | ]]) command('mode') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {T:Foo>}Ba^ | - ]], reset=true} + ]], + reset = true, + } end) it('allows omitting everything with dictionary argument', function() command('echohl Test') feed(':echo inputdialog({})<CR>') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 ^ | ]]) end) it('supports completion', function() feed(':let var = inputdialog({"completion": "customlist,CustomListCompl"})<CR>') feed('<Tab><CR>') - eq('FOO', meths.get_var('var')) + eq('FOO', api.nvim_get_var('var')) end) it('supports cancelreturn', function() feed(':let var = inputdialog("", "", "CR1")<CR>') feed('<Esc>') - eq('CR1', meths.get_var('var')) + eq('CR1', api.nvim_get_var('var')) feed(':let var = inputdialog({"cancelreturn": "BAR"})<CR>') feed('<Esc>') - eq('BAR', meths.get_var('var')) + eq('BAR', api.nvim_get_var('var')) end) it('supports default string', function() feed(':let var = inputdialog("", "DEF1")<CR>') feed('<CR>') - eq('DEF1', meths.get_var('var')) + eq('DEF1', api.nvim_get_var('var')) feed(':let var = inputdialog({"default": "DEF2"})<CR>') feed('<CR>') - eq('DEF2', meths.get_var('var')) + eq('DEF2', api.nvim_get_var('var')) end) it('errors out on invalid inputs', function() - eq('Vim(call):E730: Using a List as a String', - exc_exec('call inputdialog([])')) - eq('Vim(call):E730: Using a List as a String', - exc_exec('call inputdialog("", [])')) - eq('Vim(call):E730: Using a List as a String', - exc_exec('call inputdialog("", "", [])')) - eq('Vim(call):E730: Using a List as a String', - exc_exec('call inputdialog({"prompt": []})')) - eq('Vim(call):E730: Using a List as a String', - exc_exec('call inputdialog({"default": []})')) - eq('Vim(call):E730: Using a List as a String', - exc_exec('call inputdialog({"completion": []})')) - eq('Vim(call):E5050: {opts} must be the only argument', - exc_exec('call inputdialog({}, "default")')) - eq('Vim(call):E118: Too many arguments for function: inputdialog', - exc_exec('call inputdialog("prompt> ", "default", "file", "extra")')) + eq('Vim(call):E730: Using a List as a String', exc_exec('call inputdialog([])')) + eq('Vim(call):E730: Using a List as a String', exc_exec('call inputdialog("", [])')) + eq('Vim(call):E730: Using a List as a String', exc_exec('call inputdialog("", "", [])')) + eq('Vim(call):E730: Using a List as a String', exc_exec('call inputdialog({"prompt": []})')) + eq('Vim(call):E730: Using a List as a String', exc_exec('call inputdialog({"default": []})')) + eq('Vim(call):E730: Using a List as a String', exc_exec('call inputdialog({"completion": []})')) + eq( + 'Vim(call):E5050: {opts} must be the only argument', + exc_exec('call inputdialog({}, "default")') + ) + eq( + 'Vim(call):E118: Too many arguments for function: inputdialog', + exc_exec('call inputdialog("prompt> ", "default", "file", "extra")') + ) end) it('supports highlighting', function() command('nnoremap <expr> X inputdialog({"highlight": "RainBowParens"})[-1]') @@ -441,9 +400,7 @@ describe('inputdialog()', function() feed('(())') screen:expect([[ | - {EOB:~ }| - {EOB:~ }| - {EOB:~ }| + {EOB:~ }|*3 {RBP1:(}{RBP2:()}{RBP1:)}^ | ]]) end) @@ -452,84 +409,91 @@ end) describe('confirm()', function() -- oldtest: Test_confirm() it('works', function() - meths.set_option_value('more', false, {}) -- Avoid hit-enter prompt - meths.set_option_value('laststatus', 2, {}) + api.nvim_set_option_value('more', false, {}) -- Avoid hit-enter prompt + api.nvim_set_option_value('laststatus', 2, {}) -- screen:expect() calls are needed to avoid feeding input too early - screen:expect({any = '%[No Name%]'}) + screen:expect({ any = '%[No Name%]' }) - async_meths.command([[let a = confirm('Press O to proceed')]]) - screen:expect({any = '{CONFIRM:.+: }'}) + async_meths.nvim_command([[let a = confirm('Press O to proceed')]]) + screen:expect({ any = '{CONFIRM:.+: }' }) feed('o') - screen:expect({any = '%[No Name%]'}) - eq(1, meths.get_var('a')) + screen:expect({ any = '%[No Name%]' }) + eq(1, api.nvim_get_var('a')) - async_meths.command([[let a = 'Are you sure?'->confirm("&Yes\n&No")]]) - screen:expect({any = '{CONFIRM:.+: }'}) + async_meths.nvim_command([[let a = 'Are you sure?'->confirm("&Yes\n&No")]]) + screen:expect({ any = '{CONFIRM:.+: }' }) feed('y') - screen:expect({any = '%[No Name%]'}) - eq(1, meths.get_var('a')) + screen:expect({ any = '%[No Name%]' }) + eq(1, api.nvim_get_var('a')) - async_meths.command([[let a = confirm('Are you sure?', "&Yes\n&No")]]) - screen:expect({any = '{CONFIRM:.+: }'}) + async_meths.nvim_command([[let a = confirm('Are you sure?', "&Yes\n&No")]]) + screen:expect({ any = '{CONFIRM:.+: }' }) feed('n') - screen:expect({any = '%[No Name%]'}) - eq(2, meths.get_var('a')) + screen:expect({ any = '%[No Name%]' }) + eq(2, api.nvim_get_var('a')) -- Not possible to match Vim's CTRL-C test here as CTRL-C always sets got_int in Nvim. -- confirm() should return 0 when pressing ESC. - async_meths.command([[let a = confirm('Are you sure?', "&Yes\n&No")]]) - screen:expect({any = '{CONFIRM:.+: }'}) + async_meths.nvim_command([[let a = confirm('Are you sure?', "&Yes\n&No")]]) + screen:expect({ any = '{CONFIRM:.+: }' }) feed('<Esc>') - screen:expect({any = '%[No Name%]'}) - eq(0, meths.get_var('a')) + screen:expect({ any = '%[No Name%]' }) + eq(0, api.nvim_get_var('a')) -- Default choice is returned when pressing <CR>. - async_meths.command([[let a = confirm('Are you sure?', "&Yes\n&No")]]) - screen:expect({any = '{CONFIRM:.+: }'}) + async_meths.nvim_command([[let a = confirm('Are you sure?', "&Yes\n&No")]]) + screen:expect({ any = '{CONFIRM:.+: }' }) feed('<CR>') - screen:expect({any = '%[No Name%]'}) - eq(1, meths.get_var('a')) + screen:expect({ any = '%[No Name%]' }) + eq(1, api.nvim_get_var('a')) - async_meths.command([[let a = confirm('Are you sure?', "&Yes\n&No", 2)]]) - screen:expect({any = '{CONFIRM:.+: }'}) + async_meths.nvim_command([[let a = confirm('Are you sure?', "&Yes\n&No", 2)]]) + screen:expect({ any = '{CONFIRM:.+: }' }) feed('<CR>') - screen:expect({any = '%[No Name%]'}) - eq(2, meths.get_var('a')) + screen:expect({ any = '%[No Name%]' }) + eq(2, api.nvim_get_var('a')) - async_meths.command([[let a = confirm('Are you sure?', "&Yes\n&No", 0)]]) - screen:expect({any = '{CONFIRM:.+: }'}) + async_meths.nvim_command([[let a = confirm('Are you sure?', "&Yes\n&No", 0)]]) + screen:expect({ any = '{CONFIRM:.+: }' }) feed('<CR>') - screen:expect({any = '%[No Name%]'}) - eq(0, meths.get_var('a')) + screen:expect({ any = '%[No Name%]' }) + eq(0, api.nvim_get_var('a')) -- Test with the {type} 4th argument - for _, type in ipairs({'Error', 'Question', 'Info', 'Warning', 'Generic'}) do - async_meths.command(([[let a = confirm('Are you sure?', "&Yes\n&No", 1, '%s')]]):format(type)) - screen:expect({any = '{CONFIRM:.+: }'}) + for _, type in ipairs({ 'Error', 'Question', 'Info', 'Warning', 'Generic' }) do + async_meths.nvim_command( + ([[let a = confirm('Are you sure?', "&Yes\n&No", 1, '%s')]]):format(type) + ) + screen:expect({ any = '{CONFIRM:.+: }' }) feed('y') - screen:expect({any = '%[No Name%]'}) - eq(1, meths.get_var('a')) + screen:expect({ any = '%[No Name%]' }) + eq(1, api.nvim_get_var('a')) end - eq('Vim(call):E730: Using a List as a String', - pcall_err(command, 'call confirm([])')) - eq('Vim(call):E730: Using a List as a String', - pcall_err(command, 'call confirm("Are you sure?", [])')) - eq('Vim(call):E745: Using a List as a Number', - pcall_err(command, 'call confirm("Are you sure?", "&Yes\n&No\n", [])')) - eq('Vim(call):E730: Using a List as a String', - pcall_err(command, 'call confirm("Are you sure?", "&Yes\n&No\n", 0, [])')) + eq('Vim(call):E730: Using a List as a String', pcall_err(command, 'call confirm([])')) + eq( + 'Vim(call):E730: Using a List as a String', + pcall_err(command, 'call confirm("Are you sure?", [])') + ) + eq( + 'Vim(call):E745: Using a List as a Number', + pcall_err(command, 'call confirm("Are you sure?", "&Yes\n&No\n", [])') + ) + eq( + 'Vim(call):E730: Using a List as a String', + pcall_err(command, 'call confirm("Are you sure?", "&Yes\n&No\n", 0, [])') + ) end) - it("shows dialog even if :silent #8788", function() + it('shows dialog even if :silent #8788', function() command("autocmd BufNewFile * call confirm('test')") local function check_and_clear(edit_line) screen:expect([[ | {SEP: }| - ]]..edit_line..[[ + ]] .. edit_line .. [[ {CONFIRM:test} | {CONFIRM:[O]k: }^ | ]]) @@ -556,7 +520,7 @@ describe('confirm()', function() feed(':call nvim_command("edit x")<cr>') check_and_clear(':call nvim_command("edit |\n') - async_meths.command('edit x') + async_meths.nvim_command('edit x') check_and_clear(' |\n') end) end) diff --git a/test/functional/vimscript/json_functions_spec.lua b/test/functional/vimscript/json_functions_spec.lua index a9dab8431c..ef0359263e 100644 --- a/test/functional/vimscript/json_functions_spec.lua +++ b/test/functional/vimscript/json_functions_spec.lua @@ -1,13 +1,13 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local eq = helpers.eq local eval = helpers.eval local command = helpers.command local exc_exec = helpers.exc_exec local pcall_err = helpers.pcall_err -local NIL = helpers.NIL +local NIL = vim.NIL local source = helpers.source describe('json_decode() function', function() @@ -59,467 +59,577 @@ describe('json_decode() function', function() before_each(restart) local speq = function(expected, actual_expr) - eq(1, funcs.EvalEq(expected, actual_expr)) + eq(1, fn.EvalEq(expected, actual_expr)) end it('accepts readfile()-style list', function() - eq({Test=1}, funcs.json_decode({ - '{', - '\t"Test": 1', - '}', - })) + eq( + { Test = 1 }, + fn.json_decode({ + '{', + '\t"Test": 1', + '}', + }) + ) end) it('accepts strings with newlines', function() - eq({Test=1}, funcs.json_decode([[ + eq( + { Test = 1 }, + fn.json_decode([[ { "Test": 1 } - ]])) + ]]) + ) end) it('parses null, true, false', function() - eq(NIL, funcs.json_decode('null')) - eq(true, funcs.json_decode('true')) - eq(false, funcs.json_decode('false')) + eq(NIL, fn.json_decode('null')) + eq(true, fn.json_decode('true')) + eq(false, fn.json_decode('false')) end) it('fails to parse incomplete null, true, false', function() - eq('Vim(call):E474: Expected null: n', - exc_exec('call json_decode("n")')) - eq('Vim(call):E474: Expected null: nu', - exc_exec('call json_decode("nu")')) - eq('Vim(call):E474: Expected null: nul', - exc_exec('call json_decode("nul")')) - eq('Vim(call):E474: Expected null: nul\n\t', - exc_exec('call json_decode("nul\\n\\t")')) - - eq('Vim(call):E474: Expected true: t', - exc_exec('call json_decode("t")')) - eq('Vim(call):E474: Expected true: tr', - exc_exec('call json_decode("tr")')) - eq('Vim(call):E474: Expected true: tru', - exc_exec('call json_decode("tru")')) - eq('Vim(call):E474: Expected true: tru\t\n', - exc_exec('call json_decode("tru\\t\\n")')) - - eq('Vim(call):E474: Expected false: f', - exc_exec('call json_decode("f")')) - eq('Vim(call):E474: Expected false: fa', - exc_exec('call json_decode("fa")')) - eq('Vim(call):E474: Expected false: fal', - exc_exec('call json_decode("fal")')) - eq('Vim(call):E474: Expected false: fal <', - exc_exec('call json_decode(" fal <")')) - eq('Vim(call):E474: Expected false: fals', - exc_exec('call json_decode("fals")')) + eq('Vim(call):E474: Expected null: n', exc_exec('call json_decode("n")')) + eq('Vim(call):E474: Expected null: nu', exc_exec('call json_decode("nu")')) + eq('Vim(call):E474: Expected null: nul', exc_exec('call json_decode("nul")')) + eq('Vim(call):E474: Expected null: nul\n\t', exc_exec('call json_decode("nul\\n\\t")')) + + eq('Vim(call):E474: Expected true: t', exc_exec('call json_decode("t")')) + eq('Vim(call):E474: Expected true: tr', exc_exec('call json_decode("tr")')) + eq('Vim(call):E474: Expected true: tru', exc_exec('call json_decode("tru")')) + eq('Vim(call):E474: Expected true: tru\t\n', exc_exec('call json_decode("tru\\t\\n")')) + + eq('Vim(call):E474: Expected false: f', exc_exec('call json_decode("f")')) + eq('Vim(call):E474: Expected false: fa', exc_exec('call json_decode("fa")')) + eq('Vim(call):E474: Expected false: fal', exc_exec('call json_decode("fal")')) + eq('Vim(call):E474: Expected false: fal <', exc_exec('call json_decode(" fal <")')) + eq('Vim(call):E474: Expected false: fals', exc_exec('call json_decode("fals")')) end) it('parses integer numbers', function() - eq(100000, funcs.json_decode('100000')) - eq(-100000, funcs.json_decode('-100000')) - eq(100000, funcs.json_decode(' 100000 ')) - eq(-100000, funcs.json_decode(' -100000 ')) - eq(0, funcs.json_decode('0')) - eq(0, funcs.json_decode('-0')) + eq(100000, fn.json_decode('100000')) + eq(-100000, fn.json_decode('-100000')) + eq(100000, fn.json_decode(' 100000 ')) + eq(-100000, fn.json_decode(' -100000 ')) + eq(0, fn.json_decode('0')) + eq(0, fn.json_decode('-0')) end) it('fails to parse +numbers and .number', function() - eq('Vim(call):E474: Unidentified byte: +1000', - exc_exec('call json_decode("+1000")')) - eq('Vim(call):E474: Unidentified byte: .1000', - exc_exec('call json_decode(".1000")')) + eq('Vim(call):E474: Unidentified byte: +1000', exc_exec('call json_decode("+1000")')) + eq('Vim(call):E474: Unidentified byte: .1000', exc_exec('call json_decode(".1000")')) end) it('fails to parse numbers with leading zeroes', function() - eq('Vim(call):E474: Leading zeroes are not allowed: 00.1', - exc_exec('call json_decode("00.1")')) - eq('Vim(call):E474: Leading zeroes are not allowed: 01', - exc_exec('call json_decode("01")')) - eq('Vim(call):E474: Leading zeroes are not allowed: -01', - exc_exec('call json_decode("-01")')) - eq('Vim(call):E474: Leading zeroes are not allowed: -001.0', - exc_exec('call json_decode("-001.0")')) + eq('Vim(call):E474: Leading zeroes are not allowed: 00.1', exc_exec('call json_decode("00.1")')) + eq('Vim(call):E474: Leading zeroes are not allowed: 01', exc_exec('call json_decode("01")')) + eq('Vim(call):E474: Leading zeroes are not allowed: -01', exc_exec('call json_decode("-01")')) + eq( + 'Vim(call):E474: Leading zeroes are not allowed: -001.0', + exc_exec('call json_decode("-001.0")') + ) end) it('fails to parse incomplete numbers', function() - eq('Vim(call):E474: Missing number after minus sign: -.1', - exc_exec('call json_decode("-.1")')) - eq('Vim(call):E474: Missing number after minus sign: -', - exc_exec('call json_decode("-")')) - eq('Vim(call):E474: Missing number after decimal dot: -1.', - exc_exec('call json_decode("-1.")')) - eq('Vim(call):E474: Missing number after decimal dot: 0.', - exc_exec('call json_decode("0.")')) - eq('Vim(call):E474: Missing exponent: 0.0e', - exc_exec('call json_decode("0.0e")')) - eq('Vim(call):E474: Missing exponent: 0.0e+', - exc_exec('call json_decode("0.0e+")')) - eq('Vim(call):E474: Missing exponent: 0.0e-', - exc_exec('call json_decode("0.0e-")')) - eq('Vim(call):E474: Missing exponent: 0.0e-', - exc_exec('call json_decode("0.0e-")')) - eq('Vim(call):E474: Missing number after decimal dot: 1.e5', - exc_exec('call json_decode("1.e5")')) - eq('Vim(call):E474: Missing number after decimal dot: 1.e+5', - exc_exec('call json_decode("1.e+5")')) - eq('Vim(call):E474: Missing number after decimal dot: 1.e+', - exc_exec('call json_decode("1.e+")')) + eq('Vim(call):E474: Missing number after minus sign: -.1', exc_exec('call json_decode("-.1")')) + eq('Vim(call):E474: Missing number after minus sign: -', exc_exec('call json_decode("-")')) + eq('Vim(call):E474: Missing number after decimal dot: -1.', exc_exec('call json_decode("-1.")')) + eq('Vim(call):E474: Missing number after decimal dot: 0.', exc_exec('call json_decode("0.")')) + eq('Vim(call):E474: Missing exponent: 0.0e', exc_exec('call json_decode("0.0e")')) + eq('Vim(call):E474: Missing exponent: 0.0e+', exc_exec('call json_decode("0.0e+")')) + eq('Vim(call):E474: Missing exponent: 0.0e-', exc_exec('call json_decode("0.0e-")')) + eq('Vim(call):E474: Missing exponent: 0.0e-', exc_exec('call json_decode("0.0e-")')) + eq( + 'Vim(call):E474: Missing number after decimal dot: 1.e5', + exc_exec('call json_decode("1.e5")') + ) + eq( + 'Vim(call):E474: Missing number after decimal dot: 1.e+5', + exc_exec('call json_decode("1.e+5")') + ) + eq( + 'Vim(call):E474: Missing number after decimal dot: 1.e+', + exc_exec('call json_decode("1.e+")') + ) end) it('parses floating-point numbers', function() -- Also test method call (->) syntax eq('100000.0', eval('"100000.0"->json_decode()->string()')) - eq(100000.5, funcs.json_decode('100000.5')) - eq(-100000.5, funcs.json_decode('-100000.5')) - eq(-100000.5e50, funcs.json_decode('-100000.5e50')) - eq(100000.5e50, funcs.json_decode('100000.5e50')) - eq(100000.5e50, funcs.json_decode('100000.5e+50')) - eq(-100000.5e-50, funcs.json_decode('-100000.5e-50')) - eq(100000.5e-50, funcs.json_decode('100000.5e-50')) - eq(100000e-50, funcs.json_decode('100000e-50')) - eq(0.5, funcs.json_decode('0.5')) - eq(0.005, funcs.json_decode('0.005')) - eq(0.005, funcs.json_decode('0.00500')) - eq(0.5, funcs.json_decode('0.00500e+002')) - eq(0.00005, funcs.json_decode('0.00500e-002')) - - eq(-0.0, funcs.json_decode('-0.0')) - eq(-0.0, funcs.json_decode('-0.0e0')) - eq(-0.0, funcs.json_decode('-0.0e+0')) - eq(-0.0, funcs.json_decode('-0.0e-0')) - eq(-0.0, funcs.json_decode('-0e-0')) - eq(-0.0, funcs.json_decode('-0e-2')) - eq(-0.0, funcs.json_decode('-0e+2')) - - eq(0.0, funcs.json_decode('0.0')) - eq(0.0, funcs.json_decode('0.0e0')) - eq(0.0, funcs.json_decode('0.0e+0')) - eq(0.0, funcs.json_decode('0.0e-0')) - eq(0.0, funcs.json_decode('0e-0')) - eq(0.0, funcs.json_decode('0e-2')) - eq(0.0, funcs.json_decode('0e+2')) + eq(100000.5, fn.json_decode('100000.5')) + eq(-100000.5, fn.json_decode('-100000.5')) + eq(-100000.5e50, fn.json_decode('-100000.5e50')) + eq(100000.5e50, fn.json_decode('100000.5e50')) + eq(100000.5e50, fn.json_decode('100000.5e+50')) + eq(-100000.5e-50, fn.json_decode('-100000.5e-50')) + eq(100000.5e-50, fn.json_decode('100000.5e-50')) + eq(100000e-50, fn.json_decode('100000e-50')) + eq(0.5, fn.json_decode('0.5')) + eq(0.005, fn.json_decode('0.005')) + eq(0.005, fn.json_decode('0.00500')) + eq(0.5, fn.json_decode('0.00500e+002')) + eq(0.00005, fn.json_decode('0.00500e-002')) + + eq(-0.0, fn.json_decode('-0.0')) + eq(-0.0, fn.json_decode('-0.0e0')) + eq(-0.0, fn.json_decode('-0.0e+0')) + eq(-0.0, fn.json_decode('-0.0e-0')) + eq(-0.0, fn.json_decode('-0e-0')) + eq(-0.0, fn.json_decode('-0e-2')) + eq(-0.0, fn.json_decode('-0e+2')) + + eq(0.0, fn.json_decode('0.0')) + eq(0.0, fn.json_decode('0.0e0')) + eq(0.0, fn.json_decode('0.0e+0')) + eq(0.0, fn.json_decode('0.0e-0')) + eq(0.0, fn.json_decode('0e-0')) + eq(0.0, fn.json_decode('0e-2')) + eq(0.0, fn.json_decode('0e+2')) end) it('fails to parse numbers with spaces inside', function() - eq('Vim(call):E474: Missing number after minus sign: - 1000', - exc_exec('call json_decode("- 1000")')) - eq('Vim(call):E474: Missing number after decimal dot: 0. ', - exc_exec('call json_decode("0. ")')) - eq('Vim(call):E474: Missing number after decimal dot: 0. 0', - exc_exec('call json_decode("0. 0")')) - eq('Vim(call):E474: Missing exponent: 0.0e 1', - exc_exec('call json_decode("0.0e 1")')) - eq('Vim(call):E474: Missing exponent: 0.0e+ 1', - exc_exec('call json_decode("0.0e+ 1")')) - eq('Vim(call):E474: Missing exponent: 0.0e- 1', - exc_exec('call json_decode("0.0e- 1")')) + eq( + 'Vim(call):E474: Missing number after minus sign: - 1000', + exc_exec('call json_decode("- 1000")') + ) + eq('Vim(call):E474: Missing number after decimal dot: 0. ', exc_exec('call json_decode("0. ")')) + eq( + 'Vim(call):E474: Missing number after decimal dot: 0. 0', + exc_exec('call json_decode("0. 0")') + ) + eq('Vim(call):E474: Missing exponent: 0.0e 1', exc_exec('call json_decode("0.0e 1")')) + eq('Vim(call):E474: Missing exponent: 0.0e+ 1', exc_exec('call json_decode("0.0e+ 1")')) + eq('Vim(call):E474: Missing exponent: 0.0e- 1', exc_exec('call json_decode("0.0e- 1")')) end) it('fails to parse "," and ":"', function() - eq('Vim(call):E474: Comma not inside container: , ', - exc_exec('call json_decode(" , ")')) - eq('Vim(call):E474: Colon not inside container: : ', - exc_exec('call json_decode(" : ")')) + eq('Vim(call):E474: Comma not inside container: , ', exc_exec('call json_decode(" , ")')) + eq('Vim(call):E474: Colon not inside container: : ', exc_exec('call json_decode(" : ")')) end) it('parses empty containers', function() - eq({}, funcs.json_decode('[]')) + eq({}, fn.json_decode('[]')) eq('[]', eval('string(json_decode("[]"))')) end) it('fails to parse "[" and "{"', function() - eq('Vim(call):E474: Unexpected end of input: {', - exc_exec('call json_decode("{")')) - eq('Vim(call):E474: Unexpected end of input: [', - exc_exec('call json_decode("[")')) + eq('Vim(call):E474: Unexpected end of input: {', exc_exec('call json_decode("{")')) + eq('Vim(call):E474: Unexpected end of input: [', exc_exec('call json_decode("[")')) end) it('fails to parse "}" and "]"', function() - eq('Vim(call):E474: No container to close: ]', - exc_exec('call json_decode("]")')) - eq('Vim(call):E474: No container to close: }', - exc_exec('call json_decode("}")')) + eq('Vim(call):E474: No container to close: ]', exc_exec('call json_decode("]")')) + eq('Vim(call):E474: No container to close: }', exc_exec('call json_decode("}")')) end) - it('fails to parse containers which are closed by different brackets', - function() - eq('Vim(call):E474: Closing dictionary with square bracket: ]', - exc_exec('call json_decode("{]")')) - eq('Vim(call):E474: Closing list with curly bracket: }', - exc_exec('call json_decode("[}")')) + it('fails to parse containers which are closed by different brackets', function() + eq( + 'Vim(call):E474: Closing dictionary with square bracket: ]', + exc_exec('call json_decode("{]")') + ) + eq('Vim(call):E474: Closing list with curly bracket: }', exc_exec('call json_decode("[}")')) end) it('fails to parse concat inside container', function() - eq('Vim(call):E474: Expected comma before list item: []]', - exc_exec('call json_decode("[[][]]")')) - eq('Vim(call):E474: Expected comma before list item: {}]', - exc_exec('call json_decode("[{}{}]")')) - eq('Vim(call):E474: Expected comma before list item: ]', - exc_exec('call json_decode("[1 2]")')) - eq('Vim(call):E474: Expected comma before dictionary key: ": 4}', - exc_exec('call json_decode("{\\"1\\": 2 \\"3\\": 4}")')) - eq('Vim(call):E474: Expected colon before dictionary value: , "3" 4}', - exc_exec('call json_decode("{\\"1\\" 2, \\"3\\" 4}")')) + eq( + 'Vim(call):E474: Expected comma before list item: []]', + exc_exec('call json_decode("[[][]]")') + ) + eq( + 'Vim(call):E474: Expected comma before list item: {}]', + exc_exec('call json_decode("[{}{}]")') + ) + eq('Vim(call):E474: Expected comma before list item: ]', exc_exec('call json_decode("[1 2]")')) + eq( + 'Vim(call):E474: Expected comma before dictionary key: ": 4}', + exc_exec('call json_decode("{\\"1\\": 2 \\"3\\": 4}")') + ) + eq( + 'Vim(call):E474: Expected colon before dictionary value: , "3" 4}', + exc_exec('call json_decode("{\\"1\\" 2, \\"3\\" 4}")') + ) end) it('fails to parse containers with leading comma or colon', function() - eq('Vim(call):E474: Leading comma: ,}', - exc_exec('call json_decode("{,}")')) - eq('Vim(call):E474: Leading comma: ,]', - exc_exec('call json_decode("[,]")')) - eq('Vim(call):E474: Using colon not in dictionary: :]', - exc_exec('call json_decode("[:]")')) - eq('Vim(call):E474: Unexpected colon: :}', - exc_exec('call json_decode("{:}")')) + eq('Vim(call):E474: Leading comma: ,}', exc_exec('call json_decode("{,}")')) + eq('Vim(call):E474: Leading comma: ,]', exc_exec('call json_decode("[,]")')) + eq('Vim(call):E474: Using colon not in dictionary: :]', exc_exec('call json_decode("[:]")')) + eq('Vim(call):E474: Unexpected colon: :}', exc_exec('call json_decode("{:}")')) end) it('fails to parse containers with trailing comma', function() - eq('Vim(call):E474: Trailing comma: ]', - exc_exec('call json_decode("[1,]")')) - eq('Vim(call):E474: Trailing comma: }', - exc_exec('call json_decode("{\\"1\\": 2,}")')) + eq('Vim(call):E474: Trailing comma: ]', exc_exec('call json_decode("[1,]")')) + eq('Vim(call):E474: Trailing comma: }', exc_exec('call json_decode("{\\"1\\": 2,}")')) end) it('fails to parse dictionaries with missing value', function() - eq('Vim(call):E474: Expected value after colon: }', - exc_exec('call json_decode("{\\"1\\":}")')) - eq('Vim(call):E474: Expected value: }', - exc_exec('call json_decode("{\\"1\\"}")')) + eq('Vim(call):E474: Expected value after colon: }', exc_exec('call json_decode("{\\"1\\":}")')) + eq('Vim(call):E474: Expected value: }', exc_exec('call json_decode("{\\"1\\"}")')) end) it('fails to parse containers with two commas or colons', function() - eq('Vim(call):E474: Duplicate comma: , "2": 2}', - exc_exec('call json_decode("{\\"1\\": 1,, \\"2\\": 2}")')) - eq('Vim(call):E474: Duplicate comma: , "2", 2]', - exc_exec('call json_decode("[\\"1\\", 1,, \\"2\\", 2]")')) - eq('Vim(call):E474: Duplicate colon: : 2}', - exc_exec('call json_decode("{\\"1\\": 1, \\"2\\":: 2}")')) - eq('Vim(call):E474: Comma after colon: , 2}', - exc_exec('call json_decode("{\\"1\\": 1, \\"2\\":, 2}")')) - eq('Vim(call):E474: Unexpected colon: : "2": 2}', - exc_exec('call json_decode("{\\"1\\": 1,: \\"2\\": 2}")')) - eq('Vim(call):E474: Unexpected colon: :, "2": 2}', - exc_exec('call json_decode("{\\"1\\": 1:, \\"2\\": 2}")')) + eq( + 'Vim(call):E474: Duplicate comma: , "2": 2}', + exc_exec('call json_decode("{\\"1\\": 1,, \\"2\\": 2}")') + ) + eq( + 'Vim(call):E474: Duplicate comma: , "2", 2]', + exc_exec('call json_decode("[\\"1\\", 1,, \\"2\\", 2]")') + ) + eq( + 'Vim(call):E474: Duplicate colon: : 2}', + exc_exec('call json_decode("{\\"1\\": 1, \\"2\\":: 2}")') + ) + eq( + 'Vim(call):E474: Comma after colon: , 2}', + exc_exec('call json_decode("{\\"1\\": 1, \\"2\\":, 2}")') + ) + eq( + 'Vim(call):E474: Unexpected colon: : "2": 2}', + exc_exec('call json_decode("{\\"1\\": 1,: \\"2\\": 2}")') + ) + eq( + 'Vim(call):E474: Unexpected colon: :, "2": 2}', + exc_exec('call json_decode("{\\"1\\": 1:, \\"2\\": 2}")') + ) end) it('fails to parse concat of two values', function() - eq('Vim(call):E474: Trailing characters: []', - exc_exec('call json_decode("{}[]")')) + eq('Vim(call):E474: Trailing characters: []', exc_exec('call json_decode("{}[]")')) end) it('parses containers', function() - eq({1}, funcs.json_decode('[1]')) - eq({NIL, 1}, funcs.json_decode('[null, 1]')) - eq({['1']=2}, funcs.json_decode('{"1": 2}')) - eq({['1']=2, ['3']={{['4']={['5']={{}, 1}}}}}, - funcs.json_decode('{"1": 2, "3": [{"4": {"5": [[], 1]}}]}')) + eq({ 1 }, fn.json_decode('[1]')) + eq({ NIL, 1 }, fn.json_decode('[null, 1]')) + eq({ ['1'] = 2 }, fn.json_decode('{"1": 2}')) + eq( + { ['1'] = 2, ['3'] = { { ['4'] = { ['5'] = { {}, 1 } } } } }, + fn.json_decode('{"1": 2, "3": [{"4": {"5": [[], 1]}}]}') + ) end) it('fails to parse incomplete strings', function() - eq('Vim(call):E474: Expected string end: \t"', - exc_exec('call json_decode("\\t\\"")')) - eq('Vim(call):E474: Expected string end: \t"abc', - exc_exec('call json_decode("\\t\\"abc")')) - eq('Vim(call):E474: Unfinished escape sequence: \t"abc\\', - exc_exec('call json_decode("\\t\\"abc\\\\")')) - eq('Vim(call):E474: Unfinished unicode escape sequence: \t"abc\\u', - exc_exec('call json_decode("\\t\\"abc\\\\u")')) - eq('Vim(call):E474: Unfinished unicode escape sequence: \t"abc\\u0', - exc_exec('call json_decode("\\t\\"abc\\\\u0")')) - eq('Vim(call):E474: Unfinished unicode escape sequence: \t"abc\\u00', - exc_exec('call json_decode("\\t\\"abc\\\\u00")')) - eq('Vim(call):E474: Unfinished unicode escape sequence: \t"abc\\u000', - exc_exec('call json_decode("\\t\\"abc\\\\u000")')) - eq('Vim(call):E474: Expected four hex digits after \\u: \\u" ', - exc_exec('call json_decode("\\t\\"abc\\\\u\\" ")')) - eq('Vim(call):E474: Expected four hex digits after \\u: \\u0" ', - exc_exec('call json_decode("\\t\\"abc\\\\u0\\" ")')) - eq('Vim(call):E474: Expected four hex digits after \\u: \\u00" ', - exc_exec('call json_decode("\\t\\"abc\\\\u00\\" ")')) - eq('Vim(call):E474: Expected four hex digits after \\u: \\u000" ', - exc_exec('call json_decode("\\t\\"abc\\\\u000\\" ")')) - eq('Vim(call):E474: Expected string end: \t"abc\\u0000', - exc_exec('call json_decode("\\t\\"abc\\\\u0000")')) + eq('Vim(call):E474: Expected string end: \t"', exc_exec('call json_decode("\\t\\"")')) + eq('Vim(call):E474: Expected string end: \t"abc', exc_exec('call json_decode("\\t\\"abc")')) + eq( + 'Vim(call):E474: Unfinished escape sequence: \t"abc\\', + exc_exec('call json_decode("\\t\\"abc\\\\")') + ) + eq( + 'Vim(call):E474: Unfinished unicode escape sequence: \t"abc\\u', + exc_exec('call json_decode("\\t\\"abc\\\\u")') + ) + eq( + 'Vim(call):E474: Unfinished unicode escape sequence: \t"abc\\u0', + exc_exec('call json_decode("\\t\\"abc\\\\u0")') + ) + eq( + 'Vim(call):E474: Unfinished unicode escape sequence: \t"abc\\u00', + exc_exec('call json_decode("\\t\\"abc\\\\u00")') + ) + eq( + 'Vim(call):E474: Unfinished unicode escape sequence: \t"abc\\u000', + exc_exec('call json_decode("\\t\\"abc\\\\u000")') + ) + eq( + 'Vim(call):E474: Expected four hex digits after \\u: \\u" ', + exc_exec('call json_decode("\\t\\"abc\\\\u\\" ")') + ) + eq( + 'Vim(call):E474: Expected four hex digits after \\u: \\u0" ', + exc_exec('call json_decode("\\t\\"abc\\\\u0\\" ")') + ) + eq( + 'Vim(call):E474: Expected four hex digits after \\u: \\u00" ', + exc_exec('call json_decode("\\t\\"abc\\\\u00\\" ")') + ) + eq( + 'Vim(call):E474: Expected four hex digits after \\u: \\u000" ', + exc_exec('call json_decode("\\t\\"abc\\\\u000\\" ")') + ) + eq( + 'Vim(call):E474: Expected string end: \t"abc\\u0000', + exc_exec('call json_decode("\\t\\"abc\\\\u0000")') + ) end) it('fails to parse unknown escape sequences', function() - eq('Vim(call):E474: Unknown escape sequence: \\a"', - exc_exec('call json_decode("\\t\\"\\\\a\\"")')) + eq( + 'Vim(call):E474: Unknown escape sequence: \\a"', + exc_exec('call json_decode("\\t\\"\\\\a\\"")') + ) end) it('parses strings properly', function() - eq('\n', funcs.json_decode('"\\n"')) - eq('', funcs.json_decode('""')) - eq('\\/"\t\b\n\r\f', funcs.json_decode([["\\\/\"\t\b\n\r\f"]])) - eq('/a', funcs.json_decode([["\/a"]])) + eq('\n', fn.json_decode('"\\n"')) + eq('', fn.json_decode('""')) + eq('\\/"\t\b\n\r\f', fn.json_decode([["\\\/\"\t\b\n\r\f"]])) + eq('/a', fn.json_decode([["\/a"]])) -- Unicode characters: 2-byte, 3-byte, 4-byte - eq({ - '«', - 'ફ', - '\240\144\128\128', - }, funcs.json_decode({ - '[', - '"«",', - '"ફ",', - '"\240\144\128\128"', - ']', - })) + eq( + { + '«', + 'ફ', + '\240\144\128\128', + }, + fn.json_decode({ + '[', + '"«",', + '"ફ",', + '"\240\144\128\128"', + ']', + }) + ) end) it('fails on strings with invalid bytes', function() - eq('Vim(call):E474: Only UTF-8 strings allowed: \255"', - exc_exec('call json_decode("\\t\\"\\xFF\\"")')) - eq('Vim(call):E474: ASCII control characters cannot be present inside string: ', - exc_exec('call json_decode(["\\"\\n\\""])')) + eq( + 'Vim(call):E474: Only UTF-8 strings allowed: \255"', + exc_exec('call json_decode("\\t\\"\\xFF\\"")') + ) + eq( + 'Vim(call):E474: ASCII control characters cannot be present inside string: ', + exc_exec('call json_decode(["\\"\\n\\""])') + ) -- 0xC2 starts 2-byte unicode character - eq('Vim(call):E474: Only UTF-8 strings allowed: \194"', - exc_exec('call json_decode("\\t\\"\\xC2\\"")')) + eq( + 'Vim(call):E474: Only UTF-8 strings allowed: \194"', + exc_exec('call json_decode("\\t\\"\\xC2\\"")') + ) -- 0xE0 0xAA starts 3-byte unicode character - eq('Vim(call):E474: Only UTF-8 strings allowed: \224"', - exc_exec('call json_decode("\\t\\"\\xE0\\"")')) - eq('Vim(call):E474: Only UTF-8 strings allowed: \224\170"', - exc_exec('call json_decode("\\t\\"\\xE0\\xAA\\"")')) + eq( + 'Vim(call):E474: Only UTF-8 strings allowed: \224"', + exc_exec('call json_decode("\\t\\"\\xE0\\"")') + ) + eq( + 'Vim(call):E474: Only UTF-8 strings allowed: \224\170"', + exc_exec('call json_decode("\\t\\"\\xE0\\xAA\\"")') + ) -- 0xF0 0x90 0x80 starts 4-byte unicode character - eq('Vim(call):E474: Only UTF-8 strings allowed: \240"', - exc_exec('call json_decode("\\t\\"\\xF0\\"")')) - eq('Vim(call):E474: Only UTF-8 strings allowed: \240\144"', - exc_exec('call json_decode("\\t\\"\\xF0\\x90\\"")')) - eq('Vim(call):E474: Only UTF-8 strings allowed: \240\144\128"', - exc_exec('call json_decode("\\t\\"\\xF0\\x90\\x80\\"")')) + eq( + 'Vim(call):E474: Only UTF-8 strings allowed: \240"', + exc_exec('call json_decode("\\t\\"\\xF0\\"")') + ) + eq( + 'Vim(call):E474: Only UTF-8 strings allowed: \240\144"', + exc_exec('call json_decode("\\t\\"\\xF0\\x90\\"")') + ) + eq( + 'Vim(call):E474: Only UTF-8 strings allowed: \240\144\128"', + exc_exec('call json_decode("\\t\\"\\xF0\\x90\\x80\\"")') + ) -- 0xF9 0x80 0x80 0x80 starts 5-byte unicode character - eq('Vim(call):E474: Only UTF-8 strings allowed: \249"', - exc_exec('call json_decode("\\t\\"\\xF9\\"")')) - eq('Vim(call):E474: Only UTF-8 strings allowed: \249\128"', - exc_exec('call json_decode("\\t\\"\\xF9\\x80\\"")')) - eq('Vim(call):E474: Only UTF-8 strings allowed: \249\128\128"', - exc_exec('call json_decode("\\t\\"\\xF9\\x80\\x80\\"")')) - eq('Vim(call):E474: Only UTF-8 strings allowed: \249\128\128\128"', - exc_exec('call json_decode("\\t\\"\\xF9\\x80\\x80\\x80\\"")')) + eq( + 'Vim(call):E474: Only UTF-8 strings allowed: \249"', + exc_exec('call json_decode("\\t\\"\\xF9\\"")') + ) + eq( + 'Vim(call):E474: Only UTF-8 strings allowed: \249\128"', + exc_exec('call json_decode("\\t\\"\\xF9\\x80\\"")') + ) + eq( + 'Vim(call):E474: Only UTF-8 strings allowed: \249\128\128"', + exc_exec('call json_decode("\\t\\"\\xF9\\x80\\x80\\"")') + ) + eq( + 'Vim(call):E474: Only UTF-8 strings allowed: \249\128\128\128"', + exc_exec('call json_decode("\\t\\"\\xF9\\x80\\x80\\x80\\"")') + ) -- 0xFC 0x90 0x80 0x80 0x80 starts 6-byte unicode character - eq('Vim(call):E474: Only UTF-8 strings allowed: \252"', - exc_exec('call json_decode("\\t\\"\\xFC\\"")')) - eq('Vim(call):E474: Only UTF-8 strings allowed: \252\144"', - exc_exec('call json_decode("\\t\\"\\xFC\\x90\\"")')) - eq('Vim(call):E474: Only UTF-8 strings allowed: \252\144\128"', - exc_exec('call json_decode("\\t\\"\\xFC\\x90\\x80\\"")')) - eq('Vim(call):E474: Only UTF-8 strings allowed: \252\144\128\128"', - exc_exec('call json_decode("\\t\\"\\xFC\\x90\\x80\\x80\\"")')) - eq('Vim(call):E474: Only UTF-8 strings allowed: \252\144\128\128\128"', - exc_exec('call json_decode("\\t\\"\\xFC\\x90\\x80\\x80\\x80\\"")')) + eq( + 'Vim(call):E474: Only UTF-8 strings allowed: \252"', + exc_exec('call json_decode("\\t\\"\\xFC\\"")') + ) + eq( + 'Vim(call):E474: Only UTF-8 strings allowed: \252\144"', + exc_exec('call json_decode("\\t\\"\\xFC\\x90\\"")') + ) + eq( + 'Vim(call):E474: Only UTF-8 strings allowed: \252\144\128"', + exc_exec('call json_decode("\\t\\"\\xFC\\x90\\x80\\"")') + ) + eq( + 'Vim(call):E474: Only UTF-8 strings allowed: \252\144\128\128"', + exc_exec('call json_decode("\\t\\"\\xFC\\x90\\x80\\x80\\"")') + ) + eq( + 'Vim(call):E474: Only UTF-8 strings allowed: \252\144\128\128\128"', + exc_exec('call json_decode("\\t\\"\\xFC\\x90\\x80\\x80\\x80\\"")') + ) -- Specification does not allow unquoted characters above 0x10FFFF - eq('Vim(call):E474: Only UTF-8 code points up to U+10FFFF are allowed to appear unescaped: \249\128\128\128\128"', - exc_exec('call json_decode("\\t\\"\\xF9\\x80\\x80\\x80\\x80\\"")')) - eq('Vim(call):E474: Only UTF-8 code points up to U+10FFFF are allowed to appear unescaped: \252\144\128\128\128\128"', - exc_exec('call json_decode("\\t\\"\\xFC\\x90\\x80\\x80\\x80\\x80\\"")')) + eq( + 'Vim(call):E474: Only UTF-8 code points up to U+10FFFF are allowed to appear unescaped: \249\128\128\128\128"', + exc_exec('call json_decode("\\t\\"\\xF9\\x80\\x80\\x80\\x80\\"")') + ) + eq( + 'Vim(call):E474: Only UTF-8 code points up to U+10FFFF are allowed to appear unescaped: \252\144\128\128\128\128"', + exc_exec('call json_decode("\\t\\"\\xFC\\x90\\x80\\x80\\x80\\x80\\"")') + ) -- '"\249\128\128\128\128"', -- '"\252\144\128\128\128\128"', end) it('parses surrogate pairs properly', function() - eq('\240\144\128\128', funcs.json_decode('"\\uD800\\uDC00"')) - eq('\237\160\128a\237\176\128', funcs.json_decode('"\\uD800a\\uDC00"')) - eq('\237\160\128\t\237\176\128', funcs.json_decode('"\\uD800\\t\\uDC00"')) + eq('\240\144\128\128', fn.json_decode('"\\uD800\\uDC00"')) + eq('\237\160\128a\237\176\128', fn.json_decode('"\\uD800a\\uDC00"')) + eq('\237\160\128\t\237\176\128', fn.json_decode('"\\uD800\\t\\uDC00"')) - eq('\237\160\128', funcs.json_decode('"\\uD800"')) - eq('\237\160\128a', funcs.json_decode('"\\uD800a"')) - eq('\237\160\128\t', funcs.json_decode('"\\uD800\\t"')) + eq('\237\160\128', fn.json_decode('"\\uD800"')) + eq('\237\160\128a', fn.json_decode('"\\uD800a"')) + eq('\237\160\128\t', fn.json_decode('"\\uD800\\t"')) - eq('\237\176\128', funcs.json_decode('"\\uDC00"')) - eq('\237\176\128a', funcs.json_decode('"\\uDC00a"')) - eq('\237\176\128\t', funcs.json_decode('"\\uDC00\\t"')) + eq('\237\176\128', fn.json_decode('"\\uDC00"')) + eq('\237\176\128a', fn.json_decode('"\\uDC00a"')) + eq('\237\176\128\t', fn.json_decode('"\\uDC00\\t"')) - eq('\237\176\128', funcs.json_decode('"\\uDC00"')) - eq('a\237\176\128', funcs.json_decode('"a\\uDC00"')) - eq('\t\237\176\128', funcs.json_decode('"\\t\\uDC00"')) + eq('\237\176\128', fn.json_decode('"\\uDC00"')) + eq('a\237\176\128', fn.json_decode('"a\\uDC00"')) + eq('\t\237\176\128', fn.json_decode('"\\t\\uDC00"')) - eq('\237\160\128¬', funcs.json_decode('"\\uD800\\u00AC"')) + eq('\237\160\128¬', fn.json_decode('"\\uD800\\u00AC"')) - eq('\237\160\128\237\160\128', funcs.json_decode('"\\uD800\\uD800"')) + eq('\237\160\128\237\160\128', fn.json_decode('"\\uD800\\uD800"')) end) local sp_decode_eq = function(expected, json) - meths.set_var('__json', json) + api.nvim_set_var('__json', json) speq(expected, 'json_decode(g:__json)') command('unlet! g:__json') end it('parses strings with NUL properly', function() - sp_decode_eq({_TYPE='string', _VAL={'\n'}}, '"\\u0000"') - sp_decode_eq({_TYPE='string', _VAL={'\n', '\n'}}, '"\\u0000\\n\\u0000"') - sp_decode_eq({_TYPE='string', _VAL={'\n«\n'}}, '"\\u0000\\u00AB\\u0000"') + sp_decode_eq({ _TYPE = 'string', _VAL = { '\n' } }, '"\\u0000"') + sp_decode_eq({ _TYPE = 'string', _VAL = { '\n', '\n' } }, '"\\u0000\\n\\u0000"') + sp_decode_eq({ _TYPE = 'string', _VAL = { '\n«\n' } }, '"\\u0000\\u00AB\\u0000"') end) it('parses dictionaries with duplicate keys to special maps', function() - sp_decode_eq({_TYPE='map', _VAL={{'a', 1}, {'a', 2}}}, - '{"a": 1, "a": 2}') - sp_decode_eq({_TYPE='map', _VAL={{'b', 3}, {'a', 1}, {'a', 2}}}, - '{"b": 3, "a": 1, "a": 2}') - sp_decode_eq({_TYPE='map', _VAL={{'b', 3}, {'a', 1}, {'c', 4}, {'a', 2}}}, - '{"b": 3, "a": 1, "c": 4, "a": 2}') - sp_decode_eq({_TYPE='map', _VAL={{'b', 3}, {'a', 1}, {'c', 4}, {'a', 2}, {'c', 4}}}, - '{"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}') - sp_decode_eq({{_TYPE='map', _VAL={{'b', 3}, {'a', 1}, {'c', 4}, {'a', 2}, {'c', 4}}}}, - '[{"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}]') - sp_decode_eq({{d={_TYPE='map', _VAL={{'b', 3}, {'a', 1}, {'c', 4}, {'a', 2}, {'c', 4}}}}}, - '[{"d": {"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}}]') - sp_decode_eq({1, {d={_TYPE='map', _VAL={{'b', 3}, {'a', 1}, {'c', 4}, {'a', 2}, {'c', 4}}}}}, - '[1, {"d": {"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}}]') - sp_decode_eq({1, {a={}, d={_TYPE='map', _VAL={{'b', 3}, {'a', 1}, {'c', 4}, {'a', 2}, {'c', 4}}}}}, - '[1, {"a": [], "d": {"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}}]') - end) - - it('parses dictionaries with empty keys to special maps', function() - sp_decode_eq({_TYPE='map', _VAL={{'', 4}}}, - '{"": 4}') - sp_decode_eq({_TYPE='map', _VAL={{'b', 3}, {'a', 1}, {'c', 4}, {'d', 2}, {'', 4}}}, - '{"b": 3, "a": 1, "c": 4, "d": 2, "": 4}') - sp_decode_eq({_TYPE='map', _VAL={{'', 3}, {'a', 1}, {'c', 4}, {'d', 2}, {'', 4}}}, - '{"": 3, "a": 1, "c": 4, "d": 2, "": 4}') - sp_decode_eq({{_TYPE='map', _VAL={{'', 3}, {'a', 1}, {'c', 4}, {'d', 2}, {'', 4}}}}, - '[{"": 3, "a": 1, "c": 4, "d": 2, "": 4}]') + sp_decode_eq({ _TYPE = 'map', _VAL = { { 'a', 1 }, { 'a', 2 } } }, '{"a": 1, "a": 2}') + sp_decode_eq( + { _TYPE = 'map', _VAL = { { 'b', 3 }, { 'a', 1 }, { 'a', 2 } } }, + '{"b": 3, "a": 1, "a": 2}' + ) + sp_decode_eq( + { _TYPE = 'map', _VAL = { { 'b', 3 }, { 'a', 1 }, { 'c', 4 }, { 'a', 2 } } }, + '{"b": 3, "a": 1, "c": 4, "a": 2}' + ) + sp_decode_eq( + { _TYPE = 'map', _VAL = { { 'b', 3 }, { 'a', 1 }, { 'c', 4 }, { 'a', 2 }, { 'c', 4 } } }, + '{"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}' + ) + sp_decode_eq( + { { _TYPE = 'map', _VAL = { { 'b', 3 }, { 'a', 1 }, { 'c', 4 }, { 'a', 2 }, { 'c', 4 } } } }, + '[{"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}]' + ) + sp_decode_eq({ + { + d = { + _TYPE = 'map', + _VAL = { { 'b', 3 }, { 'a', 1 }, { 'c', 4 }, { 'a', 2 }, { 'c', 4 } }, + }, + }, + }, '[{"d": {"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}}]') + sp_decode_eq({ + 1, + { + d = { + _TYPE = 'map', + _VAL = { { 'b', 3 }, { 'a', 1 }, { 'c', 4 }, { 'a', 2 }, { 'c', 4 } }, + }, + }, + }, '[1, {"d": {"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}}]') + sp_decode_eq({ + 1, + { + a = {}, + d = { + _TYPE = 'map', + _VAL = { + { 'b', 3 }, + { 'a', 1 }, + { 'c', 4 }, + { 'a', 2 }, + { + 'c', + 4, + }, + }, + }, + }, + }, '[1, {"a": [], "d": {"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}}]') + sp_decode_eq( + { _TYPE = 'map', _VAL = { { '', 3 }, { 'a', 1 }, { 'c', 4 }, { 'd', 2 }, { '', 4 } } }, + '{"": 3, "a": 1, "c": 4, "d": 2, "": 4}' + ) + sp_decode_eq( + { { _TYPE = 'map', _VAL = { { '', 3 }, { 'a', 1 }, { 'c', 4 }, { 'd', 2 }, { '', 4 } } } }, + '[{"": 3, "a": 1, "c": 4, "d": 2, "": 4}]' + ) + end) + + it('parses dictionaries with empty keys', function() + eq({ [''] = 4 }, fn.json_decode('{"": 4}')) + eq( + { b = 3, a = 1, c = 4, d = 2, [''] = 4 }, + fn.json_decode('{"b": 3, "a": 1, "c": 4, "d": 2, "": 4}') + ) end) it('parses dictionaries with keys with NUL bytes to special maps', function() - sp_decode_eq({_TYPE='map', _VAL={{{_TYPE='string', _VAL={'a\n', 'b'}}, 4}}}, - '{"a\\u0000\\nb": 4}') - sp_decode_eq({_TYPE='map', _VAL={{{_TYPE='string', _VAL={'a\n', 'b', ''}}, 4}}}, - '{"a\\u0000\\nb\\n": 4}') - sp_decode_eq({_TYPE='map', _VAL={{'b', 3}, {'a', 1}, {'c', 4}, {'d', 2}, {{_TYPE='string', _VAL={'\n'}}, 4}}}, - '{"b": 3, "a": 1, "c": 4, "d": 2, "\\u0000": 4}') + sp_decode_eq( + { _TYPE = 'map', _VAL = { { { _TYPE = 'string', _VAL = { 'a\n', 'b' } }, 4 } } }, + '{"a\\u0000\\nb": 4}' + ) + sp_decode_eq( + { _TYPE = 'map', _VAL = { { { _TYPE = 'string', _VAL = { 'a\n', 'b', '' } }, 4 } } }, + '{"a\\u0000\\nb\\n": 4}' + ) + sp_decode_eq({ + _TYPE = 'map', + _VAL = { + { 'b', 3 }, + { 'a', 1 }, + { 'c', 4 }, + { 'd', 2 }, + { + { _TYPE = 'string', _VAL = { '\n' } }, + 4, + }, + }, + }, '{"b": 3, "a": 1, "c": 4, "d": 2, "\\u0000": 4}') end) it('parses U+00C3 correctly', function() - eq('\195\131', funcs.json_decode('"\195\131"')) + eq('\195\131', fn.json_decode('"\195\131"')) end) it('fails to parse empty string', function() - eq('Vim(call):E474: Attempt to decode a blank string', - exc_exec('call json_decode("")')) - eq('Vim(call):E474: Attempt to decode a blank string', - exc_exec('call json_decode([])')) - eq('Vim(call):E474: Attempt to decode a blank string', - exc_exec('call json_decode([""])')) - eq('Vim(call):E474: Attempt to decode a blank string', - exc_exec('call json_decode(" ")')) - eq('Vim(call):E474: Attempt to decode a blank string', - exc_exec('call json_decode("\\t")')) - eq('Vim(call):E474: Attempt to decode a blank string', - exc_exec('call json_decode("\\n")')) - eq('Vim(call):E474: Attempt to decode a blank string', - exc_exec('call json_decode(" \\t\\n \\n\\t\\t \\n\\t\\n \\n \\t\\n\\t ")')) + eq('Vim(call):E474: Attempt to decode a blank string', exc_exec('call json_decode("")')) + eq('Vim(call):E474: Attempt to decode a blank string', exc_exec('call json_decode([])')) + eq('Vim(call):E474: Attempt to decode a blank string', exc_exec('call json_decode([""])')) + eq('Vim(call):E474: Attempt to decode a blank string', exc_exec('call json_decode(" ")')) + eq('Vim(call):E474: Attempt to decode a blank string', exc_exec('call json_decode("\\t")')) + eq('Vim(call):E474: Attempt to decode a blank string', exc_exec('call json_decode("\\n")')) + eq( + 'Vim(call):E474: Attempt to decode a blank string', + exc_exec('call json_decode(" \\t\\n \\n\\t\\t \\n\\t\\n \\n \\t\\n\\t ")') + ) end) it('accepts all spaces in every position where space may be put', function() - local s = ' \t\n\r \t\r\n \n\t\r \n\r\t \r\t\n \r\n\t\t \n\r\t \r\n\t\n \r\t\n\r \t\r \n\t\r\n \n \t\r\n \r\t\n\t \r\n\t\r \n\r \t\n\r\t \r \t\n\r \n\t\r\t \n\r\t\n \r\n \t\r\n\t' + local s = + ' \t\n\r \t\r\n \n\t\r \n\r\t \r\t\n \r\n\t\t \n\r\t \r\n\t\n \r\t\n\r \t\r \n\t\r\n \n \t\r\n \r\t\n\t \r\n\t\r \n\r \t\n\r\t \r \t\n\r \n\t\r\t \n\r\t\n \r\n \t\r\n\t' local str = ('%s{%s"key"%s:%s[%s"val"%s,%s"val2"%s]%s,%s"key2"%s:%s1%s}%s'):gsub('%%s', s) - eq({key={'val', 'val2'}, key2=1}, funcs.json_decode(str)) + eq({ key = { 'val', 'val2' }, key2 = 1 }, fn.json_decode(str)) end) - it('does not overflow when writing error message about decoding ["", ""]', - function() - eq('Vim(call):E474: Attempt to decode a blank string', - pcall_err(command, 'call json_decode(["", ""])')) + it('does not overflow when writing error message about decoding ["", ""]', function() + eq( + 'Vim(call):E474: Attempt to decode a blank string', + pcall_err(command, 'call json_decode(["", ""])') + ) end) end) @@ -530,12 +640,12 @@ describe('json_encode() function', function() end) it('dumps strings', function() - eq('"Test"', funcs.json_encode('Test')) - eq('""', funcs.json_encode('')) - eq('"\\t"', funcs.json_encode('\t')) - eq('"\\n"', funcs.json_encode('\n')) - eq('"\\u001B"', funcs.json_encode('\27')) - eq('"þÿþ"', funcs.json_encode('þÿþ')) + eq('"Test"', fn.json_encode('Test')) + eq('""', fn.json_encode('')) + eq('"\\t"', fn.json_encode('\t')) + eq('"\\n"', fn.json_encode('\n')) + eq('"\\u001B"', fn.json_encode('\27')) + eq('"þÿþ"', fn.json_encode('þÿþ')) end) it('dumps blobs', function() @@ -544,43 +654,50 @@ describe('json_encode() function', function() end) it('dumps numbers', function() - eq('0', funcs.json_encode(0)) - eq('10', funcs.json_encode(10)) - eq('-10', funcs.json_encode(-10)) + eq('0', fn.json_encode(0)) + eq('10', fn.json_encode(10)) + eq('-10', fn.json_encode(-10)) end) it('dumps floats', function() -- Also test method call (->) syntax eq('0.0', eval('0.0->json_encode()')) - eq('10.5', funcs.json_encode(10.5)) - eq('-10.5', funcs.json_encode(-10.5)) - eq('-1.0e-5', funcs.json_encode(-1e-5)) + eq('10.5', fn.json_encode(10.5)) + eq('-10.5', fn.json_encode(-10.5)) + eq('-1.0e-5', fn.json_encode(-1e-5)) eq('1.0e50', eval('1.0e50->json_encode()')) end) it('fails to dump NaN and infinite values', function() - eq('Vim(call):E474: Unable to represent NaN value in JSON', - exc_exec('call json_encode(str2float("nan"))')) - eq('Vim(call):E474: Unable to represent infinity in JSON', - exc_exec('call json_encode(str2float("inf"))')) - eq('Vim(call):E474: Unable to represent infinity in JSON', - exc_exec('call json_encode(-str2float("inf"))')) + eq( + 'Vim(call):E474: Unable to represent NaN value in JSON', + exc_exec('call json_encode(str2float("nan"))') + ) + eq( + 'Vim(call):E474: Unable to represent infinity in JSON', + exc_exec('call json_encode(str2float("inf"))') + ) + eq( + 'Vim(call):E474: Unable to represent infinity in JSON', + exc_exec('call json_encode(-str2float("inf"))') + ) end) it('dumps lists', function() - eq('[]', funcs.json_encode({})) - eq('[[]]', funcs.json_encode({{}})) - eq('[[], []]', funcs.json_encode({{}, {}})) + eq('[]', fn.json_encode({})) + eq('[[]]', fn.json_encode({ {} })) + eq('[[], []]', fn.json_encode({ {}, {} })) end) it('dumps dictionaries', function() eq('{}', eval('json_encode({})')) - eq('{"d": []}', funcs.json_encode({d={}})) - eq('{"d": [], "e": []}', funcs.json_encode({d={}, e={}})) + eq('{"d": []}', fn.json_encode({ d = {} })) + eq('{"d": [], "e": []}', fn.json_encode({ d = {}, e = {} })) + -- Empty keys are allowed per JSON spec (and Vim dicts, and msgpack). + eq('{"": []}', fn.json_encode({ [''] = {} })) end) - it('cannot dump generic mapping with generic mapping keys and values', - function() + it('cannot dump generic mapping with generic mapping keys and values', function() command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}') command('let todumpv1 = {"_TYPE": v:msgpack_types.map, "_VAL": []}') command('let todumpv2 = {"_TYPE": v:msgpack_types.map, "_VAL": []}') @@ -673,33 +790,43 @@ describe('json_encode() function', function() end) it('fails to dump a function reference', function() - eq('Vim(call):E474: Error while dumping encode_tv2json() argument, itself: attempt to dump function reference', - exc_exec('call json_encode(function("tr"))')) + eq( + 'Vim(call):E474: Error while dumping encode_tv2json() argument, itself: attempt to dump function reference', + exc_exec('call json_encode(function("tr"))') + ) end) it('fails to dump a partial', function() command('function T() dict\nendfunction') - eq('Vim(call):E474: Error while dumping encode_tv2json() argument, itself: attempt to dump function reference', - exc_exec('call json_encode(function("T", [1, 2], {}))')) + eq( + 'Vim(call):E474: Error while dumping encode_tv2json() argument, itself: attempt to dump function reference', + exc_exec('call json_encode(function("T", [1, 2], {}))') + ) end) it('fails to dump a function reference in a list', function() - eq('Vim(call):E474: Error while dumping encode_tv2json() argument, index 0: attempt to dump function reference', - exc_exec('call json_encode([function("tr")])')) + eq( + 'Vim(call):E474: Error while dumping encode_tv2json() argument, index 0: attempt to dump function reference', + exc_exec('call json_encode([function("tr")])') + ) end) it('fails to dump a recursive list', function() command('let todump = [[[]]]') command('call add(todump[0][0], todump)') - eq('Vim(call):E724: unable to correctly dump variable with self-referencing container', - exc_exec('call json_encode(todump)')) + eq( + 'Vim(call):E724: unable to correctly dump variable with self-referencing container', + exc_exec('call json_encode(todump)') + ) end) it('fails to dump a recursive dict', function() command('let todump = {"d": {"d": {}}}') command('call extend(todump.d.d, {"d": todump})') - eq('Vim(call):E724: unable to correctly dump variable with self-referencing container', - exc_exec('call json_encode([todump])')) + eq( + 'Vim(call):E724: unable to correctly dump variable with self-referencing container', + exc_exec('call json_encode([todump])') + ) end) it('can dump dict with two same dicts inside', function() @@ -717,58 +844,77 @@ describe('json_encode() function', function() it('fails to dump a recursive list in a special dict', function() command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}') command('call add(todump._VAL, todump)') - eq('Vim(call):E724: unable to correctly dump variable with self-referencing container', - exc_exec('call json_encode(todump)')) + eq( + 'Vim(call):E724: unable to correctly dump variable with self-referencing container', + exc_exec('call json_encode(todump)') + ) end) it('fails to dump a recursive (val) map in a special dict', function() command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}') command('call add(todump._VAL, ["", todump])') - eq('Vim(call):E724: unable to correctly dump variable with self-referencing container', - exc_exec('call json_encode([todump])')) + eq( + 'Vim(call):E724: unable to correctly dump variable with self-referencing container', + exc_exec('call json_encode([todump])') + ) end) it('fails to dump a recursive (val) map in a special dict, _VAL reference', function() command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [["", []]]}') command('call add(todump._VAL[0][1], todump._VAL)') - eq('Vim(call):E724: unable to correctly dump variable with self-referencing container', - exc_exec('call json_encode(todump)')) + eq( + 'Vim(call):E724: unable to correctly dump variable with self-referencing container', + exc_exec('call json_encode(todump)') + ) end) - it('fails to dump a recursive (val) special list in a special dict', - function() + it('fails to dump a recursive (val) special list in a special dict', function() command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}') command('call add(todump._VAL, ["", todump._VAL])') - eq('Vim(call):E724: unable to correctly dump variable with self-referencing container', - exc_exec('call json_encode(todump)')) + eq( + 'Vim(call):E724: unable to correctly dump variable with self-referencing container', + exc_exec('call json_encode(todump)') + ) end) it('fails when called with no arguments', function() - eq('Vim(call):E119: Not enough arguments for function: json_encode', - exc_exec('call json_encode()')) + eq( + 'Vim(call):E119: Not enough arguments for function: json_encode', + exc_exec('call json_encode()') + ) end) it('fails when called with two arguments', function() - eq('Vim(call):E118: Too many arguments for function: json_encode', - exc_exec('call json_encode(["", ""], 1)')) + eq( + 'Vim(call):E118: Too many arguments for function: json_encode', + exc_exec('call json_encode(["", ""], 1)') + ) end) it('ignores improper values in &isprint', function() - meths.set_option_value('isprint', '1', {}) + api.nvim_set_option_value('isprint', '1', {}) eq(1, eval('"\1" =~# "\\\\p"')) - eq('"\\u0001"', funcs.json_encode('\1')) + eq('"\\u0001"', fn.json_encode('\1')) end) it('fails when using surrogate character in a UTF-8 string', function() - eq('Vim(call):E474: UTF-8 string contains code point which belongs to a surrogate pair: \237\160\128', - exc_exec('call json_encode("\237\160\128")')) - eq('Vim(call):E474: UTF-8 string contains code point which belongs to a surrogate pair: \237\175\191', - exc_exec('call json_encode("\237\175\191")')) + eq( + 'Vim(call):E474: UTF-8 string contains code point which belongs to a surrogate pair: \237\160\128', + exc_exec('call json_encode("\237\160\128")') + ) + eq( + 'Vim(call):E474: UTF-8 string contains code point which belongs to a surrogate pair: \237\175\191', + exc_exec('call json_encode("\237\175\191")') + ) end) it('dumps control characters as expected', function() - eq([["\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000B\f\r\u000E\u000F\u0010\u0011\u0012\u0013"]], - eval('json_encode({"_TYPE": v:msgpack_types.string, "_VAL": ["\n\1\2\3\4\5\6\7\8\9", "\11\12\13\14\15\16\17\18\19"]})')) + eq( + [["\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000B\f\r\u000E\u000F\u0010\u0011\u0012\u0013"]], + eval( + 'json_encode({"_TYPE": v:msgpack_types.string, "_VAL": ["\n\1\2\3\4\5\6\7\8\9", "\11\12\13\14\15\16\17\18\19"]})' + ) + ) end) it('can dump NULL string', function() @@ -788,9 +934,13 @@ describe('json_encode() function', function() end) it('fails to parse NULL strings and lists', function() - eq('Vim(call):E474: Attempt to decode a blank string', - exc_exec('call json_decode($XXX_UNEXISTENT_VAR_XXX)')) - eq('Vim(call):E474: Attempt to decode a blank string', - exc_exec('call json_decode(v:_null_list)')) + eq( + 'Vim(call):E474: Attempt to decode a blank string', + exc_exec('call json_decode($XXX_UNEXISTENT_VAR_XXX)') + ) + eq( + 'Vim(call):E474: Attempt to decode a blank string', + exc_exec('call json_decode(v:_null_list)') + ) end) end) diff --git a/test/functional/vimscript/lang_spec.lua b/test/functional/vimscript/lang_spec.lua index 90437f2ee1..2dde90e334 100644 --- a/test/functional/vimscript/lang_spec.lua +++ b/test/functional/vimscript/lang_spec.lua @@ -7,7 +7,7 @@ describe('vimscript', function() it('parses `<SID>` with turkish locale', function() if exc_exec('lang ctype tr_TR.UTF-8') ~= 0 then - pending("Locale tr_TR.UTF-8 not supported") + pending('Locale tr_TR.UTF-8 not supported') return end source([[ @@ -22,10 +22,10 @@ describe('vimscript', function() it('str2float is not affected by locale', function() if exc_exec('lang ctype sv_SE.UTF-8') ~= 0 then - pending("Locale sv_SE.UTF-8 not supported") + pending('Locale sv_SE.UTF-8 not supported') return end - clear{env={LANG="", LC_NUMERIC="sv_SE.UTF-8"}} + clear { env = { LANG = '', LC_NUMERIC = 'sv_SE.UTF-8' } } eq(2.2, eval('str2float("2.2")')) end) end) diff --git a/test/functional/vimscript/let_spec.lua b/test/functional/vimscript/let_spec.lua index 11417c5846..15d4b189b8 100644 --- a/test/functional/vimscript/let_spec.lua +++ b/test/functional/vimscript/let_spec.lua @@ -4,7 +4,7 @@ local eq = helpers.eq local clear = helpers.clear local command = helpers.command local eval = helpers.eval -local meths = helpers.meths +local api = helpers.api local exec = helpers.exec local exec_capture = helpers.exec_capture local expect_exit = helpers.expect_exit @@ -15,21 +15,24 @@ before_each(clear) describe(':let', function() it('correctly lists variables with curly-braces', function() - meths.set_var('v', {0}) + api.nvim_set_var('v', { 0 }) eq('v [0]', exec_capture('let {"v"}')) end) it('correctly lists variables with subscript', function() - meths.set_var('v', {0}) + api.nvim_set_var('v', { 0 }) eq('v[0] #0', exec_capture('let v[0]')) eq('g:["v"][0] #0', exec_capture('let g:["v"][0]')) eq('{"g:"}["v"][0] #0', exec_capture('let {"g:"}["v"][0]')) end) - it(":unlet self-referencing node in a List graph #6070", function() + it(':unlet self-referencing node in a List graph #6070', function() -- :unlet-ing a self-referencing List must not allow GC on indirectly -- referenced in-scope Lists. Before #6070 this caused use-after-free. - expect_exit(1000, source, [=[ + expect_exit( + 1000, + source, + [=[ let [l1, l2] = [[], []] echo 'l1:' . id(l1) echo 'l2:' . id(l2) @@ -45,10 +48,11 @@ describe(':let', function() unlet l4 call garbagecollect(1) call feedkeys(":\e:echo l1 l3\n:echo 42\n:cq\n", "t") - ]=]) + ]=] + ) end) - it("multibyte env var #8398 #9267", function() + it('multibyte env var #8398 #9267', function() command("let $NVIM_TEST_LET = 'AìaB'") eq('AìaB', eval('$NVIM_TEST_LET')) command("let $NVIM_TEST_LET = 'AaあB'") @@ -56,12 +60,14 @@ describe(':let', function() local mbyte = [[\p* .ม .ม .ม .ม่ .ม่ .ม่ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ ֹֻ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ a a a ca ca ca à à à]] - command("let $NVIM_TEST_LET = '"..mbyte.."'") + command("let $NVIM_TEST_LET = '" .. mbyte .. "'") eq(mbyte, eval('$NVIM_TEST_LET')) end) - it("multibyte env var to child process #8398 #9267", function() - local cmd_get_child_env = ("let g:env_from_child = system(['%s', 'NVIM_TEST_LET'])"):format(testprg('printenv-test')) + it('multibyte env var to child process #8398 #9267', function() + local cmd_get_child_env = ("let g:env_from_child = system(['%s', 'NVIM_TEST_LET'])"):format( + testprg('printenv-test') + ) command("let $NVIM_TEST_LET = 'AìaB'") command(cmd_get_child_env) eq(eval('$NVIM_TEST_LET'), eval('g:env_from_child')) @@ -73,12 +79,12 @@ describe(':let', function() local mbyte = [[\p* .ม .ม .ม .ม่ .ม่ .ม่ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ ֹֻ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ a a a ca ca ca à à à]] - command("let $NVIM_TEST_LET = '"..mbyte.."'") + command("let $NVIM_TEST_LET = '" .. mbyte .. "'") command(cmd_get_child_env) eq(eval('$NVIM_TEST_LET'), eval('g:env_from_child')) end) - it("release of list assigned to l: variable does not trigger assertion #12387, #12430", function() + it('release of list assigned to l: variable does not trigger assertion #12387, #12430', function() source([[ func! s:f() let l:x = [1] @@ -94,17 +100,17 @@ describe(':let', function() end) it('can apply operator to boolean option', function() - eq(true, meths.get_option_value('equalalways', {})) + eq(true, api.nvim_get_option_value('equalalways', {})) command('let &equalalways -= 1') - eq(false, meths.get_option_value('equalalways', {})) + eq(false, api.nvim_get_option_value('equalalways', {})) command('let &equalalways += 1') - eq(true, meths.get_option_value('equalalways', {})) + eq(true, api.nvim_get_option_value('equalalways', {})) command('let &equalalways *= 1') - eq(true, meths.get_option_value('equalalways', {})) + eq(true, api.nvim_get_option_value('equalalways', {})) command('let &equalalways /= 1') - eq(true, meths.get_option_value('equalalways', {})) + eq(true, api.nvim_get_option_value('equalalways', {})) command('let &equalalways %= 1') - eq(false, meths.get_option_value('equalalways', {})) + eq(false, api.nvim_get_option_value('equalalways', {})) end) end) diff --git a/test/functional/vimscript/map_functions_spec.lua b/test/functional/vimscript/map_functions_spec.lua index acba5e9708..59d427ca90 100644 --- a/test/functional/vimscript/map_functions_spec.lua +++ b/test/functional/vimscript/map_functions_spec.lua @@ -7,9 +7,8 @@ local exec = helpers.exec local exec_lua = helpers.exec_lua local expect = helpers.expect local feed = helpers.feed -local funcs = helpers.funcs -local meths = helpers.meths -local nvim = helpers.nvim +local fn = helpers.fn +local api = helpers.api local source = helpers.source local command = helpers.command local exec_capture = helpers.exec_capture @@ -19,65 +18,65 @@ describe('maparg()', function() before_each(clear) local foo_bar_map_table = { - lhs='foo', - lhsraw='foo', - script=0, - silent=0, - rhs='bar', - expr=0, - sid=0, - scriptversion=1, - buffer=0, - nowait=0, - mode='n', - mode_bits=0x01, - abbr=0, - noremap=1, - lnum=0, - } + lhs = 'foo', + lhsraw = 'foo', + script = 0, + silent = 0, + rhs = 'bar', + expr = 0, + sid = 0, + scriptversion = 1, + buffer = 0, + nowait = 0, + mode = 'n', + mode_bits = 0x01, + abbr = 0, + noremap = 1, + lnum = 0, + } it('returns a dictionary', function() - nvim('command', 'nnoremap foo bar') - eq('bar', funcs.maparg('foo')) - eq(foo_bar_map_table, funcs.maparg('foo', 'n', false, true)) + command('nnoremap foo bar') + eq('bar', fn.maparg('foo')) + eq(foo_bar_map_table, fn.maparg('foo', 'n', false, true)) end) it('returns 1 for silent when <silent> is used', function() - nvim('command', 'nnoremap <silent> foo bar') - eq(1, funcs.maparg('foo', 'n', false, true)['silent']) + command('nnoremap <silent> foo bar') + eq(1, fn.maparg('foo', 'n', false, true)['silent']) - nvim('command', 'nnoremap baz bat') - eq(0, funcs.maparg('baz', 'n', false, true)['silent']) + command('nnoremap baz bat') + eq(0, fn.maparg('baz', 'n', false, true)['silent']) end) it('returns an empty string when no map is present', function() - eq('', funcs.maparg('not a mapping')) + eq('', fn.maparg('not a mapping')) end) it('returns an empty dictionary when no map is present and dict is requested', function() - eq({}, funcs.maparg('not a mapping', 'n', false, true)) + eq({}, fn.maparg('not a mapping', 'n', false, true)) end) it('returns the same value for noremap and <script>', function() - nvim('command', 'inoremap <script> hello world') - nvim('command', 'inoremap this that') + command('inoremap <script> hello world') + command('inoremap this that') eq( - funcs.maparg('hello', 'i', false, true)['noremap'], - funcs.maparg('this', 'i', false, true)['noremap'] - ) + fn.maparg('hello', 'i', false, true)['noremap'], + fn.maparg('this', 'i', false, true)['noremap'] + ) end) it('returns a boolean for buffer', function() -- Open enough windows to know we aren't on buffer number 1 - nvim('command', 'new') - nvim('command', 'new') - nvim('command', 'new') - nvim('command', 'cnoremap <buffer> this that') - eq(1, funcs.maparg('this', 'c', false, true)['buffer']) + command('new') + command('new') + command('new') + command('cnoremap <buffer> this that') + eq(1, fn.maparg('this', 'c', false, true)['buffer']) -- Global will return 0 always - nvim('command', 'nnoremap other another') - eq(0, funcs.maparg('other', 'n', false, true)['buffer']) + command('nnoremap other another') + eq(0, fn.maparg('other', 'n', false, true)['buffer']) end) it('returns script numbers', function() @@ -88,8 +87,8 @@ describe('maparg()', function() nnoremap fizz :call <SID>maparg_test_function()<CR> ]]) - eq(1, funcs.maparg('fizz', 'n', false, true)['sid']) - eq('testing', nvim('call_function', '<SNR>1_maparg_test_function', {})) + eq(1, fn.maparg('fizz', 'n', false, true)['sid']) + eq('testing', api.nvim_call_function('<SNR>1_maparg_test_function', {})) end) it('works with <F12> and others', function() @@ -104,7 +103,7 @@ describe('maparg()', function() ]]) eq(1, eval('g:maparg_test_var')) - eq(':let g:maparg_test_var = 1<CR>', funcs.maparg('<F12>', 'n', false, true)['rhs']) + eq(':let g:maparg_test_var = 1<CR>', fn.maparg('<F12>', 'n', false, true)['rhs']) end) it('works with <expr>', function() @@ -127,7 +126,7 @@ describe('maparg()', function() ]]) eq(1, eval('g:counter')) - local map_dict = funcs.maparg('<C-L>', 'i', false, true) + local map_dict = fn.maparg('<C-L>', 'i', false, true) eq(1, map_dict['expr']) eq('i', map_dict['mode']) end) @@ -135,7 +134,7 @@ describe('maparg()', function() it('works with combining characters', function() -- Using addacutes to make combining character better visible local function ac(s) - local acute = '\204\129' -- U+0301 COMBINING ACUTE ACCENT + local acute = '\204\129' -- U+0301 COMBINING ACUTE ACCENT local ret = s:gsub('`', acute) return ret end @@ -144,10 +143,10 @@ describe('maparg()', function() nnoremap c` d nnoremap e` f` ]])) - eq(ac('b`'), funcs.maparg(ac('a'))) - eq(ac(''), funcs.maparg(ac('c'))) - eq(ac('d'), funcs.maparg(ac('c`'))) - eq(ac('f`'), funcs.maparg(ac('e`'))) + eq(ac('b`'), fn.maparg(ac('a'))) + eq(ac(''), fn.maparg(ac('c'))) + eq(ac('d'), fn.maparg(ac('c`'))) + eq(ac('f`'), fn.maparg(ac('e`'))) local function acmap(lhs, rhs) return { @@ -170,35 +169,45 @@ describe('maparg()', function() } end - eq({}, funcs.maparg(ac('c'), 'n', 0, 1)) - eq(acmap('a', 'b`'), funcs.maparg(ac('a'), 'n', 0, 1)) - eq(acmap('c`', 'd'), funcs.maparg(ac('c`'), 'n', 0, 1)) - eq(acmap('e`', 'f`'), funcs.maparg(ac('e`'), 'n', 0, 1)) + eq({}, fn.maparg(ac('c'), 'n', 0, 1)) + eq(acmap('a', 'b`'), fn.maparg(ac('a'), 'n', 0, 1)) + eq(acmap('c`', 'd'), fn.maparg(ac('c`'), 'n', 0, 1)) + eq(acmap('e`', 'f`'), fn.maparg(ac('e`'), 'n', 0, 1)) end) end) describe('mapset()', function() before_each(clear) + it('can restore mapping with backslash in lhs', function() + api.nvim_set_keymap('n', '\\ab', 'a', {}) + eq('\nn \\ab a', exec_capture('nmap \\ab')) + local mapargs = fn.maparg('\\ab', 'n', false, true) + api.nvim_set_keymap('n', '\\ab', 'b', {}) + eq('\nn \\ab b', exec_capture('nmap \\ab')) + fn.mapset('n', false, mapargs) + eq('\nn \\ab a', exec_capture('nmap \\ab')) + end) + it('can restore mapping description from the dict returned by maparg()', function() - meths.set_keymap('n', 'lhs', 'rhs', {desc = 'map description'}) - eq('\nn lhs rhs\n map description', exec_capture("nmap lhs")) - local mapargs = funcs.maparg('lhs', 'n', false, true) - meths.set_keymap('n', 'lhs', 'rhs', {desc = 'MAP DESCRIPTION'}) - eq('\nn lhs rhs\n MAP DESCRIPTION', exec_capture("nmap lhs")) - funcs.mapset('n', false, mapargs) - eq('\nn lhs rhs\n map description', exec_capture("nmap lhs")) + api.nvim_set_keymap('n', 'lhs', 'rhs', { desc = 'map description' }) + eq('\nn lhs rhs\n map description', exec_capture('nmap lhs')) + local mapargs = fn.maparg('lhs', 'n', false, true) + api.nvim_set_keymap('n', 'lhs', 'rhs', { desc = 'MAP DESCRIPTION' }) + eq('\nn lhs rhs\n MAP DESCRIPTION', exec_capture('nmap lhs')) + fn.mapset('n', false, mapargs) + eq('\nn lhs rhs\n map description', exec_capture('nmap lhs')) end) it('can restore "replace_keycodes" from the dict returned by maparg()', function() - meths.set_keymap('i', 'foo', [['<l' .. 't>']], {expr = true, replace_keycodes = true}) + api.nvim_set_keymap('i', 'foo', [['<l' .. 't>']], { expr = true, replace_keycodes = true }) feed('Afoo') expect('<') - local mapargs = funcs.maparg('foo', 'i', false, true) - meths.set_keymap('i', 'foo', [['<l' .. 't>']], {expr = true}) + local mapargs = fn.maparg('foo', 'i', false, true) + api.nvim_set_keymap('i', 'foo', [['<l' .. 't>']], { expr = true }) feed('foo') expect('<<lt>') - funcs.mapset('i', false, mapargs) + fn.mapset('i', false, mapargs) feed('foo') expect('<<lt><') end) @@ -208,23 +217,26 @@ describe('mapset()', function() eq('\ni foo * bar', exec_capture('iabbr foo')) feed('ifoo ') expect('bar ') - local mapargs = funcs.maparg('foo', 'i', true, true) + local mapargs = fn.maparg('foo', 'i', true, true) command('inoreabbr foo BAR') eq('\ni foo * BAR', exec_capture('iabbr foo')) feed('foo ') expect('bar BAR ') - funcs.mapset('i', true, mapargs) + fn.mapset('i', true, mapargs) eq('\ni foo * bar', exec_capture('iabbr foo')) feed('foo<Esc>') expect('bar BAR bar') end) it('can restore Lua callback from the dict returned by maparg()', function() - eq(0, exec_lua([[ + eq( + 0, + exec_lua([[ GlobalCount = 0 vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end }) return GlobalCount - ]])) + ]]) + ) feed('asdf') eq(1, exec_lua([[return GlobalCount]])) @@ -252,9 +264,13 @@ describe('mapset()', function() end) it('does not leak memory if lhs is missing', function() - eq('Vim:E460: Entries missing in mapset() dict argument', - pcall_err(exec_lua, [[vim.fn.mapset('n', false, {rhs = 'foo'})]])) - eq('Vim:E460: Entries missing in mapset() dict argument', - pcall_err(exec_lua, [[vim.fn.mapset('n', false, {callback = function() end})]])) + eq( + 'Vim:E460: Entries missing in mapset() dict argument', + pcall_err(exec_lua, [[vim.fn.mapset('n', false, {rhs = 'foo'})]]) + ) + eq( + 'Vim:E460: Entries missing in mapset() dict argument', + pcall_err(exec_lua, [[vim.fn.mapset('n', false, {callback = function() end})]]) + ) end) end) diff --git a/test/functional/vimscript/match_functions_spec.lua b/test/functional/vimscript/match_functions_spec.lua index 9f168c913a..3db612e472 100644 --- a/test/functional/vimscript/match_functions_spec.lua +++ b/test/functional/vimscript/match_functions_spec.lua @@ -3,155 +3,198 @@ local Screen = require('test.functional.ui.screen') local eq = helpers.eq local clear = helpers.clear -local funcs = helpers.funcs +local fn = helpers.fn local command = helpers.command local exc_exec = helpers.exc_exec before_each(clear) describe('setmatches()', function() - it('correctly handles case when both group and pattern entries are numbers', - function() + it('correctly handles case when both group and pattern entries are numbers', function() command('hi def link 1 PreProc') - eq(0, funcs.setmatches({{group=1, pattern=2, id=3, priority=4}})) - eq({{ - group='1', - pattern='2', - id=3, - priority=4, - }}, funcs.getmatches()) - eq(0, funcs.setmatches({{group=1, pattern=2, id=3, priority=4, conceal=5}})) - eq({{ - group='1', - pattern='2', - id=3, - priority=4, - conceal='5', - }}, funcs.getmatches()) - eq(0, funcs.setmatches({{group=1, pos1={2}, pos2={6}, id=3, priority=4, conceal=5}})) - eq({{ - group='1', - pos1={2}, - pos2={6}, - id=3, - priority=4, - conceal='5', - }}, funcs.getmatches()) + eq(0, fn.setmatches({ { group = 1, pattern = 2, id = 3, priority = 4 } })) + eq({ + { + group = '1', + pattern = '2', + id = 3, + priority = 4, + }, + }, fn.getmatches()) + eq(0, fn.setmatches({ { group = 1, pattern = 2, id = 3, priority = 4, conceal = 5 } })) + eq({ + { + group = '1', + pattern = '2', + id = 3, + priority = 4, + conceal = '5', + }, + }, fn.getmatches()) + eq( + 0, + fn.setmatches({ + { group = 1, pos1 = { 2 }, pos2 = { 6 }, id = 3, priority = 4, conceal = 5 }, + }) + ) + eq({ + { + group = '1', + pos1 = { 2 }, + pos2 = { 6 }, + id = 3, + priority = 4, + conceal = '5', + }, + }, fn.getmatches()) end) it('does not fail if highlight group is not defined', function() - eq(0, funcs.setmatches{{group=1, pattern=2, id=3, priority=4}}) - eq({{group='1', pattern='2', id=3, priority=4}}, - funcs.getmatches()) - eq(0, funcs.setmatches{{group=1, pos1={2}, pos2={6}, id=3, priority=4, conceal=5}}) - eq({{group='1', pos1={2}, pos2={6}, id=3, priority=4, conceal='5'}}, - funcs.getmatches()) + eq(0, fn.setmatches { { group = 1, pattern = 2, id = 3, priority = 4 } }) + eq({ { group = '1', pattern = '2', id = 3, priority = 4 } }, fn.getmatches()) + eq( + 0, + fn.setmatches { + { group = 1, pos1 = { 2 }, pos2 = { 6 }, id = 3, priority = 4, conceal = 5 }, + } + ) + eq( + { { group = '1', pos1 = { 2 }, pos2 = { 6 }, id = 3, priority = 4, conceal = '5' } }, + fn.getmatches() + ) end) end) describe('matchadd()', function() - it('correctly works when first two arguments and conceal are numbers at once', - function() + it('correctly works when first two arguments and conceal are numbers at once', function() command('hi def link 1 PreProc') - eq(4, funcs.matchadd(1, 2, 3, 4, {conceal=5})) - eq({{ - group='1', - pattern='2', - priority=3, - id=4, - conceal='5', - }}, funcs.getmatches()) + eq(4, fn.matchadd(1, 2, 3, 4, { conceal = 5 })) + eq({ + { + group = '1', + pattern = '2', + priority = 3, + id = 4, + conceal = '5', + }, + }, fn.getmatches()) end) end) describe('matchaddpos()', function() it('errors out on invalid input', function() command('hi clear PreProc') - eq('Vim(let):E5030: Empty list at position 0', - exc_exec('let val = matchaddpos("PreProc", [[]])')) - eq('Vim(let):E5030: Empty list at position 1', - exc_exec('let val = matchaddpos("PreProc", [1, v:_null_list])')) - eq('Vim(let):E5031: List or number required at position 1', - exc_exec('let val = matchaddpos("PreProc", [1, v:_null_dict])')) + eq( + 'Vim(let):E5030: Empty list at position 0', + exc_exec('let val = matchaddpos("PreProc", [[]])') + ) + eq( + 'Vim(let):E5030: Empty list at position 1', + exc_exec('let val = matchaddpos("PreProc", [1, v:_null_list])') + ) + eq( + 'Vim(let):E5031: List or number required at position 1', + exc_exec('let val = matchaddpos("PreProc", [1, v:_null_dict])') + ) end) it('works with 0 lnum', function() command('hi clear PreProc') - eq(4, funcs.matchaddpos('PreProc', {1}, 3, 4)) - eq({{ - group='PreProc', - pos1 = {1}, - priority=3, - id=4, - }}, funcs.getmatches()) - funcs.matchdelete(4) - eq(4, funcs.matchaddpos('PreProc', {{0}, 1}, 3, 4)) - eq({{ - group='PreProc', - pos1 = {1}, - priority=3, - id=4, - }}, funcs.getmatches()) - funcs.matchdelete(4) - eq(4, funcs.matchaddpos('PreProc', {0, 1}, 3, 4)) - eq({{ - group='PreProc', - pos1 = {1}, - priority=3, - id=4, - }}, funcs.getmatches()) + eq(4, fn.matchaddpos('PreProc', { 1 }, 3, 4)) + eq({ + { + group = 'PreProc', + pos1 = { 1 }, + priority = 3, + id = 4, + }, + }, fn.getmatches()) + fn.matchdelete(4) + eq(4, fn.matchaddpos('PreProc', { { 0 }, 1 }, 3, 4)) + eq({ + { + group = 'PreProc', + pos1 = { 1 }, + priority = 3, + id = 4, + }, + }, fn.getmatches()) + fn.matchdelete(4) + eq(4, fn.matchaddpos('PreProc', { 0, 1 }, 3, 4)) + eq({ + { + group = 'PreProc', + pos1 = { 1 }, + priority = 3, + id = 4, + }, + }, fn.getmatches()) end) it('works with negative numbers', function() command('hi clear PreProc') - eq(4, funcs.matchaddpos('PreProc', {-10, 1}, 3, 4)) - eq({{ - group='PreProc', - pos1 = {1}, - priority=3, - id=4, - }}, funcs.getmatches()) - funcs.matchdelete(4) - eq(4, funcs.matchaddpos('PreProc', {{-10}, 1}, 3, 4)) - eq({{ - group='PreProc', - pos1 = {1}, - priority=3, - id=4, - }}, funcs.getmatches()) - funcs.matchdelete(4) - eq(4, funcs.matchaddpos('PreProc', {{2, -1}, 1}, 3, 4)) - eq({{ - group='PreProc', - pos1 = {1}, - priority=3, - id=4, - }}, funcs.getmatches()) - funcs.matchdelete(4) - eq(4, funcs.matchaddpos('PreProc', {{2, 0, -1}, 1}, 3, 4)) - eq({{ - group='PreProc', - pos1 = {1}, - priority=3, - id=4, - }}, funcs.getmatches()) + eq(4, fn.matchaddpos('PreProc', { -10, 1 }, 3, 4)) + eq({ + { + group = 'PreProc', + pos1 = { 1 }, + priority = 3, + id = 4, + }, + }, fn.getmatches()) + fn.matchdelete(4) + eq(4, fn.matchaddpos('PreProc', { { -10 }, 1 }, 3, 4)) + eq({ + { + group = 'PreProc', + pos1 = { 1 }, + priority = 3, + id = 4, + }, + }, fn.getmatches()) + fn.matchdelete(4) + eq(4, fn.matchaddpos('PreProc', { { 2, -1 }, 1 }, 3, 4)) + eq({ + { + group = 'PreProc', + pos1 = { 1 }, + priority = 3, + id = 4, + }, + }, fn.getmatches()) + fn.matchdelete(4) + eq(4, fn.matchaddpos('PreProc', { { 2, 0, -1 }, 1 }, 3, 4)) + eq({ + { + group = 'PreProc', + pos1 = { 1 }, + priority = 3, + id = 4, + }, + }, fn.getmatches()) end) it('works with zero length', function() local screen = Screen.new(40, 5) screen:attach() - funcs.setline(1, 'abcdef') + fn.setline(1, 'abcdef') command('hi PreProc guifg=Red') - eq(4, funcs.matchaddpos('PreProc', {{1, 2, 0}}, 3, 4)) - eq({{ - group='PreProc', - pos1 = {1, 2, 0}, - priority=3, - id=4, - }}, funcs.getmatches()) - screen:expect([[ + eq(4, fn.matchaddpos('PreProc', { { 1, 2, 0 } }, 3, 4)) + eq({ + { + group = 'PreProc', + pos1 = { 1, 2, 0 }, + priority = 3, + id = 4, + }, + }, fn.getmatches()) + screen:expect( + [[ ^a{1:b}cdef | - {2:~ }| - {2:~ }| - {2:~ }| + {2:~ }|*3 | - ]], {[1] = {foreground = Screen.colors.Red}, [2] = {bold = true, foreground = Screen.colors.Blue1}}) + ]], + { + [1] = { foreground = Screen.colors.Red }, + [2] = { bold = true, foreground = Screen.colors.Blue1 }, + } + ) end) end) diff --git a/test/functional/vimscript/minmax_functions_spec.lua b/test/functional/vimscript/minmax_functions_spec.lua index 91106bef1e..c4a986bc8c 100644 --- a/test/functional/vimscript/minmax_functions_spec.lua +++ b/test/functional/vimscript/minmax_functions_spec.lua @@ -4,18 +4,21 @@ local eq = helpers.eq local eval = helpers.eval local command = helpers.command local clear = helpers.clear -local funcs = helpers.funcs +local fn = helpers.fn local pcall_err = helpers.pcall_err before_each(clear) -for _, func in ipairs({'min', 'max'}) do +for _, func in ipairs({ 'min', 'max' }) do describe(func .. '()', function() - it('gives a single error message when multiple values failed conversions', - function() - eq('Vim(echo):E745: Using a List as a Number', - pcall_err(command, 'echo ' .. func .. '([-5, [], [], [], 5])')) - eq('Vim(echo):E745: Using a List as a Number', - pcall_err(command, 'echo ' .. func .. '({1:-5, 2:[], 3:[], 4:[], 5:5})')) + it('gives a single error message when multiple values failed conversions', function() + eq( + 'Vim(echo):E745: Using a List as a Number', + pcall_err(command, 'echo ' .. func .. '([-5, [], [], [], 5])') + ) + eq( + 'Vim(echo):E745: Using a List as a Number', + pcall_err(command, 'echo ' .. func .. '({1:-5, 2:[], 3:[], 4:[], 5:5})') + ) for errmsg, errinput in pairs({ ['Vim(echo):E745: Using a List as a Number'] = '[]', ['Vim(echo):E805: Using a Float as a Number'] = '0.0', @@ -27,22 +30,30 @@ for _, func in ipairs({'min', 'max'}) do end end) it('works with arrays/dictionaries with zero items', function() - eq(0, funcs[func]({})) + eq(0, fn[func]({})) eq(0, eval(func .. '({})')) end) it('works with arrays/dictionaries with one item', function() - eq(5, funcs[func]({5})) - eq(5, funcs[func]({test=5})) + eq(5, fn[func]({ 5 })) + eq(5, fn[func]({ test = 5 })) end) it('works with NULL arrays/dictionaries', function() eq(0, eval(func .. '(v:_null_list)')) eq(0, eval(func .. '(v:_null_dict)')) end) it('errors out for invalid types', function() - for _, errinput in ipairs({'1', 'v:true', 'v:false', 'v:null', - 'function("tr")', '""'}) do - eq(('Vim(echo):E712: Argument of %s() must be a List or Dictionary'):format(func), - pcall_err(command, 'echo ' .. func .. '(' .. errinput .. ')')) + for _, errinput in ipairs({ + '1', + 'v:true', + 'v:false', + 'v:null', + 'function("tr")', + '""', + }) do + eq( + ('Vim(echo):E712: Argument of %s() must be a List or Dictionary'):format(func), + pcall_err(command, 'echo ' .. func .. '(' .. errinput .. ')') + ) end end) end) diff --git a/test/functional/vimscript/modeline_spec.lua b/test/functional/vimscript/modeline_spec.lua index b2346079a1..ae63a66f43 100644 --- a/test/functional/vimscript/modeline_spec.lua +++ b/test/functional/vimscript/modeline_spec.lua @@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each) local assert_alive = helpers.assert_alive local clear, command, write_file = helpers.clear, helpers.command, helpers.write_file -describe("modeline", function() +describe('modeline', function() local tempfile = helpers.tmpname() before_each(clear) diff --git a/test/functional/vimscript/msgpack_functions_spec.lua b/test/functional/vimscript/msgpack_functions_spec.lua index de5a721efe..609a706155 100644 --- a/test/functional/vimscript/msgpack_functions_spec.lua +++ b/test/functional/vimscript/msgpack_functions_spec.lua @@ -1,9 +1,9 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear -local funcs = helpers.funcs +local fn = helpers.fn local eval, eq = helpers.eval, helpers.eq local command = helpers.command -local nvim = helpers.nvim +local api = helpers.api local exc_exec = helpers.exc_exec local is_os = helpers.is_os @@ -12,7 +12,7 @@ describe('msgpack*() functions', function() local obj_test = function(msg, obj) it(msg, function() - nvim('set_var', 'obj', obj) + api.nvim_set_var('obj', obj) eq(obj, eval('msgpackparse(msgpackdump(g:obj))')) eq(obj, eval('msgpackparse(msgpackdump(g:obj, "B"))')) end) @@ -20,17 +20,18 @@ describe('msgpack*() functions', function() -- Regression test: msgpack_list_write was failing to write buffer with zero -- length. - obj_test('are able to dump and restore {"file": ""}', {{file=''}}) + obj_test('are able to dump and restore {"file": ""}', { { file = '' } }) -- Regression test: msgpack_list_write was failing to write buffer with NL at -- the end. - obj_test('are able to dump and restore {0, "echo mpack"}', {{0, 'echo mpack'}}) - obj_test('are able to dump and restore "Test\\n"', {'Test\n'}) + obj_test('are able to dump and restore {0, "echo mpack"}', { { 0, 'echo mpack' } }) + obj_test('are able to dump and restore "Test\\n"', { 'Test\n' }) -- Regression test: msgpack_list_write was failing to write buffer with NL -- inside. - obj_test('are able to dump and restore "Test\\nTest 2"', {'Test\nTest 2'}) + obj_test('are able to dump and restore "Test\\nTest 2"', { 'Test\nTest 2' }) -- Test that big objects (requirement: dump to something that is bigger then -- IOSIZE) are also fine. This particular object is obtained by concatenating -- 5 identical shada files. + -- stylua: ignore local big_obj = { 1, 1436711454, 78, { encoding="utf-8", @@ -330,19 +331,18 @@ describe('msgpack*() functions', function() } obj_test('are able to dump and restore rather big object', big_obj) - obj_test('are able to dump and restore floating-point value', {0.125}) + obj_test('are able to dump and restore floating-point value', { 0.125 }) it('can restore and dump UINT64_MAX', function() command('let dumped = ["\\xCF" . repeat("\\xFF", 8)]') command('let parsed = msgpackparse(dumped)') command('let dumped2 = msgpackdump(parsed)') - eq(1, eval('type(parsed[0]) == type(0) ' .. - '|| parsed[0]._TYPE is v:msgpack_types.integer')) + eq(1, eval('type(parsed[0]) == type(0) ' .. '|| parsed[0]._TYPE is v:msgpack_types.integer')) if eval('type(parsed[0]) == type(0)') == 1 then command('call assert_equal(0xFFFFFFFFFFFFFFFF, parsed[0])') eq({}, eval('v:errors')) else - eq({_TYPE={}, _VAL={1, 3, 0x7FFFFFFF, 0x7FFFFFFF}}, eval('parsed[0]')) + eq({ _TYPE = {}, _VAL = { 1, 3, 0x7FFFFFFF, 0x7FFFFFFF } }, eval('parsed[0]')) end eq(1, eval('dumped ==# dumped2')) end) @@ -351,13 +351,12 @@ describe('msgpack*() functions', function() command('let dumped = ["\\xD3\\x80" . repeat("\\n", 7)]') command('let parsed = msgpackparse(dumped)') command('let dumped2 = msgpackdump(parsed)') - eq(1, eval('type(parsed[0]) == type(0) ' .. - '|| parsed[0]._TYPE is v:msgpack_types.integer')) + eq(1, eval('type(parsed[0]) == type(0) ' .. '|| parsed[0]._TYPE is v:msgpack_types.integer')) if eval('type(parsed[0]) == type(0)') == 1 then command('call assert_equal(-0x7fffffffffffffff - 1, parsed[0])') eq({}, eval('v:errors')) else - eq({_TYPE={}, _VAL={-1, 2, 0, 0}}, eval('parsed[0]')) + eq({ _TYPE = {}, _VAL = { -1, 2, 0, 0 } }, eval('parsed[0]')) end eq(1, eval('dumped ==# dumped2')) end) @@ -366,7 +365,7 @@ describe('msgpack*() functions', function() command('let dumped = ["\\xC4\\x01\\n"]') command('let parsed = msgpackparse(dumped)') command('let dumped2 = msgpackdump(parsed)') - eq({'\000'}, eval('parsed')) + eq({ '\000' }, eval('parsed')) eq(1, eval('dumped ==# dumped2')) end) @@ -374,7 +373,7 @@ describe('msgpack*() functions', function() command('let dumped = ["\\xA1\\n"]') command('let parsed = msgpackparse(dumped)') command('let dumped2 = msgpackdump(parsed)') - eq({{_TYPE={}, _VAL={'\n'}}}, eval('parsed')) + eq({ { _TYPE = {}, _VAL = { '\n' } } }, eval('parsed')) eq(1, eval('parsed[0]._TYPE is v:msgpack_types.string')) eq(1, eval('dumped ==# dumped2')) end) @@ -383,19 +382,19 @@ describe('msgpack*() functions', function() command('let dumped = ["\\xC4\\x01", ""]') command('let parsed = msgpackparse(dumped)') command('let dumped2 = msgpackdump(parsed)') - eq({"\n"}, eval('parsed')) + eq({ '\n' }, eval('parsed')) eq(1, eval('dumped ==# dumped2')) end) it('dump and restore special mapping with floating-point value', function() command('let todump = {"_TYPE": v:msgpack_types.float, "_VAL": 0.125}') - eq({0.125}, eval('msgpackparse(msgpackdump([todump]))')) + eq({ 0.125 }, eval('msgpackparse(msgpackdump([todump]))')) end) end) local blobstr = function(list) local l = {} - for i,v in ipairs(list) do + for i, v in ipairs(list) do l[i] = v:gsub('\n', '\000') end return table.concat(l, '\n') @@ -403,10 +402,11 @@ end -- Test msgpackparse() with a readfile()-style list and a blob argument local parse_eq = function(expect, list_arg) - local blob_expr = '0z' .. blobstr(list_arg):gsub('(.)', function(c) - return ('%.2x'):format(c:byte()) - end) - eq(expect, funcs.msgpackparse(list_arg)) + local blob_expr = '0z' + .. blobstr(list_arg):gsub('(.)', function(c) + return ('%.2x'):format(c:byte()) + end) + eq(expect, fn.msgpackparse(list_arg)) command('let g:parsed = msgpackparse(' .. blob_expr .. ')') eq(expect, eval('g:parsed')) end @@ -415,33 +415,33 @@ describe('msgpackparse() function', function() before_each(clear) it('restores nil as v:null', function() - parse_eq(eval('[v:null]'), {'\192'}) + parse_eq(eval('[v:null]'), { '\192' }) end) it('restores boolean false as v:false', function() - parse_eq({false}, {'\194'}) + parse_eq({ false }, { '\194' }) end) it('restores boolean true as v:true', function() - parse_eq({true}, {'\195'}) + parse_eq({ true }, { '\195' }) end) it('restores FIXSTR as special dict', function() - parse_eq({{_TYPE={}, _VAL={'ab'}}}, {'\162ab'}) + parse_eq({ { _TYPE = {}, _VAL = { 'ab' } } }, { '\162ab' }) eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.string')) end) it('restores BIN 8 as string', function() - parse_eq({'ab'}, {'\196\002ab'}) + parse_eq({ 'ab' }, { '\196\002ab' }) end) it('restores FIXEXT1 as special dictionary', function() - parse_eq({{_TYPE={}, _VAL={0x10, {"", ""}}}}, {'\212\016', ''}) + parse_eq({ { _TYPE = {}, _VAL = { 0x10, { '', '' } } } }, { '\212\016', '' }) eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.ext')) end) it('restores MAP with BIN key as special dictionary', function() - parse_eq({{_TYPE={}, _VAL={{'a', ''}}}}, {'\129\196\001a\196\n'}) + parse_eq({ { _TYPE = {}, _VAL = { { 'a', '' } } } }, { '\129\196\001a\196\n' }) eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map')) end) @@ -449,72 +449,93 @@ describe('msgpackparse() function', function() command('let dumped = ["\\x82\\xA1a\\xC4\\n\\xA1a\\xC4\\n"]') -- FIXME Internal error bug, can't use parse_eq() here command('silent! let parsed = msgpackparse(dumped)') - eq({{_TYPE={}, _VAL={ {{_TYPE={}, _VAL={'a'}}, ''}, - {{_TYPE={}, _VAL={'a'}}, ''}}} }, eval('parsed')) + eq({ + { + _TYPE = {}, + _VAL = { + { { _TYPE = {}, _VAL = { 'a' } }, '' }, + { { _TYPE = {}, _VAL = { 'a' } }, '' }, + }, + }, + }, eval('parsed')) eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map')) eq(1, eval('g:parsed[0]._VAL[0][0]._TYPE is v:msgpack_types.string')) eq(1, eval('g:parsed[0]._VAL[1][0]._TYPE is v:msgpack_types.string')) end) it('restores MAP with MAP key as special dictionary', function() - parse_eq({{_TYPE={}, _VAL={{{}, ''}}}}, {'\129\128\196\n'}) + parse_eq({ { _TYPE = {}, _VAL = { { {}, '' } } } }, { '\129\128\196\n' }) eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map')) end) it('msgpackparse(systemlist(...)) does not segfault. #3135', function() - local cmd = "sort(keys(msgpackparse(systemlist('" - ..helpers.nvim_prog.." --api-info'))[0]))" + local cmd = "sort(keys(msgpackparse(systemlist('" .. helpers.nvim_prog .. " --api-info'))[0]))" eval(cmd) - eval(cmd) -- do it again (try to force segfault) - local api_info = eval(cmd) -- do it again + eval(cmd) -- do it again (try to force segfault) + local api_info = eval(cmd) -- do it again if is_os('win') then helpers.assert_alive() pending('msgpackparse() has a bug on windows') return end - eq({'error_types', 'functions', 'types', - 'ui_events', 'ui_options', 'version'}, api_info) + eq({ 'error_types', 'functions', 'types', 'ui_events', 'ui_options', 'version' }, api_info) end) it('fails when called with no arguments', function() - eq('Vim(call):E119: Not enough arguments for function: msgpackparse', - exc_exec('call msgpackparse()')) + eq( + 'Vim(call):E119: Not enough arguments for function: msgpackparse', + exc_exec('call msgpackparse()') + ) end) it('fails when called with two arguments', function() - eq('Vim(call):E118: Too many arguments for function: msgpackparse', - exc_exec('call msgpackparse(["", ""], 1)')) + eq( + 'Vim(call):E118: Too many arguments for function: msgpackparse', + exc_exec('call msgpackparse(["", ""], 1)') + ) end) it('fails to parse a string', function() - eq('Vim(call):E899: Argument of msgpackparse() must be a List or Blob', - exc_exec('call msgpackparse("abcdefghijklmnopqrstuvwxyz")')) + eq( + 'Vim(call):E899: Argument of msgpackparse() must be a List or Blob', + exc_exec('call msgpackparse("abcdefghijklmnopqrstuvwxyz")') + ) end) it('fails to parse a number', function() - eq('Vim(call):E899: Argument of msgpackparse() must be a List or Blob', - exc_exec('call msgpackparse(127)')) + eq( + 'Vim(call):E899: Argument of msgpackparse() must be a List or Blob', + exc_exec('call msgpackparse(127)') + ) end) it('fails to parse a dictionary', function() - eq('Vim(call):E899: Argument of msgpackparse() must be a List or Blob', - exc_exec('call msgpackparse({})')) + eq( + 'Vim(call):E899: Argument of msgpackparse() must be a List or Blob', + exc_exec('call msgpackparse({})') + ) end) it('fails to parse a funcref', function() - eq('Vim(call):E899: Argument of msgpackparse() must be a List or Blob', - exc_exec('call msgpackparse(function("tr"))')) + eq( + 'Vim(call):E899: Argument of msgpackparse() must be a List or Blob', + exc_exec('call msgpackparse(function("tr"))') + ) end) it('fails to parse a partial', function() command('function T() dict\nendfunction') - eq('Vim(call):E899: Argument of msgpackparse() must be a List or Blob', - exc_exec('call msgpackparse(function("T", [1, 2], {}))')) + eq( + 'Vim(call):E899: Argument of msgpackparse() must be a List or Blob', + exc_exec('call msgpackparse(function("T", [1, 2], {}))') + ) end) it('fails to parse a float', function() - eq('Vim(call):E899: Argument of msgpackparse() must be a List or Blob', - exc_exec('call msgpackparse(0.0)')) + eq( + 'Vim(call):E899: Argument of msgpackparse() must be a List or Blob', + exc_exec('call msgpackparse(0.0)') + ) end) it('fails on incomplete msgpack string', function() @@ -541,11 +562,11 @@ describe('msgpackdump() function', function() end it('dumps string as BIN 8', function() - dump_eq({'\196\004Test'}, '["Test"]') + dump_eq({ '\196\004Test' }, '["Test"]') end) it('dumps blob as BIN 8', function() - dump_eq({'\196\005Bl\nb!'}, '[0z426c006221]') + dump_eq({ '\196\005Bl\nb!' }, '[0z426c006221]') end) it('can dump generic mapping with generic mapping keys and values', function() @@ -553,209 +574,245 @@ describe('msgpackdump() function', function() command('let todumpv1 = {"_TYPE": v:msgpack_types.map, "_VAL": []}') command('let todumpv2 = {"_TYPE": v:msgpack_types.map, "_VAL": []}') command('call add(todump._VAL, [todumpv1, todumpv2])') - dump_eq({'\129\128\128'}, '[todump]') + dump_eq({ '\129\128\128' }, '[todump]') end) it('can dump v:true', function() - dump_eq({'\195'}, '[v:true]') + dump_eq({ '\195' }, '[v:true]') end) it('can dump v:false', function() - dump_eq({'\194'}, '[v:false]') + dump_eq({ '\194' }, '[v:false]') end) it('can dump v:null', function() - dump_eq({'\192'}, '[v:null]') + dump_eq({ '\192' }, '[v:null]') end) it('can dump special bool mapping (true)', function() command('let todump = {"_TYPE": v:msgpack_types.boolean, "_VAL": 1}') - dump_eq({'\195'}, '[todump]') + dump_eq({ '\195' }, '[todump]') end) it('can dump special bool mapping (false)', function() command('let todump = {"_TYPE": v:msgpack_types.boolean, "_VAL": 0}') - dump_eq({'\194'}, '[todump]') + dump_eq({ '\194' }, '[todump]') end) it('can dump special nil mapping', function() command('let todump = {"_TYPE": v:msgpack_types.nil, "_VAL": 0}') - dump_eq({'\192'}, '[todump]') + dump_eq({ '\192' }, '[todump]') end) it('can dump special ext mapping', function() command('let todump = {"_TYPE": v:msgpack_types.ext, "_VAL": [5, ["",""]]}') - dump_eq({'\212\005', ''}, '[todump]') + dump_eq({ '\212\005', '' }, '[todump]') end) it('can dump special array mapping', function() command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": [5, [""]]}') - dump_eq({'\146\005\145\196\n'}, '[todump]') + dump_eq({ '\146\005\145\196\n' }, '[todump]') end) it('can dump special UINT64_MAX mapping', function() command('let todump = {"_TYPE": v:msgpack_types.integer}') command('let todump._VAL = [1, 3, 0x7FFFFFFF, 0x7FFFFFFF]') - dump_eq({'\207\255\255\255\255\255\255\255\255'}, '[todump]') + dump_eq({ '\207\255\255\255\255\255\255\255\255' }, '[todump]') end) it('can dump special INT64_MIN mapping', function() command('let todump = {"_TYPE": v:msgpack_types.integer}') command('let todump._VAL = [-1, 2, 0, 0]') - dump_eq({'\211\128\n\n\n\n\n\n\n'}, '[todump]') + dump_eq({ '\211\128\n\n\n\n\n\n\n' }, '[todump]') end) it('fails to dump a function reference', function() command('let Todump = function("tr")') - eq('Vim(call):E5004: Error while dumping msgpackdump() argument, index 0, itself: attempt to dump function reference', - exc_exec('call msgpackdump([Todump])')) + eq( + 'Vim(call):E5004: Error while dumping msgpackdump() argument, index 0, itself: attempt to dump function reference', + exc_exec('call msgpackdump([Todump])') + ) end) it('fails to dump a partial', function() command('function T() dict\nendfunction') command('let Todump = function("T", [1, 2], {})') - eq('Vim(call):E5004: Error while dumping msgpackdump() argument, index 0, itself: attempt to dump function reference', - exc_exec('call msgpackdump([Todump])')) + eq( + 'Vim(call):E5004: Error while dumping msgpackdump() argument, index 0, itself: attempt to dump function reference', + exc_exec('call msgpackdump([Todump])') + ) end) it('fails to dump a function reference in a list', function() command('let todump = [function("tr")]') - eq('Vim(call):E5004: Error while dumping msgpackdump() argument, index 0, index 0: attempt to dump function reference', - exc_exec('call msgpackdump([todump])')) + eq( + 'Vim(call):E5004: Error while dumping msgpackdump() argument, index 0, index 0: attempt to dump function reference', + exc_exec('call msgpackdump([todump])') + ) end) it('fails to dump a recursive list', function() command('let todump = [[[]]]') command('call add(todump[0][0], todump)') - eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0, index 0, index 0', - exc_exec('call msgpackdump([todump])')) + eq( + 'Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0, index 0, index 0', + exc_exec('call msgpackdump([todump])') + ) end) it('fails to dump a recursive dict', function() command('let todump = {"d": {"d": {}}}') command('call extend(todump.d.d, {"d": todump})') - eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key \'d\', key \'d\', key \'d\'', - exc_exec('call msgpackdump([todump])')) + eq( + "Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key 'd', key 'd', key 'd'", + exc_exec('call msgpackdump([todump])') + ) end) it('can dump dict with two same dicts inside', function() command('let inter = {}') command('let todump = {"a": inter, "b": inter}') - dump_eq({"\130\161a\128\161b\128"}, '[todump]') + dump_eq({ '\130\161a\128\161b\128' }, '[todump]') end) it('can dump list with two same lists inside', function() command('let inter = []') command('let todump = [inter, inter]') - dump_eq({"\146\144\144"}, '[todump]') + dump_eq({ '\146\144\144' }, '[todump]') end) it('fails to dump a recursive list in a special dict', function() command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}') command('call add(todump._VAL, todump)') - eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0', - exc_exec('call msgpackdump([todump])')) + eq( + 'Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0', + exc_exec('call msgpackdump([todump])') + ) end) it('fails to dump a recursive (key) map in a special dict', function() command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}') command('call add(todump._VAL, [todump, 0])') - eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0', - exc_exec('call msgpackdump([todump])')) + eq( + 'Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0', + exc_exec('call msgpackdump([todump])') + ) end) it('fails to dump a recursive (val) map in a special dict', function() command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}') command('call add(todump._VAL, [0, todump])') - eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key 0 at index 0 from special map', - exc_exec('call msgpackdump([todump])')) + eq( + 'Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key 0 at index 0 from special map', + exc_exec('call msgpackdump([todump])') + ) end) it('fails to dump a recursive (key) map in a special dict, _VAL reference', function() command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[[], []]]}') command('call add(todump._VAL[0][0], todump._VAL)') - eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key [[[[...@0], []]]] at index 0 from special map, index 0', - exc_exec('call msgpackdump([todump])')) + eq( + 'Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key [[[[...@0], []]]] at index 0 from special map, index 0', + exc_exec('call msgpackdump([todump])') + ) end) it('fails to dump a recursive (val) map in a special dict, _VAL reference', function() command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[[], []]]}') command('call add(todump._VAL[0][1], todump._VAL)') - eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key [] at index 0 from special map, index 0', - exc_exec('call msgpackdump([todump])')) + eq( + 'Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key [] at index 0 from special map, index 0', + exc_exec('call msgpackdump([todump])') + ) end) - it('fails to dump a recursive (val) special list in a special dict', - function() + it('fails to dump a recursive (val) special list in a special dict', function() command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}') command('call add(todump._VAL, [0, todump._VAL])') - eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0, index 1', - exc_exec('call msgpackdump([todump])')) + eq( + 'Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0, index 1', + exc_exec('call msgpackdump([todump])') + ) end) it('fails when called with no arguments', function() - eq('Vim(call):E119: Not enough arguments for function: msgpackdump', - exc_exec('call msgpackdump()')) + eq( + 'Vim(call):E119: Not enough arguments for function: msgpackdump', + exc_exec('call msgpackdump()') + ) end) it('fails when called with three arguments', function() - eq('Vim(call):E118: Too many arguments for function: msgpackdump', - exc_exec('call msgpackdump(["", ""], 1, 2)')) + eq( + 'Vim(call):E118: Too many arguments for function: msgpackdump', + exc_exec('call msgpackdump(["", ""], 1, 2)') + ) end) it('fails to dump a string', function() - eq('Vim(call):E686: Argument of msgpackdump() must be a List', - exc_exec('call msgpackdump("abcdefghijklmnopqrstuvwxyz")')) + eq( + 'Vim(call):E686: Argument of msgpackdump() must be a List', + exc_exec('call msgpackdump("abcdefghijklmnopqrstuvwxyz")') + ) end) it('fails to dump a number', function() - eq('Vim(call):E686: Argument of msgpackdump() must be a List', - exc_exec('call msgpackdump(127)')) + eq( + 'Vim(call):E686: Argument of msgpackdump() must be a List', + exc_exec('call msgpackdump(127)') + ) end) it('fails to dump a dictionary', function() - eq('Vim(call):E686: Argument of msgpackdump() must be a List', - exc_exec('call msgpackdump({})')) + eq('Vim(call):E686: Argument of msgpackdump() must be a List', exc_exec('call msgpackdump({})')) end) it('fails to dump a funcref', function() - eq('Vim(call):E686: Argument of msgpackdump() must be a List', - exc_exec('call msgpackdump(function("tr"))')) + eq( + 'Vim(call):E686: Argument of msgpackdump() must be a List', + exc_exec('call msgpackdump(function("tr"))') + ) end) it('fails to dump a partial', function() command('function T() dict\nendfunction') - eq('Vim(call):E686: Argument of msgpackdump() must be a List', - exc_exec('call msgpackdump(function("T", [1, 2], {}))')) + eq( + 'Vim(call):E686: Argument of msgpackdump() must be a List', + exc_exec('call msgpackdump(function("T", [1, 2], {}))') + ) end) it('fails to dump a float', function() - eq('Vim(call):E686: Argument of msgpackdump() must be a List', - exc_exec('call msgpackdump(0.0)')) + eq( + 'Vim(call):E686: Argument of msgpackdump() must be a List', + exc_exec('call msgpackdump(0.0)') + ) end) it('fails to dump special value', function() - for _, val in ipairs({'v:true', 'v:false', 'v:null'}) do - eq('Vim(call):E686: Argument of msgpackdump() must be a List', - exc_exec('call msgpackdump(' .. val .. ')')) + for _, val in ipairs({ 'v:true', 'v:false', 'v:null' }) do + eq( + 'Vim(call):E686: Argument of msgpackdump() must be a List', + exc_exec('call msgpackdump(' .. val .. ')') + ) end end) it('can dump NULL string', function() - dump_eq({'\196\n'}, '[$XXX_UNEXISTENT_VAR_XXX]') - dump_eq({'\196\n'}, '[{"_TYPE": v:msgpack_types.binary, "_VAL": [$XXX_UNEXISTENT_VAR_XXX]}]') - dump_eq({'\160'}, '[{"_TYPE": v:msgpack_types.string, "_VAL": [$XXX_UNEXISTENT_VAR_XXX]}]') + dump_eq({ '\196\n' }, '[$XXX_UNEXISTENT_VAR_XXX]') + dump_eq({ '\196\n' }, '[{"_TYPE": v:msgpack_types.binary, "_VAL": [$XXX_UNEXISTENT_VAR_XXX]}]') + dump_eq({ '\160' }, '[{"_TYPE": v:msgpack_types.string, "_VAL": [$XXX_UNEXISTENT_VAR_XXX]}]') end) it('can dump NULL blob', function() - eq({'\196\n'}, eval('msgpackdump([v:_null_blob])')) + eq({ '\196\n' }, eval('msgpackdump([v:_null_blob])')) end) it('can dump NULL list', function() - eq({'\144'}, eval('msgpackdump([v:_null_list])')) + eq({ '\144' }, eval('msgpackdump([v:_null_list])')) end) it('can dump NULL dictionary', function() - eq({'\128'}, eval('msgpackdump([v:_null_dict])')) + eq({ '\128' }, eval('msgpackdump([v:_null_dict])')) end) end) diff --git a/test/functional/vimscript/null_spec.lua b/test/functional/vimscript/null_spec.lua index d4c36d835b..805cd13844 100644 --- a/test/functional/vimscript/null_spec.lua +++ b/test/functional/vimscript/null_spec.lua @@ -1,23 +1,22 @@ local helpers = require('test.functional.helpers')(after_each) -local curbufmeths = helpers.curbufmeths local exc_exec = helpers.exc_exec local command = helpers.command local clear = helpers.clear -local meths = helpers.meths -local funcs = helpers.funcs +local api = helpers.api +local fn = helpers.fn local eq = helpers.eq local function redir_exec(cmd) - meths.set_var('__redir_exec_cmd', cmd) + api.nvim_set_var('__redir_exec_cmd', cmd) command([[ redir => g:__redir_exec_output silent! execute g:__redir_exec_cmd redir END ]]) - local ret = meths.get_var('__redir_exec_output') - meths.del_var('__redir_exec_output') - meths.del_var('__redir_exec_cmd') + local ret = api.nvim_get_var('__redir_exec_output') + api.nvim_del_var('__redir_exec_output') + api.nvim_del_var('__redir_exec_cmd') return ret end @@ -40,12 +39,11 @@ describe('NULL', function() end local null_expr_test = function(name, expr, err, val, after) it(name, function() - eq((err == 0) and ('') or ('\n' .. err), - redir_exec('let g:_var = ' .. expr)) + eq((err == 0) and '' or ('\n' .. err), redir_exec('let g:_var = ' .. expr)) if val == nil then - eq(0, funcs.exists('g:_var')) + eq(0, fn.exists('g:_var')) else - eq(val, meths.get_var('_var')) + eq(val, api.nvim_get_var('_var')) end if after ~= nil then after() @@ -58,25 +56,31 @@ describe('NULL', function() null_expr_test('is equal to empty list (reverse order)', '[] == L', 0, 1) -- Correct behaviour - null_test('can be :unlet item with error message for empty list', ':unlet L[0]', - 'Vim(unlet):E684: List index out of range: 0') - null_expr_test('can be indexed with error message for empty list', 'L[0]', - 'E684: List index out of range: 0', nil) + null_test( + 'can be :unlet item with error message for empty list', + ':unlet L[0]', + 'Vim(unlet):E684: List index out of range: 0' + ) + null_expr_test( + 'can be indexed with error message for empty list', + 'L[0]', + 'E684: List index out of range: 0', + nil + ) null_expr_test('can be splice-indexed', 'L[:]', 0, {}) null_expr_test('is not locked', 'islocked("v:_null_list")', 0, 0) null_test('is accepted by :for', 'for x in L|throw x|endfor', 0) null_expr_test('does not crash append()', 'append(0, L)', 0, 0, function() - eq({''}, curbufmeths.get_lines(0, -1, false)) + eq({ '' }, api.nvim_buf_get_lines(0, 0, -1, false)) end) null_expr_test('does not crash setline()', 'setline(1, L)', 0, 0, function() - eq({''}, curbufmeths.get_lines(0, -1, false)) + eq({ '' }, api.nvim_buf_get_lines(0, 0, -1, false)) end) null_expr_test('is identical to itself', 'L is L', 0, 1) null_expr_test('can be sliced', 'L[:]', 0, {}) null_expr_test('can be copied', 'copy(L)', 0, {}) null_expr_test('can be deepcopied', 'deepcopy(L)', 0, {}) - null_expr_test('does not crash when indexed', 'L[1]', - 'E684: List index out of range: 1', nil) + null_expr_test('does not crash when indexed', 'L[1]', 'E684: List index out of range: 1', nil) null_expr_test('does not crash call()', 'call("arglistid", L)', 0, 0) null_expr_test('does not crash col()', 'col(L)', 0, 0) null_expr_test('does not crash virtcol()', 'virtcol(L)', 0, 0) @@ -96,44 +100,92 @@ describe('NULL', function() null_test('does not crash lockvar', 'lockvar! L', 0) null_expr_test('can be added to itself', '(L + L)', 0, {}) null_expr_test('can be added to itself', '(L + L) is L', 0, 1) - null_expr_test('can be added to non-empty list', '([1] + L)', 0, {1}) - null_expr_test('can be added to non-empty list (reversed)', '(L + [1])', 0, {1}) + null_expr_test('can be added to non-empty list', '([1] + L)', 0, { 1 }) + null_expr_test('can be added to non-empty list (reversed)', '(L + [1])', 0, { 1 }) null_expr_test('is equal to itself', 'L == L', 0, 1) null_expr_test('is not not equal to itself', 'L != L', 0, 0) null_expr_test('counts correctly', 'count([L], L)', 0, 1) null_expr_test('makes map() return v:_null_list', 'map(L, "v:val") is# L', 0, 1) null_expr_test('makes filter() return v:_null_list', 'filter(L, "1") is# L', 0, 1) - null_test('is treated by :let as empty list', ':let [l] = L', 'Vim(let):E688: More targets than List items') - null_expr_test('is accepted as an empty list by inputlist()', '[feedkeys("\\n"), inputlist(L)]', - 'Type number and <Enter> or click with the mouse (q or empty cancels): ', {0, 0}) - null_expr_test('is accepted as an empty list by writefile()', - ('[writefile(L, "%s"), readfile("%s")]'):format(tmpfname, tmpfname), - 0, {0, {}}) - null_expr_test('makes add() error out', 'add(L, 0)', - 'E742: Cannot change value of add() argument', 1) - null_expr_test('makes insert() error out', 'insert(L, 1)', - 'E742: Cannot change value of insert() argument', 0) - null_expr_test('does not crash remove()', 'remove(L, 0)', - 'E742: Cannot change value of remove() argument', 0) - null_expr_test('makes reverse() error out', 'reverse(L)', - 'E742: Cannot change value of reverse() argument', 0) - null_expr_test('makes sort() error out', 'sort(L)', - 'E742: Cannot change value of sort() argument', 0) - null_expr_test('makes uniq() error out', 'uniq(L)', - 'E742: Cannot change value of uniq() argument', 0) - null_expr_test('does not crash extend()', 'extend(L, [1])', 'E742: Cannot change value of extend() argument', 0) - null_expr_test('does not crash extend() (second position)', 'extend([1], L)', 0, {1}) + null_test( + 'is treated by :let as empty list', + ':let [l] = L', + 'Vim(let):E688: More targets than List items' + ) + null_expr_test( + 'is accepted as an empty list by inputlist()', + '[feedkeys("\\n"), inputlist(L)]', + 'Type number and <Enter> or click with the mouse (q or empty cancels): ', + { 0, 0 } + ) + null_expr_test( + 'is accepted as an empty list by writefile()', + ('[writefile(L, "%s"), readfile("%s")]'):format(tmpfname, tmpfname), + 0, + { 0, {} } + ) + null_expr_test( + 'makes add() error out', + 'add(L, 0)', + 'E742: Cannot change value of add() argument', + 1 + ) + null_expr_test( + 'makes insert() error out', + 'insert(L, 1)', + 'E742: Cannot change value of insert() argument', + 0 + ) + null_expr_test( + 'does not crash remove()', + 'remove(L, 0)', + 'E742: Cannot change value of remove() argument', + 0 + ) + null_expr_test( + 'makes reverse() error out', + 'reverse(L)', + 'E742: Cannot change value of reverse() argument', + 0 + ) + null_expr_test( + 'makes sort() error out', + 'sort(L)', + 'E742: Cannot change value of sort() argument', + 0 + ) + null_expr_test( + 'makes uniq() error out', + 'uniq(L)', + 'E742: Cannot change value of uniq() argument', + 0 + ) + null_expr_test( + 'does not crash extend()', + 'extend(L, [1])', + 'E742: Cannot change value of extend() argument', + 0 + ) + null_expr_test('does not crash extend() (second position)', 'extend([1], L)', 0, { 1 }) null_expr_test('makes join() return empty string', 'join(L, "")', 0, '') null_expr_test('makes msgpackdump() return empty list', 'msgpackdump(L)', 0, {}) null_expr_test('does not crash system()', 'system("cat", L)', 0, '') null_expr_test('does not crash setreg', 'setreg("x", L)', 0, 0) null_expr_test('does not crash systemlist()', 'systemlist("cat", L)', 0, {}) - null_test('does not make Neovim crash when v:oldfiles gets assigned to that', ':let v:oldfiles = L|oldfiles', 0) - null_expr_test('does not make complete() crash or error out', - 'execute(":normal i\\<C-r>=complete(1, L)[-1]\\n")', - 0, '', function() - eq({''}, curbufmeths.get_lines(0, -1, false)) - end) + null_test( + 'does not make Neovim crash when v:oldfiles gets assigned to that', + ':let v:oldfiles = L|oldfiles', + 0 + ) + null_expr_test( + 'does not make complete() crash or error out', + 'execute(":normal i\\<C-r>=complete(1, L)[-1]\\n")', + 0, + '', + function() + eq({ '' }, api.nvim_buf_get_lines(0, 0, -1, false)) + end + ) null_expr_test('is accepted by setmatches()', 'setmatches(L)', 0, 0) null_expr_test('is accepted by setqflist()', 'setqflist(L)', 0, 0) null_expr_test('is accepted by setloclist()', 'setloclist(1, L)', 0, 0) @@ -143,11 +195,15 @@ describe('NULL', function() end) describe('dict', function() it('does not crash when indexing NULL dict', function() - eq('\nE716: Key not present in Dictionary: "test"', - redir_exec('echo v:_null_dict.test')) + eq('\nE716: Key not present in Dictionary: "test"', redir_exec('echo v:_null_dict.test')) end) - null_expr_test('makes extend error out', 'extend(D, {})', 'E742: Cannot change value of extend() argument', 0) - null_expr_test('makes extend do nothing', 'extend({1: 2}, D)', 0, {['1']=2}) + null_expr_test( + 'makes extend error out', + 'extend(D, {})', + 'E742: Cannot change value of extend() argument', + 0 + ) + null_expr_test('makes extend do nothing', 'extend({1: 2}, D)', 0, { ['1'] = 2 }) null_expr_test('does not crash map()', 'map(D, "v:val")', 0, {}) null_expr_test('does not crash filter()', 'filter(D, "1")', 0, {}) null_expr_test('makes map() return v:_null_dict', 'map(D, "v:val") is# D', 0, 1) @@ -158,7 +214,12 @@ describe('NULL', function() null_test('does not crash :execute', 'execute S', 0) null_expr_test('does not crash execute()', 'execute(S)', 0, '') null_expr_test('does not crash executable()', 'executable(S)', 0, 0) - null_expr_test('makes timer_start() error out', 'timer_start(0, S)', 'E921: Invalid callback argument', -1) + null_expr_test( + 'makes timer_start() error out', + 'timer_start(0, S)', + 'E921: Invalid callback argument', + -1 + ) null_expr_test('does not crash filereadable()', 'filereadable(S)', 0, 0) null_expr_test('does not crash filewritable()', 'filewritable(S)', 0, 0) null_expr_test('does not crash fnamemodify()', 'fnamemodify(S, S)', 0, '') @@ -169,7 +230,7 @@ describe('NULL', function() null_expr_test('does not crash glob()', 'glob(S)', 0, '') null_expr_test('does not crash globpath()', 'globpath(S, S)', 0, '') null_expr_test('does not crash mkdir()', 'mkdir(S)', 0, 0) - null_expr_test('does not crash sort()', 'sort(["b", S, "a"])', 0, {'', 'a', 'b'}) + null_expr_test('does not crash sort()', 'sort(["b", S, "a"])', 0, { '', 'a', 'b' }) null_expr_test('does not crash split()', 'split(S)', 0, {}) null_test('can be used to set an option', 'let &grepprg = S', 0) diff --git a/test/functional/vimscript/operators_spec.lua b/test/functional/vimscript/operators_spec.lua index 4d07bc1b05..64f6b60238 100644 --- a/test/functional/vimscript/operators_spec.lua +++ b/test/functional/vimscript/operators_spec.lua @@ -7,22 +7,22 @@ describe('Division operator', function() before_each(clear) it('returns infinity on {positive}/0.0', function() - eq('str2float(\'inf\')', eval('string(1.0/0.0)')) - eq('str2float(\'inf\')', eval('string(1.0e-100/0.0)')) - eq('str2float(\'inf\')', eval('string(1.0e+100/0.0)')) - eq('str2float(\'inf\')', eval('string((1.0/0.0)/0.0)')) + eq("str2float('inf')", eval('string(1.0/0.0)')) + eq("str2float('inf')", eval('string(1.0e-100/0.0)')) + eq("str2float('inf')", eval('string(1.0e+100/0.0)')) + eq("str2float('inf')", eval('string((1.0/0.0)/0.0)')) end) it('returns -infinity on {negative}/0.0', function() - eq('-str2float(\'inf\')', eval('string((-1.0)/0.0)')) - eq('-str2float(\'inf\')', eval('string((-1.0e-100)/0.0)')) - eq('-str2float(\'inf\')', eval('string((-1.0e+100)/0.0)')) - eq('-str2float(\'inf\')', eval('string((-1.0/0.0)/0.0)')) + eq("-str2float('inf')", eval('string((-1.0)/0.0)')) + eq("-str2float('inf')", eval('string((-1.0e-100)/0.0)')) + eq("-str2float('inf')", eval('string((-1.0e+100)/0.0)')) + eq("-str2float('inf')", eval('string((-1.0/0.0)/0.0)')) end) it('returns NaN on 0.0/0.0', function() - eq('str2float(\'nan\')', eval('string(0.0/0.0)')) - eq('str2float(\'nan\')', eval('string(-(0.0/0.0))')) - eq('str2float(\'nan\')', eval('string((-0.0)/0.0)')) + eq("str2float('nan')", eval('string(0.0/0.0)')) + eq("str2float('nan')", eval('string(-(0.0/0.0))')) + eq("str2float('nan')", eval('string((-0.0)/0.0)')) end) end) diff --git a/test/functional/vimscript/printf_spec.lua b/test/functional/vimscript/printf_spec.lua index 27e24c4118..4fa4ea7f4c 100644 --- a/test/functional/vimscript/printf_spec.lua +++ b/test/functional/vimscript/printf_spec.lua @@ -3,56 +3,56 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local eq = helpers.eq local eval = helpers.eval -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local exc_exec = helpers.exc_exec describe('printf()', function() before_each(clear) it('works with zero and %b', function() - eq('0', funcs.printf('%lb', 0)) - eq('0', funcs.printf('%llb', 0)) - eq('0', funcs.printf('%zb', 0)) + eq('0', fn.printf('%lb', 0)) + eq('0', fn.printf('%llb', 0)) + eq('0', fn.printf('%zb', 0)) end) it('works with one and %b', function() - eq('1', funcs.printf('%b', 1)) - eq('1', funcs.printf('%lb', 1)) - eq('1', funcs.printf('%llb', 1)) - eq('1', funcs.printf('%zb', 1)) + eq('1', fn.printf('%b', 1)) + eq('1', fn.printf('%lb', 1)) + eq('1', fn.printf('%llb', 1)) + eq('1', fn.printf('%zb', 1)) end) it('works with 0xff and %b', function() - eq('11111111', funcs.printf('%b', 0xff)) - eq('11111111', funcs.printf('%lb', 0xff)) - eq('11111111', funcs.printf('%llb', 0xff)) - eq('11111111', funcs.printf('%zb', 0xff)) + eq('11111111', fn.printf('%b', 0xff)) + eq('11111111', fn.printf('%lb', 0xff)) + eq('11111111', fn.printf('%llb', 0xff)) + eq('11111111', fn.printf('%zb', 0xff)) end) it('accepts width modifier with %b', function() - eq(' 1', funcs.printf('%3b', 1)) + eq(' 1', fn.printf('%3b', 1)) end) it('accepts prefix modifier with %b', function() - eq('0b1', funcs.printf('%#b', 1)) + eq('0b1', fn.printf('%#b', 1)) end) it('writes capital B with %B', function() - eq('0B1', funcs.printf('%#B', 1)) + eq('0B1', fn.printf('%#B', 1)) end) it('accepts prefix, zero-fill and width modifiers with %b', function() - eq('0b001', funcs.printf('%#05b', 1)) + eq('0b001', fn.printf('%#05b', 1)) end) it('accepts prefix and width modifiers with %b', function() - eq(' 0b1', funcs.printf('%#5b', 1)) + eq(' 0b1', fn.printf('%#5b', 1)) end) it('does not write prefix for zero with prefix and width modifier used with %b', function() - eq(' 0', funcs.printf('%#5b', 0)) + eq(' 0', fn.printf('%#5b', 0)) end) it('accepts precision modifier with %b', function() - eq('00000', funcs.printf('%.5b', 0)) + eq('00000', fn.printf('%.5b', 0)) end) it('accepts all modifiers with %b at once', function() -- zero-fill modifier is ignored when used with left-align -- force-sign and add-blank are ignored -- use-grouping-characters modifier is ignored always - eq('0b00011 ', funcs.printf('% \'+#0-10.5b', 3)) + eq('0b00011 ', fn.printf("% '+#0-10.5b", 3)) end) it('errors out when %b modifier is used for a list', function() eq('Vim(call):E745: Using a List as a Number', exc_exec('call printf("%b", [])')) @@ -65,12 +65,12 @@ describe('printf()', function() local seen_rets = {} -- Collect all args in an array to avoid possible allocation of the same -- address after freeing unreferenced values. - meths.set_var('__args', {}) + api.nvim_set_var('__args', {}) local function check_printf(expr, is_null) eq(0, exc_exec('call add(__args, ' .. expr .. ')')) eq(0, exc_exec('let __result = printf("%p", __args[-1])')) local id_ret = eval('id(__args[-1])') - eq(id_ret, meths.get_var('__result')) + eq(id_ret, api.nvim_get_var('__result')) if is_null then if null_ret then eq(null_ret, id_ret) @@ -81,7 +81,7 @@ describe('printf()', function() eq(nil, seen_rets[id_ret]) seen_rets[id_ret] = expr end - meths.del_var('__result') + api.nvim_del_var('__result') end check_printf('v:_null_list', true) check_printf('v:_null_dict', true) diff --git a/test/functional/vimscript/reltime_spec.lua b/test/functional/vimscript/reltime_spec.lua index 6d661402a6..7cdb78e4ce 100644 --- a/test/functional/vimscript/reltime_spec.lua +++ b/test/functional/vimscript/reltime_spec.lua @@ -1,7 +1,7 @@ local helpers = require('test.functional.helpers')(after_each) -local clear, eq, ok = helpers.clear, helpers.eq, helpers.ok -local neq, command, funcs = helpers.neq, helpers.command, helpers.funcs -local reltime, reltimestr, reltimefloat = funcs.reltime, funcs.reltimestr, funcs.reltimefloat +local clear, eq, ok = helpers.clear, helpers.eq, helpers.ok +local neq, command, fn = helpers.neq, helpers.command, helpers.fn +local reltime, reltimestr, reltimefloat = fn.reltime, fn.reltimestr, fn.reltimefloat describe('reltimestr(), reltimefloat()', function() before_each(clear) @@ -15,7 +15,7 @@ describe('reltimestr(), reltimefloat()', function() neq('0.0', reltimestr(elapsed)) ok(reltimefloat(elapsed) > 0.0) -- original vim test for < 0.1, but easily fails on travis - ok(nil ~= string.match(reltimestr(elapsed), "0%.")) + ok(nil ~= string.match(reltimestr(elapsed), '0%.')) ok(reltimefloat(elapsed) < 1.0) local same = reltime(now, now) @@ -29,7 +29,7 @@ describe('reltimestr(), reltimefloat()', function() neq('0.0', reltimestr(differs)) ok(reltimefloat(differs) > 0.0) -- original vim test for < 0.1, but easily fails on travis - ok(nil ~= string.match(reltimestr(differs), "0%.")) + ok(nil ~= string.match(reltimestr(differs), '0%.')) ok(reltimefloat(differs) < 1.0) end) diff --git a/test/functional/vimscript/screenchar_spec.lua b/test/functional/vimscript/screenchar_spec.lua index 767e3c57ef..48b6893865 100644 --- a/test/functional/vimscript/screenchar_spec.lua +++ b/test/functional/vimscript/screenchar_spec.lua @@ -1,7 +1,7 @@ local helpers = require('test.functional.helpers')(after_each) local clear, eq, neq = helpers.clear, helpers.eq, helpers.neq -local command, meths, funcs = helpers.command, helpers.meths, helpers.funcs -local tbl_deep_extend = helpers.tbl_deep_extend +local command, api, fn = helpers.command, helpers.api, helpers.fn +local tbl_deep_extend = vim.tbl_deep_extend -- Set up two overlapping floating windows local setup_floating_windows = function() @@ -14,15 +14,15 @@ local setup_floating_windows = function() border = 'none', } - local bufnr_1 = meths.create_buf(false, true) - meths.buf_set_lines(bufnr_1, 0, -1, true, { 'aa' }) + local bufnr_1 = api.nvim_create_buf(false, true) + api.nvim_buf_set_lines(bufnr_1, 0, -1, true, { 'aa' }) local opts_1 = tbl_deep_extend('force', { row = 0, col = 0, zindex = 11 }, base_opts) - meths.open_win(bufnr_1, false, opts_1) + api.nvim_open_win(bufnr_1, false, opts_1) - local bufnr_2 = meths.create_buf(false, true) - meths.buf_set_lines(bufnr_2, 0, -1, true, { 'bb' }) + local bufnr_2 = api.nvim_create_buf(false, true) + api.nvim_buf_set_lines(bufnr_2, 0, -1, true, { 'bb' }) local opts_2 = tbl_deep_extend('force', { row = 0, col = 1, zindex = 10 }, base_opts) - meths.open_win(bufnr_2, false, opts_2) + api.nvim_open_win(bufnr_2, false, opts_2) command('redraw') end @@ -32,38 +32,38 @@ describe('screenchar() and family respect floating windows', function() clear() -- These commands result into visible text `aabc`. -- `aab` - from floating windows, `c` - from text in regular window. - meths.buf_set_lines(0, 0, -1, true, { 'cccc' }) + api.nvim_buf_set_lines(0, 0, -1, true, { 'cccc' }) setup_floating_windows() end) it('screenattr()', function() - local attr_1 = funcs.screenattr(1, 1) - local attr_2 = funcs.screenattr(1, 2) - local attr_3 = funcs.screenattr(1, 3) - local attr_4 = funcs.screenattr(1, 4) + local attr_1 = fn.screenattr(1, 1) + local attr_2 = fn.screenattr(1, 2) + local attr_3 = fn.screenattr(1, 3) + local attr_4 = fn.screenattr(1, 4) eq(attr_1, attr_2) eq(attr_1, attr_3) neq(attr_1, attr_4) end) it('screenchar()', function() - eq(97, funcs.screenchar(1, 1)) - eq(97, funcs.screenchar(1, 2)) - eq(98, funcs.screenchar(1, 3)) - eq(99, funcs.screenchar(1, 4)) + eq(97, fn.screenchar(1, 1)) + eq(97, fn.screenchar(1, 2)) + eq(98, fn.screenchar(1, 3)) + eq(99, fn.screenchar(1, 4)) end) it('screenchars()', function() - eq({ 97 }, funcs.screenchars(1, 1)) - eq({ 97 }, funcs.screenchars(1, 2)) - eq({ 98 }, funcs.screenchars(1, 3)) - eq({ 99 }, funcs.screenchars(1, 4)) + eq({ 97 }, fn.screenchars(1, 1)) + eq({ 97 }, fn.screenchars(1, 2)) + eq({ 98 }, fn.screenchars(1, 3)) + eq({ 99 }, fn.screenchars(1, 4)) end) it('screenstring()', function() - eq('a', funcs.screenstring(1, 1)) - eq('a', funcs.screenstring(1, 2)) - eq('b', funcs.screenstring(1, 3)) - eq('c', funcs.screenstring(1, 4)) + eq('a', fn.screenstring(1, 1)) + eq('a', fn.screenstring(1, 2)) + eq('b', fn.screenstring(1, 3)) + eq('c', fn.screenstring(1, 4)) end) end) diff --git a/test/functional/vimscript/screenpos_spec.lua b/test/functional/vimscript/screenpos_spec.lua index 8b8276457d..b951d830a6 100644 --- a/test/functional/vimscript/screenpos_spec.lua +++ b/test/functional/vimscript/screenpos_spec.lua @@ -1,6 +1,6 @@ local helpers = require('test.functional.helpers')(after_each) -local clear, eq, meths = helpers.clear, helpers.eq, helpers.meths -local command, funcs = helpers.command, helpers.funcs +local clear, eq, api = helpers.clear, helpers.eq, helpers.api +local command, fn = helpers.command, helpers.fn local feed = helpers.feed before_each(clear) @@ -8,66 +8,72 @@ before_each(clear) describe('screenpos() function', function() it('works in floating window with border', function() local opts = { - relative='editor', - height=8, - width=12, - row=6, - col=8, - anchor='NW', - style='minimal', - border='none', - focusable=1 + relative = 'editor', + height = 8, + width = 12, + row = 6, + col = 8, + anchor = 'NW', + style = 'minimal', + border = 'none', + focusable = 1, } - local float = meths.open_win(meths.create_buf(false, true), false, opts) + local float = api.nvim_open_win(api.nvim_create_buf(false, true), false, opts) command('redraw') - eq({row = 7, col = 9, endcol = 9, curscol = 9}, funcs.screenpos(float, 1, 1)) + eq({ row = 7, col = 9, endcol = 9, curscol = 9 }, fn.screenpos(float, 1, 1)) -- only left border - opts.border = {'', '', '', '', '', '', '', '|'} - meths.win_set_config(float, opts) + opts.border = { '', '', '', '', '', '', '', '|' } + api.nvim_win_set_config(float, opts) command('redraw') - eq({row = 7, col = 10, endcol = 10, curscol = 10}, funcs.screenpos(float, 1, 1)) + eq({ row = 7, col = 10, endcol = 10, curscol = 10 }, fn.screenpos(float, 1, 1)) -- only top border - opts.border = {'', '_', '', '', '', '', '', ''} - meths.win_set_config(float, opts) + opts.border = { '', '_', '', '', '', '', '', '' } + api.nvim_win_set_config(float, opts) command('redraw') - eq({row = 8, col = 9, endcol = 9, curscol = 9}, funcs.screenpos(float, 1, 1)) + eq({ row = 8, col = 9, endcol = 9, curscol = 9 }, fn.screenpos(float, 1, 1)) -- both left and top border opts.border = 'single' - meths.win_set_config(float, opts) + api.nvim_win_set_config(float, opts) command('redraw') - eq({row = 8, col = 10, endcol = 10, curscol = 10}, funcs.screenpos(float, 1, 1)) + eq({ row = 8, col = 10, endcol = 10, curscol = 10 }, fn.screenpos(float, 1, 1)) end) it('works for folded line with virt_lines attached to line above', function() - meths.buf_set_lines(0, 0, -1, true, {'aaa', 'bbb', 'ccc', 'ddd'}) - local ns = meths.create_namespace('') - meths.buf_set_extmark(0, ns, 0, 0, { virt_lines = {{{'abb'}}, {{'acc'}}, {{'add'}}} }) + api.nvim_buf_set_lines(0, 0, -1, true, { 'aaa', 'bbb', 'ccc', 'ddd' }) + local ns = api.nvim_create_namespace('') + api.nvim_buf_set_extmark( + 0, + ns, + 0, + 0, + { virt_lines = { { { 'abb' } }, { { 'acc' } }, { { 'add' } } } } + ) command('2,3fold') - eq({row = 5, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 2, 1)) - eq({row = 5, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 3, 1)) - eq({row = 6, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 4, 1)) + eq({ row = 5, col = 1, endcol = 1, curscol = 1 }, fn.screenpos(0, 2, 1)) + eq({ row = 5, col = 1, endcol = 1, curscol = 1 }, fn.screenpos(0, 3, 1)) + eq({ row = 6, col = 1, endcol = 1, curscol = 1 }, fn.screenpos(0, 4, 1)) feed('<C-E>') - eq({row = 4, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 2, 1)) - eq({row = 4, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 3, 1)) - eq({row = 5, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 4, 1)) + eq({ row = 4, col = 1, endcol = 1, curscol = 1 }, fn.screenpos(0, 2, 1)) + eq({ row = 4, col = 1, endcol = 1, curscol = 1 }, fn.screenpos(0, 3, 1)) + eq({ row = 5, col = 1, endcol = 1, curscol = 1 }, fn.screenpos(0, 4, 1)) feed('<C-E>') - eq({row = 3, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 2, 1)) - eq({row = 3, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 3, 1)) - eq({row = 4, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 4, 1)) + eq({ row = 3, col = 1, endcol = 1, curscol = 1 }, fn.screenpos(0, 2, 1)) + eq({ row = 3, col = 1, endcol = 1, curscol = 1 }, fn.screenpos(0, 3, 1)) + eq({ row = 4, col = 1, endcol = 1, curscol = 1 }, fn.screenpos(0, 4, 1)) feed('<C-E>') - eq({row = 2, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 2, 1)) - eq({row = 2, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 3, 1)) - eq({row = 3, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 4, 1)) + eq({ row = 2, col = 1, endcol = 1, curscol = 1 }, fn.screenpos(0, 2, 1)) + eq({ row = 2, col = 1, endcol = 1, curscol = 1 }, fn.screenpos(0, 3, 1)) + eq({ row = 3, col = 1, endcol = 1, curscol = 1 }, fn.screenpos(0, 4, 1)) feed('<C-E>') - eq({row = 1, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 2, 1)) - eq({row = 1, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 3, 1)) - eq({row = 2, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 4, 1)) + eq({ row = 1, col = 1, endcol = 1, curscol = 1 }, fn.screenpos(0, 2, 1)) + eq({ row = 1, col = 1, endcol = 1, curscol = 1 }, fn.screenpos(0, 3, 1)) + eq({ row = 2, col = 1, endcol = 1, curscol = 1 }, fn.screenpos(0, 4, 1)) end) end) diff --git a/test/functional/vimscript/server_spec.lua b/test/functional/vimscript/server_spec.lua index c89a0c4e93..360fcf0dfe 100644 --- a/test/functional/vimscript/server_spec.lua +++ b/test/functional/vimscript/server_spec.lua @@ -1,7 +1,7 @@ local helpers = require('test.functional.helpers')(after_each) local assert_log = helpers.assert_log local eq, neq, eval = helpers.eq, helpers.neq, helpers.eval -local clear, funcs, meths = helpers.clear, helpers.funcs, helpers.meths +local clear, fn, api = helpers.clear, helpers.fn, helpers.api local ok = helpers.ok local matches = helpers.matches local pcall_err = helpers.pcall_err @@ -11,8 +11,8 @@ local is_os = helpers.is_os local testlog = 'Xtest-server-log' local function clear_serverlist() - for _, server in pairs(funcs.serverlist()) do - funcs.serverstop(server) + for _, server in pairs(fn.serverlist()) do + fn.serverstop(server) end end @@ -24,120 +24,119 @@ describe('server', function() it('serverstart() stores sockets in $XDG_RUNTIME_DIR', function() local dir = 'Xtest_xdg_run' mkdir(dir) - clear({ env={ XDG_RUNTIME_DIR=dir } }) - matches(dir, funcs.stdpath('run')) + clear({ env = { XDG_RUNTIME_DIR = dir } }) + matches(dir, fn.stdpath('run')) if not is_os('win') then - matches(dir, funcs.serverstart()) + matches(dir, fn.serverstart()) end end) - it('serverstart(), serverstop() does not set $NVIM', function() clear() local s = eval('serverstart()') - assert(s ~= nil and s:len() > 0, "serverstart() returned empty") + assert(s ~= nil and s:len() > 0, 'serverstart() returned empty') eq('', eval('$NVIM')) eq('', eval('$NVIM_LISTEN_ADDRESS')) - eq(1, eval("serverstop('"..s.."')")) + eq(1, eval("serverstop('" .. s .. "')")) eq('', eval('$NVIM_LISTEN_ADDRESS')) end) it('sets new v:servername if $NVIM_LISTEN_ADDRESS is invalid', function() - clear({env={NVIM_LISTEN_ADDRESS='.'}}) + clear({ env = { NVIM_LISTEN_ADDRESS = '.' } }) -- Cleared on startup. eq('', eval('$NVIM_LISTEN_ADDRESS')) - local servers = funcs.serverlist() + local servers = fn.serverlist() eq(1, #servers) - ok(string.len(servers[1]) > 4) -- "~/.local/state/nvim…/…" or "\\.\pipe\…" + ok(string.len(servers[1]) > 4) -- "~/.local/state/nvim…/…" or "\\.\pipe\…" end) it('sets v:servername at startup or if all servers were stopped', function() clear() - local initial_server = meths.get_vvar('servername') - assert(initial_server ~= nil and initial_server:len() > 0, - 'v:servername was not initialized') + local initial_server = api.nvim_get_vvar('servername') + assert(initial_server ~= nil and initial_server:len() > 0, 'v:servername was not initialized') -- v:servername is readonly so we cannot unset it--but we can test that it -- does not get set again thereafter. - local s = funcs.serverstart() - assert(s ~= nil and s:len() > 0, "serverstart() returned empty") + local s = fn.serverstart() + assert(s ~= nil and s:len() > 0, 'serverstart() returned empty') neq(initial_server, s) -- serverstop() does _not_ modify v:servername... - eq(1, funcs.serverstop(s)) - eq(initial_server, meths.get_vvar('servername')) + eq(1, fn.serverstop(s)) + eq(initial_server, api.nvim_get_vvar('servername')) -- ...unless we stop _all_ servers. - eq(1, funcs.serverstop(funcs.serverlist()[1])) - eq('', meths.get_vvar('servername')) + eq(1, fn.serverstop(fn.serverlist()[1])) + eq('', api.nvim_get_vvar('servername')) -- v:servername and $NVIM take the next available server. - local servername = (is_os('win') and [[\\.\pipe\Xtest-functional-server-pipe]] - or './Xtest-functional-server-socket') - funcs.serverstart(servername) - eq(servername, meths.get_vvar('servername')) + local servername = ( + is_os('win') and [[\\.\pipe\Xtest-functional-server-pipe]] + or './Xtest-functional-server-socket' + ) + fn.serverstart(servername) + eq(servername, api.nvim_get_vvar('servername')) -- Not set in the current process, only in children. eq('', eval('$NVIM')) end) it('serverstop() returns false for invalid input', function() - clear{env={ - NVIM_LOG_FILE=testlog, - NVIM_LISTEN_ADDRESS='.', - }} + clear { env = { + NVIM_LOG_FILE = testlog, + NVIM_LISTEN_ADDRESS = '.', + } } eq(0, eval("serverstop('')")) eq(0, eval("serverstop('bogus-socket-name')")) assert_log('Not listening on bogus%-socket%-name', testlog, 10) end) it('parses endpoints', function() - clear{env={ - NVIM_LOG_FILE=testlog, - NVIM_LISTEN_ADDRESS='.', - }} + clear { env = { + NVIM_LOG_FILE = testlog, + NVIM_LISTEN_ADDRESS = '.', + } } clear_serverlist() - eq({}, funcs.serverlist()) + eq({}, fn.serverlist()) - local s = funcs.serverstart('127.0.0.1:0') -- assign random port + local s = fn.serverstart('127.0.0.1:0') -- assign random port if #s > 0 then assert(string.match(s, '127.0.0.1:%d+')) - eq(s, funcs.serverlist()[1]) + eq(s, fn.serverlist()[1]) clear_serverlist() end - s = funcs.serverstart('127.0.0.1:') -- assign random port + s = fn.serverstart('127.0.0.1:') -- assign random port if #s > 0 then assert(string.match(s, '127.0.0.1:%d+')) - eq(s, funcs.serverlist()[1]) + eq(s, fn.serverlist()[1]) clear_serverlist() end local expected = {} local v4 = '127.0.0.1:12345' - local status, _ = pcall(funcs.serverstart, v4) + local status, _ = pcall(fn.serverstart, v4) if status then table.insert(expected, v4) - pcall(funcs.serverstart, v4) -- exists already; ignore + pcall(fn.serverstart, v4) -- exists already; ignore assert_log('Failed to start server: address already in use: 127%.0%.0%.1', testlog, 10) end local v6 = '::1:12345' - status, _ = pcall(funcs.serverstart, v6) + status, _ = pcall(fn.serverstart, v6) if status then table.insert(expected, v6) - pcall(funcs.serverstart, v6) -- exists already; ignore + pcall(fn.serverstart, v6) -- exists already; ignore assert_log('Failed to start server: address already in use: ::1', testlog, 10) end - eq(expected, funcs.serverlist()) + eq(expected, fn.serverlist()) clear_serverlist() -- Address without slashes is a "name" which is appended to a generated path. #8519 - matches([[.*[/\\]xtest1%.2%.3%.4[^/\\]*]], funcs.serverstart('xtest1.2.3.4')) + matches([[.*[/\\]xtest1%.2%.3%.4[^/\\]*]], fn.serverstart('xtest1.2.3.4')) clear_serverlist() - eq('Vim:Failed to start server: invalid argument', - pcall_err(funcs.serverstart, '127.0.0.1:65536')) -- invalid port - eq({}, funcs.serverlist()) + eq('Vim:Failed to start server: invalid argument', pcall_err(fn.serverstart, '127.0.0.1:65536')) -- invalid port + eq({}, fn.serverlist()) end) it('serverlist() returns the list of servers', function() @@ -146,11 +145,12 @@ describe('server', function() local n = eval('len(serverlist())') -- Add some servers. - local servs = (is_os('win') - and { [[\\.\pipe\Xtest-pipe0934]], [[\\.\pipe\Xtest-pipe4324]] } - or { [[./Xtest-pipe0934]], [[./Xtest-pipe4324]] }) + local servs = ( + is_os('win') and { [[\\.\pipe\Xtest-pipe0934]], [[\\.\pipe\Xtest-pipe4324]] } + or { [[./Xtest-pipe0934]], [[./Xtest-pipe4324]] } + ) for _, s in ipairs(servs) do - eq(s, eval("serverstart('"..s.."')")) + eq(s, eval("serverstart('" .. s .. "')")) end local new_servs = eval('serverlist()') @@ -160,7 +160,7 @@ describe('server', function() -- The new servers should be at the end of the list. for i = 1, #servs do eq(servs[i], new_servs[i + n]) - eq(1, eval("serverstop('"..servs[i].."')")) + eq(1, eval("serverstop('" .. servs[i] .. "')")) end -- After serverstop() the servers should NOT be in the list. eq(n, eval('len(serverlist())')) @@ -172,22 +172,20 @@ describe('startup --listen', function() clear() local cmd = { unpack(helpers.nvim_argv) } table.insert(cmd, '--listen') - matches('nvim.*: Argument missing after: "%-%-listen"', funcs.system(cmd)) + matches('nvim.*: Argument missing after: "%-%-listen"', fn.system(cmd)) cmd = { unpack(helpers.nvim_argv) } table.insert(cmd, '--listen2') - matches('nvim.*: Garbage after option argument: "%-%-listen2"', funcs.system(cmd)) + matches('nvim.*: Garbage after option argument: "%-%-listen2"', fn.system(cmd)) end) it('sets v:servername, overrides $NVIM_LISTEN_ADDRESS', function() - local addr = (is_os('win') and [[\\.\pipe\Xtest-listen-pipe]] - or './Xtest-listen-pipe') - clear({ env={ NVIM_LISTEN_ADDRESS='./Xtest-env-pipe' }, - args={ '--listen', addr } }) - eq(addr, meths.get_vvar('servername')) + local addr = (is_os('win') and [[\\.\pipe\Xtest-listen-pipe]] or './Xtest-listen-pipe') + clear({ env = { NVIM_LISTEN_ADDRESS = './Xtest-env-pipe' }, args = { '--listen', addr } }) + eq(addr, api.nvim_get_vvar('servername')) -- Address without slashes is a "name" which is appended to a generated path. #8519 - clear({ args={ '--listen', 'test-name' } }) - matches([[.*[/\\]test%-name[^/\\]*]], meths.get_vvar('servername')) + clear({ args = { '--listen', 'test-name' } }) + matches([[.*[/\\]test%-name[^/\\]*]], api.nvim_get_vvar('servername')) end) end) diff --git a/test/functional/vimscript/setpos_spec.lua b/test/functional/vimscript/setpos_spec.lua index 02e550dcc0..a26e48f469 100644 --- a/test/functional/vimscript/setpos_spec.lua +++ b/test/functional/vimscript/setpos_spec.lua @@ -1,6 +1,6 @@ local helpers = require('test.functional.helpers')(after_each) -local setpos = helpers.funcs.setpos -local getpos = helpers.funcs.getpos +local setpos = helpers.fn.setpos +local getpos = helpers.fn.getpos local insert = helpers.insert local clear = helpers.clear local command = helpers.command @@ -8,7 +8,6 @@ local eval = helpers.eval local eq = helpers.eq local exc_exec = helpers.exc_exec - describe('setpos() function', function() before_each(function() clear() @@ -23,42 +22,42 @@ describe('setpos() function', function() Line of text 3]]) end) it('can set the current cursor position', function() - setpos(".", {0, 2, 1, 0}) - eq({0, 2, 1, 0}, getpos(".")) - setpos(".", {2, 1, 1, 0}) - eq({0, 1, 1, 0}, getpos(".")) + setpos('.', { 0, 2, 1, 0 }) + eq({ 0, 2, 1, 0 }, getpos('.')) + setpos('.', { 2, 1, 1, 0 }) + eq({ 0, 1, 1, 0 }, getpos('.')) local ret = exc_exec('call setpos(".", [1, 1, 1, 0])') eq(0, ret) end) it('can set lowercase marks in the current buffer', function() - setpos("'d", {0, 2, 1, 0}) - eq({0, 2, 1, 0}, getpos("'d")) + setpos("'d", { 0, 2, 1, 0 }) + eq({ 0, 2, 1, 0 }, getpos("'d")) command('undo') command('call setpos("\'d", [2, 3, 1, 0])') - eq({0, 3, 1, 0}, getpos("'d")) + eq({ 0, 3, 1, 0 }, getpos("'d")) end) it('can set lowercase marks in other buffers', function() - local retval = setpos("'d", {1, 2, 1, 0}) + local retval = setpos("'d", { 1, 2, 1, 0 }) eq(0, retval) - setpos("'d", {1, 2, 1, 0}) - eq({0, 0, 0, 0}, getpos("'d")) + setpos("'d", { 1, 2, 1, 0 }) + eq({ 0, 0, 0, 0 }, getpos("'d")) command('wincmd w') eq(1, eval('bufnr("%")')) - eq({0, 2, 1, 0}, getpos("'d")) + eq({ 0, 2, 1, 0 }, getpos("'d")) end) it("fails when setting a mark in a buffer that doesn't exist", function() - local retval = setpos("'d", {3, 2, 1, 0}) + local retval = setpos("'d", { 3, 2, 1, 0 }) eq(-1, retval) - eq({0, 0, 0, 0}, getpos("'d")) - retval = setpos("'D", {3, 2, 1, 0}) + eq({ 0, 0, 0, 0 }, getpos("'d")) + retval = setpos("'D", { 3, 2, 1, 0 }) eq(-1, retval) - eq({0, 0, 0, 0}, getpos("'D")) + eq({ 0, 0, 0, 0 }, getpos("'D")) end) it('can set uppercase marks', function() - setpos("'D", {2, 2, 3, 0}) - eq({2, 2, 3, 0}, getpos("'D")) + setpos("'D", { 2, 2, 3, 0 }) + eq({ 2, 2, 3, 0 }, getpos("'D")) -- Can set a mark in another buffer - setpos("'D", {1, 2, 2, 0}) - eq({1, 2, 2, 0}, getpos("'D")) + setpos("'D", { 1, 2, 2, 0 }) + eq({ 1, 2, 2, 0 }, getpos("'D")) end) end) diff --git a/test/functional/vimscript/sort_spec.lua b/test/functional/vimscript/sort_spec.lua index e09949a0f2..bd3d0da146 100644 --- a/test/functional/vimscript/sort_spec.lua +++ b/test/functional/vimscript/sort_spec.lua @@ -1,11 +1,11 @@ local helpers = require('test.functional.helpers')(after_each) local eq = helpers.eq -local NIL = helpers.NIL +local NIL = vim.NIL local eval = helpers.eval local clear = helpers.clear -local meths = helpers.meths -local funcs = helpers.funcs +local api = helpers.api +local fn = helpers.fn local command = helpers.command local exc_exec = helpers.exc_exec local pcall_err = helpers.pcall_err @@ -14,31 +14,41 @@ before_each(clear) describe('sort()', function() it('errors out when sorting special values', function() - eq('Vim(call):E362: Using a boolean value as a Float', - exc_exec('call sort([v:true, v:false], "f")')) + eq( + 'Vim(call):E362: Using a boolean value as a Float', + exc_exec('call sort([v:true, v:false], "f")') + ) end) - it('sorts “wrong” values between -0.0001 and 0.0001, preserving order', - function() - meths.set_var('list', {true, false, NIL, {}, {a=42}, 'check', - 0.0001, -0.0001}) + it('sorts “wrong” values between -0.0001 and 0.0001, preserving order', function() + api.nvim_set_var('list', { + true, + false, + NIL, + {}, + { a = 42 }, + 'check', + 0.0001, + -0.0001, + }) command('call insert(g:list, function("tr"))') - local error_lines = funcs.split( - funcs.execute('silent! call sort(g:list, "f")'), '\n') + local error_lines = fn.split(fn.execute('silent! call sort(g:list, "f")'), '\n') local errors = {} for _, err in ipairs(error_lines) do errors[err] = true end eq({ - ['E362: Using a boolean value as a Float']=true, - ['E891: Using a Funcref as a Float']=true, - ['E892: Using a String as a Float']=true, - ['E893: Using a List as a Float']=true, - ['E894: Using a Dictionary as a Float']=true, - ['E907: Using a special value as a Float']=true, + ['E362: Using a boolean value as a Float'] = true, + ['E891: Using a Funcref as a Float'] = true, + ['E892: Using a String as a Float'] = true, + ['E893: Using a List as a Float'] = true, + ['E894: Using a Dictionary as a Float'] = true, + ['E907: Using a special value as a Float'] = true, }, errors) - eq('[-1.0e-4, function(\'tr\'), v:true, v:false, v:null, [], {\'a\': 42}, \'check\', 1.0e-4]', - eval('string(g:list)')) + eq( + "[-1.0e-4, function('tr'), v:true, v:false, v:null, [], {'a': 42}, 'check', 1.0e-4]", + eval('string(g:list)') + ) end) it('can yield E702 and stop sorting after that', function() @@ -50,7 +60,9 @@ describe('sort()', function() return (a:a > a:b) - (a:a < a:b) endfunction ]]) - eq('Vim(let):E745: Using a List as a Number', - pcall_err(command, 'let sl = sort([1, 0, [], 3, 2], "Cmp")')) + eq( + 'Vim(let):E745: Using a List as a Number', + pcall_err(command, 'let sl = sort([1, 0, [], 3, 2], "Cmp")') + ) end) end) diff --git a/test/functional/vimscript/special_vars_spec.lua b/test/functional/vimscript/special_vars_spec.lua index 217f0b2c2b..590d409141 100644 --- a/test/functional/vimscript/special_vars_spec.lua +++ b/test/functional/vimscript/special_vars_spec.lua @@ -1,12 +1,12 @@ local helpers = require('test.functional.helpers')(after_each) local exc_exec = helpers.exc_exec local command = helpers.command -local funcs = helpers.funcs +local fn = helpers.fn local clear = helpers.clear local eval = helpers.eval local eq = helpers.eq -local meths = helpers.meths -local NIL = helpers.NIL +local api = helpers.api +local NIL = vim.NIL describe('Special values', function() before_each(clear) @@ -25,15 +25,15 @@ describe('Special values', function() end) it('work with empty()', function() - eq(0, funcs.empty(true)) - eq(1, funcs.empty(false)) - eq(1, funcs.empty(NIL)) + eq(0, fn.empty(true)) + eq(1, fn.empty(false)) + eq(1, fn.empty(NIL)) end) it('can be stringified and eval’ed back', function() - eq(true, funcs.eval(funcs.string(true))) - eq(false, funcs.eval(funcs.string(false))) - eq(NIL, funcs.eval(funcs.string(NIL))) + eq(true, fn.eval(fn.string(true))) + eq(false, fn.eval(fn.string(false))) + eq(NIL, fn.eval(fn.string(NIL))) end) it('work with is/isnot properly', function() @@ -98,8 +98,8 @@ describe('Special values', function() eq(0, eval('0 + v:false')) eq(-1, eval('0 - v:true')) - eq( 0, eval('0 - v:null')) - eq( 0, eval('0 - v:false')) + eq(0, eval('0 - v:null')) + eq(0, eval('0 - v:false')) eq(1, eval('1 * v:true')) eq(0, eval('1 * v:null')) @@ -107,8 +107,8 @@ describe('Special values', function() end) it('does not work with +=/-=/.=', function() - meths.set_var('true', true) - meths.set_var('false', false) + api.nvim_set_var('true', true) + api.nvim_set_var('false', false) command('let null = v:null') eq('Vim(let):E734: Wrong variable type for +=', exc_exec('let true += 1')) @@ -125,9 +125,9 @@ describe('Special values', function() end) it('work with . (concat) properly', function() - eq("v:true", eval('"" . v:true')) - eq("v:null", eval('"" . v:null')) - eq("v:false", eval('"" . v:false')) + eq('v:true', eval('"" . v:true')) + eq('v:null', eval('"" . v:null')) + eq('v:false', eval('"" . v:false')) end) it('work with ?? (falsy operator)', function() @@ -137,19 +137,19 @@ describe('Special values', function() end) it('work with type()', function() - eq(6, funcs.type(true)) - eq(6, funcs.type(false)) - eq(7, funcs.type(NIL)) + eq(6, fn.type(true)) + eq(6, fn.type(false)) + eq(7, fn.type(NIL)) end) it('work with copy() and deepcopy()', function() - eq(true, funcs.deepcopy(true)) - eq(false, funcs.deepcopy(false)) - eq(NIL, funcs.deepcopy(NIL)) + eq(true, fn.deepcopy(true)) + eq(false, fn.deepcopy(false)) + eq(NIL, fn.deepcopy(NIL)) - eq(true, funcs.copy(true)) - eq(false, funcs.copy(false)) - eq(NIL, funcs.copy(NIL)) + eq(true, fn.copy(true)) + eq(false, fn.copy(false)) + eq(NIL, fn.copy(NIL)) end) it('fails in index', function() @@ -159,20 +159,20 @@ describe('Special values', function() end) it('is accepted by assert_true and assert_false', function() - funcs.assert_false(false) - funcs.assert_false(true) - funcs.assert_false(NIL) + fn.assert_false(false) + fn.assert_false(true) + fn.assert_false(NIL) - funcs.assert_true(false) - funcs.assert_true(true) - funcs.assert_true(NIL) + fn.assert_true(false) + fn.assert_true(true) + fn.assert_true(NIL) eq({ 'Expected False but got v:true', 'Expected False but got v:null', 'Expected True but got v:false', 'Expected True but got v:null', - }, meths.get_vvar('errors')) + }, api.nvim_get_vvar('errors')) end) describe('compat', function() diff --git a/test/functional/vimscript/state_spec.lua b/test/functional/vimscript/state_spec.lua index 0508b8b1da..7179806e36 100644 --- a/test/functional/vimscript/state_spec.lua +++ b/test/functional/vimscript/state_spec.lua @@ -4,7 +4,7 @@ local eq = helpers.eq local exec = helpers.exec local exec_lua = helpers.exec_lua local feed = helpers.feed -local meths = helpers.meths +local api = helpers.api local poke_eventloop = helpers.poke_eventloop before_each(clear) @@ -12,7 +12,7 @@ before_each(clear) describe('state() function', function() -- oldtest: Test_state() it('works', function() - meths.ui_attach(80, 24, {}) -- Allow hit-enter-prompt + api.nvim_ui_attach(80, 24, {}) -- Allow hit-enter-prompt exec_lua([[ function _G.Get_state_mode() @@ -42,34 +42,34 @@ describe('state() function', function() -- Using a timer callback feed([[:call RunTimer()<CR>]]) - poke_eventloop() -- Process pending input - poke_eventloop() -- Process time_event + poke_eventloop() -- Process pending input + poke_eventloop() -- Process time_event eq({ 'c', 'n' }, exec_lua('return _G.res')) -- Halfway a mapping feed([[:call v:lua.Run_timer()<CR>;]]) - meths.get_mode() -- Process pending input and luv timer callback + api.nvim_get_mode() -- Process pending input and luv timer callback feed(';') eq({ 'mS', 'n' }, exec_lua('return _G.res')) -- An operator is pending feed([[:call RunTimer()<CR>y]]) - poke_eventloop() -- Process pending input - poke_eventloop() -- Process time_event + poke_eventloop() -- Process pending input + poke_eventloop() -- Process time_event feed('y') eq({ 'oSc', 'n' }, exec_lua('return _G.res')) -- A register was specified feed([[:call RunTimer()<CR>"r]]) - poke_eventloop() -- Process pending input - poke_eventloop() -- Process time_event + poke_eventloop() -- Process pending input + poke_eventloop() -- Process time_event feed('yy') eq({ 'oSc', 'n' }, exec_lua('return _G.res')) -- Insert mode completion feed([[:call RunTimer()<CR>Got<C-N>]]) - poke_eventloop() -- Process pending input - poke_eventloop() -- Process time_event + poke_eventloop() -- Process pending input + poke_eventloop() -- Process time_event feed('<Esc>') eq({ 'aSc', 'i' }, exec_lua('return _G.res')) @@ -79,7 +79,7 @@ describe('state() function', function() -- messages scrolled feed([[:call v:lua.Run_timer() | echo "one\ntwo\nthree"<CR>]]) - meths.get_mode() -- Process pending input and luv timer callback + api.nvim_get_mode() -- Process pending input and luv timer callback feed('<CR>') eq({ 'Ss', 'r' }, exec_lua('return _G.res')) end) diff --git a/test/functional/vimscript/string_spec.lua b/test/functional/vimscript/string_spec.lua index cb7e93f264..6a7fe1bad9 100644 --- a/test/functional/vimscript/string_spec.lua +++ b/test/functional/vimscript/string_spec.lua @@ -2,12 +2,12 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local eq = helpers.eq local command = helpers.command -local meths = helpers.meths +local api = helpers.api local eval = helpers.eval local exc_exec = helpers.exc_exec local pcall_err = helpers.pcall_err -local funcs = helpers.funcs -local NIL = helpers.NIL +local fn = helpers.fn +local NIL = vim.NIL local source = helpers.source describe('string() function', function() @@ -15,17 +15,17 @@ describe('string() function', function() describe('used to represent floating-point values', function() it('dumps NaN values', function() - eq('str2float(\'nan\')', eval('string(str2float(\'nan\'))')) + eq("str2float('nan')", eval("string(str2float('nan'))")) end) it('dumps infinite values', function() - eq('str2float(\'inf\')', eval('string(str2float(\'inf\'))')) - eq('-str2float(\'inf\')', eval('string(str2float(\'-inf\'))')) + eq("str2float('inf')", eval("string(str2float('inf'))")) + eq("-str2float('inf')", eval("string(str2float('-inf'))")) end) it('dumps regular values', function() - eq('1.5', funcs.string(1.5)) - eq('1.56e-20', funcs.string(1.56000e-020)) + eq('1.5', fn.string(1.5)) + eq('1.56e-20', fn.string(1.56000e-020)) eq('0.0', eval('string(0.0)')) end) @@ -33,64 +33,62 @@ describe('string() function', function() eq('v:true', eval('string(v:true)')) eq('v:false', eval('string(v:false)')) eq('v:null', eval('string(v:null)')) - eq('v:true', funcs.string(true)) - eq('v:false', funcs.string(false)) - eq('v:null', funcs.string(NIL)) + eq('v:true', fn.string(true)) + eq('v:false', fn.string(false)) + eq('v:null', fn.string(NIL)) end) - it('dumps values with at most six digits after the decimal point', - function() - eq('1.234568e-20', funcs.string(1.23456789123456789123456789e-020)) - eq('1.234568', funcs.string(1.23456789123456789123456789)) + it('dumps values with at most six digits after the decimal point', function() + eq('1.234568e-20', fn.string(1.23456789123456789123456789e-020)) + eq('1.234568', fn.string(1.23456789123456789123456789)) end) - it('dumps values with at most seven digits before the decimal point', - function() - eq('1234567.891235', funcs.string(1234567.89123456789123456789)) - eq('1.234568e7', funcs.string(12345678.9123456789123456789)) + it('dumps values with at most seven digits before the decimal point', function() + eq('1234567.891235', fn.string(1234567.89123456789123456789)) + eq('1.234568e7', fn.string(12345678.9123456789123456789)) end) it('dumps negative values', function() - eq('-1.5', funcs.string(-1.5)) - eq('-1.56e-20', funcs.string(-1.56000e-020)) - eq('-1.234568e-20', funcs.string(-1.23456789123456789123456789e-020)) - eq('-1.234568', funcs.string(-1.23456789123456789123456789)) - eq('-1234567.891235', funcs.string(-1234567.89123456789123456789)) - eq('-1.234568e7', funcs.string(-12345678.9123456789123456789)) + eq('-1.5', fn.string(-1.5)) + eq('-1.56e-20', fn.string(-1.56000e-020)) + eq('-1.234568e-20', fn.string(-1.23456789123456789123456789e-020)) + eq('-1.234568', fn.string(-1.23456789123456789123456789)) + eq('-1234567.891235', fn.string(-1234567.89123456789123456789)) + eq('-1.234568e7', fn.string(-12345678.9123456789123456789)) end) end) describe('used to represent numbers', function() it('dumps regular values', function() - eq('0', funcs.string(0)) - eq('-1', funcs.string(-1)) - eq('1', funcs.string(1)) + eq('0', fn.string(0)) + eq('-1', fn.string(-1)) + eq('1', fn.string(1)) end) it('dumps large values', function() - eq('2147483647', funcs.string(2^31-1)) - eq('-2147483648', funcs.string(-2^31)) + eq('2147483647', fn.string(2 ^ 31 - 1)) + eq('-2147483648', fn.string(-2 ^ 31)) end) end) describe('used to represent strings', function() it('dumps regular strings', function() - eq('\'test\'', funcs.string('test')) + eq("'test'", fn.string('test')) end) it('dumps empty strings', function() - eq('\'\'', funcs.string('')) + eq("''", fn.string('')) end) - it('dumps strings with \' inside', function() - eq('\'\'\'\'\'\'\'\'', funcs.string('\'\'\'')) - eq('\'a\'\'b\'\'\'\'\'', funcs.string('a\'b\'\'')) - eq('\'\'\'b\'\'\'\'d\'', funcs.string('\'b\'\'d')) - eq('\'a\'\'b\'\'c\'\'d\'', funcs.string('a\'b\'c\'d')) + it("dumps strings with ' inside", function() + eq("''''''''", fn.string("'''")) + eq("'a''b'''''", fn.string("a'b''")) + eq("'''b''''d'", fn.string("'b''d")) + eq("'a''b''c''d'", fn.string("a'b'c'd")) end) it('dumps NULL strings', function() - eq('\'\'', eval('string($XXX_UNEXISTENT_VAR_XXX)')) + eq("''", eval('string($XXX_UNEXISTENT_VAR_XXX)')) end) it('dumps NULL lists', function() @@ -119,16 +117,16 @@ describe('string() function', function() end) it('dumps references to built-in functions', function() - eq('function(\'function\')', eval('string(function("function"))')) + eq("function('function')", eval('string(function("function"))')) end) it('dumps references to user functions', function() - eq('function(\'Test1\')', eval('string(function("Test1"))')) - eq('function(\'g:Test3\')', eval('string(function("g:Test3"))')) + eq("function('Test1')", eval('string(function("Test1"))')) + eq("function('g:Test3')", eval('string(function("g:Test3"))')) end) it('dumps references to script functions', function() - eq('function(\'<SNR>1_Test2\')', eval('string(Test2_f)')) + eq("function('<SNR>1_Test2')", eval('string(Test2_f)')) end) it('dumps partials with self referencing a partial', function() @@ -139,96 +137,119 @@ describe('string() function', function() let TestDictRef = function('TestDict', d) let d.tdr = TestDictRef ]]) - eq("Vim(echo):E724: unable to correctly dump variable with self-referencing container", - pcall_err(command, 'echo string(d.tdr)')) + eq( + 'Vim(echo):E724: unable to correctly dump variable with self-referencing container', + pcall_err(command, 'echo string(d.tdr)') + ) end) it('dumps automatically created partials', function() - eq('function(\'<SNR>1_Test2\', {\'f\': function(\'<SNR>1_Test2\')})', - eval('string({"f": Test2_f}.f)')) - eq('function(\'<SNR>1_Test2\', [1], {\'f\': function(\'<SNR>1_Test2\', [1])})', - eval('string({"f": function(Test2_f, [1])}.f)')) + eq( + "function('<SNR>1_Test2', {'f': function('<SNR>1_Test2')})", + eval('string({"f": Test2_f}.f)') + ) + eq( + "function('<SNR>1_Test2', [1], {'f': function('<SNR>1_Test2', [1])})", + eval('string({"f": function(Test2_f, [1])}.f)') + ) end) it('dumps manually created partials', function() - eq('function(\'Test3\', [1, 2], {})', - eval('string(function("Test3", [1, 2], {}))')) - eq('function(\'Test3\', {})', - eval('string(function("Test3", {}))')) - eq('function(\'Test3\', [1, 2])', - eval('string(function("Test3", [1, 2]))')) + eq("function('Test3', [1, 2], {})", eval('string(function("Test3", [1, 2], {}))')) + eq("function('Test3', {})", eval('string(function("Test3", {}))')) + eq("function('Test3', [1, 2])", eval('string(function("Test3", [1, 2]))')) end) - it('does not crash or halt when dumping partials with reference cycles in self', - function() - meths.set_var('d', {v=true}) - eq([[Vim(echo):E724: unable to correctly dump variable with self-referencing container]], - pcall_err(command, 'echo string(extend(extend(g:d, {"f": g:Test2_f}), {"p": g:d.f}))')) + it('does not crash or halt when dumping partials with reference cycles in self', function() + api.nvim_set_var('d', { v = true }) + eq( + [[Vim(echo):E724: unable to correctly dump variable with self-referencing container]], + pcall_err(command, 'echo string(extend(extend(g:d, {"f": g:Test2_f}), {"p": g:d.f}))') + ) end) - it('does not show errors when dumping partials referencing the same dictionary', - function() + it('does not show errors when dumping partials referencing the same dictionary', function() command('let d = {}') -- Regression for “eval/typval_encode: Dump empty dictionary before -- checking for refcycle”, results in error. - eq('[function(\'tr\', {}), function(\'tr\', {})]', eval('string([function("tr", d), function("tr", d)])')) + eq( + "[function('tr', {}), function('tr', {})]", + eval('string([function("tr", d), function("tr", d)])') + ) -- Regression for “eval: Work with reference cycles in partials (self) -- properly”, results in crash. eval('extend(d, {"a": 1})') - eq('[function(\'tr\', {\'a\': 1}), function(\'tr\', {\'a\': 1})]', eval('string([function("tr", d), function("tr", d)])')) + eq( + "[function('tr', {'a': 1}), function('tr', {'a': 1})]", + eval('string([function("tr", d), function("tr", d)])') + ) end) - it('does not crash or halt when dumping partials with reference cycles in arguments', - function() - meths.set_var('l', {}) + it('does not crash or halt when dumping partials with reference cycles in arguments', function() + api.nvim_set_var('l', {}) eval('add(l, l)') -- Regression: the below line used to crash (add returns original list and -- there was error in dumping partials). Tested explicitly in -- test/unit/api/private_helpers_spec.lua. eval('add(l, function("Test1", l))') - eq([=[Vim(echo):E724: unable to correctly dump variable with self-referencing container]=], - pcall_err(command, 'echo string(function("Test1", l))')) - end) - - it('does not crash or halt when dumping partials with reference cycles in self and arguments', - function() - meths.set_var('d', {v=true}) - meths.set_var('l', {}) - eval('add(l, l)') - eval('add(l, function("Test1", l))') - eval('add(l, function("Test1", d))') - eq([=[Vim(echo):E724: unable to correctly dump variable with self-referencing container]=], - pcall_err(command, 'echo string(extend(extend(g:d, {"f": g:Test2_f}), {"p": function(g:d.f, l)}))')) - end) + eq( + [=[Vim(echo):E724: unable to correctly dump variable with self-referencing container]=], + pcall_err(command, 'echo string(function("Test1", l))') + ) + end) + + it( + 'does not crash or halt when dumping partials with reference cycles in self and arguments', + function() + api.nvim_set_var('d', { v = true }) + api.nvim_set_var('l', {}) + eval('add(l, l)') + eval('add(l, function("Test1", l))') + eval('add(l, function("Test1", d))') + eq( + [=[Vim(echo):E724: unable to correctly dump variable with self-referencing container]=], + pcall_err( + command, + 'echo string(extend(extend(g:d, {"f": g:Test2_f}), {"p": function(g:d.f, l)}))' + ) + ) + end + ) end) describe('used to represent lists', function() it('dumps empty list', function() - eq('[]', funcs.string({})) + eq('[]', fn.string({})) end) it('dumps nested lists', function() - eq('[[[[[]]]]]', funcs.string({{{{{}}}}})) + eq('[[[[[]]]]]', fn.string({ { { { {} } } } })) end) it('dumps nested non-empty lists', function() - eq('[1, [[3, [[5], 4]], 2]]', funcs.string({1, {{3, {{5}, 4}}, 2}})) + eq('[1, [[3, [[5], 4]], 2]]', fn.string({ 1, { { 3, { { 5 }, 4 } }, 2 } })) end) it('errors when dumping recursive lists', function() - meths.set_var('l', {}) + api.nvim_set_var('l', {}) eval('add(l, l)') - eq('Vim(echo):E724: unable to correctly dump variable with self-referencing container', - exc_exec('echo string(l)')) + eq( + 'Vim(echo):E724: unable to correctly dump variable with self-referencing container', + exc_exec('echo string(l)') + ) end) it('dumps recursive lists despite the error', function() - meths.set_var('l', {}) + api.nvim_set_var('l', {}) eval('add(l, l)') - eq('Vim(echo):E724: unable to correctly dump variable with self-referencing container', - pcall_err(command, 'echo string(l)')) - eq('Vim(echo):E724: unable to correctly dump variable with self-referencing container', - pcall_err(command, 'echo string([l])')) + eq( + 'Vim(echo):E724: unable to correctly dump variable with self-referencing container', + pcall_err(command, 'echo string(l)') + ) + eq( + 'Vim(echo):E724: unable to correctly dump variable with self-referencing container', + pcall_err(command, 'echo string([l])') + ) end) end) @@ -240,28 +261,34 @@ describe('string() function', function() it('dumps list with two same empty dictionaries, also in partials', function() command('let d = {}') eq('[{}, {}]', eval('string([d, d])')) - eq('[function(\'tr\', {}), {}]', eval('string([function("tr", d), d])')) - eq('[{}, function(\'tr\', {})]', eval('string([d, function("tr", d)])')) + eq("[function('tr', {}), {}]", eval('string([function("tr", d), d])')) + eq("[{}, function('tr', {})]", eval('string([d, function("tr", d)])')) end) it('dumps non-empty dictionary', function() - eq('{\'t\'\'est\': 1}', funcs.string({['t\'est']=1})) + eq("{'t''est': 1}", fn.string({ ["t'est"] = 1 })) end) it('errors when dumping recursive dictionaries', function() - meths.set_var('d', {d=1}) + api.nvim_set_var('d', { d = 1 }) eval('extend(d, {"d": d})') - eq('Vim(echo):E724: unable to correctly dump variable with self-referencing container', - exc_exec('echo string(d)')) + eq( + 'Vim(echo):E724: unable to correctly dump variable with self-referencing container', + exc_exec('echo string(d)') + ) end) it('dumps recursive dictionaries despite the error', function() - meths.set_var('d', {d=1}) + api.nvim_set_var('d', { d = 1 }) eval('extend(d, {"d": d})') - eq('Vim(echo):E724: unable to correctly dump variable with self-referencing container', - pcall_err(command, 'echo string(d)')) - eq('Vim(echo):E724: unable to correctly dump variable with self-referencing container', - pcall_err(command, 'echo string({"out": d})')) + eq( + 'Vim(echo):E724: unable to correctly dump variable with self-referencing container', + pcall_err(command, 'echo string(d)') + ) + eq( + 'Vim(echo):E724: unable to correctly dump variable with self-referencing container', + pcall_err(command, 'echo string({"out": d})') + ) end) end) end) diff --git a/test/functional/vimscript/system_spec.lua b/test/functional/vimscript/system_spec.lua index 90aab48d61..d44f68e152 100644 --- a/test/functional/vimscript/system_spec.lua +++ b/test/functional/vimscript/system_spec.lua @@ -4,9 +4,14 @@ local helpers = require('test.functional.helpers')(after_each) local assert_alive = helpers.assert_alive local testprg = helpers.testprg -local eq, call, clear, eval, feed_command, feed, nvim = - helpers.eq, helpers.call, helpers.clear, helpers.eval, helpers.feed_command, - helpers.feed, helpers.nvim +local eq, call, clear, eval, feed_command, feed, api = + helpers.eq, + helpers.call, + helpers.clear, + helpers.eval, + helpers.feed_command, + helpers.feed, + helpers.api local command = helpers.command local insert = helpers.insert local expect = helpers.expect @@ -19,14 +24,14 @@ local Screen = require('test.functional.ui.screen') local function create_file_with_nuls(name) return function() - feed('ipart1<C-V>000part2<C-V>000part3<ESC>:w '..name..'<CR>') - eval('1') -- wait for the file to be created + feed('ipart1<C-V>000part2<C-V>000part3<ESC>:w ' .. name .. '<CR>') + eval('1') -- wait for the file to be created end end local function delete_file(name) return function() - eval("delete('"..name.."')") + eval("delete('" .. name .. "')") end end @@ -35,8 +40,10 @@ describe('system()', function() describe('command passed as a List', function() it('throws error if cmd[0] is not executable', function() - eq("Vim:E475: Invalid value for argument cmd: 'this-should-not-exist' is not executable", - pcall_err(call, 'system', { 'this-should-not-exist' })) + eq( + "Vim:E475: Invalid value for argument cmd: 'this-should-not-exist' is not executable", + pcall_err(call, 'system', { 'this-should-not-exist' }) + ) eq(-1, eval('v:shell_error')) end) @@ -51,8 +58,10 @@ describe('system()', function() eq(0, eval('v:shell_error')) -- Provoke a non-zero v:shell_error. - eq("Vim:E475: Invalid value for argument cmd: 'this-should-not-exist' is not executable", - pcall_err(call, 'system', { 'this-should-not-exist' })) + eq( + "Vim:E475: Invalid value for argument cmd: 'this-should-not-exist' is not executable", + pcall_err(call, 'system', { 'this-should-not-exist' }) + ) local old_val = eval('v:shell_error') eq(-1, old_val) @@ -65,8 +74,8 @@ describe('system()', function() end) it('quotes arguments correctly #5280', function() - local out = call('system', - { testprg('printargs-test'), [[1]], [[2 "3]], [[4 ' 5]], [[6 ' 7']] }) + local out = + call('system', { testprg('printargs-test'), [[1]], [[2 "3]], [[4 ' 5]], [[6 ' 7']] }) eq(0, eval('v:shell_error')) eq([[arg1=1;arg2=2 "3;arg3=4 ' 5;arg4=6 ' 7';]], out) @@ -75,22 +84,29 @@ describe('system()', function() eq(0, eval('v:shell_error')) eq([[arg1='1;arg2=2 "3;]], out) - out = call('system', { testprg('printargs-test'), "A\nB" }) + out = call('system', { testprg('printargs-test'), 'A\nB' }) eq(0, eval('v:shell_error')) - eq("arg1=A\nB;", out) + eq('arg1=A\nB;', out) end) it('calls executable in $PATH', function() - if 0 == eval("executable('python3')") then pending("missing `python3`") end - eq("foo\n", eval([[system(['python3', '-c', 'print("foo")'])]])) + if 0 == eval("executable('python3')") then + pending('missing `python3`') + end + eq('foo\n', eval([[system(['python3', '-c', 'print("foo")'])]])) eq(0, eval('v:shell_error')) end) it('does NOT run in shell', function() if is_os('win') then - eq("%PATH%\n", eval("system(['powershell', '-NoProfile', '-NoLogo', '-ExecutionPolicy', 'RemoteSigned', '-Command', 'Write-Output', '%PATH%'])")) + eq( + '%PATH%\n', + eval( + "system(['powershell', '-NoProfile', '-NoLogo', '-ExecutionPolicy', 'RemoteSigned', '-Command', 'Write-Output', '%PATH%'])" + ) + ) else - eq("* $PATH %PATH%\n", eval("system(['echo', '*', '$PATH', '%PATH%'])")) + eq('* $PATH %PATH%\n', eval("system(['echo', '*', '$PATH', '%PATH%'])")) end end) end) @@ -133,7 +149,12 @@ describe('system()', function() eval([[system('"ping" "-n" "1" "127.0.0.1"')]]) eq(0, eval('v:shell_error')) eq('"a b"\n', eval([[system('cmd /s/c "cmd /s/c "cmd /s/c "echo "a b""""')]])) - eq('"a b"\n', eval([[system('powershell -NoProfile -NoLogo -ExecutionPolicy RemoteSigned -Command Write-Output ''\^"a b\^"''')]])) + eq( + '"a b"\n', + eval( + [[system('powershell -NoProfile -NoLogo -ExecutionPolicy RemoteSigned -Command Write-Output ''\^"a b\^"''')]] + ) + ) end it('with shell=cmd.exe', function() @@ -177,7 +198,7 @@ describe('system()', function() it('powershell w/ UTF-8 text #13713', function() if not helpers.has_powershell() then - pending("powershell not found", function() end) + pending('powershell not found', function() end) return end helpers.set_shell_powershell() @@ -193,32 +214,21 @@ describe('system()', function() feed(':call system("echo")<cr>') screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*12 :call system("echo") | ]]) end) it('prints verbose information', function() - nvim('set_option_value', 'shell', 'fake_shell', {}) - nvim('set_option_value', 'shellcmdflag', 'cmdflag', {}) + api.nvim_set_option_value('shell', 'fake_shell', {}) + api.nvim_set_option_value('shellcmdflag', 'cmdflag', {}) screen:try_resize(72, 14) feed(':4verbose echo system("echo hi")<cr>') if is_os('win') then - screen:expect{any=[[Executing command: "'fake_shell' 'cmdflag' '"echo hi"'"]]} + screen:expect { any = [[Executing command: "'fake_shell' 'cmdflag' '"echo hi"'"]] } else - screen:expect{any=[[Executing command: "'fake_shell' 'cmdflag' 'echo hi'"]]} + screen:expect { any = [[Executing command: "'fake_shell' 'cmdflag' 'echo hi'"]] } end feed('<cr>') end) @@ -237,94 +247,50 @@ describe('system()', function() feed(':edit ' .. tempfile .. '<cr>') - local command_total_time = tonumber(helpers.funcs.split(helpers.funcs.getline(7))[2]) - local command_self_time = tonumber(helpers.funcs.split(helpers.funcs.getline(7))[3]) + local command_total_time = tonumber(helpers.fn.split(helpers.fn.getline(7))[2]) + local command_self_time = tonumber(helpers.fn.split(helpers.fn.getline(7))[3]) helpers.neq(nil, command_total_time) helpers.neq(nil, command_self_time) end) it('`yes` interrupted with CTRL-C', function() - feed(':call system("' .. (is_os('win') - and 'for /L %I in (1,0,2) do @echo y' - or 'yes') .. '")<cr>') + feed( + ':call system("' + .. (is_os('win') and 'for /L %I in (1,0,2) do @echo y' or 'yes') + .. '")<cr>' + ) screen:expect([[ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | -]] .. (is_os('win') - and [[ - :call system("for /L %I in (1,0,2) do @echo y") |]] - or [[ + ~ |*12 +]] .. (is_os('win') and [[ + :call system("for /L %I in (1,0,2) do @echo y") |]] or [[ :call system("yes") |]])) feed('foo<c-c>') screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*12 Type :qa and press <Enter> to exit Nvim | ]]) end) it('`yes` interrupted with mapped CTRL-C', function() command('nnoremap <C-C> i') - feed(':call system("' .. (is_os('win') - and 'for /L %I in (1,0,2) do @echo y' - or 'yes') .. '")<cr>') + feed( + ':call system("' + .. (is_os('win') and 'for /L %I in (1,0,2) do @echo y' or 'yes') + .. '")<cr>' + ) screen:expect([[ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | -]] .. (is_os('win') - and [[ - :call system("for /L %I in (1,0,2) do @echo y") |]] - or [[ + ~ |*12 +]] .. (is_os('win') and [[ + :call system("for /L %I in (1,0,2) do @echo y") |]] or [[ :call system("yes") |]])) feed('foo<c-c>') screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*12 -- INSERT -- | ]]) end) @@ -333,17 +299,19 @@ describe('system()', function() describe('passing no input', function() it('returns the program output', function() if is_os('win') then - eq("echoed\n", eval('system("echo echoed")')) + eq('echoed\n', eval('system("echo echoed")')) else - eq("echoed", eval('system("printf echoed")')) + eq('echoed', eval('system("printf echoed")')) end end) it('to backgrounded command does not crash', function() -- This is indeterminate, just exercise the codepath. May get E5677. - feed_command('call system(has("win32") ? "start /b /wait cmd /c echo echoed" : "printf echoed &")') - local v_errnum = string.match(eval("v:errmsg"), "^E%d*:") + feed_command( + 'call system(has("win32") ? "start /b /wait cmd /c echo echoed" : "printf echoed &")' + ) + local v_errnum = string.match(eval('v:errmsg'), '^E%d*:') if v_errnum then - eq("E5677:", v_errnum) + eq('E5677:', v_errnum) end assert_alive() end) @@ -351,19 +319,19 @@ describe('system()', function() describe('passing input', function() it('returns the program output', function() - eq("input", eval('system("cat -", "input")')) + eq('input', eval('system("cat -", "input")')) end) it('to backgrounded command does not crash', function() -- This is indeterminate, just exercise the codepath. May get E5677. feed_command('call system(has("win32") ? "start /b /wait more" : "cat - &", "input")') - local v_errnum = string.match(eval("v:errmsg"), "^E%d*:") + local v_errnum = string.match(eval('v:errmsg'), '^E%d*:') if v_errnum then - eq("E5677:", v_errnum) + eq('E5677:', v_errnum) end assert_alive() end) it('works with an empty string', function() - eq("test\n", eval('system("echo test", "")')) + eq('test\n', eval('system("echo test", "")')) assert_alive() end) end) @@ -378,7 +346,7 @@ describe('system()', function() input[#input + 1] = '01234567890ABCDEFabcdef' end input = table.concat(input, '\n') - nvim('set_var', 'input', input) + api.nvim_set_var('input', input) eq(input, eval('system("cat -", g:input)')) end) end) @@ -387,8 +355,7 @@ describe('system()', function() it('is treated as a buffer id', function() command("put ='text in buffer 1'") eq('\ntext in buffer 1\n', eval('system("cat", 1)')) - eq('Vim(echo):E86: Buffer 42 does not exist', - exc_exec('echo system("cat", 42)')) + eq('Vim(echo):E86: Buffer 42 does not exist', exc_exec('echo system("cat", 42)')) end) end) @@ -399,14 +366,13 @@ describe('system()', function() after_each(delete_file(fname)) it('replaces NULs by SOH characters', function() - eq('part1\001part2\001part3\n', eval([[system('"cat" "]]..fname..[["')]])) + eq('part1\001part2\001part3\n', eval([[system('"cat" "]] .. fname .. [["')]])) end) end) describe('input passed as List', function() it('joins List items with linefeed characters', function() - eq('line1\nline2\nline3', - eval("system('cat -', ['line1', 'line2', 'line3'])")) + eq('line1\nline2\nline3', eval("system('cat -', ['line1', 'line2', 'line3'])")) end) -- Notice that NULs are converted to SOH when the data is read back. This @@ -415,15 +381,19 @@ describe('system()', function() -- characters(see the following tests with `systemlist()` below) describe('with linefeed characters inside List items', function() it('converts linefeed characters to NULs', function() - eq('l1\001p2\nline2\001a\001b\nl3', - eval([[system('cat -', ["l1\np2", "line2\na\nb", 'l3'])]])) + eq( + 'l1\001p2\nline2\001a\001b\nl3', + eval([[system('cat -', ["l1\np2", "line2\na\nb", 'l3'])]]) + ) end) end) describe('with leading/trailing whitespace characters on items', function() it('preserves whitespace, replacing linefeeds by NULs', function() - eq('line \nline2\001\n\001line3', - eval([[system('cat -', ['line ', "line2\n", "\nline3"])]])) + eq( + 'line \nline2\001\n\001line3', + eval([[system('cat -', ['line ', "line2\n", "\nline3"])]]) + ) end) end) end) @@ -431,7 +401,7 @@ describe('system()', function() it("with a program that doesn't close stdout will exit properly after passing input", function() local out = eval(string.format("system('%s', 'clip-data')", testprg('streams-test'))) assert(out:sub(0, 5) == 'pid: ', out) - os_kill(out:match("%d+")) + os_kill(out:match('%d+')) end) end) @@ -477,18 +447,7 @@ describe('systemlist()', function() feed(':call systemlist("echo")<cr>') screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*12 :call systemlist("echo") | ]]) end) @@ -497,35 +456,13 @@ describe('systemlist()', function() feed(':call systemlist("yes | xargs")<cr>') screen:expect([[ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*12 :call systemlist("yes | xargs") | ]]) feed('<c-c>') screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | - ~ | + ~ |*12 Type :qa and press <Enter> to exit Nvim | ]]) end) @@ -533,7 +470,7 @@ describe('systemlist()', function() describe('passing string with linefeed characters as input', function() it('splits the output on linefeed characters', function() - eq({'abc', 'def', 'ghi'}, eval([[systemlist("cat -", "abc\ndef\nghi")]])) + eq({ 'abc', 'def', 'ghi' }, eval([[systemlist("cat -", "abc\ndef\nghi")]])) end) end) @@ -543,7 +480,7 @@ describe('systemlist()', function() for _ = 1, 0xffff do input[#input + 1] = '01234567890ABCDEFabcdef' end - nvim('set_var', 'input', input) + api.nvim_set_var('input', input) eq(input, eval('systemlist("cat -", g:input)')) end) end) @@ -558,75 +495,77 @@ describe('systemlist()', function() after_each(delete_file(fname)) it('replaces NULs by newline characters', function() - eq({'part1\npart2\npart3'}, eval([[systemlist('"cat" "]]..fname..[["')]])) + eq({ 'part1\npart2\npart3' }, eval([[systemlist('"cat" "]] .. fname .. [["')]])) end) end) describe('input passed as List', function() it('joins list items with linefeed characters', function() - eq({'line1', 'line2', 'line3'}, - eval("systemlist('cat -', ['line1', 'line2', 'line3'])")) + eq({ 'line1', 'line2', 'line3' }, eval("systemlist('cat -', ['line1', 'line2', 'line3'])")) end) -- Unlike `system()` which uses SOH to represent NULs, with `systemlist()` -- input and output are the same. describe('with linefeed characters inside list items', function() it('converts linefeed characters to NULs', function() - eq({'l1\np2', 'line2\na\nb', 'l3'}, - eval([[systemlist('cat -', ["l1\np2", "line2\na\nb", 'l3'])]])) + eq( + { 'l1\np2', 'line2\na\nb', 'l3' }, + eval([[systemlist('cat -', ["l1\np2", "line2\na\nb", 'l3'])]]) + ) end) end) describe('with leading/trailing whitespace characters on items', function() it('preserves whitespace, replacing linefeeds by NULs', function() - eq({'line ', 'line2\n', '\nline3'}, - eval([[systemlist('cat -', ['line ', "line2\n", "\nline3"])]])) + eq( + { 'line ', 'line2\n', '\nline3' }, + eval([[systemlist('cat -', ['line ', "line2\n", "\nline3"])]]) + ) end) end) end) describe('handles empty lines', function() it('in the middle', function() - eq({'line one','','line two'}, eval("systemlist('cat',['line one','','line two'])")) + eq({ 'line one', '', 'line two' }, eval("systemlist('cat',['line one','','line two'])")) end) it('in the beginning', function() - eq({'','line one','line two'}, eval("systemlist('cat',['','line one','line two'])")) + eq({ '', 'line one', 'line two' }, eval("systemlist('cat',['','line one','line two'])")) end) end) describe('when keepempty option is', function() it('0, ignores trailing newline', function() - eq({'aa','bb'}, eval("systemlist('cat',['aa','bb'],0)")) - eq({'aa','bb'}, eval("systemlist('cat',['aa','bb',''],0)")) + eq({ 'aa', 'bb' }, eval("systemlist('cat',['aa','bb'],0)")) + eq({ 'aa', 'bb' }, eval("systemlist('cat',['aa','bb',''],0)")) end) it('1, preserves trailing newline', function() - eq({'aa','bb'}, eval("systemlist('cat',['aa','bb'],1)")) - eq({'aa','bb',''}, eval("systemlist('cat',['aa','bb',''],2)")) + eq({ 'aa', 'bb' }, eval("systemlist('cat',['aa','bb'],1)")) + eq({ 'aa', 'bb', '' }, eval("systemlist('cat',['aa','bb',''],2)")) end) end) it("with a program that doesn't close stdout will exit properly after passing input", function() local out = eval(string.format("systemlist('%s', 'clip-data')", testprg('streams-test'))) assert(out[1]:sub(0, 5) == 'pid: ', out) - os_kill(out[1]:match("%d+")) + os_kill(out[1]:match('%d+')) end) it('powershell w/ UTF-8 text #13713', function() if not helpers.has_powershell() then - pending("powershell not found", function() end) + pending('powershell not found', function() end) return end helpers.set_shell_powershell() - eq({is_os('win') and 'あ\r' or 'あ'}, eval([[systemlist('Write-Output あ')]])) + eq({ is_os('win') and 'あ\r' or 'あ' }, eval([[systemlist('Write-Output あ')]])) -- Sanity test w/ default encoding -- * on Windows, expected to default to Western European enc -- * on Linux, expected to default to UTF8 command([[let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command ']]) - eq({is_os('win') and '?\r' or 'あ'}, eval([[systemlist('Write-Output あ')]])) + eq({ is_os('win') and '?\r' or 'あ' }, eval([[systemlist('Write-Output あ')]])) end) - end) describe('shell :!', function() @@ -643,13 +582,13 @@ describe('shell :!', function() 2]]) if is_os('win') then feed(':4verbose %!sort /R<cr>') - screen:expect{ - any=[[Executing command: .?& { Get%-Content .* | & sort /R } 2>&1 | %%{ "$_" } | Out%-File .*; exit $LastExitCode"]] + screen:expect { + any = [[Executing command: .?& { Get%-Content .* | & sort /R } 2>&1 | %%{ "$_" } | Out%-File .*; exit $LastExitCode"]], } else feed(':4verbose %!sort -r<cr>') - screen:expect{ - any=[[Executing command: .?& { Get%-Content .* | & sort %-r } 2>&1 | %%{ "$_" } | Out%-File .*; exit $LastExitCode"]] + screen:expect { + any = [[Executing command: .?& { Get%-Content .* | & sort %-r } 2>&1 | %%{ "$_" } | Out%-File .*; exit $LastExitCode"]], } end feed('<CR>') @@ -673,20 +612,19 @@ describe('shell :!', function() 2]]) feed(':4verbose %w !sort<cr>') if is_os('win') then - screen:expect{ - any=[[Executing command: .?sort %< .*]] + screen:expect { + any = [[Executing command: .?sort %< .*]], } else - screen:expect{ - any=[[Executing command: .?%(sort%) %< .*]] - + screen:expect { + any = [[Executing command: .?%(sort%) %< .*]], } end feed('<CR>') helpers.set_shell_powershell(true) feed(':4verbose %w !sort<cr>') - screen:expect{ - any=[[Executing command: .?& { Get%-Content .* | & sort }]] + screen:expect { + any = [[Executing command: .?& { Get%-Content .* | & sort }]], } feed('<CR>') helpers.expect_exit(command, 'qall!') diff --git a/test/functional/vimscript/timer_spec.lua b/test/functional/vimscript/timer_spec.lua index a58cd6ae7f..046d451888 100644 --- a/test/functional/vimscript/timer_spec.lua +++ b/test/functional/vimscript/timer_spec.lua @@ -1,10 +1,10 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local feed, eq, eval, ok = helpers.feed, helpers.eq, helpers.eval, helpers.ok -local source, nvim_async, run = helpers.source, helpers.nvim_async, helpers.run -local clear, command, funcs = helpers.clear, helpers.command, helpers.funcs +local source, async_meths, run = helpers.source, helpers.async_meths, helpers.run +local clear, command, fn = helpers.clear, helpers.command, helpers.fn local exc_exec = helpers.exc_exec -local curbufmeths = helpers.curbufmeths +local api = helpers.api local load_adjust = helpers.load_adjust local retry = helpers.retry @@ -22,20 +22,20 @@ describe('timers', function() it('works one-shot', function() eq(0, eval("[timer_start(10, 'MyHandler'), g:val][1]")) run(nil, nil, nil, load_adjust(100)) - eq(1,eval("g:val")) + eq(1, eval('g:val')) end) it('works one-shot when repeat=0', function() eq(0, eval("[timer_start(10, 'MyHandler', {'repeat': 0}), g:val][1]")) run(nil, nil, nil, load_adjust(100)) - eq(1, eval("g:val")) + eq(1, eval('g:val')) end) it('works with repeat two', function() eq(0, eval("[timer_start(10, 'MyHandler', {'repeat': 2}), g:val][1]")) run(nil, nil, nil, load_adjust(20)) retry(nil, load_adjust(300), function() - eq(2, eval("g:val")) + eq(2, eval('g:val')) end) end) @@ -52,12 +52,12 @@ describe('timers', function() endfunc ]]) eval("timer_start(10, 'MyHandler', {'repeat': -1})") - nvim_async("command", "sleep 10") - eq(-1, eval("g:val")) -- timer did nothing yet. - nvim_async("command", "let g:val = 0") + async_meths.nvim_command('sleep 10') + eq(-1, eval('g:val')) -- timer did nothing yet. + async_meths.nvim_command('let g:val = 0') run(nil, nil, nil, load_adjust(20)) retry(nil, nil, function() - eq(2, eval("g:val")) + eq(2, eval('g:val')) end) end) @@ -65,52 +65,53 @@ describe('timers', function() -- timer_start does still not invoke the callback immediately eq(0, eval("[timer_start(0, 'MyHandler', {'repeat': 1000}), g:val][1]")) retry(nil, nil, function() - eq(1000, eval("g:val")) + eq(1000, eval('g:val')) end) end) it('can be started during sleep', function() - nvim_async("command", "sleep 10") + async_meths.nvim_command('sleep 10') -- this also tests that remote requests works during sleep eq(0, eval("[timer_start(10, 'MyHandler', {'repeat': 2}), g:val][1]")) run(nil, nil, nil, load_adjust(20)) - retry(nil, load_adjust(300), function() eq(2,eval("g:val")) end) + retry(nil, load_adjust(300), function() + eq(2, eval('g:val')) + end) end) it('are paused when event processing is disabled', function() command("call timer_start(5, 'MyHandler', {'repeat': -1})") run(nil, nil, nil, load_adjust(10)) - local count = eval("g:val") + local count = eval('g:val') -- shows two line error message and thus invokes the return prompt. -- if we start to allow event processing here, we need to change this test. feed(':throw "fatal error"<CR>') run(nil, nil, nil, load_adjust(30)) - feed("<cr>") - local diff = eval("g:val") - count - assert(0 <= diff and diff <= 4, - 'expected (0 <= diff <= 4), got: '..tostring(diff)) + feed('<cr>') + local diff = eval('g:val') - count + assert(0 <= diff and diff <= 4, 'expected (0 <= diff <= 4), got: ' .. tostring(diff)) end) it('are triggered in blocking getchar() call', function() command("call timer_start(5, 'MyHandler', {'repeat': -1})") - nvim_async("command", "let g:val = 0 | let g:c = getchar()") + async_meths.nvim_command('let g:val = 0 | let g:c = getchar()') retry(nil, nil, function() - local val = eval("g:val") + local val = eval('g:val') ok(val >= 2, '>= 2', tostring(val)) - eq(0, eval("getchar(1)")) + eq(0, eval('getchar(1)')) end) - feed("c") - eq(99, eval("g:c")) + feed('c') + eq(99, eval('g:c')) end) it('can invoke redraw in blocking getchar() call', function() local screen = Screen.new(40, 6) screen:attach() screen:set_default_attr_ids({ - [1] = {bold=true, foreground=Screen.colors.Blue}, + [1] = { bold = true, foreground = Screen.colors.Blue }, }) - curbufmeths.set_lines(0, -1, true, {"ITEM 1", "ITEM 2"}) + api.nvim_buf_set_lines(0, 0, -1, true, { 'ITEM 1', 'ITEM 2' }) source([[ let g:cont = 0 func! AddItem(timer) @@ -127,48 +128,49 @@ describe('timers', function() redraw endfunc ]]) - nvim_async("command", "let g:c2 = getchar()") - nvim_async("command", "call timer_start("..load_adjust(100)..", 'AddItem', {'repeat': -1})") + async_meths.nvim_command('let g:c2 = getchar()') + async_meths.nvim_command( + 'call timer_start(' .. load_adjust(100) .. ", 'AddItem', {'repeat': -1})" + ) screen:expect([[ ^ITEM 1 | ITEM 2 | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]) - nvim_async("command", "let g:cont = 1") + async_meths.nvim_command('let g:cont = 1') screen:expect([[ ^ITEM 1 | ITEM 2 | ITEM 3 | - {1:~ }| - {1:~ }| + {1:~ }|*2 | ]]) - feed("3") - eq(51, eval("g:c2")) - screen:expect{grid=[[ + feed('3') + eq(51, eval('g:c2')) + screen:expect { + grid = [[ ^ITEM 1 | ITEM 2 | ITEM 3 | - {1:~ }| - {1:~ }| + {1:~ }|*2 | - ]], unchanged=true} + ]], + unchanged = true, + } end) it('can be stopped', function() local t_init_val = eval("[timer_start(5, 'MyHandler', {'repeat': -1}), g:val]") eq(0, t_init_val[2]) run(nil, nil, nil, load_adjust(30)) - funcs.timer_stop(t_init_val[1]) - local count = eval("g:val") + fn.timer_stop(t_init_val[1]) + local count = eval('g:val') run(nil, load_adjust(300), nil, load_adjust(30)) - local count2 = eval("g:val") + local count2 = eval('g:val') -- when count is eval:ed after timer_stop this should be non-racy eq(count, count2) end) @@ -184,10 +186,10 @@ describe('timers', function() endif endfunc ]]) - eq(0, eval("g:val")) + eq(0, eval('g:val')) command("call timer_start(10, 'MyHandler', {'repeat': -1})") retry(nil, nil, function() - eq(3, eval("g:val")) + eq(3, eval('g:val')) end) end) @@ -201,8 +203,8 @@ describe('timers', function() command("call timer_start(2, 'MyHandler', {'repeat': 3})") command("call timer_start(4, 'MyHandler2', {'repeat': 2})") retry(nil, nil, function() - eq(3, eval("g:val")) - eq(2, eval("g:val2")) + eq(3, eval('g:val')) + eq(2, eval('g:val2')) end) end) @@ -218,15 +220,14 @@ describe('timers', function() command("call timer_start(5, 'MyHandler', {'repeat': 1})") run(nil, nil, nil, load_adjust(20)) retry(nil, load_adjust(150), function() - eq(1, eval("g:val")) + eq(1, eval('g:val')) end) end) - it("doesn't mess up the cmdline", function() local screen = Screen.new(40, 6) screen:attach() - screen:set_default_attr_ids( {[0] = {bold=true, foreground=255}} ) + screen:set_default_attr_ids({ [0] = { bold = true, foreground = 255 } }) source([[ let g:val = 0 func! MyHandler(timer) @@ -241,13 +242,10 @@ describe('timers', function() endfunc ]]) command("call timer_start(100, 'MyHandler', {'repeat': -1})") - feed(":good") + feed(':good') screen:expect([[ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 :good^ | ]]) command('let g:val = 1') @@ -262,7 +260,7 @@ describe('timers', function() call execute('echo ''execute() should be disallowed''', '') endfunction ]] - eq("Vim(call):E48: Not allowed in sandbox", exc_exec("sandbox call timer_start(0, 'Scary')")) + eq('Vim(call):E48: Not allowed in sandbox', exc_exec("sandbox call timer_start(0, 'Scary')")) end) it('can be triggered after an empty string <expr> mapping #17257', function() @@ -270,6 +268,6 @@ describe('timers', function() screen:attach() command([=[imap <expr> <F2> [timer_start(0, { _ -> execute("throw 'x'", "") }), ''][-1]]=]) feed('i<F2>') - screen:expect({any='E605: Exception not caught: x'}) + screen:expect({ any = 'E605: Exception not caught: x' }) end) end) diff --git a/test/functional/vimscript/uniq_spec.lua b/test/functional/vimscript/uniq_spec.lua index 43ad4a7640..8fd4004be4 100644 --- a/test/functional/vimscript/uniq_spec.lua +++ b/test/functional/vimscript/uniq_spec.lua @@ -10,8 +10,10 @@ before_each(clear) describe('uniq()', function() it('errors out when processing special values', function() - eq('Vim(call):E362: Using a boolean value as a Float', - exc_exec('call uniq([v:true, v:false], "f")')) + eq( + 'Vim(call):E362: Using a boolean value as a Float', + exc_exec('call uniq([v:true, v:false], "f")') + ) end) it('can yield E882 and stop filtering after that', function() @@ -23,7 +25,9 @@ describe('uniq()', function() return (a:a > a:b) - (a:a < a:b) endfunction ]]) - eq('Vim(let):E745: Using a List as a Number', - pcall_err(command, 'let fl = uniq([0, 0, [], 1, 1], "Cmp")')) + eq( + 'Vim(let):E745: Using a List as a Number', + pcall_err(command, 'let fl = uniq([0, 0, [], 1, 1], "Cmp")') + ) end) end) diff --git a/test/functional/vimscript/vvar_event_spec.lua b/test/functional/vimscript/vvar_event_spec.lua index eec8aa917a..68eda05363 100644 --- a/test/functional/vimscript/vvar_event_spec.lua +++ b/test/functional/vimscript/vvar_event_spec.lua @@ -12,4 +12,3 @@ describe('v:event', function() eq(false, pcall(command, 'let v:event.mykey = {}')) end) end) - diff --git a/test/functional/vimscript/wait_spec.lua b/test/functional/vimscript/wait_spec.lua index ee95e02a7f..50cdb2cfb4 100644 --- a/test/functional/vimscript/wait_spec.lua +++ b/test/functional/vimscript/wait_spec.lua @@ -7,14 +7,14 @@ local eq = helpers.eq local feed = helpers.feed local feed_command = helpers.feed_command local next_msg = helpers.next_msg -local nvim = helpers.nvim +local api = helpers.api local source = helpers.source local pcall_err = helpers.pcall_err before_each(function() clear() - local channel = nvim('get_api_info')[1] - nvim('set_var', 'channel', channel) + local channel = api.nvim_get_chan_info(0).id + api.nvim_set_var('channel', channel) end) describe('wait()', function() @@ -36,11 +36,12 @@ describe('wait()', function() end) it('returns -2 when interrupted', function() - feed_command('call rpcnotify(g:channel, "ready") | '.. - 'call rpcnotify(g:channel, "wait", wait(-1, 0))') - eq({'notification', 'ready', {}}, next_msg()) + feed_command( + 'call rpcnotify(g:channel, "ready") | ' .. 'call rpcnotify(g:channel, "wait", wait(-1, 0))' + ) + eq({ 'notification', 'ready', {} }, next_msg()) feed('<c-c>') - eq({'notification', 'wait', {-2}}, next_msg()) + eq({ 'notification', 'wait', { -2 } }, next_msg()) end) it('returns -3 on error', function() @@ -60,13 +61,13 @@ describe('wait()', function() -- XXX: flaky (#11137) helpers.retry(nil, nil, function() - nvim('set_var', 'counter', 0) + api.nvim_set_var('counter', 0) eq(-1, call('wait', 20, 'Count() >= 5', 99999)) end) - nvim('set_var', 'counter', 0) + api.nvim_set_var('counter', 0) eq(0, call('wait', 10000, 'Count() >= 5', 5)) - eq(5, nvim('get_var', 'counter')) + eq(5, api.nvim_get_var('counter')) end) it('validates args', function() diff --git a/test/functional/vimscript/writefile_spec.lua b/test/functional/vimscript/writefile_spec.lua index 88c19bd839..051e3794a3 100644 --- a/test/functional/vimscript/writefile_spec.lua +++ b/test/functional/vimscript/writefile_spec.lua @@ -1,11 +1,10 @@ local helpers = require('test.functional.helpers')(after_each) -local luv = require('luv') local mkdir = helpers.mkdir local clear = helpers.clear local eq = helpers.eq -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local exc_exec = helpers.exc_exec local read_file = helpers.read_file local write_file = helpers.write_file @@ -28,149 +27,175 @@ end) after_each(function() os.remove(fname) os.remove(dfname) - luv.fs_rmdir(ddname) - luv.fs_rmdir(dname) + vim.uv.fs_rmdir(ddname) + vim.uv.fs_rmdir(dname) end) describe('writefile()', function() it('writes empty list to a file', function() eq(nil, read_file(fname)) - eq(0, funcs.writefile({}, fname)) + eq(0, fn.writefile({}, fname)) eq('', read_file(fname)) os.remove(fname) eq(nil, read_file(fname)) - eq(0, funcs.writefile({}, fname, 'b')) + eq(0, fn.writefile({}, fname, 'b')) eq('', read_file(fname)) os.remove(fname) eq(nil, read_file(fname)) - eq(0, funcs.writefile({}, fname, 'ab')) + eq(0, fn.writefile({}, fname, 'ab')) eq('', read_file(fname)) os.remove(fname) eq(nil, read_file(fname)) - eq(0, funcs.writefile({}, fname, 'a')) + eq(0, fn.writefile({}, fname, 'a')) eq('', read_file(fname)) end) it('writes list with an empty string to a file', function() - eq(0, exc_exec( - ('call writefile([$XXX_NONEXISTENT_VAR_XXX], "%s", "b")'):format( - fname))) + eq(0, exc_exec(('call writefile([$XXX_NONEXISTENT_VAR_XXX], "%s", "b")'):format(fname))) eq('', read_file(fname)) - eq(0, exc_exec(('call writefile([$XXX_NONEXISTENT_VAR_XXX], "%s")'):format( - fname))) + eq(0, exc_exec(('call writefile([$XXX_NONEXISTENT_VAR_XXX], "%s")'):format(fname))) eq('\n', read_file(fname)) end) it('writes list with a null string to a file', function() - eq(0, exc_exec( - ('call writefile([v:_null_string], "%s", "b")'):format( - fname))) + eq(0, exc_exec(('call writefile([v:_null_string], "%s", "b")'):format(fname))) eq('', read_file(fname)) - eq(0, exc_exec(('call writefile([v:_null_string], "%s")'):format( - fname))) + eq(0, exc_exec(('call writefile([v:_null_string], "%s")'):format(fname))) eq('\n', read_file(fname)) end) it('appends to a file', function() eq(nil, read_file(fname)) - eq(0, funcs.writefile({'abc', 'def', 'ghi'}, fname)) + eq(0, fn.writefile({ 'abc', 'def', 'ghi' }, fname)) eq('abc\ndef\nghi\n', read_file(fname)) - eq(0, funcs.writefile({'jkl'}, fname, 'a')) + eq(0, fn.writefile({ 'jkl' }, fname, 'a')) eq('abc\ndef\nghi\njkl\n', read_file(fname)) os.remove(fname) eq(nil, read_file(fname)) - eq(0, funcs.writefile({'abc', 'def', 'ghi'}, fname, 'b')) + eq(0, fn.writefile({ 'abc', 'def', 'ghi' }, fname, 'b')) eq('abc\ndef\nghi', read_file(fname)) - eq(0, funcs.writefile({'jkl'}, fname, 'ab')) + eq(0, fn.writefile({ 'jkl' }, fname, 'ab')) eq('abc\ndef\nghijkl', read_file(fname)) end) it('correctly treats NLs', function() - eq(0, funcs.writefile({'\na\nb\n'}, fname, 'b')) + eq(0, fn.writefile({ '\na\nb\n' }, fname, 'b')) eq('\0a\0b\0', read_file(fname)) - eq(0, funcs.writefile({'a\n\n\nb'}, fname, 'b')) + eq(0, fn.writefile({ 'a\n\n\nb' }, fname, 'b')) eq('a\0\0\0b', read_file(fname)) end) it('writes with s and S', function() - eq(0, funcs.writefile({'\na\nb\n'}, fname, 'bs')) + eq(0, fn.writefile({ '\na\nb\n' }, fname, 'bs')) eq('\0a\0b\0', read_file(fname)) - eq(0, funcs.writefile({'a\n\n\nb'}, fname, 'bS')) + eq(0, fn.writefile({ 'a\n\n\nb' }, fname, 'bS')) eq('a\0\0\0b', read_file(fname)) end) it('correctly overwrites file', function() - eq(0, funcs.writefile({'\na\nb\n'}, fname, 'b')) + eq(0, fn.writefile({ '\na\nb\n' }, fname, 'b')) eq('\0a\0b\0', read_file(fname)) - eq(0, funcs.writefile({'a\n'}, fname, 'b')) + eq(0, fn.writefile({ 'a\n' }, fname, 'b')) eq('a\0', read_file(fname)) end) it('shows correct file name when supplied numbers', function() - meths.set_current_dir(dname) - eq('Vim(call):E482: Can\'t open file 2 for writing: illegal operation on a directory', - pcall_err(command, ('call writefile([42], %s)'):format(ddname_tail))) + api.nvim_set_current_dir(dname) + eq( + "Vim(call):E482: Can't open file 2 for writing: illegal operation on a directory", + pcall_err(command, ('call writefile([42], %s)'):format(ddname_tail)) + ) end) it('writefile(..., "p") creates missing parent directories', function() os.remove(dname) eq(nil, read_file(dfname)) - eq(0, funcs.writefile({'abc', 'def', 'ghi'}, dfname, 'p')) + eq(0, fn.writefile({ 'abc', 'def', 'ghi' }, dfname, 'p')) eq('abc\ndef\nghi\n', read_file(dfname)) os.remove(dfname) os.remove(dname) eq(nil, read_file(dfname)) - eq(0, funcs.writefile({'\na\nb\n'}, dfname, 'pb')) + eq(0, fn.writefile({ '\na\nb\n' }, dfname, 'pb')) eq('\0a\0b\0', read_file(dfname)) os.remove(dfname) os.remove(dname) - eq('Vim(call):E32: No file name', - pcall_err(command, ('call writefile([], "%s", "p")'):format(dfname .. '.d/'))) - eq(('Vim(call):E482: Can\'t open file ./ for writing: illegal operation on a directory'), - pcall_err(command, 'call writefile([], "./", "p")')) - eq(('Vim(call):E482: Can\'t open file . for writing: illegal operation on a directory'), - pcall_err(command, 'call writefile([], ".", "p")')) + eq( + 'Vim(call):E32: No file name', + pcall_err(command, ('call writefile([], "%s", "p")'):format(dfname .. '.d/')) + ) + eq( + "Vim(call):E482: Can't open file ./ for writing: illegal operation on a directory", + pcall_err(command, 'call writefile([], "./", "p")') + ) + eq( + "Vim(call):E482: Can't open file . for writing: illegal operation on a directory", + pcall_err(command, 'call writefile([], ".", "p")') + ) end) it('errors out with invalid arguments', function() write_file(fname, 'TEST') - eq('Vim(call):E119: Not enough arguments for function: writefile', - pcall_err(command, 'call writefile()')) - eq('Vim(call):E119: Not enough arguments for function: writefile', - pcall_err(command, 'call writefile([])')) - eq('Vim(call):E118: Too many arguments for function: writefile', - pcall_err(command, ('call writefile([], "%s", "b", 1)'):format(fname))) - for _, arg in ipairs({'0', '0.0', 'function("tr")', '{}', '"test"'}) do - eq('Vim(call):E475: Invalid argument: writefile() first argument must be a List or a Blob', - pcall_err(command, ('call writefile(%s, "%s", "b")'):format(arg, fname))) + eq( + 'Vim(call):E119: Not enough arguments for function: writefile', + pcall_err(command, 'call writefile()') + ) + eq( + 'Vim(call):E119: Not enough arguments for function: writefile', + pcall_err(command, 'call writefile([])') + ) + eq( + 'Vim(call):E118: Too many arguments for function: writefile', + pcall_err(command, ('call writefile([], "%s", "b", 1)'):format(fname)) + ) + for _, arg in ipairs({ '0', '0.0', 'function("tr")', '{}', '"test"' }) do + eq( + 'Vim(call):E475: Invalid argument: writefile() first argument must be a List or a Blob', + pcall_err(command, ('call writefile(%s, "%s", "b")'):format(arg, fname)) + ) end - for _, args in ipairs({'[], %s, "b"', '[], "' .. fname .. '", %s'}) do - eq('Vim(call):E730: Using a List as a String', - pcall_err(command, ('call writefile(%s)'):format(args:format('[]')))) - eq('Vim(call):E731: Using a Dictionary as a String', - pcall_err(command, ('call writefile(%s)'):format(args:format('{}')))) - eq('Vim(call):E729: Using a Funcref as a String', - pcall_err(command, ('call writefile(%s)'):format(args:format('function("tr")')))) + for _, args in ipairs({ '[], %s, "b"', '[], "' .. fname .. '", %s' }) do + eq( + 'Vim(call):E730: Using a List as a String', + pcall_err(command, ('call writefile(%s)'):format(args:format('[]'))) + ) + eq( + 'Vim(call):E731: Using a Dictionary as a String', + pcall_err(command, ('call writefile(%s)'):format(args:format('{}'))) + ) + eq( + 'Vim(call):E729: Using a Funcref as a String', + pcall_err(command, ('call writefile(%s)'):format(args:format('function("tr")'))) + ) end - eq('Vim(call):E5060: Unknown flag: «»', - pcall_err(command, ('call writefile([], "%s", "bs«»")'):format(fname))) + eq( + 'Vim(call):E5060: Unknown flag: «»', + pcall_err(command, ('call writefile([], "%s", "bs«»")'):format(fname)) + ) eq('TEST', read_file(fname)) end) it('does not write to file if error in list', function() local args = '["tset"] + repeat([%s], 3), "' .. fname .. '"' - eq('Vim(call):E805: Expected a Number or a String, Float found', - pcall_err(command, ('call writefile(%s)'):format(args:format('0.0')))) + eq( + 'Vim(call):E805: Expected a Number or a String, Float found', + pcall_err(command, ('call writefile(%s)'):format(args:format('0.0'))) + ) eq(nil, read_file(fname)) write_file(fname, 'TEST') - eq('Vim(call):E745: Expected a Number or a String, List found', - pcall_err(command, ('call writefile(%s)'):format(args:format('[]')))) + eq( + 'Vim(call):E745: Expected a Number or a String, List found', + pcall_err(command, ('call writefile(%s)'):format(args:format('[]'))) + ) eq('TEST', read_file(fname)) - eq('Vim(call):E728: Expected a Number or a String, Dictionary found', - pcall_err(command, ('call writefile(%s)'):format(args:format('{}')))) + eq( + 'Vim(call):E728: Expected a Number or a String, Dictionary found', + pcall_err(command, ('call writefile(%s)'):format(args:format('{}'))) + ) eq('TEST', read_file(fname)) - eq('Vim(call):E703: Expected a Number or a String, Funcref found', - pcall_err(command, ('call writefile(%s)'):format(args:format('function("tr")')))) + eq( + 'Vim(call):E703: Expected a Number or a String, Funcref found', + pcall_err(command, ('call writefile(%s)'):format(args:format('function("tr")'))) + ) eq('TEST', read_file(fname)) end) end) |