aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/README.md23
-rw-r--r--test/functional/api/buffer_spec.lua91
-rw-r--r--test/functional/api/keymap_spec.lua508
-rw-r--r--test/functional/api/rpc_fixture.lua6
-rw-r--r--test/functional/api/server_requests_spec.lua5
-rw-r--r--test/functional/api/vim_spec.lua34
-rw-r--r--test/functional/autocmd/autocmd_spec.lua154
-rw-r--r--test/functional/autocmd/cursormoved_spec.lua34
-rw-r--r--test/functional/autocmd/textyankpost_spec.lua16
-rw-r--r--test/functional/core/channels_spec.lua8
-rw-r--r--test/functional/core/fileio_spec.lua2
-rw-r--r--test/functional/core/main_spec.lua12
-rw-r--r--test/functional/core/spellfile_spec.lua (renamed from test/functional/spell/spellfile_spec.lua)0
-rw-r--r--test/functional/core/startup_spec.lua38
-rw-r--r--test/functional/eval/api_functions_spec.lua2
-rw-r--r--test/functional/eval/executable_spec.lua65
-rw-r--r--test/functional/eval/exepath_spec.lua14
-rw-r--r--test/functional/eval/let_spec.lua2
-rw-r--r--test/functional/ex_cmds/cd_spec.lua9
-rw-r--r--test/functional/ex_cmds/dict_notifications_spec.lua21
-rw-r--r--test/functional/ex_cmds/help_spec.lua27
-rw-r--r--test/functional/ex_cmds/mksession_spec.lua23
-rw-r--r--test/functional/ex_cmds/oldfiles_spec.lua12
-rw-r--r--test/functional/ex_cmds/quickfix_commands_spec.lua10
-rw-r--r--test/functional/ex_cmds/swapfile_preserve_recover_spec.lua10
-rw-r--r--test/functional/ex_cmds/wviminfo_spec.lua16
-rw-r--r--test/functional/example_spec.lua36
-rw-r--r--test/functional/helpers.lua169
-rw-r--r--test/functional/legacy/074_global_var_in_viminfo_spec.lua8
-rw-r--r--test/functional/legacy/assert_spec.lua9
-rw-r--r--test/functional/lua/overrides_spec.lua16
-rw-r--r--test/functional/normal/jump_spec.lua48
-rw-r--r--test/functional/options/defaults_spec.lua57
-rw-r--r--test/functional/provider/clipboard_spec.lua (renamed from test/functional/clipboard/clipboard_provider_spec.lua)18
-rw-r--r--test/functional/shada/marks_spec.lua6
-rw-r--r--test/functional/shada/merging_spec.lua11
-rw-r--r--test/functional/terminal/ex_terminal_spec.lua16
-rw-r--r--test/functional/terminal/highlight_spec.lua50
-rw-r--r--test/functional/terminal/scrollback_spec.lua12
-rw-r--r--test/functional/terminal/tui_spec.lua39
-rw-r--r--test/functional/terminal/window_split_tab_spec.lua8
-rw-r--r--test/functional/ui/cmdline_highlight_spec.lua2
-rw-r--r--test/functional/ui/cmdline_spec.lua156
-rw-r--r--test/functional/ui/cursor_spec.lua4
-rw-r--r--test/functional/ui/diff_spec.lua408
-rw-r--r--test/functional/ui/embed_spec.lua2
-rw-r--r--test/functional/ui/float_spec.lua916
-rw-r--r--test/functional/ui/fold_spec.lua48
-rw-r--r--test/functional/ui/highlight_spec.lua78
-rw-r--r--test/functional/ui/inccommand_spec.lua27
-rw-r--r--test/functional/ui/input_spec.lua54
-rw-r--r--test/functional/ui/messages_spec.lua139
-rw-r--r--test/functional/ui/multigrid_spec.lua2
-rw-r--r--test/functional/ui/options_spec.lua6
-rw-r--r--test/functional/ui/output_spec.lua3
-rw-r--r--test/functional/ui/popupmenu_spec.lua264
-rw-r--r--test/functional/ui/screen.lua55
-rw-r--r--test/functional/ui/searchhl_spec.lua14
-rw-r--r--test/functional/ui/sign_spec.lua187
-rw-r--r--test/functional/ui/wildmode_spec.lua32
-rw-r--r--test/functional/viml/completion_spec.lua97
-rw-r--r--test/functional/viml/errorlist_spec.lua8
-rw-r--r--test/helpers.lua55
-rw-r--r--test/symbolic/klee/nvim/keymap.c20
-rw-r--r--test/unit/eval/typval_spec.lua6
-rw-r--r--test/unit/helpers.lua5
-rw-r--r--test/unit/undo_spec.lua8
-rw-r--r--test/unit/viml/expressions/lexer_spec.lua6
-rw-r--r--test/unit/viml/expressions/parser_spec.lua12
69 files changed, 3470 insertions, 789 deletions
diff --git a/test/README.md b/test/README.md
index d3f421e8fc..c87f835f79 100644
--- a/test/README.md
+++ b/test/README.md
@@ -88,10 +88,25 @@ To run a *single* legacy test set `TEST_FILE`, for example:
Debugging tests
---------------
-You can set `$GDB` to [run tests under gdbserver](https://github.com/neovim/neovim/pull/1527).
-And if `$VALGRIND` is set it will pass `--vgdb=yes` to valgrind instead of
-starting gdbserver directly.
-
+- You can set `$GDB` to [run tests under gdbserver](https://github.com/neovim/neovim/pull/1527).
+ And if `$VALGRIND` is set it will pass `--vgdb=yes` to valgrind instead of
+ starting gdbserver directly.
+- Hanging tests often happen due to unexpected `:h press-enter` prompts. The
+ default screen width is 50 columns. Commands that try to print lines longer
+ than 50 columns in the command-line, e.g. `:edit very...long...path`, will
+ trigger the prompt. In this case, a shorter path or `:silent edit` should be
+ used.
+- If you can't figure out what is going on, try to visualize the screen. Put
+ this at the beginning of your test:
+
+ ```lua
+ local Screen = require('test.functional.ui.screen')
+ local screen = Screen.new()
+ screen:attach()
+ ```
+
+ Afterwards, put `screen:snapshot_util()` at any position in your test. See the
+ comment at the top of `test/functional/ui/screen.lua` for more.
Filtering Tests
---------------
diff --git a/test/functional/api/buffer_spec.lua b/test/functional/api/buffer_spec.lua
index 93599c04f1..9d6cfb99ab 100644
--- a/test/functional/api/buffer_spec.lua
+++ b/test/functional/api/buffer_spec.lua
@@ -24,8 +24,8 @@ describe('api/buf', function()
end
- describe('line_count, insert and del_line', function()
- it('works', function()
+ describe('nvim_buf_set_lines, nvim_buf_line_count', function()
+ it('deprecated forms', function()
eq(1, curbuf_depr('line_count'))
curbuf_depr('insert', -1, {'line'})
eq(2, curbuf_depr('line_count'))
@@ -39,6 +39,41 @@ describe('api/buf', function()
eq(1, curbuf_depr('line_count'))
end)
+ it('cursor position is maintained after lines are inserted #9961', function()
+ -- replace the buffer contents with these three lines.
+ request('nvim_buf_set_lines', 0, 0, -1, 1, {"line1", "line2", "line3", "line4"})
+ -- Set the current cursor to {3, 2}.
+ curwin('set_cursor', {3, 2})
+
+ -- add 2 lines and delete 1 line above the current cursor position.
+ request('nvim_buf_set_lines', 0, 1, 2, 1, {"line5", "line6"})
+ -- check the current set of lines in the buffer.
+ eq({"line1", "line5", "line6", "line3", "line4"}, buffer('get_lines', 0, 0, -1, 1))
+ -- cursor should be moved below by 1 line.
+ eq({4, 2}, curwin('get_cursor'))
+
+ -- add a line after the current cursor position.
+ request('nvim_buf_set_lines', 0, 5, 5, 1, {"line7"})
+ -- check the current set of lines in the buffer.
+ eq({"line1", "line5", "line6", "line3", "line4", "line7"}, buffer('get_lines', 0, 0, -1, 1))
+ -- cursor position is unchanged.
+ eq({4, 2}, curwin('get_cursor'))
+
+ -- overwrite current cursor line.
+ request('nvim_buf_set_lines', 0, 3, 5, 1, {"line8", "line9"})
+ -- check the current set of lines in the buffer.
+ eq({"line1", "line5", "line6", "line8", "line9", "line7"}, buffer('get_lines', 0, 0, -1, 1))
+ -- cursor position is unchanged.
+ eq({4, 2}, curwin('get_cursor'))
+
+ -- delete current cursor line.
+ request('nvim_buf_set_lines', 0, 3, 5, 1, {})
+ -- check the current set of lines in the buffer.
+ eq({"line1", "line5", "line6", "line7"}, buffer('get_lines', 0, 0, -1, 1))
+ -- cursor position is unchanged.
+ eq({4, 2}, curwin('get_cursor'))
+ end)
+
it('line_count has defined behaviour for unloaded buffers', function()
-- we'll need to know our bufnr for when it gets unloaded
local bufnr = curbuf('get_number')
@@ -70,7 +105,7 @@ describe('api/buf', function()
end)
end)
- describe('{get,set,del}_line', function()
+ describe('deprecated: {get,set,del}_line', function()
it('works', function()
eq('', curbuf_depr('get_line', 0))
curbuf_depr('set_line', 0, 'line1')
@@ -102,7 +137,7 @@ describe('api/buf', function()
end)
end)
- describe('{get,set}_line_slice', function()
+ describe('deprecated: {get,set}_line_slice', function()
it('get_line_slice: out-of-bounds returns empty array', function()
curbuf_depr('set_line_slice', 0, 0, true, true, {'a', 'b', 'c'})
eq({'a', 'b', 'c'}, curbuf_depr('get_line_slice', 0, 2, true, true)) --sanity
@@ -149,7 +184,7 @@ describe('api/buf', function()
end)
end)
- describe('{get,set}_lines', function()
+ describe('nvim_buf_get_lines, nvim_buf_set_lines', function()
local get_lines, set_lines = curbufmeths.get_lines, curbufmeths.set_lines
local line_count = curbufmeths.line_count
@@ -272,7 +307,7 @@ describe('api/buf', function()
eq({}, get_lines(-3, -4, true))
end)
- it('set_line_slice: out-of-bounds can extend past end', function()
+ it('set_lines: out-of-bounds can extend past end', function()
set_lines(0, -1, true, {'a', 'b', 'c'})
eq({'a', 'b', 'c'}, get_lines(0, -1, true)) --sanity
@@ -286,7 +321,7 @@ describe('api/buf', function()
eq({'e', 'a', 'b', 'c', 'd'}, get_lines(0, -1, true))
end)
- it("set_line on alternate buffer does not access invalid line (E315)", function()
+ it("set_lines on alternate buffer does not access invalid line (E315)", function()
feed_command('set hidden')
insert('Initial file')
command('enew')
@@ -334,9 +369,27 @@ describe('api/buf', function()
{2:-- INSERT --} |
]])
end)
+
+ it('set_lines on hidden buffer preserves "previous window" #9741', function()
+ insert([[
+ visible buffer line 1
+ line 2
+ ]])
+ local hiddenbuf = meths.create_buf(false,true)
+ command('vsplit')
+ command('vsplit')
+ feed('<c-w>l<c-w>l<c-w>l')
+ eq(3, funcs.winnr())
+ feed('<c-w>h')
+ eq(2, funcs.winnr())
+ meths.buf_set_lines(hiddenbuf, 0, -1, true,
+ {'hidden buffer line 1', 'line 2'})
+ feed('<c-w>p')
+ eq(3, funcs.winnr())
+ end)
end)
- describe('get_offset', function()
+ describe('nvim_buf_get_offset', function()
local get_offset = curbufmeths.get_offset
it('works', function()
curbufmeths.set_lines(0,-1,true,{'Some\r','exa\000mple', '', 'buf\rfer', 'text'})
@@ -373,7 +426,7 @@ describe('api/buf', function()
end)
end)
- describe('{get,set,del}_var', function()
+ describe('nvim_buf_get_var, nvim_buf_set_var, nvim_buf_del_var', function()
it('works', function()
curbuf('set_var', 'lua', {1, 2, {['3'] = 1}})
eq({1, 2, {['3'] = 1}}, curbuf('get_var', 'lua'))
@@ -393,7 +446,7 @@ describe('api/buf', function()
end)
end)
- describe('get_changedtick', function()
+ describe('nvim_buf_get_changedtick', function()
it('works', function()
eq(2, curbufmeths.get_changedtick())
curbufmeths.set_lines(0, 1, false, {'abc\0', '\0def', 'ghi'})
@@ -417,7 +470,7 @@ describe('api/buf', function()
end)
end)
- describe('{get,set}_option', function()
+ describe('nvim_buf_get_option, nvim_buf_set_option', function()
it('works', function()
eq(8, curbuf('get_option', 'shiftwidth'))
curbuf('set_option', 'shiftwidth', 4)
@@ -430,7 +483,7 @@ describe('api/buf', function()
end)
end)
- describe('{get,set}_name', function()
+ describe('nvim_buf_get_name, nvim_buf_set_name', function()
it('works', function()
nvim('command', 'new')
eq('', curbuf('get_name'))
@@ -438,14 +491,12 @@ describe('api/buf', function()
curbuf('set_name', new_name)
eq(new_name, curbuf('get_name'))
nvim('command', 'w!')
- local f = io.open(new_name)
- ok(f ~= nil)
- f:close()
+ eq(1, funcs.filereadable(new_name))
os.remove(new_name)
end)
end)
- describe('is_loaded', function()
+ describe('nvim_buf_is_loaded', function()
it('works', function()
-- record our buffer number for when we unload it
local bufnr = curbuf('get_number')
@@ -470,7 +521,7 @@ describe('api/buf', function()
end)
end)
- describe('is_valid', function()
+ describe('nvim_buf_is_valid', function()
it('works', function()
nvim('command', 'new')
local b = nvim('get_current_buf')
@@ -480,12 +531,12 @@ describe('api/buf', function()
end)
end)
- describe('get_mark', function()
+ describe('nvim_buf_get_mark', function()
it('works', function()
curbuf('set_lines', -1, -1, true, {'a', 'bit of', 'text'})
curwin('set_cursor', {3, 4})
- nvim('command', 'mark V')
- eq({3, 0}, curbuf('get_mark', 'V'))
+ nvim('command', 'mark v')
+ eq({3, 0}, curbuf('get_mark', 'v'))
end)
end)
end)
diff --git a/test/functional/api/keymap_spec.lua b/test/functional/api/keymap_spec.lua
index f52372bee3..b3f6bb7895 100644
--- a/test/functional/api/keymap_spec.lua
+++ b/test/functional/api/keymap_spec.lua
@@ -1,15 +1,18 @@
local helpers = require('test.functional.helpers')(after_each)
-local global_helpers = require('test.helpers')
+local bufmeths = helpers.bufmeths
local clear = helpers.clear
local command = helpers.command
local curbufmeths = helpers.curbufmeths
-local eq = helpers.eq
+local eq, neq = helpers.eq, helpers.neq
+local expect_err = helpers.expect_err
+local feed = helpers.feed
local funcs = helpers.funcs
local meths = helpers.meths
local source = helpers.source
-local shallowcopy = global_helpers.shallowcopy
+local shallowcopy = helpers.shallowcopy
+local sleep = helpers.sleep
describe('nvim_get_keymap', function()
before_each(clear)
@@ -308,3 +311,502 @@ describe('nvim_get_keymap', function()
eq({space_table}, meths.get_keymap('n'))
end)
end)
+
+describe('nvim_set_keymap, nvim_del_keymap', function()
+ before_each(clear)
+
+ -- `generate_expected` is truthy: for generating an expected output for
+ -- maparg(), which does not accept "!" (though it returns "!" in its output
+ -- if getting a mapping set with |:map!|).
+ local function normalize_mapmode(mode, generate_expected)
+ if not generate_expected and mode == '!' then
+ -- Cannot retrieve mapmode-ic mappings with "!", but can with "i" or "c".
+ mode = 'i'
+ elseif mode == '' then
+ mode = generate_expected and ' ' or mode
+ end
+ return mode
+ end
+
+ -- Generate a mapargs dict, for comparison against the mapping that was
+ -- actually set
+ local function generate_mapargs(mode, lhs, rhs, opts)
+ if not opts then
+ opts = {}
+ end
+
+ local to_return = {}
+ to_return.mode = normalize_mapmode(mode, true)
+ to_return.noremap = not opts.noremap and 0 or 1
+ to_return.lhs = lhs
+ to_return.rhs = rhs
+ to_return.silent = not opts.silent and 0 or 1
+ to_return.nowait = not opts.nowait and 0 or 1
+ to_return.expr = not opts.expr and 0 or 1
+ to_return.sid = not opts.sid and 0 or opts.sid
+ to_return.buffer = not opts.buffer and 0 or opts.buffer
+
+ -- mode 't' doesn't print when calling maparg
+ if mode == 't' then
+ to_return.mode = ''
+ end
+
+ return to_return
+ end
+
+ -- Gets a maparg() dict from Nvim, if one exists.
+ local function get_mapargs(mode, lhs)
+ return funcs.maparg(lhs, normalize_mapmode(mode), false, true)
+ end
+
+ it('error on empty LHS', function()
+ -- escape parentheses in lua string, else comparison fails erroneously
+ expect_err('Invalid %(empty%) LHS',
+ meths.set_keymap, '', '', 'rhs', {})
+ expect_err('Invalid %(empty%) LHS',
+ meths.set_keymap, '', '', '', {})
+
+ expect_err('Invalid %(empty%) LHS', meths.del_keymap, '', '')
+ end)
+
+ it('error if LHS longer than MAXMAPLEN', function()
+ -- assume MAXMAPLEN of 50 chars, as declared in vim.h
+ local MAXMAPLEN = 50
+ local lhs = ''
+ for i=1,MAXMAPLEN do
+ lhs = lhs..(i % 10)
+ end
+
+ -- exactly 50 chars should be fine
+ meths.set_keymap('', lhs, 'rhs', {})
+
+ -- del_keymap should unmap successfully
+ meths.del_keymap('', lhs)
+ eq({}, get_mapargs('', lhs))
+
+ -- 51 chars should produce an error
+ lhs = lhs..'1'
+ expect_err('LHS exceeds maximum map length: '..lhs,
+ meths.set_keymap, '', lhs, 'rhs', {})
+ expect_err('LHS exceeds maximum map length: '..lhs,
+ meths.del_keymap, '', lhs)
+ end)
+
+ it('does not throw errors when rhs is longer than MAXMAPLEN', function()
+ local MAXMAPLEN = 50
+ local rhs = ''
+ for i=1,MAXMAPLEN do
+ rhs = rhs..(i % 10)
+ end
+ rhs = rhs..'1'
+ meths.set_keymap('', 'lhs', rhs, {})
+ eq(generate_mapargs('', 'lhs', rhs),
+ get_mapargs('', 'lhs'))
+ end)
+
+ it('throws errors when given too-long mode shortnames', function()
+ expect_err('Shortname is too long: map',
+ meths.set_keymap, 'map', 'lhs', 'rhs', {})
+
+ expect_err('Shortname is too long: vmap',
+ meths.set_keymap, 'vmap', 'lhs', 'rhs', {})
+
+ expect_err('Shortname is too long: xnoremap',
+ meths.set_keymap, 'xnoremap', 'lhs', 'rhs', {})
+
+ expect_err('Shortname is too long: map', meths.del_keymap, 'map', 'lhs')
+ expect_err('Shortname is too long: vmap', meths.del_keymap, 'vmap', 'lhs')
+ expect_err('Shortname is too long: xnoremap', meths.del_keymap, 'xnoremap', 'lhs')
+ end)
+
+ it('error on invalid mode shortname', function()
+ expect_err('Invalid mode shortname: " "',
+ meths.set_keymap, ' ', 'lhs', 'rhs', {})
+ expect_err('Invalid mode shortname: "m"',
+ meths.set_keymap, 'm', 'lhs', 'rhs', {})
+ expect_err('Invalid mode shortname: "?"',
+ meths.set_keymap, '?', 'lhs', 'rhs', {})
+ expect_err('Invalid mode shortname: "y"',
+ meths.set_keymap, 'y', 'lhs', 'rhs', {})
+ expect_err('Invalid mode shortname: "p"',
+ meths.set_keymap, 'p', 'lhs', 'rhs', {})
+ expect_err('Invalid mode shortname: "?"', meths.del_keymap, '?', 'lhs')
+ expect_err('Invalid mode shortname: "y"', meths.del_keymap, 'y', 'lhs')
+ expect_err('Invalid mode shortname: "p"', meths.del_keymap, 'p', 'lhs')
+ end)
+
+ it('error on invalid optnames', function()
+ expect_err('Invalid key: silentt',
+ meths.set_keymap, 'n', 'lhs', 'rhs', {silentt = true})
+ expect_err('Invalid key: sidd',
+ meths.set_keymap, 'n', 'lhs', 'rhs', {sidd = false})
+ expect_err('Invalid key: nowaiT',
+ meths.set_keymap, 'n', 'lhs', 'rhs', {nowaiT = false})
+ end)
+
+ it('error on <buffer> option key', function()
+ expect_err('Invalid key: buffer',
+ meths.set_keymap, 'n', 'lhs', 'rhs', {buffer = 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
+ it('throws an error when given non-boolean value for '..opt, function()
+ local opts = {}
+ opts[opt] = 2
+ expect_err('Gave non%-boolean value for an opt: '..opt,
+ meths.set_keymap, 'n', 'lhs', 'rhs', opts)
+ end)
+ end
+
+ -- Perform tests of basic functionality
+ it('sets ordinary mappings', function()
+ meths.set_keymap('n', 'lhs', 'rhs', {})
+ eq(generate_mapargs('n', 'lhs', 'rhs'), get_mapargs('n', 'lhs'))
+
+ meths.set_keymap('v', 'lhs', 'rhs', {})
+ eq(generate_mapargs('v', 'lhs', 'rhs'), get_mapargs('v', 'lhs'))
+ end)
+
+ it('does not throw when LHS or RHS have leading/trailing whitespace', function()
+ meths.set_keymap('n', ' lhs', 'rhs', {})
+ eq(generate_mapargs('n', '<Space><Space><Space>lhs', 'rhs'),
+ get_mapargs('n', ' lhs'))
+
+ meths.set_keymap('n', 'lhs ', 'rhs', {})
+ eq(generate_mapargs('n', 'lhs<Space><Space><Space><Space>', 'rhs'),
+ get_mapargs('n', 'lhs '))
+
+ meths.set_keymap('v', ' lhs ', '\trhs\t\f', {})
+ eq(generate_mapargs('v', '<Space>lhs<Space><Space>', '\trhs\t\f'),
+ get_mapargs('v', ' lhs '))
+ end)
+
+ it('can set noremap mappings', function()
+ meths.set_keymap('x', 'lhs', 'rhs', {noremap = true})
+ eq(generate_mapargs('x', 'lhs', 'rhs', {noremap = true}),
+ get_mapargs('x', 'lhs'))
+
+ meths.set_keymap('t', 'lhs', 'rhs', {noremap = true})
+ eq(generate_mapargs('t', 'lhs', 'rhs', {noremap = true}),
+ get_mapargs('t', 'lhs'))
+ end)
+
+ it('can unmap mappings', function()
+ meths.set_keymap('v', 'lhs', 'rhs', {})
+ meths.del_keymap('v', 'lhs')
+ eq({}, get_mapargs('v', 'lhs'))
+
+ meths.set_keymap('t', 'lhs', 'rhs', {noremap = true})
+ meths.del_keymap('t', 'lhs')
+ eq({}, get_mapargs('t', 'lhs'))
+ end)
+
+ -- Test some edge cases
+ it('"!" and empty string are synonyms for mapmode-nvo', function()
+ local nvo_shortnames = {'', '!'}
+ for _, name in ipairs(nvo_shortnames) do
+ meths.set_keymap(name, 'lhs', 'rhs', {})
+ meths.del_keymap(name, 'lhs')
+ eq({}, get_mapargs(name, 'lhs'))
+ end
+ end)
+
+ local special_chars = {'<C-U>', '<S-Left>', '<F12><F2><Tab>', '<Space><Tab>'}
+ for _, lhs in ipairs(special_chars) do
+ for _, rhs in ipairs(special_chars) do
+ local mapmode = '!'
+ it('can set mappings with special characters, lhs: '..lhs..', rhs: '..rhs,
+ function()
+ meths.set_keymap(mapmode, lhs, rhs, {})
+ eq(generate_mapargs(mapmode, lhs, rhs), get_mapargs(mapmode, lhs))
+ end)
+ end
+ end
+
+ it('can set mappings containing literal keycodes', function()
+ meths.set_keymap('n', '\n\r\n', 'rhs', {})
+ local expected = generate_mapargs('n', '<NL><CR><NL>', 'rhs')
+ eq(expected, get_mapargs('n', '<C-j><CR><C-j>'))
+ end)
+
+ it('can set mappings whose RHS is a <Nop>', function()
+ meths.set_keymap('i', 'lhs', '<Nop>', {})
+ command('normal ilhs')
+ eq({''}, curbufmeths.get_lines(0, -1, 0)) -- imap to <Nop> does nothing
+ eq(generate_mapargs('i', 'lhs', '<Nop>', {}),
+ get_mapargs('i', 'lhs'))
+
+ -- also test for case insensitivity
+ meths.set_keymap('i', 'lhs', '<nOp>', {})
+ command('normal ilhs')
+ eq({''}, curbufmeths.get_lines(0, -1, 0))
+ -- note: RHS in returned mapargs() dict reflects the original RHS
+ -- provided by the user
+ eq(generate_mapargs('i', 'lhs', '<nOp>', {}),
+ get_mapargs('i', 'lhs'))
+
+ meths.set_keymap('i', 'lhs', '<NOP>', {})
+ command('normal ilhs')
+ eq({''}, curbufmeths.get_lines(0, -1, 0))
+ eq(generate_mapargs('i', 'lhs', '<NOP>', {}),
+ get_mapargs('i', 'lhs'))
+ end)
+
+ it('treats an empty RHS in a mapping like a <Nop>', function()
+ meths.set_keymap('i', 'lhs', '', {})
+ command('normal ilhs')
+ eq({''}, curbufmeths.get_lines(0, -1, 0))
+ eq(generate_mapargs('i', 'lhs', '', {}),
+ get_mapargs('i', 'lhs'))
+ end)
+
+ it('can set and unset <M-">', function()
+ -- Taken from the legacy test: test_mapping.vim. Exposes a bug in which
+ -- replace_termcodes changes the length of the mapping's LHS, but
+ -- do_map continues to use the *old* length of LHS.
+ meths.set_keymap('i', '<M-">', 'foo', {})
+ meths.del_keymap('i', '<M-">')
+ eq({}, get_mapargs('i', '<M-">'))
+ end)
+
+ it('interprets control sequences in expr-quotes correctly when called '
+ ..'inside vim', function()
+ command([[call nvim_set_keymap('i', "\<space>", "\<tab>", {})]])
+ eq(generate_mapargs('i', '<Space>', '\t', {}),
+ get_mapargs('i', '<Space>'))
+ feed('i ')
+ eq({'\t'}, curbufmeths.get_lines(0, -1, 0))
+ end)
+
+ it('throws appropriate error messages when setting <unique> maps', function()
+ meths.set_keymap('l', 'lhs', 'rhs', {})
+ expect_err('E227: mapping already exists for lhs',
+ meths.set_keymap, 'l', 'lhs', 'rhs', {unique = true})
+ -- different mapmode, no error should be thrown
+ meths.set_keymap('t', 'lhs', 'rhs', {unique = true})
+ end)
+
+ it('can set <expr> mappings whose RHS change dynamically', function()
+ meths.command_output([[
+ function! FlipFlop() abort
+ if !exists('g:flip') | let g:flip = 0 | endif
+ let g:flip = !g:flip
+ return g:flip
+ endfunction
+ ]])
+ eq(1, meths.call_function('FlipFlop', {}))
+ eq(0, meths.call_function('FlipFlop', {}))
+ eq(1, meths.call_function('FlipFlop', {}))
+ eq(0, meths.call_function('FlipFlop', {}))
+
+ meths.set_keymap('i', 'lhs', 'FlipFlop()', {expr = true})
+ command('normal ilhs')
+ eq({'1'}, curbufmeths.get_lines(0, -1, 0))
+
+ command('normal! ggVGd')
+
+ command('normal ilhs')
+ eq({'0'}, curbufmeths.get_lines(0, -1, 0))
+ end)
+
+ it('can set mappings that do trigger other mappings', function()
+ meths.set_keymap('i', 'mhs', 'rhs', {})
+ meths.set_keymap('i', 'lhs', 'mhs', {})
+
+ command('normal imhs')
+ eq({'rhs'}, curbufmeths.get_lines(0, -1, 0))
+
+ command('normal! ggVGd')
+
+ command('normal ilhs')
+ eq({'rhs'}, curbufmeths.get_lines(0, -1, 0))
+ end)
+
+ it("can set noremap mappings that don't trigger other mappings", function()
+ meths.set_keymap('i', 'mhs', 'rhs', {})
+ meths.set_keymap('i', 'lhs', 'mhs', {noremap = true})
+
+ command('normal imhs')
+ eq({'rhs'}, curbufmeths.get_lines(0, -1, 0))
+
+ command('normal! ggVGd')
+
+ command('normal ilhs') -- shouldn't trigger mhs-to-rhs mapping
+ eq({'mhs'}, curbufmeths.get_lines(0, -1, 0))
+ end)
+
+ it("can set nowait mappings that fire without waiting", function()
+ meths.set_keymap('i', '123456', 'longer', {})
+ meths.set_keymap('i', '123', 'shorter', {nowait = true})
+
+ -- feed keys one at a time; if all keys arrive atomically, the longer
+ -- mapping will trigger
+ local keys = 'i123456'
+ for c in string.gmatch(keys, '.') do
+ feed(c)
+ sleep(5)
+ end
+ eq({'shorter456'}, curbufmeths.get_lines(0, -1, 0))
+ end)
+
+ -- Perform exhaustive tests of basic functionality
+ local mapmodes = {'n', 'v', 'x', 's', 'o', '!', 'i', 'l', 'c', 't', ''}
+ for _, mapmode in ipairs(mapmodes) do
+ it('can set/unset normal mappings in mapmode '..mapmode, function()
+ meths.set_keymap(mapmode, 'lhs', 'rhs', {})
+ eq(generate_mapargs(mapmode, 'lhs', 'rhs'),
+ get_mapargs(mapmode, 'lhs'))
+
+ -- some mapmodes (like 'o') will prevent other mapmodes (like '!') from
+ -- taking effect, so unmap after each mapping
+ meths.del_keymap(mapmode, 'lhs')
+ eq({}, get_mapargs(mapmode, 'lhs'))
+ end)
+ end
+
+ for _, mapmode in ipairs(mapmodes) do
+ it('can set/unset noremap mappings using mapmode '..mapmode, function()
+ meths.set_keymap(mapmode, 'lhs', 'rhs', {noremap = true})
+ eq(generate_mapargs(mapmode, 'lhs', 'rhs', {noremap = true}),
+ get_mapargs(mapmode, 'lhs'))
+
+ meths.del_keymap(mapmode, 'lhs')
+ eq({}, get_mapargs(mapmode, 'lhs'))
+ end)
+ end
+
+ -- Test map-arguments, using optnames from above
+ -- remove some map arguments that are harder to test, or were already tested
+ optnames = {'nowait', 'silent', 'expr', 'noremap'}
+ for _, mapmode in ipairs(mapmodes) do
+ local printable_mode = normalize_mapmode(mapmode)
+
+ -- Test with single mappings
+ for _, maparg in ipairs(optnames) do
+ it('can set/unset '..printable_mode..'-mappings with maparg: '..maparg,
+ function()
+ meths.set_keymap(mapmode, 'lhs', 'rhs', {[maparg] = true})
+ eq(generate_mapargs(mapmode, 'lhs', 'rhs', {[maparg] = true}),
+ get_mapargs(mapmode, 'lhs'))
+ meths.del_keymap(mapmode, 'lhs')
+ eq({}, get_mapargs(mapmode, 'lhs'))
+ end)
+ it ('can set/unset '..printable_mode..'-mode mappings with maparg '..
+ maparg..', whose value is false', function()
+ meths.set_keymap(mapmode, 'lhs', 'rhs', {[maparg] = false})
+ eq(generate_mapargs(mapmode, 'lhs', 'rhs'),
+ get_mapargs(mapmode, 'lhs'))
+ meths.del_keymap(mapmode, 'lhs')
+ eq({}, get_mapargs(mapmode, 'lhs'))
+ end)
+ end
+
+ -- Test with triplets of mappings, one of which is false
+ for i = 1, (#optnames - 2) do
+ local opt1, opt2, opt3 = optnames[i], optnames[i + 1], optnames[i + 2]
+ it('can set/unset '..printable_mode..'-mode mappings with mapargs '..
+ opt1..', '..opt2..', '..opt3, function()
+ local opts = {[opt1] = true, [opt2] = false, [opt3] = true}
+ meths.set_keymap(mapmode, 'lhs', 'rhs', opts)
+ eq(generate_mapargs(mapmode, 'lhs', 'rhs', opts),
+ get_mapargs(mapmode, 'lhs'))
+ meths.del_keymap(mapmode, 'lhs')
+ eq({}, get_mapargs(mapmode, 'lhs'))
+ end)
+ end
+ end
+end)
+
+describe('nvim_buf_set_keymap, nvim_buf_del_keymap', function()
+ before_each(clear)
+
+ -- nvim_set_keymap is implemented as a wrapped call to nvim_buf_set_keymap,
+ -- so its tests also effectively test nvim_buf_set_keymap
+
+ -- here, we mainly test for buffer specificity and other special cases
+
+ -- switch to the given buffer, abandoning any changes in the current buffer
+ local function switch_to_buf(bufnr)
+ command(bufnr..'buffer!')
+ end
+
+ -- `set hidden`, then create two buffers and return their bufnr's
+ -- If start_from_first is truthy, the first buffer will be open when
+ -- the function returns; if falsy, the second buffer will be open.
+ local function make_two_buffers(start_from_first)
+ command('set hidden')
+
+ local first_buf = meths.call_function('bufnr', {'%'})
+ command('new')
+ local second_buf = meths.call_function('bufnr', {'%'})
+ neq(second_buf, first_buf) -- sanity check
+
+ if start_from_first then
+ switch_to_buf(first_buf)
+ end
+
+ return first_buf, second_buf
+ end
+
+ it('rejects negative bufnr values', function()
+ expect_err('Wrong type for argument 1, expecting Buffer',
+ bufmeths.set_keymap, -1, '', 'lhs', 'rhs', {})
+ end)
+
+ it('can set mappings active in the current buffer but not others', function()
+ local first, second = make_two_buffers(true)
+
+ bufmeths.set_keymap(0, '', 'lhs', 'irhs<Esc>', {})
+ command('normal lhs')
+ eq({'rhs'}, bufmeths.get_lines(0, 0, 1, 1))
+
+ -- mapping should have no effect in new buffer
+ switch_to_buf(second)
+ command('normal lhs')
+ eq({''}, bufmeths.get_lines(0, 0, 1, 1))
+
+ -- mapping should remain active in old buffer
+ switch_to_buf(first)
+ command('normal ^lhs')
+ eq({'rhsrhs'}, bufmeths.get_lines(0, 0, 1, 1))
+ end)
+
+ it('can set local mappings in buffer other than current', function()
+ local first = make_two_buffers(false)
+ bufmeths.set_keymap(first, '', 'lhs', 'irhs<Esc>', {})
+
+ -- shouldn't do anything
+ command('normal lhs')
+ eq({''}, bufmeths.get_lines(0, 0, 1, 1))
+
+ -- should take effect
+ switch_to_buf(first)
+ command('normal lhs')
+ eq({'rhs'}, bufmeths.get_lines(0, 0, 1, 1))
+ end)
+
+ it('can disable mappings made in another buffer, inside that buffer', function()
+ local first = make_two_buffers(false)
+ bufmeths.set_keymap(first, '', 'lhs', 'irhs<Esc>', {})
+ bufmeths.del_keymap(first, '', 'lhs')
+ switch_to_buf(first)
+
+ -- shouldn't do anything
+ command('normal lhs')
+ eq({''}, bufmeths.get_lines(0, 0, 1, 1))
+ end)
+
+ it("can't disable mappings given wrong buffer handle", function()
+ local first, second = make_two_buffers(false)
+ bufmeths.set_keymap(first, '', 'lhs', 'irhs<Esc>', {})
+ expect_err('E31: No such mapping',
+ bufmeths.del_keymap, second, '', 'lhs')
+
+ -- should still work
+ switch_to_buf(first)
+ command('normal lhs')
+ eq({'rhs'}, bufmeths.get_lines(0, 0, 1, 1))
+ end)
+end)
diff --git a/test/functional/api/rpc_fixture.lua b/test/functional/api/rpc_fixture.lua
index e885a525af..87f5a91115 100644
--- a/test/functional/api/rpc_fixture.lua
+++ b/test/functional/api/rpc_fixture.lua
@@ -1,7 +1,5 @@
-local deps_prefix = './.deps/usr'
-if os.getenv('DEPS_PREFIX') then
- deps_prefix = os.getenv('DEPS_PREFIX')
-end
+local deps_prefix = (os.getenv('DEPS_PREFIX') and os.getenv('DEPS_PREFIX')
+ or './.deps/usr')
package.path = deps_prefix .. '/share/lua/5.1/?.lua;' ..
deps_prefix .. '/share/lua/5.1/?/init.lua;' ..
diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua
index 4d25ba0819..7d9a8269d9 100644
--- a/test/functional/api/server_requests_spec.lua
+++ b/test/functional/api/server_requests_spec.lua
@@ -1,7 +1,6 @@
-- Test server -> client RPC scenarios. Note: unlike `rpcnotify`, to evaluate
-- `rpcrequest` calls we need the client event loop to be running.
local helpers = require('test.functional.helpers')(after_each)
-local Paths = require('test.config.paths')
local clear, nvim, eval = helpers.clear, helpers.nvim, helpers.eval
local eq, neq, run, stop = helpers.eq, helpers.neq, helpers.run, helpers.stop
@@ -243,8 +242,8 @@ describe('server -> client', function()
\ 'rpc': v:true
\ }
]])
- local lua_prog = Paths.test_lua_prg
- meths.set_var("args", {lua_prog, 'test/functional/api/rpc_fixture.lua'})
+ meths.set_var("args", {helpers.test_lua_prg,
+ 'test/functional/api/rpc_fixture.lua'})
jobid = eval("jobstart(g:args, g:job_opts)")
neq(0, 'jobid')
end)
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index 75b9fb71c9..a7d8dc59ec 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -1,6 +1,5 @@
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
-local global_helpers = require('test.helpers')
local NIL = helpers.NIL
local clear, nvim, eq, neq = helpers.clear, helpers.nvim, helpers.eq, helpers.neq
@@ -16,10 +15,10 @@ local request = helpers.request
local source = helpers.source
local next_msg = helpers.next_msg
-local expect_err = global_helpers.expect_err
-local format_string = global_helpers.format_string
-local intchar2lua = global_helpers.intchar2lua
-local mergedicts_copy = global_helpers.mergedicts_copy
+local expect_err = helpers.expect_err
+local format_string = helpers.format_string
+local intchar2lua = helpers.intchar2lua
+local mergedicts_copy = helpers.mergedicts_copy
describe('API', function()
before_each(clear)
@@ -49,13 +48,30 @@ describe('API', function()
it('handles errors in async requests', function()
local error_types = meths.get_api_info()[2].error_types
- nvim_async("bogus")
+ nvim_async('bogus')
eq({'notification', 'nvim_error_event',
{error_types.Exception.id, 'Invalid method: nvim_bogus'}}, next_msg())
-- error didn't close channel.
eq(2, eval('1+1'))
end)
+ it('failed async request emits nvim_error_event', function()
+ local error_types = meths.get_api_info()[2].error_types
+ nvim_async('command', 'bogus')
+ eq({'notification', 'nvim_error_event',
+ {error_types.Exception.id, 'Vim:E492: Not an editor command: bogus'}},
+ next_msg())
+ -- error didn't close channel.
+ eq(2, eval('1+1'))
+ end)
+
+ it('does not set CA_COMMAND_BUSY #7254', function()
+ nvim('command', 'split')
+ nvim('command', 'autocmd WinEnter * startinsert')
+ nvim('command', 'wincmd w')
+ eq({mode='i', blocking=false}, nvim("get_mode"))
+ end)
+
describe('nvim_command', function()
it('works', function()
local fname = helpers.tmpname()
@@ -83,7 +99,7 @@ describe('API', function()
end)
it('VimL execution error: fails with specific error', function()
- local status, rv = pcall(nvim, "command_output", "buffer 23487")
+ local status, rv = pcall(nvim, "command", "buffer 23487")
eq(false, status) -- nvim_command() failed.
eq("E86: Buffer 23487 does not exist", string.match(rv, "E%d*:.*"))
eq('', eval('v:errmsg')) -- v:errmsg was not updated.
@@ -1267,7 +1283,7 @@ describe('API', function()
end)
it('returns attached UIs', function()
local screen = Screen.new(20, 4)
- screen:attach()
+ screen:attach({override=true})
local expected = {
{
chan = 1,
@@ -1282,6 +1298,7 @@ describe('API', function()
ext_messages = false,
height = 4,
rgb = true,
+ override = true,
width = 20,
}
}
@@ -1291,6 +1308,7 @@ describe('API', function()
screen = Screen.new(44, 99)
screen:attach({ rgb = false })
expected[1].rgb = false
+ expected[1].override = false
expected[1].width = 44
expected[1].height = 99
eq(expected, nvim("list_uis"))
diff --git a/test/functional/autocmd/autocmd_spec.lua b/test/functional/autocmd/autocmd_spec.lua
index 42e5c46fa5..337c5442ef 100644
--- a/test/functional/autocmd/autocmd_spec.lua
+++ b/test/functional/autocmd/autocmd_spec.lua
@@ -1,4 +1,5 @@
local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
local dedent = helpers.dedent
local eq = helpers.eq
@@ -6,11 +7,13 @@ local eval = helpers.eval
local feed = helpers.feed
local clear = helpers.clear
local meths = helpers.meths
+local meth_pcall = helpers.meth_pcall
local funcs = helpers.funcs
local expect = helpers.expect
local command = helpers.command
local exc_exec = helpers.exc_exec
local curbufmeths = helpers.curbufmeths
+local source = helpers.source
describe('autocmd', function()
before_each(clear)
@@ -59,9 +62,9 @@ describe('autocmd', function()
end)
end)
- it('once', function() -- :help autocmd-once
+ it('++once', function() -- :help autocmd-once
--
- -- ":autocmd ... once" executes its handler once, then removes the handler.
+ -- ":autocmd ... ++once" executes its handler once, then removes the handler.
--
local expected = {
'Many1',
@@ -76,10 +79,10 @@ describe('autocmd', function()
}
command('let g:foo = []')
command('autocmd TabNew * :call add(g:foo, "Many1")')
- command('autocmd TabNew * once :call add(g:foo, "Once1")')
- command('autocmd TabNew * once :call add(g:foo, "Once2")')
+ command('autocmd TabNew * ++once :call add(g:foo, "Once1")')
+ command('autocmd TabNew * ++once :call add(g:foo, "Once2")')
command('autocmd TabNew * :call add(g:foo, "Many2")')
- command('autocmd TabNew * once :call add(g:foo, "Once3")')
+ command('autocmd TabNew * ++once :call add(g:foo, "Once3")')
eq(dedent([[
--- Autocommands ---
@@ -103,27 +106,158 @@ describe('autocmd', function()
funcs.execute('autocmd Tabnew'))
--
- -- ":autocmd ... once" handlers can be deleted.
+ -- ":autocmd ... ++once" handlers can be deleted.
--
expected = {}
command('let g:foo = []')
- command('autocmd TabNew * once :call add(g:foo, "Once1")')
+ command('autocmd TabNew * ++once :call add(g:foo, "Once1")')
command('autocmd! TabNew')
command('tabnew')
eq(expected, eval('g:foo'))
--
- -- ":autocmd ... <buffer> once nested"
+ -- ":autocmd ... <buffer> ++once ++nested"
--
expected = {
'OptionSet-Once',
'CursorMoved-Once',
}
command('let g:foo = []')
- command('autocmd OptionSet binary once nested :call add(g:foo, "OptionSet-Once")')
- command('autocmd CursorMoved <buffer> once nested setlocal binary|:call add(g:foo, "CursorMoved-Once")')
+ command('autocmd OptionSet binary ++nested ++once :call add(g:foo, "OptionSet-Once")')
+ command('autocmd CursorMoved <buffer> ++once ++nested setlocal binary|:call add(g:foo, "CursorMoved-Once")')
command("put ='foo bar baz'")
feed('0llhlh')
eq(expected, eval('g:foo'))
+
+ --
+ -- :autocmd should not show empty section after ++once handlers expire.
+ --
+ expected = {
+ 'Once1',
+ 'Once2',
+ }
+ command('let g:foo = []')
+ command('autocmd! TabNew') -- Clear all TabNew handlers.
+ command('autocmd TabNew * ++once :call add(g:foo, "Once1")')
+ command('autocmd TabNew * ++once :call add(g:foo, "Once2")')
+ command('tabnew')
+ eq(expected, eval('g:foo'))
+ eq(dedent([[
+
+ --- Autocommands ---]]),
+ funcs.execute('autocmd Tabnew'))
+ end)
+
+ it('window works', function()
+ -- Nvim uses a special window to execute certain actions for an invisible buffer,
+ -- internally called autcmd_win and mentioned in the docs at :help E813
+ -- Do some safety checks for redrawing and api accesses to this window.
+
+ local screen = Screen.new(50, 10)
+ screen:attach()
+ screen:set_default_attr_ids({
+ [1] = {bold = true, foreground = Screen.colors.Blue1},
+ [2] = {background = Screen.colors.LightMagenta},
+ [3] = {background = Screen.colors.LightMagenta, bold = true, foreground = Screen.colors.Blue1},
+ })
+
+ source([[
+ function! Doit()
+ let g:winid = nvim_get_current_win()
+ redraw!
+ echo getchar()
+ " API functions work when aucmd_win is in scope
+ let g:had_value = has_key(w:, "testvar")
+ call nvim_win_set_var(g:winid, "testvar", 7)
+ let g:test = w:testvar
+ endfunction
+ set hidden
+ " add dummy text to not discard the buffer
+ call setline(1,"bb")
+ autocmd User <buffer> call Doit()
+ ]])
+ screen:expect([[
+ ^bb |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]])
+
+ feed(":enew | doautoall User<cr>")
+ screen:expect([[
+ {2:bb }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ ^:enew | doautoall User |
+ ]])
+
+ feed('<cr>')
+ screen:expect([[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ 13 |
+ ]])
+ eq(7, eval('g:test'))
+
+ -- API calls are blocked when aucmd_win is not in scope
+ eq({false, 'Vim(call):Invalid window id'},
+ meth_pcall(command, "call nvim_set_current_win(g:winid)"))
+
+ -- second time aucmd_win is needed, a different code path is invoked
+ -- to reuse the same window, so check again
+ command("let g:test = v:null")
+ command("let g:had_value = v:null")
+ feed(":doautoall User<cr>")
+ screen:expect([[
+ {2:bb }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ ^:doautoall User |
+ ]])
+
+ feed('<cr>')
+ screen:expect([[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ 13 |
+ ]])
+ -- win vars in aucmd_win should have been reset
+ eq(0, eval('g:had_value'))
+ eq(7, eval('g:test'))
+
+ eq({false, 'Vim(call):Invalid window id'},
+ meth_pcall(command, "call nvim_set_current_win(g:winid)"))
end)
end)
diff --git a/test/functional/autocmd/cursormoved_spec.lua b/test/functional/autocmd/cursormoved_spec.lua
new file mode 100644
index 0000000000..d0f46e689b
--- /dev/null
+++ b/test/functional/autocmd/cursormoved_spec.lua
@@ -0,0 +1,34 @@
+local helpers = require('test.functional.helpers')(after_each)
+
+local clear = helpers.clear
+local eq = helpers.eq
+local eval = helpers.eval
+local funcs = helpers.funcs
+local source = helpers.source
+
+describe('CursorMoved', function()
+ before_each(clear)
+
+ it('is triggered by changing windows', function()
+ source([[
+ let g:cursormoved = 0
+ vsplit
+ autocmd CursorMoved * let g:cursormoved += 1
+ wincmd w
+ wincmd w
+ ]])
+ eq(2, eval('g:cursormoved'))
+ end)
+
+ it("is not triggered by functions that don't change the window", function()
+ source([[
+ let g:cursormoved = 0
+ let g:buf = bufnr('%')
+ vsplit foo
+ autocmd CursorMoved * let g:cursormoved += 1
+ call nvim_buf_set_lines(g:buf, 0, -1, v:true, ['aaa'])
+ ]])
+ eq({'aaa'}, funcs.nvim_buf_get_lines(eval('g:buf'), 0, -1, true))
+ eq(0, eval('g:cursormoved'))
+ end)
+end)
diff --git a/test/functional/autocmd/textyankpost_spec.lua b/test/functional/autocmd/textyankpost_spec.lua
index 486a3346b1..5849679dd2 100644
--- a/test/functional/autocmd/textyankpost_spec.lua
+++ b/test/functional/autocmd/textyankpost_spec.lua
@@ -23,6 +23,7 @@ describe('TextYankPost', function()
it('is executed after yank and handles register types', function()
feed('yy')
eq({
+ inclusive = false,
operator = 'y',
regcontents = { 'foo\nbar' },
regname = '',
@@ -35,6 +36,7 @@ describe('TextYankPost', function()
feed('+yw')
eq({
+ inclusive = false,
operator = 'y',
regcontents = { 'baz ' },
regname = '',
@@ -44,6 +46,7 @@ describe('TextYankPost', function()
feed('<c-v>eky')
eq({
+ inclusive = true,
operator = 'y',
regcontents = { 'foo', 'baz' },
regname = '',
@@ -55,6 +58,7 @@ describe('TextYankPost', function()
it('makes v:event immutable', function()
feed('yy')
eq({
+ inclusive = false,
operator = 'y',
regcontents = { 'foo\nbar' },
regname = '',
@@ -84,6 +88,7 @@ describe('TextYankPost', function()
command('autocmd TextYankPost * normal "+yy')
feed('yy')
eq({
+ inclusive = false,
operator = 'y',
regcontents = { 'foo\nbar' },
regname = '',
@@ -96,6 +101,7 @@ describe('TextYankPost', function()
it('is executed after delete and change', function()
feed('dw')
eq({
+ inclusive = false,
operator = 'd',
regcontents = { 'foo' },
regname = '',
@@ -105,6 +111,7 @@ describe('TextYankPost', function()
feed('dd')
eq({
+ inclusive = false,
operator = 'd',
regcontents = { '\nbar' },
regname = '',
@@ -114,6 +121,7 @@ describe('TextYankPost', function()
feed('cwspam<esc>')
eq({
+ inclusive = true,
operator = 'c',
regcontents = { 'baz' },
regname = '',
@@ -141,6 +149,7 @@ describe('TextYankPost', function()
it('gives the correct register name', function()
feed('$"byiw')
eq({
+ inclusive = true,
operator = 'y',
regcontents = { 'bar' },
regname = 'b',
@@ -149,6 +158,7 @@ describe('TextYankPost', function()
feed('"*yy')
eq({
+ inclusive = true,
operator = 'y',
regcontents = { 'foo\nbar' },
regname = '*',
@@ -160,6 +170,7 @@ describe('TextYankPost', function()
-- regname still shows the name the user requested
feed('yy')
eq({
+ inclusive = true,
operator = 'y',
regcontents = { 'foo\nbar' },
regname = '',
@@ -168,6 +179,7 @@ describe('TextYankPost', function()
feed('"*yy')
eq({
+ inclusive = true,
operator = 'y',
regcontents = { 'foo\nbar' },
regname = '*',
@@ -178,6 +190,7 @@ describe('TextYankPost', function()
it('works with Ex commands', function()
command('1delete +')
eq({
+ inclusive = false,
operator = 'd',
regcontents = { 'foo\nbar' },
regname = '+',
@@ -187,6 +200,7 @@ describe('TextYankPost', function()
command('yank')
eq({
+ inclusive = false,
operator = 'y',
regcontents = { 'baz text' },
regname = '',
@@ -196,6 +210,7 @@ describe('TextYankPost', function()
command('normal yw')
eq({
+ inclusive = false,
operator = 'y',
regcontents = { 'baz ' },
regname = '',
@@ -205,6 +220,7 @@ describe('TextYankPost', function()
command('normal! dd')
eq({
+ inclusive = false,
operator = 'd',
regcontents = { 'baz text' },
regname = '',
diff --git a/test/functional/core/channels_spec.lua b/test/functional/core/channels_spec.lua
index 7b89172f92..ddaed1c448 100644
--- a/test/functional/core/channels_spec.lua
+++ b/test/functional/core/channels_spec.lua
@@ -1,5 +1,5 @@
-
local helpers = require('test.functional.helpers')(after_each)
+local uname = helpers.uname
local clear, eq, eval, next_msg, ok, source = helpers.clear, helpers.eq,
helpers.eval, helpers.next_msg, helpers.ok, helpers.source
local command, funcs, meths = helpers.command, helpers.funcs, helpers.meths
@@ -7,6 +7,7 @@ local sleep = helpers.sleep
local spawn, nvim_argv = helpers.spawn, helpers.nvim_argv
local set_session = helpers.set_session
local nvim_prog = helpers.nvim_prog
+local os_name = helpers.os_name
local retry = helpers.retry
local expect_twostreams = helpers.expect_twostreams
@@ -138,9 +139,8 @@ describe('channels', function()
command("call chansend(id, 'incomplet\004')")
- local is_freebsd = eval("system('uname') =~? 'FreeBSD'") == 1
- local bsdlike = is_freebsd or (helpers.os_name() == "osx")
- print("bsdlike:", bsdlike)
+ local is_freebsd = (string.lower(uname()) == 'freebsd')
+ local bsdlike = is_freebsd or (os_name() == "osx")
local extra = bsdlike and "^D\008\008" or ""
expect_twoline(id, "stdout",
"incomplet"..extra, "[1, ['incomplet'], 'stdin']", true)
diff --git a/test/functional/core/fileio_spec.lua b/test/functional/core/fileio_spec.lua
index 6468aa9d0a..c74eb3bb02 100644
--- a/test/functional/core/fileio_spec.lua
+++ b/test/functional/core/fileio_spec.lua
@@ -68,7 +68,7 @@ describe('fileio', function()
eq(4, request('nvim__stats').fsync)
end)
- it('creates a backup', function()
+ it('backup #9709', function()
clear({ args={ '-i', 'Xtest_startup_shada',
'--cmd', 'set directory=Xtest_startup_swapdir' } })
diff --git a/test/functional/core/main_spec.lua b/test/functional/core/main_spec.lua
index a0981e9207..b793e531c9 100644
--- a/test/functional/core/main_spec.lua
+++ b/test/functional/core/main_spec.lua
@@ -7,19 +7,9 @@ local feed = helpers.feed
local eval = helpers.eval
local clear = helpers.clear
local funcs = helpers.funcs
-local nvim_prog = helpers.nvim_prog
+local nvim_prog_abs = helpers.nvim_prog_abs
local write_file = helpers.write_file
-local function nvim_prog_abs()
- -- system(['build/bin/nvim']) does not work for whatever reason. It needs to
- -- either be executable searched in $PATH or something starting with / or ./.
- if nvim_prog:match('[/\\]') then
- return funcs.fnamemodify(nvim_prog, ':p')
- else
- return nvim_prog
- end
-end
-
describe('Command-line option', function()
describe('-s', function()
local fname = 'Xtest-functional-core-main-s'
diff --git a/test/functional/spell/spellfile_spec.lua b/test/functional/core/spellfile_spec.lua
index afd2c1bce4..afd2c1bce4 100644
--- a/test/functional/spell/spellfile_spec.lua
+++ b/test/functional/core/spellfile_spec.lua
diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua
index 8edb8fc014..f77af836a6 100644
--- a/test/functional/core/startup_spec.lua
+++ b/test/functional/core/startup_spec.lua
@@ -13,9 +13,7 @@ local nvim_set = helpers.nvim_set
local read_file = helpers.read_file
local retry = helpers.retry
local rmdir = helpers.rmdir
-local set_session = helpers.set_session
local sleep = helpers.sleep
-local spawn = helpers.spawn
local iswin = helpers.iswin
local write_file = helpers.write_file
@@ -203,6 +201,20 @@ describe('startup', function()
{ 'set encoding', '' }))
end)
+ it('-es/-Es disables swapfile, user config #8540', function()
+ for _,arg in ipairs({'-es', '-Es'}) do
+ local out = funcs.system({nvim_prog, arg,
+ '+set swapfile? updatecount? shada?',
+ "+put =execute('scriptnames')", '+%print'})
+ local line1 = string.match(out, '^.-\n')
+ -- updatecount=0 means swapfile was disabled.
+ eq(" swapfile updatecount=0 shada=!,'100,<50,s10,h\n", line1)
+ -- Standard plugins were loaded, but not user config.
+ eq('health.vim', string.match(out, 'health.vim'))
+ eq(nil, string.match(out, 'init.vim'))
+ end
+ end)
+
it('does not crash if --embed is given twice', function()
clear{args={'--embed'}}
eq(2, eval('1+1'))
@@ -214,10 +226,6 @@ describe('sysinit', function()
local vimdir = 'Xvim'
local xhome = 'Xhome'
local pathsep = helpers.get_pathsep()
- local argv = {
- nvim_prog, '--headless', '--embed', '-i', 'NONE', '-n',
- '--cmd', 'set nomore undodir=. directory=. belloff='
- }
before_each(function()
rmdir(xdgdir)
@@ -246,19 +254,21 @@ describe('sysinit', function()
end)
it('prefers XDG_CONFIG_DIRS over VIM', function()
- set_session(spawn(argv, nil,
- { 'HOME='..xhome,
- 'XDG_CONFIG_DIRS='..xdgdir,
- 'VIM='..vimdir }))
+ clear{args={'--cmd', 'set nomore undodir=. directory=. belloff='},
+ args_rm={'-u', '--cmd'},
+ env={ HOME=xhome,
+ XDG_CONFIG_DIRS=xdgdir,
+ VIM=vimdir }}
eq('loaded 1 xdg 1 vim 0',
eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))'))
end)
it('uses VIM if XDG_CONFIG_DIRS unset', function()
- set_session(spawn(argv, nil,
- { 'HOME='..xhome,
- 'XDG_CONFIG_DIRS=',
- 'VIM='..vimdir }))
+ clear{args={'--cmd', 'set nomore undodir=. directory=. belloff='},
+ args_rm={'-u', '--cmd'},
+ env={ HOME=xhome,
+ XDG_CONFIG_DIRS='',
+ VIM=vimdir }}
eq('loaded 1 xdg 0 vim 1',
eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))'))
end)
diff --git a/test/functional/eval/api_functions_spec.lua b/test/functional/eval/api_functions_spec.lua
index 6f440c7d82..40d06b599f 100644
--- a/test/functional/eval/api_functions_spec.lua
+++ b/test/functional/eval/api_functions_spec.lua
@@ -6,7 +6,7 @@ local clear, curbufmeths = helpers.clear, helpers.curbufmeths
local exc_exec, expect, eval = helpers.exc_exec, helpers.expect, helpers.eval
local insert = helpers.insert
-describe('api functions', function()
+describe('eval-API', function()
before_each(clear)
it("work", function()
diff --git a/test/functional/eval/executable_spec.lua b/test/functional/eval/executable_spec.lua
index c931b47221..6a95128a4d 100644
--- a/test/functional/eval/executable_spec.lua
+++ b/test/functional/eval/executable_spec.lua
@@ -1,6 +1,7 @@
local helpers = require('test.functional.helpers')(after_each)
-local eq, clear, call, iswin, write_file =
- helpers.eq, helpers.clear, helpers.call, helpers.iswin, helpers.write_file
+local eq, clear, call, iswin, write_file, command =
+ helpers.eq, helpers.clear, helpers.call, helpers.iswin, helpers.write_file,
+ helpers.command
describe('executable()', function()
before_each(clear)
@@ -48,18 +49,17 @@ describe('executable()', function()
end)
it('not set', function()
- local expected = iswin() and 1 or 0
- eq(expected, call('executable', 'Xtest_not_executable'))
- eq(expected, call('executable', './Xtest_not_executable'))
+ eq(0, call('executable', 'Xtest_not_executable'))
+ eq(0, call('executable', './Xtest_not_executable'))
end)
it('set, unqualified and not in $PATH', function()
- local expected = iswin() and 1 or 0
- eq(expected, call('executable', 'Xtest_executable'))
+ eq(0, call('executable', 'Xtest_executable'))
end)
it('set, qualified as a path', function()
- eq(1, call('executable', './Xtest_executable'))
+ local expected = iswin() and 0 or 1
+ eq(expected, call('executable', './Xtest_executable'))
end)
end)
end)
@@ -136,16 +136,48 @@ describe('executable() (Windows)', function()
eq(1, call('executable', '.\\test_executable_zzz'))
end)
- it('returns 1 for any existing filename', function()
+ it("with weird $PATHEXT", function()
+ clear({env={PATHEXT=';'}})
+ eq(0, call('executable', '.\\test_executable_zzz'))
+ clear({env={PATHEXT=';;;.zzz;;'}})
+ eq(1, call('executable', '.\\test_executable_zzz'))
+ end)
+
+ it("unqualified filename, Unix-style 'shell'", function()
clear({env={PATHEXT=''}})
+ command('set shell=sh')
for _,ext in ipairs(exts) do
eq(1, call('executable', 'test_executable_'..ext..'.'..ext))
end
eq(1, call('executable', 'test_executable_zzz.zzz'))
end)
- it('returns 1 for any existing path (backslashes)', function()
+ it("relative path, Unix-style 'shell' (backslashes)", function()
clear({env={PATHEXT=''}})
+ command('set shell=bash.exe')
+ for _,ext in ipairs(exts) do
+ eq(1, call('executable', '.\\test_executable_'..ext..'.'..ext))
+ eq(1, call('executable', './test_executable_'..ext..'.'..ext))
+ end
+ eq(1, call('executable', '.\\test_executable_zzz.zzz'))
+ eq(1, call('executable', './test_executable_zzz.zzz'))
+ end)
+
+ it('unqualified filename, $PATHEXT contains dot', function()
+ clear({env={PATHEXT='.;.zzz'}})
+ for _,ext in ipairs(exts) do
+ eq(1, call('executable', 'test_executable_'..ext..'.'..ext))
+ end
+ eq(1, call('executable', 'test_executable_zzz.zzz'))
+ clear({env={PATHEXT='.zzz;.'}})
+ for _,ext in ipairs(exts) do
+ eq(1, call('executable', 'test_executable_'..ext..'.'..ext))
+ end
+ eq(1, call('executable', 'test_executable_zzz.zzz'))
+ end)
+
+ it('relative path, $PATHEXT contains dot (backslashes)', function()
+ clear({env={PATHEXT='.;.zzz'}})
for _,ext in ipairs(exts) do
eq(1, call('executable', '.\\test_executable_'..ext..'.'..ext))
eq(1, call('executable', './test_executable_'..ext..'.'..ext))
@@ -153,4 +185,17 @@ describe('executable() (Windows)', function()
eq(1, call('executable', '.\\test_executable_zzz.zzz'))
eq(1, call('executable', './test_executable_zzz.zzz'))
end)
+
+ it('ignores case of extension', function()
+ clear({env={PATHEXT='.ZZZ'}})
+ eq(1, call('executable', 'test_executable_zzz.zzz'))
+ end)
+
+ it('relative path does not search $PATH', function()
+ clear({env={PATHEXT=''}})
+ eq(0, call('executable', './System32/notepad.exe'))
+ eq(0, call('executable', '.\\System32\\notepad.exe'))
+ eq(0, call('executable', '../notepad.exe'))
+ eq(0, call('executable', '..\\notepad.exe'))
+ end)
end)
diff --git a/test/functional/eval/exepath_spec.lua b/test/functional/eval/exepath_spec.lua
new file mode 100644
index 0000000000..10a11aeacc
--- /dev/null
+++ b/test/functional/eval/exepath_spec.lua
@@ -0,0 +1,14 @@
+local helpers = require('test.functional.helpers')(after_each)
+local eq, clear, call, iswin =
+ helpers.eq, helpers.clear, helpers.call, helpers.iswin
+
+describe('exepath() (Windows)', function()
+ if not iswin() then return end -- N/A for Unix.
+
+ it('append extension if omitted', function()
+ local filename = 'cmd'
+ local pathext = '.exe'
+ clear({env={PATHEXT=pathext}})
+ eq(call('exepath', filename..pathext), call('exepath', filename))
+ end)
+end)
diff --git a/test/functional/eval/let_spec.lua b/test/functional/eval/let_spec.lua
index 0cbf40137e..63e18f943f 100644
--- a/test/functional/eval/let_spec.lua
+++ b/test/functional/eval/let_spec.lua
@@ -59,7 +59,7 @@ describe(':let', function()
end)
it("multibyte env var to child process #8398 #9267", function()
- if (not helpers.iswin()) and require('test.helpers').isCI() then
+ if (not helpers.iswin()) and helpers.isCI() then
-- Fails on non-Windows CI. Buffering/timing issue?
pending('fails on unix CI', function() end)
end
diff --git a/test/functional/ex_cmds/cd_spec.lua b/test/functional/ex_cmds/cd_spec.lua
index bc2b365b30..283fcf9672 100644
--- a/test/functional/ex_cmds/cd_spec.lua
+++ b/test/functional/ex_cmds/cd_spec.lua
@@ -286,6 +286,15 @@ describe("getcwd()", function ()
command("call delete('../"..directories.global.."', 'd')")
eq("", helpers.eval("getcwd()"))
end)
+
+ it("works with 'autochdir' after local directory was set (#9892)", function()
+ local curdir = cwd()
+ command('lcd ' .. directories.global)
+ command('lcd -')
+ command('set autochdir')
+ command('edit ' .. directories.global .. '/foo')
+ eq(curdir .. pathsep .. directories.global, cwd())
+ end)
end)
diff --git a/test/functional/ex_cmds/dict_notifications_spec.lua b/test/functional/ex_cmds/dict_notifications_spec.lua
index 3d550588e7..48e7e05e4c 100644
--- a/test/functional/ex_cmds/dict_notifications_spec.lua
+++ b/test/functional/ex_cmds/dict_notifications_spec.lua
@@ -1,12 +1,13 @@
local helpers = require('test.functional.helpers')(after_each)
local clear, nvim, source = helpers.clear, helpers.nvim, helpers.source
+local insert = helpers.insert
local eq, next_msg = helpers.eq, helpers.next_msg
local exc_exec = helpers.exc_exec
local command = helpers.command
local eval = helpers.eval
-describe('dictionary change notifications', function()
+describe('VimL dictionary notifications', function()
local channel
before_each(function()
@@ -338,4 +339,22 @@ describe('dictionary change notifications', function()
eq({'notification', '2', {'foo', {old = 'baz', new = 'bar'}}}, next_msg())
end)
end)
+
+ it('for b:changedtick', function()
+ source([[
+ function! OnTickChanged(dict, key, value)
+ call rpcnotify(g:channel, 'SendChangeTick', a:key, a:value)
+ endfunction
+ call dictwatcheradd(b:, 'changedtick', 'OnTickChanged')
+ ]])
+
+ insert('t');
+ eq({'notification', 'SendChangeTick', {'changedtick', {old = 2, new = 3}}},
+ next_msg())
+
+ command([[call dictwatcherdel(b:, 'changedtick', 'OnTickChanged')]])
+ insert('t');
+ eq(2, eval('1+1')) -- Still alive?
+ end)
+
end)
diff --git a/test/functional/ex_cmds/help_spec.lua b/test/functional/ex_cmds/help_spec.lua
new file mode 100644
index 0000000000..66d7d7d89f
--- /dev/null
+++ b/test/functional/ex_cmds/help_spec.lua
@@ -0,0 +1,27 @@
+local helpers = require('test.functional.helpers')(after_each)
+
+local clear = helpers.clear
+local command = helpers.command
+local eq = helpers.eq
+local funcs = helpers.funcs
+
+describe(':help', function()
+ before_each(clear)
+
+ it('window closed makes cursor return to a valid win/buf #9773', function()
+ command('help help')
+ eq(1001, funcs.win_getid())
+ command('quit')
+ eq(1000, funcs.win_getid())
+
+ command('autocmd WinNew * wincmd p')
+
+ command('help help')
+ -- Window 1002 is opened, but the autocmd switches back to 1000 and
+ -- creates the help buffer there instead.
+ eq(1000, funcs.win_getid())
+ command('quit')
+ -- Before #9773, Nvim would crash on quitting the help window.
+ eq(1002, funcs.win_getid())
+ end)
+end)
diff --git a/test/functional/ex_cmds/mksession_spec.lua b/test/functional/ex_cmds/mksession_spec.lua
index a5b327095e..0f7860740e 100644
--- a/test/functional/ex_cmds/mksession_spec.lua
+++ b/test/functional/ex_cmds/mksession_spec.lua
@@ -47,4 +47,27 @@ describe(':mksession', function()
command('tabnext 2')
eq(cwd_dir .. get_pathsep() .. tab_dir, funcs.getcwd())
end)
+
+ it('restores buffers when using tab-local working directories', function()
+ local tmpfile_base = file_prefix .. '-tmpfile'
+ local cwd_dir = funcs.getcwd()
+ local session_path = cwd_dir .. get_pathsep() .. session_file
+
+ command('edit ' .. tmpfile_base .. '1')
+ command('tcd ' .. tab_dir)
+ command('tabnew')
+ command('edit ' .. cwd_dir .. get_pathsep() .. tmpfile_base .. '2')
+ command('tabfirst')
+ command('mksession ' .. session_path)
+
+ -- Create a new test instance of Nvim.
+ clear()
+
+ -- Use :silent to avoid press-enter prompt due to long path
+ command('silent source ' .. session_path)
+ command('tabnext 1')
+ eq(cwd_dir .. get_pathsep() .. tmpfile_base .. '1', funcs.expand('%:p'))
+ command('tabnext 2')
+ eq(cwd_dir .. get_pathsep() .. tmpfile_base .. '2', funcs.expand('%:p'))
+ end)
end)
diff --git a/test/functional/ex_cmds/oldfiles_spec.lua b/test/functional/ex_cmds/oldfiles_spec.lua
index e2958c2924..802c3f68c6 100644
--- a/test/functional/ex_cmds/oldfiles_spec.lua
+++ b/test/functional/ex_cmds/oldfiles_spec.lua
@@ -1,18 +1,18 @@
local Screen = require('test.functional.ui.screen')
local helpers = require('test.functional.helpers')(after_each)
+local clear = helpers.clear
local buf, eq, feed_command = helpers.curbufmeths, helpers.eq, helpers.feed_command
-local feed, nvim_prog, wait = helpers.feed, helpers.nvim_prog, helpers.wait
-local ok, set_session, spawn = helpers.ok, helpers.set_session, helpers.spawn
+local feed, wait = helpers.feed, helpers.wait
+local ok = helpers.ok
local eval = helpers.eval
local shada_file = 'Xtest.shada'
local function _clear()
- set_session(spawn({nvim_prog, '--embed', '--headless', '-u', 'NONE',
- -- Need shada for these tests.
- '-i', shada_file,
- '--cmd', 'set noswapfile undodir=. directory=. viewdir=. backupdir=. belloff= noshowcmd noruler'}))
+ clear{args={'-i', shada_file, -- Need shada for these tests.
+ '--cmd', 'set noswapfile undodir=. directory=. viewdir=. backupdir=. belloff= noshowcmd noruler'},
+ args_rm={'-i', '--cmd'}}
end
describe(':oldfiles', function()
diff --git a/test/functional/ex_cmds/quickfix_commands_spec.lua b/test/functional/ex_cmds/quickfix_commands_spec.lua
index bf10f80401..3392a90270 100644
--- a/test/functional/ex_cmds/quickfix_commands_spec.lua
+++ b/test/functional/ex_cmds/quickfix_commands_spec.lua
@@ -37,9 +37,9 @@ for _, c in ipairs({'l', 'c'}) do
-- Second line of each entry (i.e. `nr=-1, …`) was obtained from actual
-- results. First line (i.e. `{lnum=…`) was obtained from legacy test.
local list = {
- {lnum=700, col=10, text='Line 700',
+ {lnum=700, col=10, text='Line 700', module='',
nr=-1, bufnr=2, valid=1, pattern='', vcol=0, ['type']=''},
- {lnum=800, col=15, text='Line 800',
+ {lnum=800, col=15, text='Line 800', module='',
nr=-1, bufnr=3, valid=1, pattern='', vcol=0, ['type']=''},
}
eq(list, getlist())
@@ -58,7 +58,7 @@ for _, c in ipairs({'l', 'c'}) do
]]):format(file))
command(('%s %s'):format(addfcmd, file))
list[#list + 1] = {
- lnum=900, col=30, text='Line 900',
+ lnum=900, col=30, text='Line 900', module='',
nr=-1, bufnr=5, valid=1, pattern='', vcol=0, ['type']='',
}
eq(list, getlist())
@@ -71,9 +71,9 @@ for _, c in ipairs({'l', 'c'}) do
command('enew!')
command(('%s %s'):format(getfcmd, file))
list = {
- {lnum=222, col=77, text='Line 222',
+ {lnum=222, col=77, text='Line 222', module='',
nr=-1, bufnr=2, valid=1, pattern='', vcol=0, ['type']=''},
- {lnum=333, col=88, text='Line 333',
+ {lnum=333, col=88, text='Line 333', module='',
nr=-1, bufnr=3, valid=1, pattern='', vcol=0, ['type']=''},
}
eq(list, getlist())
diff --git a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua
index bbab1471f6..73cbb1d54e 100644
--- a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua
+++ b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua
@@ -13,6 +13,7 @@ local rmdir = helpers.rmdir
local set_session = helpers.set_session
local spawn = helpers.spawn
local nvim_async = helpers.nvim_async
+local expect_msg_seq = helpers.expect_msg_seq
describe(':recover', function()
before_each(clear)
@@ -163,6 +164,13 @@ describe('swapfile detection', function()
screen2:expect{any=[[Found a swap file by the name ".*]]
..[[Xtest_swapdialog_dir[/\].*]]..testfile..[[%.swp"]]}
feed('e') -- Chose "Edit" at the swap dialog.
- feed('<c-c>')
+ expect_msg_seq({
+ ignore={'redraw'},
+ seqs={
+ { {'notification', 'nvim_error_event', {0, 'Vim(edit):E325: ATTENTION'}},
+ }
+ }
+ })
+ feed('<cr>')
end)
end)
diff --git a/test/functional/ex_cmds/wviminfo_spec.lua b/test/functional/ex_cmds/wviminfo_spec.lua
index df0b9df5dd..7c00daf1d7 100644
--- a/test/functional/ex_cmds/wviminfo_spec.lua
+++ b/test/functional/ex_cmds/wviminfo_spec.lua
@@ -1,23 +1,21 @@
local helpers = require('test.functional.helpers')(after_each)
local lfs = require('lfs')
-local command, eq, neq, spawn, nvim_prog, set_session, write_file =
- helpers.command, helpers.eq, helpers.neq, helpers.spawn,
- helpers.nvim_prog, helpers.set_session, helpers.write_file
+local clear = helpers.clear
+local command, eq, neq, write_file =
+ helpers.command, helpers.eq, helpers.neq, helpers.write_file
local iswin = helpers.iswin
local read_file = helpers.read_file
describe(':wshada', function()
local shada_file = 'wshada_test'
- local session
before_each(function()
- -- Override the default session because we need 'swapfile' for these tests.
- session = spawn({nvim_prog, '-u', 'NONE', '-i', iswin() and 'nul' or '/dev/null', '--embed',
- '--cmd', 'set swapfile'})
- set_session(session)
+ clear{args={'-i', iswin() and 'nul' or '/dev/null',
+ -- Need 'swapfile' for these tests.
+ '--cmd', 'set swapfile undodir=. directory=. viewdir=. backupdir=. belloff= noshowcmd noruler'},
+ args_rm={'-n', '-i', '--cmd'}}
end)
after_each(function ()
- session:close()
os.remove(shada_file)
end)
diff --git a/test/functional/example_spec.lua b/test/functional/example_spec.lua
new file mode 100644
index 0000000000..883fe4ba63
--- /dev/null
+++ b/test/functional/example_spec.lua
@@ -0,0 +1,36 @@
+-- To run this test:
+-- TEST_FILE=test/functional/example_spec.lua make functionaltest
+
+local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
+local clear, feed = helpers.clear, helpers.feed
+
+describe('example', function()
+ local screen
+ before_each(function()
+ clear()
+ screen = Screen.new(20,5)
+ screen:attach()
+ screen:set_default_attr_ids( {
+ [0] = {bold=true, foreground=Screen.colors.Blue},
+ [1] = {bold=true, foreground=Screen.colors.Brown}
+ } )
+ end)
+
+ it('screen test', function()
+ -- Do some stuff.
+ feed('iline1<cr>line2<esc>')
+
+ -- For debugging only: prints the current screen.
+ -- screen:snapshot_util()
+
+ -- Assert the expected state.
+ screen:expect([[
+ line1 |
+ line^2 |
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+ end)
+end)
diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua
index 9d82ce9c0d..35084f6cff 100644
--- a/test/functional/helpers.lua
+++ b/test/functional/helpers.lua
@@ -8,37 +8,28 @@ local Session = require('nvim.session')
local TcpStream = require('nvim.tcp_stream')
local SocketStream = require('nvim.socket_stream')
local ChildProcessStream = require('nvim.child_process_stream')
-local Paths = require('test.config.paths')
local check_cores = global_helpers.check_cores
local check_logs = global_helpers.check_logs
local dedent = global_helpers.dedent
local eq = global_helpers.eq
-local expect_err = global_helpers.expect_err
-local filter = global_helpers.filter
-local map = global_helpers.map
-local matches = global_helpers.matches
-local near = global_helpers.near
-local neq = global_helpers.neq
local ok = global_helpers.ok
-local read_file = global_helpers.read_file
local sleep = global_helpers.sleep
-local table_flatten = global_helpers.table_flatten
+local tbl_contains = global_helpers.tbl_contains
local write_file = global_helpers.write_file
-local trim = global_helpers.trim
local start_dir = lfs.currentdir()
-- XXX: NVIM_PROG takes precedence, QuickBuild sets it.
local nvim_prog = (
os.getenv('NVIM_PROG')
or os.getenv('NVIM_PRG')
- or Paths.test_build_dir .. '/bin/nvim'
+ or global_helpers.test_build_dir .. '/bin/nvim'
)
-- Default settings for the test session.
local nvim_set = 'set shortmess+=I background=light noswapfile noautoindent'
..' laststatus=1 undodir=. directory=. viewdir=. backupdir=.'
..' belloff= noshowcmd noruler nomore'
-local nvim_argv = {nvim_prog, '-u', 'NONE', '-i', 'NONE', '-N',
+local nvim_argv = {nvim_prog, '-u', 'NONE', '-i', 'NONE',
'--cmd', nvim_set, '--embed'}
-- Directory containing nvim.
local nvim_dir = nvim_prog:gsub("[/\\][^/\\]+$", "")
@@ -130,16 +121,33 @@ end
-- Expects a sequence of next_msg() results. If multiple sequences are
-- passed they are tried until one succeeds, in order of shortest to longest.
+--
+-- Can be called with positional args (list of sequences only):
+-- expect_msg_seq(seq1, seq2, ...)
+-- or keyword args:
+-- expect_msg_seq{ignore={...}, seqs={seq1, seq2, ...}}
+--
+-- ignore: List of ignored event names.
+-- seqs: List of one or more potential event sequences.
local function expect_msg_seq(...)
if select('#', ...) < 1 then
error('need at least 1 argument')
end
- local seqs = {...}
+ local arg1 = select(1, ...)
+ if (arg1['seqs'] and select('#', ...) > 1) or type(arg1) ~= 'table' then
+ error('invalid args')
+ end
+ local ignore = arg1['ignore'] and arg1['ignore'] or {}
+ local seqs = arg1['seqs'] and arg1['seqs'] or {...}
+ if type(ignore) ~= 'table' then
+ error("'ignore' arg must be a list of strings")
+ end
table.sort(seqs, function(a, b) -- Sort ascending, by (shallow) length.
return #a < #b
end)
local actual_seq = {}
+ local nr_ignored = 0
local final_error = ''
local function cat_err(err1, err2)
if err1 == nil then
@@ -152,12 +160,16 @@ local function expect_msg_seq(...)
-- Collect enough messages to compare the next expected sequence.
while #actual_seq < #expected_seq do
local msg = next_msg(10000) -- Big timeout for ASAN/valgrind.
+ local msg_type = msg and msg[2] or nil
if msg == nil then
error(cat_err(final_error,
- string.format('got %d messages, expected %d',
- #actual_seq, #expected_seq)))
+ string.format('got %d messages (ignored %d), expected %d',
+ #actual_seq, nr_ignored, #expected_seq)))
+ elseif tbl_contains(ignore, msg_type) then
+ nr_ignored = nr_ignored + 1
+ else
+ table.insert(actual_seq, msg)
end
- table.insert(actual_seq, msg)
end
local status, result = pcall(eq, expected_seq, actual_seq)
if status then
@@ -217,6 +229,16 @@ local function stop()
session:stop()
end
+local function nvim_prog_abs()
+ -- system(['build/bin/nvim']) does not work for whatever reason. It must
+ -- be executable searched in $PATH or something starting with / or ./.
+ if nvim_prog:match('[/\\]') then
+ return request('nvim_call_function', 'fnamemodify', {nvim_prog, ':p'})
+ else
+ return nvim_prog
+ end
+end
+
-- Executes an ex-command. VimL errors manifest as client (lua) errors, but
-- v:errmsg will not be updated.
local function nvim_command(cmd)
@@ -291,6 +313,43 @@ local function merge_args(...)
return argv
end
+-- Removes Nvim startup args from `args` matching items in `args_rm`.
+--
+-- "-u", "-i", "--cmd" are treated specially: their "values" are also removed.
+-- Example:
+-- args={'--headless', '-u', 'NONE'}
+-- args_rm={'--cmd', '-u'}
+-- Result:
+-- {'--headless'}
+--
+-- All cases are removed.
+-- Example:
+-- args={'--cmd', 'foo', '-N', '--cmd', 'bar'}
+-- args_rm={'--cmd', '-u'}
+-- Result:
+-- {'-N'}
+local function remove_args(args, args_rm)
+ local new_args = {}
+ local skip_following = {'-u', '-i', '-c', '--cmd', '-s', '--listen'}
+ if not args_rm or #args_rm == 0 then
+ return {unpack(args)}
+ end
+ for _, v in ipairs(args_rm) do
+ assert(type(v) == 'string')
+ end
+ local last = ''
+ for _, arg in ipairs(args) do
+ if tbl_contains(skip_following, last) then
+ last = ''
+ elseif tbl_contains(args_rm, arg) then
+ last = arg
+ else
+ table.insert(new_args, arg)
+ end
+ end
+ return new_args
+end
+
local function spawn(argv, merge, env)
local child_stream = ChildProcessStream.spawn(
merge and merge_args(prepend_argv, argv) or argv,
@@ -329,20 +388,25 @@ local function retry(max, max_ms, fn)
end
-- Starts a new global Nvim session.
+--
-- Parameters are interpreted as startup args, OR a map with these keys:
--- args: Merged with the default `nvim_argv` set.
--- env : Defines the environment of the new session.
+-- args: List: Args appended to the default `nvim_argv` set.
+-- args_rm: List: Args removed from the default set. All cases are
+-- removed, e.g. args_rm={'--cmd'} removes all cases of "--cmd"
+-- (and its value) from the default set.
+-- env: Map: Defines the environment of the new session.
--
-- Example:
-- clear('-e')
--- clear({args={'-e'}, env={TERM=term}})
+-- clear{args={'-e'}, args_rm={'-i'}, env={TERM=term}}
local function clear(...)
local args = {unpack(nvim_argv)}
+ table.insert(args, '--headless')
local new_args
local env = nil
local opts = select(1, ...)
- local headless = true
if type(opts) == 'table' then
+ args = remove_args(args, opts.args_rm)
if opts.env then
local env_tbl = {}
for k, v in pairs(opts.env) do
@@ -353,7 +417,8 @@ local function clear(...)
for _, k in ipairs({
'HOME',
'ASAN_OPTIONS',
- 'LD_LIBRARY_PATH', 'PATH',
+ 'LD_LIBRARY_PATH',
+ 'PATH',
'NVIM_LOG_FILE',
'NVIM_RPLUGIN_MANIFEST',
}) do
@@ -367,15 +432,9 @@ local function clear(...)
end
end
new_args = opts.args or {}
- if opts.headless == false then
- headless = false
- end
else
new_args = {...}
end
- if headless then
- table.insert(args, '--headless')
- end
for _, arg in ipairs(new_args) do
table.insert(args, arg)
end
@@ -679,41 +738,14 @@ local function alter_slashes(obj)
end
end
-local function compute_load_factor()
- local timeout = 200
- local times = {}
-
- clear()
-
- for _ = 1, 5 do
- source([[
- let g:val = 0
- call timer_start(200, {-> nvim_set_var('val', 1)})
- let start = reltime()
- while 1
- sleep 10m
- if g:val == 1
- let g:waited_in_ms = float2nr(reltimefloat(reltime(start)) * 1000)
- break
- endif
- endwhile
- ]])
- table.insert(times, nvim_eval('g:waited_in_ms'))
- end
-
- session:close()
- session = nil
-
- local longest = math.max(unpack(times))
- local factor = (longest + 50.0) / timeout
-
- return factor
-end
-
--- Compute load factor only once.
-local load_factor = compute_load_factor()
+local load_factor = nil
local function load_adjust(num)
+ if load_factor == nil then -- Compute load factor only once.
+ clear()
+ request('nvim_command', 'source src/nvim/testdir/load.vim')
+ load_factor = request('nvim_eval', 'g:test_load_factor')
+ end
return math.ceil(num * load_factor)
end
@@ -734,33 +766,25 @@ local module = {
curtabmeths = curtabmeths,
curwin = curwin,
curwinmeths = curwinmeths,
- dedent = dedent,
- eq = eq,
eval = nvim_eval,
exc_exec = exc_exec,
expect = expect,
expect_any = expect_any,
- expect_err = expect_err,
expect_msg_seq = expect_msg_seq,
expect_twostreams = expect_twostreams,
feed = feed,
feed_command = feed_command,
- filter = filter,
funcs = funcs,
get_pathsep = get_pathsep,
get_session = get_session,
insert = insert,
iswin = iswin,
- map = map,
- matches = matches,
merge_args = merge_args,
meth_pcall = meth_pcall,
meths = meths,
missing_provider = missing_provider,
mkdir = lfs.mkdir,
load_adjust = load_adjust,
- near = near,
- neq = neq,
new_pipename = new_pipename,
next_msg = next_msg,
nvim = nvim,
@@ -768,14 +792,13 @@ local module = {
nvim_async = nvim_async,
nvim_dir = nvim_dir,
nvim_prog = nvim_prog,
+ nvim_prog_abs = nvim_prog_abs,
nvim_set = nvim_set,
- ok = ok,
os_name = os_name,
pathroot = pathroot,
pending_win32 = pending_win32,
prepend_argv = prepend_argv,
rawfeed = rawfeed,
- read_file = read_file,
redir_exec = redir_exec,
request = request,
retry = retry,
@@ -785,21 +808,17 @@ local module = {
set_session = set_session,
set_shell_powershell = set_shell_powershell,
skip_fragile = skip_fragile,
- sleep = sleep,
source = source,
spawn = spawn,
stop = stop,
- table_flatten = table_flatten,
tabmeths = tabmeths,
tabpage = tabpage,
- tmpname = tmpname,
uimeths = uimeths,
wait = wait,
window = window,
winmeths = winmeths,
- write_file = write_file,
- trim = trim,
}
+module = global_helpers.tbl_extend('error', module, global_helpers)
return function(after_each)
if after_each then
diff --git a/test/functional/legacy/074_global_var_in_viminfo_spec.lua b/test/functional/legacy/074_global_var_in_viminfo_spec.lua
index e17b463e30..f7f074c61a 100644
--- a/test/functional/legacy/074_global_var_in_viminfo_spec.lua
+++ b/test/functional/legacy/074_global_var_in_viminfo_spec.lua
@@ -2,9 +2,9 @@
local helpers = require('test.functional.helpers')(after_each)
local lfs = require('lfs')
-local clear, command, eq, neq, eval, wait, spawn =
+local clear, command, eq, neq, eval, wait =
helpers.clear, helpers.command, helpers.eq, helpers.neq, helpers.eval,
- helpers.wait, helpers.spawn
+ helpers.wait
describe('storing global variables in ShaDa files', function()
local tempname = 'Xtest-functional-legacy-074'
@@ -14,9 +14,7 @@ describe('storing global variables in ShaDa files', function()
end)
it('is working', function()
- local nvim2 = spawn({helpers.nvim_prog, '-u', 'NONE',
- '-i', 'Xviminfo', '--embed'})
- helpers.set_session(nvim2)
+ clear{args_rm={'-i'}, args={'-i', 'Xviminfo'}}
local test_dict = {foo = 1, bar = 0, longvarible = 1000}
local test_list = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
diff --git a/test/functional/legacy/assert_spec.lua b/test/functional/legacy/assert_spec.lua
index 10703465aa..8df2d89b70 100644
--- a/test/functional/legacy/assert_spec.lua
+++ b/test/functional/legacy/assert_spec.lua
@@ -18,6 +18,15 @@ describe('assert function:', function()
clear()
end)
+ describe('assert_beeps', function()
+ it('works', function()
+ call('assert_beeps', 'normal h')
+ expected_empty()
+ call('assert_beeps', 'normal 0')
+ expected_errors({'command did not beep: normal 0'})
+ end)
+ end)
+
-- assert_equal({expected}, {actual}, [, {msg}])
describe('assert_equal', function()
it('should not change v:errors when expected is equal to actual', function()
diff --git a/test/functional/lua/overrides_spec.lua b/test/functional/lua/overrides_spec.lua
index 007d40874f..8f318e3503 100644
--- a/test/functional/lua/overrides_spec.lua
+++ b/test/functional/lua/overrides_spec.lua
@@ -300,3 +300,19 @@ describe('package.path/package.cpath', function()
eq(new_paths_str, eval_lua('package.path'):sub(1, #new_paths_str))
end)
end)
+
+describe('os.getenv', function()
+ it('returns nothing for undefined env var', function()
+ eq(NIL, funcs.luaeval('os.getenv("XTEST_1")'))
+ end)
+ it('returns env var set by the parent process', function()
+ local value = 'foo'
+ clear({env = {['XTEST_1']=value}})
+ eq(value, funcs.luaeval('os.getenv("XTEST_1")'))
+ end)
+ it('returns env var set by let', function()
+ local value = 'foo'
+ meths.command('let $XTEST_1 = "'..value..'"')
+ eq(value, funcs.luaeval('os.getenv("XTEST_1")'))
+ end)
+end)
diff --git a/test/functional/normal/jump_spec.lua b/test/functional/normal/jump_spec.lua
new file mode 100644
index 0000000000..5bed541752
--- /dev/null
+++ b/test/functional/normal/jump_spec.lua
@@ -0,0 +1,48 @@
+local helpers = require('test.functional.helpers')(after_each)
+
+local clear = helpers.clear
+local command = helpers.command
+local eq = helpers.eq
+local funcs = helpers.funcs
+local feed = helpers.feed
+local write_file = helpers.write_file
+
+describe('jumplist', function()
+ local fname1 = 'Xtest-functional-normal-jump'
+ local fname2 = fname1..'2'
+ before_each(clear)
+ after_each(function()
+ os.remove(fname1)
+ os.remove(fname2)
+ end)
+
+ it('does not add a new entry on startup', function()
+ eq('\n jump line col file/text\n>', funcs.execute('jumps'))
+ end)
+
+ it('does not require two <C-O> strokes to jump back', function()
+ write_file(fname1, 'first file contents')
+ write_file(fname2, 'second file contents')
+
+ command('args '..fname1..' '..fname2)
+ local buf1 = funcs.bufnr(fname1)
+ local buf2 = funcs.bufnr(fname2)
+
+ command('next')
+ feed('<C-O>')
+ eq(buf1, funcs.bufnr('%'))
+
+ command('first')
+ command('snext')
+ feed('<C-O>')
+ eq(buf1, funcs.bufnr('%'))
+ feed('<C-I>')
+ eq(buf2, funcs.bufnr('%'))
+ feed('<C-O>')
+ eq(buf1, funcs.bufnr('%'))
+
+ command('drop '..fname2)
+ feed('<C-O>')
+ eq(buf1, funcs.bufnr('%'))
+ end)
+end)
diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua
index f6f3f02f45..415b526051 100644
--- a/test/functional/options/defaults_spec.lua
+++ b/test/functional/options/defaults_spec.lua
@@ -15,6 +15,7 @@ local neq = helpers.neq
local mkdir = helpers.mkdir
local rmdir = helpers.rmdir
local alter_slashes = helpers.alter_slashes
+local tbl_contains = helpers.tbl_contains
describe('startup defaults', function()
describe(':filetype', function()
@@ -160,20 +161,39 @@ describe('startup defaults', function()
end)
end)
- describe("'packpath'", function()
- it('defaults to &runtimepath', function()
- eq(meths.get_option('runtimepath'), meths.get_option('packpath'))
- end)
+ it("'shadafile' ('viminfofile')", function()
+ local env = {XDG_DATA_HOME='Xtest-userdata', XDG_CONFIG_HOME='Xtest-userconfig'}
+ clear{args={}, args_rm={'-i'}, env=env}
+ -- Default 'shadafile' is empty.
+ -- This means use the default location. :help shada-file-name
+ eq('', meths.get_option('shadafile'))
+ eq('', meths.get_option('viminfofile'))
+ -- Check that shada data (such as v:oldfiles) is saved/restored.
+ command('edit Xtest-foo')
+ command('write')
+ local f = eval('fnamemodify(@%,":p")')
+ assert(string.len(f) > 3)
+ command('qall')
+ clear{args={}, args_rm={'-i'}, env=env}
+ eq({ f }, eval('v:oldfiles'))
+ os.remove('Xtest-foo')
+ rmdir('Xtest-userdata')
+ end)
- it('does not follow modifications to runtimepath', function()
- meths.command('set runtimepath+=foo')
- neq(meths.get_option('runtimepath'), meths.get_option('packpath'))
- meths.command('set packpath+=foo')
- eq(meths.get_option('runtimepath'), meths.get_option('packpath'))
- end)
+ it("'packpath'", function()
+ clear()
+ -- Defaults to &runtimepath.
+ eq(meths.get_option('runtimepath'), meths.get_option('packpath'))
+
+ -- Does not follow modifications to runtimepath.
+ meths.command('set runtimepath+=foo')
+ neq(meths.get_option('runtimepath'), meths.get_option('packpath'))
+ meths.command('set packpath+=foo')
+ eq(meths.get_option('runtimepath'), meths.get_option('packpath'))
end)
it('v:progpath is set to the absolute path', function()
+ clear()
eq(eval("fnamemodify(v:progpath, ':p')"), eval('v:progpath'))
end)
@@ -231,6 +251,23 @@ describe('XDG-based defaults', function()
-- Need separate describe() blocks to not run clear() twice.
-- Do not put before_each() here for the same reasons.
+ it("&runtimepath data-dir matches stdpath('data') #9910", function()
+ clear()
+ local rtp = eval('split(&runtimepath, ",")')
+ local rv = {}
+ local expected = (iswin()
+ and { [[\nvim-data\site]], [[\nvim-data\site\after]], }
+ or { '/nvim/site', '/nvim/site/after', })
+
+ for _,v in ipairs(rtp) do
+ local m = string.match(v, [=[[/\]nvim[^/\]*[/\]site.*$]=])
+ if m and not tbl_contains(rv, m) then
+ table.insert(rv, m)
+ end
+ end
+ eq(expected, rv)
+ end)
+
describe('with empty/broken environment', function()
it('sets correct defaults', function()
clear({env={
diff --git a/test/functional/clipboard/clipboard_provider_spec.lua b/test/functional/provider/clipboard_spec.lua
index 2bbc678a02..b2d75db745 100644
--- a/test/functional/clipboard/clipboard_provider_spec.lua
+++ b/test/functional/provider/clipboard_spec.lua
@@ -236,7 +236,7 @@ describe('clipboard', function()
end)
end)
-describe('clipboard', function()
+describe('clipboard (with fake clipboard.vim)', function()
local function reset(...)
clear('--cmd', 'let &rtp = "test/functional/fixtures,".&rtp', ...)
end
@@ -664,4 +664,20 @@ describe('clipboard', function()
the a sourcetarget]])
end)
+ it('setreg("*") with clipboard=unnamed #5646', function()
+ source([=[
+ function! Paste_without_yank(direction) range
+ let [reg_save,regtype_save] = [getreg('*'), getregtype('*')]
+ normal! gvp
+ call setreg('*', reg_save, regtype_save)
+ endfunction
+ xnoremap p :call Paste_without_yank('p')<CR>
+ set clipboard=unnamed
+ ]=])
+ insert('some words')
+ feed('gg0yiw')
+ feed('wviwp')
+ expect('some some')
+ eq('some', eval('getreg("*")'))
+ end)
end)
diff --git a/test/functional/shada/marks_spec.lua b/test/functional/shada/marks_spec.lua
index c2f6351e00..e6450e68b3 100644
--- a/test/functional/shada/marks_spec.lua
+++ b/test/functional/shada/marks_spec.lua
@@ -189,9 +189,6 @@ describe('ShaDa support code', function()
eq(1, nvim_current_line())
nvim_command('execute "normal! \\<C-o>"')
eq(testfilename, funcs.bufname('%'))
- eq(1, nvim_current_line())
- nvim_command('execute "normal! \\<C-o>"')
- eq(testfilename, funcs.bufname('%'))
eq(2, nvim_current_line())
nvim_command('execute "normal! \\<C-o>"')
eq(testfilename_2, funcs.bufname('%'))
@@ -199,6 +196,9 @@ describe('ShaDa support code', function()
nvim_command('execute "normal! \\<C-o>"')
eq(testfilename_2, funcs.bufname('%'))
eq(2, nvim_current_line())
+ nvim_command('execute "normal! \\<C-o>"')
+ eq(testfilename_2, funcs.bufname('%'))
+ eq(2, nvim_current_line())
end)
it('is able to dump and restore change list', function()
diff --git a/test/functional/shada/merging_spec.lua b/test/functional/shada/merging_spec.lua
index a628baff53..22f2b8348d 100644
--- a/test/functional/shada/merging_spec.lua
+++ b/test/functional/shada/merging_spec.lua
@@ -912,12 +912,11 @@ describe('ShaDa jumps support code', function()
eq('', curbufmeths.get_name())
eq('\n'
.. ' jump line col file/text\n'
- .. ' 6 2 0 ' .. mock_file_path .. 'c\n'
- .. ' 5 2 0 ' .. mock_file_path .. 'd\n'
- .. ' 4 3 0 ' .. mock_file_path .. 'd\n'
- .. ' 3 2 0 ' .. mock_file_path .. 'e\n'
- .. ' 2 2 0 ' .. mock_file_path .. 'f\n'
- .. ' 1 1 0 \n'
+ .. ' 5 2 0 ' .. mock_file_path .. 'c\n'
+ .. ' 4 2 0 ' .. mock_file_path .. 'd\n'
+ .. ' 3 3 0 ' .. mock_file_path .. 'd\n'
+ .. ' 2 2 0 ' .. mock_file_path .. 'e\n'
+ .. ' 1 2 0 ' .. mock_file_path .. 'f\n'
.. '>', redir_exec('jumps'))
end)
diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua
index dbee9bdb49..f3849709e3 100644
--- a/test/functional/terminal/ex_terminal_spec.lua
+++ b/test/functional/terminal/ex_terminal_spec.lua
@@ -99,6 +99,22 @@ describe(':terminal', function()
eq(3, #jumps)
end)
+ it(':stopinsert RPC request exits terminal-mode #7807', function()
+ command(':terminal')
+ feed('i[tui] insert-mode')
+ eq({ blocking=false, mode='t' }, nvim('get_mode'))
+ command('stopinsert')
+ eq({ blocking=false, mode='n' }, nvim('get_mode'))
+ end)
+
+ it(':stopinsert in normal mode doesn\'t break insert mode #9889', function()
+ command(':terminal')
+ eq({ blocking=false, mode='n' }, nvim('get_mode'))
+ command(':stopinsert')
+ eq({ blocking=false, mode='n' }, nvim('get_mode'))
+ feed('a')
+ eq({ blocking=false, mode='t' }, nvim('get_mode'))
+ end)
end)
describe(':terminal (with fake shell)', function()
diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua
index 9579e0ea0b..48fedd5927 100644
--- a/test/functional/terminal/highlight_spec.lua
+++ b/test/functional/terminal/highlight_spec.lua
@@ -3,9 +3,12 @@ local Screen = require('test.functional.ui.screen')
local thelpers = require('test.functional.terminal.helpers')
local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim
local nvim_dir, command = helpers.nvim_dir, helpers.command
+local nvim_prog_abs = helpers.nvim_prog_abs
local eq, eval = helpers.eq, helpers.eval
+local funcs = helpers.funcs
+local nvim_set = helpers.nvim_set
-describe(':terminal window highlighting', function()
+describe(':terminal highlight', function()
local screen
before_each(function()
@@ -112,8 +115,51 @@ describe(':terminal window highlighting', function()
end)
end)
+it(':terminal highlight has lower precedence than editor #9964', function()
+ clear()
+ local screen = Screen.new(30, 4)
+ screen:set_default_attr_ids({
+ -- "Normal" highlight emitted by the child nvim process.
+ N_child = {foreground = tonumber('0x4040ff'), background = tonumber('0xffff40')},
+ -- "Search" highlight emitted by the child nvim process.
+ S_child = {background = tonumber('0xffff40'), italic = true, foreground = tonumber('0x4040ff')},
+ -- "Search" highlight in the parent nvim process.
+ S = {background = Screen.colors.Green, italic = true, foreground = Screen.colors.Red},
+ -- "Question" highlight in the parent nvim process.
+ Q = {background = tonumber('0xffff40'), bold = true, foreground = Screen.colors.SeaGreen4},
+ })
+ screen:attach({rgb=true})
+ -- Child nvim process in :terminal (with cterm colors).
+ funcs.termopen({
+ nvim_prog_abs(), '-n', '-u', 'NORC', '-i', 'NONE', '--cmd', nvim_set,
+ '+hi Normal ctermfg=Blue ctermbg=Yellow',
+ '+norm! ichild nvim',
+ '+norm! oline 2',
+ })
+ screen:expect([[
+ {N_child:^child nvim }|
+ {N_child:line 2 }|
+ {N_child: }|
+ |
+ ]])
+ command('hi Search gui=italic guifg=Red guibg=Green cterm=italic ctermfg=Red ctermbg=Green')
+ feed('/nvim<cr>')
+ screen:expect([[
+ {N_child:child }{S:^nvim}{N_child: }|
+ {N_child:line 2 }|
+ {N_child: }|
+ /nvim |
+ ]])
+ command('syntax keyword Question line')
+ screen:expect([[
+ {N_child:child }{S:^nvim}{N_child: }|
+ {Q:line}{N_child: 2 }|
+ {N_child: }|
+ /nvim |
+ ]])
+end)
-describe('terminal window highlighting with custom palette', function()
+describe(':terminal highlight with custom palette', function()
local screen
before_each(function()
diff --git a/test/functional/terminal/scrollback_spec.lua b/test/functional/terminal/scrollback_spec.lua
index 75bb89a1ab..544325e746 100644
--- a/test/functional/terminal/scrollback_spec.lua
+++ b/test/functional/terminal/scrollback_spec.lua
@@ -142,15 +142,15 @@ describe(':terminal scrollback', function()
describe('and height decreased by 1', function()
if helpers.pending_win32(pending) then return end
local function will_hide_top_line()
- feed([[<C-\><C-N>:]]) -- Go to cmdline-mode, so cursor is at bottom.
+ feed([[<C-\><C-N>]])
screen:try_resize(screen._width - 2, screen._height - 1)
screen:expect([[
line2 |
line3 |
line4 |
rows: 5, cols: 28 |
- {2: } |
- :^ |
+ {2:^ } |
+ |
]])
end
@@ -166,11 +166,11 @@ describe(':terminal scrollback', function()
screen:expect([[
rows: 5, cols: 28 |
rows: 3, cols: 26 |
- {2: } |
- :^ |
+ {2:^ } |
+ |
]])
eq(8, curbuf('line_count'))
- feed([[<C-\><C-N>3k]])
+ feed([[3k]])
screen:expect([[
^line4 |
rows: 5, cols: 28 |
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index a0adb45630..56d6f68b7a 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -1,8 +1,7 @@
-- TUI acceptance tests.
-- Uses :terminal as a way to send keys and assert screen state.
-local global_helpers = require('test.helpers')
-local uname = global_helpers.uname
local helpers = require('test.functional.helpers')(after_each)
+local uname = helpers.uname
local thelpers = require('test.functional.terminal.helpers')
local Screen = require('test.functional.ui.screen')
local eq = helpers.eq
@@ -255,14 +254,14 @@ describe('TUI', function()
]])
end)
- it('shows up in nvim_list_uis', function()
+ it('is included in nvim_list_uis()', function()
feed_data(':echo map(nvim_list_uis(), {k,v -> sort(items(filter(v, {k,v -> k[:3] !=# "ext_" })))})\013')
screen:expect([=[
|
{4:~ }|
{5: }|
- [[['height', 6], ['rgb', v:false], ['width', 50]]]|
- |
+ [[['height', 6], ['override', v:false], ['rgb', v:|
+ false], ['width', 50]]] |
{10:Press ENTER or type command to continue}{1: } |
{3:-- TERMINAL --} |
]=])
@@ -839,8 +838,7 @@ describe('TUI background color', function()
it("triggers OptionSet event on terminal-response", function()
feed_data('\027:autocmd OptionSet background echo "did OptionSet, yay!"\n')
- -- The child Nvim is running asynchronously; wait for it to register the
- -- OptionSet handler.
+ -- Wait for the child Nvim to register the OptionSet handler.
feed_data('\027:autocmd OptionSet\n')
screen:expect({any='--- Autocommands ---'})
@@ -860,16 +858,23 @@ describe('TUI background color', function()
local function assert_bg(color, bg)
it('handles '..color..' as '..bg, function()
- feed_data('\027]11;rgb:'..color..'\007:echo &background\n')
- screen:expect(string.format([[
- {1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
- {5:[No Name] 0,0-1 All}|
- %-5s |
- {3:-- TERMINAL --} |
- ]], bg))
+ feed_data('\027]11;rgb:'..color..'\007')
+ -- Retry until the terminal response is handled.
+ retry(100, nil, function()
+ feed_data(':echo &background\n')
+ screen:expect({
+ timeout=40,
+ grid=string.format([[
+ {1: } |
+ {4:~ }|
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] 0,0-1 All}|
+ %-5s |
+ {3:-- TERMINAL --} |
+ ]], bg)
+ })
+ end)
end)
end
diff --git a/test/functional/terminal/window_split_tab_spec.lua b/test/functional/terminal/window_split_tab_spec.lua
index c0ce656bb1..ad70b3d14f 100644
--- a/test/functional/terminal/window_split_tab_spec.lua
+++ b/test/functional/terminal/window_split_tab_spec.lua
@@ -69,7 +69,7 @@ describe(':terminal', function()
end)
it('forwards resize request to the program', function()
- feed([[<C-\><C-N>G:]]) -- Go to cmdline-mode, so cursor is at bottom.
+ feed([[<C-\><C-N>G]])
local w1, h1 = screen._width - 3, screen._height - 2
local w2, h2 = w1 - 6, h1 - 3
@@ -92,16 +92,16 @@ describe(':terminal', function()
|
|
|
+ ^ |
|
- :^ |
]])
screen:try_resize(w2, h2)
screen:expect([[
tty ready |
rows: 7, cols: 47 |
rows: 4, cols: 41 |
- {2: } |
- :^ |
+ {2:^ } |
+ |
]])
end)
end)
diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua
index 1568b7816e..45808b3b1b 100644
--- a/test/functional/ui/cmdline_highlight_spec.lua
+++ b/test/functional/ui/cmdline_highlight_spec.lua
@@ -975,8 +975,6 @@ describe('Expressions coloring support', function()
]])
funcs.setreg('a', {'\192'})
feed('<C-r>="<C-r><C-r>a"<C-r><C-r>a"foo"')
- -- TODO(ZyX-I): Parser highlighting should not override special character
- -- highlighting.
screen:expect([[
|
{EOB:~ }|
diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua
index 5d112d7f35..5d563895d6 100644
--- a/test/functional/ui/cmdline_spec.lua
+++ b/test/functional/ui/cmdline_spec.lua
@@ -116,6 +116,31 @@ local function test_cmdline(linegrid)
}}}
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>')
@@ -600,6 +625,137 @@ local function test_cmdline(linegrid)
pos = 12,
}}}
end)
+
+ it('works together with ext_popupmenu', function()
+ local expected = {
+ {'define', '', '', ''},
+ {'jump', '', '', ''},
+ {'list', '', '', ''},
+ {'place', '', '', ''},
+ {'undefine', '', '', ''},
+ {'unplace', '', '', ''},
+ }
+
+ command('set wildmode=full')
+ command('set wildmenu')
+ screen:set_option('ext_popupmenu', true)
+ feed(':sign <tab>')
+
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]], cmdline={{
+ firstc = ":",
+ content = {{"sign define"}},
+ pos = 11,
+ }}, popupmenu={items=expected, pos=0, anchor={-1, 0, 5}}}
+
+ feed('<tab>')
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]], cmdline={{
+ firstc = ":",
+ content = {{"sign jump"}},
+ pos = 9,
+ }}, popupmenu={items=expected, pos=1, anchor={-1, 0, 5}}}
+
+ feed('<left><left>')
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]], cmdline={{
+ firstc = ":",
+ content = {{"sign "}},
+ pos = 5,
+ }}, popupmenu={items=expected, pos=-1, anchor={-1, 0, 5}}}
+
+ feed('<right>')
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]], cmdline={{
+ firstc = ":",
+ content = {{"sign define"}},
+ pos = 11,
+ }}, popupmenu={items=expected, pos=0, anchor={-1, 0, 5}}}
+
+ feed('a')
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]], cmdline={{
+ firstc = ":",
+ content = {{"sign definea"}},
+ pos = 12,
+ }}}
+ feed('<esc>')
+
+ -- check positioning with multibyte char in pattern
+ command("e långfile1")
+ command("sp långfile2")
+ feed(':b lå<tab>')
+ screen:expect{grid=[[
+ ^ |
+ {3:långfile2 }|
+ |
+ {2:långfile1 }|
+ |
+ ]], popupmenu={
+ anchor = { -1, 0, 2 },
+ items = {{ "långfile1", "", "", "" }, { "långfile2", "", "", "" }},
+ pos = 0
+ }, cmdline={{
+ content = {{ "b långfile1" }},
+ firstc = ":",
+ pos = 12
+ }}}
+ end)
+
+ it('ext_wildmenu takes precedence over ext_popupmenu', function()
+ local expected = {
+ 'define',
+ 'jump',
+ 'list',
+ 'place',
+ 'undefine',
+ 'unplace',
+ }
+
+ command('set wildmode=full')
+ command('set wildmenu')
+ screen:set_option('ext_wildmenu', true)
+ screen:set_option('ext_popupmenu', true)
+ feed(':sign <tab>')
+
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]], cmdline={{
+ firstc = ":",
+ content = {{"sign define"}},
+ pos = 11,
+ }}, wildmenu_items=expected, wildmenu_pos=0}
+ end)
+
end
-- the representation of cmdline and cmdline_block contents changed with ext_linegrid
diff --git a/test/functional/ui/cursor_spec.lua b/test/functional/ui/cursor_spec.lua
index 3e0370db14..4dc86f1e1f 100644
--- a/test/functional/ui/cursor_spec.lua
+++ b/test/functional/ui/cursor_spec.lua
@@ -216,10 +216,10 @@ describe('ui/cursor', function()
if m.blinkwait then m.blinkwait = 700 end
end
if m.hl_id then
- m.hl_id = 49
+ m.hl_id = 50
m.attr = {background = Screen.colors.DarkGray}
end
- if m.id_lm then m.id_lm = 50 end
+ if m.id_lm then m.id_lm = 51 end
end
-- Assert the new expectation.
diff --git a/test/functional/ui/diff_spec.lua b/test/functional/ui/diff_spec.lua
index 8e6756e550..8eb2bbf779 100644
--- a/test/functional/ui/diff_spec.lua
+++ b/test/functional/ui/diff_spec.lua
@@ -62,12 +62,12 @@ describe('Diff mode screen', function()
{1: }5 {3:│}{1: }5 |
{1: }6 {3:│}{1: }6 |
{1:+ }{5:+-- 4 lines: 7···}{3:│}{1:+ }{5:+-- 4 lines: 7··}|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt=filler |
]])
@@ -82,12 +82,12 @@ describe('Diff mode screen', function()
{1: }5 {3:│}{1: }5 |
{1: }6 {3:│}{1: }6 |
{1:+ }{5:+-- 4 lines: 7···}{3:│}{1:+ }{5:+-- 4 lines: 7··}|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt+=internal |
]])
@@ -108,12 +108,12 @@ describe('Diff mode screen', function()
{1: }5 {3:│}{1: }5 |
{1: }6 {3:│}{1: }6 |
{1:+ }{5:+-- 4 lines: 7···}{3:│}{1:+ }{5:+-- 4 lines: 7··}|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt=filler |
]])
@@ -128,12 +128,12 @@ describe('Diff mode screen', function()
{1: }5 {3:│}{1: }5 |
{1: }6 {3:│}{1: }6 |
{1:+ }{5:+-- 4 lines: 7···}{3:│}{1:+ }{5:+-- 4 lines: 7··}|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt+=internal |
]])
@@ -154,12 +154,12 @@ describe('Diff mode screen', function()
{1: }9 {3:│}{1: }9 |
{1: }10 {3:│}{1: }10 |
{1: }{2:------------------}{3:│}{1: }{4:11 }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt=filler |
]])
@@ -174,12 +174,12 @@ describe('Diff mode screen', function()
{1: }9 {3:│}{1: }9 |
{1: }10 {3:│}{1: }10 |
{1: }{2:------------------}{3:│}{1: }{4:11 }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt+=internal |
]])
@@ -200,12 +200,12 @@ describe('Diff mode screen', function()
{1: }9 {3:│}{1: }9 |
{1: }10 {3:│}{1: }10 |
{1: }{4:11 }{3:│}{1: }{2:-----------------}|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt=filler |
]])
@@ -220,12 +220,12 @@ describe('Diff mode screen', function()
{1: }9 {3:│}{1: }9 |
{1: }10 {3:│}{1: }10 |
{1: }{4:11 }{3:│}{1: }{2:-----------------}|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt+=internal |
]])
@@ -250,8 +250,8 @@ describe('Diff mode screen', function()
{1: }9 {3:│}{1: }9 |
{1: }10 {3:│}{1: }10 |
{1: }{4:11 }{3:│}{1: }{2:-----------------}|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt=filler |
]])
@@ -270,8 +270,8 @@ describe('Diff mode screen', function()
{1: }9 {3:│}{1: }9 |
{1: }10 {3:│}{1: }10 |
{1: }{4:11 }{3:│}{1: }{2:-----------------}|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt+=internal |
]])
@@ -296,8 +296,8 @@ describe('Diff mode screen', function()
{1: }9 {3:│}{1: }9 |
{1: }10 {3:│}{1: }10 |
{1: }{2:------------------}{3:│}{1: }{4:11 }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt=filler |
]])
@@ -316,8 +316,8 @@ describe('Diff mode screen', function()
{1: }9 {3:│}{1: }9 |
{1: }10 {3:│}{1: }10 |
{1: }{2:------------------}{3:│}{1: }{4:11 }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt+=internal |
]])
@@ -546,11 +546,11 @@ int main(int argc, char **argv)
{1: }{2:------------------}{3:│}{1: }{4: values.each do }|
{1: } v.finalize {3:│}{1: } v.finalize |
{1: } end {3:│}{1: } end |
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt=internal,filler |
]])
@@ -569,11 +569,11 @@ int main(int argc, char **argv)
{1: } values.each do |{3:│}{1: } values.each do |
{1: } v.finalize {3:│}{1: } v.finalize |
{1: } end {3:│}{1: } end |
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
|
]])
@@ -593,11 +593,11 @@ int main(int argc, char **argv)
{1: } values.each do |{3:│}{1: } values.each do |
{1: } v.finalize {3:│}{1: } v.finalize |
{1: } end {3:│}{1: } end |
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
: |
]])
@@ -612,19 +612,19 @@ int main(int argc, char **argv)
feed(':set diffopt=filler<cr>')
screen:expect([[
{1:+ }{5:^+-- 10 lines: 1···}{3:│}{1:+ }{5:+-- 10 lines: 1··}|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt=filler |
]])
@@ -632,19 +632,19 @@ int main(int argc, char **argv)
feed(':set diffopt+=internal<cr>')
screen:expect([[
{1:+ }{5:^+-- 10 lines: 1···}{3:│}{1:+ }{5:+-- 10 lines: 1··}|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt+=internal |
]])
@@ -658,19 +658,19 @@ int main(int argc, char **argv)
feed(':set diffopt=filler<cr>')
screen:expect([[
{1:- }^ {3:│}{1:- } |
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt=filler |
]])
@@ -678,19 +678,19 @@ int main(int argc, char **argv)
feed(':set diffopt+=internal<cr>')
screen:expect([[
{1:- }^ {3:│}{1:- } |
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt+=internal |
]])
@@ -706,17 +706,17 @@ int main(int argc, char **argv)
{1: }^a {3:│}{1: }A |
{1: }b {3:│}{1: }b |
{1: }{9:cd }{3:│}{1: }{9:cD}{8:e}{9: }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt=filler,icase |
]])
@@ -726,17 +726,17 @@ int main(int argc, char **argv)
{1: }^a {3:│}{1: }A |
{1: }b {3:│}{1: }b |
{1: }{9:cd }{3:│}{1: }{9:cD}{8:e}{9: }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt+=internal |
]])
@@ -763,12 +763,12 @@ int main(int argc, char **argv)
{1: } return 0; {3:│}{1: } return 0; |
{1: }{2:------------------}{3:│}{1: }{4: } }|
{1: }} {3:│}{1: }} |
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt=filler,iwhite |
]])
@@ -786,12 +786,12 @@ int main(int argc, char **argv)
{1: } return 0; {3:│}{1: } return 0; |
{1: }{2:------------------}{3:│}{1: }{4: } }|
{1: }} {3:│}{1: }} |
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt=filler,iwhite,internal |
]])
@@ -815,14 +815,14 @@ int main(int argc, char **argv)
{1: }cd {3:│}{1: }cd |
{1: }ef {3:│}{1: } |
{1: }{8:xxx}{9: }{3:│}{1: }ef |
- {1: }{6:~ }{3:│}{1: }{8:yyy}{9: }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{1: }{8:yyy}{9: }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
:set diffopt=internal,filler,iblank |
]])
@@ -838,15 +838,15 @@ int main(int argc, char **argv)
{1: } {3:│}{1: } |
{1: }cd {3:│}{1: }ef |
{1: }ef {3:│}{1: }{8:yyy}{9: }|
- {1: }{8:xxx}{9: }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {1: }{8:xxx}{9: }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
: |
]])
@@ -862,15 +862,15 @@ int main(int argc, char **argv)
{1: } {3:│}{1: } |
{1: }cd {3:│}{1: }ef |
{1: }ef {3:│}{1: }{8:yyy}{9: }|
- {1: }{8:xxx}{9: }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {1: }{8:xxx}{9: }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
: |
]])
@@ -886,15 +886,15 @@ int main(int argc, char **argv)
{1: } {3:│}{1: } |
{1: }cd {3:│}{1: }ef |
{1: }ef {3:│}{1: }{8:yyy}{9: }|
- {1: }{8:xxx}{9: }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {1: }{8:xxx}{9: }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
: |
]])
@@ -921,12 +921,12 @@ int main(int argc, char **argv)
{1: }foo {3:│}{1: }foo |
{1: }{2:------------------}{3:│}{1: }{4: }|
{1: }bar {3:│}{1: }bar |
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
: |
]])
@@ -945,12 +945,12 @@ int main(int argc, char **argv)
{1: }foo {3:│}{1: }foo |
{1: }{2:------------------}{3:│}{1: }{4: }|
{1: }bar {3:│}{1: }bar |
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
- {1: }{6:~ }{3:│}{1: }{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
+ {6:~ }{3:│}{6:~ }|
{7:<onal-diff-screen-1 }{3:<l-diff-screen-1.2 }|
: |
]])
diff --git a/test/functional/ui/embed_spec.lua b/test/functional/ui/embed_spec.lua
index 10dbc68672..9196c8af40 100644
--- a/test/functional/ui/embed_spec.lua
+++ b/test/functional/ui/embed_spec.lua
@@ -8,7 +8,7 @@ local clear = helpers.clear
local function test_embed(ext_linegrid)
local screen
local function startup(...)
- clear{headless=false, args={...}}
+ clear{args_rm={'--headless'}, args={...}}
-- attach immediately after startup, for early UI
screen = Screen.new(60, 8)
diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua
index 3be2182eb4..a567fbb941 100644
--- a/test/functional/ui/float_spec.lua
+++ b/test/functional/ui/float_spec.lua
@@ -5,6 +5,7 @@ local clear, feed = helpers.clear, helpers.feed
local command, feed_command = helpers.command, helpers.feed_command
local eval = helpers.eval
local eq = helpers.eq
+local insert = helpers.insert
local meths = helpers.meths
local curbufmeths = helpers.curbufmeths
local funcs = helpers.funcs
@@ -29,9 +30,27 @@ describe('floating windows', function()
[10] = {background = Screen.colors.LightGrey, underline = true, bold = true, foreground = Screen.colors.Magenta},
[11] = {bold = true, foreground = Screen.colors.Magenta},
[12] = {background = Screen.colors.Red, bold = true, foreground = Screen.colors.Blue1},
- [13] = {background = Screen.colors.WebGray}
+ [13] = {background = Screen.colors.WebGray},
+ [14] = {foreground = Screen.colors.Brown},
+ [15] = {background = Screen.colors.Grey20},
+ [16] = {background = Screen.colors.Grey20, bold = true, foreground = Screen.colors.Blue1},
+ [17] = {background = Screen.colors.Yellow},
}
+ it('behavior', function()
+ -- Create three windows and test that ":wincmd <direction>" changes to the
+ -- first window, if the previous window is invalid.
+ command('split')
+ meths.open_win(0, true, {width=10, height=10, relative='editor', row=0, col=0})
+ eq(1002, funcs.win_getid())
+ eq('editor', meths.win_get_config(1002).relative)
+ command([[
+ call nvim_win_close(1001, v:false)
+ wincmd j
+ ]])
+ eq(1000, funcs.win_getid())
+ end)
+
local function with_ext_multigrid(multigrid)
local screen
before_each(function()
@@ -42,13 +61,11 @@ describe('floating windows', function()
it('can be created and reconfigured', function()
local buf = meths.create_buf(false,false)
- local win = meths.open_win(buf, false, 20, 2, {relative='editor', row=2, col=5})
- meths.win_set_option(win , 'winhl', 'Normal:PMenu')
+ local win = meths.open_win(buf, false, {relative='editor', width=20, height=2, row=2, col=5})
local expected_pos = {
[3]={{id=1001}, 'NW', 1, 2, 5, true},
}
-
if multigrid then
screen:expect{grid=[[
## grid 1
@@ -83,7 +100,7 @@ describe('floating windows', function()
end
- meths.win_config(win,0,0,{relative='editor', row=0, col=10})
+ meths.win_set_config(win, {relative='editor', row=0, col=10})
expected_pos[3][4] = 0
expected_pos[3][5] = 10
if multigrid then
@@ -151,20 +168,226 @@ describe('floating windows', function()
end
end)
+ it('return their configuration', function()
+ local buf = meths.create_buf(false, false)
+ local win = meths.open_win(buf, false, {relative='editor', width=20, height=2, row=3, col=5})
+ local expected = {anchor='NW', col=5, external=false, focusable=true, height=2, relative='editor', row=3, width=20}
+ eq(expected, meths.win_get_config(win))
+
+ eq({relative='', external=false, focusable=true}, meths.win_get_config(0))
+
+ if multigrid then
+ meths.win_set_config(win, {external=true, width=10, height=1})
+ eq({external=true,focusable=true,width=10,height=1,relative=''}, meths.win_get_config(win))
+ end
+ end)
+
+ it('defaults to nonumber and NormalFloat highlight', function()
+ command('set number')
+ command('hi NormalFloat guibg=#333333')
+ feed('ix<cr>y<cr><esc>gg')
+ local win = meths.open_win(0, false, {relative='editor', width=20, height=4, row=4, col=10})
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ |
+ ## grid 2
+ {14: 1 }^x |
+ {14: 2 }y |
+ {14: 3 } |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ {15:x }|
+ {15:y }|
+ {15: }|
+ {16:~ }|
+ ]], float_pos={[3] = {{id = 1001}, "NW", 1, 4, 10, true}}}
+ else
+ screen:expect([[
+ {14: 1 }^x |
+ {14: 2 }y |
+ {14: 3 } {15:x } |
+ {0:~ }{15:y }{0: }|
+ {0:~ }{15: }{0: }|
+ {0:~ }{16:~ }{0: }|
+ |
+ ]])
+ end
+
+ local buf = meths.create_buf(false, true)
+ meths.win_set_buf(win, buf)
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ |
+ ## grid 2
+ {14: 1 }^x |
+ {14: 2 }y |
+ {14: 3 } |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ {15: }|
+ {16:~ }|
+ {16:~ }|
+ {16:~ }|
+ ]], float_pos={[3] = {{id = 1001}, "NW", 1, 4, 10, true}}}
+ else
+ screen:expect([[
+ {14: 1 }^x |
+ {14: 2 }y |
+ {14: 3 } {15: } |
+ {0:~ }{16:~ }{0: }|
+ {0:~ }{16:~ }{0: }|
+ {0:~ }{16:~ }{0: }|
+ |
+ ]])
+ end
+ end)
+
+ it('can have minimum size', function()
+ insert("the background text")
+ local buf = meths.create_buf(false, true)
+ meths.buf_set_lines(buf, 0, -1, true, {'x'})
+ local win = meths.open_win(buf, false, {relative='win', width=1, height=1, row=0, col=4, focusable=false})
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ |
+ ## grid 2
+ the background tex^t |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 4
+ {1:x}|
+ ]], float_pos={
+ [4] = {{id = 1002}, "NW", 2, 0, 4, false}
+ }}
+ else
+ screen:expect([[
+ the {1:x}ackground tex^t |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+ end
+
+ meths.win_set_config(win, {relative='win', row=0, col=15})
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ |
+ ## grid 2
+ the background tex^t |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 4
+ {1:x}|
+ ]], float_pos={
+ [4] = {{id = 1002}, "NW", 2, 0, 15, false}
+ }}
+ else
+ screen:expect([[
+ the background {1:x}ex^t |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+ end
+
+ meths.win_close(win,false)
+ if multigrid then
+ screen:expect([[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ |
+ ## grid 2
+ the background tex^t |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ]])
+ else
+ screen:expect([[
+ the background tex^t |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+ end
+ end)
+
it('API has proper error messages', function()
local buf = meths.create_buf(false,false)
- eq({false, "Invalid options key 'bork'"},
- meth_pcall(meths.open_win,buf, false, 20, 2, {bork=true}))
- eq({false, "'win' option is only valid with relative='win'"},
- meth_pcall(meths.open_win,buf, false, 20, 2, {relative='editor',row=0,col=0,win=0}))
- eq({false, "Only one of 'relative' and 'external' should be used"},
- meth_pcall(meths.open_win,buf, false, 20, 2, {relative='editor',row=0,col=0,external=true}))
- eq({false, "Invalid value of 'relative' option"},
- meth_pcall(meths.open_win,buf, false, 20, 2, {relative='shell',row=0,col=0}))
- eq({false, "Invalid value of 'anchor' option"},
- meth_pcall(meths.open_win,buf, false, 20, 2, {relative='editor',row=0,col=0,anchor='bottom'}))
+ eq({false, "Invalid key 'bork'"},
+ meth_pcall(meths.open_win,buf, false, {width=20,height=2,bork=true}))
+ eq({false, "'win' key is only valid with relative='win'"},
+ meth_pcall(meths.open_win,buf, false, {width=20,height=2,relative='editor',row=0,col=0,win=0}))
+ eq({false, "Only one of 'relative' and 'external' must be used"},
+ meth_pcall(meths.open_win,buf, false, {width=20,height=2,relative='editor',row=0,col=0,external=true}))
+ eq({false, "Invalid value of 'relative' key"},
+ meth_pcall(meths.open_win,buf, false, {width=20,height=2,relative='shell',row=0,col=0}))
+ eq({false, "Invalid value of 'anchor' key"},
+ meth_pcall(meths.open_win,buf, false, {width=20,height=2,relative='editor',row=0,col=0,anchor='bottom'}))
eq({false, "All of 'relative', 'row', and 'col' has to be specified at once"},
- meth_pcall(meths.open_win,buf, false, 20, 2, {relative='editor'}))
+ meth_pcall(meths.open_win,buf, false, {width=20,height=2,relative='editor'}))
+ eq({false, "'width' key must be a positive Integer"},
+ meth_pcall(meths.open_win,buf, false, {width=-1,height=2,relative='editor'}))
+ eq({false, "'height' key must be a positive Integer"},
+ meth_pcall(meths.open_win,buf, false, {width=20,height=-1,relative='editor'}))
+ eq({false, "'height' key must be a positive Integer"},
+ meth_pcall(meths.open_win,buf, false, {width=20,height=0,relative='editor'}))
+ eq({false, "Must specify 'width' and 'height'"},
+ meth_pcall(meths.open_win,buf, false, {relative='editor'}))
end)
it('can be placed relative window or cursor', function()
@@ -210,8 +433,7 @@ describe('floating windows', function()
local buf = meths.create_buf(false,false)
-- no 'win' arg, relative default window
- local win = meths.open_win(buf, false, 20, 2, {relative='win', row=0, col=10})
- meths.win_set_option(win, 'winhl', 'Normal:PMenu')
+ local win = meths.open_win(buf, false, {relative='win', width=20, height=2, row=0, col=10})
if multigrid then
screen:expect{grid=[[
## grid 1
@@ -252,7 +474,7 @@ describe('floating windows', function()
]])
end
- meths.win_config(win, -1, -1, {relative='cursor', row=1, col=-2})
+ meths.win_set_config(win, {relative='cursor', row=1, col=-2})
if multigrid then
screen:expect{grid=[[
## grid 1
@@ -293,7 +515,7 @@ describe('floating windows', function()
]])
end
- meths.win_config(win, -1, -1, {relative='cursor', row=0, col=0, anchor='SW'})
+ meths.win_set_config(win, {relative='cursor', row=0, col=0, anchor='SW'})
if multigrid then
screen:expect{grid=[[
## grid 1
@@ -335,7 +557,7 @@ describe('floating windows', function()
end
- meths.win_config(win, -1, -1, {relative='win', win=oldwin, row=1, col=10, anchor='NW'})
+ meths.win_set_config(win, {relative='win', win=oldwin, row=1, col=10, anchor='NW'})
if multigrid then
screen:expect{grid=[[
## grid 1
@@ -376,7 +598,7 @@ describe('floating windows', function()
]])
end
- meths.win_config(win, -1, -1, {relative='win', win=oldwin, row=3, col=39, anchor='SE'})
+ meths.win_set_config(win, {relative='win', win=oldwin, row=3, col=39, anchor='SE'})
if multigrid then
screen:expect{grid=[[
## grid 1
@@ -417,7 +639,7 @@ describe('floating windows', function()
]])
end
- meths.win_config(win, -1, -1, {relative='win', win=0, row=0, col=50, anchor='NE'})
+ meths.win_set_config(win, {relative='win', win=0, row=0, col=50, anchor='NE'})
if multigrid then
screen:expect{grid=[[
## grid 1
@@ -459,6 +681,66 @@ describe('floating windows', function()
end
end)
+ it('validates cursor even when window is not entered', function()
+ screen:try_resize(30,5)
+ command("set nowrap")
+ insert([[some text that is wider than the window]])
+ if multigrid then
+ screen:expect([[
+ ## grid 1
+ [2:------------------------------]|
+ [2:------------------------------]|
+ [2:------------------------------]|
+ [2:------------------------------]|
+ |
+ ## grid 2
+ that is wider than the windo^w |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ]])
+ else
+ screen:expect([[
+ that is wider than the windo^w |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+ end
+
+ local buf = meths.create_buf(false,true)
+ meths.buf_set_lines(buf, 0, -1, true, {'some floaty text'})
+ meths.open_win(buf, false, {relative='editor', width=20, height=1, row=3, col=1})
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:------------------------------]|
+ [2:------------------------------]|
+ [2:------------------------------]|
+ [2:------------------------------]|
+ |
+ ## grid 2
+ that is wider than the windo^w |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 4
+ {1:some floaty text }|
+ ]], float_pos={
+ [4] = {{id = 1002}, "NW", 1, 3, 1, true}
+ }}
+ else
+ screen:expect([[
+ that is wider than the windo^w |
+ {0:~ }|
+ {0:~ }|
+ {0:~}{1:some floaty text }{0: }|
+ |
+ ]])
+ end
+ end)
+
if multigrid then
pending("supports second UI without multigrid", function()
local session2 = helpers.connect(eval('v:servername'))
@@ -467,8 +749,7 @@ describe('floating windows', function()
screen2:attach(nil, session2)
screen2:set_default_attr_ids(attrs)
local buf = meths.create_buf(false,false)
- local win = meths.open_win(buf, true, 20, 2, {relative='editor', row=2, col=5})
- meths.win_set_option(win, 'winhl', 'Normal:PMenu')
+ meths.open_win(buf, true, {relative='editor', width=20, height=2, row=2, col=5})
local expected_pos = {
[2]={{id=1001}, 'NW', 1, 2, 5}
}
@@ -501,8 +782,7 @@ describe('floating windows', function()
it('handles resized screen', function()
local buf = meths.create_buf(false,false)
meths.buf_set_lines(buf, 0, -1, true, {'such', 'very', 'float'})
- local win = meths.open_win(buf, false, 15, 4, {relative='editor', row=2, col=10})
- meths.win_set_option(win , 'winhl', 'Normal:PMenu')
+ local win = meths.open_win(buf, false, {relative='editor', width=15, height=4, row=2, col=10})
local expected_pos = {
[4]={{id=1002}, 'NW', 1, 2, 10, true},
}
@@ -673,15 +953,15 @@ describe('floating windows', function()
screen:expect([[
|
{0:~ }|
+ {0:~ }{1:such }{0: }|
{0:~ }{1:very }{0: }|
{0:~ }{1:^float }{0: }|
- {0:~ }|
- {0:~ }|
+ {0:~ }{2:~ }{0: }|
|
]])
end
- meths.win_config(win, -1, 3, {})
+ meths.win_set_config(win, {height=3})
feed('gg')
if multigrid then
screen:expect{grid=[[
@@ -1010,10 +1290,126 @@ describe('floating windows', function()
screen:expect([[
|
{0:~ }|
- {0:~ }{1:^such }{0: }|
+ {0:~ }{1:^such }{0: }|
+ {0:~ }{1:very }{0: }|
+ {0:~ }{1:float }{0: }|
{0:~ }|
+ |
+ ]])
+ end
+ end)
+
+ it('does not crash with inccommand #9379', function()
+ local expected_pos = {
+ [3]={{id=1001}, 'NW', 1, 2, 0, true},
+ }
+
+ command("set inccommand=split")
+ command("set laststatus=2")
+
+ local buf = meths.create_buf(false,false)
+ meths.open_win(buf, true, {relative='editor', width=30, height=3, row=2, col=0})
+
+ insert([[
+ foo
+ bar
+ ]])
+
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {5:[No Name] }|
+ |
+ ## grid 2
+ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ {1:foo }|
+ {1:bar }|
+ {1:^ }|
+ ]], float_pos=expected_pos}
+ else
+ screen:expect([[
+ |
{0:~ }|
+ {1:foo }{0: }|
+ {1:bar }{0: }|
+ {1:^ }{0: }|
+ {5:[No Name] }|
+ |
+ ]])
+ end
+
+ feed(':%s/.')
+
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {5:[Preview] }|
+ :%s/.^ |
+ ## grid 2
+ |
+ ## grid 3
+ {17:f}{1:oo }|
+ {17:b}{1:ar }|
+ {1: }|
+ ]], float_pos=expected_pos}
+ else
+ screen:expect([[
+ |
+ {5:[No Name] }|
+ {17:f}{1:oo } |
+ {17:b}{1:ar } |
+ {1: }{0: }|
+ {5:[Preview] }|
+ :%s/.^ |
+ ]])
+ end
+
+ feed('<Esc>')
+
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {5:[No Name] }|
+ |
+ ## grid 2
+ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ {1:foo }|
+ {1:bar }|
+ {1:^ }|
+ ]], float_pos=expected_pos}
+ else
+ screen:expect([[
+ |
{0:~ }|
+ {1:foo }{0: }|
+ {1:bar }{0: }|
+ {1:^ }{0: }|
+ {5:[No Name] }|
|
]])
end
@@ -1021,7 +1417,7 @@ describe('floating windows', function()
it('does not crash when set cmdheight #9680', function()
local buf = meths.create_buf(false,false)
- meths.open_win(buf, false, 20, 2, {relative='editor', row=2, col=5})
+ meths.open_win(buf, false, {relative='editor', width=20, height=2, row=2, col=5})
command("set cmdheight=2")
eq(1, meths.eval('1'))
end)
@@ -1029,7 +1425,7 @@ describe('floating windows', function()
describe('and completion', function()
before_each(function()
local buf = meths.create_buf(false,false)
- local win = meths.open_win(buf, true, 12, 4, {relative='editor', row=2, col=5})
+ local win = meths.open_win(buf, true, {relative='editor', width=12, height=4, row=2, col=5})
meths.win_set_option(win , 'winhl', 'Normal:ErrorMsg')
if multigrid then
screen:expect{grid=[[
@@ -1266,7 +1662,7 @@ describe('floating windows', function()
]], float_pos={
[3] = {{ id = 1001 }, "NW", 1, 2, 5, true},
}, popupmenu={
- anchor = {0, 2, 3}, items = items, pos = 0
+ anchor = {3, 0, 2}, items = items, pos = 0
}}
else
screen:expect{grid=[[
@@ -1278,7 +1674,7 @@ describe('floating windows', function()
{0:~ }{12:~ }{0: }|
{3:-- INSERT --} |
]], popupmenu={
- anchor = {2, 7}, items = items, pos = 0
+ anchor = {1, 2, 7}, items = items, pos = 0
}}
end
@@ -1348,7 +1744,7 @@ describe('floating windows', function()
]], float_pos={
[3] = {{ id = 1001 }, "NW", 1, 2, 5, true},
}, popupmenu={
- anchor = {0, 0, 2}, items = items, pos = 0
+ anchor = {2, 0, 0}, items = items, pos = 0
}}
else
screen:expect{grid=[[
@@ -1360,7 +1756,7 @@ describe('floating windows', function()
{0:~ }{12:~ }{0: }|
{3:-- INSERT --} |
]], popupmenu={
- anchor = {0, 0}, items = items, pos = 0
+ anchor = {1, 0, 0}, items = items, pos = 0
}}
end
@@ -1402,9 +1798,233 @@ describe('floating windows', function()
]])
end
end)
-
end)
+ describe('float shown after pum', function()
+ local win
+ before_each(function()
+ command('hi NormalFloat guibg=#333333')
+ feed('i')
+ funcs.complete(1, {'aa', 'word', 'longtext'})
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {3:-- INSERT --} |
+ ## grid 2
+ aa^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ {13:aa }|
+ {1:word }|
+ {1:longtext }|
+ ]], float_pos={
+ [3] = {{id = -1}, "NW", 2, 1, 0, false}}
+ }
+ else
+ screen:expect([[
+ aa^ |
+ {13:aa }{0: }|
+ {1:word }{0: }|
+ {1:longtext }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {3:-- INSERT --} |
+ ]])
+ end
+
+ local buf = meths.create_buf(false,true)
+ meths.buf_set_lines(buf,0,-1,true,{"some info", "about item"})
+ win = meths.open_win(buf, false, {relative='cursor', width=12, height=2, row=1, col=10})
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {3:-- INSERT --} |
+ ## grid 2
+ aa^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ {13:aa }|
+ {1:word }|
+ {1:longtext }|
+ ## grid 5
+ {15:some info }|
+ {15:about item }|
+ ]], float_pos={
+ [3] = {{id = -1}, "NW", 2, 1, 0, false},
+ [5] = {{id = 1002}, "NW", 2, 1, 12, true},
+ }}
+ else
+ screen:expect([[
+ aa^ |
+ {13:aa }{15:e info }{0: }|
+ {1:word }{15:ut item }{0: }|
+ {1:longtext }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {3:-- INSERT --} |
+ ]])
+ end
+ end)
+
+ it('and close pum first', function()
+ feed('<c-y>')
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {3:-- INSERT --} |
+ ## grid 2
+ aa^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 5
+ {15:some info }|
+ {15:about item }|
+ ]], float_pos={
+ [5] = {{id = 1002}, "NW", 2, 1, 12, true},
+ }}
+ else
+ screen:expect([[
+ aa^ |
+ {0:~ }{15:some info }{0: }|
+ {0:~ }{15:about item }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {3:-- INSERT --} |
+ ]])
+ end
+
+ meths.win_close(win, false)
+ if multigrid then
+ screen:expect([[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {3:-- INSERT --} |
+ ## grid 2
+ aa^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ]])
+ else
+ screen:expect([[
+ aa^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {3:-- INSERT --} |
+ ]])
+ end
+ end)
+
+ it('and close float first', function()
+ meths.win_close(win, false)
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {3:-- INSERT --} |
+ ## grid 2
+ aa^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ {13:aa }|
+ {1:word }|
+ {1:longtext }|
+ ]], float_pos={
+ [3] = {{id = -1}, "NW", 2, 1, 0, false},
+ }}
+ else
+ screen:expect([[
+ aa^ |
+ {13:aa }{0: }|
+ {1:word }{0: }|
+ {1:longtext }{0: }|
+ {0:~ }|
+ {0:~ }|
+ {3:-- INSERT --} |
+ ]])
+ end
+
+ feed('<c-y>')
+ if multigrid then
+ screen:expect([[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {3:-- INSERT --} |
+ ## grid 2
+ aa^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ]])
+ else
+ screen:expect([[
+ aa^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {3:-- INSERT --} |
+ ]])
+ end
+ end)
+ end)
describe("handles :wincmd", function()
local win
@@ -1415,9 +2035,8 @@ describe('floating windows', function()
command("set hidden")
meths.buf_set_lines(0,0,-1,true,{"x"})
local buf = meths.create_buf(false,false)
- win = meths.open_win(buf, false, 20, 2, {relative='editor', row=2, col=5})
+ win = meths.open_win(buf, false, {relative='editor', width=20, height=2, row=2, col=5})
meths.buf_set_lines(buf,0,-1,true,{"y"})
- meths.win_set_option(win , 'winhl', 'Normal:PMenu')
expected_pos = {
[3]={{id=1001}, 'NW', 1, 2, 5, true}
}
@@ -1526,7 +2145,7 @@ describe('floating windows', function()
end)
it("w with focusable=false", function()
- meths.win_config(win, -1, -1, {focusable=false})
+ meths.win_set_config(win, {focusable=false})
expected_pos[3][6] = false
feed("<c-w>wi") -- i to provoke redraw
if multigrid then
@@ -1740,7 +2359,7 @@ describe('floating windows', function()
end)
it("focus by mouse (focusable=false)", function()
- meths.win_config(win, -1, -1, {focusable=false})
+ meths.win_set_config(win, {focusable=false})
meths.buf_set_lines(0, -1, -1, true, {"a"})
expected_pos[3][6] = false
if multigrid then
@@ -2074,39 +2693,6 @@ describe('floating windows', function()
{1:y }|
{2:~ }|
## grid 4
- {1:^y }|
- {2:~ }|
- ]], float_pos=expected_pos}
- else
- screen:expect([[
- {1:^y }|
- {2:~ }|
- {4:[No N}{1:y }{4: }|
- x {2:~ } |
- {0:~ }|
- {5:[No Name] [+] }|
- |
- ]])
- end
-
- feed(":set winhighlight=<cr><c-l>")
- if multigrid then
- screen:expect{grid=[[
- ## grid 1
- [4:----------------------------------------]|
- [4:----------------------------------------]|
- {4:[No Name] [+] }|
- [2:----------------------------------------]|
- [2:----------------------------------------]|
- {5:[No Name] [+] }|
- |
- ## grid 2
- x |
- {0:~ }|
- ## grid 3
- {1:y }|
- {2:~ }|
- ## grid 4
^y |
{0:~ }|
]], float_pos=expected_pos}
@@ -2122,7 +2708,6 @@ describe('floating windows', function()
]])
end
-
feed("<c-w>j")
if multigrid then
screen:expect{grid=[[
@@ -2405,6 +2990,119 @@ describe('floating windows', function()
eq(exited, true)
end)
+ it(':quit two floats in a row', function()
+ -- enter first float
+ feed('<c-w><c-w>')
+ -- enter second float
+ meths.open_win(0, true, {relative='editor', width=20, height=2, row=4, col=8})
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ |
+ ## grid 2
+ x |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ {1:y }|
+ {2:~ }|
+ ## grid 4
+ {1:^y }|
+ {2:~ }|
+ ]], float_pos={
+ [3] = {{id = 1001}, "NW", 1, 2, 5, true},
+ [4] = {{id = 1002}, "NW", 1, 4, 8, true}
+ }}
+ else
+ screen:expect([[
+ x |
+ {0:~ }|
+ {0:~ }{1:y }{0: }|
+ {0:~ }{2:~ }{0: }|
+ {0:~ }{1:^y }{0: }|
+ {0:~ }{2:~ }{0: }|
+ |
+ ]])
+ end
+
+ feed(':quit<cr>')
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ {5:[No Name] [+] }|
+ :quit |
+ ## grid 2
+ x |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ {1:^y }|
+ {2:~ }|
+ ]], float_pos={
+ [3] = {{id = 1001}, "NW", 1, 2, 5, true},
+ }}
+ else
+ screen:expect([[
+ x |
+ {0:~ }|
+ {0:~ }{1:^y }{0: }|
+ {0:~ }{2:~ }{0: }|
+ {0:~ }|
+ {5:[No Name] [+] }|
+ :quit |
+ ]])
+ end
+
+ feed(':quit<cr>')
+ if multigrid then
+ screen:expect([[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ :quit |
+ ## grid 2
+ ^x |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ]])
+ else
+ screen:expect([[
+ ^x |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ :quit |
+ ]])
+ end
+
+ eq(2, eval('1+1'))
+ end)
+
it("o (:only) non-float", function()
feed("<c-w>o")
if multigrid then
@@ -2659,23 +3357,23 @@ describe('floating windows', function()
x |
{0:~ }|
## grid 3
- {1:^y }|
- {2:~ }|
+ ^y |
+ {0:~ }|
]]}
else
screen:expect([[
x |
{0:~ }|
{5:[No Name] [+] }|
- {1:^y }|
- {2:~ }|
+ ^y |
+ {0:~ }|
{4:[No Name] [+] }|
|
]])
end
if multigrid then
- meths.win_config(0,-1,-1,{external=true})
+ meths.win_set_config(0, {external=true, width=30, height=2})
expected_pos = {[3]={external=true}}
screen:expect{grid=[[
## grid 1
@@ -2693,12 +3391,12 @@ describe('floating windows', function()
{0:~ }|
{0:~ }|
## grid 3
- {1:^y }|
- {2:~ }|
+ ^y |
+ {0:~ }|
]], float_pos=expected_pos}
else
eq({false, "UI doesn't support external windows"},
- meth_pcall(meths.win_config, 0,-1,-1,{external=true}))
+ meth_pcall(meths.win_set_config, 0, {external=true, width=30, height=2}))
return
end
@@ -2717,11 +3415,10 @@ describe('floating windows', function()
x |
{0:~ }|
## grid 3
- {1:^y }|
- {2:~ }|
+ ^y |
+ {0:~ }|
]])
end
-
end)
it('movements with nested split layout', function()
@@ -2786,8 +3483,8 @@ describe('floating windows', function()
4 |
{0:~ }|
## grid 3
- ^5 |
- {0:~ }|
+ {1:^5 }|
+ {2:~ }|
## grid 4
2 |
{0:~ }|
@@ -2802,8 +3499,8 @@ describe('floating windows', function()
screen:expect([[
1 {5:│}2 |
{0:~ }{5:│}{0:~ }|
- {5:[No N}^5 {5:ame] [+] }|
- 3 {0:~ } |
+ {5:[No N}{1:^5 }{5:ame] [+] }|
+ 3 {2:~ } |
{0:~ }{5:│}{0:~ }|
{5:[No Name] [+] [No Name] [+] }|
:enew |
@@ -2895,13 +3592,14 @@ describe('floating windows', function()
[2:----------------------------------------]|
[2:----------------------------------------]|
[2:----------------------------------------]|
- {4:[No Name] [+] }|
+ [2:----------------------------------------]|
:tabnext |
## grid 2
^x |
{0:~ }|
{0:~ }|
{0:~ }|
+ {0:~ }|
## grid 3
{1:y }|
{2:~ }|
@@ -2919,7 +3617,7 @@ describe('floating windows', function()
{0:~ }{1:y }{0: }|
{0:~ }{2:~ }{0: }|
{0:~ }|
- {4:[No Name] [+] }|
+ {0:~ }|
:tabnext |
]])
end
@@ -2940,6 +3638,7 @@ describe('floating windows', function()
{0:~ }|
{0:~ }|
{0:~ }|
+ {0:~ }|
## grid 3
{1:y }|
{2:~ }|
@@ -2965,7 +3664,8 @@ describe('floating windows', function()
it(":tabnew and :tabnext (external)", function()
if multigrid then
- meths.win_config(win,-1,-1,{external=true})
+ -- also test external window wider than main screen
+ meths.win_set_config(win, {external=true, width=65, height=4})
expected_pos = {[3]={external=true}}
feed(":tabnew<cr>")
screen:expect{grid=[[
@@ -2985,8 +3685,10 @@ describe('floating windows', function()
{0:~ }|
{0:~ }|
## grid 3
- {1:y }|
- {2:~ }|
+ y |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
## grid 4
^ |
{0:~ }|
@@ -2996,7 +3698,7 @@ describe('floating windows', function()
]], float_pos=expected_pos}
else
eq({false, "UI doesn't support external windows"},
- meth_pcall(meths.win_config, 0,-1,-1,{external=true}))
+ meth_pcall(meths.win_set_config, 0, {external=true, width=65, height=4}))
end
feed(":tabnext<cr>")
@@ -3008,16 +3710,19 @@ describe('floating windows', function()
[2:----------------------------------------]|
[2:----------------------------------------]|
[2:----------------------------------------]|
- {4:[No Name] [+] }|
+ [2:----------------------------------------]|
:tabnext |
## grid 2
^x |
{0:~ }|
{0:~ }|
{0:~ }|
+ {0:~ }|
## grid 3
- {1:y }|
- {2:~ }|
+ y |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
## grid 4
|
{0:~ }|
@@ -3036,21 +3741,25 @@ describe('floating windows', function()
[4:----------------------------------------]|
[4:----------------------------------------]|
[4:----------------------------------------]|
- {4:[No Name] }|
+ [4:----------------------------------------]|
:tabnext |
## grid 2
x |
{0:~ }|
{0:~ }|
{0:~ }|
+ {0:~ }|
## grid 3
- {1:y }|
- {2:~ }|
+ y |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
## grid 4
^ |
{0:~ }|
{0:~ }|
{0:~ }|
+ {0:~ }|
]], float_pos=expected_pos}
end
end)
@@ -3063,6 +3772,5 @@ describe('floating windows', function()
describe('without ext_multigrid', function()
with_ext_multigrid(false)
end)
-
end)
diff --git a/test/functional/ui/fold_spec.lua b/test/functional/ui/fold_spec.lua
index 943cbcef56..5fa299bed9 100644
--- a/test/functional/ui/fold_spec.lua
+++ b/test/functional/ui/fold_spec.lua
@@ -39,11 +39,11 @@ describe("folded lines", function()
screen:expect([[
{7:+ }{5: 1 +-- 2 lines: ·························}|
{7:+ }{5: 0 ^+-- 2 lines: ·························}|
- {7: }{1:~ }|
- {7: }{1:~ }|
- {7: }{1:~ }|
- {7: }{1:~ }|
- {7: }{1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
:set foldcolumn=2 |
]])
end)
@@ -93,12 +93,12 @@ describe("folded lines", function()
feed_command("set number foldcolumn=2")
screen:expect([[
{7:+ }{5: 1 ^+-- 2 lines: å 语 x̎͂̀̂͛͛ العَرَبِيَّة···········}|
- {7: }{1:~ }|
- {7: }{1:~ }|
- {7: }{1:~ }|
- {7: }{1:~ }|
- {7: }{1:~ }|
- {7: }{1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
:set number foldcolumn=2 |
]])
@@ -106,12 +106,12 @@ describe("folded lines", function()
feed_command("set rightleft")
screen:expect([[
{5:+-- 2 lines: å ······················^· 1 }{7: +}|
- {1: ~}{7: }|
- {1: ~}{7: }|
- {1: ~}{7: }|
- {1: ~}{7: }|
- {1: ~}{7: }|
- {1: ~}{7: }|
+ {1: ~}|
+ {1: ~}|
+ {1: ~}|
+ {1: ~}|
+ {1: ~}|
+ {1: ~}|
:set rightleft |
]])
@@ -178,7 +178,7 @@ describe("folded lines", function()
{1::}set foldmethod=manual |
{1::}let x = 1 |
{1::}^ |
- {1::~ }|
+ {1:~ }|
{3:[Command Line] }|
: |
]])
@@ -189,8 +189,8 @@ describe("folded lines", function()
{2:[No Name] }|
{1::}{5:^+-- 2 lines: set foldmethod=manual·········}|
{1::} |
- {1::~ }|
- {1::~ }|
+ {1:~ }|
+ {1:~ }|
{3:[Command Line] }|
: |
]])
@@ -214,7 +214,7 @@ describe("folded lines", function()
{1:/}alpha |
{1:/}{6:omega} |
{1:/}^ |
- {1:/~ }|
+ {1:~ }|
{3:[Command Line] }|
/ |
]])
@@ -224,9 +224,9 @@ describe("folded lines", function()
|
{2:[No Name] }|
{1:/}{5:^+-- 3 lines: alpha·························}|
- {1:/~ }|
- {1:/~ }|
- {1:/~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
{3:[Command Line] }|
/ |
]])
diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua
index 3ee3f173d6..85b5aed2f8 100644
--- a/test/functional/ui/highlight_spec.lua
+++ b/test/functional/ui/highlight_spec.lua
@@ -748,6 +748,66 @@ describe('CursorLine highlight', function()
]])
end)
+ it('always updated. vim-patch:8.1.0849', function()
+ local screen = Screen.new(50,5)
+ screen:set_default_attr_ids({
+ [1] = {foreground = Screen.colors.SlateBlue},
+ [2] = {bold = true, foreground = Screen.colors.Brown},
+ [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
+ [4] = {foreground = Screen.colors.SlateBlue, background = Screen.colors.Gray90},
+ [5] = {background = Screen.colors.Gray90},
+ [6] = {bold = true, foreground = Screen.colors.Blue1},
+ [7] = {background = Screen.colors.LightRed},
+ [8] = {foreground = Screen.colors.Brown},
+ })
+ screen:attach()
+ command('set cursorline relativenumber')
+ command('call setline(1, ["","1","2","3",""])')
+ feed('Gy3k')
+ screen:expect([[
+ {2: 0 }{5:^1 }|
+ {8: 1 }2 |
+ {8: 2 }3 |
+ {8: 3 } |
+ 4 lines yanked |
+ ]])
+ feed('jj')
+ screen:expect([[
+ {8: 2 }1 |
+ {8: 1 }2 |
+ {2: 0 }{5:^3 }|
+ {8: 1 } |
+ 4 lines yanked |
+ ]])
+ end)
+
+ it('with visual area. vim-patch:8.1.1001', function()
+ local screen = Screen.new(50,5)
+ screen:set_default_attr_ids({
+ [1] = {foreground = Screen.colors.SlateBlue},
+ [2] = {bold = true, foreground = Screen.colors.Brown},
+ [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
+ [4] = {foreground = Screen.colors.SlateBlue, background = Screen.colors.Gray90},
+ [5] = {background = Screen.colors.Gray90},
+ [6] = {bold = true, foreground = Screen.colors.Blue1},
+ [7] = {background = Screen.colors.LightRed},
+ [8] = {foreground = Screen.colors.Brown},
+ [9] = {background = Screen.colors.LightGrey},
+ [10] = {bold = true},
+ })
+ screen:attach()
+ command('set cursorline')
+ command('call setline(1, repeat(["abc"], 50))')
+ feed('V<C-f>zbkkjk')
+ screen:expect([[
+ {9:abc} |
+ ^a{9:bc} |
+ abc |
+ abc |
+ {10:-- VISUAL LINE --} |
+ ]])
+ end)
+
it('with split-windows in diff-mode', function()
local screen = Screen.new(50,12)
screen:set_default_attr_ids({
@@ -781,9 +841,9 @@ describe('CursorLine highlight', function()
{1: }extra line! {4:│}{1: }extra line! |
{1: }last line ... {4:│}{1: }last line ... |
{1: } {4:│}{1: } |
- {1: }{8:~ }{4:│}{1: }{8:~ }|
- {1: }{8:~ }{4:│}{1: }{8:~ }|
- {1: }{8:~ }{4:│}{1: }{8:~ }|
+ {8:~ }{4:│}{8:~ }|
+ {8:~ }{4:│}{8:~ }|
+ {8:~ }{4:│}{8:~ }|
{4:[No Name] [+] }{9:[No Name] [+] }|
|
]])
@@ -796,9 +856,9 @@ describe('CursorLine highlight', function()
{1: }extra line! {4:│}{1: }extra line! |
{1: }last line ... {4:│}{1: }last line ... |
{1: }{7: }{4:│}{1: }{7:^ }|
- {1: }{8:~ }{4:│}{1: }{8:~ }|
- {1: }{8:~ }{4:│}{1: }{8:~ }|
- {1: }{8:~ }{4:│}{1: }{8:~ }|
+ {8:~ }{4:│}{8:~ }|
+ {8:~ }{4:│}{8:~ }|
+ {8:~ }{4:│}{8:~ }|
{4:[No Name] [+] }{9:[No Name] [+] }|
|
]])
@@ -815,9 +875,9 @@ describe('CursorLine highlight', function()
{1: }extra line! {4:│}{1: }extra line! |
{1: }last line ... {4:│}{1: }last line ... |
{1: } {4:│}{1: } |
- {1: }{8:~ }{4:│}{1: }{8:~ }|
- {1: }{8:~ }{4:│}{1: }{8:~ }|
- {1: }{8:~ }{4:│}{1: }{8:~ }|
+ {8:~ }{4:│}{8:~ }|
+ {8:~ }{4:│}{8:~ }|
+ {8:~ }{4:│}{8:~ }|
{4:[No Name] [+] }{9:[No Name] [+] }|
|
]], {
diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua
index c215ece2f2..4f243e6413 100644
--- a/test/functional/ui/inccommand_spec.lua
+++ b/test/functional/ui/inccommand_spec.lua
@@ -2607,3 +2607,30 @@ it(':substitute with inccommand during :terminal activity', function()
end)
end)
+
+it(':substitute with inccommand, timer-induced :redraw #9777', function()
+ local screen = Screen.new(30,12)
+ clear()
+ command('set cmdwinheight=3')
+ command('call timer_start(10, {-> execute("redraw")}, {"repeat":-1})')
+ command('call timer_start(10, {-> execute("redrawstatus")}, {"repeat":-1})')
+ common_setup(screen, 'split', 'foo bar baz\nbar baz fox\nbar foo baz')
+
+ feed('gg')
+ feed(':%s/foo/ZZZ')
+ sleep(20) -- Allow some timer activity.
+ screen:expect([[
+ {12:ZZZ} bar baz |
+ bar baz fox |
+ bar {12:ZZZ} baz |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {11:[No Name] [+] }|
+ |1| {12:ZZZ} bar baz |
+ |3| bar {12:ZZZ} baz |
+ {15:~ }|
+ {10:[Preview] }|
+ :%s/foo/ZZZ^ |
+ ]])
+end)
diff --git a/test/functional/ui/input_spec.lua b/test/functional/ui/input_spec.lua
index 850efed282..121cbe47d6 100644
--- a/test/functional/ui/input_spec.lua
+++ b/test/functional/ui/input_spec.lua
@@ -30,6 +30,24 @@ describe('mappings', function()
add_mapping('<c-s-a-d-up>', '<c-s-a-d-up>')
add_mapping('<c-d-a>', '<c-d-a>')
add_mapping('<d-1>', '<d-1>')
+ add_mapping('<khome>','<khome>')
+ add_mapping('<kup>','<kup>')
+ add_mapping('<kpageup>','<kpageup>')
+ add_mapping('<kleft>','<kleft>')
+ add_mapping('<korigin>','<korigin>')
+ add_mapping('<kright>','<kright>')
+ add_mapping('<kend>','<kend>')
+ add_mapping('<kdown>','<kdown>')
+ add_mapping('<kpagedown>','<kpagedown>')
+ add_mapping('<kinsert>','<kinsert>')
+ add_mapping('<kdel>','<kdel>')
+ add_mapping('<kdivide>','<kdivide>')
+ add_mapping('<kmultiply>','<kmultiply>')
+ add_mapping('<kminus>','<kminus>')
+ add_mapping('<kplus>','<kplus>')
+ add_mapping('<kenter>','<kenter>')
+ add_mapping('<kcomma>','<kcomma>')
+ add_mapping('<kequal>','<kequal>')
end)
it('ok', function()
@@ -48,6 +66,42 @@ describe('mappings', function()
check_mapping('<c-d-a>', '<c-d-a>')
check_mapping('<d-c-a>', '<c-d-a>')
check_mapping('<d-1>', '<d-1>')
+ check_mapping('<khome>','<khome>')
+ check_mapping('<KP7>','<khome>')
+ check_mapping('<kup>','<kup>')
+ check_mapping('<KP8>','<kup>')
+ check_mapping('<kpageup>','<kpageup>')
+ check_mapping('<KP9>','<kpageup>')
+ check_mapping('<kleft>','<kleft>')
+ check_mapping('<KP4>','<kleft>')
+ check_mapping('<korigin>','<korigin>')
+ check_mapping('<KP5>','<korigin>')
+ check_mapping('<kright>','<kright>')
+ check_mapping('<KP6>','<kright>')
+ check_mapping('<kend>','<kend>')
+ check_mapping('<KP1>','<kend>')
+ check_mapping('<kdown>','<kdown>')
+ check_mapping('<KP2>','<kdown>')
+ check_mapping('<kpagedown>','<kpagedown>')
+ check_mapping('<KP3>','<kpagedown>')
+ check_mapping('<kinsert>','<kinsert>')
+ check_mapping('<KP0>','<kinsert>')
+ check_mapping('<kdel>','<kdel>')
+ check_mapping('<KPPeriod>','<kdel>')
+ check_mapping('<kdivide>','<kdivide>')
+ check_mapping('<KPDiv>','<kdivide>')
+ check_mapping('<kmultiply>','<kmultiply>')
+ check_mapping('<KPMult>','<kmultiply>')
+ check_mapping('<kminus>','<kminus>')
+ check_mapping('<KPMinus>','<kminus>')
+ check_mapping('<kplus>','<kplus>')
+ check_mapping('<KPPlus>','<kplus>')
+ check_mapping('<kenter>','<kenter>')
+ check_mapping('<KPEnter>','<kenter>')
+ check_mapping('<kcomma>','<kcomma>')
+ check_mapping('<KPComma>','<kcomma>')
+ check_mapping('<kequal>','<kequal>')
+ check_mapping('<KPEquals>','<kequal>')
end)
end)
diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua
index 388c6b3e95..d49d2f0316 100644
--- a/test/functional/ui/messages_spec.lua
+++ b/test/functional/ui/messages_spec.lua
@@ -22,8 +22,129 @@ describe('ui/ext_messages', function()
[6] = {bold = true, reverse = true},
})
end)
+ after_each(function()
+ os.remove('Xtest')
+ end)
+
+ it('msg_show kind=confirm,confirm_sub,emsg,wmsg', function()
+ feed('iline 1\nline 2<esc>')
+
+ -- kind=confirm
+ feed(':echo confirm("test")<cr>')
+ screen:expect{grid=[[
+ line 1 |
+ line ^2 |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ ]], messages={ {
+ content = {{"\ntest\n[O]k: ", 4}},
+ kind = 'confirm',
+ }}}
+ feed('<cr><cr>')
+ screen:expect{grid=[[
+ line 1 |
+ line ^2 |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ ]], messages={ {
+ content = { { "\ntest\n[O]k: ", 4 } },
+ kind = "confirm"
+ }, {
+ content = { { "1" } },
+ kind = "echo"
+ }, {
+ content = { { "Press ENTER or type command to continue", 4 } },
+ kind = "return_prompt"
+ } }}
+ feed('<cr><cr>')
+
+ -- kind=confirm_sub
+ feed(':%s/i/X/gc<cr>')
+ screen:expect{grid=[[
+ l{7:i}ne 1 |
+ l{8:i}ne ^2 |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ ]], attr_ids={
+ [1] = {bold = true, foreground = Screen.colors.Blue1},
+ [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
+ [3] = {bold = true},
+ [4] = {bold = true, foreground = Screen.colors.SeaGreen4},
+ [5] = {foreground = Screen.colors.Blue1},
+ [6] = {bold = true, reverse = true},
+ [7] = {reverse = true},
+ [8] = {background = Screen.colors.Yellow},
+ }, messages={ {
+ content = { { "replace with X (y/n/a/q/l/^E/^Y)?", 4 } },
+ kind = "confirm_sub"
+ } }}
+ feed('nq')
+
+ -- kind=wmsg (editing readonly file)
+ command('write Xtest')
+ command('set readonly nohls')
+ feed('G$x')
+ screen:expect{grid=[[
+ line 1 |
+ {IGNORE}|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ ]], attr_ids={
+ [1] = {bold = true, foreground = Screen.colors.Blue1},
+ [7] = {foreground = Screen.colors.Red},
+ }, messages={ {
+ content = { { "W10: Warning: Changing a readonly file", 7 } },
+ kind = "wmsg"
+ }
+ }}
+
+ -- kind=wmsg ('wrapscan' after search reaches EOF)
+ feed('uG$/i<cr>')
+ screen:expect{grid=[[
+ l^ine 1 |
+ line 2 |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ ]], attr_ids={
+ [1] = {bold = true, foreground = Screen.colors.Blue1},
+ [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
+ [3] = {bold = true},
+ [4] = {bold = true, foreground = Screen.colors.SeaGreen4},
+ [5] = {foreground = Screen.colors.Blue1},
+ [6] = {bold = true, reverse = true},
+ [7] = {foreground = Screen.colors.Red},
+ }, messages={ {
+ content = { { "search hit BOTTOM, continuing at TOP", 7 } },
+ kind = "wmsg"
+ } }}
+
+ -- kind=emsg after :throw
+ feed(':throw "foo"<cr>')
+ screen:expect{grid=[[
+ l^ine 1 |
+ line 2 |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ ]], messages={ {
+ content = { { "Error detected while processing :", 2 } },
+ kind = "emsg"
+ }, {
+ content = { { "E605: Exception not caught: foo", 2 } },
+ kind = ""
+ }, {
+ content = { { "Press ENTER or type command to continue", 4 } },
+ kind = "return_prompt"
+ } }
+ }
+ end)
- it('supports :echoerr', function()
+ it(':echoerr', function()
feed(':echoerr "raa"<cr>')
screen:expect{grid=[[
^ |
@@ -142,7 +263,7 @@ describe('ui/ext_messages', function()
}}
end)
- it('supports showmode', function()
+ it('&showmode', function()
command('imap <f2> <cmd>echomsg "stuff"<cr>')
feed('i')
screen:expect{grid=[[
@@ -179,7 +300,7 @@ describe('ui/ext_messages', function()
{1:~ }|
{1:~ }|
]], popupmenu={
- anchor = { 2, 0 },
+ anchor = { 1, 2, 0 },
items = { { "alphpabet", "", "", "" }, { "alphanum", "", "", "" } },
pos = 1
}, showmode={ { "-- Keyword Local completion (^N^P) ", 3 }, { "match 1 of 2", 4 } }}
@@ -194,7 +315,7 @@ describe('ui/ext_messages', function()
{1:~ }|
{1:~ }|
]], popupmenu={
- anchor = { 2, 0 },
+ anchor = { 1, 2, 0 },
items = { { "alphpabet", "", "", "" }, { "alphanum", "", "", "" } },
pos = 1
}, messages={ {
@@ -210,7 +331,7 @@ describe('ui/ext_messages', function()
{1:~ }|
{1:~ }|
]], popupmenu={
- anchor = { 2, 0 },
+ anchor = { 1, 2, 0 },
items = { { "alphpabet", "", "", "" }, { "alphanum", "", "", "" } },
pos = 0
}, messages={ {
@@ -230,7 +351,7 @@ describe('ui/ext_messages', function()
}}
end)
- it('supports showmode with recording message', function()
+ it('&showmode with macro-recording message', function()
feed('qq')
screen:expect{grid=[[
^ |
@@ -268,7 +389,7 @@ describe('ui/ext_messages', function()
]])
end)
- it('shows recording message with noshowmode', function()
+ it('shows macro-recording message with &noshowmode', function()
command("set noshowmode")
feed('qq')
-- also check mode to avoid immediate success
@@ -308,7 +429,7 @@ describe('ui/ext_messages', function()
]], mode="normal"}
end)
- it('supports showcmd and ruler', function()
+ it('supports &showcmd and &ruler', function()
command('set showcmd ruler')
screen:expect{grid=[[
^ |
@@ -529,7 +650,7 @@ describe('ui/ext_messages', function()
local screen
before_each(function()
- clear{headless=false, args={"--cmd", "set shortmess-=I"}}
+ clear{args_rm={'--headless'}, args={"--cmd", "set shortmess-=I"}}
screen = Screen.new(80, 24)
screen:attach({rgb=true, ext_messages=true, ext_popupmenu=true})
screen:set_default_attr_ids({
diff --git a/test/functional/ui/multigrid_spec.lua b/test/functional/ui/multigrid_spec.lua
index c54d608ec4..c5a23e4661 100644
--- a/test/functional/ui/multigrid_spec.lua
+++ b/test/functional/ui/multigrid_spec.lua
@@ -11,7 +11,7 @@ describe('ext_multigrid', function()
local screen
before_each(function()
- clear{headless=false, args={'--cmd', 'set laststatus=2'}}
+ clear{args_rm={'--headless'}, args={'--cmd', 'set laststatus=2'}}
screen = Screen.new(53,14)
screen:attach({ext_multigrid=true})
screen:set_default_attr_ids({
diff --git a/test/functional/ui/options_spec.lua b/test/functional/ui/options_spec.lua
index ed630259be..93192934c7 100644
--- a/test/functional/ui/options_spec.lua
+++ b/test/functional/ui/options_spec.lua
@@ -1,10 +1,9 @@
-local global_helpers = require('test.helpers')
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
local command = helpers.command
local eq = helpers.eq
-local shallowcopy = global_helpers.shallowcopy
+local shallowcopy = helpers.shallowcopy
describe('ui receives option updates', function()
local screen
@@ -115,7 +114,8 @@ describe('ui receives option updates', function()
end)
local function startup_test(headless)
- local expected = reset(nil,{headless=headless,args={'--cmd', 'set guifont=Comic\\ Sans\\ 12'}})
+ local expected = reset(nil, {args_rm=(headless and {} or {'--headless'}),
+ args={'--cmd', 'set guifont=Comic\\ Sans\\ 12'}})
expected.guifont = "Comic Sans 12"
screen:expect(function()
eq(expected, screen.options)
diff --git a/test/functional/ui/output_spec.lua b/test/functional/ui/output_spec.lua
index 87b489fd71..38c4527a5b 100644
--- a/test/functional/ui/output_spec.lua
+++ b/test/functional/ui/output_spec.lua
@@ -51,7 +51,8 @@ describe("shell command :!", function()
end)
it("throttles shell-command output greater than ~10KB", function()
- if helpers.skip_fragile(pending) then
+ if helpers.skip_fragile(pending,
+ (os.getenv("TRAVIS") and helpers.os_name() == "osx")) then
return
end
child_session.feed_data(
diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua
index 1e6ebb87f5..b457ebebab 100644
--- a/test/functional/ui/popupmenu_spec.lua
+++ b/test/functional/ui/popupmenu_spec.lua
@@ -50,7 +50,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={
items=expected,
pos=0,
- anchor={1,0},
+ anchor={1,1,0},
}}
feed('<c-p>')
@@ -66,7 +66,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={
items=expected,
pos=-1,
- anchor={1,0},
+ anchor={1,1,0},
}}
-- down moves the selection in the menu, but does not insert anything
@@ -83,7 +83,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={
items=expected,
pos=1,
- anchor={1,0},
+ anchor={1,1,0},
}}
feed('<cr>')
@@ -113,7 +113,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={
items=expected,
pos=0,
- anchor={1,0},
+ anchor={1,1,0},
}}
meths.select_popupmenu_item(1,false,false,{})
@@ -129,7 +129,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={
items=expected,
pos=1,
- anchor={1,0},
+ anchor={1,1,0},
}}
meths.select_popupmenu_item(2,true,false,{})
@@ -145,7 +145,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={
items=expected,
pos=2,
- anchor={1,0},
+ anchor={1,1,0},
}}
meths.select_popupmenu_item(0,true,true,{})
@@ -174,7 +174,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={
items=expected,
pos=0,
- anchor={1,0},
+ anchor={1,1,0},
}}
meths.select_popupmenu_item(-1,false,false,{})
@@ -190,7 +190,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={
items=expected,
pos=-1,
- anchor={1,0},
+ anchor={1,1,0},
}}
meths.select_popupmenu_item(1,true,false,{})
@@ -206,7 +206,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={
items=expected,
pos=1,
- anchor={1,0},
+ anchor={1,1,0},
}}
meths.select_popupmenu_item(-1,true,false,{})
@@ -222,7 +222,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={
items=expected,
pos=-1,
- anchor={1,0},
+ anchor={1,1,0},
}}
meths.select_popupmenu_item(0,true,false,{})
@@ -238,7 +238,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={
items=expected,
pos=0,
- anchor={1,0},
+ anchor={1,1,0},
}}
meths.select_popupmenu_item(-1,true,true,{})
@@ -269,7 +269,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={
items=expected,
pos=0,
- anchor={1,0},
+ anchor={1,1,0},
}}
feed('<f1>')
@@ -285,7 +285,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={
items=expected,
pos=2,
- anchor={1,0},
+ anchor={1,1,0},
}}
feed('<f2>')
@@ -301,7 +301,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={
items=expected,
pos=-1,
- anchor={1,0},
+ anchor={1,1,0},
}}
feed('<f3>')
@@ -366,6 +366,113 @@ describe('ui/ext_popupmenu', function()
{2:-- INSERT --} |
]])
end)
+
+ it('works with wildoptions=pum', function()
+ screen:try_resize(32,10)
+ command('set wildmenu')
+ command('set wildoptions=pum')
+
+ local wild_expected = {
+ {'define', '', '', ''},
+ {'jump', '', '', ''},
+ {'list', '', '', ''},
+ {'place', '', '', ''},
+ {'undefine', '', '', ''},
+ {'unplace', '', '', ''},
+ }
+
+ feed(':sign ')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ :sign ^ |
+ ]])
+
+ feed('<tab>')
+ screen:expect{grid=[[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ :sign define^ |
+ ]], popupmenu={items=wild_expected, pos=0, anchor={1, 9, 6}}}
+
+ feed('<left>')
+ screen:expect{grid=[[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ :sign ^ |
+ ]], popupmenu={items=wild_expected, pos=-1, anchor={1, 9, 6}}}
+
+ feed('<left>')
+ screen:expect{grid=[[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ :sign unplace^ |
+ ]], popupmenu={items=wild_expected, pos=5, anchor={1, 9, 6}}}
+
+ feed('x')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ :sign unplacex^ |
+ ]])
+ feed('<esc>')
+
+ -- check positioning with multibyte char in pattern
+ command("e långfile1")
+ command("sp långfile2")
+ feed(':b lå<tab>')
+ screen:expect{grid=[[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {4:långfile2 }|
+ |
+ {1:~ }|
+ {1:~ }|
+ {3:långfile1 }|
+ :b långfile1^ |
+ ]], popupmenu={
+ anchor = {1, 9, 3},
+ items = {{"långfile1", "", "", "" }, {"långfile2", "", "", ""}},
+ pos = 0,
+ }}
+ end)
end)
@@ -1209,7 +1316,7 @@ describe('builtin popupmenu', function()
]])
meths.input_mouse('wheel', 'down', '', 0, 6, 15)
- screen:expect([[
+ screen:expect{grid=[[
choice^ |
{1:~ }|
{n:word }{1: }|
@@ -1218,7 +1325,7 @@ describe('builtin popupmenu', function()
{n:thing }{1: }|
{3:[No Name] [+] }|
{2:-- INSERT --} |
- ]])
+ ]], unchanged=true}
end)
it('works with kind, menu and abbr attributes', function()
@@ -1273,6 +1380,131 @@ describe('builtin popupmenu', function()
]])
end)
+ it('works with wildoptions=pum', function()
+ screen:try_resize(32,10)
+ command('set wildmenu')
+ command('set wildoptions=pum')
+
+ feed(':sign ')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ :sign ^ |
+ ]])
+
+ feed('<tab>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }{s: define }{1: }|
+ {1:~ }{n: jump }{1: }|
+ {1:~ }{n: list }{1: }|
+ {1:~ }{n: place }{1: }|
+ {1:~ }{n: undefine }{1: }|
+ {1:~ }{n: unplace }{1: }|
+ :sign define^ |
+ ]])
+
+ feed('<left>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }{n: define }{1: }|
+ {1:~ }{n: jump }{1: }|
+ {1:~ }{n: list }{1: }|
+ {1:~ }{n: place }{1: }|
+ {1:~ }{n: undefine }{1: }|
+ {1:~ }{n: unplace }{1: }|
+ :sign ^ |
+ ]])
+
+ feed('<left>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }{n: define }{1: }|
+ {1:~ }{n: jump }{1: }|
+ {1:~ }{n: list }{1: }|
+ {1:~ }{n: place }{1: }|
+ {1:~ }{n: undefine }{1: }|
+ {1:~ }{s: unplace }{1: }|
+ :sign unplace^ |
+ ]])
+
+ feed('x')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ :sign unplacex^ |
+ ]])
+
+ feed('<esc>')
+
+ -- check positioning with multibyte char in pattern
+ command("e långfile1")
+ command("sp långfile2")
+ feed(':b lå<tab>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {4:långfile2 }|
+ |
+ {1:~ }|
+ {1:~ }{s: långfile1 }{1: }|
+ {3:lå}{n: långfile2 }{3: }|
+ :b långfile1^ |
+ ]])
+
+ -- check doesn't crash on screen resize
+ screen:try_resize(20,6)
+ screen:expect([[
+ |
+ {1:~ }|
+ {4:långfile2 }|
+ {s: långfile1 } |
+ {3:lå}{n: långfile2 }{3: }|
+ :b långfile1^ |
+ ]])
+
+ screen:try_resize(50,15)
+ screen:expect([[
+ |
+ {1:~ }|
+ {4:långfile2 }|
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }{s: långfile1 }{1: }|
+ {3:lå}{n: långfile2 }{3: }|
+ :b långfile1^ |
+ ]])
+ end)
+
it("'pumblend' RGB-color", function()
screen:try_resize(60,14)
screen:set_default_attr_ids({
diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua
index 8b1b77eb81..a81851cbba 100644
--- a/test/functional/ui/screen.lua
+++ b/test/functional/ui/screen.lua
@@ -71,10 +71,10 @@
-- To help write screen tests, see Screen:snapshot_util().
-- To debug screen tests, see Screen:redraw_debug().
-local global_helpers = require('test.helpers')
-local deepcopy = global_helpers.deepcopy
-local shallowcopy = global_helpers.shallowcopy
local helpers = require('test.functional.helpers')(nil)
+local deepcopy = helpers.deepcopy
+local shallowcopy = helpers.shallowcopy
+local concat_tables = helpers.concat_tables
local request, run_session = helpers.request, helpers.run_session
local eq = helpers.eq
local dedent = helpers.dedent
@@ -259,22 +259,19 @@ local ext_keys = {
'messages', 'showmode', 'showcmd', 'ruler', 'float_pos',
}
--- Asserts that the screen state eventually matches an expected state
+-- Asserts that the screen state eventually matches an expected state.
--
--- This function can either be called with the positional forms
---
--- screen:expect(grid, [attr_ids, attr_ignore])
--- screen:expect(condition)
---
--- or to use additional arguments (or grid and condition at the same time)
--- the keyword form has to be used:
---
--- screen:expect{grid=[[...]], cmdline={...}, condition=function() ... end}
+-- Can be called with positional args:
+-- screen:expect(grid, [attr_ids, attr_ignore])
+-- screen:expect(condition)
+-- or keyword args (supports more options):
+-- screen:expect{grid=[[...]], cmdline={...}, condition=function() ... end}
--
--
-- grid: Expected screen state (string). Each line represents a screen
-- row. Last character of each row (typically "|") is stripped.
-- Common indentation is stripped.
+-- Lines containing only "{IGNORE}|" are skipped.
-- attr_ids: Expected text attributes. Screen rows are transformed according
-- to this table, as follows: each substring S composed of
-- characters having the same attributes will be substituted by
@@ -416,26 +413,23 @@ screen:redraw_debug() to show all intermediate screen states. ]])
end
end
- -- Extension features. The default expectations should cover the case of
+ -- UI extensions. The default expectations should cover the case of
-- the ext_ feature being disabled, or the feature currently not activated
- -- (for instance no external cmdline visible). Some extensions require
+ -- (e.g. no external cmdline visible). Some extensions require
-- preprocessing to represent highlights in a reproducible way.
local extstate = self:_extstate_repr(attr_state)
-
- -- convert assertion errors into invalid screen state descriptions
- local status, res = pcall(function()
- for _, k in ipairs(ext_keys) do
- -- Empty states is considered the default and need not be mentioned
- if not (expected[k] == nil and isempty(extstate[k])) then
- eq(expected[k], extstate[k], k)
+ if expected['mode'] ~= nil then
+ extstate['mode'] = self.mode
+ end
+ -- Convert assertion errors into invalid screen state descriptions.
+ for _, k in ipairs(concat_tables(ext_keys, {'mode'})) do
+ -- Empty states are considered the default and need not be mentioned.
+ if (not (expected[k] == nil and isempty(extstate[k]))) then
+ local status, res = pcall(eq, expected[k], extstate[k], k)
+ if not status then
+ return (tostring(res)..'\nHint: full state of "'..k..'":\n '..inspect(extstate[k]))
end
end
- if expected.mode ~= nil then
- eq(expected.mode, self.mode, "mode")
- end
- end)
- if not status then
- return tostring(res)
end
end, expected)
end
@@ -937,10 +931,7 @@ function Screen:_handle_option_set(name, value)
end
function Screen:_handle_popupmenu_show(items, selected, row, col, grid)
- if (not self._options.ext_multigrid) and grid == 1 then
- grid = nil
- end
- self.popupmenu = {items=items, pos=selected, anchor={row, col, grid}}
+ self.popupmenu = {items=items, pos=selected, anchor={grid, row, col}}
end
function Screen:_handle_popupmenu_select(selected)
diff --git a/test/functional/ui/searchhl_spec.lua b/test/functional/ui/searchhl_spec.lua
index a46670d8a2..65ae124353 100644
--- a/test/functional/ui/searchhl_spec.lua
+++ b/test/functional/ui/searchhl_spec.lua
@@ -163,12 +163,14 @@ describe('search highlighting', function()
]])
feed('/foo')
sleep(50) -- Allow some terminal activity.
- screen:expect([[
- {3:foo} bar baz {3:│}xxx |
- bar baz {2:foo} {3:│}xxx |
- bar {2:foo} baz {3:│}xxx |
- {3:│}xxx |
- {1:~ }{3:│}xxx |
+ -- NB: in earlier versions terminal output was redrawn during cmdline mode.
+ -- For now just assert that the screens remain unchanged.
+ screen:expect([[
+ {3:foo} bar baz {3:│} |
+ bar baz {2:foo} {3:│} |
+ bar {2:foo} baz {3:│} |
+ {3:│} |
+ {1:~ }{3:│} |
{5:[No Name] [+] }{3:term }|
/foo^ |
]], { [1] = {bold = true, foreground = Screen.colors.Blue1},
diff --git a/test/functional/ui/sign_spec.lua b/test/functional/ui/sign_spec.lua
index bc0e2e3799..74019046c0 100644
--- a/test/functional/ui/sign_spec.lua
+++ b/test/functional/ui/sign_spec.lua
@@ -43,15 +43,15 @@ describe('Signs', function()
{2: }b |
{1:>>}c |
{2: }^ |
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
|
]])
end)
@@ -72,14 +72,14 @@ describe('Signs', function()
{1:>>}b |
{2: }c |
{2: } |
- {2: }{0:~ }|
- {2: }{0:~ }|
+ {0:~ }|
+ {0:~ }|
{4:[No Name] [+] }|
{2: }{3:a }|
{1:>>}b |
{2: }c |
{2: } |
- {2: }{0:~ }|
+ {0:~ }|
{5:[No Name] [+] }|
|
]])
@@ -102,31 +102,140 @@ describe('Signs', function()
{2: }{6: 2 }{8:b }|
{2: }{7: 3 }c |
{1:>>}{7: 4 }{8:^ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
|
]])
end)
+ it('multiple signs #9295', function()
+ feed('ia<cr>b<cr>c<cr><esc>')
+ command('set number')
+ command('set signcolumn=yes:2')
+ command('sign define pietSearch text=>> texthl=Search')
+ command('sign define pietError text=XX texthl=Error')
+ command('sign define pietWarn text=WW texthl=Warning')
+ command('sign place 1 line=1 name=pietSearch buffer=1')
+ command('sign place 2 line=1 name=pietError buffer=1')
+ -- Line 2 helps checking that signs in the same line are ordered by Id.
+ command('sign place 4 line=2 name=pietSearch buffer=1')
+ command('sign place 3 line=2 name=pietError buffer=1')
+ -- Line 3 checks that with a limit over the maximum number
+ -- of signs, the ones with the highest Ids are being picked,
+ -- and presented by their sorted Id order.
+ command('sign place 4 line=3 name=pietSearch buffer=1')
+ command('sign place 5 line=3 name=pietWarn buffer=1')
+ command('sign place 3 line=3 name=pietError buffer=1')
+ screen:expect([[
+ {1:>>}XX{6: 1 }a |
+ XX{1:>>}{6: 2 }b |
+ {1:>>}WW{6: 3 }c |
+ {2: }{6: 4 }^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+ -- With the default setting, we get the sign with the top id.
+ command('set signcolumn=yes:1')
+ screen:expect([[
+ XX{6: 1 }a |
+ {1:>>}{6: 2 }b |
+ WW{6: 3 }c |
+ {2: }{6: 4 }^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+ -- "auto:3" accommodates all the signs we defined so far.
+ command('set signcolumn=auto:3')
+ screen:expect([[
+ {1:>>}XX{2: }{6: 1 }a |
+ XX{1:>>}{2: }{6: 2 }b |
+ XX{1:>>}WW{6: 3 }c |
+ {2: }{6: 4 }^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+ -- Check "yes:9".
+ command('set signcolumn=yes:9')
+ screen:expect([[
+ {1:>>}XX{2: }{6: 1 }a |
+ XX{1:>>}{2: }{6: 2 }b |
+ XX{1:>>}WW{2: }{6: 3 }c |
+ {2: }{6: 4 }^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+ -- Check "auto:N" larger than the maximum number of signs defined in
+ -- a single line (same result as "auto:3").
+ command('set signcolumn=auto:4')
+ screen:expect{grid=[[
+ {1:>>}XX{2: }{6: 1 }a |
+ XX{1:>>}{2: }{6: 2 }b |
+ XX{1:>>}WW{6: 3 }c |
+ {2: }{6: 4 }^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]]}
+ end)
+
it('can have 32bit sign IDs', function()
command('sign define piet text=>> texthl=Search')
command('sign place 100000 line=1 name=piet buffer=1')
feed(':sign place<cr>')
screen:expect([[
{1:>>} |
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{4: }|
:sign place |
{9:--- Signs ---} |
@@ -139,18 +248,18 @@ describe('Signs', function()
feed('<cr>')
screen:expect([[
{1:>>}^ |
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
- {2: }{0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
|
]])
end)
diff --git a/test/functional/ui/wildmode_spec.lua b/test/functional/ui/wildmode_spec.lua
index 7cd09fb222..f4b80fd428 100644
--- a/test/functional/ui/wildmode_spec.lua
+++ b/test/functional/ui/wildmode_spec.lua
@@ -1,7 +1,6 @@
-local global_helpers = require('test.helpers')
-local shallowcopy = global_helpers.shallowcopy
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
+local shallowcopy = helpers.shallowcopy
local clear, feed, command = helpers.clear, helpers.feed, helpers.command
local iswin = helpers.iswin
local funcs = helpers.funcs
@@ -29,8 +28,7 @@ describe("'wildmenu'", function()
end
it(':sign <tab> shows wildmenu completions', function()
- command('set wildmode=full')
- command('set wildmenu')
+ command('set wildmenu wildmode=full')
feed(':sign <tab>')
screen:expect([[
|
@@ -96,10 +94,12 @@ describe("'wildmenu'", function()
feed([[<C-\><C-N>gg]])
feed([[:sign <Tab>]]) -- Invoke wildmenu.
+ -- NB: in earlier versions terminal output was redrawn during cmdline mode.
+ -- For now just assert that the screen remains unchanged.
expect_stay_unchanged{grid=[[
- foo |
- foo |
- foo |
+ |
+ |
+ |
define jump list > |
:sign define^ |
]]}
@@ -201,14 +201,28 @@ describe('command line completion', function()
]])
end)
+ it('completes env var names #9681', function()
+ clear()
+ screen:attach()
+ command('let $XTEST_1 = "foo" | let $XTEST_2 = "bar"')
+ command('set wildmenu wildmode=full')
+ feed(':!echo $XTEST_<tab>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {2:XTEST_1}{3: XTEST_2 }|
+ :!echo $XTEST_1^ |
+ ]])
+ end)
+
it('completes (multibyte) env var names #9655', function()
clear({env={
['XTEST_1AaあB']='foo',
['XTEST_2']='bar',
}})
screen:attach()
- command('set wildmode=full')
- command('set wildmenu')
+ command('set wildmenu wildmode=full')
feed(':!echo $XTEST_<tab>')
screen:expect([[
|
diff --git a/test/functional/viml/completion_spec.lua b/test/functional/viml/completion_spec.lua
index cd1b312265..9d4cb325d9 100644
--- a/test/functional/viml/completion_spec.lua
+++ b/test/functional/viml/completion_spec.lua
@@ -904,9 +904,9 @@ describe('completion', function()
|
{8:[No Name] }|
{0::}foo faa fee f^ |
- {0::~ }|
- {0::~ }|
- {0::~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{9:[Command Line] }|
{3:-- INSERT --} |
]] )
@@ -915,9 +915,9 @@ describe('completion', function()
|
{8:[No Name] }|
{0::}foo faa fee foo^ |
- {0::~ }{2: foo }{0: }|
- {0::~ }{1: faa }{0: }|
- {0::~ }{1: fee }{0: }|
+ {0:~ }{2: foo }{0: }|
+ {0:~ }{1: faa }{0: }|
+ {0:~ }{1: fee }{0: }|
{9:[Command Line] }|
{3:-- Keyword Local completion (^N^P) }{4:match 1 of 3} |
]])
@@ -926,9 +926,9 @@ describe('completion', function()
|
{8:[No Name] }|
{0::}foo faa fee foo |
- {0::~ }|
- {0::~ }|
- {0::~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{9:[Command Line] }|
:foo faa fee foo^ |
]])
@@ -1072,4 +1072,83 @@ describe('completion', function()
set complete&vim completeopt&vim
]])
end)
+
+ it('CompleteChanged autocommand', function()
+ curbufmeths.set_lines(0, 1, false, { 'foo', 'bar', 'foobar', ''})
+ source([[
+ set complete=. completeopt=noinsert,noselect,menuone
+ function! OnPumChange()
+ let g:event = copy(v:event)
+ let g:item = get(v:event, 'completed_item', {})
+ let g:word = get(g:item, 'word', v:null)
+ endfunction
+ autocmd! CompleteChanged * :call OnPumChange()
+ call cursor(4, 1)
+ ]])
+
+ feed('Sf<C-N>')
+ screen:expect([[
+ foo |
+ bar |
+ foobar |
+ f^ |
+ {1:foo }{0: }|
+ {1:foobar }{0: }|
+ {0:~ }|
+ {3:-- Keyword completion (^N^P) }{5:Back at original} |
+ ]])
+ eq({completed_item = {}, width = 15,
+ height = 2, size = 2,
+ col = 0, row = 4, scrollbar = false},
+ eval('g:event'))
+ feed('<C-N>')
+ screen:expect([[
+ foo |
+ bar |
+ foobar |
+ foo^ |
+ {2:foo }{0: }|
+ {1:foobar }{0: }|
+ {0:~ }|
+ {3:-- Keyword completion (^N^P) }{4:match 1 of 2} |
+ ]])
+ eq('foo', eval('g:word'))
+ feed('<C-N>')
+ screen:expect([[
+ foo |
+ bar |
+ foobar |
+ foobar^ |
+ {1:foo }{0: }|
+ {2:foobar }{0: }|
+ {0:~ }|
+ {3:-- Keyword completion (^N^P) }{4:match 2 of 2} |
+ ]])
+ eq('foobar', eval('g:word'))
+ feed('<up>')
+ screen:expect([[
+ foo |
+ bar |
+ foobar |
+ foobar^ |
+ {2:foo }{0: }|
+ {1:foobar }{0: }|
+ {0:~ }|
+ {3:-- Keyword completion (^N^P) }{4:match 1 of 2} |
+ ]])
+ eq('foo', eval('g:word'))
+ feed('<down>')
+ screen:expect([[
+ foo |
+ bar |
+ foobar |
+ foobar^ |
+ {1:foo }{0: }|
+ {2:foobar }{0: }|
+ {0:~ }|
+ {3:-- Keyword completion (^N^P) }{4:match 2 of 2} |
+ ]])
+ eq('foobar', eval('g:word'))
+ feed('<esc>')
+ end)
end)
diff --git a/test/functional/viml/errorlist_spec.lua b/test/functional/viml/errorlist_spec.lua
index 6c5a63e6b1..c5390cbd12 100644
--- a/test/functional/viml/errorlist_spec.lua
+++ b/test/functional/viml/errorlist_spec.lua
@@ -26,7 +26,7 @@ describe('setqflist()', function()
it('sets w:quickfix_title', function()
setqflist({''}, 'r', 'foo')
command('copen')
- eq(':foo', get_cur_win_var('quickfix_title'))
+ eq('foo', get_cur_win_var('quickfix_title'))
setqflist({''}, 'r', {['title'] = 'qf_title'})
eq('qf_title', get_cur_win_var('quickfix_title'))
end)
@@ -34,7 +34,7 @@ describe('setqflist()', function()
it('allows string {what} for backwards compatibility', function()
setqflist({}, 'r', '5')
command('copen')
- eq(':5', get_cur_win_var('quickfix_title'))
+ eq('5', get_cur_win_var('quickfix_title'))
end)
it('requires a dict for {what}', function()
@@ -64,8 +64,8 @@ describe('setloclist()', function()
setloclist(1, {}, 'r', 'foo')
setloclist(2, {}, 'r', 'bar')
command('lopen')
- eq(':bar', get_cur_win_var('quickfix_title'))
+ eq('bar', get_cur_win_var('quickfix_title'))
command('lclose | wincmd w | lopen')
- eq(':foo', get_cur_win_var('quickfix_title'))
+ eq('foo', get_cur_win_var('quickfix_title'))
end)
end)
diff --git a/test/helpers.lua b/test/helpers.lua
index 3a766b99f5..2a6285e685 100644
--- a/test/helpers.lua
+++ b/test/helpers.lua
@@ -1,8 +1,10 @@
require('vim.compat')
+local shared = require('vim.shared')
local assert = require('luassert')
local luv = require('luv')
local lfs = require('lfs')
local relpath = require('pl.path').relpath
+local Paths = require('test.config.paths')
local quote_me = '[^.%w%+%-%@%_%/]' -- complement (needn't quote)
local function shell_quote(str)
@@ -235,6 +237,11 @@ local function hasenv(name)
return nil
end
+local function deps_prefix()
+ local env = os.getenv('DEPS_PREFIX')
+ return (env and env ~= '') and env or '.deps/usr'
+end
+
local tests_skipped = 0
local function check_cores(app, force)
@@ -263,7 +270,7 @@ local function check_cores(app, force)
else
initial_path = '.'
re = '/core[^/]*$'
- exc_re = { '^/%.deps$', local_tmpdir, '^/%node_modules$' }
+ exc_re = { '^/%.deps$', '^/%'..deps_prefix()..'$', local_tmpdir, '^/%node_modules$' }
db_cmd = gdb_db_cmd
random_skip = true
end
@@ -329,30 +336,6 @@ local function shallowcopy(orig)
return copy
end
-local deepcopy
-
-local function id(v)
- return v
-end
-
-local deepcopy_funcs = {
- table = function(orig)
- local copy = {}
- for k, v in pairs(orig) do
- copy[deepcopy(k)] = deepcopy(v)
- end
- return copy
- end,
- number = id,
- string = id,
- ['nil'] = id,
- boolean = id,
-}
-
-deepcopy = function(orig)
- return deepcopy_funcs[type(orig)](orig)
-end
-
local REMOVE_THIS = {}
local function mergedicts_copy(d1, d2)
@@ -415,6 +398,7 @@ local function updated(d, d2)
return d
end
+-- Concat list-like tables.
local function concat_tables(...)
local ret = {}
for i = 1, select('#', ...) do
@@ -604,24 +588,6 @@ local function fixtbl_rec(tbl)
return fixtbl(tbl)
end
--- From https://github.com/premake/premake-core/blob/master/src/base/table.lua
-local function table_flatten(arr)
- local result = {}
- local function _table_flatten(_arr)
- local n = #_arr
- for i = 1, n do
- local v = _arr[i]
- if type(v) == "table" then
- _table_flatten(v)
- elseif v then
- table.insert(result, v)
- end
- end
- end
- _table_flatten(arr)
- return result
-end
-
local function hexdump(str)
local len = string.len(str)
local dump = ""
@@ -742,7 +708,6 @@ local module = {
check_logs = check_logs,
concat_tables = concat_tables,
dedent = dedent,
- deepcopy = deepcopy,
dictdiff = dictdiff,
eq = eq,
expect_err = expect_err,
@@ -770,7 +735,6 @@ local module = {
repeated_read_cmd = repeated_read_cmd,
shallowcopy = shallowcopy,
sleep = sleep,
- table_flatten = table_flatten,
tmpname = tmpname,
uname = uname,
updated = updated,
@@ -778,5 +742,6 @@ local module = {
write_file = write_file,
trim = trim,
}
+module = shared.tbl_extend('error', module, Paths, shared)
return module
diff --git a/test/symbolic/klee/nvim/keymap.c b/test/symbolic/klee/nvim/keymap.c
index a341a73689..07eb4fa70a 100644
--- a/test/symbolic/klee/nvim/keymap.c
+++ b/test/symbolic/klee/nvim/keymap.c
@@ -165,6 +165,7 @@ static const struct key_name_entry {
{ K_DEL, "Del" },
{ K_DEL, "Delete" }, // Alternative name
{ K_KDEL, "kDel" },
+ { K_KDEL, "KPPeriod" }, // termkey KPPeriod value
{ K_UP, "Up" },
{ K_DOWN, "Down" },
{ K_LEFT, "Left" },
@@ -173,6 +174,14 @@ static const struct key_name_entry {
{ K_XDOWN, "xDown" },
{ K_XLEFT, "xLeft" },
{ K_XRIGHT, "xRight" },
+ { K_KUP, "kUp" },
+ { K_KUP, "KP8" },
+ { K_KDOWN, "kDown" },
+ { K_KDOWN, "KP2" },
+ { K_KLEFT, "kLeft" },
+ { K_KLEFT, "KP4" },
+ { K_KRIGHT, "kRight" },
+ { K_KRIGHT, "KP6" },
{ K_F1, "F1" },
{ K_F2, "F2" },
@@ -225,8 +234,10 @@ static const struct key_name_entry {
{ K_INS, "Insert" },
{ K_INS, "Ins" }, // Alternative name
{ K_KINS, "kInsert" },
+ { K_KINS, "KP0" },
{ K_HOME, "Home" },
{ K_KHOME, "kHome" },
+ { K_KHOME, "KP7" },
{ K_XHOME, "xHome" },
{ K_ZHOME, "zHome" },
{ K_END, "End" },
@@ -236,13 +247,22 @@ static const struct key_name_entry {
{ K_PAGEUP, "PageUp" },
{ K_PAGEDOWN, "PageDown" },
{ K_KPAGEUP, "kPageUp" },
+ { K_KPAGEUP, "KP9" },
{ K_KPAGEDOWN, "kPageDown" },
+ { K_KPAGEDOWN, "KP3" },
+ { K_KORIGIN, "kOrigin" },
+ { K_KORIGIN, "KP5" },
{ K_KPLUS, "kPlus" },
+ { K_KPLUS, "KPPlus" },
{ K_KMINUS, "kMinus" },
+ { K_KMINUS, "KPMinus" },
{ K_KDIVIDE, "kDivide" },
+ { K_KDIVIDE, "KPDiv" },
{ K_KMULTIPLY, "kMultiply" },
+ { K_KMULTIPLY, "KPMult" },
{ K_KENTER, "kEnter" },
+ { K_KENTER, "KPEnter" },
{ K_KPOINT, "kPoint" },
{ K_K0, "k0" },
diff --git a/test/unit/eval/typval_spec.lua b/test/unit/eval/typval_spec.lua
index 919a42fbb9..4535d6a0b2 100644
--- a/test/unit/eval/typval_spec.lua
+++ b/test/unit/eval/typval_spec.lua
@@ -1,7 +1,6 @@
local bit = require('bit')
local helpers = require('test.unit.helpers')(after_each)
local eval_helpers = require('test.unit.eval.helpers')
-local global_helpers = require('test.helpers')
local itp = helpers.gen_itp(it)
@@ -14,6 +13,8 @@ local NULL = helpers.NULL
local cimport = helpers.cimport
local to_cstr = helpers.to_cstr
local alloc_log_new = helpers.alloc_log_new
+local concat_tables = helpers.concat_tables
+local map = helpers.map
local a = eval_helpers.alloc_logging_helpers
local int = eval_helpers.int
@@ -40,9 +41,6 @@ local callback2tbl = eval_helpers.callback2tbl
local tbl2callback = eval_helpers.tbl2callback
local dict_watchers = eval_helpers.dict_watchers
-local concat_tables = global_helpers.concat_tables
-local map = global_helpers.map
-
local lib = cimport('./src/nvim/eval/typval.h', './src/nvim/memory.h',
'./src/nvim/mbyte.h', './src/nvim/garray.h',
'./src/nvim/eval.h', './src/nvim/vim.h',
diff --git a/test/unit/helpers.lua b/test/unit/helpers.lua
index 1345fbce17..b5d3dd9f47 100644
--- a/test/unit/helpers.lua
+++ b/test/unit/helpers.lua
@@ -15,7 +15,6 @@ local dedent = global_helpers.dedent
local neq = global_helpers.neq
local map = global_helpers.map
local eq = global_helpers.eq
-local ok = global_helpers.ok
local trim = global_helpers.trim
-- C constants.
@@ -839,9 +838,6 @@ local module = {
cimport = cimport,
cppimport = cppimport,
internalize = internalize,
- ok = ok,
- eq = eq,
- neq = neq,
ffi = ffi,
lib = lib,
cstr = cstr,
@@ -866,6 +862,7 @@ local module = {
ptr2key = ptr2key,
debug_log = debug_log,
}
+module = global_helpers.tbl_extend('error', module, global_helpers)
return function()
return module
end
diff --git a/test/unit/undo_spec.lua b/test/unit/undo_spec.lua
index f23110b329..616c6fbe3d 100644
--- a/test/unit/undo_spec.lua
+++ b/test/unit/undo_spec.lua
@@ -2,9 +2,7 @@ local helpers = require('test.unit.helpers')(after_each)
local itp = helpers.gen_itp(it)
local lfs = require('lfs')
local child_call_once = helpers.child_call_once
-
-local global_helpers = require('test.helpers')
-local sleep = global_helpers.sleep
+local sleep = helpers.sleep
local ffi = helpers.ffi
local cimport = helpers.cimport
@@ -156,12 +154,12 @@ describe('u_write_undo', function()
local file_contents = "testing permissions"
-- Write a text file where the undofile should go
local correct_name = ffi.string(undo.u_get_undo_file_name(file_buffer.b_ffname, false))
- global_helpers.write_file(correct_name, file_contents, true, false)
+ helpers.write_file(correct_name, file_contents, true, false)
-- Call with `forceit`.
u_write_undo(correct_name, true, file_buffer, buffer_hash)
- local undo_file_contents = global_helpers.read_file(correct_name)
+ local undo_file_contents = helpers.read_file(correct_name)
neq(file_contents, undo_file_contents)
local success, deletion_err = os.remove(correct_name) -- delete the file now that we're done with it.
diff --git a/test/unit/viml/expressions/lexer_spec.lua b/test/unit/viml/expressions/lexer_spec.lua
index 1b57a24ad5..358e858d61 100644
--- a/test/unit/viml/expressions/lexer_spec.lua
+++ b/test/unit/viml/expressions/lexer_spec.lua
@@ -1,5 +1,4 @@
local helpers = require('test.unit.helpers')(after_each)
-local global_helpers = require('test.helpers')
local itp = helpers.gen_itp(it)
local viml_helpers = require('test.unit.viml.helpers')
@@ -8,6 +7,8 @@ local conv_enum = helpers.conv_enum
local cimport = helpers.cimport
local ffi = helpers.ffi
local eq = helpers.eq
+local shallowcopy = helpers.shallowcopy
+local intchar2lua = helpers.intchar2lua
local conv_ccs = viml_helpers.conv_ccs
local new_pstate = viml_helpers.new_pstate
@@ -15,9 +16,6 @@ local conv_cmp_type = viml_helpers.conv_cmp_type
local pstate_set_str = viml_helpers.pstate_set_str
local conv_expr_asgn_type = viml_helpers.conv_expr_asgn_type
-local shallowcopy = global_helpers.shallowcopy
-local intchar2lua = global_helpers.intchar2lua
-
local lib = cimport('./src/nvim/viml/parser/expressions.h')
local eltkn_type_tab, eltkn_mul_type_tab, eltkn_opt_scope_tab
diff --git a/test/unit/viml/expressions/parser_spec.lua b/test/unit/viml/expressions/parser_spec.lua
index 73388e5dd2..a8f29529ec 100644
--- a/test/unit/viml/expressions/parser_spec.lua
+++ b/test/unit/viml/expressions/parser_spec.lua
@@ -1,5 +1,4 @@
local helpers = require('test.unit.helpers')(after_each)
-local global_helpers = require('test.helpers')
local itp = helpers.gen_itp(it)
local viml_helpers = require('test.unit.viml.helpers')
@@ -14,6 +13,11 @@ local cimport = helpers.cimport
local ffi = helpers.ffi
local neq = helpers.neq
local eq = helpers.eq
+local mergedicts_copy = helpers.mergedicts_copy
+local format_string = helpers.format_string
+local format_luav = helpers.format_luav
+local intchar2lua = helpers.intchar2lua
+local dictdiff = helpers.dictdiff
local conv_ccs = viml_helpers.conv_ccs
local new_pstate = viml_helpers.new_pstate
@@ -21,12 +25,6 @@ local conv_cmp_type = viml_helpers.conv_cmp_type
local pstate_set_str = viml_helpers.pstate_set_str
local conv_expr_asgn_type = viml_helpers.conv_expr_asgn_type
-local mergedicts_copy = global_helpers.mergedicts_copy
-local format_string = global_helpers.format_string
-local format_luav = global_helpers.format_luav
-local intchar2lua = global_helpers.intchar2lua
-local dictdiff = global_helpers.dictdiff
-
local lib = cimport('./src/nvim/viml/parser/expressions.h',
'./src/nvim/syntax.h')