diff options
Diffstat (limited to 'test/functional')
35 files changed, 861 insertions, 174 deletions
diff --git a/test/functional/api/keymap_spec.lua b/test/functional/api/keymap_spec.lua index 773207d360..210394c83f 100644 --- a/test/functional/api/keymap_spec.lua +++ b/test/functional/api/keymap_spec.lua @@ -585,13 +585,13 @@ describe('nvim_set_keymap, nvim_del_keymap', function() end) it('can set <expr> mappings whose RHS change dynamically', function() - meths.command_output([[ + meths.exec([[ function! FlipFlop() abort if !exists('g:flip') | let g:flip = 0 | endif let g:flip = !g:flip return g:flip endfunction - ]]) + ]], true) eq(1, meths.call_function('FlipFlop', {})) eq(0, meths.call_function('FlipFlop', {})) eq(1, meths.call_function('FlipFlop', {})) diff --git a/test/functional/api/mark_extended_spec.lua b/test/functional/api/mark_extended_spec.lua index 76db9f9d81..bf910568b1 100644 --- a/test/functional/api/mark_extended_spec.lua +++ b/test/functional/api/mark_extended_spec.lua @@ -5,6 +5,7 @@ local request = helpers.request local eq = helpers.eq local ok = helpers.ok local curbufmeths = helpers.curbufmeths +local bufmeths = helpers.bufmeths local pcall_err = helpers.pcall_err local insert = helpers.insert local feed = helpers.feed @@ -36,7 +37,7 @@ local function get_extmarks(ns_id, start, end_, opts) return curbufmeths.get_extmarks(ns_id, start, end_, opts) end -describe('Extmarks buffer api', function() +describe('API/extmarks', function() local screen local marks, positions, ns_string2, ns_string, init_text, row, col local ns, ns2 @@ -153,26 +154,26 @@ describe('Extmarks buffer api', function() end -- next with mark id - rv = get_extmarks(ns, marks[1], {-1, -1}, {amount=1}) + rv = get_extmarks(ns, marks[1], {-1, -1}, {limit=1}) eq({{marks[1], positions[1][1], positions[1][2]}}, rv) - rv = get_extmarks(ns, marks[2], {-1, -1}, {amount=1}) + rv = get_extmarks(ns, marks[2], {-1, -1}, {limit=1}) eq({{marks[2], positions[2][1], positions[2][2]}}, rv) -- next with positional when mark exists at position - rv = get_extmarks(ns, positions[1], {-1, -1}, {amount=1}) + rv = get_extmarks(ns, positions[1], {-1, -1}, {limit=1}) eq({{marks[1], positions[1][1], positions[1][2]}}, rv) -- next with positional index (no mark at position) - rv = get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {-1, -1}, {amount=1}) + rv = get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {-1, -1}, {limit=1}) eq({{marks[2], positions[2][1], positions[2][2]}}, rv) -- next with Extremity index - rv = get_extmarks(ns, {0,0}, {-1, -1}, {amount=1}) + rv = get_extmarks(ns, {0,0}, {-1, -1}, {limit=1}) eq({{marks[1], positions[1][1], positions[1][2]}}, rv) -- nextrange with mark id rv = get_extmarks(ns, marks[1], marks[3]) eq({marks[1], positions[1][1], positions[1][2]}, rv[1]) eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) - -- nextrange with amount - rv = get_extmarks(ns, marks[1], marks[3], {amount=2}) + -- nextrange with `limit` + rv = get_extmarks(ns, marks[1], marks[3], {limit=2}) eq(2, table.getn(rv)) -- nextrange with positional when mark exists at position rv = get_extmarks(ns, positions[1], positions[3]) @@ -196,18 +197,18 @@ describe('Extmarks buffer api', function() eq({{marks[3], positions[3][1], positions[3][2]}}, rv) -- prev with mark id - rv = get_extmarks(ns, marks[3], {0, 0}, {amount=1}) + rv = get_extmarks(ns, marks[3], {0, 0}, {limit=1}) eq({{marks[3], positions[3][1], positions[3][2]}}, rv) - rv = get_extmarks(ns, marks[2], {0, 0}, {amount=1}) + rv = get_extmarks(ns, marks[2], {0, 0}, {limit=1}) eq({{marks[2], positions[2][1], positions[2][2]}}, rv) -- prev with positional when mark exists at position - rv = get_extmarks(ns, positions[3], {0, 0}, {amount=1}) + rv = get_extmarks(ns, positions[3], {0, 0}, {limit=1}) eq({{marks[3], positions[3][1], positions[3][2]}}, rv) -- prev with positional index (no mark at position) - rv = get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {0, 0}, {amount=1}) + rv = get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {0, 0}, {limit=1}) eq({{marks[1], positions[1][1], positions[1][2]}}, rv) -- prev with Extremity index - rv = get_extmarks(ns, {-1,-1}, {0,0}, {amount=1}) + rv = get_extmarks(ns, {-1,-1}, {0,0}, {limit=1}) eq({{marks[3], positions[3][1], positions[3][2]}}, rv) -- prevrange with mark id @@ -215,8 +216,8 @@ describe('Extmarks buffer api', function() eq({marks[3], positions[3][1], positions[3][2]}, rv[1]) eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) eq({marks[1], positions[1][1], positions[1][2]}, rv[3]) - -- prevrange with amount - rv = get_extmarks(ns, marks[3], marks[1], {amount=2}) + -- prevrange with limit + rv = get_extmarks(ns, marks[3], marks[1], {limit=2}) eq(2, table.getn(rv)) -- prevrange with positional when mark exists at position rv = get_extmarks(ns, positions[3], positions[1]) @@ -241,7 +242,7 @@ describe('Extmarks buffer api', function() eq({{marks[1], positions[1][1], positions[1][2]}}, rv) end) - it('querying for information with amount #extmarks', function() + it('querying for information with limit #extmarks', function() -- add some more marks for i, m in ipairs(marks) do if positions[i] ~= nil then @@ -250,19 +251,19 @@ describe('Extmarks buffer api', function() end end - local rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=1}) + local rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=1}) eq(1, table.getn(rv)) - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=2}) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=2}) eq(2, table.getn(rv)) - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=3}) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=3}) eq(3, table.getn(rv)) -- now in reverse - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=1}) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=1}) eq(1, table.getn(rv)) - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=2}) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=2}) eq(2, table.getn(rv)) - rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=3}) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {limit=3}) eq(3, table.getn(rv)) end) @@ -295,9 +296,9 @@ describe('Extmarks buffer api', function() rv) end) - it('get_marks amount 0 returns nothing #extmarks', function() + it('get_marks limit=0 returns nothing #extmarks', function() set_extmark(ns, marks[1], positions[1][1], positions[1][2]) - local rv = get_extmarks(ns, {-1, -1}, {-1, -1}, {amount=0}) + local rv = get_extmarks(ns, {-1, -1}, {-1, -1}, {limit=0}) eq({}, rv) end) @@ -422,7 +423,7 @@ describe('Extmarks buffer api', function() set_extmark(ns, marks[1], 1, 2) -- Insert a fullwidth (two col) tilde, NICE feed('0i~<esc>') - check_undo_redo(ns, marks[1], 1, 2, 1, 3) + check_undo_redo(ns, marks[1], 1, 2, 1, 5) end) it('marks move with blockwise inserts #extmarks', function() @@ -475,6 +476,13 @@ describe('Extmarks buffer api', function() check_undo_redo(ns, marks[2], 0, 3, 1, 2) end) + it('deleting right before a mark works #extmarks', function() + -- op_delete in ops.c + set_extmark(ns, marks[1], 0, 2) + feed('0lx') + check_undo_redo(ns, marks[1], 0, 2, 0, 1) + end) + it('deleting on a mark works #extmarks', function() -- op_delete in ops.c set_extmark(ns, marks[1], 0, 2) @@ -499,7 +507,7 @@ describe('Extmarks buffer api', function() feed('0l3dl<esc>') check_undo_redo(ns, marks[1], 0, 2, 0, 1) check_undo_redo(ns, marks[2], 0, 3, 0, 1) - -- delete 1, nothing should happend to our marks + -- delete 1, nothing should happen to our marks feed('u') feed('$x') check_undo_redo(ns, marks[2], 0, 3, 0, 3) @@ -535,7 +543,7 @@ describe('Extmarks buffer api', function() check_undo_redo(ns, marks[1], 0, 1, 0, 0) check_undo_redo(ns, marks[2], 0, 3, 0, 0) check_undo_redo(ns, marks[3], 1, 2, 1, 0) - -- delete 1, nothing should happend to our marks + -- delete 1, nothing should happen to our marks feed('u') feed('$<c-v>jx') check_undo_redo(ns, marks[2], 0, 3, 0, 3) @@ -723,7 +731,7 @@ describe('Extmarks buffer api', function() -- Test updates feed('o<esc>') set_extmark(ns, marks[1], positions[1][1], positions[1][2]) - rv = get_extmarks(ns, marks[1], marks[1], {amount=1}) + rv = get_extmarks(ns, marks[1], marks[1], {limit=1}) eq(1, table.getn(rv)) feed("u") feed("<c-r>") @@ -764,23 +772,23 @@ describe('Extmarks buffer api', function() set_extmark(ns2, marks[2], positions[2][1], positions[2][2]) set_extmark(ns2, marks[3], positions[3][1], positions[3][2]) - -- get_next (amount set) - rv = get_extmarks(ns, {0, 0}, positions[2], {amount=1}) + -- get_next (limit set) + rv = get_extmarks(ns, {0, 0}, positions[2], {limit=1}) eq(1, table.getn(rv)) - rv = get_extmarks(ns2, {0, 0}, positions[2], {amount=1}) + rv = get_extmarks(ns2, {0, 0}, positions[2], {limit=1}) eq(1, table.getn(rv)) - -- get_prev (amount set) - rv = get_extmarks(ns, positions[1], {0, 0}, {amount=1}) + -- get_prev (limit set) + rv = get_extmarks(ns, positions[1], {0, 0}, {limit=1}) eq(1, table.getn(rv)) - rv = get_extmarks(ns2, positions[1], {0, 0}, {amount=1}) + rv = get_extmarks(ns2, positions[1], {0, 0}, {limit=1}) eq(1, table.getn(rv)) - -- get_next (amount not set) + -- get_next (no limit) rv = get_extmarks(ns, positions[1], positions[2]) eq(2, table.getn(rv)) rv = get_extmarks(ns2, positions[1], positions[2]) eq(2, table.getn(rv)) - -- get_prev (amount not set) + -- get_prev (no limit) rv = get_extmarks(ns, positions[2], positions[1]) eq(2, table.getn(rv)) rv = get_extmarks(ns2, positions[2], positions[1]) @@ -1243,7 +1251,7 @@ describe('Extmarks buffer api', function() eq("col value outside range", pcall_err(set_extmark, ns, marks[1], 0, invalid_col)) end) - it('when line > line_count, throw error #extmarks', function() + it('fails when line > line_count #extmarks', function() local invalid_col = init_text:len() + 1 local invalid_lnum = 3 eq('line value outside range', pcall_err(set_extmark, ns, marks[1], invalid_lnum, invalid_col)) @@ -1251,10 +1259,9 @@ describe('Extmarks buffer api', function() end) it('bug from check_col in extmark_set #extmarks_sub', function() - -- This bug was caused by extmark_set always using - -- check_col. check_col always uses the current buffer. - -- This wasn't working during undo so we now use - -- check_col and check_lnum only when they are required. + -- This bug was caused by extmark_set always using check_col. check_col + -- always uses the current buffer. This wasn't working during undo so we + -- now use check_col and check_lnum only when they are required. feed('A<cr>67890<cr>xx<esc>') feed('A<cr>12345<cr>67890<cr>xx<esc>') set_extmark(ns, marks[1], 3, 4) @@ -1268,6 +1275,13 @@ describe('Extmarks buffer api', function() local id = set_extmark(ns, 0, 0, 2) eq({{id, 0, 2}}, get_extmarks(ns,0, -1)) end) + + it('can set a mark to other buffer', function() + local buf = request('nvim_create_buf', 0, 1) + request('nvim_buf_set_lines', buf, 0, -1, 1, {"", ""}) + local id = bufmeths.set_extmark(buf, ns, 0, 1, 0, {}) + eq({{id, 1, 0}}, bufmeths.get_extmarks(buf, ns, 0, -1, {})) + end) end) describe('Extmarks buffer api with many marks', function() diff --git a/test/functional/api/proc_spec.lua b/test/functional/api/proc_spec.lua index 063d382790..d828bdf948 100644 --- a/test/functional/api/proc_spec.lua +++ b/test/functional/api/proc_spec.lua @@ -10,7 +10,7 @@ local request = helpers.request local retry = helpers.retry local NIL = helpers.NIL -describe('api', function() +describe('API', function() before_each(clear) describe('nvim_get_proc_children', function() diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 8b77dbcaa6..d901a5e2eb 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -16,6 +16,8 @@ local parse_context = helpers.parse_context local request = helpers.request local source = helpers.source local next_msg = helpers.next_msg +local tmpname = helpers.tmpname +local write_file = helpers.write_file local pcall_err = helpers.pcall_err local format_string = helpers.format_string @@ -74,9 +76,127 @@ describe('API', function() eq({mode='i', blocking=false}, nvim("get_mode")) end) + describe('nvim_exec', function() + it('one-line input', function() + nvim('exec', "let x1 = 'a'", false) + eq('a', nvim('get_var', 'x1')) + end) + + it(':verbose set {option}?', function() + nvim('exec', 'set nowrap', false) + eq('nowrap\n\tLast set from anonymous :source', + nvim('exec', 'verbose set wrap?', true)) + end) + + it('multiline input', function() + -- Heredoc + empty lines. + nvim('exec', "let x2 = 'a'\n", false) + eq('a', nvim('get_var', 'x2')) + nvim('exec','lua <<EOF\n\n\n\ny=3\n\n\nEOF', false) + eq(3, nvim('eval', "luaeval('y')")) + + eq('', nvim('exec', 'lua <<EOF\ny=3\nEOF', false)) + eq(3, nvim('eval', "luaeval('y')")) + + -- Multiple statements + nvim('exec', 'let x1=1\nlet x2=2\nlet x3=3\n', false) + eq(1, nvim('eval', 'x1')) + eq(2, nvim('eval', 'x2')) + eq(3, nvim('eval', 'x3')) + + -- Functions + nvim('exec', 'function Foo()\ncall setline(1,["xxx"])\nendfunction', false) + eq(nvim('get_current_line'), '') + nvim('exec', 'call Foo()', false) + eq(nvim('get_current_line'), 'xxx') + + -- Autocmds + nvim('exec','autocmd BufAdd * :let x1 = "Hello"', false) + nvim('command', 'new foo') + eq('Hello', request('nvim_eval', 'g:x1')) + end) + + it('non-ASCII input', function() + nvim('exec', [=[ + new + exe "normal! i ax \n Ax " + :%s/ax/--a1234--/g | :%s/Ax/--A1234--/g + ]=], false) + nvim('command', '1') + eq(' --a1234-- ', nvim('get_current_line')) + nvim('command', '2') + eq(' --A1234-- ', nvim('get_current_line')) + + nvim('exec', [[ + new + call setline(1,['xxx']) + call feedkeys('r') + call feedkeys('ñ', 'xt') + ]], false) + eq('ñxx', nvim('get_current_line')) + end) + + it('execution error', function() + eq('Vim:E492: Not an editor command: bogus_command', + pcall_err(request, 'nvim_exec', 'bogus_command', false)) + eq('', nvim('eval', 'v:errmsg')) -- v:errmsg was not updated. + eq('', eval('v:exception')) + + eq('Vim(buffer):E86: Buffer 23487 does not exist', + pcall_err(request, 'nvim_exec', 'buffer 23487', false)) + eq('', eval('v:errmsg')) -- v:errmsg was not updated. + eq('', eval('v:exception')) + end) + + it('recursion', function() + local fname = tmpname() + write_file(fname, 'let x1 = "set from :source file"\n') + -- nvim_exec + -- :source + -- nvim_exec + request('nvim_exec', [[ + let x2 = substitute('foo','o','X','g') + let x4 = 'should be overwritten' + call nvim_exec("source ]]..fname..[[\nlet x3 = substitute('foo','foo','set by recursive nvim_exec','g')\nlet x5='overwritten'\nlet x4=x5\n", v:false) + ]], false) + eq('set from :source file', request('nvim_get_var', 'x1')) + eq('fXX', request('nvim_get_var', 'x2')) + eq('set by recursive nvim_exec', request('nvim_get_var', 'x3')) + eq('overwritten', request('nvim_get_var', 'x4')) + eq('overwritten', request('nvim_get_var', 'x5')) + os.remove(fname) + end) + + it('traceback', function() + local fname = tmpname() + write_file(fname, 'echo "hello"\n') + local sourcing_fname = tmpname() + write_file(sourcing_fname, 'call nvim_exec("source '..fname..'", v:false)\n') + meths.exec('set verbose=2', false) + local traceback_output = 'line 0: sourcing "'..sourcing_fname..'"\n'.. + 'line 0: sourcing "'..fname..'"\n'.. + 'hello\n'.. + 'finished sourcing '..fname..'\n'.. + 'continuing in nvim_exec() called at '..sourcing_fname..':1\n'.. + 'finished sourcing '..sourcing_fname..'\n'.. + 'continuing in nvim_exec() called at nvim_exec():0' + eq(traceback_output, + meths.exec('call nvim_exec("source '..sourcing_fname..'", v:false)', true)) + os.remove(fname) + os.remove(sourcing_fname) + end) + + it('returns output', function() + eq('this is spinal tap', + nvim('exec', 'lua <<EOF\n\n\nprint("this is spinal tap")\n\n\nEOF', true)) + eq('', nvim('exec', 'echo', true)) + eq('foo 42', nvim('exec', 'echo "foo" 42', true)) + end) + end) + describe('nvim_command', function() it('works', function() - local fname = helpers.tmpname() + local fname = tmpname() nvim('command', 'new') nvim('command', 'edit '..fname) nvim('command', 'normal itesting\napi') @@ -313,41 +433,44 @@ describe('API', function() end) end) - describe('nvim_execute_lua', function() + describe('nvim_exec_lua', function() it('works', function() - meths.execute_lua('vim.api.nvim_set_var("test", 3)', {}) + meths.exec_lua('vim.api.nvim_set_var("test", 3)', {}) eq(3, meths.get_var('test')) - eq(17, meths.execute_lua('a, b = ...\nreturn a + b', {10,7})) + eq(17, meths.exec_lua('a, b = ...\nreturn a + b', {10,7})) - eq(NIL, meths.execute_lua('function xx(a,b)\nreturn a..b\nend',{})) + eq(NIL, meths.exec_lua('function xx(a,b)\nreturn a..b\nend',{})) + eq("xy", meths.exec_lua('return xx(...)', {'x','y'})) + + -- Deprecated name: nvim_execute_lua. eq("xy", meths.execute_lua('return xx(...)', {'x','y'})) end) it('reports errors', function() eq([[Error loading lua: [string "<nvim>"]:1: '=' expected near '+']], - pcall_err(meths.execute_lua, 'a+*b', {})) + pcall_err(meths.exec_lua, 'a+*b', {})) eq([[Error loading lua: [string "<nvim>"]:1: unexpected symbol near '1']], - pcall_err(meths.execute_lua, '1+2', {})) + pcall_err(meths.exec_lua, '1+2', {})) eq([[Error loading lua: [string "<nvim>"]:1: unexpected symbol]], - pcall_err(meths.execute_lua, 'aa=bb\0', {})) + pcall_err(meths.exec_lua, 'aa=bb\0', {})) eq([[Error executing lua: [string "<nvim>"]:1: attempt to call global 'bork' (a nil value)]], - pcall_err(meths.execute_lua, 'bork()', {})) + pcall_err(meths.exec_lua, 'bork()', {})) eq('Error executing lua: [string "<nvim>"]:1: did\nthe\nfail', - pcall_err(meths.execute_lua, 'error("did\\nthe\\nfail")', {})) + pcall_err(meths.exec_lua, 'error("did\\nthe\\nfail")', {})) end) it('uses native float values', function() - eq(2.5, meths.execute_lua("return select(1, ...)", {2.5})) - eq("2.5", meths.execute_lua("return vim.inspect(...)", {2.5})) + eq(2.5, meths.exec_lua("return select(1, ...)", {2.5})) + eq("2.5", meths.exec_lua("return vim.inspect(...)", {2.5})) -- "special" float values are still accepted as return values. - eq(2.5, meths.execute_lua("return vim.api.nvim_eval('2.5')", {})) - eq("{\n [false] = 2.5,\n [true] = 3\n}", meths.execute_lua("return vim.inspect(vim.api.nvim_eval('2.5'))", {})) + eq(2.5, meths.exec_lua("return vim.api.nvim_eval('2.5')", {})) + eq("{\n [false] = 2.5,\n [true] = 3\n}", meths.exec_lua("return vim.inspect(vim.api.nvim_eval('2.5'))", {})) end) end) @@ -453,7 +576,7 @@ describe('API', function() eq({0,3,14,0}, funcs.getpos('.')) end) it('vim.paste() failure', function() - nvim('execute_lua', 'vim.paste = (function(lines, phase) error("fake fail") end)', {}) + nvim('exec_lua', 'vim.paste = (function(lines, phase) error("fake fail") end)', {}) eq([[Error executing lua: [string "<nvim>"]:1: fake fail]], pcall_err(request, 'nvim_paste', 'line 1\nline 2\nline 3', false, 1)) end) @@ -677,7 +800,7 @@ describe('API', function() ok(nil ~= string.find(rv, 'noequalalways\n'.. '\tLast set from API client %(channel id %d+%)')) - nvim('execute_lua', 'vim.api.nvim_set_option("equalalways", true)', {}) + nvim('exec_lua', 'vim.api.nvim_set_option("equalalways", true)', {}) status, rv = pcall(nvim, 'command_output', 'verbose set equalalways?') eq(true, status) @@ -1680,7 +1803,7 @@ describe('API', function() eq(' 1 %a "[No Name]" line 1\n'.. ' 3 h "[Scratch]" line 0\n'.. ' 4 h "[Scratch]" line 0', - meths.command_output("ls")) + meths.exec('ls', true)) -- current buffer didn't change eq({id=1}, meths.get_current_buf()) diff --git a/test/functional/autocmd/cmdline_spec.lua b/test/functional/autocmd/cmdline_spec.lua index 51b7b819e9..8ec06dc148 100644 --- a/test/functional/autocmd/cmdline_spec.lua +++ b/test/functional/autocmd/cmdline_spec.lua @@ -33,7 +33,7 @@ describe('cmdline autocommands', function() eq({'notification', 'CmdlineEnter', {{cmdtype=':', cmdlevel=1}}}, next_msg()) -- note: feed('bork<c-c>') might not consume 'bork' - -- due to out-of-band interupt handling + -- due to out-of-band interrupt handling feed('bork<esc>') eq({'notification', 'CmdlineLeave', {{cmdtype=':', cmdlevel=1, abort=true}}}, next_msg()) diff --git a/test/functional/autocmd/tabclose_spec.lua b/test/functional/autocmd/tabclose_spec.lua index b7c33dc3d8..92d860c628 100644 --- a/test/functional/autocmd/tabclose_spec.lua +++ b/test/functional/autocmd/tabclose_spec.lua @@ -11,10 +11,10 @@ describe('TabClosed', function() repeat nvim('command', 'tabnew') until nvim('eval', 'tabpagenr()') == 6 -- current tab is now 6 - eq("tabclosed:6:6:5", nvim('command_output', 'tabclose')) -- close last 6, current tab is now 5 - eq("tabclosed:5:5:4", nvim('command_output', 'close')) -- close last window on tab, closes tab - eq("tabclosed:2:2:3", nvim('command_output', '2tabclose')) -- close tab 2, current tab is now 3 - eq("tabclosed:1:1:2\ntabclosed:1:1:1", nvim('command_output', 'tabonly')) -- close tabs 1 and 2 + eq("tabclosed:6:6:5", nvim('exec', 'tabclose', true)) -- close last 6, current tab is now 5 + eq("tabclosed:5:5:4", nvim('exec', 'close', true)) -- close last window on tab, closes tab + eq("tabclosed:2:2:3", nvim('exec', '2tabclose', true)) -- close tab 2, current tab is now 3 + eq("tabclosed:1:1:2\ntabclosed:1:1:1", nvim('exec', 'tabonly', true)) -- close tabs 1 and 2 end) it('is triggered when closing a window via bdelete from another tab', function() @@ -23,7 +23,7 @@ describe('TabClosed', function() nvim('command', '1tabedit Xtestfile') nvim('command', 'normal! 1gt') eq({1, 3}, nvim('eval', '[tabpagenr(), tabpagenr("$")]')) - eq("tabclosed:2:2:1\ntabclosed:2:2:1", nvim('command_output', 'bdelete Xtestfile')) + eq("tabclosed:2:2:1\ntabclosed:2:2:1", nvim('exec', 'bdelete Xtestfile', true)) eq({1, 1}, nvim('eval', '[tabpagenr(), tabpagenr("$")]')) end) @@ -35,7 +35,7 @@ describe('TabClosed', function() -- Only one tab is closed, and the alternate file is used for the other. eq({2, 3}, nvim('eval', '[tabpagenr(), tabpagenr("$")]')) - eq("tabclosed:2:2:2", nvim('command_output', 'bdelete Xtestfile2')) + eq("tabclosed:2:2:2", nvim('exec', 'bdelete Xtestfile2', true)) eq('Xtestfile1', nvim('eval', 'bufname("")')) end) end) @@ -48,9 +48,9 @@ describe('TabClosed', function() nvim('command', 'tabnew') until nvim('eval', 'tabpagenr()') == 7 -- current tab is now 7 -- sanity check, we shouldn't match on tabs with numbers other than 2 - eq("tabclosed:7:7:6", nvim('command_output', 'tabclose')) + eq("tabclosed:7:7:6", nvim('exec', 'tabclose', true)) -- close tab page 2, current tab is now 5 - eq("tabclosed:2:2:5\ntabclosed:match", nvim('command_output', '2tabclose')) + eq("tabclosed:2:2:5\ntabclosed:match", nvim('exec', '2tabclose', true)) end) end) @@ -59,7 +59,7 @@ describe('TabClosed', function() nvim('command', 'au! TabClosed * echom "tabclosed:".expand("<afile>").":".expand("<amatch>").":".tabpagenr()') nvim('command', 'tabedit Xtestfile') eq({2, 2}, nvim('eval', '[tabpagenr(), tabpagenr("$")]')) - eq("tabclosed:2:2:1", nvim('command_output', 'close')) + eq("tabclosed:2:2:1", nvim('exec', 'close', true)) eq({1, 1}, nvim('eval', '[tabpagenr(), tabpagenr("$")]')) end) end) diff --git a/test/functional/autocmd/tabnewentered_spec.lua b/test/functional/autocmd/tabnewentered_spec.lua index 59cac07b34..32e341184d 100644 --- a/test/functional/autocmd/tabnewentered_spec.lua +++ b/test/functional/autocmd/tabnewentered_spec.lua @@ -7,15 +7,15 @@ describe('TabNewEntered', function() it('matches when entering any new tab', function() clear() nvim('command', 'au! TabNewEntered * echom "tabnewentered:".tabpagenr().":".bufnr("")') - eq("tabnewentered:2:2", nvim('command_output', 'tabnew')) - eq("tabnewentered:3:3", nvim('command_output', 'tabnew test.x2')) + eq("tabnewentered:2:2", nvim('exec', 'tabnew', true)) + eq("tabnewentered:3:3", nvim('exec', 'tabnew test.x2', true)) end) end) describe('with FILE as <afile>', function() it('matches when opening a new tab for FILE', function() nvim('command', 'au! TabNewEntered Xtest-tabnewentered echom "tabnewentered:match"') eq('tabnewentered:4:4\ntabnewentered:match', - nvim('command_output', 'tabnew Xtest-tabnewentered')) + nvim('exec', 'tabnew Xtest-tabnewentered', true)) end) end) describe('with CTRL-W T', function() @@ -24,7 +24,7 @@ describe('TabNewEntered', function() nvim('command', 'au! TabNewEntered * echom "entered"') nvim('command', 'tabnew test.x2') nvim('command', 'split') - eq('entered', nvim('command_output', 'execute "normal \\<C-W>T"')) + eq('entered', nvim('exec', 'execute "normal \\<C-W>T"', true)) end) end) end) diff --git a/test/functional/cmdline/ctrl_r_spec.lua b/test/functional/cmdline/ctrl_r_spec.lua index d2dad23e98..a0f3955282 100644 --- a/test/functional/cmdline/ctrl_r_spec.lua +++ b/test/functional/cmdline/ctrl_r_spec.lua @@ -15,7 +15,7 @@ describe('cmdline CTRL-R', function() -- <CR> inserted between lines, NOT after the final line. eq('line1abc\rline2somemoretext', funcs.getcmdline()) - -- Yank 2 lines characterwise, then paste to cmdline. + -- Yank 2 lines charwise, then paste to cmdline. feed([[<C-\><C-N>gg05lyvj:<C-R>0]]) -- <CR> inserted between lines, NOT after the final line. eq('abc\rline2', funcs.getcmdline()) diff --git a/test/functional/cmdline/history_spec.lua b/test/functional/cmdline/history_spec.lua index 20f9cf06a2..ee2d36f642 100644 --- a/test/functional/cmdline/history_spec.lua +++ b/test/functional/cmdline/history_spec.lua @@ -6,7 +6,7 @@ describe('history support code', function() before_each(clear) it('correctly clears start of the history', function() - -- Regression test: check absense of the memory leak when clearing start of + -- Regression test: check absence of the memory leak when clearing start of -- the history using ex_getln.c/clr_history(). eq(1, funcs.histadd(':', 'foo')) eq(1, funcs.histdel(':')) @@ -14,7 +14,7 @@ describe('history support code', function() end) it('correctly clears end of the history', function() - -- Regression test: check absense of the memory leak when clearing end of + -- Regression test: check absence of the memory leak when clearing end of -- the history using ex_getln.c/clr_history(). meths.set_option('history', 1) eq(1, funcs.histadd(':', 'foo')) diff --git a/test/functional/ex_cmds/dict_notifications_spec.lua b/test/functional/ex_cmds/dict_notifications_spec.lua index 48e7e05e4c..5c67431221 100644 --- a/test/functional/ex_cmds/dict_notifications_spec.lua +++ b/test/functional/ex_cmds/dict_notifications_spec.lua @@ -357,4 +357,18 @@ describe('VimL dictionary notifications', function() eq(2, eval('1+1')) -- Still alive? end) + it('does not cause use-after-free when unletting from callback', function() + source([[ + let g:called = 0 + function W(...) abort + unlet g:d + let g:called = 1 + endfunction + let g:d = {} + call dictwatcheradd(g:d, '*', function('W')) + let g:d.foo = 123 + ]]) + eq(1, eval('g:called')) + end) + end) diff --git a/test/functional/ex_cmds/script_spec.lua b/test/functional/ex_cmds/script_spec.lua index 4e57d2755d..0a772c559b 100644 --- a/test/functional/ex_cmds/script_spec.lua +++ b/test/functional/ex_cmds/script_spec.lua @@ -22,7 +22,7 @@ describe('script_get-based command', function() %s %s endif ]])):format(cmd, garbage))) - eq('', meths.command_output('messages')) + eq('', meths.exec('messages', true)) if check_neq then neq(0, exc_exec(dedent([[ %s %s @@ -37,7 +37,7 @@ describe('script_get-based command', function() EOF endif ]])):format(cmd, garbage))) - eq('', meths.command_output('messages')) + eq('', meths.exec('messages', true)) if check_neq then eq(true, pcall(source, (dedent([[ let g:exc = 0 diff --git a/test/functional/ex_cmds/sign_spec.lua b/test/functional/ex_cmds/sign_spec.lua index 9d08a66625..891cfe1670 100644 --- a/test/functional/ex_cmds/sign_spec.lua +++ b/test/functional/ex_cmds/sign_spec.lua @@ -16,8 +16,8 @@ describe('sign', function() nvim('command', 'sign place 34 line=3 name=Foo buffer='..buf2) -- now unplace without specifying a buffer nvim('command', 'sign unplace 34') - eq("--- Signs ---\n", nvim('command_output', 'sign place buffer='..buf1)) - eq("--- Signs ---\n", nvim('command_output', 'sign place buffer='..buf2)) + eq("--- Signs ---\n", nvim('exec', 'sign place buffer='..buf1, true)) + eq("--- Signs ---\n", nvim('exec', 'sign place buffer='..buf2, true)) end) end) end) diff --git a/test/functional/example_spec.lua b/test/functional/example_spec.lua index 883fe4ba63..f07f88b2b6 100644 --- a/test/functional/example_spec.lua +++ b/test/functional/example_spec.lua @@ -3,7 +3,10 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local clear, feed = helpers.clear, helpers.feed +local clear = helpers.clear +local command = helpers.command +local eq = helpers.eq +local feed = helpers.feed describe('example', function() local screen @@ -33,4 +36,37 @@ describe('example', function() | ]]) end) + + it('override UI event-handler', function() + -- Example: override the "tabline_update" UI event handler. + -- + -- screen.lua defines default handlers for UI events, but tests + -- may sometimes want to override a handler. + + -- The UI must declare that it wants to handle the UI events. + -- For this example, we enable `ext_tabline`: + screen:detach() + screen = Screen.new(25, 5) + screen:attach({rgb=true, ext_tabline=true}) + + -- From ":help ui" we find that `tabline_update` receives `curtab` and + -- `tabs` objects. So we declare the UI handler like this: + local event_tabs, event_curtab + function screen:_handle_tabline_update(curtab, tabs) + event_curtab, event_tabs = curtab, tabs + end + + -- Create a tabpage... + command('tabedit foo') + + -- Use screen:expect{condition=…} to check the result. + screen:expect{condition=function() + eq({ id = 2 }, event_curtab) + eq({ + {tab = { id = 1 }, name = '[No Name]'}, + {tab = { id = 2 }, name = 'foo'}, + }, + event_tabs) + end} + end) end) diff --git a/test/functional/fixtures/lsp-test-rpc-server.lua b/test/functional/fixtures/lsp-test-rpc-server.lua index 971e61b072..798883ced0 100644 --- a/test/functional/fixtures/lsp-test-rpc-server.lua +++ b/test/functional/fixtures/lsp-test-rpc-server.lua @@ -170,7 +170,7 @@ function tests.basic_check_buffer_open() expect_notification('textDocument/didOpen', { textDocument = { languageId = ""; - text = table.concat({"testing"; "123"}, "\n"); + text = table.concat({"testing"; "123"}, "\n") .. '\n'; uri = "file://"; version = 0; }; @@ -197,6 +197,42 @@ function tests.basic_check_buffer_open_and_change() expect_notification('textDocument/didOpen', { textDocument = { languageId = ""; + text = table.concat({"testing"; "123"}, "\n") .. '\n'; + uri = "file://"; + version = 0; + }; + }) + expect_notification('textDocument/didChange', { + textDocument = { + uri = "file://"; + version = 3; + }; + contentChanges = { + { text = table.concat({"testing"; "boop"}, "\n") .. '\n'; }; + } + }) + expect_notification("finish") + notify('finish') + end; + } +end + +function tests.basic_check_buffer_open_and_change_noeol() + skeleton { + on_init = function(params) + local expected_capabilities = protocol.make_client_capabilities() + assert_eq(params.capabilities, expected_capabilities) + return { + capabilities = { + textDocumentSync = protocol.TextDocumentSyncKind.Full; + } + } + end; + body = function() + notify('start') + expect_notification('textDocument/didOpen', { + textDocument = { + languageId = ""; text = table.concat({"testing"; "123"}, "\n"); uri = "file://"; version = 0; @@ -216,7 +252,6 @@ function tests.basic_check_buffer_open_and_change() end; } end - function tests.basic_check_buffer_open_and_change_multi() skeleton { on_init = function(params) @@ -233,7 +268,7 @@ function tests.basic_check_buffer_open_and_change_multi() expect_notification('textDocument/didOpen', { textDocument = { languageId = ""; - text = table.concat({"testing"; "123"}, "\n"); + text = table.concat({"testing"; "123"}, "\n") .. '\n'; uri = "file://"; version = 0; }; @@ -244,7 +279,7 @@ function tests.basic_check_buffer_open_and_change_multi() version = 3; }; contentChanges = { - { text = table.concat({"testing"; "321"}, "\n"); }; + { text = table.concat({"testing"; "321"}, "\n") .. '\n'; }; } }) expect_notification('textDocument/didChange', { @@ -253,7 +288,7 @@ function tests.basic_check_buffer_open_and_change_multi() version = 4; }; contentChanges = { - { text = table.concat({"testing"; "boop"}, "\n"); }; + { text = table.concat({"testing"; "boop"}, "\n") .. '\n'; }; } }) expect_notification("finish") @@ -278,7 +313,7 @@ function tests.basic_check_buffer_open_and_change_multi_and_close() expect_notification('textDocument/didOpen', { textDocument = { languageId = ""; - text = table.concat({"testing"; "123"}, "\n"); + text = table.concat({"testing"; "123"}, "\n") .. '\n'; uri = "file://"; version = 0; }; @@ -289,7 +324,7 @@ function tests.basic_check_buffer_open_and_change_multi_and_close() version = 3; }; contentChanges = { - { text = table.concat({"testing"; "321"}, "\n"); }; + { text = table.concat({"testing"; "321"}, "\n") .. '\n'; }; } }) expect_notification('textDocument/didChange', { @@ -298,7 +333,7 @@ function tests.basic_check_buffer_open_and_change_multi_and_close() version = 4; }; contentChanges = { - { text = table.concat({"testing"; "boop"}, "\n"); }; + { text = table.concat({"testing"; "boop"}, "\n") .. '\n'; }; } }) expect_notification('textDocument/didClose', { @@ -328,7 +363,7 @@ function tests.basic_check_buffer_open_and_change_incremental() expect_notification('textDocument/didOpen', { textDocument = { languageId = ""; - text = table.concat({"testing"; "123"}, "\n"); + text = table.concat({"testing"; "123"}, "\n") .. '\n'; uri = "file://"; version = 0; }; diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index 9fcd1cf7b1..97248973da 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -706,7 +706,7 @@ module.curwinmeths = module.create_callindex(module.curwin) module.curtabmeths = module.create_callindex(module.curtab) function module.exec_lua(code, ...) - return module.meths.execute_lua(code, {...}) + return module.meths.exec_lua(code, {...}) end function module.redir_exec(cmd) diff --git a/test/functional/lua/overrides_spec.lua b/test/functional/lua/overrides_spec.lua index 8c260632d9..1bccc02847 100644 --- a/test/functional/lua/overrides_spec.lua +++ b/test/functional/lua/overrides_spec.lua @@ -299,14 +299,11 @@ describe('package.path/package.cpath', function() end return new_paths end - local function execute_lua(cmd, ...) - return meths.execute_lua(cmd, {...}) - end local function eval_lua(expr, ...) - return meths.execute_lua('return ' .. expr, {...}) + return meths.exec_lua('return '..expr, {...}) end local function set_path(which, value) - return execute_lua('package[select(1, ...)] = select(2, ...)', which, value) + return exec_lua('package[select(1, ...)] = select(2, ...)', which, value) end it('contains directories from &runtimepath on first invocation', function() diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index 028f2dcd52..22c975147f 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -117,6 +117,34 @@ describe('lua stdlib', function() eq(1, funcs.luaeval('vim.stricmp("\\0C\\0", "\\0B\\0")')) end) + it('vim.startswith', function() + eq(true, funcs.luaeval('vim.startswith("123", "1")')) + eq(true, funcs.luaeval('vim.startswith("123", "")')) + eq(true, funcs.luaeval('vim.startswith("123", "123")')) + eq(true, funcs.luaeval('vim.startswith("", "")')) + + eq(false, funcs.luaeval('vim.startswith("123", " ")')) + eq(false, funcs.luaeval('vim.startswith("123", "2")')) + eq(false, funcs.luaeval('vim.startswith("123", "1234")')) + + eq("string", type(pcall_err(funcs.luaeval, 'vim.startswith("123", nil)'))) + eq("string", type(pcall_err(funcs.luaeval, 'vim.startswith(nil, "123")'))) + end) + + it('vim.endswith', function() + eq(true, funcs.luaeval('vim.endswith("123", "3")')) + eq(true, funcs.luaeval('vim.endswith("123", "")')) + eq(true, funcs.luaeval('vim.endswith("123", "123")')) + eq(true, funcs.luaeval('vim.endswith("", "")')) + + eq(false, funcs.luaeval('vim.endswith("123", " ")')) + eq(false, funcs.luaeval('vim.endswith("123", "2")')) + eq(false, funcs.luaeval('vim.endswith("123", "1234")')) + + eq("string", type(pcall_err(funcs.luaeval, 'vim.endswith("123", nil)'))) + eq("string", type(pcall_err(funcs.luaeval, 'vim.endswith(nil, "123")'))) + end) + it("vim.str_utfindex/str_byteindex", function() exec_lua([[_G.test_text = "xy åäö ɧ 汉语 ↥ 🤦x🦄 å بِيَّ"]]) local indicies32 = {[0]=0,1,2,3,5,7,9,10,12,13,16,19,20,23,24,28,29,33,34,35,37,38,40,42,44,46,48} @@ -353,10 +381,14 @@ describe('lua stdlib', function() it('vim.list_extend', function() eq({1,2,3}, exec_lua [[ return vim.list_extend({1}, {2,3}) ]]) - eq('Error executing lua: .../shared.lua: src must be a table', + eq('Error executing lua: .../shared.lua: src: expected table, got nil', pcall_err(exec_lua, [[ return vim.list_extend({1}, nil) ]])) eq({1,2}, exec_lua [[ return vim.list_extend({1}, {2;a=1}) ]]) eq(true, exec_lua [[ local a = {1} return vim.list_extend(a, {2;a=1}) == a ]]) + eq({2}, exec_lua [[ return vim.list_extend({}, {2;a=1}, 1) ]]) + eq({}, exec_lua [[ return vim.list_extend({}, {2;a=1}, 2) ]]) + eq({}, exec_lua [[ return vim.list_extend({}, {2;a=1}, 1, -1) ]]) + eq({2}, exec_lua [[ return vim.list_extend({}, {2;a=1}, -1, 2) ]]) end) it('vim.tbl_add_reverse_lookup', function() @@ -549,4 +581,78 @@ describe('lua stdlib', function() eq(false, exec_lua("return vim.is_callable('foo')")) eq(false, exec_lua("return vim.is_callable({})")) end) + + it('vim.g', function() + exec_lua [[ + vim.api.nvim_set_var("testing", "hi") + vim.api.nvim_set_var("other", 123) + ]] + eq('hi', funcs.luaeval "vim.g.testing") + eq(123, funcs.luaeval "vim.g.other") + eq(NIL, funcs.luaeval "vim.g.nonexistant") + end) + + it('vim.env', function() + exec_lua [[ + vim.fn.setenv("A", 123) + ]] + eq('123', funcs.luaeval "vim.env.A") + eq(true, funcs.luaeval "vim.env.B == nil") + end) + + it('vim.v', function() + eq(funcs.luaeval "vim.api.nvim_get_vvar('progpath')", funcs.luaeval "vim.v.progpath") + eq(false, funcs.luaeval "vim.v['false']") + eq(NIL, funcs.luaeval "vim.v.null") + end) + + it('vim.bo', function() + eq('', funcs.luaeval "vim.bo.filetype") + exec_lua [[ + vim.api.nvim_buf_set_option(0, "filetype", "markdown") + BUF = vim.api.nvim_create_buf(false, true) + vim.api.nvim_buf_set_option(BUF, "modifiable", false) + ]] + eq(false, funcs.luaeval "vim.bo.modified") + eq('markdown', funcs.luaeval "vim.bo.filetype") + eq(false, funcs.luaeval "vim.bo[BUF].modifiable") + exec_lua [[ + vim.bo.filetype = '' + vim.bo[BUF].modifiable = true + ]] + eq('', funcs.luaeval "vim.bo.filetype") + eq(true, funcs.luaeval "vim.bo[BUF].modifiable") + matches("^Error executing lua: .*: Invalid option name: 'nosuchopt'$", + pcall_err(exec_lua, 'return vim.bo.nosuchopt')) + matches("^Error executing lua: .*: Expected lua string$", + pcall_err(exec_lua, 'return vim.bo[0][0].autoread')) + end) + + it('vim.wo', function() + eq('', funcs.luaeval "vim.bo.filetype") + exec_lua [[ + vim.api.nvim_win_set_option(0, "cole", 2) + BUF = vim.api.nvim_create_buf(false, true) + vim.api.nvim_buf_set_option(BUF, "modifiable", false) + ]] + eq(2, funcs.luaeval "vim.wo.cole") + exec_lua [[ + vim.wo.conceallevel = 0 + vim.bo[BUF].modifiable = true + ]] + eq(0, funcs.luaeval "vim.wo.cole") + matches("^Error executing lua: .*: Invalid option name: 'notanopt'$", + pcall_err(exec_lua, 'return vim.wo.notanopt')) + matches("^Error executing lua: .*: Expected lua string$", + pcall_err(exec_lua, 'return vim.wo[0][0].list')) + end) + + it('vim.cmd', function() + exec_lua [[ + vim.cmd "autocmd BufNew * ++once lua BUF = vim.fn.expand('<abuf>')" + vim.cmd "new" + ]] + eq('2', funcs.luaeval "BUF") + eq(2, funcs.luaeval "#vim.api.nvim_list_bufs()") + end) end) diff --git a/test/functional/normal/put_spec.lua b/test/functional/normal/put_spec.lua index 40a4f051e3..357fafec44 100644 --- a/test/functional/normal/put_spec.lua +++ b/test/functional/normal/put_spec.lua @@ -307,7 +307,7 @@ describe('put command', function() -- }}} -- Conversion functions {{{ - local function convert_characterwise(expect_base, conversion_table, + local function convert_charwise(expect_base, conversion_table, virtualedit_end, visual_put) expect_base = dedent(expect_base) -- There is no difference between 'P' and 'p' when VIsual_active @@ -335,7 +335,7 @@ describe('put command', function() expect_base = expect_base:gsub('(test_stringx?)"', '%1.') end return expect_base - end -- convert_characterwise() + end -- convert_charwise() local function make_back(string) local prev_line @@ -500,7 +500,7 @@ describe('put command', function() local function run_normal_mode_tests(test_string, base_map, extra_setup, virtualedit_end, selection_string) local function convert_closure(e, c) - return convert_characterwise(e, c, virtualedit_end, selection_string) + return convert_charwise(e, c, virtualedit_end, selection_string) end local function expect_normal_creator(expect_base, conversion_table) local test_expect = expect_creator(convert_closure, expect_base, conversion_table) diff --git a/test/functional/options/chars_spec.lua b/test/functional/options/chars_spec.lua index 3453e79429..5439ca3dba 100644 --- a/test/functional/options/chars_spec.lua +++ b/test/functional/options/chars_spec.lua @@ -67,16 +67,29 @@ describe("'fillchars'", function() shouldfail('eob:xy') -- two ascii chars shouldfail('eob:\255', 'eob:<ff>') -- invalid UTF-8 end) - it('is local to window', function() - clear() - screen = Screen.new(50, 5) - screen:attach() + it('has global value', function() + screen:try_resize(50, 5) insert("foo\nbar") command('set laststatus=0') command('1,2fold') command('vsplit') command('set fillchars=fold:x') screen:expect([[ + ^+-- 2 lines: fooxxxxxxxx│+-- 2 lines: fooxxxxxxx| + ~ │~ | + ~ │~ | + ~ │~ | + | + ]]) + end) + it('has local window value', function() + screen:try_resize(50, 5) + insert("foo\nbar") + command('set laststatus=0') + command('1,2fold') + command('vsplit') + command('setl fillchars=fold:x') + screen:expect([[ ^+-- 2 lines: fooxxxxxxxx│+-- 2 lines: foo·······| ~ │~ | ~ │~ | @@ -96,12 +109,25 @@ describe("'listchars'", function() screen:attach() end) - it('is local to window', function() + it('has global value', function() + feed('i<tab><tab><tab><esc>') + command('set list laststatus=0') + command('vsplit') + command('set listchars=tab:<->') + screen:expect([[ + <------><------>^<------> │<------><------><------>| + ~ │~ | + ~ │~ | + ~ │~ | + | + ]]) + end) + it('has value local to window', function() feed('i<tab><tab><tab><esc>') - command('set laststatus=0') - command('set list listchars=tab:<->') + command('set list laststatus=0') + command('setl listchars=tab:<->') command('vsplit') - command('set listchars&') + command('setl listchars<') screen:expect([[ > > ^> │<------><------><------>| ~ │~ | diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua index 490a04186d..57e5077989 100644 --- a/test/functional/options/defaults_spec.lua +++ b/test/functional/options/defaults_spec.lua @@ -224,9 +224,6 @@ describe('startup defaults', function() XDG_DATA_HOME=xdgdir, NVIM_LOG_FILE='', -- Empty is invalid. }}) - -- server_start() calls ELOG, which tickles log_path_init(). - pcall(command, 'call serverstart(serverlist()[0])') - eq(xdgdir..'/'..datasubdir..'/log', string.gsub(eval('$NVIM_LOG_FILE'), '\\', '/')) end) it('defaults to stdpath("data")/log if invalid', function() @@ -235,9 +232,6 @@ describe('startup defaults', function() XDG_DATA_HOME=xdgdir, NVIM_LOG_FILE='.', -- Any directory is invalid. }}) - -- server_start() calls ELOG, which tickles log_path_init(). - pcall(command, 'call serverstart(serverlist()[0])') - eq(xdgdir..'/'..datasubdir..'/log', string.gsub(eval('$NVIM_LOG_FILE'), '\\', '/')) end) it('defaults to .nvimlog if stdpath("data") is invalid', function() @@ -245,9 +239,6 @@ describe('startup defaults', function() XDG_DATA_HOME='Xtest-missing-xdg-dir', NVIM_LOG_FILE='.', -- Any directory is invalid. }}) - -- server_start() calls ELOG, which tickles log_path_init(). - pcall(command, 'call serverstart(serverlist()[0])') - eq('.nvimlog', eval('$NVIM_LOG_FILE')) end) end) diff --git a/test/functional/options/keymap_spec.lua b/test/functional/options/keymap_spec.lua index 7f6d623dc7..52a714f7a8 100644 --- a/test/functional/options/keymap_spec.lua +++ b/test/functional/options/keymap_spec.lua @@ -30,7 +30,7 @@ describe("'keymap' / :lmap", function() command('lmapclear <buffer>') command('set keymap=dvorak') command('set nomore') - local bindings = funcs.nvim_command_output('lmap') + local bindings = funcs.nvim_exec('lmap', true) eq(dedent([[ l " @_ diff --git a/test/functional/plugin/lsp/lsp_spec.lua b/test/functional/plugin/lsp/lsp_spec.lua index cd0974b81c..c38c9b72ce 100644 --- a/test/functional/plugin/lsp/lsp_spec.lua +++ b/test/functional/plugin/lsp/lsp_spec.lua @@ -410,6 +410,54 @@ describe('Language Client API', function() } end) + it('should check the body and didChange full with noeol', function() + local expected_callbacks = { + {NIL, "shutdown", {}, 1}; + {NIL, "finish", {}, 1}; + {NIL, "start", {}, 1}; + } + local client + test_rpc_server { + test_name = "basic_check_buffer_open_and_change_noeol"; + on_setup = function() + exec_lua [[ + BUFFER = vim.api.nvim_create_buf(false, true) + vim.api.nvim_buf_set_lines(BUFFER, 0, -1, false, { + "testing"; + "123"; + }) + vim.api.nvim_buf_set_option(BUFFER, 'eol', false) + ]] + end; + on_init = function(_client) + client = _client + local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") + eq(full_kind, client.resolved_capabilities().text_document_did_change) + eq(true, client.resolved_capabilities().text_document_open_close) + exec_lua [[ + assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) + ]] + end; + on_exit = function(code, signal) + eq(0, code, "exit code") eq(0, signal, "exit signal") + end; + on_callback = function(err, method, params, client_id) + if method == 'start' then + exec_lua [[ + vim.api.nvim_buf_set_lines(BUFFER, 1, 2, false, { + "boop"; + }) + ]] + client.notify('finish') + end + eq(table.remove(expected_callbacks), {err, method, params, client_id}, "expected callback") + if method == 'finish' then + client.stop() + end + end; + } + end) + -- TODO(askhan) we don't support full for now, so we can disable these tests. pending('should check the body and didChange incremental', function() local expected_callbacks = { diff --git a/test/functional/plugin/lsp/util_spec.lua b/test/functional/plugin/lsp/util_spec.lua new file mode 100644 index 0000000000..1cf0e48be4 --- /dev/null +++ b/test/functional/plugin/lsp/util_spec.lua @@ -0,0 +1,76 @@ +local helpers = require('test.functional.helpers')(after_each) +local eq = helpers.eq +local exec_lua = helpers.exec_lua +local dedent = helpers.dedent +local insert = helpers.insert +local clear = helpers.clear + +describe('LSP util', function() + local test_text = dedent([[ + First line of text + Second line of text + Third line of text + Fourth line of text]]) + + local function reset() + clear() + insert(test_text) + end + + before_each(reset) + + local function make_edit(y_0, x_0, y_1, x_1, text) + return { + range = { + start = { line = y_0, character = x_0 }; + ["end"] = { line = y_1, character = x_1 }; + }; + newText = type(text) == 'table' and table.concat(text, '\n') or (text or ""); + } + end + + local function buf_lines(bufnr) + return exec_lua("return vim.api.nvim_buf_get_lines((...), 0, -1, false)", bufnr) + end + + describe('apply_edits', function() + it('should apply simple edits', function() + local edits = { + make_edit(0, 0, 0, 0, {"123"}); + make_edit(1, 0, 1, 1, {"2"}); + make_edit(2, 0, 2, 2, {"3"}); + } + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1) + eq({ + '123First line of text'; + '2econd line of text'; + '3ird line of text'; + 'Fourth line of text'; + }, buf_lines(1)) + end) + + it('should apply complex edits', function() + local edits = { + make_edit(0, 0, 0, 0, {"", "12"}); + make_edit(0, 0, 0, 0, {"3", "foo"}); + make_edit(0, 1, 0, 1, {"bar", "123"}); + make_edit(0, #"First ", 0, #"First line of text", {"guy"}); + make_edit(1, 0, 1, #'Second', {"baz"}); + make_edit(2, #'Th', 2, #"Third", {"e next"}); + make_edit(3, #'', 3, #"Fourth", {"another line of text", "before this"}); + make_edit(3, #'Fourth', 3, #"Fourth line of text", {"!"}); + } + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1) + eq({ + ''; + '123'; + 'fooFbar'; + '123irst guy'; + 'baz line of text'; + 'The next line of text'; + 'another line of text'; + 'before this!'; + }, buf_lines(1)) + end) + end) +end) diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua index 7560b0e872..d40baca871 100644 --- a/test/functional/terminal/buffer_spec.lua +++ b/test/functional/terminal/buffer_spec.lua @@ -5,6 +5,7 @@ local wait = helpers.wait local eval, feed_command, source = helpers.eval, helpers.feed_command, helpers.source local eq, neq = helpers.eq, helpers.neq local write_file = helpers.write_file +local command= helpers.command describe(':terminal buffer', function() local screen @@ -59,7 +60,7 @@ describe(':terminal buffer', function() end) it('does not create swap files', function() - local swapfile = nvim('command_output', 'swapname'):gsub('\n', '') + local swapfile = nvim('exec', 'swapname', true):gsub('\n', '') eq(nil, io.open(swapfile)) end) @@ -224,6 +225,22 @@ describe(':terminal buffer', function() neq('terminal', eval('&buftype')) end) end) + + it('it works with set rightleft #11438', function() + local columns = eval('&columns') + feed(string.rep('a', columns)) + command('set rightleft') + screen:expect([[ + ydaer ytt| + {1:a}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + | + | + | + | + {3:-- TERMINAL --} | + ]]) + command('bdelete!') + end) end) describe('No heap-buffer-overflow when using', function() diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index 676d6ef76d..077e9dc7d5 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -486,7 +486,7 @@ describe('TUI', function() end) it('paste: recovers from vim.paste() failure', function() - child_session:request('nvim_execute_lua', [[ + child_session:request('nvim_exec_lua', [[ _G.save_paste_fn = vim.paste vim.paste = function(lines, phase) error("fake fail") end ]], {}) @@ -544,7 +544,7 @@ describe('TUI', function() {3:-- TERMINAL --} | ]]} -- Paste works if vim.paste() succeeds. - child_session:request('nvim_execute_lua', [[ + child_session:request('nvim_exec_lua', [[ vim.paste = _G.save_paste_fn ]], {}) feed_data('\027[200~line A\nline B\n\027[201~') @@ -563,7 +563,7 @@ describe('TUI', function() it('paste: vim.paste() cancel (retval=false) #10865', function() -- This test only exercises the "cancel" case. Use-case would be "dangling -- paste", but that is not implemented yet. #10865 - child_session:request('nvim_execute_lua', [[ + child_session:request('nvim_exec_lua', [[ vim.paste = function(lines, phase) return false end ]], {}) feed_data('\027[200~line A\nline B\n\027[201~') diff --git a/test/functional/ui/bufhl_spec.lua b/test/functional/ui/bufhl_spec.lua index 65c5f67726..f589bb0e83 100644 --- a/test/functional/ui/bufhl_spec.lua +++ b/test/functional/ui/bufhl_spec.lua @@ -217,6 +217,161 @@ describe('Buffer highlighting', function() | ]]) end) + + it('and adjusting columns', function() + -- insert before + feed('ggiquite <esc>') + screen:expect{grid=[[ + quite^ a {5:longer} example | + in {6:order} to {7:de}{5:monstr}{7:ate} | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]} + + feed('u') + screen:expect{grid=[[ + ^a {5:longer} example | + in {6:order} to {7:de}{5:monstr}{7:ate} | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {1:~ }| + {1:~ }| + 1 change; before #2 {MATCH:.*}| + ]]} + + -- change/insert in the middle + feed('+fesAAAA') + screen:expect{grid=[[ + a {5:longer} example | + in {6:ordAAAA^r} to {7:de}{5:monstr}{7:ate} | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {1:~ }| + {1:~ }| + {7:-- INSERT --} | + ]]} + + feed('<esc>tdD') + screen:expect{grid=[[ + a {5:longer} example | + in {6:ordAAAAr} t^o | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]} + + feed('u') + screen:expect{grid=[[ + a {5:longer} example | + in {6:ordAAAAr} to^ demonstrate | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {1:~ }| + {1:~ }| + 1 change; before #4 {MATCH:.*}| + ]]} + + feed('u') + screen:expect{grid=[[ + a {5:longer} example | + in {6:ord^er} to demonstrate | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {1:~ }| + {1:~ }| + 1 change; before #3 {MATCH:.*}| + ]]} + end) + + it('and joining lines', function() + feed('ggJJJ') + screen:expect{grid=[[ + a {5:longer} example in {6:order} to {7:de}{5:monstr}{7:ate}| + {7: combin}{8:ing hi}{7:ghlights^ }{8:from diff}{7:erent sou}| + {7:rces} | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]} + + -- TODO(bfredl): perhaps better undo + feed('uuu') + screen:expect{grid=[[ + ^a longer example | + in order to demonstrate | + combining highlights | + from different sources | + {1:~ }| + {1:~ }| + {1:~ }| + 1 more line; before #2 {MATCH:.*}| + ]]} + end) + + it('and splitting lines', function() + feed('2Gtti<cr>') + screen:expect{grid=[[ + a {5:longer} example | + in {6:order} | + ^ to {7:de}{5:monstr}{7:ate} | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {1:~ }| + {7:-- INSERT --} | + ]]} + + -- TODO(bfredl): keep both "parts" after split, requires proper extmark ranges + feed('<esc>tsi<cr>') + screen:expect{grid=[[ + a {5:longer} example | + in {6:order} | + to {7:de}{5:mo} | + ^nstrate | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {7:-- INSERT --} | + ]]} + + -- TODO(bfredl): perhaps better undo + feed('<esc>u') + screen:expect{grid=[[ + a {5:longer} example | + in {6:order} | + to demo{7:^nstrat}{8:e} | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {1:~ }| + 1 line less; before #3 {MATCH:.*}| + ]]} + + feed('<esc>u') + screen:expect{grid=[[ + a {5:longer} example | + in order^ to demonstrate | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {1:~ }| + {1:~ }| + 1 line less; before #2 {MATCH:.*}| + ]]} + end) end) it('prioritizes latest added highlight', function() diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua index 052414a43d..9c746b99bd 100644 --- a/test/functional/ui/cmdline_highlight_spec.lua +++ b/test/functional/ui/cmdline_highlight_spec.lua @@ -362,7 +362,7 @@ describe('Command-line coloring', function() {EOB:~ }| :e^ | ]]) - eq('', meths.command_output('messages')) + eq('', meths.exec('messages', true)) end) it('silences :echon', function() set_color_cb('Echoning') @@ -377,7 +377,7 @@ describe('Command-line coloring', function() {EOB:~ }| :e^ | ]]) - eq('', meths.command_output('messages')) + eq('', meths.exec('messages', true)) end) it('silences :echomsg', function() set_color_cb('Echomsging') @@ -392,7 +392,7 @@ describe('Command-line coloring', function() {EOB:~ }| :e^ | ]]) - eq('', meths.command_output('messages')) + eq('', meths.exec('messages', true)) end) it('does the right thing when throwing', function() set_color_cb('Throwing') @@ -857,7 +857,7 @@ describe('Ex commands coloring', function() ]]) feed('<CR>') eq('Error detected while processing :\nE605: Exception not caught: 42\nE749: empty buffer', - meths.command_output('messages')) + meths.exec('messages', true)) end) it('errors out when failing to get callback', function() meths.set_var('Nvim_color_cmdline', 42) diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua index c2354103c2..21c01b3458 100644 --- a/test/functional/ui/cmdline_spec.lua +++ b/test/functional/ui/cmdline_spec.lua @@ -775,7 +775,7 @@ local function test_cmdline(linegrid) }}} -- This used to send an invalid event where pos where larger than the total - -- lenght of content. Checked in _handle_cmdline_show. + -- length of content. Checked in _handle_cmdline_show. feed('<esc>') screen:expect([[ ^ | diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua index dbaf6f802b..7a5569c14b 100644 --- a/test/functional/ui/float_spec.lua +++ b/test/functional/ui/float_spec.lua @@ -2,9 +2,11 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local os = require('os') local clear, feed = helpers.clear, helpers.feed +local assert_alive = helpers.assert_alive local command, feed_command = helpers.command, helpers.feed_command local eval = helpers.eval local eq = helpers.eq +local exec_lua = helpers.exec_lua local insert = helpers.insert local meths = helpers.meths local curbufmeths = helpers.curbufmeths @@ -12,7 +14,7 @@ local funcs = helpers.funcs local run = helpers.run local pcall_err = helpers.pcall_err -describe('floating windows', function() +describe('floatwin', function() before_each(function() clear() end) @@ -39,6 +41,7 @@ describe('floating windows', function() [19] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGray}, [20] = {bold = true, foreground = Screen.colors.Brown}, [21] = {background = Screen.colors.Gray90}, + [22] = {background = Screen.colors.LightRed}, } it('behavior', function() @@ -55,6 +58,31 @@ describe('floating windows', function() eq(1000, funcs.win_getid()) end) + it('closed immediately by autocmd #11383', function() + eq('Error executing lua: [string "<nvim>"]:4: Window was closed immediately', + pcall_err(exec_lua, [[ + local a = vim.api + local function crashes(contents) + local buf = a.nvim_create_buf(false, true) + local floatwin = a.nvim_open_win(buf, true, { + relative = 'cursor'; + style = 'minimal'; + row = 0; col = 0; + height = #contents; + width = 10; + }) + a.nvim_buf_set_lines(buf, 0, -1, true, contents) + local winnr = vim.fn.win_id2win(floatwin) + a.nvim_command('wincmd p') + a.nvim_command('autocmd CursorMoved * ++once '..winnr..'wincmd c') + return buf, floatwin + end + crashes{'foo'} + crashes{'bar'} + ]])) + assert_alive() + end) + local function with_ext_multigrid(multigrid) local screen before_each(function() @@ -398,6 +426,7 @@ describe('floating windows', function() it("can use 'minimal' style", function() command('set number') command('set signcolumn=yes') + command('set colorcolumn=1') command('set cursorline') command('set foldcolumn=1') command('hi NormalFloat guibg=#333333') @@ -414,9 +443,9 @@ describe('floating windows', function() [2:----------------------------------------]| [3:----------------------------------------]| ## grid 2 - {19: }{20: 1 }{21:^x }| - {19: }{14: 2 }y | - {19: }{14: 3 } | + {19: }{20: 1 }{22:^x}{21: }| + {19: }{14: 2 }{22:y} | + {19: }{14: 3 }{22: } | {0:~ }| {0:~ }| {0:~ }| @@ -430,9 +459,9 @@ describe('floating windows', function() ]], float_pos={[4] = {{id = 1001}, "NW", 1, 4, 10, true}}} else screen:expect{grid=[[ - {19: }{20: 1 }{21:^x }| - {19: }{14: 2 }y | - {19: }{14: 3 } {15:x } | + {19: }{20: 1 }{22:^x}{21: }| + {19: }{14: 2 }{22:y} | + {19: }{14: 3 }{22: } {15:x } | {0:~ }{15:y }{0: }| {0:~ }{15: }{0: }| {0:~ }{15: }{0: }| @@ -454,9 +483,9 @@ describe('floating windows', function() [2:----------------------------------------]| [3:----------------------------------------]| ## grid 2 - {19: }{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{21:^x }| - {19: }{14: 2 }y | - {19: }{14: 3 } | + {19: }{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{22:^x}{21: }| + {19: }{14: 2 }{22:y} | + {19: }{14: 3 }{22: } | {0:~ }| {0:~ }| {0:~ }| @@ -471,9 +500,9 @@ describe('floating windows', function() else screen:expect([[ - {19: }{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{21:^x }| - {19: }{14: 2 }y | - {19: }{14: 3 } {17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{15:x } | + {19: }{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{22:^x}{21: }| + {19: }{14: 2 }{22:y} | + {19: }{14: 3 }{22: } {17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{15:x } | {0:~ }{19: }{15:y }{0: }| {0:~ }{19: }{15: }{0: }| {0:~ }{15: }{0: }| @@ -495,9 +524,9 @@ describe('floating windows', function() [2:----------------------------------------]| [3:----------------------------------------]| ## grid 2 - {19: }{20: 1 }{21:^x }| - {19: }{14: 2 }y | - {19: }{14: 3 } | + {19: }{20: 1 }{22:^x}{21: }| + {19: }{14: 2 }{22:y} | + {19: }{14: 3 }{22: } | {0:~ }| {0:~ }| {0:~ }| @@ -511,9 +540,9 @@ describe('floating windows', function() ]], float_pos={[4] = {{id = 1001}, "NW", 1, 4, 10, true}}} else screen:expect([[ - {19: }{20: 1 }{21:^x }| - {19: }{14: 2 }y | - {19: }{14: 3 } {15: } | + {19: }{20: 1 }{22:^x}{21: }| + {19: }{14: 2 }{22:y} | + {19: }{14: 3 }{22: } {15: } | {0:~ }{15: }{0: }| {0:~ }{15: }{0: }| {0:~ }{15: }{0: }| diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua index 40ea030f73..25b38b1feb 100644 --- a/test/functional/ui/messages_spec.lua +++ b/test/functional/ui/messages_spec.lua @@ -861,7 +861,7 @@ describe('ui/builtin messages', function() -- screen size doesn't affect internal output #10285 eq('ErrorMsg xxx ctermfg=15 ctermbg=1 guifg=White guibg=Red', - meths.command_output("hi ErrorMsg")) + meths.exec("hi ErrorMsg", true)) end) it(':syntax list langGroup output', function() @@ -900,7 +900,7 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim match /\<endif\s\+".*$/ms=s+5,lc=5 contains=@vimCommentGroup,vimCommentString match /\<else\s\+".*$/ms=s+4,lc=4 contains=@vimCommentGroup,vimCommentString links to Comment]], - meths.command_output('syntax list vimComment')) + meths.exec('syntax list vimComment', true)) -- luacheck: pop end) diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua index 7840ba9167..d857b57a31 100644 --- a/test/functional/ui/mouse_spec.lua +++ b/test/functional/ui/mouse_spec.lua @@ -12,7 +12,10 @@ describe('ui/mouse/input', function() clear() meths.set_option('mouse', 'a') meths.set_option('list', true) - meths.set_option('listchars', 'eol:$') + -- NB: this is weird, but mostly irrelevant to the test + -- So I didn't bother to change it + command('set listchars=eol:$') + command('setl listchars=nbsp:x') screen = Screen.new(25, 5) screen:attach() screen:set_default_attr_ids({ @@ -812,7 +815,8 @@ describe('ui/mouse/input', function() feed_command('set concealcursor=ni') feed_command('set nowrap') - feed_command('set shiftwidth=2 tabstop=4 list listchars=tab:>-') + feed_command('set shiftwidth=2 tabstop=4 list') + feed_command('setl listchars=tab:>-') feed_command('syntax match NonText "\\*" conceal') feed_command('syntax match NonText "cats" conceal cchar=X') feed_command('syntax match NonText "x" conceal cchar=>') diff --git a/test/functional/ui/options_spec.lua b/test/functional/ui/options_spec.lua index ea71f5eae9..581e196bbb 100644 --- a/test/functional/ui/options_spec.lua +++ b/test/functional/ui/options_spec.lua @@ -5,7 +5,7 @@ local command = helpers.command local eq = helpers.eq local shallowcopy = helpers.shallowcopy -describe('ui receives option updates', function() +describe('UI receives option updates', function() local screen local function reset(opts, ...) @@ -47,6 +47,33 @@ describe('ui receives option updates', function() end) end) + it('on attach #11372', function() + clear() + local evs = {} + screen = Screen.new(20,5) + -- Override mouse_on/mouse_off handlers. + function screen:_handle_mouse_on() + table.insert(evs, 'mouse_on') + end + function screen:_handle_mouse_off() + table.insert(evs, 'mouse_off') + end + screen:attach() + screen:expect(function() + eq({'mouse_off'}, evs) + end) + command("set mouse=nvi") + screen:expect(function() + eq({'mouse_off','mouse_on'}, evs) + end) + screen:detach() + eq({'mouse_off','mouse_on'}, evs) + screen:attach() + screen:expect(function() + eq({'mouse_off','mouse_on','mouse_on'}, evs) + end) + end) + it("when setting options", function() local expected = reset() local defaults = shallowcopy(expected) diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua index d3f78bf77b..64f784afe3 100644 --- a/test/functional/ui/screen.lua +++ b/test/functional/ui/screen.lua @@ -606,17 +606,12 @@ function Screen:_redraw(updates) for i = 2, #update do local handler_name = '_handle_'..method local handler = self[handler_name] - if handler ~= nil then - local status, res = pcall(handler, self, unpack(update[i])) - if not status then - error(handler_name..' failed' - ..'\n payload: '..inspect(update) - ..'\n error: '..tostring(res)) - end - else - assert(self._on_event, - "Add Screen:"..handler_name.." or call Screen:set_on_event_handler") - self._on_event(method, update[i]) + assert(handler ~= nil, "missing handler: Screen:"..handler_name) + local status, res = pcall(handler, self, unpack(update[i])) + if not status then + error(handler_name..' failed' + ..'\n payload: '..inspect(update) + ..'\n error: '..tostring(res)) end end if k == #updates and method == "flush" then @@ -626,10 +621,6 @@ function Screen:_redraw(updates) return did_flush end -function Screen:set_on_event_handler(callback) - self._on_event = callback -end - function Screen:_handle_resize(width, height) self:_handle_grid_resize(1, width, height) self._scroll_region = { diff --git a/test/functional/ui/searchhl_spec.lua b/test/functional/ui/searchhl_spec.lua index 486de02a09..635ce7392b 100644 --- a/test/functional/ui/searchhl_spec.lua +++ b/test/functional/ui/searchhl_spec.lua @@ -442,7 +442,7 @@ describe('search highlighting', function() feed_command("call matchadd('MyGroup', 'special')") feed_command("call matchadd('MyGroup2', 'text', 0)") - -- searchhl and matchadd matches are exclusive, only the higest priority + -- searchhl and matchadd matches are exclusive, only the highest priority -- is used (and matches with lower priorities are not combined) feed_command("/ial te") screen:expect([[ diff --git a/test/functional/ui/tabline_spec.lua b/test/functional/ui/tabline_spec.lua index 0ee7e03fac..23aae81745 100644 --- a/test/functional/ui/tabline_spec.lua +++ b/test/functional/ui/tabline_spec.lua @@ -10,11 +10,9 @@ describe('ui/ext_tabline', function() clear() screen = Screen.new(25, 5) screen:attach({rgb=true, ext_tabline=true}) - screen:set_on_event_handler(function(name, data) - if name == "tabline_update" then - event_curtab, event_tabs = unpack(data) - end - end) + function screen:_handle_tabline_update(curtab, tabs) + event_curtab, event_tabs = curtab, tabs + end end) it('publishes UI events', function() |