aboutsummaryrefslogtreecommitdiff
path: root/test/functional
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional')
-rw-r--r--test/functional/api/highlight_spec.lua11
-rw-r--r--test/functional/api/keymap_spec.lua80
-rw-r--r--test/functional/api/vim_spec.lua6
-rw-r--r--test/functional/editor/mark_spec.lua7
-rw-r--r--test/functional/editor/meta_key_spec.lua2
-rw-r--r--test/functional/editor/put_spec.lua9
-rw-r--r--test/functional/editor/tabpage_spec.lua41
-rw-r--r--test/functional/ex_cmds/mksession_spec.lua115
-rw-r--r--test/functional/fixtures/fake-lsp-server.lua30
-rw-r--r--test/functional/helpers.lua20
-rw-r--r--test/functional/legacy/075_maparg_spec.lua59
-rw-r--r--test/functional/legacy/arglist_spec.lua3
-rw-r--r--test/functional/legacy/cmdline_spec.lua29
-rw-r--r--test/functional/legacy/ex_mode_spec.lua51
-rw-r--r--test/functional/legacy/excmd_spec.lua619
-rw-r--r--test/functional/legacy/global_spec.lua51
-rw-r--r--test/functional/legacy/messages_spec.lua25
-rw-r--r--test/functional/legacy/syn_attr_spec.lua60
-rw-r--r--test/functional/lua/vim_spec.lua46
-rw-r--r--test/functional/plugin/lsp_spec.lua40
-rw-r--r--test/functional/terminal/buffer_spec.lua49
-rw-r--r--test/functional/terminal/tui_spec.lua12
-rw-r--r--test/functional/ui/cmdline_spec.lua263
-rw-r--r--test/functional/ui/cursor_spec.lua2
-rw-r--r--test/functional/ui/diff_spec.lua89
-rw-r--r--test/functional/ui/float_spec.lua10
-rw-r--r--test/functional/ui/fold_spec.lua77
-rw-r--r--test/functional/ui/messages_spec.lua20
-rw-r--r--test/functional/ui/mouse_spec.lua18
-rw-r--r--test/functional/ui/options_spec.lua9
-rw-r--r--test/functional/ui/statusline_spec.lua87
-rw-r--r--test/functional/ui/winbar_spec.lua45
-rw-r--r--test/functional/vimscript/buf_functions_spec.lua4
-rw-r--r--test/functional/vimscript/let_spec.lua3
-rw-r--r--test/functional/vimscript/map_functions_spec.lua34
-rw-r--r--test/functional/vimscript/system_spec.lua23
36 files changed, 1638 insertions, 411 deletions
diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua
index 933103046c..c4197f0b3e 100644
--- a/test/functional/api/highlight_spec.lua
+++ b/test/functional/api/highlight_spec.lua
@@ -34,6 +34,7 @@ describe('API: highlight',function()
underdotted = true,
underdashed = true,
strikethrough = true,
+ nocombine = true,
}
before_each(function()
@@ -55,7 +56,7 @@ describe('API: highlight',function()
eq('Invalid highlight id: 30000', string.match(emsg, 'Invalid.*'))
-- Test all highlight properties.
- command('hi NewHighlight gui=underline,bold,undercurl,underdouble,underdotted,underdashed,italic,reverse,strikethrough')
+ command('hi NewHighlight gui=underline,bold,undercurl,underdouble,underdotted,underdashed,italic,reverse,strikethrough,nocombine')
eq(expected_rgb2, nvim("get_hl_by_id", hl_id, true))
-- Test nil argument.
@@ -136,10 +137,10 @@ describe('API: highlight',function()
-- Test cterm & Normal values. #18024 (tail) & #18980
-- Ensure Normal, and groups that match Normal return their fg & bg cterm values
meths.set_hl(0, 'Normal', {ctermfg = 17, ctermbg = 213})
- meths.set_hl(0, 'NotNormal', {ctermfg = 17, ctermbg = 213})
+ meths.set_hl(0, 'NotNormal', {ctermfg = 17, ctermbg = 213, nocombine = true})
-- Note colors are "cterm" values, not rgb-as-ints
eq({foreground = 17, background = 213}, nvim("get_hl_by_name", 'Normal', false))
- eq({foreground = 17, background = 213}, nvim("get_hl_by_name", 'NotNormal', false))
+ eq({foreground = 17, background = 213, nocombine = true}, nvim("get_hl_by_name", 'NotNormal', false))
end)
it('nvim_get_hl_id_by_name', function()
@@ -214,6 +215,7 @@ describe("API: set highlight", function()
reverse = true,
undercurl = true,
strikethrough = true,
+ nocombine = true,
}
}
local highlight3_result_gui = {
@@ -236,6 +238,7 @@ describe("API: set highlight", function()
reverse = true,
undercurl = true,
strikethrough = true,
+ nocombine = true,
}
local function get_ns()
@@ -290,7 +293,7 @@ describe("API: set highlight", function()
exec_capture('highlight Test_hl'))
meths.set_hl(0, 'Test_hl2', highlight3_config)
- eq('Test_hl2 xxx cterm=undercurl,italic,reverse,strikethrough ctermfg=8 ctermbg=15 gui=bold,underline,undercurl,underdouble,underdotted,underdashed,italic,reverse,strikethrough guifg=#ff0000 guibg=#0032aa',
+ eq('Test_hl2 xxx cterm=undercurl,italic,reverse,strikethrough,nocombine ctermfg=8 ctermbg=15 gui=bold,underline,undercurl,underdouble,underdotted,underdashed,italic,reverse,strikethrough guifg=#ff0000 guibg=#0032aa',
exec_capture('highlight Test_hl2'))
-- Colors are stored with the name they are defined, but
diff --git a/test/functional/api/keymap_spec.lua b/test/functional/api/keymap_spec.lua
index 6bc6651e04..eb2a467a8b 100644
--- a/test/functional/api/keymap_spec.lua
+++ b/test/functional/api/keymap_spec.lua
@@ -25,6 +25,7 @@ describe('nvim_get_keymap', function()
local foo_bar_string = 'nnoremap foo bar'
local foo_bar_map_table = {
lhs='foo',
+ lhsraw='foo',
script=0,
silent=0,
rhs='bar',
@@ -56,6 +57,7 @@ describe('nvim_get_keymap', function()
command('nnoremap foo_longer bar_longer')
local foolong_bar_map_table = shallowcopy(foo_bar_map_table)
foolong_bar_map_table['lhs'] = 'foo_longer'
+ foolong_bar_map_table['lhsraw'] = 'foo_longer'
foolong_bar_map_table['rhs'] = 'bar_longer'
eq({foolong_bar_map_table, foo_bar_map_table},
@@ -87,6 +89,7 @@ describe('nvim_get_keymap', function()
command('nnoremap foo_longer bar_longer')
local foolong_bar_map_table = shallowcopy(foo_bar_map_table)
foolong_bar_map_table['lhs'] = 'foo_longer'
+ foolong_bar_map_table['lhsraw'] = 'foo_longer'
foolong_bar_map_table['rhs'] = 'bar_longer'
local buffer_table = shallowcopy(foo_bar_map_table)
@@ -283,6 +286,16 @@ describe('nvim_get_keymap', function()
command('onoremap \\<C-a><C-a><LT>C-a>\\ \\<C-b><C-b><LT>C-b>\\')
command('onoremap <special> \\<C-c><C-c><LT>C-c>\\ \\<C-d><C-d><LT>C-d>\\')
+ -- wrapper around get_keymap() that drops "lhsraw" and "lhsrawalt" which are hard to check
+ local function get_keymap_noraw(...)
+ local ret = meths.get_keymap(...)
+ for _, item in ipairs(ret) do
+ item.lhsraw = nil
+ item.lhsrawalt = nil
+ end
+ return ret
+ end
+
for _, cmd in ipairs({
'set cpo-=B',
'set cpo+=B',
@@ -290,22 +303,23 @@ describe('nvim_get_keymap', function()
command(cmd)
eq({cpomap('\\<C-C><C-C><lt>C-c>\\', '\\<C-D><C-D><lt>C-d>\\', 'n'),
cpomap('\\<C-A><C-A><lt>C-a>\\', '\\<C-B><C-B><lt>C-b>\\', 'n')},
- meths.get_keymap('n'))
+ get_keymap_noraw('n'))
eq({cpomap('\\<C-C><C-C><lt>C-c>\\', '\\<C-D><C-D><lt>C-d>\\', 'x'),
cpomap('\\<C-A><C-A><lt>C-a>\\', '\\<C-B><C-B><lt>C-b>\\', 'x')},
- meths.get_keymap('x'))
+ get_keymap_noraw('x'))
eq({cpomap('<lt>C-c><C-C><lt>C-c> ', '<lt>C-d><C-D><lt>C-d>', 's'),
cpomap('<lt>C-a><C-A><lt>C-a> ', '<lt>C-b><C-B><lt>C-b>', 's')},
- meths.get_keymap('s'))
+ get_keymap_noraw('s'))
eq({cpomap('<lt>C-c><C-C><lt>C-c> ', '<lt>C-d><C-D><lt>C-d>', 'o'),
cpomap('<lt>C-a><C-A><lt>C-a> ', '<lt>C-b><C-B><lt>C-b>', 'o')},
- meths.get_keymap('o'))
+ get_keymap_noraw('o'))
end
end)
it('always uses space for space and bar for bar', function()
local space_table = {
lhs='| |',
+ lhsraw='| |',
rhs='| |',
mode='n',
script=0,
@@ -340,6 +354,7 @@ describe('nvim_get_keymap', function()
mapargs[1].callback = nil
eq({
lhs='asdf',
+ lhsraw='asdf',
script=0,
silent=0,
expr=0,
@@ -356,6 +371,7 @@ describe('nvim_get_keymap', function()
meths.set_keymap('n', 'lhs', 'rhs', {desc="map description"})
eq({
lhs='lhs',
+ lhsraw='lhs',
rhs='rhs',
script=0,
silent=0,
@@ -413,7 +429,11 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
-- Gets a maparg() dict from Nvim, if one exists.
local function get_mapargs(mode, lhs)
- return funcs.maparg(lhs, normalize_mapmode(mode), false, true)
+ local mapargs = funcs.maparg(lhs, normalize_mapmode(mode), false, true)
+ -- drop "lhsraw" and "lhsrawalt" which are hard to check
+ mapargs.lhsraw = nil
+ mapargs.lhsrawalt = nil
+ return mapargs
end
it('error on empty LHS', function()
@@ -503,6 +523,11 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
pcall_err(meths.set_keymap, 'n', 'lhs', 'rhs', {buffer = true}))
end)
+ it('error when "replace_keycodes" is used without "expr"', function()
+ eq('"replace_keycodes" requires "expr"',
+ pcall_err(meths.set_keymap, 'n', 'lhs', 'rhs', {replace_keycodes = true}))
+ end)
+
local optnames = {'nowait', 'silent', 'script', 'expr', 'unique'}
for _, opt in ipairs(optnames) do
-- note: need '%' to escape hyphens, which have special meaning in lua
@@ -817,17 +842,39 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
local mapargs = funcs.maparg('asdf', 'n', false, true)
assert(type(mapargs.callback) == 'number', 'callback is not luaref number')
mapargs.callback = nil
+ mapargs.lhsraw = nil
+ mapargs.lhsrawalt = nil
eq(generate_mapargs('n', 'asdf', nil, {sid=sid_lua}), mapargs)
end)
- it('can make lua expr mappings', function()
+ it('can make lua expr mappings replacing keycodes', function()
exec_lua [[
- vim.api.nvim_set_keymap ('n', 'aa', '', {callback = function() return vim.api.nvim_replace_termcodes(':lua SomeValue = 99<cr>', true, false, true) end, expr = true })
+ vim.api.nvim_set_keymap ('n', 'aa', '', {callback = function() return '<Insert>π<C-V><M-π>foo<lt><Esc>' end, expr = true, replace_keycodes = true })
]]
feed('aa')
- eq(99, exec_lua[[return SomeValue]])
+ eq({'π<M-π>foo<'}, meths.buf_get_lines(0, 0, -1, false))
+ end)
+
+ it('can make lua expr mappings without replacing keycodes', function()
+ exec_lua [[
+ vim.api.nvim_set_keymap ('i', 'aa', '', {callback = function() return '<space>' end, expr = true })
+ ]]
+
+ feed('iaa<esc>')
+
+ eq({'<space>'}, meths.buf_get_lines(0, 0, -1, false))
+ end)
+
+ it('lua expr mapping returning nil is equivalent to returnig an empty string', function()
+ exec_lua [[
+ vim.api.nvim_set_keymap ('i', 'aa', '', {callback = function() return nil end, expr = true })
+ ]]
+
+ feed('iaa<esc>')
+
+ eq({''}, meths.buf_get_lines(0, 0, -1, false))
end)
it('does not reset pum in lua mapping', function()
@@ -1018,16 +1065,27 @@ describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function()
eq(1, exec_lua[[return GlobalCount]])
end)
- it('can make lua expr mappings', function()
+ it('can make lua expr mappings replacing keycodes', function()
exec_lua [[
- vim.api.nvim_buf_set_keymap (0, 'n', 'aa', '', {callback = function() return vim.api.nvim_replace_termcodes(':lua SomeValue = 99<cr>', true, false, true) end, expr = true })
+ vim.api.nvim_buf_set_keymap (0, 'n', 'aa', '', {callback = function() return '<Insert>π<C-V><M-π>foo<lt><Esc>' end, expr = true, replace_keycodes = true })
]]
feed('aa')
- eq(99, exec_lua[[return SomeValue ]])
+ eq({'π<M-π>foo<'}, meths.buf_get_lines(0, 0, -1, false))
+ end)
+
+ it('can make lua expr mappings without replacing keycodes', function()
+ exec_lua [[
+ vim.api.nvim_buf_set_keymap (0, 'i', 'aa', '', {callback = function() return '<space>' end, expr = true })
+ ]]
+
+ feed('iaa<esc>')
+
+ eq({'<space>'}, meths.buf_get_lines(0, 0, -1, false))
end)
+
it('can overwrite lua mappings', function()
eq(0, exec_lua [[
GlobalCount = 0
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index 3724dbf820..17de6730fb 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -3733,6 +3733,12 @@ describe('API', function()
eq("", meths.cmd({ cmd = "Foo", bang = false }, { output = true }))
end)
it('works with modifiers', function()
+ -- with :silent output is still captured
+ eq('1',
+ meths.cmd({ cmd = 'echomsg', args = { '1' }, mods = { silent = true } },
+ { output = true }))
+ -- with :silent message isn't added to message history
+ eq('', meths.cmd({ cmd = 'messages' }, { output = true }))
meths.create_user_command("Foo", 'set verbose', {})
eq(" verbose=1", meths.cmd({ cmd = "Foo", mods = { verbose = 1 } }, { output = true }))
eq(0, meths.get_option_value("verbose", {}))
diff --git a/test/functional/editor/mark_spec.lua b/test/functional/editor/mark_spec.lua
index 1eb76aa628..2440867c6e 100644
--- a/test/functional/editor/mark_spec.lua
+++ b/test/functional/editor/mark_spec.lua
@@ -157,6 +157,13 @@ describe('named marks', function()
os.remove(file1)
end)
+ it("errors when using a mark in another buffer in command range", function()
+ feed('ifoo<Esc>mA')
+ command('enew')
+ feed('ibar<Esc>')
+ eq('Vim(print):E20: Mark not set', pcall_err(command, [['Aprint]]))
+ end)
+
it("leave a context mark when moving with '", function()
command("edit " .. file1)
feed("llmamA")
diff --git a/test/functional/editor/meta_key_spec.lua b/test/functional/editor/meta_key_spec.lua
index 23964ca10f..825b20138a 100644
--- a/test/functional/editor/meta_key_spec.lua
+++ b/test/functional/editor/meta_key_spec.lua
@@ -91,7 +91,7 @@ describe('meta-keys #8226 #13042', function()
command('tnoremap <A-j> alt-j')
feed('i<M-l> xxx <A-j>')
eq('meta-l xxx alt-j', exec_lua([[return _G.input_data]]))
- -- Unmapped ALT-chord is sent to terminal as-is. #16220
+ -- Unmapped ALT-chord is sent to terminal as-is. #16202 #16220
exec_lua([[_G.input_data = '']])
command('tunmap <M-l>')
feed('<M-l>')
diff --git a/test/functional/editor/put_spec.lua b/test/functional/editor/put_spec.lua
index cc9fce8f67..5050edff5c 100644
--- a/test/functional/editor/put_spec.lua
+++ b/test/functional/editor/put_spec.lua
@@ -879,9 +879,13 @@ describe('put command', function()
ine of words 2]], curbuf_contents())
end)
- local function bell_test(actions, should_ring)
- local screen = Screen.new()
+ local screen
+ setup(function()
+ screen = Screen.new()
screen:attach()
+ end)
+
+ local function bell_test(actions, should_ring)
if should_ring then
-- check bell is not set by nvim before the action
screen:sleep(50)
@@ -899,7 +903,6 @@ describe('put command', function()
end
end
end, unchanged=(not should_ring)}
- screen:detach()
end
it('should not ring the bell with gp at end of line', function()
diff --git a/test/functional/editor/tabpage_spec.lua b/test/functional/editor/tabpage_spec.lua
index 3b2c1db350..7dd0b9f154 100644
--- a/test/functional/editor/tabpage_spec.lua
+++ b/test/functional/editor/tabpage_spec.lua
@@ -1,4 +1,5 @@
local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
local command = helpers.command
@@ -53,6 +54,46 @@ describe('tabpage', function()
neq(999, eval('g:win_closed'))
end)
+ it('switching tabpage after setting laststatus=3 #19591', function()
+ local screen = Screen.new(40, 8)
+ screen:set_default_attr_ids({
+ [0] = {bold = true, foreground = Screen.colors.Blue},
+ [1] = {bold = true, reverse = true}, -- StatusLine
+ [2] = {reverse = true}, -- StatusLineNC, TabLineFill
+ [3] = {bold = true}, -- TabLineSel
+ [4] = {background = Screen.colors.LightGrey, underline = true}, -- TabLine
+ [5] = {bold = true, foreground = Screen.colors.Magenta},
+ })
+ screen:attach()
+
+ command('tabnew')
+ command('tabprev')
+ command('set laststatus=3')
+ command('tabnext')
+ feed('<C-G>')
+ screen:expect([[
+ {4: [No Name] }{3: [No Name] }{2: }{4:X}|
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {1:[No Name] }|
+ "[No Name]" --No lines in buffer-- |
+ ]])
+ command('vnew')
+ screen:expect([[
+ {4: [No Name] }{3: }{5:2}{3: [No Name] }{2: }{4:X}|
+ ^ │ |
+ {0:~ }│{0:~ }|
+ {0:~ }│{0:~ }|
+ {0:~ }│{0:~ }|
+ {0:~ }│{0:~ }|
+ {1:[No Name] }|
+ "[No Name]" --No lines in buffer-- |
+ ]])
+ end)
+
it(":tabmove handles modifiers and addr", function()
command('tabnew | tabnew | tabnew')
eq(4, funcs.nvim_tabpage_get_number(0))
diff --git a/test/functional/ex_cmds/mksession_spec.lua b/test/functional/ex_cmds/mksession_spec.lua
index 1553de4432..ee8da2932d 100644
--- a/test/functional/ex_cmds/mksession_spec.lua
+++ b/test/functional/ex_cmds/mksession_spec.lua
@@ -14,7 +14,6 @@ local pesc = helpers.pesc
local rmdir = helpers.rmdir
local sleep = helpers.sleep
local meths = helpers.meths
-local expect_exit = helpers.expect_exit
local file_prefix = 'Xtest-functional-ex_cmds-mksession_spec'
@@ -42,18 +41,85 @@ describe(':mksession', function()
command('split')
command('terminal')
command('split')
- command('mksession '..session_file)
+ command('mksession ' .. session_file)
+ command('%bwipeout!')
-- Create a new test instance of Nvim.
- expect_exit(command, 'qall!')
clear()
-- Restore session.
- command('source '..session_file)
+ command('source ' .. session_file)
eq(funcs.winbufnr(1), funcs.winbufnr(2))
neq(funcs.winbufnr(1), funcs.winbufnr(3))
end)
+ -- common testing procedure for testing "sessionoptions-=terminal"
+ local function test_terminal_session_disabled(expected_buf_count)
+ command('set sessionoptions-=terminal')
+
+ command('mksession ' .. session_file)
+
+ -- Create a new test instance of Nvim.
+ clear()
+
+ -- Restore session.
+ command('source ' .. session_file)
+
+ eq(expected_buf_count, #meths.list_bufs())
+ end
+
+ it(
+ 'do not restore :terminal if not set in sessionoptions, terminal in current window #13078',
+ function()
+ local tmpfile_base = file_prefix .. '-tmpfile'
+ command('edit ' .. tmpfile_base)
+ command('terminal')
+
+ local buf_count = #meths.list_bufs()
+ eq(2, buf_count)
+
+ eq('terminal', meths.buf_get_option(0, 'buftype'))
+
+ test_terminal_session_disabled(2)
+
+ -- no terminal should be set. As a side effect we end up with a blank buffer
+ eq('', meths.buf_get_option(meths.list_bufs()[1], 'buftype'))
+ eq('', meths.buf_get_option(meths.list_bufs()[2], 'buftype'))
+ end
+ )
+
+ it('do not restore :terminal if not set in sessionoptions, terminal hidden #13078', function()
+ command('terminal')
+ local terminal_bufnr = meths.get_current_buf()
+
+ local tmpfile_base = file_prefix .. '-tmpfile'
+ -- make terminal hidden by opening a new file
+ command('edit ' .. tmpfile_base .. '1')
+
+ local buf_count = #meths.list_bufs()
+ eq(2, buf_count)
+
+ eq(1, funcs.getbufinfo(terminal_bufnr)[1].hidden)
+
+ test_terminal_session_disabled(1)
+
+ -- no terminal should exist here
+ neq('', meths.buf_get_name(meths.list_bufs()[1]))
+ end)
+
+ it('do not restore :terminal if not set in sessionoptions, only buffer #13078', function()
+ command('terminal')
+ eq('terminal', meths.buf_get_option(0, 'buftype'))
+
+ local buf_count = #meths.list_bufs()
+ eq(1, buf_count)
+
+ test_terminal_session_disabled(1)
+
+ -- no terminal should be set
+ eq('', meths.buf_get_option(0, 'buftype'))
+ end)
+
it('restores tab-local working directories', function()
local tmpfile_base = file_prefix .. '-tmpfile'
local cwd_dir = funcs.getcwd()
@@ -103,28 +169,27 @@ describe(':mksession', function()
it('restores CWD for :terminal buffers #11288', function()
local cwd_dir = funcs.fnamemodify('.', ':p:~'):gsub([[[\/]*$]], '')
- cwd_dir = cwd_dir:gsub([[\]], '/') -- :mksession always uses unix slashes.
- local session_path = cwd_dir..'/'..session_file
+ cwd_dir = cwd_dir:gsub([[\]], '/') -- :mksession always uses unix slashes.
+ local session_path = cwd_dir .. '/' .. session_file
- command('cd '..tab_dir)
+ command('cd ' .. tab_dir)
command('terminal')
- command('cd '..cwd_dir)
- command('mksession '..session_path)
- command('bdelete!')
+ command('cd ' .. cwd_dir)
+ command('mksession ' .. session_path)
+ command('%bwipeout!')
if iswin() then
- sleep(100) -- Make sure all child processes have exited.
+ sleep(100) -- Make sure all child processes have exited.
end
- expect_exit(command, 'qall!')
-- Create a new test instance of Nvim.
clear()
- command('silent source '..session_path)
+ command('silent source ' .. session_path)
- local expected_cwd = cwd_dir..'/'..tab_dir
- matches('^term://'..pesc(expected_cwd)..'//%d+:', funcs.expand('%'))
- command('bdelete!')
+ local expected_cwd = cwd_dir .. '/' .. tab_dir
+ matches('^term://' .. pesc(expected_cwd) .. '//%d+:', funcs.expand('%'))
+ command('%bwipeout!')
if iswin() then
- sleep(100) -- Make sure all child processes have exited.
+ sleep(100) -- Make sure all child processes have exited.
end
end)
@@ -136,10 +201,10 @@ describe(':mksession', function()
local screen
local cwd_dir = funcs.fnamemodify('.', ':p:~'):gsub([[[\/]*$]], '')
- local session_path = cwd_dir..'/'..session_file
+ local session_path = cwd_dir .. '/' .. session_file
screen = Screen.new(50, 6)
- screen:attach({rgb=false})
+ screen:attach({ rgb = false })
local expected_screen = [[
^/ |
|
@@ -155,15 +220,15 @@ describe(':mksession', function()
-- Verify that the terminal's working directory is "/".
screen:expect(expected_screen)
- command('cd '..cwd_dir)
- command('mksession '..session_path)
- expect_exit(command, 'qall!')
+ command('cd ' .. cwd_dir)
+ command('mksession ' .. session_path)
+ command('%bwipeout!')
-- Create a new test instance of Nvim.
clear()
screen = Screen.new(50, 6)
- screen:attach({rgb=false})
- command('silent source '..session_path)
+ screen:attach({ rgb = false })
+ command('silent source ' .. session_path)
-- Verify that the terminal's working directory is "/".
screen:expect(expected_screen)
@@ -181,7 +246,7 @@ describe(':mksession', function()
height = 3,
row = 0,
col = 1,
- style = 'minimal'
+ style = 'minimal',
}
meths.open_win(buf, false, config)
local cmdheight = meths.get_option('cmdheight')
diff --git a/test/functional/fixtures/fake-lsp-server.lua b/test/functional/fixtures/fake-lsp-server.lua
index 0dc0c8c2db..aa47198f7a 100644
--- a/test/functional/fixtures/fake-lsp-server.lua
+++ b/test/functional/fixtures/fake-lsp-server.lua
@@ -67,10 +67,12 @@ local function expect_notification(method, params, ...)
local message = read_message()
assert_eq(method, message.method,
..., "expect_notification", "method")
- assert_eq(params, message.params,
- ..., "expect_notification", method, "params")
- assert_eq({jsonrpc = "2.0"; method=method, params=params}, message,
- ..., "expect_notification", "message")
+ if params then
+ assert_eq(params, message.params,
+ ..., "expect_notification", method, "params")
+ assert_eq({jsonrpc = "2.0"; method=method, params=params}, message,
+ ..., "expect_notification", "message")
+ end
end
local function expect_request(method, handler, ...)
@@ -257,6 +259,26 @@ function tests.basic_check_capabilities()
}
end
+function tests.text_document_save_did_open()
+ skeleton {
+ on_init = function()
+ return {
+ capabilities = {
+ textDocumentSync = {
+ save = true
+ }
+ }
+ }
+ end;
+ body = function()
+ notify('start')
+ expect_notification('textDocument/didOpen')
+ expect_notification('textDocument/didSave')
+ notify('shutdown')
+ end;
+ }
+end
+
function tests.text_document_sync_save_bool()
skeleton {
on_init = function()
diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua
index 0c616e73fb..8c5a60657a 100644
--- a/test/functional/helpers.lua
+++ b/test/functional/helpers.lua
@@ -271,10 +271,22 @@ function module.command(cmd)
end
--- use for commands which expect nvim to quit
-function module.expect_exit(...)
- eq("EOF was received from Nvim. Likely the Nvim process crashed.",
- module.pcall_err(...))
+-- Use for commands which expect nvim to quit.
+-- The first argument can also be a timeout.
+function module.expect_exit(fn_or_timeout, ...)
+ local eof_err_msg = 'EOF was received from Nvim. Likely the Nvim process crashed.'
+ if type(fn_or_timeout) == 'function' then
+ eq(eof_err_msg, module.pcall_err(fn_or_timeout, ...))
+ else
+ eq(eof_err_msg, module.pcall_err(function(timeout, fn, ...)
+ fn(...)
+ while session:next_message(timeout) do
+ end
+ if session.eof_err then
+ error(session.eof_err[2])
+ end
+ end, fn_or_timeout, ...))
+ end
end
-- Evaluates a VimL expression.
diff --git a/test/functional/legacy/075_maparg_spec.lua b/test/functional/legacy/075_maparg_spec.lua
deleted file mode 100644
index ad6c190104..0000000000
--- a/test/functional/legacy/075_maparg_spec.lua
+++ /dev/null
@@ -1,59 +0,0 @@
--- Tests for maparg().
--- Also test utf8 map with a 0x80 byte.
-
-local helpers = require('test.functional.helpers')(after_each)
-local clear, feed = helpers.clear, helpers.feed
-local command, expect = helpers.command, helpers.expect
-local poke_eventloop = helpers.poke_eventloop
-
-describe('maparg()', function()
- setup(clear)
-
- it('is working', function()
- command('set cpo-=<')
-
- -- Test maparg() with a string result
- command('map foo<C-V> is<F4>foo')
- command('vnoremap <script> <buffer> <expr> <silent> bar isbar')
- command([[call append('$', maparg('foo<C-V>'))]])
- command([[call append('$', string(maparg('foo<C-V>', '', 0, 1)))]])
- command([[call append('$', string(maparg('bar', '', 0, 1)))]])
- command('map <buffer> <nowait> foo bar')
- command([[call append('$', string(maparg('foo', '', 0, 1)))]])
- command('map abc x<char-114>x')
- command([[call append('$', maparg('abc'))]])
- command('map abc y<S-char-114>y')
- command([[call append('$', maparg('abc'))]])
- feed('Go<esc>:<cr>')
- poke_eventloop()
-
- -- Outside of the range, minimum
- command('inoremap <Char-0x1040> a')
- command([[execute "normal a\u1040\<Esc>"]])
-
- -- Inside of the range, minimum
- command('inoremap <Char-0x103f> b')
- command([[execute "normal a\u103f\<Esc>"]])
-
- -- Inside of the range, maximum
- command('inoremap <Char-0xf03f> c')
- command([[execute "normal a\uf03f\<Esc>"]])
-
- -- Outside of the range, maximum
- command('inoremap <Char-0xf040> d')
- command([[execute "normal a\uf040\<Esc>"]])
-
- -- Remove empty line
- command('1d')
-
- -- Assert buffer contents.
- expect([[
- is<F4>foo
- {'lnum': 0, 'script': 0, 'silent': 0, 'noremap': 0, 'lhs': 'foo<C-V>', 'mode': ' ', 'nowait': 0, 'expr': 0, 'sid': 0, 'rhs': 'is<F4>foo', 'buffer': 0}
- {'lnum': 0, 'script': 1, 'silent': 1, 'noremap': 1, 'lhs': 'bar', 'mode': 'v', 'nowait': 0, 'expr': 1, 'sid': 0, 'rhs': 'isbar', 'buffer': 1}
- {'lnum': 0, 'script': 0, 'silent': 0, 'noremap': 0, 'lhs': 'foo', 'mode': ' ', 'nowait': 1, 'expr': 0, 'sid': 0, 'rhs': 'bar', 'buffer': 1}
- xrx
- yRy
- abcd]])
- end)
-end)
diff --git a/test/functional/legacy/arglist_spec.lua b/test/functional/legacy/arglist_spec.lua
index 8379e426e0..f90da16d7b 100644
--- a/test/functional/legacy/arglist_spec.lua
+++ b/test/functional/legacy/arglist_spec.lua
@@ -4,6 +4,7 @@ local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, command, eq = helpers.clear, helpers.command, helpers.eq
local eval, exc_exec, neq = helpers.eval, helpers.exc_exec, helpers.neq
+local expect_exit = helpers.expect_exit
local feed = helpers.feed
local pcall_err = helpers.pcall_err
@@ -275,6 +276,6 @@ describe('argument list commands', function()
2 more files to edit. Quit anyway? |
[Y]es, (N)o: ^ |
]])
- feed('Y')
+ expect_exit(100, feed, 'Y')
end)
end)
diff --git a/test/functional/legacy/cmdline_spec.lua b/test/functional/legacy/cmdline_spec.lua
index d8d849271b..cf02636890 100644
--- a/test/functional/legacy/cmdline_spec.lua
+++ b/test/functional/legacy/cmdline_spec.lua
@@ -3,11 +3,12 @@ local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
local feed = helpers.feed
local feed_command = helpers.feed_command
-local source = helpers.source
+local exec = helpers.exec
describe('cmdline', function()
before_each(clear)
+ -- oldtest: Test_cmdlineclear_tabenter()
it('is cleared when switching tabs', function()
local screen = Screen.new(30, 10)
screen:attach()
@@ -91,10 +92,11 @@ describe('cmdline', function()
]])
end)
+ -- oldtest: Test_verbose_option()
it('prints every executed Ex command if verbose >= 16', function()
local screen = Screen.new(60, 12)
screen:attach()
- source([[
+ exec([[
command DoSomething echo 'hello' |set ts=4 |let v = '123' |echo v
call feedkeys("\r", 't') " for the hit-enter prompt
set verbose=20
@@ -115,4 +117,27 @@ describe('cmdline', function()
Press ENTER or type command to continue^ |
]])
end)
+
+ -- oldtest: Test_cmdline_redraw_tabline()
+ it('tabline is redrawn on entering cmdline', function()
+ local screen = Screen.new(30, 6)
+ screen:set_default_attr_ids({
+ [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
+ [1] = {reverse = true}, -- TabLineFill
+ })
+ screen:attach()
+ exec([[
+ set showtabline=2
+ autocmd CmdlineEnter * set tabline=foo
+ ]])
+ feed(':')
+ screen:expect([[
+ {1:foo }|
+ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ :^ |
+ ]])
+ end)
end)
diff --git a/test/functional/legacy/ex_mode_spec.lua b/test/functional/legacy/ex_mode_spec.lua
index 98f113bbd0..a8f54c6939 100644
--- a/test/functional/legacy/ex_mode_spec.lua
+++ b/test/functional/legacy/ex_mode_spec.lua
@@ -6,6 +6,7 @@ local eq = helpers.eq
local eval = helpers.eval
local feed = helpers.feed
local meths = helpers.meths
+local sleep = helpers.sleep
before_each(clear)
@@ -122,4 +123,54 @@ describe('Ex mode', function()
|
]])
end)
+
+ it('pressing Ctrl-C in :append inside a loop in Ex mode does not hang', function()
+ local screen = Screen.new(60, 6)
+ screen:set_default_attr_ids({
+ [0] = {bold = true, reverse = true}, -- MsgSeparator
+ [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
+ })
+ screen:attach()
+ feed('gQ')
+ feed('for i in range(1)<CR>')
+ feed('append<CR>')
+ screen:expect([[
+ {0: }|
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :for i in range(1) |
+ |
+ : append |
+ ^ |
+ ]])
+ feed('<C-C>')
+ sleep(10) -- Wait for input to be flushed
+ feed('foo<CR>')
+ screen:expect([[
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :for i in range(1) |
+ |
+ : append |
+ foo |
+ ^ |
+ ]])
+ feed('.<CR>')
+ screen:expect([[
+ :for i in range(1) |
+ |
+ : append |
+ foo |
+ . |
+ : ^ |
+ ]])
+ feed('endfor<CR>')
+ feed('vi<CR>')
+ screen:expect([[
+ ^foo |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]])
+ end)
end)
diff --git a/test/functional/legacy/excmd_spec.lua b/test/functional/legacy/excmd_spec.lua
index 6b3b265579..65957d85de 100644
--- a/test/functional/legacy/excmd_spec.lua
+++ b/test/functional/legacy/excmd_spec.lua
@@ -2,10 +2,13 @@ local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
local command = helpers.command
+local exec = helpers.exec
local exec_lua = helpers.exec_lua
+local expect_exit = helpers.expect_exit
local feed = helpers.feed
+local funcs = helpers.funcs
+local iswin = helpers.iswin
local meths = helpers.meths
-local poke_eventloop = helpers.poke_eventloop
local read_file = helpers.read_file
local source = helpers.source
local eq = helpers.eq
@@ -37,152 +40,484 @@ describe('Ex command', function()
end)
end)
-it(':confirm command dialog', function()
+describe(':confirm command dialog', function()
local screen
local function start_new()
clear()
- screen = Screen.new(60, 20)
+ screen = Screen.new(75, 20)
+ screen:set_default_attr_ids({
+ [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
+ [1] = {bold = true, reverse = true}, -- StatusLine, MsgSeparator
+ [2] = {reverse = true}, -- StatusLineNC
+ [3] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg
+ })
screen:attach()
end
- write_file('foo', 'foo1\n')
- write_file('bar', 'bar1\n')
-
- -- Test for saving all the modified buffers
- start_new()
- command("set nomore")
- command("new foo")
- command("call setline(1, 'foo2')")
- command("new bar")
- command("call setline(1, 'bar2')")
- command("wincmd b")
- feed(':confirm qall\n')
- screen:expect([[
- bar2 |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- bar [+] |
- foo2 |
- ~ |
- ~ |
- ~ |
- ~ |
- foo [+] |
- |
- ~ |
- ~ |
- |
- :confirm qall |
- Save changes to "bar"? |
- [Y]es, (N)o, Save (A)ll, (D)iscard All, (C)ancel: ^ |
- ]])
- feed('A')
- poke_eventloop()
-
- eq('foo2\n', read_file('foo'))
- eq('bar2\n', read_file('bar'))
-
- -- Test for discarding all the changes to modified buffers
- start_new()
- command("set nomore")
- command("new foo")
- command("call setline(1, 'foo3')")
- command("new bar")
- command("call setline(1, 'bar3')")
- command("wincmd b")
- feed(':confirm qall\n')
- screen:expect([[
- bar3 |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- bar [+] |
- foo3 |
- ~ |
- ~ |
- ~ |
- ~ |
- foo [+] |
- |
- ~ |
- ~ |
- |
- :confirm qall |
- Save changes to "bar"? |
- [Y]es, (N)o, Save (A)ll, (D)iscard All, (C)ancel: ^ |
- ]])
- feed('D')
- poke_eventloop()
-
- eq('foo2\n', read_file('foo'))
- eq('bar2\n', read_file('bar'))
-
- -- Test for saving and discarding changes to some buffers
- start_new()
- command("set nomore")
- command("new foo")
- command("call setline(1, 'foo4')")
- command("new bar")
- command("call setline(1, 'bar4')")
- command("wincmd b")
- feed(':confirm qall\n')
- screen:expect([[
- bar4 |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- bar [+] |
- foo4 |
- ~ |
- ~ |
- ~ |
- ~ |
- foo [+] |
- |
- ~ |
- ~ |
- |
- :confirm qall |
- Save changes to "bar"? |
- [Y]es, (N)o, Save (A)ll, (D)iscard All, (C)ancel: ^ |
- ]])
- feed('N')
- screen:expect([[
- bar4 |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- bar [+] |
- foo4 |
- ~ |
- ~ |
- ~ |
- ~ |
- foo [+] |
- |
- |
- :confirm qall |
- Save changes to "bar"? |
- |
- Save changes to "foo"? |
- [Y]es, (N)o, (C)ancel: ^ |
- ]])
- feed('Y')
- poke_eventloop()
-
- eq('foo4\n', read_file('foo'))
- eq('bar2\n', read_file('bar'))
-
- os.remove('foo')
- os.remove('bar')
+ -- Test for the :confirm command dialog
+ -- oldtest: Test_confirm_cmd()
+ it('works', function()
+ write_file('Xfoo', 'foo1\n')
+ write_file('Xbar', 'bar1\n')
+
+ -- Test for saving all the modified buffers
+ start_new()
+ exec([[
+ set nomore
+ new Xfoo
+ call setline(1, 'foo2')
+ new Xbar
+ call setline(1, 'bar2')
+ wincmd b
+ ]])
+ feed(':confirm qall\n')
+ screen:expect([[
+ bar2 |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:Xbar [+] }|
+ foo2 |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:Xfoo [+] }|
+ |
+ {0:~ }|
+ {0:~ }|
+ {1: }|
+ :confirm qall |
+ {3:Save changes to "Xbar"?} |
+ {3:[Y]es, (N)o, Save (A)ll, (D)iscard All, (C)ancel: }^ |
+ ]])
+ expect_exit(100, feed, 'A')
+
+ eq('foo2\n', read_file('Xfoo'))
+ eq('bar2\n', read_file('Xbar'))
+
+ -- Test for discarding all the changes to modified buffers
+ start_new()
+ exec([[
+ set nomore
+ new Xfoo
+ call setline(1, 'foo3')
+ new Xbar
+ call setline(1, 'bar3')
+ wincmd b
+ ]])
+ feed(':confirm qall\n')
+ screen:expect([[
+ bar3 |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:Xbar [+] }|
+ foo3 |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:Xfoo [+] }|
+ |
+ {0:~ }|
+ {0:~ }|
+ {1: }|
+ :confirm qall |
+ {3:Save changes to "Xbar"?} |
+ {3:[Y]es, (N)o, Save (A)ll, (D)iscard All, (C)ancel: }^ |
+ ]])
+ expect_exit(100, feed, 'D')
+
+ eq('foo2\n', read_file('Xfoo'))
+ eq('bar2\n', read_file('Xbar'))
+
+ -- Test for saving and discarding changes to some buffers
+ start_new()
+ exec([[
+ set nomore
+ new Xfoo
+ call setline(1, 'foo4')
+ new Xbar
+ call setline(1, 'bar4')
+ wincmd b
+ ]])
+ feed(':confirm qall\n')
+ screen:expect([[
+ bar4 |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:Xbar [+] }|
+ foo4 |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:Xfoo [+] }|
+ |
+ {0:~ }|
+ {0:~ }|
+ {1: }|
+ :confirm qall |
+ {3:Save changes to "Xbar"?} |
+ {3:[Y]es, (N)o, Save (A)ll, (D)iscard All, (C)ancel: }^ |
+ ]])
+ feed('N')
+ screen:expect([[
+ bar4 |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:Xbar [+] }|
+ foo4 |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:Xfoo [+] }|
+ |
+ {1: }|
+ :confirm qall |
+ {3:Save changes to "Xbar"?} |
+ |
+ {3:Save changes to "Xfoo"?} |
+ {3:[Y]es, (N)o, (C)ancel: }^ |
+ ]])
+ expect_exit(100, feed, 'Y')
+
+ eq('foo4\n', read_file('Xfoo'))
+ eq('bar2\n', read_file('Xbar'))
+
+ os.remove('Xfoo')
+ os.remove('Xbar')
+ end)
+
+ -- oldtest: Test_confirm_cmd_cancel()
+ it('can be cancelled', function()
+ -- Test for closing a window with a modified buffer
+ start_new()
+ screen:try_resize(75, 10)
+ exec([[
+ set nohidden nomore
+ new
+ call setline(1, 'abc')
+ ]])
+ feed(':confirm close\n')
+ screen:expect([[
+ abc |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {1:[No Name] [+] }|
+ |
+ {1: }|
+ :confirm close |
+ {3:Save changes to "Untitled"?} |
+ {3:[Y]es, (N)o, (C)ancel: }^ |
+ ]])
+ feed('C')
+ screen:expect([[
+ ^abc |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {1:[No Name] [+] }|
+ |
+ {0:~ }|
+ {0:~ }|
+ {2:[No Name] }|
+ |
+ ]])
+ feed(':confirm close\n')
+ screen:expect([[
+ abc |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {1:[No Name] [+] }|
+ |
+ {1: }|
+ :confirm close |
+ {3:Save changes to "Untitled"?} |
+ {3:[Y]es, (N)o, (C)ancel: }^ |
+ ]])
+ feed('N')
+ screen:expect([[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+ end)
+
+ -- oldtest: Test_confirm_q_wq()
+ it('works with :q and :wq', function()
+ write_file('Xfoo', 'foo')
+ start_new()
+ screen:try_resize(75, 8)
+ exec([[
+ set hidden nomore
+ call setline(1, 'abc')
+ edit Xfoo
+ set nofixendofline
+ ]])
+ feed(':confirm q\n')
+ screen:expect([[
+ foo |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {1: }|
+ :confirm q |
+ {3:Save changes to "Untitled"?} |
+ {3:[Y]es, (N)o, (C)ancel: }^ |
+ ]])
+ feed('C')
+ screen:expect([[
+ ^abc |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+
+ command('edit Xfoo')
+ feed(':confirm wq\n')
+ screen:expect([[
+ foo |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {1: }|
+ "Xfoo" [noeol] 1L, 3B written |
+ {3:Save changes to "Untitled"?} |
+ {3:[Y]es, (N)o, (C)ancel: }^ |
+ ]])
+ feed('C')
+ screen:expect([[
+ ^abc |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ "Xfoo" [noeol] 1L, 3B written |
+ ]])
+
+ os.remove('Xfoo')
+ end)
+
+ -- oldtest: Test_confirm_write_ro()
+ it('works when writing a read-only file', function()
+ write_file('Xconfirm_write_ro', 'foo\n')
+ start_new()
+ screen:try_resize(75, 8)
+ exec([[
+ set ruler
+ set nobackup ff=unix cmdheight=2
+ edit Xconfirm_write_ro
+ norm Abar
+ ]])
+
+ -- Try to write with 'ro' option.
+ feed(':set ro | confirm w\n')
+ screen:expect([[
+ foobar |
+ {0:~ }|
+ {0:~ }|
+ {1: }|
+ :set ro | confirm w |
+ {3:'readonly' option is set for "Xconfirm_write_ro".} |
+ {3:Do you wish to write anyway?} |
+ {3:(Y)es, [N]o: }^ |
+ ]])
+ feed('N')
+ screen:expect([[
+ fooba^r |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ 1,6 All |
+ ]])
+ eq('foo\n', read_file('Xconfirm_write_ro'))
+
+ feed(':confirm w\n')
+ screen:expect([[
+ foobar |
+ {0:~ }|
+ {0:~ }|
+ {1: }|
+ :confirm w |
+ {3:'readonly' option is set for "Xconfirm_write_ro".} |
+ {3:Do you wish to write anyway?} |
+ {3:(Y)es, [N]o: }^ |
+ ]])
+ feed('Y')
+ if iswin() then
+ screen:expect([[
+ foobar |
+ {0:~ }|
+ {1: }|
+ :confirm w |
+ {3:'readonly' option is set for "Xconfirm_write_ro".} |
+ {3:Do you wish to write anyway?} |
+ "Xconfirm_write_ro" [unix] 1L, 7B written |
+ {3:Press ENTER or type command to continue}^ |
+ ]])
+ else
+ screen:expect([[
+ foobar |
+ {0:~ }|
+ {1: }|
+ :confirm w |
+ {3:'readonly' option is set for "Xconfirm_write_ro".} |
+ {3:Do you wish to write anyway?} |
+ "Xconfirm_write_ro" 1L, 7B written |
+ {3:Press ENTER or type command to continue}^ |
+ ]])
+ end
+ eq('foobar\n', read_file('Xconfirm_write_ro'))
+ feed('<CR>') -- suppress hit-enter prompt
+
+ -- Try to write with read-only file permissions.
+ funcs.setfperm('Xconfirm_write_ro', 'r--r--r--')
+ feed(':set noro | silent undo | confirm w\n')
+ screen:expect([[
+ foobar |
+ {0:~ }|
+ {1: }|
+ :set noro | silent undo | confirm w |
+ {3:File permissions of "Xconfirm_write_ro" are read-only.} |
+ {3:It may still be possible to write it.} |
+ {3:Do you wish to try?} |
+ {3:(Y)es, [N]o: }^ |
+ ]])
+ feed('Y')
+ if iswin() then
+ screen:expect([[
+ foobar |
+ {1: }|
+ :set noro | silent undo | confirm w |
+ {3:File permissions of "Xconfirm_write_ro" are read-only.} |
+ {3:It may still be possible to write it.} |
+ {3:Do you wish to try?} |
+ "Xconfirm_write_ro" [unix] 1L, 4B written |
+ {3:Press ENTER or type command to continue}^ |
+ ]])
+ else
+ screen:expect([[
+ foobar |
+ {1: }|
+ :set noro | silent undo | confirm w |
+ {3:File permissions of "Xconfirm_write_ro" are read-only.} |
+ {3:It may still be possible to write it.} |
+ {3:Do you wish to try?} |
+ "Xconfirm_write_ro" 1L, 4B written |
+ {3:Press ENTER or type command to continue}^ |
+ ]])
+ end
+ eq('foo\n', read_file('Xconfirm_write_ro'))
+ feed('<CR>') -- suppress hit-enter prompt
+
+ os.remove('Xconfirm_write_ro')
+ end)
+
+ -- oldtest: Test_confirm_write_partial_file()
+ it('works when writing a partial file', function()
+ write_file('Xwrite_partial', 'a\nb\nc\nd\n')
+ start_new()
+ screen:try_resize(75, 8)
+ exec([[
+ set ruler
+ set nobackup ff=unix cmdheight=2
+ edit Xwrite_partial
+ ]])
+
+ feed(':confirm 2,3w\n')
+ screen:expect([[
+ a |
+ b |
+ c |
+ d |
+ {1: }|
+ :confirm 2,3w |
+ {3:Write partial file?} |
+ {3:(Y)es, [N]o: }^ |
+ ]])
+ feed('N')
+ screen:expect([[
+ ^a |
+ b |
+ c |
+ d |
+ {0:~ }|
+ {0:~ }|
+ |
+ 1,1 All |
+ ]])
+ eq('a\nb\nc\nd\n', read_file('Xwrite_partial'))
+ os.remove('Xwrite_partial')
+
+ feed(':confirm 2,3w\n')
+ screen:expect([[
+ a |
+ b |
+ c |
+ d |
+ {1: }|
+ :confirm 2,3w |
+ {3:Write partial file?} |
+ {3:(Y)es, [N]o: }^ |
+ ]])
+ feed('Y')
+ if iswin() then
+ screen:expect([[
+ a |
+ b |
+ c |
+ {1: }|
+ :confirm 2,3w |
+ {3:Write partial file?} |
+ "Xwrite_partial" [New][unix] 2L, 4B written |
+ {3:Press ENTER or type command to continue}^ |
+ ]])
+ else
+ screen:expect([[
+ a |
+ b |
+ c |
+ {1: }|
+ :confirm 2,3w |
+ {3:Write partial file?} |
+ "Xwrite_partial" [New] 2L, 4B written |
+ {3:Press ENTER or type command to continue}^ |
+ ]])
+ end
+ eq('b\nc\n', read_file('Xwrite_partial'))
+
+ os.remove('Xwrite_partial')
+ end)
end)
diff --git a/test/functional/legacy/global_spec.lua b/test/functional/legacy/global_spec.lua
new file mode 100644
index 0000000000..9f4528530c
--- /dev/null
+++ b/test/functional/legacy/global_spec.lua
@@ -0,0 +1,51 @@
+local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
+local clear = helpers.clear
+local exec = helpers.exec
+local feed = helpers.feed
+local sleep = helpers.sleep
+
+before_each(clear)
+
+describe(':global', function()
+ -- oldtest: Test_interrupt_global()
+ it('can be interrupted using Ctrl-C in cmdline mode vim-patch:9.0.0082', function()
+ local screen = Screen.new(75, 6)
+ screen:set_default_attr_ids({
+ [0] = {bold = true, reverse = true}, -- MsgSeparator
+ [1] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg
+ })
+ screen:attach()
+
+ exec([[
+ set nohlsearch noincsearch
+ cnoremap ; <Cmd>sleep 10<CR>
+ call setline(1, repeat(['foo'], 5))
+ ]])
+
+ feed(':g/foo/norm :<C-V>;<CR>')
+ sleep(10) -- Wait for :sleep to start
+ feed('<C-C>')
+ screen:expect([[
+ ^foo |
+ foo |
+ foo |
+ foo |
+ foo |
+ {1:Interrupted} |
+ ]])
+
+ -- Also test in Ex mode
+ feed('gQg/foo/norm :<C-V>;<CR>')
+ sleep(10) -- Wait for :sleep to start
+ feed('<C-C>')
+ screen:expect([[
+ {0: }|
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :g/foo/norm :; |
+ |
+ {1:Interrupted} |
+ :^ |
+ ]])
+ end)
+end)
diff --git a/test/functional/legacy/messages_spec.lua b/test/functional/legacy/messages_spec.lua
index b296ac909d..51c2406933 100644
--- a/test/functional/legacy/messages_spec.lua
+++ b/test/functional/legacy/messages_spec.lua
@@ -27,7 +27,16 @@ describe('messages', function()
it('works', function()
command('call setline(1, range(1, 100))')
- feed(':%p#\n')
+ feed(':%pfoo<C-H><C-H><C-H>#')
+ screen:expect([[
+ 1 |
+ 2 |
+ 3 |
+ 4 |
+ 5 |
+ :%p#^ |
+ ]])
+ feed('\n')
screen:expect([[
{2: 1 }1 |
{2: 2 }2 |
@@ -199,11 +208,11 @@ describe('messages', function()
-- Up all the way with 'g'.
feed('g')
screen:expect([[
+ :%p# |
{2: 1 }1 |
{2: 2 }2 |
{2: 3 }3 |
{2: 4 }4 |
- {2: 5 }5 |
{1:-- More --}^ |
]])
@@ -241,6 +250,18 @@ describe('messages', function()
{1:Press ENTER or type command to continue}^ |
]])
+ -- A command line that doesn't print text is appended to scrollback,
+ -- even if it invokes a nested command line.
+ feed([[:<C-R>=':'<CR>:<CR>g<lt>]])
+ screen:expect([[
+ {2: 97 }97 |
+ {2: 98 }98 |
+ {2: 99 }99 |
+ {2:100 }100 |
+ ::: |
+ {1:Press ENTER or type command to continue}^ |
+ ]])
+
feed(':%p#\n')
screen:expect([[
{2: 1 }1 |
diff --git a/test/functional/legacy/syn_attr_spec.lua b/test/functional/legacy/syn_attr_spec.lua
new file mode 100644
index 0000000000..06e8427e27
--- /dev/null
+++ b/test/functional/legacy/syn_attr_spec.lua
@@ -0,0 +1,60 @@
+local helpers = require('test.functional.helpers')(after_each)
+local clear = helpers.clear
+local command = helpers.command
+local eq = helpers.eq
+local eval = helpers.eval
+
+before_each(clear)
+
+-- oldtest: Test_missing_attr()
+it('synIDattr() works', function()
+ local bool_attrs = {
+ 'bold',
+ 'italic',
+ 'reverse',
+ 'standout',
+ 'underline',
+ 'undercurl',
+ 'underdouble',
+ 'underdotted',
+ 'underdashed',
+ 'strikethrough',
+ 'nocombine',
+ }
+
+ command('hi Mine cterm=NONE gui=NONE')
+ eq('Mine', eval([[synIDattr(hlID("Mine"), "name")]]))
+ for _, mode in ipairs({'cterm', 'gui'}) do
+ eq('', eval(([[synIDattr("Mine"->hlID(), "bg", '%s')]]):format(mode)))
+ eq('', eval(([[synIDattr("Mine"->hlID(), "fg", '%s')]]):format(mode)))
+ eq('', eval(([[synIDattr("Mine"->hlID(), "sp", '%s')]]):format(mode)))
+ for _, attr in ipairs(bool_attrs) do
+ eq('', eval(([[synIDattr(hlID("Mine"), "%s", '%s')]]):format(attr, mode)))
+ eq('', eval(([[synIDattr(hlID("Mine"), "%s", '%s')]]):format(attr, mode)))
+ eq('', eval(([[synIDattr(hlID("Mine"), "%s", '%s')]]):format(attr, mode)))
+ end
+ eq('', eval(([[synIDattr(hlID("Mine"), "inverse", '%s')]]):format(mode)))
+ end
+
+ for i, attr1 in ipairs(bool_attrs) do
+ local attr2 = bool_attrs[i - 1] or bool_attrs[#bool_attrs]
+
+ command(('hi Mine cterm=%s gui=%s'):format(attr1, attr2))
+ eq('1', eval(([[synIDattr(hlID("Mine"), "%s", 'cterm')]]):format(attr1)))
+ eq('', eval(([[synIDattr(hlID("Mine"), "%s", 'cterm')]]):format(attr2)))
+ eq('', eval(([[synIDattr("Mine"->hlID(), "%s", 'gui')]]):format(attr1)))
+ eq('1', eval(([[synIDattr("Mine"->hlID(), "%s", 'gui')]]):format(attr2)))
+
+ command(('hi Mine cterm=%s gui=%s'):format(attr2, attr1))
+ eq('', eval(([[synIDattr("Mine"->hlID(), "%s", 'cterm')]]):format(attr1)))
+ eq('1', eval(([[synIDattr("Mine"->hlID(), "%s", 'cterm')]]):format(attr2)))
+ eq('1', eval(([[synIDattr(hlID("Mine"), "%s", 'gui')]]):format(attr1)))
+ eq('', eval(([[synIDattr(hlID("Mine"), "%s", 'gui')]]):format(attr2)))
+ end
+
+ command('hi Mine cterm=reverse gui=inverse')
+ eq('1', eval([[synIDattr(hlID("Mine"), "reverse", 'cterm')]]))
+ eq('1', eval([[synIDattr(hlID("Mine"), "inverse", 'cterm')]]))
+ eq('1', eval([[synIDattr(hlID("Mine"), "reverse", 'gui')]]))
+ eq('1', eval([[synIDattr(hlID("Mine"), "inverse", 'gui')]]))
+end)
diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua
index 883e0e373b..2b249b7a69 100644
--- a/test/functional/lua/vim_spec.lua
+++ b/test/functional/lua/vim_spec.lua
@@ -2148,6 +2148,13 @@ describe('lua stdlib', function()
]]
eq('2', funcs.luaeval "BUF")
eq(2, funcs.luaeval "#vim.api.nvim_list_bufs()")
+
+ -- vim.cmd can be indexed with a command name
+ exec_lua [[
+ vim.cmd.let 'g:var = 2'
+ ]]
+
+ eq(2, funcs.luaeval "vim.g.var")
end)
it('vim.regex', function()
@@ -2493,6 +2500,41 @@ describe('lua stdlib', function()
eq(false, pcall_result)
end)
+
+ describe('returns -2 when interrupted', function()
+ before_each(function()
+ local channel = meths.get_api_info()[1]
+ meths.set_var('channel', channel)
+ end)
+
+ it('without callback', function()
+ exec_lua([[
+ function _G.Wait()
+ vim.rpcnotify(vim.g.channel, 'ready')
+ local _, interrupted = vim.wait(4000)
+ vim.rpcnotify(vim.g.channel, 'wait', interrupted)
+ end
+ ]])
+ feed(':lua _G.Wait()<CR>')
+ eq({'notification', 'ready', {}}, next_msg(500))
+ feed('<C-C>')
+ eq({'notification', 'wait', {-2}}, next_msg(500))
+ end)
+
+ it('with callback', function()
+ exec_lua([[
+ function _G.Wait()
+ vim.rpcnotify(vim.g.channel, 'ready')
+ local _, interrupted = vim.wait(4000, function() end)
+ vim.rpcnotify(vim.g.channel, 'wait', interrupted)
+ end
+ ]])
+ feed(':lua _G.Wait()<CR>')
+ eq({'notification', 'ready', {}}, next_msg(500))
+ feed('<C-C>')
+ eq({'notification', 'wait', {-2}}, next_msg(500))
+ end)
+ end)
end)
it('vim.notify_once', function()
@@ -2750,12 +2792,12 @@ describe('vim.keymap', function()
it('can make an expr mapping', function()
exec_lua [[
- vim.keymap.set('n', 'aa', function() return ':lua SomeValue = 99<cr>' end, {expr = true})
+ vim.keymap.set('n', 'aa', function() return '<Insert>π<C-V><M-π>foo<lt><Esc>' end, {expr = true})
]]
feed('aa')
- eq(99, exec_lua[[return SomeValue]])
+ eq({'π<M-π>foo<'}, meths.buf_get_lines(0, 0, -1, false))
end)
it('can overwrite a mapping', function()
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua
index c166982052..cd7415de90 100644
--- a/test/functional/plugin/lsp_spec.lua
+++ b/test/functional/plugin/lsp_spec.lua
@@ -535,6 +535,46 @@ describe('LSP', function()
}
end)
+ it('saveas sends didOpen if filename changed', function()
+ local expected_handlers = {
+ { NIL, {}, { method = 'shutdown', client_id = 1 } },
+ { NIL, {}, { method = 'start', client_id = 1 } },
+ }
+ local client
+ test_rpc_server({
+ test_name = 'text_document_save_did_open',
+ on_init = function(c)
+ client = c
+ end,
+ on_exit = function(code, signal)
+ eq(0, code, 'exit code')
+ eq(0, signal, 'exit signal')
+ end,
+ on_handler = function(err, result, ctx)
+ eq(table.remove(expected_handlers), { err, result, ctx }, 'expected handler')
+ if ctx.method == 'start' then
+ local tmpfile_old = helpers.tmpname()
+ local tmpfile_new = helpers.tmpname()
+ os.remove(tmpfile_new)
+ exec_lua(
+ [=[
+ local oldname, newname = ...
+ BUFFER = vim.api.nvim_get_current_buf()
+ vim.api.nvim_buf_set_name(BUFFER, oldname)
+ vim.api.nvim_buf_set_lines(BUFFER, 0, -1, true, {"help me"})
+ lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)
+ vim.api.nvim_buf_call(BUFFER, function() vim.cmd('saveas ' .. newname) end)
+ ]=],
+ tmpfile_old,
+ tmpfile_new
+ )
+ else
+ client.stop()
+ end
+ end,
+ })
+ end)
+
it('BufWritePost sends didSave including text if server capability is set', function()
local expected_handlers = {
{NIL, {}, {method="shutdown", client_id=1}};
diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua
index 1cef771f0d..23430a620b 100644
--- a/test/functional/terminal/buffer_spec.lua
+++ b/test/functional/terminal/buffer_spec.lua
@@ -5,12 +5,15 @@ local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim
local poke_eventloop = helpers.poke_eventloop
local eval, feed_command, source = helpers.eval, helpers.feed_command, helpers.source
local eq, neq = helpers.eq, helpers.neq
+local meths = helpers.meths
+local retry = helpers.retry
local write_file = helpers.write_file
local command = helpers.command
local exc_exec = helpers.exc_exec
local matches = helpers.matches
local exec_lua = helpers.exec_lua
local sleep = helpers.sleep
+local funcs = helpers.funcs
describe(':terminal buffer', function()
local screen
@@ -298,6 +301,44 @@ describe(':terminal buffer', function()
feed_command('put a') -- register a is empty
helpers.assert_alive()
end)
+
+ it([[can use temporary normal mode <c-\><c-o>]], function()
+ eq('t', funcs.mode(1))
+ feed [[<c-\><c-o>]]
+ screen:expect{grid=[[
+ tty ready |
+ {2:^ } |
+ |
+ |
+ |
+ |
+ {3:-- (terminal) --} |
+ ]]}
+ eq('ntT', funcs.mode(1))
+
+ feed [[:let g:x = 17]]
+ screen:expect{grid=[[
+ tty ready |
+ {2: } |
+ |
+ |
+ |
+ |
+ :let g:x = 17^ |
+ ]]}
+
+ feed [[<cr>]]
+ screen:expect{grid=[[
+ tty ready |
+ {1: } |
+ |
+ |
+ |
+ |
+ {3:-- TERMINAL --} |
+ ]]}
+ eq('t', funcs.mode(1))
+ end)
end)
describe('No heap-buffer-overflow when using', function()
@@ -364,3 +405,11 @@ describe('on_lines does not emit out-of-bounds line indexes when', function()
eq('', exec_lua([[return _G.cb_error]]))
end)
end)
+
+it('terminal truncates number of composing characters to 5', function()
+ clear()
+ local chan = meths.open_term(0, {})
+ local composing = ('a̳'):sub(2)
+ meths.chan_send(chan, 'a' .. composing:rep(8))
+ retry(nil, nil, function() eq('a' .. composing:rep(5), meths.get_current_line()) end)
+end)
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index dd88379344..eee759d2be 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -144,10 +144,9 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]]}
- -- TODO(bfredl): messes up the output (just like vim does).
feed_data('g')
screen:expect{grid=[[
- ) |
+ :call ManyErr() |
{8:Error detected while processing function ManyErr:} |
{11:line 2:} |
{10:-- More --}{1: } |
@@ -156,7 +155,7 @@ describe('TUI', function()
screen:try_resize(50,10)
screen:expect{grid=[[
- ) |
+ :call ManyErr() |
{8:Error detected while processing function ManyErr:} |
{11:line 2:} |
{8:FAIL 0} |
@@ -436,8 +435,11 @@ describe('TUI', function()
|
{3:-- TERMINAL --} |
]])
- feed_data(':tab split\r:tabnew\r')
- feed_data(':highlight Tabline ctermbg=NONE ctermfg=NONE cterm=underline\r')
+ child_session:request('nvim_command', [[
+ tab split
+ tabnew
+ highlight Tabline ctermbg=NONE ctermfg=NONE cterm=underline
+ ]])
local attrs = screen:get_default_attr_ids()
attrs[11] = {underline = true}
screen:expect([[
diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua
index eb0a14da31..db13647cc6 100644
--- a/test/functional/ui/cmdline_spec.lua
+++ b/test/functional/ui/cmdline_spec.lua
@@ -96,119 +96,6 @@ local function test_cmdline(linegrid)
]]}
end)
- describe("redraws statusline on entering", function()
- before_each(function()
- command('set laststatus=2')
- command('set statusline=%{mode()}')
- end)
-
- it('from normal mode', function()
- screen:expect{grid=[[
- ^ |
- {1:~ }|
- {1:~ }|
- {3:n }|
- |
- ]]}
-
- feed(':')
- screen:expect{grid=[[
- ^ |
- {1:~ }|
- {1:~ }|
- {3:c }|
- |
- ]], cmdline={{
- firstc = ":",
- content = {{""}},
- pos = 0,
- }}}
- end)
-
- it('from normal mode when : is mapped', function()
- command('nnoremap ; :')
-
- screen:expect{grid=[[
- ^ |
- {1:~ }|
- {1:~ }|
- {3:n }|
- |
- ]]}
-
- feed(';')
- screen:expect{grid=[[
- ^ |
- {1:~ }|
- {1:~ }|
- {3:c }|
- |
- ]], cmdline={{
- firstc = ":",
- content = {{""}},
- pos = 0,
- }}}
- end)
-
- it('but not with scrolled messages', function()
- screen:try_resize(35,10)
- feed(':echoerr doesnotexist<cr>')
- screen:expect{grid=[[
- |
- {1:~ }|
- {1:~ }|
- {1:~ }|
- {1:~ }|
- {3: }|
- {4:E121: Undefined variable: doesnotex}|
- {4:ist} |
- {5:Press ENTER or type command to cont}|
- {5:inue}^ |
- ]]}
- feed(':echoerr doesnotexist<cr>')
- screen:expect{grid=[[
- |
- {1:~ }|
- {3: }|
- {4:E121: Undefined variable: doesnotex}|
- {4:ist} |
- {5:Press ENTER or type command to cont}|
- {4:E121: Undefined variable: doesnotex}|
- {4:ist} |
- {5:Press ENTER or type command to cont}|
- {5:inue}^ |
- ]]}
-
- feed(':echoerr doesnotexist<cr>')
- screen:expect{grid=[[
- {4:E121: Undefined variable: doesnotex}|
- {4:ist} |
- {5:Press ENTER or type command to cont}|
- {4:E121: Undefined variable: doesnotex}|
- {4:ist} |
- {5:Press ENTER or type command to cont}|
- {4:E121: Undefined variable: doesnotex}|
- {4:ist} |
- {5:Press ENTER or type command to cont}|
- {5:inue}^ |
- ]]}
-
- feed('<cr>')
- screen:expect{grid=[[
- ^ |
- {1:~ }|
- {1:~ }|
- {1:~ }|
- {1:~ }|
- {1:~ }|
- {1:~ }|
- {1:~ }|
- {3:n }|
- |
- ]]}
- end)
- end)
-
it("works with input()", function()
feed(':call input("input", "default")<cr>')
screen:expect{grid=[[
@@ -883,6 +770,154 @@ describe('cmdline redraw', function()
end)
end)
+describe('statusline is redrawn on entering cmdline', function()
+ local screen
+
+ before_each(function()
+ clear()
+ screen = new_screen()
+ command('set laststatus=2')
+ end)
+
+ it('from normal mode', function()
+ command('set statusline=%{mode()}')
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {3:n }|
+ |
+ ]]}
+
+ feed(':')
+ screen:expect{grid=[[
+ |
+ {1:~ }|
+ {1:~ }|
+ {3:c }|
+ :^ |
+ ]]}
+ end)
+
+ it('from normal mode when : is mapped', function()
+ command('set statusline=%{mode()}')
+ command('nnoremap ; :')
+
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {3:n }|
+ |
+ ]]}
+
+ feed(';')
+ screen:expect{grid=[[
+ |
+ {1:~ }|
+ {1:~ }|
+ {3:c }|
+ :^ |
+ ]]}
+ end)
+
+ it('but not with scrolled messages', function()
+ command('set statusline=%{mode()}')
+ screen:try_resize(35,10)
+ feed(':echoerr doesnotexist<cr>')
+ screen:expect{grid=[[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {3: }|
+ {4:E121: Undefined variable: doesnotex}|
+ {4:ist} |
+ {5:Press ENTER or type command to cont}|
+ {5:inue}^ |
+ ]]}
+ feed(':echoerr doesnotexist<cr>')
+ screen:expect{grid=[[
+ |
+ {1:~ }|
+ {3: }|
+ {4:E121: Undefined variable: doesnotex}|
+ {4:ist} |
+ {5:Press ENTER or type command to cont}|
+ {4:E121: Undefined variable: doesnotex}|
+ {4:ist} |
+ {5:Press ENTER or type command to cont}|
+ {5:inue}^ |
+ ]]}
+
+ feed(':echoerr doesnotexist<cr>')
+ screen:expect{grid=[[
+ {4:E121: Undefined variable: doesnotex}|
+ {4:ist} |
+ {5:Press ENTER or type command to cont}|
+ {4:E121: Undefined variable: doesnotex}|
+ {4:ist} |
+ {5:Press ENTER or type command to cont}|
+ {4:E121: Undefined variable: doesnotex}|
+ {4:ist} |
+ {5:Press ENTER or type command to cont}|
+ {5:inue}^ |
+ ]]}
+
+ feed('<cr>')
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {3:n }|
+ |
+ ]]}
+ end)
+
+ describe('if custom statusline is set by', function()
+ before_each(function()
+ command('set statusline=')
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {3:[No Name] }|
+ |
+ ]]}
+ end)
+
+ it('CmdlineEnter autocommand', function()
+ command('autocmd CmdlineEnter * set statusline=command')
+ feed(':')
+ screen:expect{grid=[[
+ |
+ {1:~ }|
+ {1:~ }|
+ {3:command }|
+ :^ |
+ ]]}
+ end)
+
+ it('ModeChanged autocommand', function()
+ command('autocmd ModeChanged *:c set statusline=command')
+ feed(':')
+ screen:expect{grid=[[
+ |
+ {1:~ }|
+ {1:~ }|
+ {3:command }|
+ :^ |
+ ]]}
+ end)
+ end)
+end)
+
describe("cmdline height", function()
it("does not crash resized screen #14263", function()
clear()
@@ -1068,7 +1103,7 @@ describe('cmdheight=0', function()
~ |
~ |
~ |
- ~ |
+ recording @q |
]], showmode={}}
feed('q')
screen:expect{grid=[[
diff --git a/test/functional/ui/cursor_spec.lua b/test/functional/ui/cursor_spec.lua
index a1423c98a8..03cd4bfd06 100644
--- a/test/functional/ui/cursor_spec.lua
+++ b/test/functional/ui/cursor_spec.lua
@@ -215,7 +215,7 @@ describe('ui/cursor', function()
m.hl_id = 60
m.attr = {background = Screen.colors.DarkGray}
end
- if m.id_lm then m.id_lm = 65 end
+ if m.id_lm then m.id_lm = 61 end
end
-- Assert the new expectation.
diff --git a/test/functional/ui/diff_spec.lua b/test/functional/ui/diff_spec.lua
index 5d056cd6c3..36dc5addcd 100644
--- a/test/functional/ui/diff_spec.lua
+++ b/test/functional/ui/diff_spec.lua
@@ -6,6 +6,7 @@ local clear = helpers.clear
local command = helpers.command
local insert = helpers.insert
local write_file = helpers.write_file
+local dedent = helpers.dedent
local exec = helpers.exec
describe('Diff mode screen', function()
@@ -985,6 +986,93 @@ int main(int argc, char **argv)
]])
end)
end)
+
+ -- oldtest: Test_diff_scroll()
+ -- This was scrolling for 'cursorbind' but 'scrollbind' is more important
+ it('scrolling works correctly vim-patch:8.2.5155', function()
+ screen:try_resize(40, 12)
+ write_file(fname, dedent([[
+ line 1
+ line 2
+ line 3
+ line 4
+
+ // Common block
+ // one
+ // containing
+ // four lines
+
+ // Common block
+ // two
+ // containing
+ // four lines]]), false)
+ write_file(fname_2, dedent([[
+ line 1
+ line 2
+ line 3
+ line 4
+
+ Lorem
+ ipsum
+ dolor
+ sit
+ amet,
+ consectetur
+ adipiscing
+ elit.
+ Etiam
+ luctus
+ lectus
+ sodales,
+ dictum
+
+ // Common block
+ // one
+ // containing
+ // four lines
+
+ Vestibulum
+ tincidunt
+ aliquet
+ nulla.
+
+ // Common block
+ // two
+ // containing
+ // four lines]]), false)
+ reread()
+
+ feed('<C-W><C-W>jjjj')
+ screen:expect([[
+ {1: }line 1 │{1: }line 1 |
+ {1: }line 2 │{1: }line 2 |
+ {1: }line 3 │{1: }line 3 |
+ {1: }line 4 │{1: }line 4 |
+ {1: } │{1: }^ |
+ {1: }{2:-----------------}│{1: }{4:Lorem }|
+ {1: }{2:-----------------}│{1: }{4:ipsum }|
+ {1: }{2:-----------------}│{1: }{4:dolor }|
+ {1: }{2:-----------------}│{1: }{4:sit }|
+ {1: }{2:-----------------}│{1: }{4:amet, }|
+ {3:<nal-diff-screen-1 }{7:<al-diff-screen-1.2 }|
+ :e |
+ ]])
+ feed('j')
+ screen:expect([[
+ {1: }line 1 │{1: }line 1 |
+ {1: }line 2 │{1: }line 2 |
+ {1: }line 3 │{1: }line 3 |
+ {1: }line 4 │{1: }line 4 |
+ {1: } │{1: } |
+ {1: }{2:-----------------}│{1: }{4:^Lorem }|
+ {1: }{2:-----------------}│{1: }{4:ipsum }|
+ {1: }{2:-----------------}│{1: }{4:dolor }|
+ {1: }{2:-----------------}│{1: }{4:sit }|
+ {1: }{2:-----------------}│{1: }{4:amet, }|
+ {3:<nal-diff-screen-1 }{7:<al-diff-screen-1.2 }|
+ :e |
+ ]])
+ end)
end)
it('win_update redraws lines properly', function()
@@ -1227,6 +1315,7 @@ it('Align the filler lines when changing text in diff mode', function()
]]}
end)
+-- oldtest: Test_diff_binary()
it('diff mode works properly if file contains NUL bytes vim-patch:8.2.3925', function()
clear()
local screen = Screen.new(40, 20)
diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua
index 50247ed214..5967b630f6 100644
--- a/test/functional/ui/float_spec.lua
+++ b/test/functional/ui/float_spec.lua
@@ -18,6 +18,7 @@ local run = helpers.run
local pcall_err = helpers.pcall_err
local tbl_contains = global_helpers.tbl_contains
local curbuf, curwin, curtab = helpers.curbuf, helpers.curwin, helpers.curtab
+local NIL = helpers.NIL
describe('float window', function()
before_each(function()
@@ -420,6 +421,15 @@ describe('float window', function()
eq(winids, eval('winids'))
end)
+ it("no segfault when setting minimal style after clearing local 'fillchars' #19510", function()
+ local float_opts = {relative = 'editor', row = 1, col = 1, width = 1, height = 1}
+ local float_win = meths.open_win(0, true, float_opts)
+ meths.win_set_option(float_win, 'fillchars', NIL)
+ float_opts.style = 'minimal'
+ meths.win_set_config(float_win, float_opts)
+ assert_alive()
+ end)
+
describe('with only one tabpage,', function()
local float_opts = {relative = 'editor', row = 1, col = 1, width = 1, height = 1}
local old_buf, old_win
diff --git a/test/functional/ui/fold_spec.lua b/test/functional/ui/fold_spec.lua
index 394f2f5f49..c79fc2989c 100644
--- a/test/functional/ui/fold_spec.lua
+++ b/test/functional/ui/fold_spec.lua
@@ -1818,6 +1818,83 @@ describe("folded lines", function()
]])
end
end)
+
+ it('fold text is shown when text has been scrolled to the right #19123', function()
+ insert(content1)
+ command('set number nowrap')
+ command('3,4fold')
+ feed('gg')
+ if multigrid then
+ screen:expect([[
+ ## grid 1
+ [2:---------------------------------------------]|
+ [2:---------------------------------------------]|
+ [2:---------------------------------------------]|
+ [2:---------------------------------------------]|
+ [2:---------------------------------------------]|
+ [2:---------------------------------------------]|
+ [2:---------------------------------------------]|
+ [3:---------------------------------------------]|
+ ## grid 2
+ {8: 1 }^This is a |
+ {8: 2 }valid English |
+ {8: 3 }{5:+-- 2 lines: sentence composed by·······}|
+ {8: 5 }in his cave. |
+ {8: 6 } |
+ {1:~ }|
+ {1:~ }|
+ ## grid 3
+ |
+ ]])
+ else
+ screen:expect([[
+ {8: 1 }^This is a |
+ {8: 2 }valid English |
+ {8: 3 }{5:+-- 2 lines: sentence composed by·······}|
+ {8: 5 }in his cave. |
+ {8: 6 } |
+ {1:~ }|
+ {1:~ }|
+ |
+ ]])
+ end
+
+ feed('zl')
+ if multigrid then
+ screen:expect([[
+ ## grid 1
+ [2:---------------------------------------------]|
+ [2:---------------------------------------------]|
+ [2:---------------------------------------------]|
+ [2:---------------------------------------------]|
+ [2:---------------------------------------------]|
+ [2:---------------------------------------------]|
+ [2:---------------------------------------------]|
+ [3:---------------------------------------------]|
+ ## grid 2
+ {8: 1 }^his is a |
+ {8: 2 }alid English |
+ {8: 3 }{5:+-- 2 lines: sentence composed by·······}|
+ {8: 5 }n his cave. |
+ {8: 6 } |
+ {1:~ }|
+ {1:~ }|
+ ## grid 3
+ |
+ ]])
+ else
+ screen:expect([[
+ {8: 1 }^his is a |
+ {8: 2 }alid English |
+ {8: 3 }{5:+-- 2 lines: sentence composed by·······}|
+ {8: 5 }n his cave. |
+ {8: 6 } |
+ {1:~ }|
+ {1:~ }|
+ |
+ ]])
+ end
+ end)
end
describe("with ext_multigrid", function()
diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua
index 00f126a1f2..e7eaedba2d 100644
--- a/test/functional/ui/messages_spec.lua
+++ b/test/functional/ui/messages_spec.lua
@@ -1854,7 +1854,7 @@ aliquip ex ea commodo consequat.]])
feed('k')
screen:expect{grid=[[
- {7:0}{8: }{7:)}{8: }|
+ {7:0}{8: }|
{9:1}{10: }|
{9:2}{10: }|
{9:3}{10: }|
@@ -1943,6 +1943,7 @@ aliquip ex ea commodo consequat.]])
-- text is not reflown; existing lines get cut
screen:try_resize(30, 12)
screen:expect{grid=[[
+ :lua error(_G.x) |
{2:E5108: Error executing lua [st}|
{2:":lua"]:1: Lorem ipsum dolor s}|
{2:et, consectetur} |
@@ -1953,7 +1954,6 @@ aliquip ex ea commodo consequat.]])
|
|
|
- |
{4:-- More --}^ |
]]}
@@ -1961,6 +1961,22 @@ aliquip ex ea commodo consequat.]])
-- wrapped at the new screen size.
feed('<cr>')
screen:expect{grid=[[
+ {2:E5108: Error executing lua [st}|
+ {2:":lua"]:1: Lorem ipsum dolor s}|
+ {2:et, consectetur} |
+ {2:adipisicing elit, sed do eiusm}|
+ {2:mpore} |
+ {2:incididunt ut labore et dolore}|
+ {2:a aliqua.} |
+ {2:Ut enim ad minim veniam, quis }|
+ {2:nostrud xercitation} |
+ {2:ullamco laboris nisi ut} |
+ {2:aliquip ex ea commodo consequa}|
+ {4:-- More --}^ |
+ ]]}
+
+ feed('<cr>')
+ screen:expect{grid=[[
{2:":lua"]:1: Lorem ipsum dolor s}|
{2:et, consectetur} |
{2:adipisicing elit, sed do eiusm}|
diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua
index 69b0d1ecec..e389b7ab89 100644
--- a/test/functional/ui/mouse_spec.lua
+++ b/test/functional/ui/mouse_spec.lua
@@ -1572,22 +1572,22 @@ describe('ui/mouse/input', function()
meths.input_mouse('left', 'release', '', 0, 0, 0)
end)
- it('scroll keys are not translated into multiclicks #6211 #6989', function()
+ it('scroll keys are not translated into multiclicks and can be mapped #6211 #6989', function()
meths.set_var('mouse_up', 0)
meths.set_var('mouse_up2', 0)
- meths.set_var('mouse_up3', 0)
- meths.set_var('mouse_up4', 0)
command('nnoremap <ScrollWheelUp> <Cmd>let g:mouse_up += 1<CR>')
command('nnoremap <2-ScrollWheelUp> <Cmd>let g:mouse_up2 += 1<CR>')
- command('nnoremap <3-ScrollWheelUp> <Cmd>let g:mouse_up3 += 1<CR>')
- command('nnoremap <4-ScrollWheelUp> <Cmd>let g:mouse_up4 += 1<CR>')
- meths.input_mouse('wheel', 'up', '', 0, 0, 0)
- meths.input_mouse('wheel', 'up', '', 0, 0, 0)
+ feed('<ScrollWheelUp><0,0>')
+ feed('<ScrollWheelUp><0,0>')
meths.input_mouse('wheel', 'up', '', 0, 0, 0)
meths.input_mouse('wheel', 'up', '', 0, 0, 0)
eq(4, meths.get_var('mouse_up'))
eq(0, meths.get_var('mouse_up2'))
- eq(0, meths.get_var('mouse_up3'))
- eq(0, meths.get_var('mouse_up4'))
+ end)
+
+ it('feeding <MouseMove> does not use uninitialized memory #19480', function()
+ feed('<MouseMove>')
+ helpers.poke_eventloop()
+ helpers.assert_alive()
end)
end)
diff --git a/test/functional/ui/options_spec.lua b/test/functional/ui/options_spec.lua
index c2b0bcdb64..8d7c404637 100644
--- a/test/functional/ui/options_spec.lua
+++ b/test/functional/ui/options_spec.lua
@@ -51,7 +51,7 @@ describe('UI receives option updates', function()
end)
it('on attach #11372', function()
- clear()
+ clear{args_rm={'--headless'}}
local evs = {}
screen = Screen.new(20,5)
-- Override mouse_on/mouse_off handlers.
@@ -88,6 +88,13 @@ describe('UI receives option updates', function()
eq(expected, screen.options)
end)
+ command("set pumblend=50")
+ expected.pumblend = 50
+ screen:expect(function()
+ eq(expected, screen.options)
+ end)
+
+ -- check handling of out-of-bounds value
command("set pumblend=-1")
expected.pumblend = 0
screen:expect(function()
diff --git a/test/functional/ui/statusline_spec.lua b/test/functional/ui/statusline_spec.lua
index 1e1066d48a..69a2d2f4ed 100644
--- a/test/functional/ui/statusline_spec.lua
+++ b/test/functional/ui/statusline_spec.lua
@@ -1,5 +1,6 @@
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
+local assert_alive = helpers.assert_alive
local clear = helpers.clear
local command = helpers.command
local feed = helpers.feed
@@ -20,11 +21,9 @@ describe('statusline clicks', function()
command('set laststatus=2 mousemodel=extend')
exec([=[
function! MyClickFunc(minwid, clicks, button, mods)
- let mods = trim(a:mods)
- if mods ==# ''
- let g:testvar = printf("%d %d %s", a:minwid, a:clicks, a:button)
- else
- let g:testvar = printf("%d %d %s %s", a:minwid, a:clicks, a:button, mods)
+ let g:testvar = printf("%d %d %s", a:minwid, a:clicks, a:button)
+ if a:mods !=# ' '
+ let g:testvar ..= '(' .. a:mods .. ')'
endif
endfunction
]=])
@@ -34,8 +33,20 @@ describe('statusline clicks', function()
meths.set_option('statusline', 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T')
meths.input_mouse('left', 'press', '', 0, 6, 17)
eq('0 1 l', eval("g:testvar"))
+ meths.input_mouse('left', 'press', '', 0, 6, 17)
+ eq('0 2 l', eval("g:testvar"))
+ meths.input_mouse('left', 'press', '', 0, 6, 17)
+ eq('0 3 l', eval("g:testvar"))
+ meths.input_mouse('left', 'press', '', 0, 6, 17)
+ eq('0 4 l', eval("g:testvar"))
meths.input_mouse('right', 'press', '', 0, 6, 17)
eq('0 1 r', eval("g:testvar"))
+ meths.input_mouse('right', 'press', '', 0, 6, 17)
+ eq('0 2 r', eval("g:testvar"))
+ meths.input_mouse('right', 'press', '', 0, 6, 17)
+ eq('0 3 r', eval("g:testvar"))
+ meths.input_mouse('right', 'press', '', 0, 6, 17)
+ eq('0 4 r', eval("g:testvar"))
end)
it('works for winbar', function()
@@ -98,12 +109,60 @@ describe('statusline clicks', function()
eq('0 2 r', eval("g:testvar"))
end)
- it("click works with modifiers #18994", function()
+ it("works with modifiers #18994", function()
meths.set_option('statusline', 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T')
- meths.input_mouse('right', 'press', 's', 0, 6, 17)
- eq('0 1 r s', eval("g:testvar"))
- meths.input_mouse('left', 'press', 's', 0, 6, 17)
- eq('0 1 l s', eval("g:testvar"))
+ -- Note: alternate between left and right mouse buttons to avoid triggering multiclicks
+ meths.input_mouse('left', 'press', 'S', 0, 6, 17)
+ eq('0 1 l(s )', eval("g:testvar"))
+ meths.input_mouse('right', 'press', 'S', 0, 6, 17)
+ eq('0 1 r(s )', eval("g:testvar"))
+ meths.input_mouse('left', 'press', 'A', 0, 6, 17)
+ eq('0 1 l( a )', eval("g:testvar"))
+ meths.input_mouse('right', 'press', 'A', 0, 6, 17)
+ eq('0 1 r( a )', eval("g:testvar"))
+ meths.input_mouse('left', 'press', 'AS', 0, 6, 17)
+ eq('0 1 l(s a )', eval("g:testvar"))
+ meths.input_mouse('right', 'press', 'AS', 0, 6, 17)
+ eq('0 1 r(s a )', eval("g:testvar"))
+ meths.input_mouse('left', 'press', 'T', 0, 6, 17)
+ eq('0 1 l( m)', eval("g:testvar"))
+ meths.input_mouse('right', 'press', 'T', 0, 6, 17)
+ eq('0 1 r( m)', eval("g:testvar"))
+ meths.input_mouse('left', 'press', 'TS', 0, 6, 17)
+ eq('0 1 l(s m)', eval("g:testvar"))
+ meths.input_mouse('right', 'press', 'TS', 0, 6, 17)
+ eq('0 1 r(s m)', eval("g:testvar"))
+ meths.input_mouse('left', 'press', 'C', 0, 6, 17)
+ eq('0 1 l( c )', eval("g:testvar"))
+ -- <C-RightMouse> is for tag jump
+ end)
+
+ it("works for global statusline with vertical splits #19186", function()
+ command('set laststatus=3')
+ meths.set_option('statusline', '%0@MyClickFunc@Clicky stuff%T %= %0@MyClickFunc@Clicky stuff%T')
+ command('vsplit')
+ screen:expect([[
+ ^ │ |
+ ~ │~ |
+ ~ │~ |
+ ~ │~ |
+ ~ │~ |
+ ~ │~ |
+ Clicky stuff Clicky stuff|
+ |
+ ]])
+
+ -- clickable area on the right
+ meths.input_mouse('left', 'press', '', 0, 6, 35)
+ eq('0 1 l', eval("g:testvar"))
+ meths.input_mouse('right', 'press', '', 0, 6, 35)
+ eq('0 1 r', eval("g:testvar"))
+
+ -- clickable area on the left
+ meths.input_mouse('left', 'press', '', 0, 6, 5)
+ eq('0 1 l', eval("g:testvar"))
+ meths.input_mouse('right', 'press', '', 0, 6, 5)
+ eq('0 1 r', eval("g:testvar"))
end)
end)
@@ -340,3 +399,11 @@ describe('global statusline', function()
eq(1, meths.get_option('cmdheight'))
end)
end)
+
+it('statusline does not crash if it has Arabic characters #19447', function()
+ clear()
+ meths.set_option('statusline', 'غً')
+ meths.set_option('laststatus', 2)
+ command('redraw!')
+ assert_alive()
+end)
diff --git a/test/functional/ui/winbar_spec.lua b/test/functional/ui/winbar_spec.lua
index 92a6ab2e84..60fa10da87 100644
--- a/test/functional/ui/winbar_spec.lua
+++ b/test/functional/ui/winbar_spec.lua
@@ -578,3 +578,48 @@ describe('winbar', function()
eq('Vim(set):E36: Not enough room', pcall_err(command, 'set winbar=test'))
end)
end)
+
+it('local winbar works with tabs', function()
+ clear()
+ local screen = Screen.new(60, 13)
+ screen:attach()
+ screen:set_default_attr_ids({
+ [1] = {bold = true},
+ [2] = {reverse = true},
+ [3] = {bold = true, foreground = Screen.colors.Blue},
+ [4] = {underline = true, background = Screen.colors.LightGray}
+ })
+ meths.set_option_value('winbar', 'foo', { scope = 'local', win = 0 })
+ command('tabnew')
+ screen:expect([[
+ {4: [No Name] }{1: [No Name] }{2: }{4:X}|
+ ^ |
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ |
+ ]])
+ command('tabnext')
+ screen:expect{grid=[[
+ {1: [No Name] }{4: [No Name] }{2: }{4:X}|
+ {1:foo }|
+ ^ |
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ |
+ ]]}
+end)
diff --git a/test/functional/vimscript/buf_functions_spec.lua b/test/functional/vimscript/buf_functions_spec.lua
index e957e5f5af..b521620320 100644
--- a/test/functional/vimscript/buf_functions_spec.lua
+++ b/test/functional/vimscript/buf_functions_spec.lua
@@ -303,4 +303,8 @@ describe('setbufvar() function', function()
pcall_err(funcs.setbufvar, 1, 'changedtick', true))
eq(2, funcs.getbufvar(1, 'changedtick'))
end)
+ it('throws error when setting a string option to a boolean value vim-patch:9.0.0090', function()
+ eq('Vim:E928: String required',
+ pcall_err(funcs.setbufvar, '', '&errorformat', true))
+ end)
end)
diff --git a/test/functional/vimscript/let_spec.lua b/test/functional/vimscript/let_spec.lua
index ca1b5e8907..86905199a8 100644
--- a/test/functional/vimscript/let_spec.lua
+++ b/test/functional/vimscript/let_spec.lua
@@ -7,6 +7,7 @@ local eval = helpers.eval
local meths = helpers.meths
local exec = helpers.exec
local exec_capture = helpers.exec_capture
+local expect_exit = helpers.expect_exit
local source = helpers.source
local testprg = helpers.testprg
@@ -28,7 +29,7 @@ describe(':let', function()
it(":unlet self-referencing node in a List graph #6070", function()
-- :unlet-ing a self-referencing List must not allow GC on indirectly
-- referenced in-scope Lists. Before #6070 this caused use-after-free.
- source([=[
+ expect_exit(100, source, [=[
let [l1, l2] = [[], []]
echo 'l1:' . id(l1)
echo 'l2:' . id(l2)
diff --git a/test/functional/vimscript/map_functions_spec.lua b/test/functional/vimscript/map_functions_spec.lua
index 275c72d212..aa64006de0 100644
--- a/test/functional/vimscript/map_functions_spec.lua
+++ b/test/functional/vimscript/map_functions_spec.lua
@@ -3,7 +3,10 @@ local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local eq = helpers.eq
local eval = helpers.eval
+local expect = helpers.expect
+local feed = helpers.feed
local funcs = helpers.funcs
+local meths = helpers.meths
local nvim = helpers.nvim
local source = helpers.source
local command = helpers.command
@@ -13,6 +16,7 @@ describe('maparg()', function()
local foo_bar_map_table = {
lhs='foo',
+ lhsraw='foo',
script=0,
silent=0,
rhs='bar',
@@ -141,6 +145,7 @@ describe('maparg()', function()
local function acmap(lhs, rhs)
return {
lhs = ac(lhs),
+ lhsraw = ac(lhs),
rhs = ac(rhs),
buffer = 0,
@@ -161,3 +166,32 @@ describe('maparg()', function()
eq(acmap('e`', 'f`'), funcs.maparg(ac('e`'), 'n', 0, 1))
end)
end)
+
+describe('mapset()', function()
+ before_each(clear)
+
+ it('can restore mapping description from the dict returned by maparg()', function()
+ meths.set_keymap('n', 'lhs', 'rhs', {desc = 'map description'})
+ eq('\nn lhs rhs\n map description',
+ helpers.exec_capture("nmap lhs"))
+ local mapargs = funcs.maparg('lhs', 'n', false, true)
+ meths.del_keymap('n', 'lhs')
+ eq('\nNo mapping found', helpers.exec_capture("nmap lhs"))
+ funcs.mapset('n', false, mapargs)
+ eq('\nn lhs rhs\n map description',
+ helpers.exec_capture("nmap lhs"))
+ end)
+
+ it('can restore "replace_keycodes" from the dict returned by maparg()', function()
+ meths.set_keymap('i', 'foo', [['<l' .. 't>']], {expr = true, replace_keycodes = true})
+ feed('Afoo')
+ expect('<')
+ local mapargs = funcs.maparg('foo', 'i', false, true)
+ meths.set_keymap('i', 'foo', [['<l' .. 't>']], {expr = true})
+ feed('foo')
+ expect('<<lt>')
+ funcs.mapset('i', false, mapargs)
+ feed('foo')
+ expect('<<lt><')
+ end)
+end)
diff --git a/test/functional/vimscript/system_spec.lua b/test/functional/vimscript/system_spec.lua
index c915556c57..a778e2f435 100644
--- a/test/functional/vimscript/system_spec.lua
+++ b/test/functional/vimscript/system_spec.lua
@@ -630,7 +630,7 @@ end)
describe('shell :!', function()
before_each(clear)
- it(':{range}! with powershell filter/redirect #16271', function()
+ it(':{range}! with powershell filter/redirect #16271 #19250', function()
local screen = Screen.new(500, 8)
screen:attach()
local found = helpers.set_shell_powershell(true)
@@ -639,18 +639,25 @@ describe('shell :!', function()
1
4
2]])
- feed(':4verbose %!sort<cr>')
- screen:expect{
- any=[[Executing command: .?Start%-Process sort %-RedirectStandardInput .* %-RedirectStandardOutput .* %-NoNewWindow %-Wait]]
- }
+ if iswin() then
+ feed(':4verbose %!sort /R<cr>')
+ screen:expect{
+ any=[[Executing command: .?Start%-Process sort %-ArgumentList "/R" %-RedirectStandardInput .* %-RedirectStandardOutput .* %-NoNewWindow %-Wait]]
+ }
+ else
+ feed(':4verbose %!sort -r<cr>')
+ screen:expect{
+ any=[[Executing command: .?Start%-Process sort %-ArgumentList "%-r" %-RedirectStandardInput .* %-RedirectStandardOutput .* %-NoNewWindow %-Wait]]
+ }
+ end
feed('<CR>')
if found then
-- Not using fake powershell, so we can test the result.
expect([[
- 1
- 2
+ 4
3
- 4]])
+ 2
+ 1]])
end
end)
end)