From f8f82901cdd0ccd5308e05c73af6deb7d083720f Mon Sep 17 00:00:00 2001 From: bfredl Date: Wed, 1 Feb 2023 12:54:22 +0100 Subject: fix(tests): fixes for using vim.mpack and more ASAN --- test/functional/api/vim_spec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/functional/api/vim_spec.lua') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 8fcdd9620b..fc550f5861 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -59,7 +59,7 @@ describe('API', function() -- XXX: This must be the last one, else next one will fail: -- "Packer instance already working. Use another Packer ..." - matches("can't serialize object$", + matches("can't serialize object of type .$", pcall_err(request, nil)) end) -- cgit From 46a87a5d2bac598fed0870f0d3c926087f95d30f Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 14 Feb 2023 05:19:04 -0500 Subject: refactor(api): VALIDATE macros #22187 Problem: - API validation involves too much boilerplate. - API validation errors are not consistently worded. Solution: Introduce some macros. Currently these are clumsy, but they at least help with consistency and avoid some nesting. --- test/functional/api/vim_spec.lua | 56 ++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 25 deletions(-) (limited to 'test/functional/api/vim_spec.lua') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index fc550f5861..5c56c90952 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1155,7 +1155,7 @@ describe('API', function() describe('nvim_put', function() it('validates args', function() - eq('Invalid lines (expected array of strings)', + 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)) @@ -1410,6 +1410,15 @@ describe('API', function() ok(not nvim('get_option_value', 'equalalways', {})) 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})) + 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'})) @@ -1780,9 +1789,9 @@ describe('API', function() it('validates args', function() eq("Invalid key: 'blah'", pcall_err(nvim, 'get_context', {blah={}})) - eq('invalid value for key: types', + eq("Invalid types: expected Array, got Integer", pcall_err(nvim, 'get_context', {types=42})) - eq('unexpected type: zub', + eq("Invalid type: 'zub'", pcall_err(nvim, 'get_context', {types={'jumps', 'zub', 'zam',}})) end) it('returns map of current editor state', function() @@ -2223,15 +2232,14 @@ describe('API', function() eq(5, meths.get_var('avar')) end) - it('throws error on malformed arguments', function() + it('validation', function() local req = { {'nvim_set_var', {'avar', 1}}, {'nvim_set_var'}, {'nvim_set_var', {'avar', 2}}, } - local status, err = pcall(meths.call_atomic, req) - eq(false, status) - ok(err:match('Items in calls array must be arrays of size 2') ~= nil) + eq('Items in calls array must be arrays of size 2', + pcall_err(meths.call_atomic, req)) -- call before was done, but not after eq(1, meths.get_var('avar')) @@ -2239,18 +2247,16 @@ describe('API', function() { 'nvim_set_var', { 'bvar', { 2, 3 } } }, 12, } - status, err = pcall(meths.call_atomic, req) - eq(false, status) - ok(err:match('Items in calls array must be arrays') ~= nil) + eq("Invalid calls item: expected Array, got Integer", + pcall_err(meths.call_atomic, req)) eq({2,3}, meths.get_var('bvar')) req = { {'nvim_set_current_line', 'little line'}, {'nvim_set_var', {'avar', 3}}, } - status, err = pcall(meths.call_atomic, req) - eq(false, status) - ok(err:match('Args must be Array') ~= nil) + eq("Invalid args: expected Array, got String", + pcall_err(meths.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)) @@ -2750,7 +2756,7 @@ describe('API', function() describe('nvim_get_option_info', function() it('should error for unknown options', function() - eq("no such option: 'bogus'", pcall_err(meths.get_option_info, 'bogus')) + eq("Invalid option (not found): 'bogus'", pcall_err(meths.get_option_info, 'bogus')) end) it('should return the same options for short and long name', function() @@ -3031,10 +3037,10 @@ describe('API', function() eq(true, meths.del_mark('F')) eq({0, 0}, meths.buf_get_mark(buf, 'F')) end) - it('fails when invalid marks are used', function() - eq(false, pcall(meths.del_mark, 'f')) - eq(false, pcall(meths.del_mark, '!')) - eq(false, pcall(meths.del_mark, 'fail')) + 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')) end) end) describe('nvim_get_mark', function() @@ -3048,10 +3054,10 @@ describe('API', function() assert(string.find(mark[4], "mybuf$")) eq({2, 2, buf.id, mark[4]}, mark) end) - it('fails when invalid marks are used', function() - eq(false, pcall(meths.del_mark, 'f')) - eq(false, pcall(meths.del_mark, '!')) - eq(false, pcall(meths.del_mark, 'fail')) + 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', {})) end) it('returns the expected when mark is not set', function() eq(true, meths.del_mark('A')) @@ -3113,15 +3119,15 @@ describe('API', function() meths.eval_statusline('a%=b', { fillchar = '\031', maxwidth = 5 })) end) it('rejects multiple-character fillchar', function() - eq('fillchar must be a single character', + eq('Invalid fillchar (not a single character)', pcall_err(meths.eval_statusline, '', { fillchar = 'aa' })) end) it('rejects empty string fillchar', function() - eq('fillchar must be a single character', + eq('Invalid fillchar (not a single character)', pcall_err(meths.eval_statusline, '', { fillchar = '' })) end) it('rejects non-string fillchar', function() - eq('fillchar must be a single character', + eq("Invalid fillchar: expected String, got Integer", pcall_err(meths.eval_statusline, '', { fillchar = 1 })) end) it('rejects invalid string', function() -- cgit From ff3d04b75b4a9314815c37d53ebc4d035a043335 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 14 Feb 2023 08:07:38 -0500 Subject: refactor(api): VALIDATE macros #22256 - VALIDATE() takes a format string - deduplicate check_string_array - VALIDATE_RANGE - validate UI args --- test/functional/api/vim_spec.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'test/functional/api/vim_spec.lua') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 5c56c90952..469d8e8b6a 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1411,9 +1411,9 @@ describe('API', function() end) it('validation', function() - eq("Invalid scope (expected 'local' or 'global')", + eq("Invalid scope: expected 'local' or 'global'", pcall_err(nvim, 'get_option_value', 'scrolloff', {scope = 'bogus'})) - eq("Invalid scope (expected 'local' or 'global')", + 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})) @@ -2238,7 +2238,7 @@ describe('API', function() {'nvim_set_var'}, {'nvim_set_var', {'avar', 2}}, } - eq('Items in calls array must be arrays of size 2', + eq('calls item must be a 2-item Array', pcall_err(meths.call_atomic, req)) -- call before was done, but not after eq(1, meths.get_var('avar')) @@ -3119,11 +3119,11 @@ describe('API', function() meths.eval_statusline('a%=b', { fillchar = '\031', maxwidth = 5 })) end) it('rejects multiple-character fillchar', function() - eq('Invalid fillchar (not a single character)', + eq('Invalid fillchar: expected single character', pcall_err(meths.eval_statusline, '', { fillchar = 'aa' })) end) it('rejects empty string fillchar', function() - eq('Invalid fillchar (not a single character)', + eq('Invalid fillchar: expected single character', pcall_err(meths.eval_statusline, '', { fillchar = '' })) end) it('rejects non-string fillchar', function() -- cgit From 556f8646c01d1751cf39fe4df9c622899dceab9d Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 14 Feb 2023 14:19:28 -0500 Subject: refactor(api): consistent VALIDATE messages #22262 Problem: Validation messages are not consistently formatted. - Parameter names sometimes are NOT quoted. - Descriptive names (non-parameters) sometimes ARE quoted. Solution: Always quote the `name` value passed to a VALIDATE macro _unless_ the value has whitespace. --- test/functional/api/vim_spec.lua | 51 +++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 22 deletions(-) (limited to 'test/functional/api/vim_spec.lua') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 469d8e8b6a..981fc19b36 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -490,7 +490,7 @@ describe('API', function() eq('', eval('v:errmsg')) -- v:errmsg was not updated. end) - it('validates args', function() + it('validation', function() 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 @@ -532,7 +532,7 @@ describe('API', function() eq('@it works@', nvim('call_dict_function', { result = 'it works', G = 'G'}, 'G', {})) end) - it('validates args', function() + 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})) @@ -648,10 +648,10 @@ describe('API', function() end) describe('nvim_paste', function() - it('validates args', function() - eq('Invalid phase: -2', + it('validation', function() + eq("Invalid 'phase': -2", pcall_err(request, 'nvim_paste', 'foo', true, -2)) - eq('Invalid phase: 4', + eq("Invalid 'phase': 4", pcall_err(request, 'nvim_paste', 'foo', true, 4)) end) local function run_streamed_paste_tests() @@ -1154,10 +1154,10 @@ describe('API', function() end) describe('nvim_put', function() - it('validates args', function() - eq("Invalid line: expected String, got Integer", + it('validation', function() + eq("Invalid 'line': expected String, got Integer", pcall_err(request, 'nvim_put', {42}, 'l', false, false)) - eq("Invalid type: 'x'", + eq("Invalid 'type': 'x'", pcall_err(request, 'nvim_put', {'foo'}, 'x', false, false)) end) it("fails if 'nomodifiable'", function() @@ -1259,9 +1259,9 @@ describe('API', function() yyybc line 2 line 3 ]]) - eq("Invalid type: 'bx'", + eq("Invalid 'type': 'bx'", pcall_err(meths.put, {'xxx', 'yyy'}, 'bx', false, true)) - eq("Invalid type: 'b3x'", + eq("Invalid 'type': 'b3x'", pcall_err(meths.put, {'xxx', 'yyy'}, 'b3x', false, true)) end) end) @@ -1288,6 +1288,11 @@ describe('API', function() 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')) + 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')) @@ -1411,12 +1416,14 @@ describe('API', function() end) it('validation', function() - eq("Invalid scope: expected 'local' or 'global'", + eq("Invalid 'scope': expected 'local' or 'global'", pcall_err(nvim, 'get_option_value', 'scrolloff', {scope = 'bogus'})) - eq("Invalid scope: expected 'local' or 'global'", + eq("Invalid 'scope': expected 'local' or 'global'", pcall_err(nvim, 'set_option_value', 'scrolloff', 1, {scope = 'bogus'})) - eq("Invalid scope: expected String, got Integer", + eq("Invalid 'scope': expected String, got Integer", pcall_err(nvim, 'get_option_value', 'scrolloff', {scope = 42})) + eq("Invalid 'scrolloff': expected Integer/Boolean/String, got Array", + pcall_err(nvim, 'set_option_value', 'scrolloff', {}, {})) end) it('can get local values when global value is set', function() @@ -1786,12 +1793,12 @@ describe('API', function() end) describe('nvim_get_context', function() - it('validates args', function() + it('validation', function() eq("Invalid key: 'blah'", pcall_err(nvim, 'get_context', {blah={}})) - eq("Invalid types: expected Array, got Integer", + eq("Invalid 'types': expected Array, got Integer", pcall_err(nvim, 'get_context', {types=42})) - eq("Invalid type: 'zub'", + eq("Invalid 'type': 'zub'", pcall_err(nvim, 'get_context', {types={'jumps', 'zub', 'zam',}})) end) it('returns map of current editor state', function() @@ -2238,7 +2245,7 @@ describe('API', function() {'nvim_set_var'}, {'nvim_set_var', {'avar', 2}}, } - eq('calls item must be a 2-item Array', + eq("Invalid 'calls' item: expected 2-item Array", pcall_err(meths.call_atomic, req)) -- call before was done, but not after eq(1, meths.get_var('avar')) @@ -2247,7 +2254,7 @@ describe('API', function() { 'nvim_set_var', { 'bvar', { 2, 3 } } }, 12, } - eq("Invalid calls item: expected Array, got Integer", + eq("Invalid 'calls' item: expected Array, got Integer", pcall_err(meths.call_atomic, req)) eq({2,3}, meths.get_var('bvar')) @@ -2255,7 +2262,7 @@ describe('API', function() {'nvim_set_current_line', 'little line'}, {'nvim_set_var', {'avar', 3}}, } - eq("Invalid args: expected Array, got String", + eq("Invalid call args: expected Array, got String", pcall_err(meths.call_atomic, req)) -- call before was done, but not after eq(1, meths.get_var('avar')) @@ -3119,15 +3126,15 @@ describe('API', function() meths.eval_statusline('a%=b', { fillchar = '\031', maxwidth = 5 })) end) it('rejects multiple-character fillchar', function() - eq('Invalid fillchar: expected single character', + eq("Invalid 'fillchar': expected single character", pcall_err(meths.eval_statusline, '', { fillchar = 'aa' })) end) it('rejects empty string fillchar', function() - eq('Invalid fillchar: expected single character', + eq("Invalid 'fillchar': expected single character", pcall_err(meths.eval_statusline, '', { fillchar = '' })) end) it('rejects non-string fillchar', function() - eq("Invalid fillchar: expected String, got Integer", + eq("Invalid 'fillchar': expected String, got Integer", pcall_err(meths.eval_statusline, '', { fillchar = 1 })) end) it('rejects invalid string', function() -- cgit From 09b3432eaff3abcadb56d61b6f247f992b80b63f Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 16 Feb 2023 10:07:18 -0500 Subject: fix(api): allow empty Lua table for nested dicts #22268 Problem: The Lua-API bridge allows Dict params to be empty Lua (list) tables at the function-signature level. But not for _nested_ Dicts, because they are not modeled: https://github.com/neovim/neovim/blob/fae754073289566051433fae74ec65783f9e7a6a/src/nvim/api/keysets.lua#L184 Some API functions like nvim_cmd check for kObjectTypeDictionary and don't handle the case of empty Lua tables (treated as "Array"). Solution: Introduce VALIDATE_T_DICT and use it in places where kObjectTypeDictionary was being checked directly. fixes #21005 --- test/functional/api/vim_spec.lua | 57 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'test/functional/api/vim_spec.lua') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 981fc19b36..3e40967dd5 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -3826,14 +3826,71 @@ describe('API', function() meths.cmd({ cmd = "set", args = { "cursorline" } }, {}) eq(true, meths.get_option_value("cursorline", {})) end) + + it('validation', function() + eq("Invalid 'cmd': expected non-empty String", + pcall_err(meths.cmd, { cmd = ""}, {})) + eq("Invalid 'cmd': expected non-empty String", + pcall_err(meths.cmd, { cmd = {}}, {})) + eq("Invalid 'args': expected Array, got Boolean", + pcall_err(meths.cmd, { cmd = "set", args = true }, {})) + eq("Invalid 'magic': expected Dict, got Array", + pcall_err(meths.cmd, { cmd = "set", args = {}, magic = {} }, {})) + 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 non-negative Integer", + 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' }, {})) + + -- 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 = {} }]])) + + -- Lua call does not allow non-empty list-like {} for dict item. + eq("Invalid 'magic': expected Dict, got Array", + 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 })) end) + it('sets correct script context', function() meths.cmd({ cmd = "set", args = { "cursorline" } }, {}) local str = meths.exec([[verbose set cursorline?]], true) neq(nil, str:find("cursorline\n\tLast set from API client %(channel id %d+%)")) end) + it('works with range', function() insert [[ line1 -- cgit From 7f424e2b65779c59fc0cac3cc7508ba2ec07f200 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 23 Feb 2023 18:29:36 +0100 Subject: feat(api): more fields in nvim_list_uis Problem: nvim_list_uis does not report all ":help ui-option" fields. Solution: Store ":help ui-option" fields on the `UI` object and update ui_array. --- test/functional/api/vim_spec.lua | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'test/functional/api/vim_spec.lua') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 3e40967dd5..08abf82f47 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -2549,20 +2549,26 @@ describe('API', function() { chan = 1, ext_cmdline = false, - ext_popupmenu = false, - ext_tabline = false, - ext_wildmenu = false, + ext_hlstate = false, ext_linegrid = screen._options.ext_linegrid or false, + ext_messages = false, ext_multigrid = false, - ext_hlstate = false, + ext_popupmenu = false, + ext_tabline = false, ext_termcolors = false, - ext_messages = false, + ext_wildmenu = false, height = 4, - rgb = true, override = true, + rgb = true, + stdin_tty = false, + stdout_tty = false, + term_background = '', + term_colors = 0, + term_name = '', width = 20, } } + eq(expected, nvim("list_uis")) screen:detach() -- cgit From 6d0c61d90d316473eee0729363e20bf06825b09b Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 11 Mar 2023 21:09:11 +0800 Subject: fix(api): set script context when setting usercmd or option (#22624) --- test/functional/api/vim_spec.lua | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'test/functional/api/vim_spec.lua') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 08abf82f47..48ac491ade 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -2832,6 +2832,24 @@ describe('API', function() type = "boolean", was_set = true }, meths.get_option_info'showcmd') + + meths.set_option_value('showcmd', true, {}) + + eq({ + allows_duplicates = true, + commalist = false, + default = true, + flaglist = false, + global_local = false, + 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') end) end) -- cgit From 673d2b52fa4335aa083c52e6686f0728e25b8ebd Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 7 Mar 2023 16:04:57 +0100 Subject: refactor!: rename vim.pretty_print => vim.print Problem: The function name `vim.pretty_print`: 1. is verbose, which partially defeats its purpose as sugar 2. does not draw from existing precedent or any sort of convention (except external projects like penlight or python?), which reduces discoverability, and degrades signaling about best practices. Solution: - Rename to `vim.print`. - Change the behavior so that 1. strings are printed without quotes 2. each arg is printed on its own line 3. tables are indented with 2 instead of 4 spaces - Example: :lua ='a', 'b', 42, {a=3} a b 42 { a = 3 } Comparison of alternatives: - `vim.print`: - pro: consistent with Lua's `print()` - pro: aligns with potential `nvim_print` API function which will replace nvim_echo, nvim_notify, etc. - con: behaves differently than Lua's `print()`, slightly misleading? - `vim.echo`: - pro: `:echo` has similar "pretty print" behavior. - con: inconsistent with Lua idioms. - `vim.p`: - pro: very short, fits with `vim.o`, etc. - con: not as discoverable as "echo" - con: less opportunity for `local p = vim.p` because of potential shadowing. --- test/functional/api/vim_spec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/functional/api/vim_spec.lua') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 48ac491ade..2af041c706 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -4042,7 +4042,7 @@ describe('API', function() it('splits arguments correctly for Lua callback', function() meths.exec_lua([[ local function FooFunc(opts) - vim.pretty_print(opts.fargs) + vim.print(opts.fargs) end vim.api.nvim_create_user_command("Foo", FooFunc, { nargs = '+' }) -- cgit From e5641df6d3fc3bb6c3c55593b6152082bfc561b6 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Sat, 11 Mar 2023 17:11:02 +0000 Subject: feat: add `vim.filetype.get_option()` --- test/functional/api/vim_spec.lua | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'test/functional/api/vim_spec.lua') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 2af041c706..ff1bfef591 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1518,6 +1518,31 @@ describe('API', function() nvim('get_option_value', 'filetype', {buf = buf}) eq({1, 9}, nvim('win_get_cursor', win)) end) + + it('can get default option values for filetypes', function() + command('filetype plugin on') + for ft, opts in pairs { + lua = { commentstring = '-- %s' }, + vim = { commentstring = '"%s' }, + 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 })) + end + end + + command'au FileType lua setlocal commentstring=NEW\\ %s' + + eq('NEW %s', 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' })) + end) + end) describe('nvim_{get,set}_current_buf, nvim_list_bufs', function() -- cgit From fe9cbcb3a5c82932ecfb8f49d07e98a1fc2b31e5 Mon Sep 17 00:00:00 2001 From: Evgeni Chasnovski Date: Sat, 25 Mar 2023 18:58:48 +0200 Subject: feat(api): nvim_exec2(), deprecate nvim_exec() #19032 Problem: The signature of nvim_exec() is not extensible per ":help api-contract". Solution: Introduce nvim_exec2() and deprecate nvim_exec(). --- test/functional/api/vim_spec.lua | 149 +++++++++++++++++++++------------------ 1 file changed, 81 insertions(+), 68 deletions(-) (limited to 'test/functional/api/vim_spec.lua') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index ff1bfef591..162735dbd7 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -89,132 +89,145 @@ describe('API', function() eq({mode='i', blocking=false}, nvim("get_mode")) end) - describe('nvim_exec', function() + 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 })) + end) + + it('default options', function() + -- Should be equivalent to { output = false } + nvim('exec2', "let x0 = 'a'", {}) + eq('a', nvim('get_var', 'x0')) + end) + it('one-line input', function() - nvim('exec', "let x1 = 'a'", false) + nvim('exec2', "let x1 = 'a'", { output = false }) eq('a', nvim('get_var', 'x1')) end) it(':verbose set {option}?', function() - nvim('exec', 'set nowrap', false) - eq('nowrap\n\tLast set from anonymous :source', - nvim('exec', 'verbose set wrap?', true)) + nvim('exec2', 'set nowrap', { output = false }) + eq({ output = 'nowrap\n\tLast set from anonymous :source' }, + nvim('exec2', 'verbose set wrap?', { output = true })) -- Using script var to force creation of a script item - nvim('exec', [[ + nvim('exec2', [[ let s:a = 1 set nowrap - ]], false) - eq('nowrap\n\tLast set from anonymous :source (script id 1)', - nvim('exec', 'verbose set wrap?', true)) + ]], { output = false }) + eq({ output = 'nowrap\n\tLast set from anonymous :source (script id 1)' }, + nvim('exec2', 'verbose set wrap?', { output = true })) end) it('multiline input', function() -- Heredoc + empty lines. - nvim('exec', "let x2 = 'a'\n", false) + nvim('exec2', "let x2 = 'a'\n", { output = false }) eq('a', nvim('get_var', 'x2')) - nvim('exec','lua <avast_ye_hades('ahoy!') - ]], true)) + ]], { output = true })) - eq('ahoy! script-scoped varrrrr', nvim('exec', [[ + eq({ output = "{'output': 'ahoy! script-scoped varrrrr'}" }, nvim('exec2', [[ let s:pirate = 'script-scoped varrrrr' function! Avast_ye_hades(s) abort return a:s .. ' ' .. s:pirate endfunction - echo nvim_exec('echo Avast_ye_hades(''ahoy!'')', 1) - ]], true)) + 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_exec', [[ + pcall_err(request, 'nvim_exec2', [[ let s:pirate = 'script-scoped varrrrr' - call nvim_exec('echo s:pirate', 1) - ]], false)) + call nvim_exec2('echo s:pirate', {'output': v:true}) + ]], { output = false })) -- Script items are created only on script var access - eq('1\n0', nvim('exec', [[ + eq({ output = '1\n0' }, nvim('exec2', [[ echo expand("")->empty() let s:a = 123 echo expand("")->empty() - ]], true)) + ]], { output = true })) - eq('1\n0', nvim('exec', [[ + eq({ output = '1\n0' }, nvim('exec2', [[ echo expand("")->empty() function s:a() abort endfunction echo expand("")->empty() - ]], true)) + ]], { output = true })) end) it('non-ASCII input', function() - nvim('exec', [=[ + nvim('exec2', [=[ new exe "normal! i ax \n Ax " :%s/ax/--a1234--/g | :%s/Ax/--A1234--/g - ]=], false) + ]=], { output = false }) nvim('command', '1') eq(' --a1234-- ', nvim('get_current_line')) nvim('command', '2') eq(' --A1234-- ', nvim('get_current_line')) - nvim('exec', [[ + nvim('exec2', [[ new call setline(1,['xxx']) call feedkeys('r') call feedkeys('ñ', 'xt') - ]], false) + ]], { output = false }) eq('ñxx', nvim('get_current_line')) end) it('execution error', function() - eq('nvim_exec(): Vim:E492: Not an editor command: bogus_command', - pcall_err(request, 'nvim_exec', 'bogus_command', false)) + 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('', eval('v:exception')) - eq('nvim_exec(): Vim(buffer):E86: Buffer 23487 does not exist', - pcall_err(request, 'nvim_exec', 'buffer 23487', false)) + 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) @@ -222,17 +235,17 @@ describe('API', function() it('recursion', function() local fname = tmpname() write_file(fname, 'let x1 = "set from :source file"\n') - -- nvim_exec + -- nvim_exec2 -- :source - -- nvim_exec - request('nvim_exec', [[ + -- nvim_exec2 + request('nvim_exec2', [[ let x2 = substitute('foo','o','X','g') let x4 = 'should be overwritten' - call nvim_exec("source ]]..fname..[[\nlet x3 = substitute('foo','foo','set by recursive nvim_exec','g')\nlet x5='overwritten'\nlet x4=x5\n", v:false) - ]], false) + 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')) - eq('set by recursive nvim_exec', request('nvim_get_var', 'x3')) + eq('set by recursive nvim_exec2', request('nvim_get_var', 'x3')) eq('overwritten', request('nvim_get_var', 'x4')) eq('overwritten', request('nvim_get_var', 'x5')) os.remove(fname) @@ -242,35 +255,35 @@ describe('API', function() local fname = tmpname() write_file(fname, 'echo "hello"\n') local sourcing_fname = tmpname() - write_file(sourcing_fname, 'call nvim_exec("source '..fname..'", v:false)\n') - meths.exec('set verbose=2', false) + 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_exec() called at '..sourcing_fname..':1\n'.. + 'continuing in nvim_exec2() called at '..sourcing_fname..':1\n'.. 'finished sourcing '..sourcing_fname..'\n'.. - 'continuing in nvim_exec() called at nvim_exec():0' - eq(traceback_output, - meths.exec('call nvim_exec("source '..sourcing_fname..'", v:false)', true)) + '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 })) os.remove(fname) os.remove(sourcing_fname) end) it('returns output', function() - eq('this is spinal tap', - nvim('exec', 'lua <]]) @@ -575,7 +588,7 @@ describe('API', function() it('sets previous directory', function() meths.set_current_dir("Xtestdir") - meths.exec('cd -', false) + meths.exec2('cd -', { output = false }) eq(funcs.getcwd(), start_dir) end) end) @@ -2674,7 +2687,7 @@ describe('API', function() eq(' 1 %a "[No Name]" line 1\n'.. ' 3 h "[Scratch]" line 0\n'.. ' 4 h "[Scratch]" line 0', - meths.exec('ls', true)) + meths.exec2('ls', { output = true }).output) -- current buffer didn't change eq({id=1}, meths.get_current_buf()) @@ -2788,7 +2801,7 @@ describe('API', function() end) it('should not crash when echoed', function() - meths.exec("echo nvim_get_all_options_info()", true) + meths.exec2("echo nvim_get_all_options_info()", { output = true }) end) end) @@ -2941,13 +2954,13 @@ describe('API', function() it('can save message history', function() nvim('command', 'set cmdheight=2') -- suppress Press ENTER nvim("echo", {{"msg\nmsg"}, {"msg"}}, true, {}) - eq("msg\nmsgmsg", meths.exec('messages', true)) + eq("msg\nmsgmsg", meths.exec2('messages', { output = true }).output) end) it('can disable saving message history', function() nvim('command', 'set cmdheight=2') -- suppress Press ENTER nvim_async("echo", {{"msg\nmsg"}, {"msg"}}, false, {}) - eq("", meths.exec("messages", true)) + eq("", meths.exec2("messages", { output = true }).output) end) end) @@ -3936,7 +3949,7 @@ describe('API', function() it('sets correct script context', function() meths.cmd({ cmd = "set", args = { "cursorline" } }, {}) - local str = meths.exec([[verbose set cursorline?]], true) + local str = meths.exec2([[verbose set cursorline?]], { output = true }).output neq(nil, str:find("cursorline\n\tLast set from API client %(channel id %d+%)")) end) @@ -3986,7 +3999,7 @@ describe('API', function() line6 ]] meths.cmd({ cmd = "del", range = { 2, 4 }, reg = 'a' }, {}) - meths.exec("1put a", false) + meths.exec2("1put a", { output = false }) expect [[ line1 line2 @@ -4051,11 +4064,11 @@ describe('API', function() { output = true })) end) it('splits arguments correctly', function() - meths.exec([[ + meths.exec2([[ function! FooFunc(...) echo a:000 endfunction - ]], false) + ]], { output = false }) meths.create_user_command("Foo", "call 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"}}, -- cgit From 4863ca6b8902c5b0aab95f2af640118cd417d379 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 26 Mar 2023 10:49:32 +0800 Subject: test: use exec_capture() in more places (#22787) Problem: Using `meths.exec2("code", { output = true })` is too verbose. Solution: Use exec_capture() in more places. --- test/functional/api/vim_spec.lua | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'test/functional/api/vim_spec.lua') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 162735dbd7..d8fb1bc623 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -9,6 +9,7 @@ local NIL = helpers.NIL local clear, nvim, eq, neq = helpers.clear, helpers.nvim, helpers.eq, helpers.neq local command = helpers.command local exec = helpers.exec +local exec_capture = helpers.exec_capture local eval = helpers.eval local expect = helpers.expect local funcs = helpers.funcs @@ -588,7 +589,7 @@ describe('API', function() it('sets previous directory', function() meths.set_current_dir("Xtestdir") - meths.exec2('cd -', { output = false }) + command('cd -') eq(funcs.getcwd(), start_dir) end) end) @@ -2687,7 +2688,7 @@ describe('API', function() eq(' 1 %a "[No Name]" line 1\n'.. ' 3 h "[Scratch]" line 0\n'.. ' 4 h "[Scratch]" line 0', - meths.exec2('ls', { output = true }).output) + exec_capture('ls')) -- current buffer didn't change eq({id=1}, meths.get_current_buf()) @@ -2954,13 +2955,13 @@ describe('API', function() it('can save message history', function() nvim('command', 'set cmdheight=2') -- suppress Press ENTER nvim("echo", {{"msg\nmsg"}, {"msg"}}, true, {}) - eq("msg\nmsgmsg", meths.exec2('messages', { output = true }).output) + 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("", meths.exec2("messages", { output = true }).output) + eq("", exec_capture('messages')) end) end) @@ -3949,7 +3950,7 @@ describe('API', function() it('sets correct script context', function() meths.cmd({ cmd = "set", args = { "cursorline" } }, {}) - local str = meths.exec2([[verbose set cursorline?]], { output = true }).output + local str = exec_capture([[verbose set cursorline?]]) neq(nil, str:find("cursorline\n\tLast set from API client %(channel id %d+%)")) end) @@ -3999,7 +4000,7 @@ describe('API', function() line6 ]] meths.cmd({ cmd = "del", range = { 2, 4 }, reg = 'a' }, {}) - meths.exec2("1put a", { output = false }) + command('1put a') expect [[ line1 line2 @@ -4064,11 +4065,11 @@ describe('API', function() { output = true })) end) it('splits arguments correctly', function() - meths.exec2([[ + exec([[ function! FooFunc(...) echo a:000 endfunction - ]], { output = false }) + ]]) meths.create_user_command("Foo", "call 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"}}, -- cgit From b7748662ed5b06c12a74560690b728fdf770666f Mon Sep 17 00:00:00 2001 From: Michal Liszcz Date: Wed, 29 Mar 2023 09:59:01 +0200 Subject: fix(api): Use local LastSet structure in nvim_get_option_info (#22741) fix(api): use local LastSet structure in nvim_get_option_info * nvim_get_option_info is deprecated. It is always using the global LastSet information as reported in #15232. * nvim_get_option_info2 is added. The new function additionally accepts an 'opts' table {scope, buf, win} allowing to specify the option scope and query local options from another buffer or window. --- test/functional/api/vim_spec.lua | 93 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) (limited to 'test/functional/api/vim_spec.lua') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index d8fb1bc623..9d5a0c4b4e 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -2892,6 +2892,99 @@ describe('API', function() end) end) + describe('nvim_get_option_info2', function() + local fname + local bufs + local wins + + before_each(function() + fname = tmpname() + write_file(fname, [[ + setglobal dictionary=mydict " 1, global-local (buffer) + setlocal formatprg=myprg " 2, global-local (buffer) + setglobal equalprg=prg1 " 3, global-local (buffer) + setlocal equalprg=prg2 " 4, global-local (buffer) + setglobal fillchars=stl:x " 5, global-local (window) + setlocal listchars=eol:c " 6, global-local (window) + 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) + + bufs = meths.list_bufs() + wins = meths.list_wins() + + meths.win_set_buf(wins[1].id, bufs[1].id) + meths.win_set_buf(wins[2].id, bufs[2].id) + + meths.set_current_win(wins[2].id) + meths.exec('source ' .. fname, false) + + meths.set_current_win(wins[1].id) + end) + + after_each(function() + os.remove(fname) + 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 + end) + + describe('last set', function() + 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'}}}, + {desc="(buf option, global requested, both set) points to global", linenr=3, sid=1, args={'equalprg', {scope='global'}}}, + {desc="(buf option, local requested, global set) is not set", linenr=0, sid=0, args={'dictionary', {scope='local'}}}, + {desc="(buf option, local requested, local set) points to local", linenr=2, sid=1, args={'formatprg', {scope='local'}}}, + {desc="(buf option, local requested, both set) points to local", linenr=4, sid=1, args={'equalprg', {scope='local'}}}, + {desc="(buf option, fallback requested, global set) points to global", linenr=1, sid=1, args={'dictionary', {}}}, + {desc="(buf option, fallback requested, local set) points to local", linenr=2, sid=1, args={'formatprg', {}}}, + {desc="(buf option, fallback requested, both set) points to local", linenr=4, sid=1, args={'equalprg', {}}}, + {desc="(win option, global requested, global set) points to global", linenr=5, sid=1, args={'fillchars', {scope='global'}}}, + {desc="(win option, global requested, local set) is not set", linenr=0, sid=0, args={'listchars', {scope='global'}}}, + {desc="(win option, global requested, both set) points to global", linenr=7, sid=1, args={'showbreak', {scope='global'}}}, + {desc="(win option, local requested, global set) is not set", linenr=0, sid=0, args={'fillchars', {scope='local'}}}, + {desc="(win option, local requested, local set) points to local", linenr=6, sid=1, args={'listchars', {scope='local'}}}, + {desc="(win option, local requested, both set) points to local", linenr=8, sid=1, args={'showbreak', {scope='local'}}}, + {desc="(win option, fallback requested, global set) points to global", linenr=5, sid=1, args={'fillchars', {}}}, + {desc="(win option, fallback requested, local set) points to local", linenr=6, sid=1, args={'listchars', {}}}, + {desc="(win option, fallback requested, both set) points to local", linenr=8, sid=1, args={'showbreak', {}}}, + {desc="(global option, global requested) points to global", linenr=9, sid=1, args={'completeopt', {scope='global'}}}, + {desc="(global option, local requested) is not set", linenr=0, sid=0, args={'completeopt', {scope='local'}}}, + {desc="(global option, fallback requested) points to global", linenr=9, sid=1, args={'completeopt', {}}}, + } + + 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)) + 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}) + 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}) + eq(6, info.last_set_linenr) + eq(1, info.last_set_sid) + end) + end) + end) + describe('nvim_echo', function() local screen -- cgit From 7c8c1550737b34fabb3e4cecbc6b6bf3581b2235 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 4 Apr 2023 08:59:11 +0800 Subject: fix(api): avoid double hit-enter prompt with nvim_err_writeln (#22879) --- test/functional/api/vim_spec.lua | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'test/functional/api/vim_spec.lua') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 9d5a0c4b4e..83347a499b 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -2080,6 +2080,46 @@ describe('API', function() end) end) + describe('nvim_err_writeln', function() + local screen + + before_each(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}, + }) + end) + + it('shows only one return prompt after all lines are shown', function() + nvim_async('err_writeln', 'FAILURE\nERROR\nEXCEPTION\nTRACEBACK') + screen:expect([[ + | + {0:~ }| + {3: }| + {1:FAILURE} | + {1:ERROR} | + {1:EXCEPTION} | + {1:TRACEBACK} | + {2:Press ENTER or type command to continue}^ | + ]]) + feed('') + screen:expect([[ + ^ | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + end) + end) + describe('nvim_list_chans, nvim_get_chan_info', function() before_each(function() command('autocmd ChanOpen * let g:opened_event = deepcopy(v:event)') -- cgit From a5c572bd446a89be2dccb2f7479ff1b017074640 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Tue, 4 Apr 2023 19:07:33 +0200 Subject: docs: fix typos Co-authored-by: Gregory Anders Co-authored-by: Raphael Co-authored-by: C.D. MacEachern Co-authored-by: himanoa --- test/functional/api/vim_spec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/functional/api/vim_spec.lua') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 83347a499b..de0d82119c 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -4180,7 +4180,7 @@ describe('API', function() meths.cmd({ cmd = "buffers", mods = { filter = { pattern = "foo", force = true } } }, { output = true })) - -- with emsg_silent = true error is suppresed + -- with emsg_silent = true error is suppressed feed([[:lua vim.api.nvim_cmd({ cmd = 'call', mods = { emsg_silent = true } }, {})]]) eq('', meths.cmd({ cmd = 'messages' }, { output = true })) -- error from the next command typed is not suppressed #21420 -- cgit From 743860de40502227b3f0ed64317eb937d24d4a36 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Tue, 4 Apr 2023 21:59:06 +0200 Subject: test: replace lfs with luv and vim.fs test: replace lfs with luv luv already pretty much does everything lfs does, so this duplication of dependencies isn't needed. --- test/functional/api/vim_spec.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'test/functional/api/vim_spec.lua') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index de0d82119c..ab26425425 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1,6 +1,5 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local lfs = require('lfs') local luv = require('luv') local fmt = string.format @@ -4193,7 +4192,7 @@ describe('API', function() vim.api.nvim_echo({{ opts.fargs[1] }}, false, {}) end, { nargs = 1 }) ]]) - eq(lfs.currentdir(), + eq(luv.cwd(), meths.cmd({ cmd = "Foo", args = { '%:p:h' }, magic = { file = true } }, { output = true })) end) -- cgit From f0ac91c58b42ed4f38dea7352d89fd39a88142f4 Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Sat, 1 Apr 2023 14:58:52 +0200 Subject: feat(api): evaluate 'statuscolumn' with nvim_eval_statusline() --- test/functional/api/vim_spec.lua | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'test/functional/api/vim_spec.lua') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index ab26425425..cddea48a76 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -3421,6 +3421,40 @@ describe('API', function() 'TextWithNoHighlight%#WarningMsg#TextWithWarningHighlight', { use_winbar = true, highlights = true })) end) + it('works with statuscolumn', function() + command([[ + let &stc='%C%s%=%l ' + set cul nu nuw=3 scl=yes:2 fdc=2 + call setline(1, repeat(['aaaaa'], 5)) + let g:ns = nvim_create_namespace('') + call sign_define('a', {'text':'aa', 'texthl':'IncSearch', 'numhl':'Normal'}) + call sign_place(2, 1, 'a', bufnr(), {'lnum':4}) + call nvim_buf_set_extmark(0, g:ns, 3, 1, { 'sign_text':'bb', 'sign_hl_group':'ErrorMsg' }) + 1,5fold | 1,5 fold | foldopen! + ]]) + command('norm 4G') + command('let v:lnum=4') + eq({ + str = '││aabb 4 ', + width = 9, + highlights = { + { group = 'CursorLineFold', start = 0 }, + { group = 'Normal', start = 6 }, + { group = 'IncSearch', start = 6 }, + { group = 'ErrorMsg', start = 8 }, + { group = 'Normal', start = 10 } + } + }, meths.eval_statusline('%C%s%=%l ', { use_statuscol = true, highlights = true })) + command('let v:lnum=3') + eq({ + str = '3 ' , + width = 2, + highlights = { + { group = 'LineNr', start = 0 }, + { group = 'ErrorMsg', start = 1 } + } + }, meths.eval_statusline('%l%#ErrorMsg# ', { use_statuscol = true, highlights = true })) + end) it('no memory leak with click functions', function() meths.eval_statusline('%@ClickFunc@StatusLineStringWithClickFunc%T', {}) eq({ -- cgit From 25dfed6e0148771cdb659df8c616df3860583c47 Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Thu, 6 Apr 2023 03:33:57 +0200 Subject: feat(api): set statuscolumn line number in nvim_eval_statusline() Having the user set `v:lnum` before calling `nvim_eval_statusline()` is unnecesarily fragile. Redraws inbetween setting `v:lnum` and the `nvim_eval_statusline()` call will overwrite `v:lnum`. --- test/functional/api/vim_spec.lua | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'test/functional/api/vim_spec.lua') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index cddea48a76..af6fbf092a 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -3422,7 +3422,7 @@ describe('API', function() { use_winbar = true, highlights = true })) end) it('works with statuscolumn', function() - command([[ + exec([[ let &stc='%C%s%=%l ' set cul nu nuw=3 scl=yes:2 fdc=2 call setline(1, repeat(['aaaaa'], 5)) @@ -3431,9 +3431,8 @@ describe('API', function() call sign_place(2, 1, 'a', bufnr(), {'lnum':4}) call nvim_buf_set_extmark(0, g:ns, 3, 1, { 'sign_text':'bb', 'sign_hl_group':'ErrorMsg' }) 1,5fold | 1,5 fold | foldopen! + norm 4G ]]) - command('norm 4G') - command('let v:lnum=4') eq({ str = '││aabb 4 ', width = 9, @@ -3444,8 +3443,7 @@ describe('API', function() { group = 'ErrorMsg', start = 8 }, { group = 'Normal', start = 10 } } - }, meths.eval_statusline('%C%s%=%l ', { use_statuscol = true, highlights = true })) - command('let v:lnum=3') + }, meths.eval_statusline('%C%s%=%l ', { use_statuscol_lnum = 4, highlights = true })) eq({ str = '3 ' , width = 2, @@ -3453,7 +3451,7 @@ describe('API', function() { group = 'LineNr', start = 0 }, { group = 'ErrorMsg', start = 1 } } - }, meths.eval_statusline('%l%#ErrorMsg# ', { use_statuscol = true, highlights = true })) + }, meths.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', {}) -- cgit From 3a1e17e3a1767b4ff8a082150f7f9d6bda50cc8f Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 5 May 2023 19:03:08 +0800 Subject: test: add tests for executing commands with backwards range --- test/functional/api/vim_spec.lua | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'test/functional/api/vim_spec.lua') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index af6fbf092a..c81b6e90cc 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -361,6 +361,12 @@ describe('API', function() 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')) + end) end) describe('nvim_command_output', function() -- cgit From 1fe1bb084d0099fc4f9bfdc11189485d0f74b75a Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Mon, 19 Dec 2022 16:37:45 +0000 Subject: refactor(options): deprecate nvim[_buf|_win]_[gs]et_option Co-authored-by: zeertzjq Co-authored-by: famiu --- test/functional/api/vim_spec.lua | 88 ++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 48 deletions(-) (limited to 'test/functional/api/vim_spec.lua') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index c81b6e90cc..5b8b52a559 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1051,7 +1051,7 @@ describe('API', function() line 3 ]]) eq({0,4,1,0}, funcs.getpos('.')) -- Cursor follows the paste. - eq(false, nvim('get_option', 'paste')) + eq(false, nvim('get_o