From be15ac06badbea6b11390ad7d9c2ddd4aea73480 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 16 Jan 2022 18:44:28 +0800 Subject: feat(statusline): support multibyte fillchar This includes a partial port of Vim patch 8.2.2569 and some changes to nvim_eval_statusline() to allow a multibyte fillchar. Literally every line of C code touched by that patch has been refactored in Nvim, and that patch contains some irrelevant foldcolumn tests I'm not sure how to port (as Nvim's foldcolumn behavior has diverged from Vim's). --- test/functional/api/vim_spec.lua | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 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 22201e21a2..886915dfb4 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -2551,6 +2551,34 @@ describe('API', function() '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('rejects double-width fillchar', function() + eq('fillchar must be a single-width character', + pcall_err(meths.eval_statusline, '', { fillchar = '哦' })) + end) + it('rejects control character fillchar', function() + eq('fillchar must be a single-width character', + pcall_err(meths.eval_statusline, '', { fillchar = '\a' })) + end) + it('rejects multiple-character fillchar', function() + eq('fillchar must be a single-width character', + pcall_err(meths.eval_statusline, '', { fillchar = 'aa' })) + end) + it('rejects empty string fillchar', function() + eq('fillchar must be a single-width character', + pcall_err(meths.eval_statusline, '', { fillchar = '' })) + end) + it('rejects non-string fillchar', function() + eq('fillchar must be a single-width character', + pcall_err(meths.eval_statusline, '', { fillchar = 1 })) + end) describe('highlight parsing', function() it('works', function() eq({ -- cgit From 6e69a3c3e79fd78b31753343213e68e73b0048c4 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 21 Jan 2022 18:08:56 +0800 Subject: refactor: remove CSI unescaping and clean up related names and comments --- test/functional/api/vim_spec.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 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 22201e21a2..201ba45803 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1367,18 +1367,18 @@ describe('API', function() end) describe('nvim_feedkeys', function() - it('CSI escaping', function() + it('K_SPECIAL escaping', function() local function on_setup() -- notice the special char(…) \xe2\80\xa6 nvim('feedkeys', ':let x1="…"\n', '', true) -- Both nvim_replace_termcodes and nvim_feedkeys escape \x80 local inp = helpers.nvim('replace_termcodes', ':let x2="…"', true, true, true) - nvim('feedkeys', inp, '', true) -- escape_csi=true + nvim('feedkeys', inp, '', true) -- escape_ks=true - -- nvim_feedkeys with CSI escaping disabled + -- nvim_feedkeys with K_SPECIAL escaping disabled inp = helpers.nvim('replace_termcodes', ':let x3="…"', true, true, true) - nvim('feedkeys', inp, '', false) -- escape_csi=false + nvim('feedkeys', inp, '', false) -- escape_ks=false helpers.stop() end -- cgit From 5b34c2ab73d62431f391d454e68a84332148d609 Mon Sep 17 00:00:00 2001 From: glacambre Date: Tue, 25 Jan 2022 07:59:17 +0100 Subject: fix(--headless): do not block on press-enter prompts when no UI This commit fixes #9358, where emitting multiple messages with 'echo' or a single one with 'echom' or 'echoerr' would result in a press-enter prompt that couldn't be dismissed by pressing enter. This requires adapting a few tests to spawn a UI before testing whether press-enter prompts are blocking. It also fixes #11718, as when combined with #15910 it enables making sure that neovim never blocks and emits messages on startup. --- test/functional/api/vim_spec.lua | 15 +++++++++++++++ 1 file changed, 15 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 b5b10c049e..937b6559de 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -333,6 +333,7 @@ describe('API', function() describe('nvim_command_output', function() it('does not induce hit-enter prompt', function() + 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"]]) @@ -1093,7 +1094,20 @@ describe('API', function() eq({mode='n', blocking=false}, nvim("get_mode")) end) + it("during press-enter prompt without UI returns blocking=false", function() + eq({mode='n', blocking=false}, 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") + eq({mode='n', blocking=false}, 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")) command("echom 'msg1'") command("echom 'msg2'") @@ -1117,6 +1131,7 @@ describe('API', function() -- TODO: bug #6247#issuecomment-286403810 it("batched with input", function() + nvim("ui_attach", 80, 20, {}) eq({mode='n', blocking=false}, nvim("get_mode")) command("echom 'msg1'") command("echom 'msg2'") -- cgit From 23c3f7f572d3a1f3816a9a9ae1b3632c53856923 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 10 Feb 2022 09:41:25 +0800 Subject: fix(api): use changedir_func() in nvim_set_current_dir() Co-Authored-By: smolck <46855713+smolck@users.noreply.github.com> --- 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 937b6559de..ccf3e81b22 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -536,6 +536,31 @@ describe('API', function() end) end) + describe('nvim_set_current_dir', function() + local start_dir + + before_each(function() + clear() + funcs.mkdir("Xtestdir") + start_dir = funcs.getcwd() + end) + + after_each(function() + helpers.rmdir("Xtestdir") + end) + + it('works', function() + meths.set_current_dir("Xtestdir") + eq(funcs.getcwd(), start_dir .. helpers.get_pathsep() .. "Xtestdir") + end) + + it('sets previous directory', function() + meths.set_current_dir("Xtestdir") + meths.exec('cd -', false) + eq(funcs.getcwd(), start_dir) + end) + end) + describe('nvim_exec_lua', function() it('works', function() meths.exec_lua('vim.api.nvim_set_var("test", 3)', {}) -- cgit From f292dd2126f8dacd6446799ac750ab368b852f81 Mon Sep 17 00:00:00 2001 From: shadmansaleh <13149513+shadmansaleh@users.noreply.github.com> Date: Sat, 12 Feb 2022 10:54:25 +0600 Subject: fix: autoload variables not loaded with vim.g & nvim_get_var --- test/functional/api/vim_spec.lua | 13 +++++++++++++ 1 file changed, 13 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 ccf3e81b22..5a387f3deb 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -898,6 +898,19 @@ describe('API', function() 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)) + + -- 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) + mkdir_p(autoload_folder) + write_file(autoload_file , [[let testload#value = 2]]) + + clear{ args_rm={'-u'}, env={ XDG_CONFIG_HOME=xconfig, XDG_DATA_HOME=xdata } } + eq(2, meths.get_var('testload#value')) + rmdir('Xhome') end) it('nvim_get_vvar, nvim_set_vvar', function() -- cgit From d512be55a2ea54dd83914ff25f57c02d703f93b4 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Thu, 16 Dec 2021 11:40:23 +0000 Subject: fix(api): re-route nvim_get_runtime_file errors This allows nvim_get_runtime_file to be properly used via pcall --- test/functional/api/vim_spec.lua | 9 +++++++++ 1 file changed, 9 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 5a387f3deb..71cd055e08 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -23,6 +23,7 @@ local next_msg = helpers.next_msg local tmpname = helpers.tmpname local write_file = helpers.write_file local exec_lua = helpers.exec_lua +local exc_exec = helpers.exc_exec local pcall_err = helpers.pcall_err local format_string = helpers.format_string @@ -2240,6 +2241,14 @@ describe('API', function() eq({}, meths.get_runtime_file("foobarlang/", true)) end) + it('can handle bad patterns', function() + if helpers.pending_win32(pending) then return end + + eq("Vim:E220: Missing }.", pcall_err(meths.get_runtime_file, "{", 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() -- cgit From 3011794c8600f529bc049983a64ca99ae03908df Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 10 Mar 2022 07:18:49 +0800 Subject: feat(api): relax statusline fillchar width check Treat fillchar as single-width even if it isn't. --- test/functional/api/vim_spec.lua | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 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 71cd055e08..e945a6c706 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -2621,24 +2621,24 @@ describe('API', function() eq({ str = 'a━━━b', width = 5 }, meths.eval_statusline('a%=b', { fillchar = '━', maxwidth = 5 })) end) - it('rejects double-width fillchar', function() - eq('fillchar must be a single-width character', - pcall_err(meths.eval_statusline, '', { fillchar = '哦' })) + 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('rejects control character fillchar', function() - eq('fillchar must be a single-width character', - pcall_err(meths.eval_statusline, '', { fillchar = '\a' })) + 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) it('rejects multiple-character fillchar', function() - eq('fillchar must be a single-width character', + eq('fillchar must be a single character', pcall_err(meths.eval_statusline, '', { fillchar = 'aa' })) end) it('rejects empty string fillchar', function() - eq('fillchar must be a single-width character', + eq('fillchar must be a single character', pcall_err(meths.eval_statusline, '', { fillchar = '' })) end) it('rejects non-string fillchar', function() - eq('fillchar must be a single-width character', + eq('fillchar must be a single character', pcall_err(meths.eval_statusline, '', { fillchar = 1 })) end) describe('highlight parsing', function() -- cgit From 9b1e1fbc9f795921afd25ba38be5c79dec8b04d2 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 6 Mar 2022 06:56:24 +0800 Subject: fix(paste): use getcmdtype() to determine whether in cmdline mode --- 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 e945a6c706..384e8d11f2 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -738,6 +738,12 @@ describe('API', function() eeffgghh iijjkkll]]) end) + it('when searching in Visual mode', function() + feed('v/') + nvim('paste', 'aabbccdd', true, -1) + eq('aabbccdd', funcs.getcmdline()) + expect('') + 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) expect('line 1\r\n\r\rline 2\nline 3\rline 4\r') -- cgit From 2601e0873ff50ed804487dff00bd27e233709beb Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 6 Mar 2022 06:56:24 +0800 Subject: fix(paste): don't move cursor past the end of pasted text in Normal mode --- test/functional/api/vim_spec.lua | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 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 384e8d11f2..3d57953a11 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -665,6 +665,43 @@ describe('API', function() feed('u') -- Undo. expect(expected1) end) + it('stream: Insert mode', function() + feed('i') + nvim('paste', 'aaaaaa', false, 1) + nvim('paste', 'bbbbbb', false, 2) + nvim('paste', 'cccccc', false, 2) + nvim('paste', 'dddddd', false, 3) + expect('aaaaaabbbbbbccccccdddddd') + end) + it('stream: Normal mode on empty line', function() + nvim('paste', 'aaaaaa', false, 1) + nvim('paste', 'bbbbbb', false, 2) + nvim('paste', 'cccccc', false, 2) + nvim('paste', 'dddddd', false, 3) + expect('aaaaaabbbbbbccccccdddddd') + feed('u') + expect('') + end) + it('stream: Normal mode not at the end of a line', function() + feed('i||0') + nvim('paste', 'aaaaaa', false, 1) + nvim('paste', 'bbbbbb', false, 2) + nvim('paste', 'cccccc', false, 2) + nvim('paste', 'dddddd', false, 3) + expect('|aaaaaabbbbbbccccccdddddd|') + feed('u') + expect('||') + end) + it('stream: Normal mode at the end of a line', function() + feed('i||') + nvim('paste', 'aaaaaa', false, 1) + nvim('paste', 'bbbbbb', false, 2) + nvim('paste', 'cccccc', false, 2) + nvim('paste', 'dddddd', false, 3) + expect('||aaaaaabbbbbbccccccdddddd') + feed('u') + expect('||') + end) it('non-streaming', function() -- With final "\n". nvim('paste', 'line 1\nline 2\nline 3\n', true, -1) -- cgit From bfb77544425b7cca372cb87f00ef6b6e87c5f6d5 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 6 Mar 2022 06:56:24 +0800 Subject: fix(paste): deal with eol and eof in Visual mode --- test/functional/api/vim_spec.lua | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 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 3d57953a11..eaee9211f4 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -702,6 +702,42 @@ describe('API', function() feed('u') expect('||') end) + it('stream: Visual mode either end not at the end of a line', function() + feed('i|xxxxxx|hvhk') + nvim('paste', 'aaaaaa', false, 1) + nvim('paste', 'bbbbbb', false, 2) + nvim('paste', 'cccccc', false, 2) + nvim('paste', 'dddddd', false, 3) + expect('|aaaaaabbbbbbccccccdddddd|') + feed('u') + expect([[ + |xxx + xxx|]]) + end) + it('stream: Visual mode cursor at the end of a line', function() + feed('i||xxxxxxvko') + nvim('paste', 'aaaaaa', false, 1) + nvim('paste', 'bbbbbb', false, 2) + nvim('paste', 'cccccc', false, 2) + nvim('paste', 'dddddd', false, 3) + expect('||aaaaaabbbbbbccccccdddddd') + feed('u') + expect([[ + ||xxx + xxx]]) + end) + it('stream: Visual mode other end at the end of a line', function() + feed('i||xxxxxxvk') + nvim('paste', 'aaaaaa', false, 1) + nvim('paste', 'bbbbbb', false, 2) + nvim('paste', 'cccccc', false, 2) + nvim('paste', 'dddddd', false, 3) + expect('||aaaaaabbbbbbccccccdddddd') + feed('u') + expect([[ + ||xxx + xxx]]) + end) it('non-streaming', function() -- With final "\n". nvim('paste', 'line 1\nline 2\nline 3\n', true, -1) -- cgit From fcc6f66cf2a67cf85e72727a08e19d0f800badb9 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 6 Mar 2022 06:56:24 +0800 Subject: fix(paste): avoid edges cases caused by empty chunk --- test/functional/api/vim_spec.lua | 67 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 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 eaee9211f4..761cbb4036 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -630,6 +630,10 @@ describe('API', function() end) describe('nvim_paste', function() + before_each(function() + -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. + feed('ifoou') + end) it('validates args', function() eq('Invalid phase: -2', pcall_err(request, 'nvim_paste', 'foo', true, -2)) @@ -702,7 +706,7 @@ describe('API', function() feed('u') expect('||') end) - it('stream: Visual mode either end not at the end of a line', function() + it('stream: Visual mode neither end at the end of a line', function() feed('i|xxxxxx|hvhk') nvim('paste', 'aaaaaa', false, 1) nvim('paste', 'bbbbbb', false, 2) @@ -714,6 +718,30 @@ describe('API', function() |xxx xxx|]]) end) + it('stream: Visual mode neither end at the end of a line with empty first chunk', function() + feed('i|xxxxxx|hvhk') + nvim('paste', '', false, 1) + nvim('paste', 'bbbbbb', false, 2) + nvim('paste', 'cccccc', false, 2) + nvim('paste', 'dddddd', false, 3) + expect('|bbbbbbccccccdddddd|') + feed('u') + expect([[ + |xxx + xxx|]]) + end) + it('stream: Visual mode neither end at the end of a line with all chunks empty', function() + feed('i|xxxxxx|hvhk') + nvim('paste', '', false, 1) + nvim('paste', '', false, 2) + nvim('paste', '', false, 2) + nvim('paste', '', false, 3) + expect('||') + feed('u') + expect([[ + |xxx + xxx|]]) + end) it('stream: Visual mode cursor at the end of a line', function() feed('i||xxxxxxvko') nvim('paste', 'aaaaaa', false, 1) @@ -726,6 +754,18 @@ describe('API', function() ||xxx xxx]]) end) + it('stream: Visual mode cursor at the end of a line with empty first chunk', function() + feed('i||xxxxxxvko') + nvim('paste', '', false, 1) + nvim('paste', 'bbbbbb', false, 2) + nvim('paste', 'cccccc', false, 2) + nvim('paste', 'dddddd', false, 3) + expect('||bbbbbbccccccdddddd') + feed('u') + expect([[ + ||xxx + xxx]]) + end) it('stream: Visual mode other end at the end of a line', function() feed('i||xxxxxxvk') nvim('paste', 'aaaaaa', false, 1) @@ -738,6 +778,18 @@ describe('API', function() ||xxx xxx]]) end) + it('stream: Visual mode other end at the end of a line with empty first chunk', function() + feed('i||xxxxxxvk') + nvim('paste', '', false, 1) + nvim('paste', 'bbbbbb', false, 2) + nvim('paste', 'cccccc', false, 2) + nvim('paste', 'dddddd', false, 3) + expect('||bbbbbbccccccdddddd') + feed('u') + expect([[ + ||xxx + xxx]]) + end) it('non-streaming', function() -- With final "\n". nvim('paste', 'line 1\nline 2\nline 3\n', true, -1) @@ -817,6 +869,19 @@ describe('API', function() eq('aabbccdd', funcs.getcmdline()) expect('') 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) + screen:expect([[ + | + ~ | + ~ | + :Foo^ | + ]]) + 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) expect('line 1\r\n\r\rline 2\nline 3\rline 4\r') -- cgit From a6eafc77ceaf2d7036aed89361b6556f46131b17 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 6 Mar 2022 06:56:24 +0800 Subject: fix(paste): deal with trailing new line in chunk --- test/functional/api/vim_spec.lua | 41 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 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 761cbb4036..9818746251 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -686,6 +686,19 @@ describe('API', function() feed('u') expect('') end) + it('stream: Normal mode on empty line 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) + expect([[ + aaaaaa + bbbbbb + cccccc + dddddd]]) + feed('u') + expect('') + end) it('stream: Normal mode not at the end of a line', function() feed('i||0') nvim('paste', 'aaaaaa', false, 1) @@ -696,6 +709,20 @@ describe('API', function() feed('u') expect('||') end) + it('stream: Normal mode not at the end of a line pasting multiple lines', function() + feed('i||0') + nvim('paste', 'aaaaaa\n', false, 1) + nvim('paste', 'bbbbbb\n', false, 2) + nvim('paste', 'cccccc\n', false, 2) + nvim('paste', 'dddddd', false, 3) + expect([[ + |aaaaaa + bbbbbb + cccccc + dddddd|]]) + feed('u') + expect('||') + end) it('stream: Normal mode at the end of a line', function() feed('i||') nvim('paste', 'aaaaaa', false, 1) @@ -706,6 +733,20 @@ describe('API', function() feed('u') expect('||') end) + it('stream: Normal mode at the end of a line pasting multiple lines', function() + feed('i||') + nvim('paste', 'aaaaaa\n', false, 1) + nvim('paste', 'bbbbbb\n', false, 2) + nvim('paste', 'cccccc\n', false, 2) + nvim('paste', 'dddddd', false, 3) + expect([[ + ||aaaaaa + bbbbbb + cccccc + dddddd]]) + feed('u') + expect('||') + end) it('stream: Visual mode neither end at the end of a line', function() feed('i|xxxxxx|hvhk') nvim('paste', 'aaaaaa', false, 1) -- cgit From e4ec8d7d5001ff15a7a844a6f74d4a9c090ac5c6 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 6 Mar 2022 06:56:24 +0800 Subject: test(paste): reorganize tests and add tests for linewise Visual mode --- test/functional/api/vim_spec.lua | 471 ++++++++++++++++++++++++++------------- 1 file changed, 317 insertions(+), 154 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 9818746251..263add599c 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -630,10 +630,6 @@ describe('API', function() end) describe('nvim_paste', function() - before_each(function() - -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. - feed('ifoou') - end) it('validates args', function() eq('Invalid phase: -2', pcall_err(request, 'nvim_paste', 'foo', true, -2)) @@ -670,166 +666,333 @@ describe('API', function() expect(expected1) end) it('stream: Insert mode', function() + -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. + feed('afoou') feed('i') nvim('paste', 'aaaaaa', false, 1) nvim('paste', 'bbbbbb', false, 2) nvim('paste', 'cccccc', false, 2) nvim('paste', 'dddddd', false, 3) expect('aaaaaabbbbbbccccccdddddd') - end) - it('stream: Normal mode on empty line', function() - nvim('paste', 'aaaaaa', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) - expect('aaaaaabbbbbbccccccdddddd') - feed('u') - expect('') - end) - it('stream: Normal mode on empty line 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) - expect([[ - aaaaaa - bbbbbb - cccccc - dddddd]]) - feed('u') + feed('u') expect('') end) - it('stream: Normal mode not at the end of a line', function() - feed('i||0') - nvim('paste', 'aaaaaa', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) - expect('|aaaaaabbbbbbccccccdddddd|') - feed('u') - expect('||') - end) - it('stream: Normal mode not at the end of a line pasting multiple lines', function() - feed('i||0') - nvim('paste', 'aaaaaa\n', false, 1) - nvim('paste', 'bbbbbb\n', false, 2) - nvim('paste', 'cccccc\n', false, 2) - nvim('paste', 'dddddd', false, 3) - expect([[ - |aaaaaa - bbbbbb - cccccc - dddddd|]]) - feed('u') - expect('||') - end) - it('stream: Normal mode at the end of a line', function() - feed('i||') - nvim('paste', 'aaaaaa', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) - expect('||aaaaaabbbbbbccccccdddddd') - feed('u') - expect('||') - end) - it('stream: Normal mode at the end of a line pasting multiple lines', function() - feed('i||') - nvim('paste', 'aaaaaa\n', false, 1) - nvim('paste', 'bbbbbb\n', false, 2) - nvim('paste', 'cccccc\n', false, 2) - nvim('paste', 'dddddd', false, 3) - expect([[ - ||aaaaaa - bbbbbb - cccccc - dddddd]]) - feed('u') - expect('||') - end) - it('stream: Visual mode neither end at the end of a line', function() - feed('i|xxxxxx|hvhk') - nvim('paste', 'aaaaaa', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) - expect('|aaaaaabbbbbbccccccdddddd|') - feed('u') - expect([[ - |xxx - xxx|]]) - end) - it('stream: Visual mode neither end at the end of a line with empty first chunk', function() - feed('i|xxxxxx|hvhk') - nvim('paste', '', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) - expect('|bbbbbbccccccdddddd|') - feed('u') - expect([[ - |xxx - xxx|]]) - end) - it('stream: Visual mode neither end at the end of a line with all chunks empty', function() - feed('i|xxxxxx|hvhk') - nvim('paste', '', false, 1) - nvim('paste', '', false, 2) - nvim('paste', '', false, 2) - nvim('paste', '', false, 3) - expect('||') - feed('u') - expect([[ - |xxx - xxx|]]) - end) - it('stream: Visual mode cursor at the end of a line', function() - feed('i||xxxxxxvko') - nvim('paste', 'aaaaaa', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) - expect('||aaaaaabbbbbbccccccdddddd') - feed('u') - expect([[ - ||xxx - xxx]]) - end) - it('stream: Visual mode cursor at the end of a line with empty first chunk', function() - feed('i||xxxxxxvko') - nvim('paste', '', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) - expect('||bbbbbbccccccdddddd') - feed('u') - expect([[ - ||xxx - xxx]]) + describe('stream: Normal mode', function() + describe('on empty line', function() + before_each(function() + -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. + feed('afoou') + end) + after_each(function() + feed('u') + 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) + 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) + expect([[ + aaaaaa + bbbbbb + cccccc + dddddd]]) + end) + end) + describe('not at the end of a line', function() + before_each(function() + feed('i||') + -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. + feed('afoou') + feed('0') + end) + after_each(function() + feed('u') + 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) + 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) + expect([[ + |aaaaaa + bbbbbb + cccccc + dddddd|]]) + end) + end) + describe('at the end of a line', function() + before_each(function() + feed('i||') + -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. + feed('afoou') + feed('$') + end) + after_each(function() + feed('u') + 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) + 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) + expect([[ + ||aaaaaa + bbbbbb + cccccc + dddddd]]) + end) + end) end) - it('stream: Visual mode other end at the end of a line', function() - feed('i||xxxxxxvk') - nvim('paste', 'aaaaaa', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) - expect('||aaaaaabbbbbbccccccdddddd') - feed('u') - expect([[ - ||xxx - xxx]]) + describe('stream: Visual mode', function() + describe('neither end at the end of a line', function() + before_each(function() + feed('i|xxxxxx|') + -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. + feed('afoou') + feed('hvhk') + end) + after_each(function() + feed('u') + expect([[ + |xxx + 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) + 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) + 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) + expect('||') + end) + end) + describe('cursor at the end of a line', function() + before_each(function() + feed('i||xxxxxx') + -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. + feed('afoou') + feed('vko') + end) + after_each(function() + feed('u') + expect([[ + ||xxx + 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) + 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) + expect('||bbbbbbccccccdddddd') + end) + end) + describe('other end at the end of a line', function() + before_each(function() + feed('i||xxxxxx') + -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. + feed('afoou') + feed('vk') + end) + after_each(function() + feed('u') + expect([[ + ||xxx + 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) + 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) + expect('||bbbbbbccccccdddddd') + end) + end) end) - it('stream: Visual mode other end at the end of a line with empty first chunk', function() - feed('i||xxxxxxvk') - nvim('paste', '', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) - expect('||bbbbbbccccccdddddd') - feed('u') - expect([[ - ||xxx - xxx]]) + describe('stream: linewise Visual mode', function() + before_each(function() + feed('i123456789987654321123456789') + -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. + feed('afoou') + end) + after_each(function() + feed('u') + expect([[ + 123456789 + 987654321 + 123456789]]) + end) + describe('selecting the start of a file', function() + before_each(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) + expect([[ + aaaaaa + bbbbbb + cccccc + dddddd987654321 + 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) + expect([[ + aaaaaa + bbbbbb + cccccc + dddddd + 987654321 + 123456789]]) + end) + end) + describe('selecting the middle of a file', function() + before_each(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) + expect([[ + 123456789 + aaaaaa + bbbbbb + cccccc + 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) + expect([[ + 123456789 + aaaaaa + bbbbbb + cccccc + dddddd + 123456789]]) + end) + end) + describe('selecting the end of a file', function() + before_each(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) + expect([[ + 123456789 + 987654321 + aaaaaa + bbbbbb + cccccc + 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) + expect([[ + 123456789 + 987654321 + aaaaaa + bbbbbb + cccccc + dddddd + ]]) + end) + end) + describe('selecting the whole file', function() + before_each(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) + expect([[ + aaaaaa + bbbbbb + cccccc + 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) + expect([[ + aaaaaa + bbbbbb + cccccc + dddddd + ]]) + end) + end) end) it('non-streaming', function() -- With final "\n". -- cgit From 3470a9c3de076ec3170525c3de66544f9836c775 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 6 Mar 2022 06:56:24 +0800 Subject: test(paste): add tests with virtualedit=onemore --- test/functional/api/vim_spec.lua | 667 ++++++++++++++++++++------------------- 1 file changed, 339 insertions(+), 328 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 263add599c..f4a7d38d31 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -636,363 +636,374 @@ describe('API', function() eq('Invalid phase: 4', pcall_err(request, 'nvim_paste', 'foo', true, 4)) end) - 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) - 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) - 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) - expect([[ - 1/chunk 1 (start) - 1/chunk 2 (end) - 2/chunk 1 (start) - 2/chunk 2 - 2/chunk 3 - 2/chunk 4 (end) - ]]) - 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('afoou') - feed('i') - nvim('paste', 'aaaaaa', false, 1) - nvim('paste', 'bbbbbb', false, 2) - nvim('paste', 'cccccc', false, 2) - nvim('paste', 'dddddd', false, 3) - expect('aaaaaabbbbbbccccccdddddd') - feed('u') - expect('') - end) - describe('stream: Normal mode', function() - describe('on empty line', function() - before_each(function() - -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. - feed('afoou') - end) - after_each(function() - feed('u') - 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) - 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) - expect([[ - aaaaaa - bbbbbb - cccccc - dddddd]]) - 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) + 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) + 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) + expect([[ + 1/chunk 1 (start) + 1/chunk 2 (end) + 2/chunk 1 (start) + 2/chunk 2 + 2/chunk 3 + 2/chunk 4 (end) + ]]) + feed('u') -- Undo. + expect(expected1) end) - describe('not at the end of a line', function() - before_each(function() - feed('i||') - -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. - feed('afoou') - feed('0') - end) - after_each(function() - feed('u') - 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) - 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) - expect([[ - |aaaaaa - bbbbbb - cccccc - dddddd|]]) - end) + it('stream: Insert mode', function() + -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. + feed('afoou') + feed('i') + nvim('paste', 'aaaaaa', false, 1) + nvim('paste', 'bbbbbb', false, 2) + nvim('paste', 'cccccc', false, 2) + nvim('paste', 'dddddd', false, 3) + expect('aaaaaabbbbbbccccccdddddd') + feed('u') + expect('') end) - describe('at the end of a line', function() - before_each(function() - feed('i||') - -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. - feed('afoou') - feed('$') - end) - after_each(function() - feed('u') - 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) - 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) - expect([[ - ||aaaaaa + describe('stream: Normal mode', function() + describe('on empty line', function() + before_each(function() + -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. + feed('afoou') + end) + after_each(function() + feed('u') + 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) + 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) + expect([[ + aaaaaa bbbbbb cccccc dddddd]]) + end) end) - end) - end) - describe('stream: Visual mode', function() - describe('neither end at the end of a line', function() - before_each(function() - feed('i|xxxxxx|') - -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. - feed('afoou') - feed('hvhk') - end) - after_each(function() - feed('u') - expect([[ - |xxx - 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) - 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) - expect('|bbbbbbccccccdddddd|') + describe('not at the end of a line', function() + before_each(function() + feed('i||') + -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. + feed('afoou') + feed('0') + end) + after_each(function() + feed('u') + 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) + 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) + expect([[ + |aaaaaa + bbbbbb + cccccc + dddddd|]]) + end) end) - it('with all chunks empty', function() - nvim('paste', '', false, 1) - nvim('paste', '', false, 2) - nvim('paste', '', false, 2) - nvim('paste', '', false, 3) - expect('||') + describe('at the end of a line', function() + before_each(function() + feed('i||') + -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. + feed('afoou') + feed('2|') + end) + after_each(function() + feed('u') + 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) + 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) + expect([[ + ||aaaaaa + bbbbbb + cccccc + dddddd]]) + end) end) end) - describe('cursor at the end of a line', function() - before_each(function() - feed('i||xxxxxx') - -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. - feed('afoou') - feed('vko') - end) - after_each(function() - feed('u') - expect([[ - ||xxx - xxx]]) + describe('stream: Visual mode', function() + describe('neither end at the end of a line', function() + before_each(function() + feed('i|xxxxxx|') + -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. + feed('afoou') + feed('3|vhk') + end) + after_each(function() + feed('u') + expect([[ + |xxx + 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) + 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) + 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) + expect('||') + end) 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) - expect('||aaaaaabbbbbbccccccdddddd') + describe('cursor at the end of a line', function() + before_each(function() + feed('i||xxxxxx') + -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. + feed('afoou') + feed('3|vko') + end) + after_each(function() + feed('u') + expect([[ + ||xxx + 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) + 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) + expect('||bbbbbbccccccdddddd') + end) 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) - expect('||bbbbbbccccccdddddd') + describe('other end at the end of a line', function() + before_each(function() + feed('i||xxxxxx') + -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. + feed('afoou') + feed('3|vk') + end) + after_each(function() + feed('u') + expect([[ + ||xxx + 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) + 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) + expect('||bbbbbbccccccdddddd') + end) end) end) - describe('other end at the end of a line', function() + describe('stream: linewise Visual mode', function() before_each(function() - feed('i||xxxxxx') + feed('i123456789987654321123456789') -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. feed('afoou') - feed('vk') end) after_each(function() feed('u') expect([[ - ||xxx - 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) - 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) - expect('||bbbbbbccccccdddddd') - end) - end) - end) - describe('stream: linewise Visual mode', function() - before_each(function() - feed('i123456789987654321123456789') - -- If nvim_paste() calls :undojoin without making any changes, this makes it an error. - feed('afoou') - end) - after_each(function() - feed('u') - expect([[ - 123456789 - 987654321 - 123456789]]) - end) - describe('selecting the start of a file', function() - before_each(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) - expect([[ - aaaaaa - bbbbbb - cccccc - dddddd987654321 - 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) - expect([[ - aaaaaa - bbbbbb - cccccc - dddddd + 123456789 987654321 123456789]]) end) - end) - describe('selecting the middle of a file', function() - before_each(function() - feed('2ggV') + describe('selecting the start of a file', function() + before_each(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) + expect([[ + aaaaaa + bbbbbb + cccccc + dddddd987654321 + 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) + expect([[ + aaaaaa + bbbbbb + cccccc + dddddd + 987654321 + 123456789]]) + end) 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) - expect([[ - 123456789 - aaaaaa - bbbbbb - cccccc - dddddd123456789]]) + describe('selecting the middle of a file', function() + before_each(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) + expect([[ + 123456789 + aaaaaa + bbbbbb + cccccc + 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) + expect([[ + 123456789 + aaaaaa + bbbbbb + cccccc + dddddd + 123456789]]) + end) 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) - expect([[ - 123456789 - aaaaaa - bbbbbb - cccccc - dddddd - 123456789]]) + describe('selecting the end of a file', function() + before_each(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) + expect([[ + 123456789 + 987654321 + aaaaaa + bbbbbb + cccccc + 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) + expect([[ + 123456789 + 987654321 + aaaaaa + bbbbbb + cccccc + dddddd + ]]) + end) end) - end) - describe('selecting the end of a file', function() - before_each(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) - expect([[ - 123456789 - 987654321 - aaaaaa - bbbbbb - cccccc - 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) - expect([[ - 123456789 - 987654321 - aaaaaa - bbbbbb - cccccc - dddddd - ]]) + describe('selecting the whole file', function() + before_each(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) + expect([[ + aaaaaa + bbbbbb + cccccc + 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) + expect([[ + aaaaaa + bbbbbb + cccccc + dddddd + ]]) + end) end) end) - describe('selecting the whole file', function() - before_each(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) - expect([[ - aaaaaa - bbbbbb - cccccc - 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) - expect([[ - aaaaaa - bbbbbb - cccccc - dddddd - ]]) - end) + end + describe('without virtualedit,', function() + run_streamed_paste_tests() + end) + describe('with virtualedit=onemore,', function() + before_each(function() + command('set virtualedit=onemore') end) + run_streamed_paste_tests() end) it('non-streaming', function() -- With final "\n". -- cgit From e263afc0e972d11d3b9b663c3ac0b5575c4deb88 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 15 Mar 2022 06:04:50 +0800 Subject: fix(paste): escape control characters in Cmdline mode --- test/functional/api/vim_spec.lua | 12 ++++++++++++ 1 file changed, 12 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 f4a7d38d31..af6872760a 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1097,6 +1097,18 @@ describe('API', function() :Foo^ | ]]) end) + it('pasting text with control characters in Cmdline mode', function() + local screen = Screen.new(20, 4) + screen:attach() + feed(':') + nvim('paste', 'normal! \023\022\006\027', true, -1) + screen:expect([[ + | + ~ | + ~ | + :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) expect('line 1\r\n\r\rline 2\nline 3\rline 4\r') -- cgit From 77eb6f9dc75ebe00aa835441ad623ba46d7108bb Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 20 Mar 2022 08:08:50 +0800 Subject: fix(api, lua): return NIL on failure to find converted function (#17779) --- test/functional/api/vim_spec.lua | 12 ++++++++++++ 1 file changed, 12 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 af6872760a..ed9d915954 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -6,6 +6,7 @@ local assert_alive = helpers.assert_alive 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 eval = helpers.eval local expect = helpers.expect local funcs = helpers.funcs @@ -1271,6 +1272,17 @@ describe('API', function() eq('Key is locked: lua', pcall_err(meths.del_var, 'lua')) eq('Key is locked: lua', pcall_err(meths.set_var, 'lua', 1)) + exec([[ + function Test() + endfunction + function s:Test() + endfunction + 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')) + -- Check if autoload works properly local pathsep = helpers.get_pathsep() local xconfig = 'Xhome' .. pathsep .. 'Xconfig' -- cgit From a9665bb12cd8cbacbc6ef6df66c1989b0c6f9fcc Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 30 Mar 2022 05:25:00 +0800 Subject: fix(event-loop): duplicate display updating logic in vgetorpeek() (#17913) --- test/functional/api/vim_spec.lua | 12 ++++++++++++ 1 file changed, 12 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 ed9d915954..e6ed0f939b 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1589,6 +1589,18 @@ describe('API', function() feed(':digraphs') eq({mode='rm', blocking=true}, nvim("get_mode")) end) + + it('after mapping returns blocking=false #17257', function() + command('nnoremap ') + feed('') + eq({mode='n', blocking=false}, nvim("get_mode")) + end) + + it('after empty string mapping returns blocking=false #17257', function() + command('nnoremap ""') + feed('') + eq({mode='n', blocking=false}, nvim("get_mode")) + end) end) describe('RPC (K_EVENT)', function() -- cgit From 813ecdac795405565aab5cb61cb83b9ca1581b60 Mon Sep 17 00:00:00 2001 From: Eden Zhang <53964412+VelocityDv@users.noreply.github.com> Date: Sun, 17 Apr 2022 12:11:53 +1200 Subject: fix(paste): ignore mappings in Cmdline mode (#18114) --- 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 e6ed0f939b..04b79a7157 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1085,6 +1085,12 @@ describe('API', function() eq('aabbccdd', funcs.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()) + end) it('pasting with empty last chunk in Cmdline mode', function() local screen = Screen.new(20, 4) screen:attach() -- cgit From 519e4c44720be9b0c8584cb53a902bc1e5bfe3a3 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 26 Apr 2022 11:35:05 +0800 Subject: test: correct order of arguments to eq() and neq() --- 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 04b79a7157..f4b1a7fd59 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -122,9 +122,9 @@ describe('API', function() -- Functions nvim('exec', 'function Foo()\ncall setline(1,["xxx"])\nendfunction', false) - eq(nvim('get_current_line'), '') + eq('', nvim('get_current_line')) nvim('exec', 'call Foo()', false) - eq(nvim('get_current_line'), 'xxx') + eq('xxx', nvim('get_current_line')) -- Autocmds nvim('exec','autocmd BufAdd * :let x1 = "Hello"', false) @@ -1841,10 +1841,10 @@ describe('API', function() -- spin the loop a bit helpers.run(nil, nil, on_setup) - eq(nvim('get_var', 'x1'), '…') + eq('…', nvim('get_var', 'x1')) -- Because of the double escaping this is neq - neq(nvim('get_var', 'x2'), '…') - eq(nvim('get_var', 'x3'), '…') + neq('…', nvim('get_var', 'x2')) + eq('…', nvim('get_var', 'x3')) end) end) -- cgit From 8dbb11ebf633e40cb57568e77c7168deffc8bd7f Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Sat, 23 Apr 2022 10:21:59 +0600 Subject: feat(api): add `nvim_parse_cmdline` Adds an API function to parse a command line string and get command information from it. --- test/functional/api/vim_spec.lua | 292 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 292 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 f4b1a7fd59..e138e2cc38 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -3098,4 +3098,296 @@ describe('API', function() end) end) end) + describe('nvim_parse_cmd', function() + it('works', function() + eq({ + cmd = 'echo', + args = { 'foo' }, + bang = false, + line1 = 1, + line2 = 1, + addr = 'none', + magic = { + file = false, + bar = false + }, + nargs = '*', + nextcmd = '', + mods = { + browse = false, + confirm = false, + emsg_silent = false, + hide = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + vertical = false, + split = "", + tab = 0, + verbose = 0 + } + }, meths.parse_cmd('echo foo', {})) + end) + it('works with ranges', function() + eq({ + cmd = 'substitute', + args = { '/math.random/math.max/' }, + bang = false, + line1 = 4, + line2 = 6, + addr = 'line', + magic = { + file = false, + bar = false + }, + nargs = '*', + nextcmd = '', + mods = { + browse = false, + confirm = false, + emsg_silent = false, + hide = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + vertical = false, + split = "", + tab = 0, + verbose = 0 + } + }, meths.parse_cmd('4,6s/math.random/math.max/', {})) + end) + it('works with bang', function() + eq({ + cmd = 'write', + args = {}, + bang = true, + line1 = 1, + line2 = 1, + addr = 'line', + magic = { + file = true, + bar = true + }, + nargs = '?', + nextcmd = '', + mods = { + browse = false, + confirm = false, + emsg_silent = false, + hide = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + vertical = false, + split = "", + tab = 0, + verbose = 0 + }, + }, meths.parse_cmd('w!', {})) + end) + it('works with modifiers', function() + eq({ + cmd = 'split', + args = { 'foo.txt' }, + bang = false, + line1 = 1, + line2 = 1, + addr = '?', + magic = { + file = true, + bar = true + }, + nargs = '?', + nextcmd = '', + mods = { + browse = false, + confirm = false, + emsg_silent = true, + hide = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = true, + vertical = false, + split = "topleft", + tab = 2, + verbose = 15 + }, + }, meths.parse_cmd('15verbose silent! aboveleft topleft tab split foo.txt', {})) + end) + it('works with user commands', function() + command('command -bang -nargs=+ -range -addr=lines MyCommand echo foo') + eq({ + cmd = 'MyCommand', + args = { 'test', 'it' }, + bang = true, + line1 = 4, + line2 = 6, + addr = 'line', + magic = { + file = false, + bar = false + }, + nargs = '+', + nextcmd = '', + mods = { + browse = false, + confirm = false, + emsg_silent = false, + hide = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + vertical = false, + split = "", + tab = 0, + verbose = 0 + } + }, meths.parse_cmd('4,6MyCommand! test it', {})) + end) + it('works for commands separated by bar', function() + eq({ + cmd = 'argadd', + args = { 'a.txt' }, + bang = false, + line1 = 0, + line2 = 0, + addr = 'arg', + magic = { + file = true, + bar = true + }, + nargs = '*', + nextcmd = 'argadd b.txt', + mods = { + browse = false, + confirm = false, + emsg_silent = false, + hide = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + vertical = false, + split = "", + tab = 0, + verbose = 0 + } + }, meths.parse_cmd('argadd a.txt | argadd b.txt', {})) + end) + it('works for nargs=1', function() + command('command -nargs=1 MyCommand echo ') + eq({ + cmd = 'MyCommand', + args = { 'test it' }, + bang = false, + line1 = 1, + line2 = 1, + addr = 'none', + magic = { + file = false, + bar = false + }, + nargs = '1', + nextcmd = '', + mods = { + browse = false, + confirm = false, + emsg_silent = false, + hide = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + vertical = false, + split = "", + tab = 0, + verbose = 0 + } + }, meths.parse_cmd('MyCommand test it', {})) + end) + it('sets correct default range', function() + command('command -range=% -addr=buffers MyCommand echo foo') + command('new') + eq({ + cmd = 'MyCommand', + args = {}, + bang = false, + line1 = 1, + line2 = 2, + addr = 'buf', + magic = { + file = false, + bar = false + }, + nargs = '0', + nextcmd = '', + mods = { + browse = false, + confirm = false, + emsg_silent = false, + hide = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + vertical = false, + split = "", + tab = 0, + verbose = 0 + } + }, meths.parse_cmd('MyCommand', {})) + end) + it('errors for invalid command', function() + eq('Error while parsing command line', pcall_err(meths.parse_cmd, 'Fubar', {})) + command('command! Fubar echo foo') + eq('Error while parsing command line', pcall_err(meths.parse_cmd, 'Fubar!', {})) + eq('Error while parsing command line', pcall_err(meths.parse_cmd, '4,6Fubar', {})) + end) + end) end) -- cgit From 3ec93ca92cb08faed342586e86a6f21b35264376 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Wed, 4 May 2022 18:04:01 +0600 Subject: feat(nvim_parse_cmd): add range, count, reg #18383 Adds range, count and reg to the return values of nvim_parse_cmd. Also makes line1 and line2 be -1 if the command does not take a range. Also moves nvim_parse_cmd to vimscript.c because it fits better there. --- test/functional/api/vim_spec.lua | 122 +++++++++++++++++++++++++++++++++++---- 1 file changed, 111 insertions(+), 11 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 e138e2cc38..7e54ae0248 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -3104,8 +3104,11 @@ describe('API', function() cmd = 'echo', args = { 'foo' }, bang = false, - line1 = 1, - line2 = 1, + line1 = -1, + line2 = -1, + range = 0, + count = -1, + reg = '', addr = 'none', magic = { file = false, @@ -3130,7 +3133,7 @@ describe('API', function() vertical = false, split = "", tab = 0, - verbose = 0 + verbose = -1 } }, meths.parse_cmd('echo foo', {})) end) @@ -3141,6 +3144,9 @@ describe('API', function() bang = false, line1 = 4, line2 = 6, + range = 2, + count = -1, + reg = '', addr = 'line', magic = { file = false, @@ -3165,10 +3171,86 @@ describe('API', function() vertical = false, split = "", tab = 0, - verbose = 0 + verbose = -1 } }, meths.parse_cmd('4,6s/math.random/math.max/', {})) end) + it('works with count', function() + eq({ + cmd = 'buffer', + args = {}, + bang = false, + line1 = 1, + line2 = 1, + range = 1, + count = 1, + reg = '', + addr = 'buf', + magic = { + file = false, + bar = true + }, + nargs = '*', + nextcmd = '', + mods = { + browse = false, + confirm = false, + emsg_silent = false, + hide = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + vertical = false, + split = "", + tab = 0, + verbose = -1 + } + }, meths.parse_cmd('buffer 1', {})) + end) + it('works with register', function() + eq({ + cmd = 'put', + args = {}, + bang = false, + line1 = 1, + line2 = 1, + range = 0, + count = -1, + reg = '+', + addr = 'line', + magic = { + file = false, + bar = true + }, + nargs = '0', + nextcmd = '', + mods = { + browse = false, + confirm = false, + emsg_silent = false, + hide = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + vertical = false, + split = "", + tab = 0, + verbose = -1 + } + }, meths.parse_cmd('put +', {})) + end) it('works with bang', function() eq({ cmd = 'write', @@ -3176,6 +3258,9 @@ describe('API', function() bang = true, line1 = 1, line2 = 1, + range = 0, + count = -1, + reg = '', addr = 'line', magic = { file = true, @@ -3200,7 +3285,7 @@ describe('API', function() vertical = false, split = "", tab = 0, - verbose = 0 + verbose = -1 }, }, meths.parse_cmd('w!', {})) end) @@ -3211,6 +3296,9 @@ describe('API', function() bang = false, line1 = 1, line2 = 1, + range = 0, + count = -1, + reg = '', addr = '?', magic = { file = true, @@ -3247,6 +3335,9 @@ describe('API', function() bang = true, line1 = 4, line2 = 6, + range = 2, + count = -1, + reg = '', addr = 'line', magic = { file = false, @@ -3271,7 +3362,7 @@ describe('API', function() vertical = false, split = "", tab = 0, - verbose = 0 + verbose = -1 } }, meths.parse_cmd('4,6MyCommand! test it', {})) end) @@ -3282,6 +3373,9 @@ describe('API', function() bang = false, line1 = 0, line2 = 0, + range = 0, + count = -1, + reg = '', addr = 'arg', magic = { file = true, @@ -3306,7 +3400,7 @@ describe('API', function() vertical = false, split = "", tab = 0, - verbose = 0 + verbose = -1 } }, meths.parse_cmd('argadd a.txt | argadd b.txt', {})) end) @@ -3316,8 +3410,11 @@ describe('API', function() cmd = 'MyCommand', args = { 'test it' }, bang = false, - line1 = 1, - line2 = 1, + line1 = -1, + line2 = -1, + range = 0, + count = -1, + reg = '', addr = 'none', magic = { file = false, @@ -3342,7 +3439,7 @@ describe('API', function() vertical = false, split = "", tab = 0, - verbose = 0 + verbose = -1 } }, meths.parse_cmd('MyCommand test it', {})) end) @@ -3355,6 +3452,9 @@ describe('API', function() bang = false, line1 = 1, line2 = 2, + range = 0, + count = -1, + reg = '', addr = 'buf', magic = { file = false, @@ -3379,7 +3479,7 @@ describe('API', function() vertical = false, split = "", tab = 0, - verbose = 0 + verbose = -1 } }, meths.parse_cmd('MyCommand', {})) end) -- cgit From 7aedcd8febaf74403851f8482529302e3ab30922 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Thu, 5 May 2022 01:49:29 +0600 Subject: refactor(api): make `range` in `nvim_parse_cmd` an array Changes the `range` value in `nvim_parse_cmd` into an array to describe range information more concisely. Also makes `range` and `count` be mutually exclusive by making count `-1` when command takes a range instead of a count. Additionally corrects the behavior of `count` for built-in commands by making the default count `0`. --- test/functional/api/vim_spec.lua | 76 +++++----------------------------------- 1 file changed, 9 insertions(+), 67 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 7e54ae0248..610036f484 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -3104,9 +3104,7 @@ describe('API', function() cmd = 'echo', args = { 'foo' }, bang = false, - line1 = -1, - line2 = -1, - range = 0, + range = {}, count = -1, reg = '', addr = 'none', @@ -3142,9 +3140,7 @@ describe('API', function() cmd = 'substitute', args = { '/math.random/math.max/' }, bang = false, - line1 = 4, - line2 = 6, - range = 2, + range = { 4, 6 }, count = -1, reg = '', addr = 'line', @@ -3180,9 +3176,7 @@ describe('API', function() cmd = 'buffer', args = {}, bang = false, - line1 = 1, - line2 = 1, - range = 1, + range = {}, count = 1, reg = '', addr = 'buf', @@ -3218,9 +3212,7 @@ describe('API', function() cmd = 'put', args = {}, bang = false, - line1 = 1, - line2 = 1, - range = 0, + range = {}, count = -1, reg = '+', addr = 'line', @@ -3256,9 +3248,7 @@ describe('API', function() cmd = 'write', args = {}, bang = true, - line1 = 1, - line2 = 1, - range = 0, + range = {}, count = -1, reg = '', addr = 'line', @@ -3294,9 +3284,7 @@ describe('API', function() cmd = 'split', args = { 'foo.txt' }, bang = false, - line1 = 1, - line2 = 1, - range = 0, + range = {}, count = -1, reg = '', addr = '?', @@ -3333,9 +3321,7 @@ describe('API', function() cmd = 'MyCommand', args = { 'test', 'it' }, bang = true, - line1 = 4, - line2 = 6, - range = 2, + range = { 4, 6 }, count = -1, reg = '', addr = 'line', @@ -3371,9 +3357,7 @@ describe('API', function() cmd = 'argadd', args = { 'a.txt' }, bang = false, - line1 = 0, - line2 = 0, - range = 0, + range = {}, count = -1, reg = '', addr = 'arg', @@ -3410,9 +3394,7 @@ describe('API', function() cmd = 'MyCommand', args = { 'test it' }, bang = false, - line1 = -1, - line2 = -1, - range = 0, + range = {}, count = -1, reg = '', addr = 'none', @@ -3443,46 +3425,6 @@ describe('API', function() } }, meths.parse_cmd('MyCommand test it', {})) end) - it('sets correct default range', function() - command('command -range=% -addr=buffers MyCommand echo foo') - command('new') - eq({ - cmd = 'MyCommand', - args = {}, - bang = false, - line1 = 1, - line2 = 2, - range = 0, - count = -1, - reg = '', - addr = 'buf', - magic = { - file = false, - bar = false - }, - nargs = '0', - nextcmd = '', - mods = { - browse = false, - confirm = false, - emsg_silent = false, - hide = false, - keepalt = false, - keepjumps = false, - keepmarks = false, - keeppatterns = false, - lockmarks = false, - noautocmd = false, - noswapfile = false, - sandbox = false, - silent = false, - vertical = false, - split = "", - tab = 0, - verbose = -1 - } - }, meths.parse_cmd('MyCommand', {})) - end) it('errors for invalid command', function() eq('Error while parsing command line', pcall_err(meths.parse_cmd, 'Fubar', {})) command('command! Fubar echo foo') -- cgit From 511f06a56e77f612f7bc8ca563ebecb7239a9914 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Thu, 5 May 2022 23:11:57 +0600 Subject: fix(api): make `nvim_parse_cmd` propagate errors Makes `nvim_parse_cmd` propagate any errors that occur while parsing to give the user a better idea of what's wrong with the command. --- test/functional/api/vim_spec.lua | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 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 610036f484..11c1fc6c2c 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -3426,10 +3426,15 @@ describe('API', function() }, meths.parse_cmd('MyCommand test it', {})) end) it('errors for invalid command', function() - eq('Error while parsing command line', pcall_err(meths.parse_cmd, 'Fubar', {})) + 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', {})) command('command! Fubar echo foo') - eq('Error while parsing command line', pcall_err(meths.parse_cmd, 'Fubar!', {})) - eq('Error while parsing command line', pcall_err(meths.parse_cmd, '4,6Fubar', {})) + 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', {})) end) end) end) -- cgit From 14f3383c0da1413a5ae82feb19ac89f01d4b9aad Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Sat, 7 May 2022 08:57:21 +0600 Subject: fix(api): make `nvim_parse_cmd` work correctly with both range and count It seems range and count can be used together in commands. This PR fixes the behavior of `nvim_parse_cmd` for those cases by removing the mutual exclusivity of "range" and "count". It also removes range line number validation for `nvim_parse_cmd` as it's not its job to validate the command. --- test/functional/api/vim_spec.lua | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 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 11c1fc6c2c..d68f299277 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -3176,7 +3176,7 @@ describe('API', function() cmd = 'buffer', args = {}, bang = false, - range = {}, + range = { 1 }, count = 1, reg = '', addr = 'buf', @@ -3243,6 +3243,42 @@ describe('API', function() } }, meths.parse_cmd('put +', {})) end) + it('works with range, count and register', function() + eq({ + cmd = 'delete', + args = {}, + bang = false, + range = { 3, 7 }, + count = 7, + reg = '*', + addr = 'line', + magic = { + file = false, + bar = true + }, + nargs = '0', + nextcmd = '', + mods = { + browse = false, + confirm = false, + emsg_silent = false, + hide = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + vertical = false, + split = "", + tab = 0, + verbose = -1 + } + }, meths.parse_cmd('1,3delete * 5', {})) + end) it('works with bang', function() eq({ cmd = 'write', -- cgit From dfcc58466505f7fb5f62d636a67facaeea143285 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Sun, 8 May 2022 17:39:45 +0600 Subject: feat(api): add `nvim_cmd` Adds the API function `nvim_cmd` which allows executing an Ex-command through a Dictionary which can have the same values as the return value of `nvim_parse_cmd()`. This makes it much easier to do things like passing arguments with a space to commands that otherwise may not allow it, or to make commands interpret certain characters literally when they otherwise would not. --- test/functional/api/vim_spec.lua | 143 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 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 d68f299277..e07202c46f 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1,5 +1,6 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') +local lfs = require('lfs') local fmt = string.format local assert_alive = helpers.assert_alive @@ -25,6 +26,7 @@ local tmpname = helpers.tmpname local write_file = helpers.write_file local exec_lua = helpers.exec_lua local exc_exec = helpers.exc_exec +local insert = helpers.insert local pcall_err = helpers.pcall_err local format_string = helpers.format_string @@ -3473,4 +3475,145 @@ describe('API', function() pcall_err(meths.parse_cmd, '4,6Fubar', {})) end) end) + describe('nvim_cmd', function() + it('works', function () + meths.cmd({ cmd = "set", args = { "cursorline" } }, {}) + eq(true, meths.get_option_value("cursorline", {})) + 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 + line2 + line3 + line4 + you didn't expect this + line5 + line6 + ]] + meths.cmd({ cmd = "del", range = {2, 4} }, {}) + expect [[ + line1 + you didn't expect this + line5 + line6 + ]] + end) + it('works with count', function() + insert [[ + line1 + line2 + line3 + line4 + you didn't expect this + line5 + line6 + ]] + meths.cmd({ cmd = "del", range = { 2 }, count = 4 }, {}) + expect [[ + line1 + line5 + line6 + ]] + end) + it('works with register', function() + insert [[ + line1 + line2 + line3 + line4 + you didn't expect this + line5 + line6 + ]] + meths.cmd({ cmd = "del", range = { 2, 4 }, reg = 'a' }, {}) + meths.exec("1put a", false) + expect [[ + line1 + line2 + line3 + line4 + you didn't expect this + line5 + line6 + ]] + end) + it('works with bang', function () + meths.create_user_command("Foo", 'echo ""', { bang = true }) + eq("!", meths.cmd({ cmd = "Foo", bang = true }, { output = true })) + eq("", meths.cmd({ cmd = "Foo", bang = false }, { output = true })) + end) + it('works with modifiers', function() + meths.create_user_command("Foo", 'set verbose', {}) + eq(" verbose=1", meths.cmd({ cmd = "Foo", mods = { verbose = 1 } }, { output = true })) + eq(0, meths.get_option_value("verbose", {})) + 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(lfs.currentdir(), + meths.cmd({ cmd = "Foo", args = { '%:p:h' }, magic = { file = true } }, + { output = true })) + end) + it('splits arguments correctly', function() + meths.exec([[ + function! FooFunc(...) + echo a:000 + endfunction + ]], 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"}}, + { output = true })) + eq([=[['test \ \\ \"""\', 'more\ tests\" ']]=], + meths.cmd({ cmd = "Foo", args = { [[test \ \\ \"""\]], [[more\ tests\" ]] } }, + { output = true })) + end) + it('splits arguments correctly for Lua callback', function() + meths.exec_lua([[ + local function FooFunc(opts) + vim.pretty_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 })) + 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")) + end) + it('triggers CmdUndefined event if command is not found', function() + meths.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 })) + end) + it('errors if command is not implemented', function() + eq("Command not implemented: popup", pcall_err(meths.cmd, { cmd = "popup" }, {})) + end) + end) end) -- cgit From cf68f0a51202342163825015602bdf78b783c777 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Wed, 11 May 2022 22:51:53 +0600 Subject: fix(api): make `nvim_cmd` work correctly with empty arguments list (#18527) Closes #18526. --- test/functional/api/vim_spec.lua | 4 ++++ 1 file changed, 4 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 e07202c46f..f39aa2f20b 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -3615,5 +3615,9 @@ describe('API', function() it('errors if command is not implemented', function() eq("Command not implemented: popup", pcall_err(meths.cmd, { cmd = "popup" }, {})) end) + it('works with empty arguments list', function() + meths.cmd({ cmd = "update" }, {}) + meths.cmd({ cmd = "buffer", count = 0 }, {}) + end) end) end) -- cgit From 0a3d615b1ca17cda978b89d66acef39b90ee7c81 Mon Sep 17 00:00:00 2001 From: deforde <7503504+deforde@users.noreply.github.com> Date: Sun, 15 May 2022 22:06:23 +0200 Subject: fix(api): nvim_eval_statusline should validate input #18347 Fix #18112 Make an exception for strings starting with "%!". --- test/functional/api/vim_spec.lua | 4 ++++ 1 file changed, 4 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 f39aa2f20b..ba170ba8c5 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -3044,6 +3044,10 @@ describe('API', function() eq('fillchar must be a single character', pcall_err(meths.eval_statusline, '', { fillchar = 1 })) end) + it('rejects invalid string', function() + eq('E539: Illegal character <}>', + pcall_err(meths.eval_statusline, '%{%}', {})) + end) describe('highlight parsing', function() it('works', function() eq({ -- cgit From 6219331c4d333e5a76129746021f972c21a040db Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Wed, 11 May 2022 13:49:43 +0100 Subject: feat(api): add win and buf to nvim_set_option_value Co-authored-by: Gregory Anders <8965202+gpanders@users.noreply.github.com> --- 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 ba170ba8c5..8c4048132c 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1439,6 +1439,24 @@ describe('API', function() nvim('set_option_value', 'autoread', NIL, {scope = 'local'}) eq(NIL, nvim('get_option_value', 'autoread', {scope = 'local'})) end) + + it('set window options', function() + -- Same as to nvim_win_set_option + nvim('set_option_value', 'colorcolumn', '4,3', {win=0}) + 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'})) + end) + + it('set local window options', function() + -- Different to nvim_win_set_option + nvim('set_option_value', 'colorcolumn', '4,3', {win=0, scope='local'}) + eq('4,3', nvim('get_option_value', 'colorcolumn', {scope = 'local'})) + command("set modified hidden") + command("enew") -- edit new buffer, window option is reset + eq('', nvim('get_option_value', 'colorcolumn', {scope = 'local'})) + end) end) describe('nvim_{get,set}_current_buf, nvim_list_bufs', function() -- cgit From e1bdb2a258cbe6c5cb981acc6bac82cd9e7706fb Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Fri, 13 May 2022 20:47:11 +0600 Subject: feat(ui): add `'winbar'` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds support for a bar at the top of each window, enabled through the `'winbar'` option. Co-authored-by: Björn Linse --- test/functional/api/vim_spec.lua | 13 +++++++++++++ 1 file changed, 13 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 ba170ba8c5..c4748cc00d 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -3102,6 +3102,19 @@ describe('API', function() 'TextWithNoHighlight%#WarningMsg#TextWithWarningHighlight', { use_tabline = true, highlights = true })) end) + it('works with winbar', function() + eq({ + str = 'TextWithNoHighlightTextWithWarningHighlight', + width = 43, + highlights = { + { start = 0, group = 'WinBar' }, + { start = 19, group = 'WarningMsg' } + } + }, + meths.eval_statusline( + 'TextWithNoHighlight%#WarningMsg#TextWithWarningHighlight', + { use_winbar = true, highlights = true })) + end) end) end) describe('nvim_parse_cmd', function() -- cgit From fb8fa004d8c91b7b591509539a228e97ebc57d9d Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Thu, 19 May 2022 21:49:12 +0600 Subject: fix: make `nvim_cmd` not suppress errors inside key mapping Closes #18632 --- test/functional/api/vim_spec.lua | 8 ++++++++ 1 file changed, 8 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 c4748cc00d..c5e8cfee23 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -3636,5 +3636,13 @@ describe('API', function() meths.cmd({ cmd = "update" }, {}) meths.cmd({ cmd = "buffer", count = 0 }, {}) end) + it('doesn\'t suppress errors when used in keymapping', function() + meths.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:")) + end) end) end) -- cgit From e3281d992e1b9366d67a4b4399e3b5e11bb6c1cc Mon Sep 17 00:00:00 2001 From: bfredl Date: Wed, 8 Jun 2022 23:22:50 +0200 Subject: fix(tests): check for EOF on exit of nvim properly --- test/functional/api/vim_spec.lua | 3 ++- 1 file changed, 2 insertions(+), 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 55535a92e5..ea5725d836 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -27,6 +27,7 @@ local write_file = helpers.write_file local exec_lua = helpers.exec_lua local exc_exec = helpers.exc_exec local insert = helpers.insert +local expect_exit = helpers.expect_exit local pcall_err = helpers.pcall_err local format_string = helpers.format_string @@ -2617,7 +2618,7 @@ describe('API', function() it('does not cause heap-use-after-free on exit while setting options', function() command('au OptionSet * q') - command('silent! call nvim_create_buf(0, 1)') + expect_exit(command, 'silent! call nvim_create_buf(0, 1)') end) end) -- cgit From 58d028f64bb0ddc80b6201906880182d14ad9a3c Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Mon, 20 Jun 2022 08:20:06 -0600 Subject: feat(api): add "buf" and "win" to nvim_get_option_value These mirror their counterparts in nvim_set_option_value. --- test/functional/api/vim_spec.lua | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 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 ea5725d836..ef6798dea3 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1453,10 +1453,21 @@ describe('API', function() it('set local window options', function() -- Different to nvim_win_set_option nvim('set_option_value', 'colorcolumn', '4,3', {win=0, scope='local'}) - eq('4,3', nvim('get_option_value', 'colorcolumn', {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', {scope = 'local'})) + eq('', 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('buf_set_option', buf, 'tagfunc', 'foobar') + eq('foobar', nvim('get_option_value', 'tagfunc', {buf = buf})) + + local win = nvim('get_current_win').id + nvim('win_set_option', win, 'number', true) + eq(true, nvim('get_option_value', 'number', {win = win})) end) end) -- cgit From cf23695dd748281daaf68e69ac48bf9eb27f2425 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 27 Jun 2022 14:10:13 +0800 Subject: fix(api): nvim_parse_cmd check for ambiguous user command (#19116) --- test/functional/api/vim_spec.lua | 3 +++ 1 file changed, 3 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 ef6798dea3..c05345dd4c 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -3520,6 +3520,9 @@ describe('API', function() pcall_err(meths.parse_cmd, 'Fubar!', {})) eq('Error while parsing command line: E481: No range allowed', pcall_err(meths.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', {})) end) end) describe('nvim_cmd', function() -- cgit From 606ec8b70874095a62289f1df3934eca78625742 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Tue, 28 Jun 2022 16:22:29 +0600 Subject: feat(api): make `nvim_parse_cmd` and `nvim_cmd` support :filter Also fixes a memory leak in `parse_cmdline`. Closes #18954. --- test/functional/api/vim_spec.lua | 87 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 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 c05345dd4c..858463efbd 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -3167,6 +3167,10 @@ describe('API', function() browse = false, confirm = false, emsg_silent = false, + filter = { + pattern = "", + force = false + }, hide = false, keepalt = false, keepjumps = false, @@ -3203,6 +3207,10 @@ describe('API', function() browse = false, confirm = false, emsg_silent = false, + filter = { + pattern = "", + force = false + }, hide = false, keepalt = false, keepjumps = false, @@ -3239,6 +3247,10 @@ describe('API', function() browse = false, confirm = false, emsg_silent = false, + filter = { + pattern = "", + force = false + }, hide = false, keepalt = false, keepjumps = false, @@ -3275,6 +3287,10 @@ describe('API', function() browse = false, confirm = false, emsg_silent = false, + filter = { + pattern = "", + force = false + }, hide = false, keepalt = false, keepjumps = false, @@ -3311,6 +3327,10 @@ describe('API', function() browse = false, confirm = false, emsg_silent = false, + filter = { + pattern = "", + force = false + }, hide = false, keepalt = false, keepjumps = false, @@ -3347,6 +3367,10 @@ describe('API', function() browse = false, confirm = false, emsg_silent = false, + filter = { + pattern = "", + force = false + }, hide = false, keepalt = false, keepjumps = false, @@ -3383,6 +3407,10 @@ describe('API', function() browse = false, confirm = false, emsg_silent = true, + filter = { + pattern = "foo", + force = false + }, hide = false, keepalt = false, keepjumps = false, @@ -3398,7 +3426,45 @@ describe('API', function() tab = 2, verbose = 15 }, - }, meths.parse_cmd('15verbose silent! aboveleft topleft tab split foo.txt', {})) + }, meths.parse_cmd('15verbose silent! aboveleft topleft tab filter /foo/ split foo.txt', {})) + eq({ + cmd = 'split', + args = { 'foo.txt' }, + bang = false, + range = {}, + count = -1, + reg = '', + addr = '?', + magic = { + file = true, + bar = true + }, + nargs = '?', + nextcmd = '', + mods = { + browse = false, + confirm = false, + emsg_silent = false, + filter = { + pattern = "foo", + force = true + }, + hide = false, + keepalt = false, + keepjumps = false, + keepmarks = false, + keeppatterns = false, + lockmarks = false, + noautocmd = false, + noswapfile = false, + sandbox = false, + silent = false, + vertical = false, + split = "", + tab = 0, + verbose = -1 + }, + }, meths.parse_cmd('filter! /foo/ split foo.txt', {})) end) it('works with user commands', function() command('command -bang -nargs=+ -range -addr=lines MyCommand echo foo') @@ -3420,6 +3486,10 @@ describe('API', function() browse = false, confirm = false, emsg_silent = false, + filter = { + pattern = "", + force = false + }, hide = false, keepalt = false, keepjumps = false, @@ -3456,6 +3526,10 @@ describe('API', function() browse = false, confirm = false, emsg_silent = false, + filter = { + pattern = "", + force = false + }, hide = false, keepalt = false, keepjumps = false, @@ -3493,6 +3567,10 @@ describe('API', function() browse = false, confirm = false, emsg_silent = false, + filter = { + pattern = "", + force = false + }, hide = false, keepalt = false, keepjumps = false, @@ -3604,6 +3682,13 @@ describe('API', function() meths.create_user_command("Foo", 'set verbose', {}) eq(" verbose=1", meths.cmd({ cmd = "Foo", mods = { verbose = 1 } }, { output = true })) eq(0, meths.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 })) end) it('works with magic.file', function() exec_lua([[ -- cgit From 610cf9f95032bd219cb5695d169fe2cd698ec307 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 30 Jun 2022 15:30:54 +0800 Subject: vim-patch:8.0.1570: can't use :popup for a menu in the terminal Problem: Can't use :popup for a menu in the terminal. (Wei Zhang) Solution: Make :popup work in the terminal. Also fix that entries were included that don't work in the current state. https://github.com/vim/vim/commit/29a2c08d792e4458a0af8371f5341394829fce29 --- 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 858463efbd..002bcd92a4 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -3748,7 +3748,7 @@ describe('API', function() eq("foo", meths.cmd({ cmd = "Foo" }, { output = true })) end) it('errors if command is not implemented', function() - eq("Command not implemented: popup", pcall_err(meths.cmd, { cmd = "popup" }, {})) + eq("Command not implemented: winpos", pcall_err(meths.cmd, { cmd = "winpos" }, {})) end) it('works with empty arguments list', function() meths.cmd({ cmd = "update" }, {}) -- cgit From 7a907c3314f939a3d2983ac07edc5c9672957352 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 2 Jul 2022 19:35:11 +0800 Subject: feat(api): add `unsilent` to command APIs --- test/functional/api/vim_spec.lua | 61 ++++++++++++++++++++++++---------------- 1 file changed, 36 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 002bcd92a4..989ed27e16 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -3181,10 +3181,11 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - vertical = false, split = "", tab = 0, - verbose = -1 + unsilent = false, + verbose = -1, + vertical = false, } }, meths.parse_cmd('echo foo', {})) end) @@ -3221,10 +3222,11 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - vertical = false, split = "", tab = 0, - verbose = -1 + unsilent = false, + verbose = -1, + vertical = false, } }, meths.parse_cmd('4,6s/math.random/math.max/', {})) end) @@ -3261,10 +3263,11 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - vertical = false, split = "", tab = 0, - verbose = -1 + unsilent = false, + verbose = -1, + vertical = false, } }, meths.parse_cmd('buffer 1', {})) end) @@ -3301,10 +3304,11 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - vertical = false, split = "", tab = 0, - verbose = -1 + unsilent = false, + verbose = -1, + vertical = false, } }, meths.parse_cmd('put +', {})) end) @@ -3341,10 +3345,11 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - vertical = false, split = "", tab = 0, - verbose = -1 + unsilent = false, + verbose = -1, + vertical = false, } }, meths.parse_cmd('1,3delete * 5', {})) end) @@ -3381,10 +3386,11 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - vertical = false, split = "", tab = 0, - verbose = -1 + unsilent = false, + verbose = -1, + vertical = false, }, }, meths.parse_cmd('w!', {})) end) @@ -3421,10 +3427,11 @@ describe('API', function() noswapfile = false, sandbox = false, silent = true, - vertical = false, split = "topleft", tab = 2, - verbose = 15 + unsilent = false, + verbose = 15, + vertical = false, }, }, meths.parse_cmd('15verbose silent! aboveleft topleft tab filter /foo/ split foo.txt', {})) eq({ @@ -3443,7 +3450,7 @@ describe('API', function() nextcmd = '', mods = { browse = false, - confirm = false, + confirm = true, emsg_silent = false, filter = { pattern = "foo", @@ -3459,12 +3466,13 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - vertical = false, - split = "", + split = "botright", tab = 0, - verbose = -1 + unsilent = true, + verbose = 0, + vertical = false, }, - }, meths.parse_cmd('filter! /foo/ split foo.txt', {})) + }, meths.parse_cmd('0verbose unsilent botright confirm filter! /foo/ split foo.txt', {})) end) it('works with user commands', function() command('command -bang -nargs=+ -range -addr=lines MyCommand echo foo') @@ -3500,10 +3508,11 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - vertical = false, split = "", tab = 0, - verbose = -1 + unsilent = false, + verbose = -1, + vertical = false, } }, meths.parse_cmd('4,6MyCommand! test it', {})) end) @@ -3540,10 +3549,11 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - vertical = false, split = "", tab = 0, - verbose = -1 + unsilent = false, + verbose = -1, + vertical = false, } }, meths.parse_cmd('argadd a.txt | argadd b.txt', {})) end) @@ -3581,10 +3591,11 @@ describe('API', function() noswapfile = false, sandbox = false, silent = false, - vertical = false, split = "", tab = 0, - verbose = -1 + unsilent = false, + verbose = -1, + vertical = false, } }, meths.parse_cmd('MyCommand test it', {})) end) -- cgit From 73526abbbdf08e68e572b8e54c583de5a0323484 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 16 Jul 2022 09:31:05 +0800 Subject: fix(api): do not switch win/buf if getting option in current win/buf (#19383) --- test/functional/api/vim_spec.lua | 11 +++++++++++ 1 file changed, 11 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 989ed27e16..63a4e9a39c 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1469,6 +1469,17 @@ describe('API', function() nvim('win_set_option', win, 'number', true) eq(true, 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 + 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)) + end) end) describe('nvim_{get,set}_current_buf, nvim_list_bufs', function() -- cgit From 9f837a5dcf61e0b27778dd7127036e12d694d92c Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 17 Jul 2022 09:59:32 +0800 Subject: fix(api): fix nvim_parse_cmd interfere with printing line in Ex mode (#19400) --- test/functional/api/vim_spec.lua | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 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 63a4e9a39c..3724dbf820 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -3624,6 +3624,38 @@ describe('API', function() eq('Error while parsing command line: E464: Ambiguous use of user-defined command', pcall_err(meths.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 + }) + screen:attach() + insert([[ + foo + bar]]) + feed('gQ1') + screen:expect([[ + foo | + bar | + {0:~ }| + {0:~ }| + {1: }| + Entering Ex mode. Type "visual" to go to Normal mode. | + :1^ | + ]]) + eq('Error while parsing command line', pcall_err(meths.parse_cmd, '', {})) + feed('') + screen:expect([[ + foo | + bar | + {1: }| + Entering Ex mode. Type "visual" to go to Normal mode. | + :1 | + foo | + :^ | + ]]) + end) end) describe('nvim_cmd', function() it('works', function () -- cgit