diff options
Diffstat (limited to 'test')
76 files changed, 2411 insertions, 405 deletions
diff --git a/test/.luacheckrc b/test/.luacheckrc index 034b4f10df..abfa881754 100644 --- a/test/.luacheckrc +++ b/test/.luacheckrc @@ -17,4 +17,4 @@ ignore = { } -- Ignore whitespace issues in converted Vim legacy tests. -files["functional/legacy"] = {ignore = { "611", "612", "613", "621" }} +--files["functional/legacy"] = {ignore = { "611", "612", "613", "621" }} diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua new file mode 100644 index 0000000000..2297a0760f --- /dev/null +++ b/test/functional/api/highlight_spec.lua @@ -0,0 +1,103 @@ +local helpers = require('test.functional.helpers')(after_each) +local clear, nvim = helpers.clear, helpers.nvim +local Screen = require('test.functional.ui.screen') +local eq, eval = helpers.eq, helpers.eval +local command = helpers.command +local meths = helpers.meths + +describe('highlight api',function() + local expected_rgb = { + background = Screen.colors.Yellow, + foreground = Screen.colors.Red, + special = Screen.colors.Blue, + bold = true, + } + local expected_cterm = { + background = 10, + underline = true, + } + local expected_rgb2 = { + background = Screen.colors.Yellow, + foreground = Screen.colors.Red, + special = Screen.colors.Blue, + bold = true, + italic = true, + reverse = true, + undercurl = true, + underline = true, + } + + before_each(function() + clear() + command("hi NewHighlight cterm=underline ctermbg=green guifg=red guibg=yellow guisp=blue gui=bold") + end) + + it("nvim_get_hl_by_id", function() + local hl_id = eval("hlID('NewHighlight')") + eq(expected_cterm, nvim("get_hl_by_id", hl_id, false)) + + hl_id = eval("hlID('NewHighlight')") + -- Test valid id. + eq(expected_rgb, nvim("get_hl_by_id", hl_id, true)) + + -- Test invalid id. + local err, emsg = pcall(meths.get_hl_by_id, 30000, false) + eq(false, err) + eq('Invalid highlight id: 30000', string.match(emsg, 'Invalid.*')) + + -- Test all highlight properties. + command('hi NewHighlight gui=underline,bold,undercurl,italic,reverse') + eq(expected_rgb2, nvim("get_hl_by_id", hl_id, true)) + + -- Test nil argument. + err, emsg = pcall(meths.get_hl_by_id, { nil }, false) + eq(false, err) + eq('Wrong type for argument 1, expecting Integer', + string.match(emsg, 'Wrong.*')) + + -- Test 0 argument. + err, emsg = pcall(meths.get_hl_by_id, 0, false) + eq(false, err) + eq('Invalid highlight id: 0', + string.match(emsg, 'Invalid.*')) + + -- Test -1 argument. + err, emsg = pcall(meths.get_hl_by_id, -1, false) + eq(false, err) + eq('Invalid highlight id: -1', + string.match(emsg, 'Invalid.*')) + end) + + it("nvim_get_hl_by_name", function() + local expected_normal = { background = Screen.colors.Yellow, + foreground = Screen.colors.Red } + + -- Test `Normal` default values. + eq({}, nvim("get_hl_by_name", 'Normal', true)) + + eq(expected_cterm, nvim("get_hl_by_name", 'NewHighlight', false)) + eq(expected_rgb, nvim("get_hl_by_name", 'NewHighlight', true)) + + -- Test `Normal` modified values. + command('hi Normal guifg=red guibg=yellow') + eq(expected_normal, nvim("get_hl_by_name", 'Normal', true)) + + -- Test invalid name. + local err, emsg = pcall(meths.get_hl_by_name , 'unknown_highlight', false) + eq(false, err) + eq('Invalid highlight name: unknown_highlight', + string.match(emsg, 'Invalid.*')) + + -- Test nil argument. + err, emsg = pcall(meths.get_hl_by_name , { nil }, false) + eq(false, err) + eq('Wrong type for argument 1, expecting String', + string.match(emsg, 'Wrong.*')) + + -- Test empty string argument. + err, emsg = pcall(meths.get_hl_by_name , '', false) + eq(false, err) + eq('Invalid highlight name: ', + string.match(emsg, 'Invalid.*')) + end) +end) diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua index 6a32f979ea..9f245d913b 100644 --- a/test/functional/api/server_requests_spec.lua +++ b/test/functional/api/server_requests_spec.lua @@ -20,6 +20,22 @@ describe('server -> client', function() cid = nvim('get_api_info')[1] end) + it('handles unexpected closed stream while preparing RPC response', function() + source([[ + let g:_nvim_args = [v:progpath, '--embed', '-n', '-u', 'NONE', '-i', 'NONE', ] + let ch1 = jobstart(g:_nvim_args, {'rpc': v:true}) + let child1_ch = rpcrequest(ch1, "nvim_get_api_info")[0] + call rpcnotify(ch1, 'nvim_eval', 'rpcrequest('.child1_ch.', "nvim_get_api_info")') + + let ch2 = jobstart(g:_nvim_args, {'rpc': v:true}) + let child2_ch = rpcrequest(ch2, "nvim_get_api_info")[0] + call rpcnotify(ch2, 'nvim_eval', 'rpcrequest('.child2_ch.', "nvim_get_api_info")') + + call jobstop(ch1) + ]]) + eq(2, eval("1+1")) -- Still alive? + end) + describe('simple call', function() it('works', function() local function on_setup() @@ -141,7 +157,7 @@ describe('server -> client', function() end) end) - describe('when the client is a recursive vim instance', function() + describe('recursive (child) nvim client', function() if os.getenv("TRAVIS") and helpers.os_name() == "osx" then -- XXX: Hangs Travis macOS since e9061117a5b8f195c3f26a5cb94e18ddd7752d86. pending("[Hangs on Travis macOS. #5002]", function() end) @@ -155,7 +171,7 @@ describe('server -> client', function() after_each(function() command('call rpcstop(vim)') end) - it('can send/recieve notifications and make requests', function() + it('can send/receive notifications and make requests', function() nvim('command', "call rpcnotify(vim, 'vim_set_current_line', 'SOME TEXT')") -- Wait for the notification to complete. @@ -188,7 +204,7 @@ describe('server -> client', function() end) end) - describe('when using jobstart', function() + describe('jobstart()', function() local jobid before_each(function() local channel = nvim('get_api_info')[1] @@ -227,7 +243,7 @@ describe('server -> client', function() end) end) - describe('when connecting to another nvim instance', function() + describe('connecting to another (peer) nvim', function() local function connect_test(server, mode, address) local serverpid = funcs.getpid() local client = spawn(nvim_argv) @@ -256,7 +272,7 @@ describe('server -> client', function() client:close() end - it('over a named pipe', function() + it('via named pipe', function() local server = spawn(nvim_argv) set_session(server) local address = funcs.serverlist()[1] @@ -265,7 +281,7 @@ describe('server -> client', function() connect_test(server, 'pipe', address) end) - it('to an ip adress', function() + it('via ip address', function() local server = spawn(nvim_argv) set_session(server) local address = funcs.serverstart("127.0.0.1:") @@ -273,7 +289,7 @@ describe('server -> client', function() connect_test(server, 'tcp', address) end) - it('to a hostname', function() + it('via hostname', function() local server = spawn(nvim_argv) set_session(server) local address = funcs.serverstart("localhost:") diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index e59b5d712d..b849304d45 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -329,24 +329,92 @@ describe('api', function() } eq({ { {mode='n', blocking=false}, 13, - {mode='n', blocking=false}, -- TODO: should be blocked=true + {mode='n', blocking=false}, -- TODO: should be blocked=true ? 1 }, NIL}, meths.call_atomic(req)) eq({mode='r', blocking=true}, nvim("get_mode")) end) - -- TODO: bug #6166 it("during insert-mode map-pending, returns blocking=true #6166", function() command("inoremap xx foo") nvim("input", "ix") eq({mode='i', blocking=true}, nvim("get_mode")) end) - -- TODO: bug #6166 it("during normal-mode gU, returns blocking=false #6166", function() nvim("input", "gu") eq({mode='no', blocking=false}, nvim("get_mode")) end) end) + describe('RPC (K_EVENT) #6166', function() + it('does not complete ("interrupt") normal-mode operator-pending', function() + helpers.insert([[ + FIRST LINE + SECOND LINE]]) + nvim('input', 'gg') + nvim('input', 'gu') + -- Make any RPC request (can be non-async: op-pending does not block). + nvim('get_current_buf') + -- Buffer should not change. + helpers.expect([[ + FIRST LINE + SECOND LINE]]) + -- Now send input to complete the operator. + nvim('input', 'j') + helpers.expect([[ + first line + second line]]) + end) + + it('does not complete ("interrupt") `d` #3732', function() + local screen = Screen.new(20, 4) + screen:attach() + command('set listchars=eol:$') + command('set list') + feed('ia<cr>b<cr>c<cr><Esc>kkk') + feed('d') + -- Make any RPC request (can be non-async: op-pending does not block). + nvim('get_current_buf') + screen:expect([[ + ^a$ | + b$ | + c$ | + | + ]]) + end) + + it('does not complete ("interrupt") normal-mode map-pending', function() + command("nnoremap dd :let g:foo='it worked...'<CR>") + helpers.insert([[ + FIRST LINE + SECOND LINE]]) + nvim('input', 'gg') + nvim('input', 'd') + -- Make any RPC request (must be async, because map-pending blocks). + nvim('get_api_info') + -- Send input to complete the mapping. + nvim('input', 'd') + helpers.expect([[ + FIRST LINE + SECOND LINE]]) + eq('it worked...', helpers.eval('g:foo')) + end) + it('does not complete ("interrupt") insert-mode map-pending', function() + command('inoremap xx foo') + command('set timeoutlen=9999') + helpers.insert([[ + FIRST LINE + SECOND LINE]]) + nvim('input', 'ix') + -- Make any RPC request (must be async, because map-pending blocks). + nvim('get_api_info') + -- Send input to complete the mapping. + nvim('input', 'x') + helpers.expect([[ + FIRST LINE + SECOND LINfooE]]) + end) + end) + describe('nvim_replace_termcodes', function() it('escapes K_SPECIAL as K_SPECIAL KS_SPECIAL KE_FILLER', function() eq('\128\254X', helpers.nvim('replace_termcodes', '\128', true, true, true)) diff --git a/test/functional/autocmd/termclose_spec.lua b/test/functional/autocmd/termclose_spec.lua index 8cc49c0d4c..c6c30494dd 100644 --- a/test/functional/autocmd/termclose_spec.lua +++ b/test/functional/autocmd/termclose_spec.lua @@ -57,7 +57,9 @@ describe('TermClose event', function() command('call jobstop(g:test_job)') retry(nil, nil, function() eq(1, eval('get(g:, "test_job_exited", 0)')) end) local duration = os.time() - start - eq(4, duration) + -- nvim starts sending kill after 2*KILL_TIMEOUT_MS + helpers.ok(4 <= duration) + helpers.ok(duration <= 7) -- <= 4 + delta because of slow CI end) it('reports the correct <abuf>', function() diff --git a/test/functional/clipboard/clipboard_provider_spec.lua b/test/functional/clipboard/clipboard_provider_spec.lua index eb2eeee0da..a3ea3b568f 100644 --- a/test/functional/clipboard/clipboard_provider_spec.lua +++ b/test/functional/clipboard/clipboard_provider_spec.lua @@ -4,6 +4,8 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert local feed_command, expect, eq, eval = helpers.feed_command, helpers.expect, helpers.eq, helpers.eval +local command = helpers.command +local meths = helpers.meths local function basic_register_test(noblock) insert("some words") @@ -80,15 +82,73 @@ local function basic_register_test(noblock) expect("two and three and one") end -describe('the unnamed register', function() +describe('clipboard', function() before_each(clear) - it('works without provider', function() + + it('unnamed register works without provider', function() eq('"', eval('v:register')) basic_register_test() end) + + it('`:redir @+>` with invalid g:clipboard shows exactly one error #7184', + function() + local screen = Screen.new(72, 4) + screen:attach() + command("let g:clipboard = 'bogus'") + feed_command('redir @+> | :silent echo system("cat CONTRIBUTING.md") | redir END') + screen:expect([[ + ^ | + ~ | + ~ | + clipboard: No provider. Try ":checkhealth" or ":h clipboard". | + ]], nil, {{bold = true, foreground = Screen.colors.Blue}}) + end) + + it('`:redir @+>|bogus_cmd|redir END` + invalid g:clipboard must not recurse #7184', + function() + local screen = Screen.new(72, 4) + screen:attach() + command("let g:clipboard = 'bogus'") + feed_command('redir @+> | bogus_cmd | redir END') + screen:expect([[ + ~ | + clipboard: No provider. Try ":checkhealth" or ":h clipboard". | + E492: Not an editor command: bogus_cmd | redir END | + Press ENTER or type command to continue^ | + ]], nil, {{bold = true, foreground = Screen.colors.Blue}}) + end) + + it('invalid g:clipboard shows hint if :redir is not active', function() + command("let g:clipboard = 'bogus'") + eq('', eval('provider#clipboard#Executable()')) + eq('clipboard: invalid g:clipboard', eval('provider#clipboard#Error()')) + + local screen = Screen.new(72, 4) + screen:attach() + command("let g:clipboard = 'bogus'") + -- Explicit clipboard attempt, should show a hint message. + feed_command('let @+="foo"') + screen:expect([[ + ^ | + ~ | + ~ | + clipboard: No provider. Try ":checkhealth" or ":h clipboard". | + ]], nil, {{bold = true, foreground = Screen.colors.Blue}}) + end) + + it('valid g:clipboard', function() + -- provider#clipboard#Executable() only checks the structure. + meths.set_var('clipboard', { + ['name'] = 'clippy!', + ['copy'] = { ['+'] = 'any command', ['*'] = 'some other' }, + ['paste'] = { ['+'] = 'any command', ['*'] = 'some other' }, + }) + eq('clippy!', eval('provider#clipboard#Executable()')) + eq('', eval('provider#clipboard#Error()')) + end) end) -describe('clipboard usage', function() +describe('clipboard', function() local function reset(...) clear('--cmd', 'let &rtp = "test/functional/fixtures,".&rtp', ...) end @@ -98,7 +158,36 @@ describe('clipboard usage', function() feed_command('call getreg("*")') -- force load of provider end) - it('has independent "* and unnamed registers per default', function() + it('`:redir @+>` invokes clipboard once-per-message', function() + eq(0, eval("g:clip_called_set")) + feed_command('redir @+> | :silent echo system("cat CONTRIBUTING.md") | redir END') + -- Assuming CONTRIBUTING.md has >100 lines. + assert(eval("g:clip_called_set") > 100) + end) + + it('`:redir @">` does NOT invoke clipboard', function() + -- :redir to a non-clipboard register, with `:set clipboard=unnamed` does + -- NOT propagate to the clipboard. This is consistent with Vim. + command("set clipboard=unnamedplus") + eq(0, eval("g:clip_called_set")) + feed_command('redir @"> | :silent echo system("cat CONTRIBUTING.md") | redir END') + eq(0, eval("g:clip_called_set")) + end) + + it('`:redir @+>|bogus_cmd|redir END` must not recurse #7184', + function() + local screen = Screen.new(72, 4) + screen:attach() + feed_command('redir @+> | bogus_cmd | redir END') + screen:expect([[ + ^ | + ~ | + ~ | + E492: Not an editor command: bogus_cmd | redir END | + ]], nil, {{bold = true, foreground = Screen.colors.Blue}}) + end) + + it('has independent "* and unnamed registers by default', function() insert("some words") feed('^"*dwdw"*P') expect('some ') @@ -139,7 +228,7 @@ describe('clipboard usage', function() eq({'some\ntext', '\nvery binary\n'}, eval("getreg('*', 1, 1)")) end) - it('support autodectection of regtype', function() + it('autodetects regtype', function() feed_command("let g:test_clip['*'] = ['linewise stuff','']") feed_command("let g:test_clip['+'] = ['charwise','stuff']") eq("V", eval("getregtype('*')")) @@ -169,7 +258,7 @@ describe('clipboard usage', function() eq({{' much', 'ktext', ''}, 'b'}, eval("g:test_clip['+']")) end) - it('supports setreg', function() + it('supports setreg()', function() feed_command('call setreg("*", "setted\\ntext", "c")') feed_command('call setreg("+", "explicitly\\nlines", "l")') feed('"+P"*p') @@ -187,7 +276,7 @@ describe('clipboard usage', function() ]]) end) - it('supports let @+ (issue #1427)', function() + it('supports :let @+ (issue #1427)', function() feed_command("let @+ = 'some'") feed_command("let @* = ' other stuff'") eq({{'some'}, 'v'}, eval("g:test_clip['+']")) @@ -303,9 +392,16 @@ describe('clipboard usage', function() eq('---', eval('getreg("*")')) end) + it('works in the cmdline window', function() + feed('q:itext<esc>yy') + eq({{'text', ''}, 'V'}, eval("g:test_clip['*']")) + command("let g:test_clip['*'] = [['star'], 'c']") + feed('p') + eq('textstar', meths.get_current_line()) + end) end) - describe('with clipboard=unnamedplus', function() + describe('clipboard=unnamedplus', function() before_each(function() feed_command('set clipboard=unnamedplus') end) @@ -349,6 +445,7 @@ describe('clipboard usage', function() really unnamed the plus]]) end) + it('is updated on global changes', function() insert([[ text diff --git a/test/functional/core/exit_spec.lua b/test/functional/core/exit_spec.lua index 3fb39f3e78..188a6a2c11 100644 --- a/test/functional/core/exit_spec.lua +++ b/test/functional/core/exit_spec.lua @@ -2,8 +2,12 @@ local helpers = require('test.functional.helpers')(after_each) local command = helpers.command local eval = helpers.eval -local eq, neq = helpers.eq, helpers.neq +local eq = helpers.eq local run = helpers.run +local funcs = helpers.funcs +local nvim_prog = helpers.nvim_prog +local redir_exec = helpers.redir_exec +local wait = helpers.wait describe('v:exiting', function() local cid @@ -29,18 +33,53 @@ describe('v:exiting', function() end run(on_request, nil, on_setup) end) +end) - it('is non-zero after :cquit', function() - local function on_setup() - command('autocmd VimLeavePre * call rpcrequest('..cid..', "")') - command('autocmd VimLeave * call rpcrequest('..cid..', "")') - command('cquit') - end - local function on_request() - neq(0, eval('v:exiting')) - return '' +describe(':cquit', function() + local function test_cq(cmdline, exit_code, redir_msg) + if redir_msg then + eq('\n' .. redir_msg, redir_exec(cmdline)) + wait() + eq(2, eval("1+1")) -- Still alive? + else + funcs.system({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless', '--cmd', cmdline}) + eq(exit_code, eval('v:shell_error')) end - run(on_request, nil, on_setup) + end + + before_each(function() + helpers.clear() + end) + + it('exits with non-zero after :cquit', function() + test_cq('cquit', 1, nil) end) + it('exits with non-zero after :cquit 123', function() + test_cq('cquit 123', 123, nil) + end) + + it('exits with non-zero after :123 cquit', function() + test_cq('123 cquit', 123, nil) + end) + + it('exits with 0 after :cquit 0', function() + test_cq('cquit 0', 0, nil) + end) + + it('exits with 0 after :0 cquit', function() + test_cq('0 cquit', 0, nil) + end) + + it('exits with redir msg for multiple exit codes after :cquit 1 2', function() + test_cq('cquit 1 2', nil, 'E488: Trailing characters: cquit 1 2') + end) + + it('exits with redir msg for non-number exit code after :cquit X', function() + test_cq('cquit X', nil, 'E488: Trailing characters: cquit X') + end) + + it('exits with redir msg for negative exit code after :cquit -1', function() + test_cq('cquit -1', nil, 'E488: Trailing characters: cquit -1') + end) end) diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua index 54e56f7f41..1b8a5b1b95 100644 --- a/test/functional/core/job_spec.lua +++ b/test/functional/core/job_spec.lua @@ -677,12 +677,12 @@ describe("pty process teardown", function() -- Exiting should terminate all descendants (PTY, its children, ...). screen:expect([[ - | + ^ | [Process exited 0] | | | | - -- TERMINAL -- | + | ]]) end) end) diff --git a/test/functional/core/path_spec.lua b/test/functional/core/path_spec.lua new file mode 100644 index 0000000000..669bc99136 --- /dev/null +++ b/test/functional/core/path_spec.lua @@ -0,0 +1,56 @@ +local helpers = require('test.functional.helpers')(after_each) +local clear = helpers.clear +local eq = helpers.eq +local eval = helpers.eval +local command = helpers.command +local iswin = helpers.iswin + +describe('path collapse', function() + local targetdir + local expected_path + + local function join_path(...) + local pathsep = (iswin() and '\\' or '/') + return table.concat({...}, pathsep) + end + + before_each(function() + targetdir = join_path('test', 'functional', 'fixtures') + clear() + command('edit '..join_path(targetdir, 'tty-test.c')) + expected_path = eval('expand("%:p")') + end) + + it('with /./ segment #7117', function() + command('edit '..join_path(targetdir, '.', 'tty-test.c')) + eq(expected_path, eval('expand("%:p")')) + end) + + it('with ./ prefix #7117', function() + command('edit '..join_path('.', targetdir, 'tty-test.c')) + eq(expected_path, eval('expand("%:p")')) + end) + + it('with ./ prefix, after directory change #7117', function() + command('edit '..join_path('.', targetdir, 'tty-test.c')) + command('cd test') + eq(expected_path, eval('expand("%:p")')) + end) + + it('with /../ segment #7117', function() + command('edit '..join_path(targetdir, '..', 'fixtures', 'tty-test.c')) + eq(expected_path, eval('expand("%:p")')) + end) + + it('with ../ and different starting directory #7117', function() + command('cd test') + command('edit '..join_path('..', targetdir, 'tty-test.c')) + eq(expected_path, eval('expand("%:p")')) + end) + + it('with ./../ and different starting directory #7117', function() + command('cd test') + command('edit '..join_path('.', '..', targetdir, 'tty-test.c')) + eq(expected_path, eval('expand("%:p")')) + end) +end) diff --git a/test/functional/eval/input_spec.lua b/test/functional/eval/input_spec.lua index 74ad32bc6c..1e6b107c60 100644 --- a/test/functional/eval/input_spec.lua +++ b/test/functional/eval/input_spec.lua @@ -23,10 +23,41 @@ before_each(function() function CustomListCompl(...) return ['FOO'] endfunction + + highlight RBP1 guibg=Red + highlight RBP2 guibg=Yellow + highlight RBP3 guibg=Green + highlight RBP4 guibg=Blue + let g:NUM_LVLS = 4 + function Redraw() + redraw! + return '' + endfunction + cnoremap <expr> {REDRAW} Redraw() + function RainBowParens(cmdline) + let ret = [] + let i = 0 + let lvl = 0 + while i < len(a:cmdline) + if a:cmdline[i] is# '(' + call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)]) + let lvl += 1 + elseif a:cmdline[i] is# ')' + let lvl -= 1 + call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)]) + endif + let i += 1 + endwhile + return ret + endfunction ]]) screen:set_default_attr_ids({ EOB={bold = true, foreground = Screen.colors.Blue1}, T={foreground=Screen.colors.Red}, + RBP1={background=Screen.colors.Red}, + RBP2={background=Screen.colors.Yellow}, + RBP3={background=Screen.colors.Green}, + RBP4={background=Screen.colors.Blue}, }) end) @@ -196,6 +227,37 @@ describe('input()', function() eq('Vim(call):E118: Too many arguments for function: input', exc_exec('call input("prompt> ", "default", "file", "extra")')) end) + it('supports highlighting', function() + command('nnoremap <expr> X input({"highlight": "RainBowParens"})[-1]') + feed([[X]]) + feed('(())') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {RBP1:(}{RBP2:()}{RBP1:)}^ | + ]]) + end) + it('is not hidden by :silent', function() + feed([[:silent call input('Foo: ')<CR>]]) + screen:expect([[ + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + Foo: ^ | + | + ]]) + feed('Bar') + screen:expect([[ + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + Foo: Bar^ | + | + ]]) + feed('<CR>') + end) end) describe('inputdialog()', function() it('works with multiline prompts', function() @@ -363,4 +425,16 @@ describe('inputdialog()', function() eq('Vim(call):E118: Too many arguments for function: inputdialog', exc_exec('call inputdialog("prompt> ", "default", "file", "extra")')) end) + it('supports highlighting', function() + command('nnoremap <expr> X inputdialog({"highlight": "RainBowParens"})[-1]') + feed([[X]]) + feed('(())') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {RBP1:(}{RBP2:()}{RBP1:)}^ | + ]]) + end) end) diff --git a/test/functional/ex_cmds/menu_spec.lua b/test/functional/ex_cmds/menu_spec.lua index 55da8da8dc..2c0535acda 100644 --- a/test/functional/ex_cmds/menu_spec.lua +++ b/test/functional/ex_cmds/menu_spec.lua @@ -107,7 +107,7 @@ describe('menu_get', function() sid = 1, noremap = 1, enabled = 1, - rhs = "inormal\27", + rhs = "inormal<Esc>", silent = 0 }, v = { @@ -242,7 +242,7 @@ describe('menu_get', function() sid = 1, noremap = 1, enabled = 1, - rhs = "\18\"", + rhs = "<C-R>\"", silent = 0 }, n = { @@ -379,5 +379,251 @@ describe('menu_get', function() } eq(expected, m) end) +end) + +describe('menu_get', function() + + before_each(function() + clear() + end) + + it('returns <keycode> representation of special keys', function() + command('nnoremenu &Test.Test inormal<ESC>') + command('inoremenu &Test.Test2 <Tab><Esc>') + command('vnoremenu &Test.Test3 yA<C-R>0<Tab>xyz<Esc>') + command('inoremenu &Test.Test4 <c-r>*') + command('inoremenu &Test.Test5 <c-R>+') + command('nnoremenu &Test.Test6 <Nop>') + command('nnoremenu &Test.Test7 <NOP>') + command('nnoremenu &Test.Test8 <NoP>') + command('nnoremenu &Test.Test9 ""') + + local m = funcs.menu_get(""); + local expected = { + { + shortcut = "T", + hidden = 0, + submenus = { + { + priority = 500, + mappings = { + n = { + sid = 1, + noremap = 1, + enabled = 1, + rhs = "inormal<Esc>", + silent = 0 + } + }, + name = "Test", + hidden = 0 + }, + { + priority = 500, + mappings = { + i = { + sid = 1, + noremap = 1, + enabled = 1, + rhs = "<Tab><Esc>", + silent = 0 + } + }, + name = "Test2", + hidden = 0 + }, + { + priority = 500, + mappings = { + s = { + sid = 1, + noremap = 1, + enabled = 1, + rhs = "yA<C-R>0<Tab>xyz<Esc>", + silent = 0 + }, + v = { + sid = 1, + noremap = 1, + enabled = 1, + rhs = "yA<C-R>0<Tab>xyz<Esc>", + silent = 0 + } + }, + name = "Test3", + hidden = 0 + }, + { + priority = 500, + mappings = { + i = { + sid = 1, + noremap = 1, + enabled = 1, + rhs = "<C-R>*", + silent = 0 + } + }, + name = "Test4", + hidden = 0 + }, + { + priority = 500, + mappings = { + i = { + sid = 1, + noremap = 1, + enabled = 1, + rhs = "<C-R>+", + silent = 0 + } + }, + name = "Test5", + hidden = 0 + }, + { + priority = 500, + mappings = { + n = { + sid = 1, + noremap = 1, + enabled = 1, + rhs = "", + silent = 0 + } + }, + name = "Test6", + hidden = 0 + }, + { + priority = 500, + mappings = { + n = { + sid = 1, + noremap = 1, + enabled = 1, + rhs = "", + silent = 0 + } + }, + name = "Test7", + hidden = 0 + }, + { + priority = 500, + mappings = { + n = { + sid = 1, + noremap = 1, + enabled = 1, + rhs = "", + silent = 0 + } + }, + name = "Test8", + hidden = 0 + }, + { + priority = 500, + mappings = { + n = { + sid = 1, + noremap = 1, + enabled = 1, + rhs = "\"\"", + silent = 0 + } + }, + name = "Test9", + hidden = 0 + } + }, + priority = 500, + name = "Test" + } + } + + eq(m, expected) + end) + + it('works with right-aligned text and spaces', function() + command('nnoremenu &Test<Tab>Y.Test<Tab>X\\ x inormal<Alt-j>') + command('nnoremenu &Test\\ 1.Test\\ 2 Wargl') + command('nnoremenu &Test4.Test<Tab>3 i space<Esc>') + + local m = funcs.menu_get(""); + local expected = { + { + shortcut = "T", + hidden = 0, + actext = "Y", + submenus = { + { + mappings = { + n = { + sid = 1, + noremap = 1, + enabled = 1, + rhs = "inormal<Alt-j>", + silent = 0 + } + }, + hidden = 0, + actext = "X x", + priority = 500, + name = "Test" + } + }, + priority = 500, + name = "Test" + }, + { + shortcut = "T", + hidden = 0, + submenus = { + { + priority = 500, + mappings = { + n = { + sid = 1, + noremap = 1, + enabled = 1, + rhs = "Wargl", + silent = 0 + } + }, + name = "Test 2", + hidden = 0 + } + }, + priority = 500, + name = "Test 1" + }, + { + shortcut = "T", + hidden = 0, + submenus = { + { + mappings = { + n = { + sid = 1, + noremap = 1, + enabled = 1, + rhs = "i space<Esc>", + silent = 0 + } + }, + hidden = 0, + actext = "3", + priority = 500, + name = "Test" + } + }, + priority = 500, + name = "Test4" + } + } + eq(m, expected) + end) end) diff --git a/test/functional/fixtures/autoload/provider/clipboard.vim b/test/functional/fixtures/autoload/provider/clipboard.vim index 411e095c71..6d777255c8 100644 --- a/test/functional/fixtures/autoload/provider/clipboard.vim +++ b/test/functional/fixtures/autoload/provider/clipboard.vim @@ -5,7 +5,13 @@ let s:methods = {} let g:cliplossy = 0 let g:cliperror = 0 +" Count how many times the clipboard was invoked. +let g:clip_called_get = 0 +let g:clip_called_set = 0 + function! s:methods.get(reg) + let g:clip_called_get += 1 + if g:cliperror return 0 end @@ -19,6 +25,8 @@ function! s:methods.get(reg) endfunction function! s:methods.set(lines, regtype, reg) + let g:clip_called_set += 1 + if a:reg == '"' call s:methods.set(a:lines,a:regtype,'+') call s:methods.set(a:lines,a:regtype,'*') diff --git a/test/functional/fixtures/tty-test.c b/test/functional/fixtures/tty-test.c index 7ba21d652a..edcbe23f86 100644 --- a/test/functional/fixtures/tty-test.c +++ b/test/functional/fixtures/tty-test.c @@ -5,42 +5,45 @@ #include <stdio.h> #include <stdlib.h> #include <uv.h> +#ifdef _WIN32 +# include <windows.h> +#else +# include <unistd.h> +#endif // -V:STRUCT_CAST:641 #define STRUCT_CAST(Type, obj) ((Type *)(obj)) +#define is_terminal(stream) (uv_guess_handle(fileno(stream)) == UV_TTY) +#define BUF_SIZE 0xfff +#define CTRL_C 0x03 uv_tty_t tty; +uv_tty_t tty_out; -#ifdef _WIN32 -#include <windows.h> bool owns_tty(void) { - HWND consoleWnd = GetConsoleWindow(); - DWORD dwProcessId; - GetWindowThreadProcessId(consoleWnd, &dwProcessId); - return GetCurrentProcessId() == dwProcessId; -} +#ifdef _WIN32 + // XXX: We need to make proper detect owns tty + // HWND consoleWnd = GetConsoleWindow(); + // DWORD dwProcessId; + // GetWindowThreadProcessId(consoleWnd, &dwProcessId); + // return GetCurrentProcessId() == dwProcessId; + return true; #else -#include <unistd.h> -bool owns_tty(void) -{ return getsid(0) == getpid(); -} #endif +} -#define is_terminal(stream) (uv_guess_handle(fileno(stream)) == UV_TTY) -#define BUF_SIZE 0xfff - -static void walk_cb(uv_handle_t *handle, void *arg) { +static void walk_cb(uv_handle_t *handle, void *arg) +{ if (!uv_is_closing(handle)) { uv_close(handle, NULL); } } -#ifndef WIN32 static void sig_handler(int signum) { - switch(signum) { + switch (signum) { case SIGWINCH: { int width, height; uv_tty_get_winsize(&tty, &width, &height); @@ -54,15 +57,15 @@ static void sig_handler(int signum) return; } } -#endif -// static void sigwinch_cb(uv_signal_t *handle, int signum) -// { -// int width, height; -// uv_tty_t *tty = handle->data; -// uv_tty_get_winsize(tty, &width, &height); -// fprintf(stderr, "rows: %d, cols: %d\n", height, width); -// } +#ifdef WIN32 +static void sigwinch_cb(uv_signal_t *handle, int signum) +{ + int width, height; + uv_tty_get_winsize(&tty_out, &width, &height); + fprintf(stderr, "rows: %d, cols: %d\n", height, width); +} +#endif static void alloc_cb(uv_handle_t *handle, size_t suggested, uv_buf_t *buf) { @@ -80,7 +83,7 @@ static void read_cb(uv_stream_t *stream, ssize_t cnt, const uv_buf_t *buf) int *interrupted = stream->data; for (int i = 0; i < cnt; i++) { - if (buf->base[i] == 3) { + if (buf->base[i] == CTRL_C) { (*interrupted)++; } } @@ -88,11 +91,13 @@ static void read_cb(uv_stream_t *stream, ssize_t cnt, const uv_buf_t *buf) uv_loop_t write_loop; uv_loop_init(&write_loop); uv_tty_t out; - uv_tty_init(&write_loop, &out, 1, 0); + uv_tty_init(&write_loop, &out, fileno(stdout), 0); + uv_write_t req; uv_buf_t b = {.base = buf->base, .len = (size_t)cnt}; uv_write(&req, STRUCT_CAST(uv_stream_t, &out), &b, 1, NULL); uv_run(&write_loop, UV_RUN_DEFAULT); + uv_close(STRUCT_CAST(uv_handle_t, &out), NULL); uv_run(&write_loop, UV_RUN_DEFAULT); if (uv_loop_close(&write_loop)) { @@ -137,7 +142,7 @@ int main(int argc, char **argv) if (argc > 1) { int count = atoi(argv[1]); - for (int i = 0; i < count; ++i) { + for (int i = 0; i < count; i++) { printf("line%d\n", i); } fflush(stdout); @@ -148,8 +153,14 @@ int main(int argc, char **argv) uv_prepare_t prepare; uv_prepare_init(uv_default_loop(), &prepare); uv_prepare_start(&prepare, prepare_cb); - // uv_tty_t tty; +#ifndef WIN32 uv_tty_init(uv_default_loop(), &tty, fileno(stderr), 1); +#else + uv_tty_init(uv_default_loop(), &tty, fileno(stdin), 1); + uv_tty_init(uv_default_loop(), &tty_out, fileno(stdout), 0); + int width, height; + uv_tty_get_winsize(&tty_out, &width, &height); +#endif uv_tty_set_mode(&tty, UV_TTY_MODE_RAW); tty.data = &interrupted; uv_read_start(STRUCT_CAST(uv_stream_t, &tty), alloc_cb, read_cb); @@ -160,15 +171,17 @@ int main(int argc, char **argv) sa.sa_handler = sig_handler; sigaction(SIGHUP, &sa, NULL); sigaction(SIGWINCH, &sa, NULL); - // uv_signal_t sigwinch_watcher; - // uv_signal_init(uv_default_loop(), &sigwinch_watcher); - // sigwinch_watcher.data = &tty; - // uv_signal_start(&sigwinch_watcher, sigwinch_cb, SIGWINCH); +#else + uv_signal_t sigwinch_watcher; + uv_signal_init(uv_default_loop(), &sigwinch_watcher); + uv_signal_start(&sigwinch_watcher, sigwinch_cb, SIGWINCH); #endif uv_run(uv_default_loop(), UV_RUN_DEFAULT); +#ifndef WIN32 // XXX: Without this the SIGHUP handler is skipped on some systems. sleep(100); +#endif return 0; } diff --git a/test/functional/legacy/003_cindent_spec.lua b/test/functional/legacy/003_cindent_spec.lua index 27835fea28..58e87354fb 100644 --- a/test/functional/legacy/003_cindent_spec.lua +++ b/test/functional/legacy/003_cindent_spec.lua @@ -15,6 +15,8 @@ local function insert_(content) feed_command('1', 'set cin ts=4 sw=4') end +-- luacheck: ignore 621 (Indentation) +-- luacheck: ignore 613 (Trailing whitespace in a string) describe('cindent', function() before_each(clear) @@ -3915,6 +3917,26 @@ describe('cindent', function() { 111111111111111111; } + namespace test::cpp17 + { + 111111111111111111; + } + namespace ::incorrectcpp17 + { + 111111111111111111; + } + namespace test::incorrectcpp17:: + { + 111111111111111111; + } + namespace test:incorrectcpp17 + { + 111111111111111111; + } + namespace test:::incorrectcpp17 + { + 111111111111111111; + } namespace{ 111111111111111111; } @@ -3986,6 +4008,26 @@ describe('cindent', function() { 111111111111111111; } + namespace test::cpp17 + { + 111111111111111111; + } + namespace ::incorrectcpp17 + { + 111111111111111111; + } + namespace test::incorrectcpp17:: + { + 111111111111111111; + } + namespace test:incorrectcpp17 + { + 111111111111111111; + } + namespace test:::incorrectcpp17 + { + 111111111111111111; + } namespace{ 111111111111111111; } @@ -4676,4 +4718,38 @@ describe('cindent', function() JSEND ]=]) end) + + it('line continuations in macros / vim-patch 8.0.0148', function() + insert_([=[ + /* start of define */ + { + } + #define AAA \ + BBB\ + CCC + + #define CNT \ + 1 + \ + 2 + \ + 4 + /* end of define */]=]) + + feed_command('set cino&') + feed_command('/start of define') + feed('=/end of define<cr>') + + expect([=[ + /* start of define */ + { + } + #define AAA \ + BBB\ + CCC + + #define CNT \ + 1 + \ + 2 + \ + 4 + /* end of define */]=]) + end) end) diff --git a/test/functional/legacy/005_bufleave_delete_buffer_spec.lua b/test/functional/legacy/005_bufleave_delete_buffer_spec.lua index 417842c52d..8b92c877a6 100644 --- a/test/functional/legacy/005_bufleave_delete_buffer_spec.lua +++ b/test/functional/legacy/005_bufleave_delete_buffer_spec.lua @@ -9,6 +9,7 @@ local wait = helpers.wait describe('test5', function() setup(clear) + -- luacheck: ignore 621 (Indentation) it('is working', function() insert([[ start of test file Xxx diff --git a/test/functional/legacy/006_argument_list_spec.lua b/test/functional/legacy/006_argument_list_spec.lua index dac58df8a5..9f75a91fa8 100644 --- a/test/functional/legacy/006_argument_list_spec.lua +++ b/test/functional/legacy/006_argument_list_spec.lua @@ -78,8 +78,8 @@ describe('argument list', function() end) teardown(function() - os.remove('Xxx1') - os.remove('Xxx2') - os.remove('Xxx3') + os.remove('Xxx1') + os.remove('Xxx2') + os.remove('Xxx3') end) end) diff --git a/test/functional/legacy/007_ball_buffer_list_spec.lua b/test/functional/legacy/007_ball_buffer_list_spec.lua index 8501faabec..a180e73301 100644 --- a/test/functional/legacy/007_ball_buffer_list_spec.lua +++ b/test/functional/legacy/007_ball_buffer_list_spec.lua @@ -36,10 +36,10 @@ describe(':ball', function() -- Open window for all args, close Xxx2 feed('$r4:ball<cr>') - + -- Write contents of this file feed_command('%yank A') - + -- Append contents of second window (Xxx1) feed('') feed_command('%yank A') diff --git a/test/functional/legacy/011_autocommands_spec.lua b/test/functional/legacy/011_autocommands_spec.lua index e01af4583b..d969a8bd37 100644 --- a/test/functional/legacy/011_autocommands_spec.lua +++ b/test/functional/legacy/011_autocommands_spec.lua @@ -94,6 +94,8 @@ describe('file reading, writing and bufnew and filter autocommands', function() eq(gzip_data, io.open('Xtestfile.gz'):read('*all')) end) + -- luacheck: ignore 621 (Indentation) + -- luacheck: ignore 611 (Line contains only whitespaces) it('FileReadPre, FileReadPost', function() prepare_gz_file('Xtestfile', text1) feed_command('au! FileReadPre *.gz exe "silent !gzip -d " . shellescape(expand("<afile>"))') diff --git a/test/functional/legacy/015_alignment_spec.lua b/test/functional/legacy/015_alignment_spec.lua index 8423aa3d11..d73ff06972 100644 --- a/test/functional/legacy/015_alignment_spec.lua +++ b/test/functional/legacy/015_alignment_spec.lua @@ -9,6 +9,7 @@ local clear, feed_command, expect = helpers.clear, helpers.feed_command, helpers describe('alignment', function() setup(clear) + -- luacheck: ignore 621 (Indentation) it('is working', function() insert([[ test for :left @@ -112,7 +113,7 @@ describe('alignment', function() asxa;ofa axxxoikey asdfaqwer axxxoikey - xxxxx xx xxxxxx + xxxxx xx xxxxxx xxxxxxx xxxxxxxxx xxx xxxx xxxxx xxxxx xxx xx xxxxxxxxxxxxxxxxxx xxxxx xxxx, xxxx xxxx xxxx xxxx xxx xx xx xx xxxxxxx. xxxx xxxx. diff --git a/test/functional/legacy/019_smarttab_expandtab_spec.lua b/test/functional/legacy/019_smarttab_expandtab_spec.lua index ecb24885bb..7b03ee8e99 100644 --- a/test/functional/legacy/019_smarttab_expandtab_spec.lua +++ b/test/functional/legacy/019_smarttab_expandtab_spec.lua @@ -8,6 +8,7 @@ local clear, feed_command, expect = helpers.clear, helpers.feed_command, helpers describe([[performing "r<Tab>" with 'smarttab' and 'expandtab' set/not set, and "dv_"]], function() setup(clear) + -- luacheck: ignore 621 (Indentation) it('is working', function() insert([[ start text diff --git a/test/functional/legacy/029_join_spec.lua b/test/functional/legacy/029_join_spec.lua index 460b9291bf..b28f276a7c 100644 --- a/test/functional/legacy/029_join_spec.lua +++ b/test/functional/legacy/029_join_spec.lua @@ -11,6 +11,8 @@ local feed_command = helpers.feed_command describe('joining lines', function() before_each(clear) + -- luacheck: ignore 613 (Trailing whitespaces in a string) + -- luacheck: ignore 611 (Line contains only whitespaces) it("keeps marks with different 'joinspaces' settings", function() insert([[ firstline diff --git a/test/functional/legacy/033_lisp_indent_spec.lua b/test/functional/legacy/033_lisp_indent_spec.lua index 2b79ee024b..5132333a5c 100644 --- a/test/functional/legacy/033_lisp_indent_spec.lua +++ b/test/functional/legacy/033_lisp_indent_spec.lua @@ -9,6 +9,7 @@ local wait = helpers.wait describe('lisp indent', function() setup(clear) + -- luacheck: ignore 621 (Indentation) it('is working', function() insert([[ (defun html-file (base) @@ -22,7 +23,7 @@ describe('lisp indent', function() :if-exists :supersede) (let ((,ti ,title)) (as title ,ti) - (with center + (with center (as h2 (string-upcase ,ti))) (brs 3) ,@body)))) @@ -58,7 +59,7 @@ describe('lisp indent', function() :if-exists :supersede) (let ((,ti ,title)) (as title ,ti) - (with center + (with center (as h2 (string-upcase ,ti))) (brs 3) ,@body)))) diff --git a/test/functional/legacy/038_virtual_replace_spec.lua b/test/functional/legacy/038_virtual_replace_spec.lua index 2dfc959a8c..8dd7bdda6e 100644 --- a/test/functional/legacy/038_virtual_replace_spec.lua +++ b/test/functional/legacy/038_virtual_replace_spec.lua @@ -7,6 +7,7 @@ local clear, feed_command, expect = helpers.clear, helpers.feed_command, helpers describe('Virtual replace mode', function() setup(clear) + -- luacheck: ignore 621 (Indentation) it('is working', function() -- Make sure that backspace works, no matter what termcap is used. feed_command('set t_kD=x7f t_kb=x08') diff --git a/test/functional/legacy/039_visual_block_mode_commands_spec.lua b/test/functional/legacy/039_visual_block_mode_commands_spec.lua index dffef50950..135058c579 100644 --- a/test/functional/legacy/039_visual_block_mode_commands_spec.lua +++ b/test/functional/legacy/039_visual_block_mode_commands_spec.lua @@ -43,6 +43,7 @@ describe('Visual block mode', function() abcdqqqqijklm]]) end) + -- luacheck: ignore 611 (Line contains only whitespaces) it('should insert a block using cursor keys for movement', function() insert([[ aaaaaa @@ -104,6 +105,7 @@ describe('Visual block mode', function() 456ab7]]) end) + -- luacheck: ignore 621 (Indentation) it('should insert and append a block when virtualedit=all', function() insert([[ line1 diff --git a/test/functional/legacy/051_highlight_spec.lua b/test/functional/legacy/051_highlight_spec.lua index 60d29246ff..2ef74196ee 100644 --- a/test/functional/legacy/051_highlight_spec.lua +++ b/test/functional/legacy/051_highlight_spec.lua @@ -37,6 +37,7 @@ describe(':highlight', function() feed('q') wait() -- wait until we're back to normal command('hi Search') + command('hi Normal') -- Test setting colors. -- Test clearing one color and all doesn't generate error or warning diff --git a/test/functional/legacy/055_list_and_dict_types_spec.lua b/test/functional/legacy/055_list_and_dict_types_spec.lua index e84c415eb0..dcbd8b7dff 100644 --- a/test/functional/legacy/055_list_and_dict_types_spec.lua +++ b/test/functional/legacy/055_list_and_dict_types_spec.lua @@ -191,6 +191,7 @@ describe('list and dictionary types', function() [3]]=]) end) + -- luacheck: ignore 613 (Trailing whitespace in a string) it('assignment to a list', function() source([[ let l = [0, 1, 2, 3] diff --git a/test/functional/legacy/060_exists_and_has_functions_spec.lua b/test/functional/legacy/060_exists_and_has_functions_spec.lua index 3e99f6df57..1794f23b3a 100644 --- a/test/functional/legacy/060_exists_and_has_functions_spec.lua +++ b/test/functional/legacy/060_exists_and_has_functions_spec.lua @@ -12,7 +12,7 @@ describe('exists() and has() functions', function() write_file('test60.vim', [[ " Vim script for exists() function test " Script-local variables are checked here - + " Existing script-local variable let s:script_var = 1 echo 's:script_var: 1' @@ -21,7 +21,7 @@ describe('exists() and has() functions', function() else echo "FAILED" endif - + " Non-existing script-local variable unlet s:script_var echo 's:script_var: 0' @@ -30,7 +30,7 @@ describe('exists() and has() functions', function() else echo "FAILED" endif - + " Existing script-local list let s:script_list = ["blue", "orange"] echo 's:script_list: 1' @@ -39,7 +39,7 @@ describe('exists() and has() functions', function() else echo "FAILED" endif - + " Non-existing script-local list unlet s:script_list echo 's:script_list: 0' @@ -48,7 +48,7 @@ describe('exists() and has() functions', function() else echo "FAILED" endif - + " Existing script-local dictionary let s:script_dict = {"xcord":100, "ycord":2} echo 's:script_dict: 1' @@ -57,7 +57,7 @@ describe('exists() and has() functions', function() else echo "FAILED" endif - + " Non-existing script-local dictionary unlet s:script_dict echo 's:script_dict: 0' @@ -66,7 +66,7 @@ describe('exists() and has() functions', function() else echo "FAILED" endif - + " Existing script curly-brace variable let str = "script" let s:curly_{str}_var = 1 @@ -76,7 +76,7 @@ describe('exists() and has() functions', function() else echo "FAILED" endif - + " Non-existing script-local curly-brace variable unlet s:curly_{str}_var echo 's:curly_' . str . '_var: 0' @@ -85,21 +85,21 @@ describe('exists() and has() functions', function() else echo "FAILED" endif - + " Existing script-local function function! s:my_script_func() endfunction - + echo '*s:my_script_func: 1' if exists('*s:my_script_func') echo "OK" else echo "FAILED" endif - + " Non-existing script-local function delfunction s:my_script_func - + echo '*s:my_script_func: 0' if !exists('*s:my_script_func') echo "OK" @@ -644,7 +644,7 @@ describe('exists() and has() functions', function() -- Assert buffer contents. expect([[ - + #myagroup: 1 OK #myagroup+b: 0 diff --git a/test/functional/legacy/066_visual_block_tab_spec.lua b/test/functional/legacy/066_visual_block_tab_spec.lua index 7c4984362f..f10152d8ea 100644 --- a/test/functional/legacy/066_visual_block_tab_spec.lua +++ b/test/functional/legacy/066_visual_block_tab_spec.lua @@ -15,7 +15,7 @@ describe('visual block shift and tab characters', function() one two three one two three one two three - + abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz @@ -49,7 +49,7 @@ describe('visual block shift and tab characters', function() on1 two three on1 two three on1 two three - + abcdefghijklmnopqrstuvwxyz abcdefghij abc defghijklmnopqrstuvwxyz diff --git a/test/functional/legacy/068_text_formatting_spec.lua b/test/functional/legacy/068_text_formatting_spec.lua index 772dbc14cf..3a1b21bf87 100644 --- a/test/functional/legacy/068_text_formatting_spec.lua +++ b/test/functional/legacy/068_text_formatting_spec.lua @@ -9,6 +9,7 @@ local expect = helpers.expect describe('text formatting', function() setup(clear) + -- luacheck: ignore 613 (Trailing whitespace in a string) it('is working', function() -- The control character <C-A> (byte \x01) needs to be put in the buffer -- directly. But the insert function sends the text to nvim in insert diff --git a/test/functional/legacy/069_multibyte_formatting_spec.lua b/test/functional/legacy/069_multibyte_formatting_spec.lua index 38ca25d57a..9c248e3aa8 100644 --- a/test/functional/legacy/069_multibyte_formatting_spec.lua +++ b/test/functional/legacy/069_multibyte_formatting_spec.lua @@ -27,7 +27,7 @@ describe('multibyte text', function() XYZ abc XYZ - + XYZ abc XYZ @@ -62,7 +62,7 @@ describe('multibyte text', function() Y X Y - + X X a @@ -125,7 +125,7 @@ describe('multibyte text', function() ab X Y - + X X a @@ -166,7 +166,7 @@ describe('multibyte text', function() X X a - + X X a @@ -190,7 +190,7 @@ describe('multibyte text', function() X X a - + X X a @@ -239,7 +239,7 @@ describe('multibyte text', function() XX XXa XXY - + X Xa Xa @@ -259,7 +259,7 @@ describe('multibyte text', function() it('formatting in replace mode', function() insert([[ { - + }]]) feed_command('/^{/+1') feed_command('set tw=2 fo=tm') diff --git a/test/functional/legacy/078_swapfile_recover_spec.lua b/test/functional/legacy/078_swapfile_recover_spec.lua index 4390ba2ca8..45f0aed37a 100644 --- a/test/functional/legacy/078_swapfile_recover_spec.lua +++ b/test/functional/legacy/078_swapfile_recover_spec.lua @@ -22,32 +22,32 @@ describe('78', function() let linecount = 10000 while i <= linecount | call append(i - 1, i . text) | let i += 1 | endwhile preserve - + " Get the name of the swap file, and clean up the :redir capture. redir => g:swapname | swapname | redir END let g:swapname = substitute(g:swapname, '[[:blank:][:cntrl:]]*\(.\{-}\)[[:blank:][:cntrl:]]*$', '\1', 'g') let g:swapname = fnameescape(g:swapname) - + " Make a copy of the swap file in Xswap set bin exe 'sp ' . g:swapname w! Xswap - + set nobin new only! bwipe! Xtest call rename('Xswap', g:swapname) - + "TODO(jkeyes): without 'silent', this hangs the test " at message: " 'Recovery completed. You should check if everything is OK.' silent recover Xtest - + call delete(g:swapname) new call append(0, 'recovery start') wincmd w - + let g:linedollar = line('$') if g:linedollar < linecount wincmd w @@ -56,7 +56,7 @@ describe('78', function() wincmd w let linecount = g:linedollar endif - + let i = 1 while i <= linecount if getline(i) != i . text @@ -72,7 +72,7 @@ describe('78', function() expect([[ recovery start - + recovery end]]) end) end) diff --git a/test/functional/legacy/081_coptions_movement_spec.lua b/test/functional/legacy/081_coptions_movement_spec.lua index 993aff2ba2..d82c46a3d3 100644 --- a/test/functional/legacy/081_coptions_movement_spec.lua +++ b/test/functional/legacy/081_coptions_movement_spec.lua @@ -7,6 +7,7 @@ local feed_command, expect = helpers.feed_command, helpers.expect describe('coptions', function() setup(clear) + -- luacheck: ignore 613 (Trailing whitespace in a string) it('is working', function() insert([[ aaa two three four diff --git a/test/functional/legacy/082_string_comparison_spec.lua b/test/functional/legacy/082_string_comparison_spec.lua index cfc0b96bce..311822c34f 100644 --- a/test/functional/legacy/082_string_comparison_spec.lua +++ b/test/functional/legacy/082_string_comparison_spec.lua @@ -115,9 +115,9 @@ describe('case-insensitive string comparison in UTF-8', function() -- Assert buffer contents. expect([=[ 3732 checks passed - + ABCD - + defg]=]) end) end) diff --git a/test/functional/legacy/084_curswant_spec.lua b/test/functional/legacy/084_curswant_spec.lua index 9809ce5b88..42cb2fc56d 100644 --- a/test/functional/legacy/084_curswant_spec.lua +++ b/test/functional/legacy/084_curswant_spec.lua @@ -7,6 +7,7 @@ local clear, expect = helpers.clear, helpers.expect describe('curswant', function() setup(clear) + -- luacheck: ignore 621 (Indentation) it('is working', function() insert([[ start target options diff --git a/test/functional/legacy/088_conceal_tabs_spec.lua b/test/functional/legacy/088_conceal_tabs_spec.lua index c9414679ab..a4c7e26583 100644 --- a/test/functional/legacy/088_conceal_tabs_spec.lua +++ b/test/functional/legacy/088_conceal_tabs_spec.lua @@ -12,6 +12,7 @@ end describe('cursor and column position with conceal and tabulators', function() setup(clear) + -- luacheck: ignore 621 (Indentation) it('are working', function() insert([[ start: diff --git a/test/functional/legacy/089_number_relnumber_findfile_spec.lua b/test/functional/legacy/089_number_relnumber_findfile_spec.lua index 7a87fc8603..6708fd50b7 100644 --- a/test/functional/legacy/089_number_relnumber_findfile_spec.lua +++ b/test/functional/legacy/089_number_relnumber_findfile_spec.lua @@ -63,26 +63,26 @@ describe("setting 'number' and 'relativenumber'", function() -- Assert buffer contents. expect([[ results: - + number relativenumber - + number relativenumber :setlocal must NOT reset the other global value - + number - + relativenumber :setglobal MUST reset the other global value - + number - + relativenumber :set MUST reset the other global value - + number - + relativenumber]]) end) end) @@ -108,7 +108,7 @@ describe('findfile', function() expect([[ Testing findfile - + src/nvim/api/vim.c api/vim.c api/vim.c]]) diff --git a/test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua b/test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua index 44f1664abe..3c46c29951 100644 --- a/test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua +++ b/test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua @@ -15,6 +15,7 @@ describe('store cursor position in session file in UTF-8', function() os.remove('test.out') end) + -- luacheck: ignore 621 (Indentation) it('is working', function() insert([[ start: diff --git a/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua b/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua index 49bc43f76f..b1221ff8b6 100644 --- a/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua +++ b/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua @@ -17,6 +17,7 @@ describe('store cursor position in session file in Latin-1', function() os.remove('test.out') end) + -- luacheck: ignore 621 (Indentation) it('is working', function() insert([[ start: diff --git a/test/functional/legacy/094_visual_mode_operators_spec.lua b/test/functional/legacy/094_visual_mode_operators_spec.lua index 84e384050a..ff1d3e7bec 100644 --- a/test/functional/legacy/094_visual_mode_operators_spec.lua +++ b/test/functional/legacy/094_visual_mode_operators_spec.lua @@ -372,6 +372,7 @@ describe('Visual mode and operator', function() end) end) + -- luacheck: ignore 613 (Trailing whitespace in a string) it('gv in exclusive select mode after operation', function() source([[ $put ='zzz ' diff --git a/test/functional/legacy/103_visual_mode_reset_spec.lua b/test/functional/legacy/103_visual_mode_reset_spec.lua index d05b47fa32..f5cd861019 100644 --- a/test/functional/legacy/103_visual_mode_reset_spec.lua +++ b/test/functional/legacy/103_visual_mode_reset_spec.lua @@ -32,7 +32,7 @@ describe('E315 error', function() -- :del the ex-way will require the colon operator which resets the -- visual mode thus preventing the problem: feed('GV:call TriggerTheProblem()<cr>') - + source([[ %del _ call append(line('$'), g:msg) @@ -41,7 +41,7 @@ describe('E315 error', function() -- Assert buffer contents. expect([[ - + Everything's fine.]]) end) end) diff --git a/test/functional/legacy/106_errorformat_spec.lua b/test/functional/legacy/106_errorformat_spec.lua index 5d76adc786..3f017a704f 100644 --- a/test/functional/legacy/106_errorformat_spec.lua +++ b/test/functional/legacy/106_errorformat_spec.lua @@ -15,9 +15,9 @@ describe('errorformat', function() command("$put =strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))") command("cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']") command("$put =strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))") - + expect([=[ - + [['W', 1], ['E^@CCCC', 1]] [['W', 1], ['E^@CCCC', 1]] [['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]]=]) diff --git a/test/functional/legacy/108_backtrace_debug_commands_spec.lua b/test/functional/legacy/108_backtrace_debug_commands_spec.lua index b2e2fa4ed3..ff1917e90c 100644 --- a/test/functional/legacy/108_backtrace_debug_commands_spec.lua +++ b/test/functional/legacy/108_backtrace_debug_commands_spec.lua @@ -89,18 +89,18 @@ describe('108', function() -- Assert buffer contents. expect([=[ - - - + + + - show backtrace: - + 2 function Foo[2] 1 Bar[2] ->0 Bazz line 2: let var3 = "another var" - + show variables on different levels: - + 6 2 function Foo[2] ->1 Bar[2] @@ -112,9 +112,9 @@ describe('108', function() 0 Bazz line 2: let var3 = "another var" 1 - + - undefined vars: - + undefined var3 on former level: Error detected while processing function Foo[2]..Bar[2]..Bazz: line 3: @@ -122,7 +122,7 @@ describe('108', function() E15: Invalid expression: var3 here var3 is defined with "another var": another var - + undefined var2 on former level Error detected while processing function Foo[2]..Bar: line 3: @@ -130,37 +130,37 @@ describe('108', function() E15: Invalid expression: var2 here var2 is defined with 10: 10 - + - backtrace movements: - + 1 function Foo[2] ->0 Bar line 3: End of function - + next command cannot go down, we are on bottom - + frame is zero - + next command cannot go up, we are on top - + frame at highest level: 1 ->1 function Foo[2] 0 Bar line 3: End of function fil is not frame or finish, it is file "[No Name]" --No lines in buffer-- - + - relative backtrace movement - + 1 function Foo[2] ->0 Bar line 3: End of function ->1 function Foo[2] 0 Bar line 3: End of function - + - go beyond limits does not crash - + frame at highest level: 1 ->1 function Foo[2] 0 Bar @@ -169,7 +169,7 @@ describe('108', function() 1 function Foo[2] ->0 Bar line 3: End of function - + - final result 19: 19 ]=]) diff --git a/test/functional/legacy/assert_spec.lua b/test/functional/legacy/assert_spec.lua index d646e8dbf4..381461dc4f 100644 --- a/test/functional/legacy/assert_spec.lua +++ b/test/functional/legacy/assert_spec.lua @@ -89,7 +89,7 @@ describe('assert function:', function() it('should change v:errors when expected is equal to actual', function() call('assert_notequal', 'foo', 'foo') - expected_errors({"Expected 'foo' differs from 'foo'"}) + expected_errors({"Expected not equal to 'foo'"}) end) end) diff --git a/test/functional/legacy/breakindent_spec.lua b/test/functional/legacy/breakindent_spec.lua index 7594dba16c..fd25e809e0 100644 --- a/test/functional/legacy/breakindent_spec.lua +++ b/test/functional/legacy/breakindent_spec.lua @@ -7,6 +7,9 @@ local clear, feed_command, expect = helpers.clear, helpers.feed_command, helpers describe('breakindent', function() setup(clear) + -- luacheck: ignore 621 (Indentation) + -- luacheck: ignore 613 (Trailing whitespace in a string) + -- luacheck: ignore 611 (Line contains only whitespaces) it('is working', function() insert('dummy text') diff --git a/test/functional/legacy/command_count_spec.lua b/test/functional/legacy/command_count_spec.lua index ad5368430a..8707c0459c 100644 --- a/test/functional/legacy/command_count_spec.lua +++ b/test/functional/legacy/command_count_spec.lua @@ -4,6 +4,7 @@ local helpers = require('test.functional.helpers')(after_each) local clear, source, expect = helpers.clear, helpers.source, helpers.expect local feed_command = helpers.feed_command +-- luacheck: ignore 613 (Trailing whitespace in a string) describe('command_count', function() it('is working', function() -- It is relevant for the test to load a file initially. If this is @@ -133,8 +134,8 @@ describe('command_count', function() let g:lines = [] func BufStatus() call add(g:lines, - \ 'aaa: ' . buflisted(g:buf_aaa) . - \ ' bbb: ' . buflisted(g:buf_bbb) . + \ 'aaa: ' . buflisted(g:buf_aaa) . + \ ' bbb: ' . buflisted(g:buf_bbb) . \ ' ccc: ' . buflisted(g:buf_ccc)) endfunc se nohidden @@ -214,7 +215,7 @@ describe('command_count', function() RangeTabsAll 1 5 RangeLines 2 5 LocalRangeLines 2 5 - + 5argu E16: Invalid range 4argu d 1argu a @@ -225,7 +226,7 @@ describe('command_count', function() $tabe 2 $+tabe E16: Invalid range 0tabm x - + aaa: 1 bbb: 1 ccc: 1 aaa: 1 bbb: 0 ccc: 0 aaa: 0 bbb: 0 ccc: 0 diff --git a/test/functional/legacy/erasebackword_spec.lua b/test/functional/legacy/erasebackword_spec.lua index 33b7704b65..8ca64df328 100644 --- a/test/functional/legacy/erasebackword_spec.lua +++ b/test/functional/legacy/erasebackword_spec.lua @@ -6,6 +6,7 @@ local clear, feed, expect = helpers.clear, helpers.feed, helpers.expect describe('CTRL-W in Insert mode', function() setup(clear) + -- luacheck: ignore 611 (Line contains only whitespaces) it('works for multi-byte characters', function() for i = 1, 6 do diff --git a/test/functional/legacy/increment_spec.lua b/test/functional/legacy/increment_spec.lua index 15273a4ad5..d51f9a2e02 100644 --- a/test/functional/legacy/increment_spec.lua +++ b/test/functional/legacy/increment_spec.lua @@ -685,7 +685,7 @@ describe('Ctrl-A/Ctrl-X on visual selections', function() " Text: " 1 23 " 4 56 - " + " " Expected: " 1) f2 Ctrl-V jl <ctrl-a>, repeat twice afterwards with . " 1 26 diff --git a/test/functional/legacy/listchars_spec.lua b/test/functional/legacy/listchars_spec.lua index 3c0fa48e76..cffb9fd376 100644 --- a/test/functional/legacy/listchars_spec.lua +++ b/test/functional/legacy/listchars_spec.lua @@ -4,12 +4,14 @@ local helpers = require('test.functional.helpers')(after_each) local feed, insert, source = helpers.feed, helpers.insert, helpers.source local clear, feed_command, expect = helpers.clear, helpers.feed_command, helpers.expect +-- luacheck: ignore 621 (Indentation) describe("'listchars'", function() before_each(function() clear() feed_command('set listchars&vi') end) + -- luacheck: ignore 613 (Trailing whitespace in a string) it("works with 'list'", function() source([[ function GetScreenCharsForLine(lnum) diff --git a/test/functional/legacy/listlbr_spec.lua b/test/functional/legacy/listlbr_spec.lua index d39125c9e6..f70d55f4a3 100644 --- a/test/functional/legacy/listlbr_spec.lua +++ b/test/functional/legacy/listlbr_spec.lua @@ -7,6 +7,9 @@ local clear, feed_command, expect = helpers.clear, helpers.feed_command, helpers describe('listlbr', function() setup(clear) + -- luacheck: ignore 621 (Indentation) + -- luacheck: ignore 611 (Line contains only whitespaces) + -- luacheck: ignore 613 (Trailing whitespaces in a string) it('is working', function() insert([[ dummy text]]) @@ -20,20 +23,20 @@ describe('listlbr', function() feed_command('set ts=4 sw=4 sts=4 linebreak sbr=+ wrap') source([[ fu! ScreenChar(width) - let c='' - for j in range(1,4) - for i in range(1,a:width) - let c.=nr2char(screenchar(j, i)) - endfor - let c.="\n" - endfor - return c + let c='' + for j in range(1,4) + for i in range(1,a:width) + let c.=nr2char(screenchar(j, i)) + endfor + let c.="\n" + endfor + return c endfu fu! DoRecordScreen() - wincmd l - $put =printf(\"\n%s\", g:test) - $put =g:line - wincmd p + wincmd l + $put =printf(\"\n%s\", g:test) + $put =g:line + wincmd p endfu ]]) feed_command('let g:test="Test 1: set linebreak"') diff --git a/test/functional/legacy/listlbr_utf8_spec.lua b/test/functional/legacy/listlbr_utf8_spec.lua index f06bca72ba..d7f4c71af2 100644 --- a/test/functional/legacy/listlbr_utf8_spec.lua +++ b/test/functional/legacy/listlbr_utf8_spec.lua @@ -8,6 +8,8 @@ local clear, expect = helpers.clear, helpers.expect describe('linebreak', function() setup(clear) + -- luacheck: ignore 621 (Indentation) + -- luacheck: ignore 613 (Trailing whitespaces in a string) it('is working', function() source([[ set wildchar=^E @@ -18,20 +20,20 @@ describe('linebreak', function() norm! zt set ts=4 sw=4 sts=4 linebreak sbr=+ wrap fu! ScreenChar(width, lines) - let c='' - for j in range(1,a:lines) - for i in range(1,a:width) - let c.=nr2char(screenchar(j, i)) - endfor + let c='' + for j in range(1,a:lines) + for i in range(1,a:width) + let c.=nr2char(screenchar(j, i)) + endfor let c.="\n" - endfor - return c + endfor + return c endfu fu! DoRecordScreen() - wincmd l - $put =printf(\"\n%s\", g:test) - $put =g:line - wincmd p + wincmd l + $put =printf(\"\n%s\", g:test) + $put =g:line + wincmd p endfu " let g:test ="Test 1: set linebreak + set list + fancy listchars" @@ -148,22 +150,22 @@ describe('linebreak', function() -- Assert buffer contents. expect([[ - + abcdef hijklmn pqrstuvwxyz 1060ABCDEFGHIJKLMNOP - + Test 1: set linebreak + set list + fancy listchars ▕———abcdef +hijklmn▕——— +pqrstuvwxyz␣1060ABC +DEFGHIJKLMNOPˑ¶ - + Test 2: set nolinebreak list ▕———abcdef hijklmn▕— +pqrstuvwxyz␣1060ABC +DEFGHIJKLMNOPˑ¶ ¶ *mask = nil; - + Test 3: set linebreak nolist *mask = nil; ~ @@ -177,7 +179,7 @@ describe('linebreak', function() #define MSG_MODE_CONSOLE 2 #define MSG_MODE_FILE_AND_CONSOLE 3 #define MSG_MODE_FILE_THEN_CONSOLE 4 - + Test 4: set linebreak list listchars and concealing #define ABCDE>-->---1 #define >CDEF>-->---1 @@ -187,7 +189,7 @@ describe('linebreak', function() #define >_CONSOLE>---------->---2 #define >_FILE_AND_CONSOLE>---------3 bbeeeeee ; some text - + Test 5: set linebreak list listchars and concealing part2 eeeeee>--->-;>some text Test 6: Screenattributes for comment @@ -196,10 +198,10 @@ describe('linebreak', function() Attribut 0 and 1 and 3 and 5 are different! Test 8: set linebreak with visual block mode and v_b_A and selection=exclusive and multibyte char long line: foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar TARGETÃx' at end - + a b c a b c - + Test 9: a multibyte sign and colorcolumn ¶ +a b c¶ diff --git a/test/functional/legacy/marks_spec.lua b/test/functional/legacy/marks_spec.lua index bcec179ca2..470ea49652 100644 --- a/test/functional/legacy/marks_spec.lua +++ b/test/functional/legacy/marks_spec.lua @@ -7,6 +7,7 @@ describe('marks', function() clear() end) + -- luacheck: ignore 621 (Indentation) it('restores a deleted mark after delete-undo-redo-undo', function() insert([[ diff --git a/test/functional/legacy/options_spec.lua b/test/functional/legacy/options_spec.lua index 4f4d4ceaf9..1db7afc7a7 100644 --- a/test/functional/legacy/options_spec.lua +++ b/test/functional/legacy/options_spec.lua @@ -21,7 +21,7 @@ describe('set', function() $put =&path]]) expect([[ - + foo,,bar]]) end) end) diff --git a/test/functional/legacy/packadd_spec.lua b/test/functional/legacy/packadd_spec.lua index c280888dda..2dfd36142b 100644 --- a/test/functional/legacy/packadd_spec.lua +++ b/test/functional/legacy/packadd_spec.lua @@ -83,6 +83,41 @@ describe('packadd', function() call assert_equal(new_rtp, &rtp) endfunc + func Test_packadd_symlink_dir() + if !has('unix') + return + endif + let top2_dir = s:topdir . '/Xdir2' + let real_dir = s:topdir . '/Xsym' + call mkdir(real_dir, 'p') + exec "silent! !ln -s Xsym" top2_dir + let &rtp = top2_dir . ',' . top2_dir . '/after' + let &packpath = &rtp + + let s:plugdir = top2_dir . '/pack/mine/opt/mytest' + call mkdir(s:plugdir . '/plugin', 'p') + + exe 'split ' . s:plugdir . '/plugin/test.vim' + call setline(1, 'let g:plugin_works = 44') + wq + let g:plugin_works = 0 + + packadd mytest + + " Must have been inserted in the middle, not at the end + call assert_true(&rtp =~ '/pack/mine/opt/mytest,') + call assert_equal(44, g:plugin_works) + + " No change when doing it again. + let rtp_before = &rtp + packadd mytest + call assert_equal(rtp_before, &rtp) + + set rtp& + let rtp = &rtp + exec "silent !rm" top2_dir + endfunc + func Test_packloadall() " plugin foo with an autoload directory let fooplugindir = &packpath . '/pack/mine/start/foo/plugin' @@ -137,9 +172,9 @@ describe('packadd', function() helptags ALL - let tags1 = readfile(docdir1 . '/tags') + let tags1 = readfile(docdir1 . '/tags') call assert_true(tags1[0] =~ 'look-here') - let tags2 = readfile(docdir2 . '/tags') + let tags2 = readfile(docdir2 . '/tags') call assert_true(tags2[0] =~ 'look-away') endfunc @@ -227,6 +262,11 @@ describe('packadd', function() expected_empty() end) + it('works with symlinks', function() + call('Test_packadd_symlink_dir') + expected_empty() + end) + it('works with :packloadall', function() call('Test_packloadall') expected_empty() diff --git a/test/functional/legacy/tagcase_spec.lua b/test/functional/legacy/tagcase_spec.lua index ed2876a375..9ca0e0009f 100644 --- a/test/functional/legacy/tagcase_spec.lua +++ b/test/functional/legacy/tagcase_spec.lua @@ -53,11 +53,11 @@ describe("'tagcase' option", function() -- Verify that the correct number of matching tags is found for all values of -- 'ignorecase' and global and local values 'tagcase', in all combinations. insert([[ - + Foo Bar foo - + end text]]) source([[ @@ -70,7 +70,7 @@ describe("'tagcase' option", function() endfor endfor endfor - + 1,/^end text$/d]]) expect([[ diff --git a/test/functional/legacy/utf8_spec.lua b/test/functional/legacy/utf8_spec.lua index 02de6ab735..5b93f25b24 100644 --- a/test/functional/legacy/utf8_spec.lua +++ b/test/functional/legacy/utf8_spec.lua @@ -54,6 +54,7 @@ describe('utf8', function() eq(1, eval('strchars("\\u20dd", 1)')) end) + -- luacheck: ignore 613 (Trailing whitespace in a string) it('customlist completion', function() source([[ function! CustomComplete1(lead, line, pos) diff --git a/test/functional/lua/utility_functions_spec.lua b/test/functional/lua/utility_functions_spec.lua index 9855a05e8c..d5756e134d 100644 --- a/test/functional/lua/utility_functions_spec.lua +++ b/test/functional/lua/utility_functions_spec.lua @@ -12,9 +12,10 @@ describe('vim.stricmp', function() -- length 2 (in bytes). -- Ⱥ: `tolower("Ⱥ")` is `ⱥ` which has length 2 while `Ⱥ` itself has -- length 3 (in bytes). - -- For some reason 'i' !=? 'İ' and 'ⱥ' !=? 'Ⱥ' on some systems. Also built-in - -- Neovim comparison (i.e. when there is no strcasecmp) works only on ASCII - -- characters. + -- + -- Note: 'i' !=? 'İ' and 'ⱥ' !=? 'Ⱥ' on some systems. + -- Note: Built-in Nvim comparison (on systems lacking `strcasecmp`) works + -- only on ASCII characters. it('works', function() eq(0, funcs.luaeval('vim.stricmp("a", "A")')) eq(0, funcs.luaeval('vim.stricmp("A", "a")')) diff --git a/test/functional/plugin/health_spec.lua b/test/functional/plugin/health_spec.lua index 3739540b09..b5374210e6 100644 --- a/test/functional/plugin/health_spec.lua +++ b/test/functional/plugin/health_spec.lua @@ -1,7 +1,30 @@ local helpers = require('test.functional.helpers')(after_each) +local Screen = require('test.functional.ui.screen') local plugin_helpers = require('test.functional.plugin.helpers') +local clear = helpers.clear +local curbuf_contents = helpers.curbuf_contents local command = helpers.command +local eq = helpers.eq + +describe(':checkhealth', function() + it("detects invalid $VIMRUNTIME", function() + clear({ + env={ VIMRUNTIME='bogus', }, + }) + local status, err = pcall(command, 'checkhealth') + eq(false, status) + eq('Invalid $VIMRUNTIME: bogus', string.match(err, 'Invalid.*')) + end) + it("detects invalid $VIM", function() + clear() + -- Do this after startup, otherwise it just breaks $VIMRUNTIME. + command("let $VIM='zub'") + command("checkhealth nvim") + eq("ERROR: $VIM is invalid: zub", + string.match(curbuf_contents(), "ERROR: $VIM .* zub")) + end) +end) describe('health.vim', function() before_each(function() @@ -13,7 +36,7 @@ describe('health.vim', function() command("set runtimepath+=test/functional/fixtures") end) - it("reports", function() + it("health#report_*()", function() helpers.source([[ let g:health_report = execute([ \ "call health#report_start('Check Bar')", @@ -30,41 +53,41 @@ describe('health.vim', function() ## Check Bar - - SUCCESS: Bar status - - SUCCESS: Other Bar status + - OK: Bar status + - OK: Other Bar status - WARNING: Zub ## Baz - WARNING: Zim - - SUGGESTIONS: + - ADVICE: - suggestion 1 - suggestion 2]]), result) end) - describe(":CheckHealth", function() + describe(":checkhealth", function() it("concatenates multiple reports", function() - command("CheckHealth success1 success2") + command("checkhealth success1 success2") helpers.expect([[ health#success1#check ======================================================================== ## report 1 - - SUCCESS: everything is fine + - OK: everything is fine ## report 2 - - SUCCESS: nothing to see here + - OK: nothing to see here health#success2#check ======================================================================== ## another 1 - - SUCCESS: ok + - OK: ok ]]) end) it("gracefully handles broken healthcheck", function() - command("CheckHealth broken") + command("checkhealth broken") helpers.expect([[ health#broken#check @@ -75,8 +98,38 @@ describe('health.vim', function() ]]) end) + it("highlights OK, ERROR", function() + local screen = Screen.new(72, 10) + screen:attach() + screen:set_default_attr_ids({ + Ok = { foreground = Screen.colors.Grey3, background = 6291200 }, + Error = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + }) + screen:set_default_attr_ignore({ + Heading = { bold=true, foreground=Screen.colors.Magenta }, + Heading2 = { foreground = Screen.colors.SlateBlue }, + Bar = { foreground=Screen.colors.Purple }, + Bullet = { bold=true, foreground=Screen.colors.Brown }, + }) + command("checkhealth foo success1") + command("1tabclose") + command("set laststatus=0") + screen:expect([[ + ^ | + health#foo#check | + ========================================================================| + - {Error:ERROR:} No healthcheck found for "foo" plugin. | + | + health#success1#check | + ========================================================================| + ## report 1 | + - {Ok:OK:} everything is fine | + | + ]]) + end) + it("gracefully handles invalid healthcheck", function() - command("CheckHealth non_existent_healthcheck") + command("checkhealth non_existent_healthcheck") helpers.expect([[ health#non_existent_healthcheck#check diff --git a/test/functional/provider/ruby_spec.lua b/test/functional/provider/ruby_spec.lua index 9f5ef3b3fc..c70f90da1c 100644 --- a/test/functional/provider/ruby_spec.lua +++ b/test/functional/provider/ruby_spec.lua @@ -16,7 +16,7 @@ do clear() if missing_provider('ruby') then pending( - "Cannot find the neovim RubyGem. Try :CheckHealth", + "Cannot find the neovim RubyGem. Try :checkhealth", function() end) return end diff --git a/test/functional/shada/compatibility_spec.lua b/test/functional/shada/compatibility_spec.lua index 1287ac010c..a5ef60d91f 100644 --- a/test/functional/shada/compatibility_spec.lua +++ b/test/functional/shada/compatibility_spec.lua @@ -10,6 +10,13 @@ local read_shada_file = shada_helpers.read_shada_file local wshada, sdrcmd, shada_fname = get_shada_rw('Xtest-functional-shada-compatibility.shada') +local mock_file_path = '/a/b/' +local mock_file_path2 = '/d/e/' +if helpers.iswin() then + mock_file_path = 'C:/a/' + mock_file_path2 = 'C:/d/' +end + describe('ShaDa forward compatibility support code', function() before_each(reset) after_each(function() @@ -114,14 +121,14 @@ describe('ShaDa forward compatibility support code', function() funcs.garbagecollect(1) end) - for _, v in ipairs({{name='global mark', mpack='\007\001\018\131\162mX\195\161f\196\006/a/b/c\161nA'}, - {name='jump', mpack='\008\001\018\131\162mX\195\161f\196\006/a/b/c\161l\002'}, - {name='local mark', mpack='\010\001\018\131\162mX\195\161f\196\006/a/b/c\161na'}, - {name='change', mpack='\011\001\015\130\162mX\195\161f\196\006/a/b/c'}, + for _, v in ipairs({{name='global mark', mpack='\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161nA'}, + {name='jump', mpack='\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002'}, + {name='local mark', mpack='\010\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161na'}, + {name='change', mpack='\011\001\015\130\162mX\195\161f\196\006' .. mock_file_path .. 'c'}, }) do it('works with ' .. v.name .. ' item with BOOL unknown (mX) key value', function() - nvim_command('silent noautocmd edit /a/b/c') - eq('/a/b/c', funcs.bufname('%')) + nvim_command('silent noautocmd edit ' .. mock_file_path .. 'c') + eq('' .. mock_file_path .. 'c', funcs.bufname('%')) funcs.setline('.', {'1', '2', '3'}) wshada(v.mpack) eq(0, exc_exec(sdrcmd(true))) @@ -159,12 +166,12 @@ describe('ShaDa forward compatibility support code', function() if v.name == 'global mark' or v.name == 'local mark' then it('works with ' .. v.name .. ' item with <C-a> name', function() - nvim_command('silent noautocmd edit /a/b/c') - eq('/a/b/c', funcs.bufname('%')) + nvim_command('silent noautocmd edit ' .. mock_file_path .. 'c') + eq('' .. mock_file_path .. 'c', funcs.bufname('%')) funcs.setline('.', {'1', '2', '3'}) wshada(v.mpack:gsub('n.$', 'n\001') .. v.mpack:gsub('n.$', 'n\002') - .. v.mpack:gsub('n.$', 'n\003'):gsub('/a/b/c', '/d/e/f')) + .. v.mpack:gsub('n.$', 'n\003'):gsub('' .. mock_file_path .. 'c', '' .. mock_file_path2 .. 'f')) eq(0, exc_exec(sdrcmd(true))) nvim_command('wshada ' .. shada_fname) local found = 0 @@ -307,10 +314,10 @@ describe('ShaDa forward compatibility support code', function() it('works with buffer list item with BOOL unknown (bX) key', function() nvim_command('set shada+=%') - wshada('\009\000\016\145\130\161f\196\006/a/b/c\162bX\195') + wshada('\009\000\016\145\130\161f\196\006' .. mock_file_path .. 'c\162bX\195') eq(0, exc_exec(sdrcmd())) eq(2, funcs.bufnr('$')) - eq('/a/b/c', funcs.bufname(2)) + eq('' .. mock_file_path .. 'c', funcs.bufname(2)) os.remove(shada_fname) nvim_command('wshada ' .. shada_fname) local found = false diff --git a/test/functional/shada/merging_spec.lua b/test/functional/shada/merging_spec.lua index 25c73b99eb..7a15c8908b 100644 --- a/test/functional/shada/merging_spec.lua +++ b/test/functional/shada/merging_spec.lua @@ -13,6 +13,11 @@ local read_shada_file = shada_helpers.read_shada_file local wshada, sdrcmd, shada_fname = get_shada_rw('Xtest-functional-shada-merging.shada') +local mock_file_path = '/a/b/' +if helpers.iswin() then + mock_file_path = 'C:/a/' +end + describe('ShaDa history merging code', function() before_each(reset) after_each(function() @@ -512,9 +517,9 @@ describe('ShaDa marks support code', function() it('uses last A mark with gt timestamp from instance when reading', function() - wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA') + wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) - wshada('\007\000\018\131\162mX\195\161f\196\006/a/b/?\161nA') + wshada('\007\000\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') eq(0, exc_exec(sdrcmd())) nvim_command('normal! `A') eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t')) @@ -522,9 +527,9 @@ describe('ShaDa marks support code', function() it('uses last A mark with gt timestamp from file when reading with !', function() - wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA') + wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) - wshada('\007\000\018\131\162mX\195\161f\196\006/a/b/?\161nA') + wshada('\007\000\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') eq(0, exc_exec(sdrcmd(true))) nvim_command('normal! `A') eq('?', funcs.fnamemodify(curbufmeths.get_name(), ':t')) @@ -532,9 +537,9 @@ describe('ShaDa marks support code', function() it('uses last A mark with eq timestamp from instance when reading', function() - wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA') + wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) - wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/?\161nA') + wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') eq(0, exc_exec(sdrcmd())) nvim_command('normal! `A') eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t')) @@ -542,9 +547,9 @@ describe('ShaDa marks support code', function() it('uses last A mark with gt timestamp from file when reading', function() - wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA') + wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) - wshada('\007\002\018\131\162mX\195\161f\196\006/a/b/?\161nA') + wshada('\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') eq(0, exc_exec(sdrcmd())) nvim_command('normal! `A') eq('?', funcs.fnamemodify(curbufmeths.get_name(), ':t')) @@ -552,15 +557,15 @@ describe('ShaDa marks support code', function() it('uses last A mark with gt timestamp from instance when writing', function() - wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA') + wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) - wshada('\007\000\018\131\162mX\195\161f\196\006/a/b/?\161nA') + wshada('\007\000\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') nvim_command('normal! `A') eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 7 and v.value.f == '/a/b/-' then + if v.type == 7 and v.value.f == '' .. mock_file_path .. '-' then found = found + 1 end end @@ -569,15 +574,15 @@ describe('ShaDa marks support code', function() it('uses last A mark with eq timestamp from instance when writing', function() - wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA') + wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) - wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/?\161nA') + wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') nvim_command('normal! `A') eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 7 and v.value.f == '/a/b/-' then + if v.type == 7 and v.value.f == mock_file_path .. '-' then found = found + 1 end end @@ -586,15 +591,15 @@ describe('ShaDa marks support code', function() it('uses last A mark with gt timestamp from file when writing', function() - wshada('\007\001\018\131\162mX\195\161f\196\006/a/b/-\161nA') + wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA') eq(0, exc_exec(sdrcmd())) - wshada('\007\002\018\131\162mX\195\161f\196\006/a/b/?\161nA') + wshada('\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA') nvim_command('normal! `A') eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 7 and v.value.f == '/a/b/?' then + if v.type == 7 and v.value.f == '' .. mock_file_path .. '?' then found = found + 1 end end @@ -603,11 +608,11 @@ describe('ShaDa marks support code', function() it('uses last a mark with gt timestamp from instance when reading', function() - nvim_command('edit /a/b/-') + nvim_command('edit ' .. mock_file_path .. '-') funcs.setline(1, {'-', '?'}) - wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na') + wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) - wshada('\010\000\017\131\161l\002\161f\196\006/a/b/-\161na') + wshada('\010\000\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) nvim_command('normal! `a') eq('-', funcs.getline('.')) @@ -615,11 +620,11 @@ describe('ShaDa marks support code', function() it('uses last a mark with gt timestamp from file when reading with !', function() - nvim_command('edit /a/b/-') + nvim_command('edit ' .. mock_file_path .. '-') funcs.setline(1, {'-', '?'}) - wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na') + wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) - wshada('\010\000\017\131\161l\002\161f\196\006/a/b/-\161na') + wshada('\010\000\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd(true))) nvim_command('normal! `a') eq('?', funcs.getline('.')) @@ -627,11 +632,11 @@ describe('ShaDa marks support code', function() it('uses last a mark with eq timestamp from instance when reading', function() - nvim_command('edit /a/b/-') + nvim_command('edit ' .. mock_file_path .. '-') funcs.setline(1, {'-', '?'}) - wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na') + wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) - wshada('\010\001\017\131\161l\002\161f\196\006/a/b/-\161na') + wshada('\010\001\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) nvim_command('normal! `a') eq('-', funcs.getline('.')) @@ -639,11 +644,11 @@ describe('ShaDa marks support code', function() it('uses last a mark with gt timestamp from file when reading', function() - nvim_command('edit /a/b/-') + nvim_command('edit ' .. mock_file_path .. '-') funcs.setline(1, {'-', '?'}) - wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na') + wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) - wshada('\010\002\017\131\161l\002\161f\196\006/a/b/-\161na') + wshada('\010\002\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) nvim_command('normal! `a') eq('?', funcs.getline('.')) @@ -651,17 +656,17 @@ describe('ShaDa marks support code', function() it('uses last a mark with gt timestamp from instance when writing', function() - nvim_command('edit /a/b/-') + nvim_command('edit ' .. mock_file_path .. '-') funcs.setline(1, {'-', '?'}) - wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na') + wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) - wshada('\010\000\017\131\161l\002\161f\196\006/a/b/-\161na') + wshada('\010\000\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') nvim_command('normal! `a') eq('-', funcs.getline('.')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 10 and v.value.f == '/a/b/-' and v.value.n == ('a'):byte() then + if v.type == 10 and v.value.f == '' .. mock_file_path .. '-' and v.value.n == ('a'):byte() then eq(true, v.value.l == 1 or v.value.l == nil) found = found + 1 end @@ -671,17 +676,17 @@ describe('ShaDa marks support code', function() it('uses last a mark with eq timestamp from instance when writing', function() - nvim_command('edit /a/b/-') + nvim_command('edit ' .. mock_file_path .. '-') funcs.setline(1, {'-', '?'}) - wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na') + wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) - wshada('\010\001\017\131\161l\002\161f\196\006/a/b/-\161na') + wshada('\010\001\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') nvim_command('normal! `a') eq('-', funcs.getline('.')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 10 and v.value.f == '/a/b/-' and v.value.n == ('a'):byte() then + if v.type == 10 and v.value.f == '' .. mock_file_path .. '-' and v.value.n == ('a'):byte() then eq(true, v.value.l == 1 or v.value.l == nil) found = found + 1 end @@ -691,17 +696,17 @@ describe('ShaDa marks support code', function() it('uses last a mark with gt timestamp from file when writing', function() - nvim_command('edit /a/b/-') + nvim_command('edit ' .. mock_file_path .. '-') funcs.setline(1, {'-', '?'}) - wshada('\010\001\017\131\161l\001\161f\196\006/a/b/-\161na') + wshada('\010\001\017\131\161l\001\161f\196\006' .. mock_file_path .. '-\161na') eq(0, exc_exec(sdrcmd())) - wshada('\010\002\017\131\161l\002\161f\196\006/a/b/-\161na') + wshada('\010\002\017\131\161l\002\161f\196\006' .. mock_file_path .. '-\161na') nvim_command('normal! `a') eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t')) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 10 and v.value.f == '/a/b/-' and v.value.n == ('a'):byte() then + if v.type == 10 and v.value.f == '' .. mock_file_path .. '-' and v.value.n == ('a'):byte() then eq(2, v.value.l) found = found + 1 end @@ -813,41 +818,41 @@ describe('ShaDa jumps support code', function() end) it('merges jumps when reading', function() - wshada('\008\001\018\131\162mX\195\161f\196\006/a/b/c\161l\002' - .. '\008\004\018\131\162mX\195\161f\196\006/a/b/d\161l\002' - .. '\008\007\018\131\162mX\195\161f\196\006/a/b/e\161l\002') + wshada('\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002' + .. '\008\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161l\002' + .. '\008\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'e\161l\002') eq(0, exc_exec(sdrcmd())) - wshada('\008\001\018\131\162mX\195\161f\196\006/a/b/c\161l\002' - .. '\008\004\018\131\162mX\195\161f\196\006/a/b/d\161l\003' - .. '\008\007\018\131\162mX\195\161f\196\006/a/b/f\161l\002') + wshada('\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002' + .. '\008\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161l\003' + .. '\008\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'f\161l\002') eq(0, exc_exec(sdrcmd())) eq('', curbufmeths.get_name()) eq('\n' .. ' jump line col file/text\n' - .. ' 6 2 0 /a/b/c\n' - .. ' 5 2 0 /a/b/d\n' - .. ' 4 3 0 /a/b/d\n' - .. ' 3 2 0 /a/b/e\n' - .. ' 2 2 0 /a/b/f\n' + .. ' 6 2 0 ' .. mock_file_path .. 'c\n' + .. ' 5 2 0 ' .. mock_file_path .. 'd\n' + .. ' 4 3 0 ' .. mock_file_path .. 'd\n' + .. ' 3 2 0 ' .. mock_file_path .. 'e\n' + .. ' 2 2 0 ' .. mock_file_path .. 'f\n' .. ' 1 1 0 \n' .. '>', redir_exec('jumps')) end) it('merges jumps when writing', function() - wshada('\008\001\018\131\162mX\195\161f\196\006/a/b/c\161l\002' - .. '\008\004\018\131\162mX\195\161f\196\006/a/b/d\161l\002' - .. '\008\007\018\131\162mX\195\161f\196\006/a/b/e\161l\002') + wshada('\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002' + .. '\008\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161l\002' + .. '\008\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'e\161l\002') eq(0, exc_exec(sdrcmd())) - wshada('\008\001\018\131\162mX\195\161f\196\006/a/b/c\161l\002' - .. '\008\004\018\131\162mX\195\161f\196\006/a/b/d\161l\003' - .. '\008\007\018\131\162mX\195\161f\196\006/a/b/f\161l\002') + wshada('\008\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002' + .. '\008\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161l\003' + .. '\008\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'f\161l\002') eq(0, exc_exec('wshada ' .. shada_fname)) local jumps = { - {file='/a/b/c', line=2}, - {file='/a/b/d', line=2}, - {file='/a/b/d', line=3}, - {file='/a/b/e', line=2}, - {file='/a/b/f', line=2}, + {file='' .. mock_file_path .. 'c', line=2}, + {file='' .. mock_file_path .. 'd', line=2}, + {file='' .. mock_file_path .. 'd', line=3}, + {file='' .. mock_file_path .. 'e', line=2}, + {file='' .. mock_file_path .. 'f', line=2}, } local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do @@ -864,9 +869,9 @@ describe('ShaDa jumps support code', function() local jumps = {} local shada = '' for i = 1,100 do - shada = shada .. ('\008%c\018\131\162mX\195\161f\196\006/a/b/c\161l%c' + shada = shada .. ('\008%c\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l%c' ):format(i, i) - jumps[i] = {file='/a/b/c', line=i} + jumps[i] = {file='' .. mock_file_path .. 'c', line=i} end wshada(shada) eq(0, exc_exec(sdrcmd())) @@ -874,9 +879,9 @@ describe('ShaDa jumps support code', function() for i = 1,101 do local t = i * 2 shada = shada .. ( - '\008\204%c\019\131\162mX\195\161f\196\006/a/b/c\161l\204%c' + '\008\204%c\019\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\204%c' ):format(t, t) - jumps[(t > #jumps + 1) and (#jumps + 1) or t] = {file='/a/b/c', line=t} + jumps[(t > #jumps + 1) and (#jumps + 1) or t] = {file='' .. mock_file_path .. 'c', line=t} end wshada(shada) eq(0, exc_exec('wshada ' .. shada_fname)) @@ -904,15 +909,15 @@ describe('ShaDa changes support code', function() end) it('merges changes when reading', function() - nvim_command('edit /a/b/c') + nvim_command('edit ' .. mock_file_path .. 'c') nvim_command('keepjumps call setline(1, range(7))') - wshada('\011\001\018\131\162mX\195\161f\196\006/a/b/c\161l\001' - .. '\011\004\018\131\162mX\195\161f\196\006/a/b/c\161l\002' - .. '\011\007\018\131\162mX\195\161f\196\006/a/b/c\161l\003') + wshada('\011\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\001' + .. '\011\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002' + .. '\011\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\003') eq(0, exc_exec(sdrcmd())) - wshada('\011\001\018\131\162mX\194\161f\196\006/a/b/c\161l\001' - .. '\011\004\018\131\162mX\195\161f\196\006/a/b/c\161l\005' - .. '\011\008\018\131\162mX\195\161f\196\006/a/b/c\161l\004') + wshada('\011\001\018\131\162mX\194\161f\196\006' .. mock_file_path .. 'c\161l\001' + .. '\011\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\005' + .. '\011\008\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\004') eq(0, exc_exec(sdrcmd())) eq('\n' .. 'change line col text\n' @@ -925,15 +930,15 @@ describe('ShaDa changes support code', function() end) it('merges changes when writing', function() - nvim_command('edit /a/b/c') + nvim_command('edit ' .. mock_file_path .. 'c') nvim_command('keepjumps call setline(1, range(7))') - wshada('\011\001\018\131\162mX\195\161f\196\006/a/b/c\161l\001' - .. '\011\004\018\131\162mX\195\161f\196\006/a/b/c\161l\002' - .. '\011\007\018\131\162mX\195\161f\196\006/a/b/c\161l\003') + wshada('\011\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\001' + .. '\011\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\002' + .. '\011\007\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\003') eq(0, exc_exec(sdrcmd())) - wshada('\011\001\018\131\162mX\194\161f\196\006/a/b/c\161l\001' - .. '\011\004\018\131\162mX\195\161f\196\006/a/b/c\161l\005' - .. '\011\008\018\131\162mX\195\161f\196\006/a/b/c\161l\004') + wshada('\011\001\018\131\162mX\194\161f\196\006' .. mock_file_path .. 'c\161l\001' + .. '\011\004\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\005' + .. '\011\008\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\004') eq(0, exc_exec('wshada ' .. shada_fname)) local changes = { {line=1}, @@ -944,7 +949,7 @@ describe('ShaDa changes support code', function() } local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 11 and v.value.f == '/a/b/c' then + if v.type == 11 and v.value.f == '' .. mock_file_path .. 'c' then found = found + 1 eq(changes[found].line, v.value.l or 1) end @@ -953,12 +958,12 @@ describe('ShaDa changes support code', function() end) it('merges JUMPLISTSIZE changes when writing', function() - nvim_command('edit /a/b/c') + nvim_command('edit ' .. mock_file_path .. 'c') nvim_command('keepjumps call setline(1, range(202))') local changes = {} local shada = '' for i = 1,100 do - shada = shada .. ('\011%c\018\131\162mX\195\161f\196\006/a/b/c\161l%c' + shada = shada .. ('\011%c\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l%c' ):format(i, i) changes[i] = {line=i} end @@ -968,7 +973,7 @@ describe('ShaDa changes support code', function() for i = 1,101 do local t = i * 2 shada = shada .. ( - '\011\204%c\019\131\162mX\195\161f\196\006/a/b/c\161l\204%c' + '\011\204%c\019\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\204%c' ):format(t, t) changes[(t > #changes + 1) and (#changes + 1) or t] = {line=t} end @@ -980,7 +985,7 @@ describe('ShaDa changes support code', function() end local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 11 and v.value.f == '/a/b/c' then + if v.type == 11 and v.value.f == '' .. mock_file_path .. 'c' then found = found + 1 eq(changes[found].line, v.value.l) end @@ -990,20 +995,20 @@ describe('ShaDa changes support code', function() it('merges JUMPLISTSIZE changes when writing, with new items between old', function() - nvim_command('edit /a/b/c') + nvim_command('edit ' .. mock_file_path .. 'c') nvim_command('keepjumps call setline(1, range(202))') local shada = '' for i = 1,101 do local t = i * 2 shada = shada .. ( - '\011\204%c\019\131\162mX\195\161f\196\006/a/b/c\161l\204%c' + '\011\204%c\019\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l\204%c' ):format(t, t) end wshada(shada) eq(0, exc_exec(sdrcmd())) shada = '' for i = 1,100 do - shada = shada .. ('\011%c\018\131\162mX\195\161f\196\006/a/b/c\161l%c' + shada = shada .. ('\011%c\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161l%c' ):format(i, i) end local changes = {} @@ -1022,7 +1027,7 @@ describe('ShaDa changes support code', function() end local found = 0 for _, v in ipairs(read_shada_file(shada_fname)) do - if v.type == 11 and v.value.f == '/a/b/c' then + if v.type == 11 and v.value.f == '' .. mock_file_path .. 'c' then found = found + 1 eq(changes[found].line, v.value.l) end @@ -1030,3 +1035,5 @@ describe('ShaDa changes support code', function() eq(found, 100) end) end) + +-- vim: ts=2 sw=2 diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua index 48b8512bf0..4ce33fef7b 100644 --- a/test/functional/terminal/buffer_spec.lua +++ b/test/functional/terminal/buffer_spec.lua @@ -6,8 +6,6 @@ local eval, feed_command, source = helpers.eval, helpers.feed_command, helpers.s local eq, neq = helpers.eq, helpers.neq local write_file = helpers.write_file -if helpers.pending_win32(pending) then return end - describe('terminal buffer', function() local screen @@ -160,6 +158,7 @@ describe('terminal buffer', function() end) it('handles loss of focus gracefully', function() + if helpers.pending_win32(pending) then return end -- Change the statusline to avoid printing the file name, which varies. nvim('set_option', 'statusline', '==========') feed_command('set laststatus=0') @@ -205,7 +204,6 @@ describe('terminal buffer', function() end) describe('No heap-buffer-overflow when using', function() - local testfilename = 'Xtestfile-functional-terminal-buffers_spec' before_each(function() diff --git a/test/functional/terminal/cursor_spec.lua b/test/functional/terminal/cursor_spec.lua index 84d0322f12..d49f1bfc23 100644 --- a/test/functional/terminal/cursor_spec.lua +++ b/test/functional/terminal/cursor_spec.lua @@ -7,8 +7,6 @@ local feed_command = helpers.feed_command local hide_cursor = thelpers.hide_cursor local show_cursor = thelpers.show_cursor -if helpers.pending_win32(pending) then return end - describe('terminal cursor', function() local screen diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua index be0fd9f8ff..e015df10db 100644 --- a/test/functional/terminal/ex_terminal_spec.lua +++ b/test/functional/terminal/ex_terminal_spec.lua @@ -3,10 +3,11 @@ local Screen = require('test.functional.ui.screen') local clear, wait, nvim = helpers.clear, helpers.wait, helpers.nvim local nvim_dir, source, eq = helpers.nvim_dir, helpers.source, helpers.eq local feed_command, eval = helpers.feed_command, helpers.eval - -if helpers.pending_win32(pending) then return end +local retry = helpers.retry +local iswin = helpers.iswin describe(':terminal', function() + if helpers.pending_win32(pending) then return end local screen before_each(function() @@ -70,19 +71,19 @@ describe(':terminal (with fake shell)', function() it('with no argument, acts like termopen()', function() terminal_with_fake_shell() - wait() + retry(3, 4 * screen.timeout, function() screen:expect([[ - ready $ | + ^ready $ | [Process exited 0] | | - -- TERMINAL -- | + :terminal | ]]) + end) end) it("with no argument, and 'shell' is set to empty string", function() nvim('set_option', 'shell', '') terminal_with_fake_shell() - wait() screen:expect([[ ^ | ~ | @@ -94,46 +95,42 @@ describe(':terminal (with fake shell)', function() it("with no argument, but 'shell' has arguments, acts like termopen()", function() nvim('set_option', 'shell', nvim_dir..'/shell-test -t jeff') terminal_with_fake_shell() - wait() screen:expect([[ - jeff $ | + ^jeff $ | [Process exited 0] | | - -- TERMINAL -- | + :terminal | ]]) end) it('executes a given command through the shell', function() terminal_with_fake_shell('echo hi') - wait() screen:expect([[ - ready $ echo hi | + ^ready $ echo hi | | [Process exited 0] | - -- TERMINAL -- | + :terminal echo hi | ]]) end) it("executes a given command through the shell, when 'shell' has arguments", function() nvim('set_option', 'shell', nvim_dir..'/shell-test -t jeff') terminal_with_fake_shell('echo hi') - wait() screen:expect([[ - jeff $ echo hi | + ^jeff $ echo hi | | [Process exited 0] | - -- TERMINAL -- | + :terminal echo hi | ]]) end) it('allows quotes and slashes', function() terminal_with_fake_shell([[echo 'hello' \ "world"]]) - wait() screen:expect([[ - ready $ echo 'hello' \ "world" | + ^ready $ echo 'hello' \ "world" | | [Process exited 0] | - -- TERMINAL -- | + :terminal echo 'hello' \ "world" | ]]) end) @@ -164,27 +161,29 @@ describe(':terminal (with fake shell)', function() it('works with :find', function() terminal_with_fake_shell() - wait() screen:expect([[ - ready $ | + ^ready $ | [Process exited 0] | | - -- TERMINAL -- | + :terminal | ]]) eq('term://', string.match(eval('bufname("%")'), "^term://")) helpers.feed([[<C-\><C-N>]]) feed_command([[find */shadacat.py]]) - eq('scripts/shadacat.py', eval('bufname("%")')) + if iswin() then + eq('scripts\\shadacat.py', eval('bufname("%")')) + else + eq('scripts/shadacat.py', eval('bufname("%")')) + end end) it('works with gf', function() terminal_with_fake_shell([[echo "scripts/shadacat.py"]]) - wait() screen:expect([[ - ready $ echo "scripts/shadacat.py" | + ^ready $ echo "scripts/shadacat.py" | | [Process exited 0] | - -- TERMINAL -- | + :terminal echo "scripts/shadacat.py" | ]]) helpers.feed([[<C-\><C-N>]]) eq('term://', string.match(eval('bufname("%")'), "^term://")) diff --git a/test/functional/terminal/helpers.lua b/test/functional/terminal/helpers.lua index 3b04d17705..bd24b9785d 100644 --- a/test/functional/terminal/helpers.lua +++ b/test/functional/terminal/helpers.lua @@ -33,7 +33,6 @@ local function disable_mouse() feed_termcode('[?1002l') end local default_command = '["'..nvim_dir..'/tty-test'..'"]' - local function screen_setup(extra_rows, command, cols) extra_rows = extra_rows and extra_rows or 0 command = command and command or default_command diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua index bb40770235..fddc0bbb71 100644 --- a/test/functional/terminal/highlight_spec.lua +++ b/test/functional/terminal/highlight_spec.lua @@ -5,8 +5,6 @@ local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim local nvim_dir, command = helpers.nvim_dir, helpers.command local eq, eval = helpers.eq, helpers.eval -if helpers.pending_win32(pending) then return end - describe('terminal window highlighting', function() local screen @@ -55,6 +53,7 @@ describe('terminal window highlighting', function() end) local function pass_attrs() + if helpers.pending_win32(pending) then return end screen:expect(sub([[ tty ready | {NUM:text}text{10: } | @@ -69,6 +68,7 @@ describe('terminal window highlighting', function() it('will pass the corresponding attributes', pass_attrs) it('will pass the corresponding attributes on scrollback', function() + if helpers.pending_win32(pending) then return end pass_attrs() local lines = {} for i = 1, 8 do @@ -145,6 +145,7 @@ describe('terminal window highlighting with custom palette', function() end) it('will use the custom color', function() + if helpers.pending_win32(pending) then return end thelpers.set_fg(3) thelpers.feed_data('text') thelpers.clear_attrs() diff --git a/test/functional/terminal/mouse_spec.lua b/test/functional/terminal/mouse_spec.lua index 9239c2ad31..29c62d7be7 100644 --- a/test/functional/terminal/mouse_spec.lua +++ b/test/functional/terminal/mouse_spec.lua @@ -4,8 +4,6 @@ local clear, eq, eval = helpers.clear, helpers.eq, helpers.eval local feed, nvim = helpers.feed, helpers.nvim local feed_data = thelpers.feed_data -if helpers.pending_win32(pending) then return end - describe('terminal mouse', function() local screen @@ -67,6 +65,7 @@ describe('terminal mouse', function() end) it('will forward mouse clicks to the program', function() + if helpers.pending_win32(pending) then return end feed('<LeftMouse><1,2>') screen:expect([[ line27 | @@ -80,6 +79,7 @@ describe('terminal mouse', function() end) it('will forward mouse scroll to the program', function() + if helpers.pending_win32(pending) then return end feed('<ScrollWheelUp><0,0>') screen:expect([[ line27 | @@ -94,6 +94,7 @@ describe('terminal mouse', function() end) describe('with a split window and other buffer', function() + if helpers.pending_win32(pending) then return end before_each(function() feed('<c-\\><c-n>:vsp<cr>') screen:expect([[ diff --git a/test/functional/terminal/scrollback_spec.lua b/test/functional/terminal/scrollback_spec.lua index 05f81295c2..af9b414311 100644 --- a/test/functional/terminal/scrollback_spec.lua +++ b/test/functional/terminal/scrollback_spec.lua @@ -3,6 +3,7 @@ local helpers = require('test.functional.helpers')(after_each) local thelpers = require('test.functional.terminal.helpers') local clear, eq, curbuf = helpers.clear, helpers.eq, helpers.curbuf local feed, nvim_dir, feed_command = helpers.feed, helpers.nvim_dir, helpers.feed_command +local iswin = helpers.iswin local eval = helpers.eval local command = helpers.command local wait = helpers.wait @@ -11,8 +12,6 @@ local curbufmeths = helpers.curbufmeths local nvim = helpers.nvim local feed_data = thelpers.feed_data -if helpers.pending_win32(pending) then return end - describe('terminal scrollback', function() local screen @@ -58,7 +57,7 @@ describe('terminal scrollback', function() end) end) - describe('with the cursor at the last row', function() + describe('with cursor at last row', function() before_each(function() feed_data({'line1', 'line2', 'line3', 'line4', ''}) screen:expect([[ @@ -139,16 +138,18 @@ describe('terminal scrollback', function() end) - describe('and the height is decreased by 1', function() + describe('and height decreased by 1', function() + if helpers.pending_win32(pending) then return end local function will_hide_top_line() - screen:try_resize(screen._width, screen._height - 1) + feed([[<C-\><C-N>:]]) -- Go to cmdline-mode, so cursor is at bottom. + screen:try_resize(screen._width - 2, screen._height - 1) screen:expect([[ - line2 | - line3 | - line4 | - rows: 5, cols: 30 | - {1: } | - {3:-- TERMINAL --} | + line2 | + line3 | + line4 | + rows: 5, cols: 28 | + {2: } | + :^ | ]]) end @@ -157,23 +158,23 @@ describe('terminal scrollback', function() describe('and then decreased by 2', function() before_each(function() will_hide_top_line() - screen:try_resize(screen._width, screen._height - 2) + screen:try_resize(screen._width - 2, screen._height - 2) end) it('will hide the top 3 lines', function() screen:expect([[ - rows: 5, cols: 30 | - rows: 3, cols: 30 | - {1: } | - {3:-- TERMINAL --} | + rows: 5, cols: 28 | + rows: 3, cols: 26 | + {2: } | + :^ | ]]) eq(8, curbuf('line_count')) - feed('<c-\\><c-n>3k') + feed([[<C-\><C-N>3k]]) screen:expect([[ - ^line4 | - rows: 5, cols: 30 | - rows: 3, cols: 30 | - | + ^line4 | + rows: 5, cols: 28 | + rows: 3, cols: 26 | + | ]]) end) end) @@ -181,6 +182,11 @@ describe('terminal scrollback', function() end) describe('with empty lines after the cursor', function() + -- XXX: Can't test this reliably on Windows unless the cursor is _moved_ + -- by the resize. http://docs.libuv.org/en/v1.x/signal.html + -- See also: https://github.com/rprichard/winpty/issues/110 + if helpers.pending_win32(pending) then return end + describe('and the height is decreased by 2', function() before_each(function() screen:try_resize(screen._width, screen._height - 2) @@ -255,6 +261,10 @@ describe('terminal scrollback', function() end) describe('and the height is increased by 1', function() + -- XXX: Can't test this reliably on Windows unless the cursor is _moved_ + -- by the resize. http://docs.libuv.org/en/v1.x/signal.html + -- See also: https://github.com/rprichard/winpty/issues/110 + if helpers.pending_win32(pending) then return end local function pop_then_push() screen:try_resize(screen._width, screen._height + 1) screen:expect([[ @@ -384,10 +394,20 @@ describe("'scrollback' option", function() end it('set to 0 behaves as 1', function() - local screen = thelpers.screen_setup(nil, "['sh']", 30) + local screen + if iswin() then + screen = thelpers.screen_setup(nil, + "['powershell.exe', '-NoLogo', '-NoProfile', '-NoExit', '-Command', 'function global:prompt {return "..'"$"'.."}']", 30) + else + screen = thelpers.screen_setup(nil, "['sh']", 30) + end curbufmeths.set_option('scrollback', 0) - feed_data('for i in $(seq 1 30); do echo "line$i"; done\n') + if iswin() then + feed_data('for($i=1;$i -le 30;$i++){Write-Host \"line$i\"}\r') + else + feed_data('for i in $(seq 1 30); do echo "line$i"; done\n') + end screen:expect('line30 ', nil, nil, nil, true) retry(nil, nil, function() expect_lines(7) end) @@ -395,7 +415,13 @@ describe("'scrollback' option", function() end) it('deletes lines (only) if necessary', function() - local screen = thelpers.screen_setup(nil, "['sh']", 30) + local screen + if iswin() then + screen = thelpers.screen_setup(nil, + "['powershell.exe', '-NoLogo', '-NoProfile', '-NoExit', '-Command', 'function global:prompt {return "..'"$"'.."}']", 30) + else + screen = thelpers.screen_setup(nil, "['sh']", 30) + end curbufmeths.set_option('scrollback', 200) @@ -403,7 +429,11 @@ describe("'scrollback' option", function() screen:expect('$', nil, nil, nil, true) wait() - feed_data('for i in $(seq 1 30); do echo "line$i"; done\n') + if iswin() then + feed_data('for($i=1;$i -le 30;$i++){Write-Host \"line$i\"}\r') + else + feed_data('for i in $(seq 1 30); do echo "line$i"; done\n') + end screen:expect('line30 ', nil, nil, nil, true) @@ -416,7 +446,11 @@ describe("'scrollback' option", function() -- Terminal job data is received asynchronously, may happen before the -- 'scrollback' option is synchronized with the internal sb_buffer. command('sleep 100m') - feed_data('for i in $(seq 1 40); do echo "line$i"; done\n') + if iswin() then + feed_data('for($i=1;$i -le 40;$i++){Write-Host \"line$i\"}\r') + else + feed_data('for i in $(seq 1 40); do echo "line$i"; done\n') + end screen:expect('line40 ', nil, nil, nil, true) diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index 21b907c8f7..d36eb46e54 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -1,5 +1,6 @@ --- Some sanity checks for the TUI using the builtin terminal emulator --- as a simple way to send keys and assert screen state. +-- TUI acceptance tests. +-- Uses :terminal as a way to send keys and assert screen state. +local global_helpers = require('test.helpers') local helpers = require('test.functional.helpers')(after_each) local thelpers = require('test.functional.terminal.helpers') local feed_data = thelpers.feed_data @@ -194,7 +195,7 @@ describe('tui with non-tty file descriptors', function() end) end) -describe('tui focus event handling', function() +describe('tui FocusGained/FocusLost', function() local screen before_each(function() @@ -206,7 +207,8 @@ describe('tui focus event handling', function() feed_data("\034\016") -- CTRL-\ CTRL-N end) - it('can handle focus events in normal mode', function() + it('in normal-mode', function() + retry(2, 3 * screen.timeout, function() feed_data('\027[I') screen:expect([[ {1: } | @@ -228,11 +230,13 @@ describe('tui focus event handling', function() lost | {3:-- TERMINAL --} | ]]) + end) end) - it('can handle focus events in insert mode', function() + it('in insert-mode', function() feed_command('set noshowmode') feed_data('i') + retry(2, 3 * screen.timeout, function() feed_data('\027[I') screen:expect([[ {1: } | @@ -253,9 +257,12 @@ describe('tui focus event handling', function() lost | {3:-- TERMINAL --} | ]]) + end) end) - it('can handle focus events in cmdline mode', function() + -- During cmdline-mode we ignore :echo invoked by timers/events. + -- See commit: 5cc87d4dabd02167117be7a978b5c8faaa975419. + it('in cmdline-mode does NOT :echo', function() feed_data(':') feed_data('\027[I') screen:expect([[ @@ -264,7 +271,7 @@ describe('tui focus event handling', function() {4:~ }| {4:~ }| {5:[No Name] }| - g{1:a}ined | + :{1: } | {3:-- TERMINAL --} | ]]) feed_data('\027[O') @@ -274,21 +281,52 @@ describe('tui focus event handling', function() {4:~ }| {4:~ }| {5:[No Name] }| - l{1:o}st | + :{1: } | {3:-- TERMINAL --} | ]]) end) - it('can handle focus events in terminal mode', function() + it('in cmdline-mode', function() + -- Set up autocmds that modify the buffer, instead of just calling :echo. + -- This is how we can test handling of focus gained/lost during cmdline-mode. + -- See commit: 5cc87d4dabd02167117be7a978b5c8faaa975419. + feed_data(":autocmd!\n") + feed_data(":autocmd FocusLost * call append(line('$'), 'lost')\n") + feed_data(":autocmd FocusGained * call append(line('$'), 'gained')\n") + retry(2, 3 * screen.timeout, function() + -- Enter cmdline-mode. + feed_data(':') + screen:sleep(1) + -- Send focus lost/gained termcodes. + feed_data('\027[O') + feed_data('\027[I') + screen:sleep(1) + -- Exit cmdline-mode. Redraws from timers/events are blocked during + -- cmdline-mode, so the buffer won't be updated until we exit cmdline-mode. + feed_data('\n') + screen:expect([[ + {1: } | + lost | + gained | + {4:~ }| + {5:[No Name] [+] }| + : | + {3:-- TERMINAL --} | + ]]) + end) + end) + + it('in terminal-mode', function() feed_data(':set shell='..nvim_dir..'/shell-test\n') feed_data(':set noshowmode laststatus=0\n') retry(2, 3 * screen.timeout, function() feed_data(':terminal\n') + screen:sleep(1) feed_data('\027[I') screen:expect([[ - ready $ | - [Process exited 0]{1: } | + {1:r}eady $ | + [Process exited 0] | | | | @@ -297,8 +335,8 @@ describe('tui focus event handling', function() ]]) feed_data('\027[O') screen:expect([[ - ready $ | - [Process exited 0]{1: } | + {1:r}eady $ | + [Process exited 0] | | | | @@ -311,13 +349,30 @@ describe('tui focus event handling', function() feed_data(':bwipeout!\n') end) end) + + it('in press-enter prompt', function() + feed_data(":echom 'msg1'|echom 'msg2'|echom 'msg3'|echom 'msg4'|echom 'msg5'\n") + -- Execute :messages to provoke the press-enter prompt. + feed_data(":messages\n") + feed_data('\027[I') + feed_data('\027[I') + screen:expect([[ + msg1 | + msg2 | + msg3 | + msg4 | + msg5 | + {10:Press ENTER or type command to continue}{1: } | + {3:-- TERMINAL --} | + ]]) + end) end) -- These tests require `thelpers` because --headless/--embed -- does not initialize the TUI. describe("tui 't_Co' (terminal colors)", function() local screen - local is_freebsd = (helpers.eval("system('uname') =~? 'FreeBSD'") == 1) + local is_freebsd = (string.lower(global_helpers.uname()) == 'freebsd') local function assert_term_colors(term, colorterm, maxcolors) helpers.clear({env={TERM=term}, args={}}) diff --git a/test/functional/terminal/window_spec.lua b/test/functional/terminal/window_spec.lua index 888b1e1328..0f705cfe40 100644 --- a/test/functional/terminal/window_spec.lua +++ b/test/functional/terminal/window_spec.lua @@ -3,8 +3,6 @@ local thelpers = require('test.functional.terminal.helpers') local feed, clear = helpers.feed, helpers.clear local wait = helpers.wait -if helpers.pending_win32(pending) then return end - describe('terminal window', function() local screen diff --git a/test/functional/terminal/window_split_tab_spec.lua b/test/functional/terminal/window_split_tab_spec.lua index 4867e0d9fa..c5199f620e 100644 --- a/test/functional/terminal/window_split_tab_spec.lua +++ b/test/functional/terminal/window_split_tab_spec.lua @@ -4,8 +4,6 @@ local clear = helpers.clear local feed, nvim = helpers.feed, helpers.nvim local feed_command = helpers.feed_command -if helpers.pending_win32(pending) then return end - describe('terminal', function() local screen @@ -25,6 +23,7 @@ describe('terminal', function() end) it('resets its size when entering terminal window', function() + if helpers.pending_win32(pending) then return end feed('<c-\\><c-n>') feed_command('2split') screen:expect([[ @@ -69,31 +68,25 @@ describe('terminal', function() describe('when the screen is resized', function() it('will forward a resize request to the program', function() - screen:try_resize(screen._width + 3, screen._height + 5) + feed([[<C-\><C-N>:]]) -- Go to cmdline-mode, so cursor is at bottom. + screen:try_resize(screen._width - 3, screen._height - 2) screen:expect([[ - tty ready | - rows: 14, cols: 53 | - {1: } | - | - | - | - | - | - | - | - | - | - | - | - {3:-- TERMINAL --} | + tty ready | + rows: 7, cols: 47 | + {2: } | + | + | + | + | + :^ | ]]) - screen:try_resize(screen._width - 6, screen._height - 10) + screen:try_resize(screen._width - 6, screen._height - 3) screen:expect([[ - tty ready | - rows: 14, cols: 53 | - rows: 4, cols: 47 | - {1: } | - {3:-- TERMINAL --} | + tty ready | + rows: 7, cols: 47 | + rows: 4, cols: 41 | + {2: } | + :^ | ]]) end) end) diff --git a/test/functional/ui/bufhl_spec.lua b/test/functional/ui/bufhl_spec.lua index e1e11203e0..2143c01139 100644 --- a/test/functional/ui/bufhl_spec.lua +++ b/test/functional/ui/bufhl_spec.lua @@ -24,7 +24,8 @@ describe('Buffer highlighting', function() [6] = {foreground = Screen.colors.DarkCyan}, -- Identifier [7] = {bold = true}, [8] = {underline = true, bold = true, foreground = Screen.colors.SlateBlue}, - [9] = {foreground = Screen.colors.SlateBlue, underline = true} + [9] = {foreground = Screen.colors.SlateBlue, underline = true}, + [10] = {foreground = Screen.colors.Red} }) curbuf = request('nvim_get_current_buf') end) @@ -255,4 +256,32 @@ describe('Buffer highlighting', function() | ]]) end) + + it('works with new syntax groups', function() + insert([[ + fancy code in a new fancy language]]) + add_hl(-1, "FancyLangItem", 0, 0, 5) + screen:expect([[ + fancy code in a new fancy languag^e | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]) + + command('hi FancyLangItem guifg=red') + screen:expect([[ + {10:fancy} code in a new fancy languag^e | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]) + end) end) diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua new file mode 100644 index 0000000000..d87ce72599 --- /dev/null +++ b/test/functional/ui/cmdline_highlight_spec.lua @@ -0,0 +1,893 @@ +local helpers = require('test.functional.helpers')(after_each) +local Screen = require('test.functional.ui.screen') + +local eq = helpers.eq +local feed = helpers.feed +local clear = helpers.clear +local meths = helpers.meths +local funcs = helpers.funcs +local source = helpers.source +local dedent = helpers.dedent +local command = helpers.command +local curbufmeths = helpers.curbufmeths + +local screen + +-- Bug in input() handling: :redraw! will erase the whole prompt up until +-- user types something. It exists in Vim as well, so using `h<BS>` as +-- a workaround. +local function redraw_input() + feed('{REDRAW}h<BS>') +end + +before_each(function() + clear() + screen = Screen.new(40, 8) + screen:attach() + source([[ + highlight RBP1 guibg=Red + highlight RBP2 guibg=Yellow + highlight RBP3 guibg=Green + highlight RBP4 guibg=Blue + let g:NUM_LVLS = 4 + function Redraw() + redraw! + return '' + endfunction + let g:id = '' + cnoremap <expr> {REDRAW} Redraw() + function DoPrompt(do_return) abort + let id = g:id + let Cb = g:Nvim_color_input{g:id} + let out = input({'prompt': ':', 'highlight': Cb}) + let g:out{id} = out + return (a:do_return ? out : '') + endfunction + nnoremap <expr> {PROMPT} DoPrompt(0) + cnoremap <expr> {PROMPT} DoPrompt(1) + function RainBowParens(cmdline) + let ret = [] + let i = 0 + let lvl = 0 + while i < len(a:cmdline) + if a:cmdline[i] is# '(' + call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)]) + let lvl += 1 + elseif a:cmdline[i] is# ')' + let lvl -= 1 + call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)]) + endif + let i += 1 + endwhile + return ret + endfunction + function SplittedMultibyteStart(cmdline) + let ret = [] + let i = 0 + while i < len(a:cmdline) + let char = nr2char(char2nr(a:cmdline[i:])) + if a:cmdline[i:i + len(char) - 1] is# char + if len(char) > 1 + call add(ret, [i + 1, i + len(char), 'RBP2']) + endif + let i += len(char) + else + let i += 1 + endif + endwhile + return ret + endfunction + function SplittedMultibyteEnd(cmdline) + let ret = [] + let i = 0 + while i < len(a:cmdline) + let char = nr2char(char2nr(a:cmdline[i:])) + if a:cmdline[i:i + len(char) - 1] is# char + if len(char) > 1 + call add(ret, [i, i + 1, 'RBP1']) + endif + let i += len(char) + else + let i += 1 + endif + endwhile + return ret + endfunction + function Echoing(cmdline) + echo 'HERE' + return v:_null_list + endfunction + function Echoning(cmdline) + echon 'HERE' + return v:_null_list + endfunction + function Echomsging(cmdline) + echomsg 'HERE' + return v:_null_list + endfunction + function Echoerring(cmdline) + echoerr 'HERE' + return v:_null_list + endfunction + function Redrawing(cmdline) + redraw! + return v:_null_list + endfunction + function Throwing(cmdline) + throw "ABC" + return v:_null_list + endfunction + function Halting(cmdline) + while 1 + endwhile + endfunction + function ReturningGlobal(cmdline) + return g:callback_return + endfunction + function ReturningGlobal2(cmdline) + return g:callback_return[:len(a:cmdline)-1] + endfunction + function ReturningGlobalN(n, cmdline) + return g:callback_return{a:n} + endfunction + let g:recording_calls = [] + function Recording(cmdline) + call add(g:recording_calls, a:cmdline) + return [] + endfunction + ]]) + screen:set_default_attr_ids({ + RBP1={background = Screen.colors.Red}, + RBP2={background = Screen.colors.Yellow}, + RBP3={background = Screen.colors.Green}, + RBP4={background = Screen.colors.Blue}, + EOB={bold = true, foreground = Screen.colors.Blue1}, + ERR={foreground = Screen.colors.Grey100, background = Screen.colors.Red}, + SK={foreground = Screen.colors.Blue}, + PE={bold = true, foreground = Screen.colors.SeaGreen4} + }) +end) + +local function set_color_cb(funcname, callback_return, id) + meths.set_var('id', id or '') + if id and id ~= '' and funcs.exists('*' .. funcname .. 'N') then + command(('let g:Nvim_color_input%s = {cmdline -> %sN(%s, cmdline)}'):format( + id, funcname, id)) + if callback_return then + meths.set_var('callback_return' .. id, callback_return) + end + else + meths.set_var('Nvim_color_input', funcname) + if callback_return then + meths.set_var('callback_return', callback_return) + end + end +end +local function start_prompt(text) + feed('{PROMPT}' .. (text or '')) +end + +describe('Command-line coloring', function() + it('works', function() + set_color_cb('RainBowParens') + meths.set_option('more', false) + start_prompt() + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :^ | + ]]) + feed('e') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :e^ | + ]]) + feed('cho ') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :echo ^ | + ]]) + feed('(') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :echo {RBP1:(}^ | + ]]) + feed('(') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :echo {RBP1:(}{RBP2:(}^ | + ]]) + feed('42') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :echo {RBP1:(}{RBP2:(}42^ | + ]]) + feed('))') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :echo {RBP1:(}{RBP2:(}42{RBP2:)}{RBP1:)}^ | + ]]) + feed('<BS>') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :echo {RBP1:(}{RBP2:(}42{RBP2:)}^ | + ]]) + redraw_input() + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :echo {RBP1:(}{RBP2:(}42{RBP2:)}^ | + ]]) + end) + for _, func_part in ipairs({'', 'n', 'msg'}) do + it('disables :echo' .. func_part .. ' messages', function() + set_color_cb('Echo' .. func_part .. 'ing') + start_prompt('echo') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :echo^ | + ]]) + end) + end + it('does the right thing when hl start appears to split multibyte char', + function() + set_color_cb('SplittedMultibyteStart') + start_prompt('echo "«') + screen:expect([[ + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :echo " | + {ERR:E5405: Chunk 0 start 7 splits multibyte }| + {ERR:character} | + :echo "«^ | + ]]) + feed('»') + screen:expect([[ + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :echo " | + {ERR:E5405: Chunk 0 start 7 splits multibyte }| + {ERR:character} | + :echo "«»^ | + ]]) + end) + it('does the right thing when hl end appears to split multibyte char', + function() + set_color_cb('SplittedMultibyteEnd') + start_prompt('echo "«') + screen:expect([[ + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :echo " | + {ERR:E5406: Chunk 0 end 7 splits multibyte ch}| + {ERR:aracter} | + :echo "«^ | + ]]) + end) + it('does the right thing when errorring', function() + set_color_cb('Echoerring') + start_prompt('e') + screen:expect([[ + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + : | + {ERR:E5407: Callback has thrown an exception:}| + {ERR: Vim(echoerr):HERE} | + :e^ | + ]]) + end) + it('silences :echo', function() + set_color_cb('Echoing') + start_prompt('e') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :e^ | + ]]) + eq('', meths.command_output('messages')) + end) + it('silences :echon', function() + set_color_cb('Echoning') + start_prompt('e') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :e^ | + ]]) + eq('', meths.command_output('messages')) + end) + it('silences :echomsg', function() + set_color_cb('Echomsging') + start_prompt('e') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :e^ | + ]]) + eq('', meths.command_output('messages')) + end) + it('does the right thing when throwing', function() + set_color_cb('Throwing') + start_prompt('e') + screen:expect([[ + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + : | + {ERR:E5407: Callback has thrown an exception:}| + {ERR: ABC} | + :e^ | + ]]) + end) + it('stops executing callback after a number of errors', function() + set_color_cb('SplittedMultibyteStart') + start_prompt('let x = "«»«»«»«»«»"\n') + screen:expect([[ + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :let x = " | + {ERR:E5405: Chunk 0 start 10 splits multibyte}| + {ERR: character} | + ^:let x = "«»«»«»«»«»" | + ]]) + feed('\n') + screen:expect([[ + ^ | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + | + ]]) + eq('let x = "«»«»«»«»«»"', meths.get_var('out')) + local msg = '\nE5405: Chunk 0 start 10 splits multibyte character' + eq(msg:rep(1), funcs.execute('messages')) + end) + it('allows interrupting callback with <C-c>', function() + set_color_cb('Halting') + start_prompt('echo 42') + screen:expect([[ + ^ | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + | + ]]) + screen:sleep(500) + feed('<C-c>') + screen:expect([[ + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + : | + {ERR:E5407: Callback has thrown an exception:}| + {ERR: Keyboard interrupt} | + :echo 42^ | + ]]) + redraw_input() + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :echo 42^ | + ]]) + feed('\n') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + ^:echo 42 | + ]]) + feed('\n') + eq('echo 42', meths.get_var('out')) + feed('<C-c>') + screen:expect([[ + ^ | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + Type :quit<Enter> to exit Nvim | + ]]) + end) + it('works fine with NUL, NL, CR', function() + set_color_cb('RainBowParens') + start_prompt('echo ("<C-v><CR><C-v><Nul><C-v><NL>")') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :echo {RBP1:(}"{SK:^M^@^@}"{RBP1:)}^ | + ]]) + end) + it('errors out when callback returns something wrong', function() + command('cnoremap + ++') + set_color_cb('ReturningGlobal', '') + start_prompt('#') + screen:expect([[ + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + : | + {ERR:E5400: Callback should return list} | + :#^ | + ]]) + + feed('<CR><CR><CR>') + set_color_cb('ReturningGlobal', {{0, 1, 'Normal'}, 42}) + start_prompt('#') + screen:expect([[ + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + : | + {ERR:E5401: List item 1 is not a List} | + :#^ | + ]]) + + feed('<CR><CR><CR>') + set_color_cb('ReturningGlobal2', {{0, 1, 'Normal'}, {1}}) + start_prompt('+') + screen:expect([[ + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :+ | + {ERR:E5402: List item 1 has incorrect length:}| + {ERR: 1 /= 3} | + :++^ | + ]]) + + feed('<CR><CR><CR>') + set_color_cb('ReturningGlobal2', {{0, 1, 'Normal'}, {2, 3, 'Normal'}}) + start_prompt('+') + screen:expect([[ + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :+ | + {ERR:E5403: Chunk 1 start 2 not in range [1, }| + {ERR:2)} | + :++^ | + ]]) + + feed('<CR><CR><CR>') + set_color_cb('ReturningGlobal2', {{0, 1, 'Normal'}, {1, 3, 'Normal'}}) + start_prompt('+') + screen:expect([[ + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :+ | + {ERR:E5404: Chunk 1 end 3 not in range (1, 2]}| + | + :++^ | + ]]) + end) + it('does not error out when called from a errorred out cycle', function() + set_color_cb('ReturningGlobal', {{0, 1, 'Normal'}}) + feed(dedent([[ + :set regexpengine=2 + :for pat in [' \ze*', ' \zs*'] + : try + : let l = matchlist('x x', pat) + : $put =input({'prompt':'>','highlight':'ReturningGlobal'}) + : + : $put ='E888 NOT detected for ' . pat + : catch + : $put =input({'prompt':'>','highlight':'ReturningGlobal'}) + : + : $put ='E888 detected for ' . pat + : endtry + :endfor + : + : + : + : + : + : + ]])) + eq({'', ':', 'E888 detected for \\ze*', ':', 'E888 detected for \\zs*'}, + curbufmeths.get_lines(0, -1, false)) + eq('', funcs.execute('messages')) + end) + it('allows nesting input()s', function() + set_color_cb('ReturningGlobal', {{0, 1, 'RBP1'}}, '') + start_prompt('1') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :{RBP1:1}^ | + ]]) + + set_color_cb('ReturningGlobal', {{0, 1, 'RBP2'}}, '1') + start_prompt('2') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :{RBP2:2}^ | + ]]) + + set_color_cb('ReturningGlobal', {{0, 1, 'RBP3'}}, '2') + start_prompt('3') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :{RBP3:3}^ | + ]]) + + set_color_cb('ReturningGlobal', {{0, 1, 'RBP4'}}, '3') + start_prompt('4') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :{RBP4:4}^ | + ]]) + + feed('<CR>') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :{RBP3:3}4^ | + ]]) + feed('<CR>') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :{RBP2:2}34^ | + ]]) + feed('<CR>') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :{RBP1:1}234^ | + ]]) + feed('<CR><CR><C-l>') + screen:expect([[ + ^ | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + | + ]]) + eq('1234', meths.get_var('out')) + eq('234', meths.get_var('out1')) + eq('34', meths.get_var('out2')) + eq('4', meths.get_var('out3')) + eq(0, funcs.exists('g:out4')) + end) + it('runs callback with the same data only once', function() + local function new_recording_calls(...) + eq({...}, meths.get_var('recording_calls')) + meths.set_var('recording_calls', {}) + end + set_color_cb('Recording') + start_prompt('') + -- Regression test. Disambiguation: + -- + -- new_recording_calls(expected_result) -- (actual_before_fix) + -- + feed('a') + new_recording_calls('a') -- ('a', 'a') + feed('b') + new_recording_calls('ab') -- ('a', 'ab', 'ab') + feed('c') + new_recording_calls('abc') -- ('ab', 'abc', 'abc') + feed('<BS>') + new_recording_calls('ab') -- ('abc', 'ab', 'ab') + feed('<BS>') + new_recording_calls('a') -- ('ab', 'a', 'a') + feed('<BS>') + new_recording_calls() -- ('a') + feed('<CR><CR>') + eq('', meths.get_var('out')) + end) +end) +describe('Ex commands coloring support', function() + it('works', function() + meths.set_var('Nvim_color_cmdline', 'RainBowParens') + feed(':echo (((1)))') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :echo {RBP1:(}{RBP2:(}{RBP3:(}1{RBP3:)}{RBP2:)}{RBP1:)}^ | + ]]) + end) + it('still executes command-line even if errored out', function() + meths.set_var('Nvim_color_cmdline', 'SplittedMultibyteStart') + feed(':let x = "«"\n') + eq('«', meths.get_var('x')) + local msg = 'E5405: Chunk 0 start 10 splits multibyte character' + eq('\n'..msg, funcs.execute('messages')) + end) + it('does not error out when called from a errorred out cycle', function() + -- Apparently when there is a cycle in which one of the commands errors out + -- this error may be caught by color_cmdline before it is presented to the + -- user. + feed(dedent([[ + :set regexpengine=2 + :for pat in [' \ze*', ' \zs*'] + : try + : let l = matchlist('x x', pat) + : $put ='E888 NOT detected for ' . pat + : catch + : $put ='E888 detected for ' . pat + : endtry + :endfor + ]])) + eq({'', 'E888 detected for \\ze*', 'E888 detected for \\zs*'}, + curbufmeths.get_lines(0, -1, false)) + eq('', funcs.execute('messages')) + end) + it('does not crash when using `n` in debug mode', function() + feed(':debug execute "echo 1"\n') + screen:expect([[ + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + Entering Debug mode. Type "cont" to con| + tinue. | + cmd: execute "echo 1" | + >^ | + ]]) + feed('n\n') + screen:expect([[ + {EOB:~ }| + {EOB:~ }| + Entering Debug mode. Type "cont" to con| + tinue. | + cmd: execute "echo 1" | + >n | + 1 | + {PE:Press ENTER or type command to continue}^ | + ]]) + feed('\n') + screen:expect([[ + ^ | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + | + ]]) + end) + it('does not prevent mapping error from cancelling prompt', function() + command("cnoremap <expr> x execute('throw 42')[-1]") + feed(':#x') + screen:expect([[ + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :# | + {ERR:Error detected while processing :} | + {ERR:E605: Exception not caught: 42} | + :#^ | + ]]) + feed('<CR>') + screen:expect([[ + ^ | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + | + ]]) + feed('<CR>') + screen:expect([[ + ^ | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + | + ]]) + eq('\nError detected while processing :\nE605: Exception not caught: 42', + meths.command_output('messages')) + end) + it('errors out when failing to get callback', function() + meths.set_var('Nvim_color_cmdline', 42) + feed(':#') + screen:expect([[ + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + : | + {ERR:E5408: Unable to get g:Nvim_color_cmdlin}| + {ERR:e callback: Vim:E6000: Argument is not a}| + {ERR: function or function name} | + :#^ | + ]]) + end) +end) +describe('Expressions coloring support', function() + it('works', function() + meths.set_var('Nvim_color_expr', 'RainBowParens') + feed(':echo <C-r>=(((1)))') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + ={RBP1:(}{RBP2:(}{RBP3:(}1{RBP3:)}{RBP2:)}{RBP1:)}^ | + ]]) + end) + it('errors out when failing to get callback', function() + meths.set_var('Nvim_color_expr', 42) + feed(':<C-r>=1') + screen:expect([[ + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + = | + {ERR:E5409: Unable to get g:Nvim_color_expr c}| + {ERR:allback: Vim:E6000: Argument is not a fu}| + {ERR:nction or function name} | + =1^ | + ]]) + end) +end) diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua index 64965ccb94..c8fa2888d1 100644 --- a/test/functional/ui/inccommand_spec.lua +++ b/test/functional/ui/inccommand_spec.lua @@ -14,6 +14,7 @@ local neq = helpers.neq local ok = helpers.ok local source = helpers.source local wait = helpers.wait +local nvim = helpers.nvim local default_text = [[ Inc substitution on @@ -892,6 +893,31 @@ describe(":substitute, inccommand=split", function() ]]) end) + it('previews correctly when previewhight is small', function() + feed_command('set cwh=3') + feed_command('set hls') + feed('ggdG') + insert(string.rep('abc abc abc\n', 20)) + feed(':%s/abc/MMM/g') + screen:expect([[ + MMM MMM MMM | + MMM MMM MMM | + MMM MMM MMM | + MMM MMM MMM | + MMM MMM MMM | + MMM MMM MMM | + MMM MMM MMM | + MMM MMM MMM | + MMM MMM MMM | + {11:[No Name] [+] }| + | 1| {12:MMM} {12:MMM} {12:MMM} | + | 2| {12:MMM} {12:MMM} {12:MMM} | + | 3| {12:MMM} {12:MMM} {12:MMM} | + {10:[Preview] }| + :%s/abc/MMM/g^ | + ]]) + end) + it('actually replaces text', function() feed(":%s/tw/XX/g<Enter>") @@ -1622,3 +1648,29 @@ describe("'inccommand' split windows", function() end) end) + +describe("'inccommand' with 'gdefault'", function() + before_each(function() + clear() + end) + + it("does not lock up #7244", function() + common_setup(nil, "nosplit", "{") + command("set gdefault") + feed(":s/{\\n") + eq({mode='c', blocking=false}, nvim("get_mode")) + feed("/A<Enter>") + expect("A") + eq({mode='n', blocking=false}, nvim("get_mode")) + end) + + it("with multiline text and range, does not lock up #7244", function() + common_setup(nil, "nosplit", "{\n\n{") + command("set gdefault") + feed(":%s/{\\n") + eq({mode='c', blocking=false}, nvim("get_mode")) + feed("/A<Enter>") + expect("A\nA") + eq({mode='n', blocking=false}, nvim("get_mode")) + end) +end) diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua index 5408e1e195..a6b7fb2997 100644 --- a/test/functional/ui/screen.lua +++ b/test/functional/ui/screen.lua @@ -251,7 +251,7 @@ function Screen:expect(expected, attr_ids, attr_ignore, condition, any) ..'Expected:\n |'..table.concat(msg_expected_rows, '|\n |')..'|\n' ..'Actual:\n |'..table.concat(actual_rows, '|\n |')..'|\n\n'..[[ To print the expect() call that would assert the current screen state, use -screen:snaphot_util(). In case of non-deterministic failures, use +screen:snapshot_util(). In case of non-deterministic failures, use screen:redraw_debug() to show all intermediate screen states. ]]) end end diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua index bfcdc7f652..b31d9cb32f 100644 --- a/test/functional/ui/screen_basic_spec.lua +++ b/test/functional/ui/screen_basic_spec.lua @@ -5,6 +5,7 @@ local feed, command = helpers.feed, helpers.command local insert = helpers.insert local eq = helpers.eq local eval = helpers.eval +local iswin = helpers.iswin describe('screen', function() local screen @@ -119,9 +120,10 @@ describe('Screen', function() end) it('has correct default title with named file', function() - local expected = 'myfile (/mydir) - NVIM' + local expected = (iswin() and 'myfile (C:\\mydir) - NVIM' + or 'myfile (/mydir) - NVIM') command('set title') - command('file /mydir/myfile') + command(iswin() and 'file C:\\mydir\\myfile' or 'file /mydir/myfile') screen:expect(function() eq(expected, screen.title) end) diff --git a/test/unit/path_spec.lua b/test/unit/path_spec.lua index a9cba7df84..befb204d0a 100644 --- a/test/unit/path_spec.lua +++ b/test/unit/path_spec.lua @@ -481,6 +481,20 @@ describe('path.c', function() eq('/tmp', ffi.string(buffer)) eq(OK, result) end) + + itp('expands "./" to the current directory #7117', function() + local force_expansion = 1 + local result = vim_FullName('./unit-test-directory/test.file', buffer, length, force_expansion) + eq(OK, result) + eq(lfs.currentdir() .. '/unit-test-directory/test.file', (ffi.string(buffer))) + end) + + itp('collapses "foo/../foo" to "foo" #7117', function() + local force_expansion = 1 + local result = vim_FullName('unit-test-directory/../unit-test-directory/test.file', buffer, length, force_expansion) + eq(OK, result) + eq(lfs.currentdir() .. '/unit-test-directory/test.file', (ffi.string(buffer))) + end) end) describe('path_fix_case', function() |