aboutsummaryrefslogtreecommitdiff
path: root/test/functional
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional')
-rw-r--r--test/functional/api/command_spec.lua92
-rw-r--r--test/functional/api/highlight_spec.lua2
-rw-r--r--test/functional/api/vim_spec.lua104
-rw-r--r--test/functional/autocmd/winscrolled_spec.lua14
-rw-r--r--test/functional/core/exit_spec.lua6
-rw-r--r--test/functional/core/job_spec.lua9
-rw-r--r--test/functional/editor/K_spec.lua11
-rw-r--r--test/functional/editor/ctrl_c_spec.lua12
-rw-r--r--test/functional/editor/mode_insert_spec.lua8
-rw-r--r--test/functional/ex_cmds/normal_spec.lua17
-rw-r--r--test/functional/ex_cmds/oldfiles_spec.lua3
-rw-r--r--test/functional/ex_cmds/source_spec.lua69
-rw-r--r--test/functional/ex_cmds/swapfile_preserve_recover_spec.lua124
-rw-r--r--test/functional/ex_cmds/wincmd_spec.lua13
-rw-r--r--test/functional/fixtures/wildpum/Xdir/XdirA/XdirB/XfileC (renamed from test/functional/fixtures/compdir/file1)0
-rw-r--r--test/functional/fixtures/wildpum/Xdir/XdirA/XfileB (renamed from test/functional/fixtures/compdir/file2)0
-rw-r--r--test/functional/fixtures/wildpum/Xdir/XfileA0
-rw-r--r--test/functional/fixtures/wildpum/compdir/file10
-rw-r--r--test/functional/fixtures/wildpum/compdir/file20
-rw-r--r--test/functional/fixtures/wildpum/あいう/1230
-rw-r--r--test/functional/fixtures/wildpum/あいう/abc0
-rw-r--r--test/functional/fixtures/wildpum/あいう/xyz0
-rw-r--r--test/functional/helpers.lua5
-rw-r--r--test/functional/legacy/arglist_spec.lua2
-rw-r--r--test/functional/legacy/buffer_spec.lua59
-rw-r--r--test/functional/legacy/cmdline_spec.lua84
-rw-r--r--test/functional/legacy/ex_mode_spec.lua4
-rw-r--r--test/functional/legacy/excmd_spec.lua6
-rw-r--r--test/functional/legacy/filechanged_spec.lua9
-rw-r--r--test/functional/legacy/gf_spec.lua15
-rw-r--r--test/functional/legacy/global_spec.lua6
-rw-r--r--test/functional/legacy/mapping_spec.lua18
-rw-r--r--test/functional/legacy/messages_spec.lua89
-rw-r--r--test/functional/lua/diagnostic_spec.lua22
-rw-r--r--test/functional/lua/luaeval_spec.lua5
-rw-r--r--test/functional/lua/overrides_spec.lua45
-rw-r--r--test/functional/lua/vim_spec.lua33
-rw-r--r--test/functional/options/defaults_spec.lua30
-rw-r--r--test/functional/plugin/lsp_spec.lua28
-rw-r--r--test/functional/plugin/man_spec.lua6
-rw-r--r--test/functional/provider/clipboard_spec.lua10
-rw-r--r--test/functional/terminal/tui_spec.lua234
-rw-r--r--test/functional/treesitter/highlight_spec.lua101
-rw-r--r--test/functional/treesitter/language_spec.lua38
-rw-r--r--test/functional/treesitter/node_spec.lua49
-rw-r--r--test/functional/treesitter/utils_spec.lua33
-rw-r--r--test/functional/ui/cmdline_highlight_spec.lua74
-rw-r--r--test/functional/ui/decorations_spec.lua38
-rw-r--r--test/functional/ui/fold_spec.lua7
-rw-r--r--test/functional/ui/highlight_spec.lua386
-rw-r--r--test/functional/ui/hlstate_spec.lua20
-rw-r--r--test/functional/ui/inccommand_spec.lua17
-rw-r--r--test/functional/ui/inccommand_user_spec.lua347
-rw-r--r--test/functional/ui/input_spec.lua29
-rw-r--r--test/functional/ui/messages_spec.lua19
-rw-r--r--test/functional/ui/mouse_spec.lua2
-rw-r--r--test/functional/ui/multigrid_spec.lua11
-rw-r--r--test/functional/ui/output_spec.lua29
-rw-r--r--test/functional/ui/popupmenu_spec.lua411
-rw-r--r--test/functional/ui/screen.lua8
-rw-r--r--test/functional/ui/statusline_spec.lua2
-rw-r--r--test/functional/ui/wildmode_spec.lua58
-rw-r--r--test/functional/ui/winbar_spec.lua141
-rw-r--r--test/functional/vimscript/eval_spec.lua103
-rw-r--r--test/functional/vimscript/input_spec.lua77
-rw-r--r--test/functional/vimscript/null_spec.lua2
-rw-r--r--test/functional/vimscript/special_vars_spec.lua6
67 files changed, 2742 insertions, 460 deletions
diff --git a/test/functional/api/command_spec.lua b/test/functional/api/command_spec.lua
index 7eb7ee73f9..440e93da0e 100644
--- a/test/functional/api/command_spec.lua
+++ b/test/functional/api/command_spec.lua
@@ -114,8 +114,8 @@ describe('nvim_create_user_command', function()
]]
eq({
- args = [[this is a\ test]],
- fargs = {"this", "is", "a test"},
+ args = [[this\ is a\ test]],
+ fargs = {"this ", "is", "a test"},
bang = false,
line1 = 1,
line2 = 1,
@@ -144,7 +144,7 @@ describe('nvim_create_user_command', function()
count = 2,
reg = "",
}, exec_lua [=[
- vim.api.nvim_command([[CommandWithLuaCallback this is a\ test]])
+ vim.api.nvim_command([[CommandWithLuaCallback this\ is a\ test]])
return result
]=])
@@ -326,7 +326,7 @@ describe('nvim_create_user_command', function()
-- f-args doesn't split when command nargs is 1 or "?"
exec_lua [[
result = {}
- vim.api.nvim_create_user_command('CommandWithOneArg', function(opts)
+ vim.api.nvim_create_user_command('CommandWithOneOrNoArg', function(opts)
result = opts
end, {
nargs = "?",
@@ -366,7 +366,89 @@ describe('nvim_create_user_command', function()
count = 2,
reg = "",
}, exec_lua [[
- vim.api.nvim_command('CommandWithOneArg hello I\'m one argument')
+ vim.api.nvim_command('CommandWithOneOrNoArg hello I\'m one argument')
+ return result
+ ]])
+
+ -- f-args is an empty table if no args were passed
+ eq({
+ args = "",
+ fargs = {},
+ bang = false,
+ line1 = 1,
+ line2 = 1,
+ mods = "",
+ smods = {
+ browse = false,
+ confirm = false,
+ emsg_silent = false,
+ hide = false,
+ keepalt = false,
+ keepjumps = false,
+ keepmarks = false,
+ keeppatterns = false,
+ lockmarks = false,
+ noautocmd = false,
+ noswapfile = false,
+ sandbox = false,
+ silent = false,
+ split = "",
+ tab = 0,
+ unsilent = false,
+ verbose = -1,
+ vertical = false,
+ },
+ range = 0,
+ count = 2,
+ reg = "",
+ }, exec_lua [[
+ vim.api.nvim_command('CommandWithOneOrNoArg')
+ return result
+ ]])
+
+ -- f-args is an empty table when the command nargs=0
+ exec_lua [[
+ result = {}
+ vim.api.nvim_create_user_command('CommandWithNoArgs', function(opts)
+ result = opts
+ end, {
+ nargs = 0,
+ bang = true,
+ count = 2,
+ })
+ ]]
+ eq({
+ args = "",
+ fargs = {},
+ bang = false,
+ line1 = 1,
+ line2 = 1,
+ mods = "",
+ smods = {
+ browse = false,
+ confirm = false,
+ emsg_silent = false,
+ hide = false,
+ keepalt = false,
+ keepjumps = false,
+ keepmarks = false,
+ keeppatterns = false,
+ lockmarks = false,
+ noautocmd = false,
+ noswapfile = false,
+ sandbox = false,
+ silent = false,
+ split = "",
+ tab = 0,
+ unsilent = false,
+ verbose = -1,
+ vertical = false,
+ },
+ range = 0,
+ count = 2,
+ reg = "",
+ }, exec_lua [[
+ vim.cmd('CommandWithNoArgs')
return result
]])
diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua
index c4197f0b3e..2730f7e23d 100644
--- a/test/functional/api/highlight_spec.lua
+++ b/test/functional/api/highlight_spec.lua
@@ -243,7 +243,7 @@ describe("API: set highlight", function()
local function get_ns()
local ns = meths.create_namespace('Test_set_hl')
- meths._set_hl_ns(ns)
+ meths.set_hl_ns(ns)
return ns
end
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index fe623ff824..24d0b6da45 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -281,8 +281,8 @@ describe('API', function()
]]}
end)
- it('does\'t display messages when output=true', function()
- local screen = Screen.new(40, 8)
+ it('doesn\'t display messages when output=true', function()
+ local screen = Screen.new(40, 6)
screen:attach()
screen:set_default_attr_ids({
[0] = {bold=true, foreground=Screen.colors.Blue},
@@ -294,9 +294,21 @@ describe('API', function()
{0:~ }|
{0:~ }|
{0:~ }|
+ |
+ ]]}
+ exec([[
+ func Print()
+ call nvim_exec('echo "hello"', v:true)
+ endfunc
+ ]])
+ feed([[:echon 1 | call Print() | echon 5<CR>]])
+ screen:expect{grid=[[
+ ^ |
{0:~ }|
{0:~ }|
- |
+ {0:~ }|
+ {0:~ }|
+ 15 |
]]}
end)
end)
@@ -3656,6 +3668,55 @@ describe('API', function()
:^ |
]])
end)
+ it('does not move cursor or change search history/pattern #19878 #19890', function()
+ meths.buf_set_lines(0, 0, -1, true, {'foo', 'bar', 'foo', 'bar'})
+ eq({1, 0}, meths.win_get_cursor(0))
+ eq('', funcs.getreg('/'))
+ eq('', funcs.histget('search'))
+ feed(':') -- call the API in cmdline mode to test whether it changes search history
+ eq({
+ cmd = 'normal',
+ args = {'x'},
+ bang = true,
+ range = {3, 4},
+ count = -1,
+ reg = '',
+ addr = 'line',
+ magic = {
+ file = false,
+ bar = false,
+ },
+ nargs = '+',
+ nextcmd = '',
+ mods = {
+ browse = false,
+ confirm = false,
+ emsg_silent = false,
+ filter = {
+ pattern = "",
+ force = false,
+ },
+ hide = false,
+ keepalt = false,
+ keepjumps = false,
+ keepmarks = false,
+ keeppatterns = false,
+ lockmarks = false,
+ noautocmd = false,
+ noswapfile = false,
+ sandbox = false,
+ silent = false,
+ split = "",
+ tab = 0,
+ unsilent = false,
+ verbose = -1,
+ vertical = false,
+ }
+ }, meths.parse_cmd('+2;/bar/normal! x', {}))
+ eq({1, 0}, meths.win_get_cursor(0))
+ eq('', funcs.getreg('/'))
+ eq('', funcs.histget('search'))
+ end)
end)
describe('nvim_cmd', function()
it('works', function ()
@@ -3829,5 +3890,42 @@ describe('API', function()
eq({'aa'}, meths.buf_get_lines(0, 0, 1, false))
assert_alive()
end)
+ it("'make' command works when argument count isn't 1 #19696", function()
+ command('set makeprg=echo')
+ meths.cmd({ cmd = 'make' }, {})
+ assert_alive()
+ meths.cmd({ cmd = 'make', args = { 'foo', 'bar' } }, {})
+ assert_alive()
+ end)
+ it('doesn\'t display messages when output=true', function()
+ local screen = Screen.new(40, 6)
+ screen:attach()
+ screen:set_default_attr_ids({
+ [0] = {bold=true, foreground=Screen.colors.Blue},
+ })
+ meths.cmd({cmd = 'echo', args = {[['hello']]}}, {output = true})
+ screen:expect{grid=[[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]]}
+ exec([[
+ func Print()
+ call nvim_cmd(#{cmd: 'echo', args: ['"hello"']}, #{output: v:true})
+ endfunc
+ ]])
+ feed([[:echon 1 | call Print() | echon 5<CR>]])
+ screen:expect{grid=[[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ 15 |
+ ]]}
+ end)
end)
end)
diff --git a/test/functional/autocmd/winscrolled_spec.lua b/test/functional/autocmd/winscrolled_spec.lua
index 5c1b758961..12b8e7c42d 100644
--- a/test/functional/autocmd/winscrolled_spec.lua
+++ b/test/functional/autocmd/winscrolled_spec.lua
@@ -61,6 +61,20 @@ describe('WinScrolled', function()
eq(3, eval('g:scrolled'))
end)
+ it('is triggered by scrolling on a long wrapped line #19968', function()
+ local height = meths.win_get_height(0)
+ local width = meths.win_get_width(0)
+ meths.buf_set_lines(0, 0, -1, true, {('foo'):rep(height * width)})
+ meths.win_set_cursor(0, {1, height * width - 1})
+ eq(0, eval('g:scrolled'))
+ feed('gj')
+ eq(1, eval('g:scrolled'))
+ feed('0')
+ eq(2, eval('g:scrolled'))
+ feed('$')
+ eq(3, eval('g:scrolled'))
+ end)
+
it('is triggered when the window scrolls in Insert mode', function()
local height = meths.win_get_height(0)
local lines = {}
diff --git a/test/functional/core/exit_spec.lua b/test/functional/core/exit_spec.lua
index 4dba58dbfc..8cad7adfa6 100644
--- a/test/functional/core/exit_spec.lua
+++ b/test/functional/core/exit_spec.lua
@@ -3,6 +3,7 @@ local helpers = require('test.functional.helpers')(after_each)
local assert_alive = helpers.assert_alive
local command = helpers.command
local feed_command = helpers.feed_command
+local feed = helpers.feed
local eval = helpers.eval
local eq = helpers.eq
local run = helpers.run
@@ -36,11 +37,12 @@ describe('v:exiting', function()
end
run(on_request, nil, on_setup)
end)
- it('is 0 on exit from ex-mode involving try-catch', function()
+ it('is 0 on exit from Ex mode involving try-catch vim-patch:8.0.0184', function()
local function on_setup()
command('autocmd VimLeavePre * call rpcrequest('..cid..', "")')
command('autocmd VimLeave * call rpcrequest('..cid..', "")')
- feed_command('call feedkey("Q")','try', 'call NoFunction()', 'catch', 'echo "bye"', 'endtry', 'quit')
+ feed('gQ')
+ feed_command('try', 'call NoFunction()', 'catch', 'echo "bye"', 'endtry', 'quit')
end
local function on_request()
eq(0, eval('v:exiting'))
diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua
index 04fbb807be..02ff18bdda 100644
--- a/test/functional/core/job_spec.lua
+++ b/test/functional/core/job_spec.lua
@@ -21,6 +21,7 @@ local nvim_set = helpers.nvim_set
local expect_twostreams = helpers.expect_twostreams
local expect_msg_seq = helpers.expect_msg_seq
local pcall_err = helpers.pcall_err
+local matches = helpers.matches
local Screen = require('test.functional.ui.screen')
describe('jobs', function()
@@ -229,8 +230,8 @@ describe('jobs', function()
local dir = 'Xtest_not_executable_dir'
mkdir(dir)
funcs.setfperm(dir, 'rw-------')
- eq('Vim(call):E475: Invalid argument: expected valid directory',
- pcall_err(nvim, 'command', "call jobstart('pwd', {'cwd': '"..dir.."'})"))
+ matches('^Vim%(call%):E903: Process failed to start: permission denied: .*',
+ pcall_err(nvim, 'command', "call jobstart(['pwd'], {'cwd': '"..dir.."'})"))
rmdir(dir)
end)
@@ -690,8 +691,8 @@ describe('jobs', function()
-- jobstart() shares its v:servername with the child via $NVIM.
eq('NVIM='..addr, get_env_in_child_job('NVIM'))
-- $NVIM_LISTEN_ADDRESS is unset by server_init in the child.
- eq('NVIM_LISTEN_ADDRESS=null', get_env_in_child_job('NVIM_LISTEN_ADDRESS'))
- eq('NVIM_LISTEN_ADDRESS=null', get_env_in_child_job('NVIM_LISTEN_ADDRESS',
+ eq('NVIM_LISTEN_ADDRESS=v:null', get_env_in_child_job('NVIM_LISTEN_ADDRESS'))
+ eq('NVIM_LISTEN_ADDRESS=v:null', get_env_in_child_job('NVIM_LISTEN_ADDRESS',
{ NVIM_LISTEN_ADDRESS='Xtest_jobstart_env' }))
-- User can explicitly set $NVIM_LOG_FILE, $VIM, $VIMRUNTIME.
eq('NVIM_LOG_FILE=Xtest_jobstart_env',
diff --git a/test/functional/editor/K_spec.lua b/test/functional/editor/K_spec.lua
index 8ad81ac3d6..3b5580540f 100644
--- a/test/functional/editor/K_spec.lua
+++ b/test/functional/editor/K_spec.lua
@@ -1,6 +1,6 @@
local helpers = require('test.functional.helpers')(after_each)
-local eq, clear, eval, feed, retry =
- helpers.eq, helpers.clear, helpers.eval, helpers.feed, helpers.retry
+local eq, clear, eval, feed, meths, retry =
+ helpers.eq, helpers.clear, helpers.eval, helpers.feed, helpers.meths, helpers.retry
describe('K', function()
local test_file = 'K_spec_out'
@@ -58,4 +58,11 @@ describe('K', function()
helpers.neq(bufnr, eval('bufnr()'))
end)
+ it('empty string falls back to :help #19298', function()
+ meths.set_option('keywordprg', '')
+ meths.buf_set_lines(0, 0, -1, true, {'doesnotexist'})
+ feed('K')
+ eq('E149: Sorry, no help for doesnotexist', meths.get_vvar('errmsg'))
+ end)
+
end)
diff --git a/test/functional/editor/ctrl_c_spec.lua b/test/functional/editor/ctrl_c_spec.lua
index 60131bf2a4..4548e1aa34 100644
--- a/test/functional/editor/ctrl_c_spec.lua
+++ b/test/functional/editor/ctrl_c_spec.lua
@@ -2,6 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, feed, source = helpers.clear, helpers.feed, helpers.source
local command = helpers.command
+local poke_eventloop = helpers.poke_eventloop
local sleep = helpers.sleep
describe("CTRL-C (mapped)", function()
@@ -57,11 +58,9 @@ describe("CTRL-C (mapped)", function()
it('interrupts :sleep', function()
command('nnoremap <C-C> <Nop>')
feed(':sleep 100<CR>')
- -- wait for :sleep to start
- sleep(10)
+ poke_eventloop() -- wait for :sleep to start
feed('foo<C-C>')
- -- wait for input buffer to be flushed
- sleep(10)
+ poke_eventloop() -- wait for input buffer to be flushed
feed('i')
screen:expect([[
^ |
@@ -77,10 +76,9 @@ describe("CTRL-C (mapped)", function()
command('nnoremap <C-C> <Nop>')
command('nmap <F2> <Ignore><F2>')
feed('<F2>')
- sleep(10)
+ sleep(10) -- wait for the key to enter typeahead
feed('foo<C-C>')
- -- wait for input buffer to be flushed
- sleep(10)
+ poke_eventloop() -- wait for input buffer to be flushed
feed('i')
screen:expect([[
^ |
diff --git a/test/functional/editor/mode_insert_spec.lua b/test/functional/editor/mode_insert_spec.lua
index e3d3cdbd85..cd51a65be3 100644
--- a/test/functional/editor/mode_insert_spec.lua
+++ b/test/functional/editor/mode_insert_spec.lua
@@ -6,12 +6,20 @@ local expect = helpers.expect
local command = helpers.command
local eq = helpers.eq
local eval = helpers.eval
+local curbuf_contents = helpers.curbuf_contents
describe('insert-mode', function()
before_each(function()
clear()
end)
+ it('indents only once after "!" keys #12894', function()
+ command('let counter = []')
+ command('set indentexpr=len(add(counter,0))')
+ feed('i<C-F>x')
+ eq(' x', curbuf_contents())
+ end)
+
it('CTRL-@', function()
-- Inserts last-inserted text, leaves insert-mode.
insert('hello')
diff --git a/test/functional/ex_cmds/normal_spec.lua b/test/functional/ex_cmds/normal_spec.lua
index f6e7dd2b3a..009f1d6516 100644
--- a/test/functional/ex_cmds/normal_spec.lua
+++ b/test/functional/ex_cmds/normal_spec.lua
@@ -1,6 +1,7 @@
local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local command = helpers.command
+local funcs = helpers.funcs
local feed = helpers.feed
local expect = helpers.expect
local eq = helpers.eq
@@ -8,20 +9,30 @@ local eval = helpers.eval
before_each(clear)
-describe(':normal', function()
+describe(':normal!', function()
it('can get out of Insert mode if called from Ex mode #17924', function()
feed('gQnormal! Ifoo<CR>')
expect('foo')
end)
- it('normal! does not execute command in Ex mode when running out of characters', function()
+ it('does not execute command in Ex mode when running out of characters', function()
command('let g:var = 0')
command('normal! gQlet g:var = 1')
eq(0, eval('g:var'))
end)
- it('normal! gQinsert does not hang #17980', function()
+ it('gQinsert does not hang #17980', function()
command('normal! gQinsert')
expect('')
end)
+
+ it('can stop Visual mode without closing cmdwin vim-patch:9.0.0234', function()
+ feed('q:')
+ feed('v')
+ eq('v', funcs.mode(1))
+ eq(':', funcs.getcmdwintype())
+ command('normal! \027')
+ eq('n', funcs.mode(1))
+ eq(':', funcs.getcmdwintype())
+ end)
end)
diff --git a/test/functional/ex_cmds/oldfiles_spec.lua b/test/functional/ex_cmds/oldfiles_spec.lua
index 003ab64dd4..5f87c3cdd9 100644
--- a/test/functional/ex_cmds/oldfiles_spec.lua
+++ b/test/functional/ex_cmds/oldfiles_spec.lua
@@ -29,7 +29,6 @@ describe(':oldfiles', function()
it('shows most recently used files', function()
local screen = Screen.new(100, 5)
screen:attach()
- feed_command("set display-=msgsep")
feed_command('edit testfile1')
feed_command('edit testfile2')
feed_command('wshada')
@@ -37,7 +36,7 @@ describe(':oldfiles', function()
local oldfiles = helpers.meths.get_vvar('oldfiles')
feed_command('oldfiles')
screen:expect([[
- testfile2 |
+ |
1: ]].. add_padding(oldfiles[1]) ..[[ |
2: ]].. add_padding(oldfiles[2]) ..[[ |
|
diff --git a/test/functional/ex_cmds/source_spec.lua b/test/functional/ex_cmds/source_spec.lua
index 13a40fcc53..cd1f43f9fd 100644
--- a/test/functional/ex_cmds/source_spec.lua
+++ b/test/functional/ex_cmds/source_spec.lua
@@ -13,6 +13,10 @@ local exec_lua = helpers.exec_lua
local eval = helpers.eval
local exec_capture = helpers.exec_capture
local neq = helpers.neq
+local matches = helpers.matches
+local iswin = helpers.iswin
+local mkdir = helpers.mkdir
+local rmdir = helpers.rmdir
describe(':source', function()
before_each(function()
@@ -39,6 +43,47 @@ describe(':source', function()
os.remove(test_file)
end)
+ it("changing 'shellslash' changes the result of expand()", function()
+ if not iswin() then
+ pending("'shellslash' only works on Windows")
+ return
+ end
+ meths.set_option('shellslash', false)
+ mkdir('Xshellslash')
+
+ write_file([[Xshellslash/Xstack.vim]], [[
+ let g:stack1 = expand('<stack>')
+ set shellslash
+ let g:stack2 = expand('<stack>')
+ set noshellslash
+ let g:stack3 = expand('<stack>')
+ ]])
+
+ for _ = 1, 2 do
+ command([[source Xshellslash/Xstack.vim]])
+ matches([[Xshellslash\Xstack%.vim]], meths.get_var('stack1'))
+ matches([[Xshellslash/Xstack%.vim]], meths.get_var('stack2'))
+ matches([[Xshellslash\Xstack%.vim]], meths.get_var('stack3'))
+ end
+
+ write_file([[Xshellslash/Xstack.lua]], [[
+ vim.g.stack1 = vim.fn.expand('<stack>')
+ vim.o.shellslash = true
+ vim.g.stack2 = vim.fn.expand('<stack>')
+ vim.o.shellslash = false
+ vim.g.stack3 = vim.fn.expand('<stack>')
+ ]])
+
+ for _ = 1, 2 do
+ command([[source Xshellslash/Xstack.lua]])
+ matches([[Xshellslash\Xstack%.lua]], meths.get_var('stack1'))
+ matches([[Xshellslash/Xstack%.lua]], meths.get_var('stack2'))
+ matches([[Xshellslash\Xstack%.lua]], meths.get_var('stack3'))
+ end
+
+ rmdir('Xshellslash')
+ end)
+
it('current buffer', function()
insert([[
let a = 2
@@ -117,11 +162,20 @@ describe(':source', function()
it('can source lua files', function()
local test_file = 'test.lua'
- write_file (test_file, [[vim.g.sourced_lua = 1]])
-
- exec('source ' .. test_file)
+ write_file(test_file, [[
+ vim.g.sourced_lua = 1
+ vim.g.sfile_value = vim.fn.expand('<sfile>')
+ vim.g.stack_value = vim.fn.expand('<stack>')
+ vim.g.script_value = vim.fn.expand('<script>')
+ ]])
+ command('set shellslash')
+ command('source ' .. test_file)
eq(1, eval('g:sourced_lua'))
+ matches([[/test%.lua$]], meths.get_var('sfile_value'))
+ matches([[/test%.lua$]], meths.get_var('stack_value'))
+ matches([[/test%.lua$]], meths.get_var('script_value'))
+
os.remove(test_file)
end)
@@ -153,13 +207,16 @@ describe(':source', function()
it('can source current lua buffer without argument', function()
local test_file = 'test.lua'
- write_file (test_file, [[
+ write_file(test_file, [[
vim.g.c = 10
vim.g.c = 11
vim.g.c = 12
a = [=[
\ 1
"\ 2]=]
+ vim.g.sfile_value = vim.fn.expand('<sfile>')
+ vim.g.stack_value = vim.fn.expand('<stack>')
+ vim.g.script_value = vim.fn.expand('<script>')
]])
command('edit '..test_file)
@@ -167,6 +224,10 @@ describe(':source', function()
eq(12, eval('g:c'))
eq(' \\ 1\n "\\ 2', exec_lua('return _G.a'))
+ eq(':source (no file)', meths.get_var('sfile_value'))
+ eq(':source (no file)', meths.get_var('stack_value'))
+ eq(':source (no file)', meths.get_var('script_value'))
+
os.remove(test_file)
end)
diff --git a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua
index 4d984af41e..69404039ff 100644
--- a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua
+++ b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua
@@ -1,8 +1,8 @@
local Screen = require('test.functional.ui.screen')
local helpers = require('test.functional.helpers')(after_each)
local lfs = require('lfs')
-local eq, eval, expect, source =
- helpers.eq, helpers.eval, helpers.expect, helpers.source
+local eq, eval, expect, exec =
+ helpers.eq, helpers.eval, helpers.expect, helpers.exec
local assert_alive = helpers.assert_alive
local clear = helpers.clear
local command = helpers.command
@@ -10,6 +10,8 @@ local feed = helpers.feed
local nvim_prog = helpers.nvim_prog
local ok = helpers.ok
local rmdir = helpers.rmdir
+local new_argv = helpers.new_argv
+local pesc = helpers.pesc
local os_kill = helpers.os_kill
local set_session = helpers.set_session
local spawn = helpers.spawn
@@ -55,11 +57,11 @@ describe(':preserve', function()
set swapfile fileformat=unix undolevels=-1
]]
- source(init)
+ exec(init)
command('edit! '..testfile)
feed('isometext<esc>')
command('preserve')
- source('redir => g:swapname | silent swapname | redir END')
+ exec('redir => g:swapname | silent swapname | redir END')
local swappath1 = eval('g:swapname')
@@ -69,12 +71,12 @@ describe(':preserve', function()
true)
set_session(nvim2)
- source(init)
+ exec(init)
-- Use the "SwapExists" event to choose the (R)ecover choice at the dialog.
command('autocmd SwapExists * let v:swapchoice = "r"')
command('silent edit! '..testfile)
- source('redir => g:swapname | silent swapname | redir END')
+ exec('redir => g:swapname | silent swapname | redir END')
local swappath2 = eval('g:swapname')
@@ -92,25 +94,28 @@ end)
describe('swapfile detection', function()
local swapdir = lfs.currentdir()..'/Xtest_swapdialog_dir'
+ local nvim0
+ -- Put swapdir at the start of the 'directory' list. #1836
+ -- Note: `set swapfile` *must* go after `set directory`: otherwise it may
+ -- attempt to create a swapfile in different directory.
+ local init = [[
+ set directory^=]]..swapdir:gsub([[\]], [[\\]])..[[//
+ set swapfile fileformat=unix undolevels=-1 hidden
+ ]]
before_each(function()
- clear()
+ nvim0 = spawn(new_argv())
+ set_session(nvim0)
rmdir(swapdir)
lfs.mkdir(swapdir)
end)
after_each(function()
+ set_session(nvim0)
command('%bwipeout!')
rmdir(swapdir)
end)
it('always show swapfile dialog #8840 #9027', function()
local testfile = 'Xtest_swapdialog_file1'
- -- Put swapdir at the start of the 'directory' list. #1836
- -- Note: `set swapfile` *must* go after `set directory`: otherwise it may
- -- attempt to create a swapfile in different directory.
- local init = [[
- set directory^=]]..swapdir:gsub([[\]], [[\\]])..[[//
- set swapfile fileformat=unix undolevels=-1 hidden
- ]]
local expected_no_dialog = '^'..(' '):rep(256)..'|\n'
for _=1,37 do
@@ -119,19 +124,17 @@ describe('swapfile detection', function()
expected_no_dialog = expected_no_dialog..testfile..(' '):rep(216)..'0,0-1 All|\n'
expected_no_dialog = expected_no_dialog..(' '):rep(256)..'|\n'
- source(init)
+ exec(init)
command('edit! '..testfile)
feed('isometext<esc>')
command('preserve')
- os_kill(eval('getpid()'))
-- Start another Nvim instance.
- local nvim2 = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed'},
- true)
+ local nvim2 = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed'}, true, nil, true)
set_session(nvim2)
local screen2 = Screen.new(256, 40)
screen2:attach()
- source(init)
+ exec(init)
-- With shortmess+=F
command('set shortmess+=F')
@@ -176,5 +179,88 @@ describe('swapfile detection', function()
}
})
feed('<cr>')
+
+ nvim2:close()
+ end)
+
+ -- oldtest: Test_swap_prompt_splitwin()
+ it('selecting "q" in the attention prompt', function()
+ exec(init)
+ command('edit Xfile1')
+ command('preserve') -- should help to make sure the swap file exists
+
+ local screen = Screen.new(75, 18)
+ screen:set_default_attr_ids({
+ [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
+ [1] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg
+ })
+
+ local nvim1 = spawn(new_argv(), true, nil, true)
+ set_session(nvim1)
+ screen:attach()
+ exec(init)
+ feed(':split Xfile1\n')
+ screen:expect({
+ any = pesc('{1:[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: }^')
+ })
+ feed('q')
+ feed(':<CR>')
+ screen:expect([[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ : |
+ ]])
+ nvim1:close()
+
+ local nvim2 = spawn(new_argv(), true, nil, true)
+ set_session(nvim2)
+ screen:attach()
+ exec(init)
+ command('set more')
+ command('au bufadd * let foo_w = wincol()')
+ feed(':e Xfile1<CR>')
+ screen:expect({any = pesc('{1:-- More --}^')})
+ feed('<Space>')
+ screen:expect({
+ any = pesc('{1:[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: }^')
+ })
+ feed('q')
+ command([[echo 'hello']])
+ screen:expect([[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ hello |
+ ]])
+ nvim2:close()
end)
end)
diff --git a/test/functional/ex_cmds/wincmd_spec.lua b/test/functional/ex_cmds/wincmd_spec.lua
new file mode 100644
index 0000000000..b1f174f445
--- /dev/null
+++ b/test/functional/ex_cmds/wincmd_spec.lua
@@ -0,0 +1,13 @@
+local helpers = require("test.functional.helpers")(after_each)
+local clear = helpers.clear
+local eq = helpers.eq
+local funcs = helpers.funcs
+local command = helpers.command
+
+it(':wincmd accepts a count', function()
+ clear()
+ command('vsplit')
+ eq(1, funcs.winnr())
+ command('wincmd 2 w')
+ eq(2, funcs.winnr())
+end)
diff --git a/test/functional/fixtures/compdir/file1 b/test/functional/fixtures/wildpum/Xdir/XdirA/XdirB/XfileC
index e69de29bb2..e69de29bb2 100644
--- a/test/functional/fixtures/compdir/file1
+++ b/test/functional/fixtures/wildpum/Xdir/XdirA/XdirB/XfileC
diff --git a/test/functional/fixtures/compdir/file2 b/test/functional/fixtures/wildpum/Xdir/XdirA/XfileB
index e69de29bb2..e69de29bb2 100644
--- a/test/functional/fixtures/compdir/file2
+++ b/test/functional/fixtures/wildpum/Xdir/XdirA/XfileB
diff --git a/test/functional/fixtures/wildpum/Xdir/XfileA b/test/functional/fixtures/wildpum/Xdir/XfileA
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/functional/fixtures/wildpum/Xdir/XfileA
diff --git a/test/functional/fixtures/wildpum/compdir/file1 b/test/functional/fixtures/wildpum/compdir/file1
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/functional/fixtures/wildpum/compdir/file1
diff --git a/test/functional/fixtures/wildpum/compdir/file2 b/test/functional/fixtures/wildpum/compdir/file2
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/functional/fixtures/wildpum/compdir/file2
diff --git a/test/functional/fixtures/wildpum/あいう/123 b/test/functional/fixtures/wildpum/あいう/123
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/functional/fixtures/wildpum/あいう/123
diff --git a/test/functional/fixtures/wildpum/あいう/abc b/test/functional/fixtures/wildpum/あいう/abc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/functional/fixtures/wildpum/あいう/abc
diff --git a/test/functional/fixtures/wildpum/あいう/xyz b/test/functional/fixtures/wildpum/あいう/xyz
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/functional/fixtures/wildpum/あいう/xyz
diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua
index 8c5a60657a..93fb0f245e 100644
--- a/test/functional/helpers.lua
+++ b/test/functional/helpers.lua
@@ -244,10 +244,12 @@ function module.run_session(lsession, request_cb, notification_cb, setup_cb, tim
last_error = nil
error(err)
end
+
+ return session.eof_err
end
function module.run(request_cb, notification_cb, setup_cb, timeout)
- module.run_session(session, request_cb, notification_cb, setup_cb, timeout)
+ return module.run_session(session, request_cb, notification_cb, setup_cb, timeout)
end
function module.stop()
@@ -759,6 +761,7 @@ function module.pending_c_parser(pending_fn)
pending_fn 'no C parser, skipping'
return true
end
+ module.exec_lua [[vim._ts_remove_language 'c']]
return false
end
diff --git a/test/functional/legacy/arglist_spec.lua b/test/functional/legacy/arglist_spec.lua
index f90da16d7b..4d9e88c446 100644
--- a/test/functional/legacy/arglist_spec.lua
+++ b/test/functional/legacy/arglist_spec.lua
@@ -276,6 +276,6 @@ describe('argument list commands', function()
2 more files to edit. Quit anyway? |
[Y]es, (N)o: ^ |
]])
- expect_exit(100, feed, 'Y')
+ expect_exit(1000, feed, 'Y')
end)
end)
diff --git a/test/functional/legacy/buffer_spec.lua b/test/functional/legacy/buffer_spec.lua
new file mode 100644
index 0000000000..acaa9a51f1
--- /dev/null
+++ b/test/functional/legacy/buffer_spec.lua
@@ -0,0 +1,59 @@
+local helpers = require('test.functional.helpers')(after_each)
+local clear, source = helpers.clear, helpers.source
+local call, eq, meths = helpers.call, helpers.eq, helpers.meths
+
+local function expected_empty()
+ eq({}, meths.get_vvar('errors'))
+end
+
+describe('buffer', function()
+ before_each(function()
+ clear()
+ meths.ui_attach(80, 24, {})
+ meths.set_option('hidden', false)
+ end)
+
+ it('deleting a modified buffer with :confirm', function()
+ source([[
+ func Test_bdel_with_confirm()
+ new
+ call setline(1, 'test')
+ call assert_fails('bdel', 'E89:')
+ call nvim_input('c')
+ confirm bdel
+ call assert_equal(2, winnr('$'))
+ call assert_equal(1, &modified)
+ call nvim_input('n')
+ confirm bdel
+ call assert_equal(1, winnr('$'))
+ endfunc
+ ]])
+ call('Test_bdel_with_confirm')
+ expected_empty()
+ end)
+
+ it('editing another buffer from a modified buffer with :confirm', function()
+ source([[
+ func Test_goto_buf_with_confirm()
+ new Xfile
+ enew
+ call setline(1, 'test')
+ call assert_fails('b Xfile', 'E37:')
+ call nvim_input('c')
+ call assert_fails('confirm b Xfile', 'E37:')
+ call assert_equal(1, &modified)
+ call assert_equal('', @%)
+ call nvim_input('y')
+ call assert_fails('confirm b Xfile', 'E37:')
+ call assert_equal(1, &modified)
+ call assert_equal('', @%)
+ call nvim_input('n')
+ confirm b Xfile
+ call assert_equal('Xfile', @%)
+ close!
+ endfunc
+ ]])
+ call('Test_goto_buf_with_confirm')
+ expected_empty()
+ end)
+end)
diff --git a/test/functional/legacy/cmdline_spec.lua b/test/functional/legacy/cmdline_spec.lua
index cf02636890..99d2d0f30e 100644
--- a/test/functional/legacy/cmdline_spec.lua
+++ b/test/functional/legacy/cmdline_spec.lua
@@ -1,9 +1,11 @@
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
+local command = helpers.command
local feed = helpers.feed
local feed_command = helpers.feed_command
local exec = helpers.exec
+local pesc = helpers.pesc
describe('cmdline', function()
before_each(clear)
@@ -18,8 +20,6 @@ describe('cmdline', function()
[3] = {reverse = true};
[4] = {bold = true, foreground = Screen.colors.Blue1};
}
- -- TODO(bfredl): redraw with tabs is severly broken. fix it
- feed_command [[ set display-=msgsep ]]
feed_command([[call setline(1, range(30))]])
screen:expect([[
@@ -60,7 +60,7 @@ describe('cmdline', function()
{4:~ }|
|
|
- :tabnew |
+ |
]]}
feed [[gt]]
@@ -141,3 +141,81 @@ describe('cmdline', function()
]])
end)
end)
+
+describe('cmdwin', function()
+ before_each(clear)
+
+ -- oldtest: Test_cmdwin_interrupted()
+ it('still uses a new buffer when interrupting more prompt on open', function()
+ local screen = Screen.new(30, 16)
+ screen:set_default_attr_ids({
+ [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
+ [1] = {bold = true, reverse = true}, -- StatusLine
+ [2] = {reverse = true}, -- StatusLineNC
+ [3] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg
+ [4] = {bold = true}, -- ModeMsg
+ })
+ screen:attach()
+ command('set more')
+ command('autocmd WinNew * highlight')
+ feed('q:')
+ screen:expect({any = pesc('{3:-- More --}^')})
+ feed('q')
+ screen:expect([[
+ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:[No Name] }|
+ {0::}^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {1:[Command Line] }|
+ |
+ ]])
+ feed([[aecho 'done']])
+ screen:expect([[
+ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2:[No Name] }|
+ {0::}echo 'done'^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {1:[Command Line] }|
+ {4:-- INSERT --} |
+ ]])
+ feed('<CR>')
+ screen:expect([[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ done |
+ ]])
+ end)
+end)
diff --git a/test/functional/legacy/ex_mode_spec.lua b/test/functional/legacy/ex_mode_spec.lua
index a8f54c6939..f21c47e175 100644
--- a/test/functional/legacy/ex_mode_spec.lua
+++ b/test/functional/legacy/ex_mode_spec.lua
@@ -6,7 +6,7 @@ local eq = helpers.eq
local eval = helpers.eval
local feed = helpers.feed
local meths = helpers.meths
-local sleep = helpers.sleep
+local poke_eventloop = helpers.poke_eventloop
before_each(clear)
@@ -143,7 +143,7 @@ describe('Ex mode', function()
^ |
]])
feed('<C-C>')
- sleep(10) -- Wait for input to be flushed
+ poke_eventloop() -- Wait for input to be flushed
feed('foo<CR>')
screen:expect([[
Entering Ex mode. Type "visual" to go to Normal mode. |
diff --git a/test/functional/legacy/excmd_spec.lua b/test/functional/legacy/excmd_spec.lua
index 65957d85de..ece88d26bd 100644
--- a/test/functional/legacy/excmd_spec.lua
+++ b/test/functional/legacy/excmd_spec.lua
@@ -94,7 +94,7 @@ describe(':confirm command dialog', function()
{3:Save changes to "Xbar"?} |
{3:[Y]es, (N)o, Save (A)ll, (D)iscard All, (C)ancel: }^ |
]])
- expect_exit(100, feed, 'A')
+ expect_exit(1000, feed, 'A')
eq('foo2\n', read_file('Xfoo'))
eq('bar2\n', read_file('Xbar'))
@@ -132,7 +132,7 @@ describe(':confirm command dialog', function()
{3:Save changes to "Xbar"?} |
{3:[Y]es, (N)o, Save (A)ll, (D)iscard All, (C)ancel: }^ |
]])
- expect_exit(100, feed, 'D')
+ expect_exit(1000, feed, 'D')
eq('foo2\n', read_file('Xfoo'))
eq('bar2\n', read_file('Xbar'))
@@ -193,7 +193,7 @@ describe(':confirm command dialog', function()
{3:Save changes to "Xfoo"?} |
{3:[Y]es, (N)o, (C)ancel: }^ |
]])
- expect_exit(100, feed, 'Y')
+ expect_exit(1000, feed, 'Y')
eq('foo4\n', read_file('Xfoo'))
eq('bar2\n', read_file('Xbar'))
diff --git a/test/functional/legacy/filechanged_spec.lua b/test/functional/legacy/filechanged_spec.lua
index ecb861098c..1f23528d61 100644
--- a/test/functional/legacy/filechanged_spec.lua
+++ b/test/functional/legacy/filechanged_spec.lua
@@ -67,6 +67,15 @@ describe('file changed dialog', function()
call assert_equal(1, line('$'))
call assert_equal('new line', getline(1))
+ " File created after starting to edit it
+ call delete('Xchanged_d')
+ new Xchanged_d
+ call writefile(['one'], 'Xchanged_d')
+ call nvim_input('L')
+ checktime Xchanged_d
+ call assert_equal(['one'], getline(1, '$'))
+ close!
+
bwipe!
call delete('Xchanged_d')
endfunc
diff --git a/test/functional/legacy/gf_spec.lua b/test/functional/legacy/gf_spec.lua
new file mode 100644
index 0000000000..f1b1790ba1
--- /dev/null
+++ b/test/functional/legacy/gf_spec.lua
@@ -0,0 +1,15 @@
+local helpers = require('test.functional.helpers')(after_each)
+local clear = helpers.clear
+local command = helpers.command
+local eq = helpers.eq
+local pcall_err = helpers.pcall_err
+
+describe('gf', function()
+ before_each(clear)
+
+ it('is not allowed when buffer is locked', function()
+ command('au OptionSet diff norm! gf')
+ command([[call setline(1, ['Xfile1', 'line2', 'line3', 'line4'])]])
+ eq('Vim(normal):E788: Not allowed to edit another buffer now', pcall_err(command, 'diffthis'))
+ end)
+end)
diff --git a/test/functional/legacy/global_spec.lua b/test/functional/legacy/global_spec.lua
index 9f4528530c..ff02c41e6c 100644
--- a/test/functional/legacy/global_spec.lua
+++ b/test/functional/legacy/global_spec.lua
@@ -3,7 +3,7 @@ local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
local exec = helpers.exec
local feed = helpers.feed
-local sleep = helpers.sleep
+local poke_eventloop = helpers.poke_eventloop
before_each(clear)
@@ -24,7 +24,7 @@ describe(':global', function()
]])
feed(':g/foo/norm :<C-V>;<CR>')
- sleep(10) -- Wait for :sleep to start
+ poke_eventloop() -- Wait for :sleep to start
feed('<C-C>')
screen:expect([[
^foo |
@@ -37,7 +37,7 @@ describe(':global', function()
-- Also test in Ex mode
feed('gQg/foo/norm :<C-V>;<CR>')
- sleep(10) -- Wait for :sleep to start
+ poke_eventloop() -- Wait for :sleep to start
feed('<C-C>')
screen:expect([[
{0: }|
diff --git a/test/functional/legacy/mapping_spec.lua b/test/functional/legacy/mapping_spec.lua
index 456acc12b5..c1f23ab0a6 100644
--- a/test/functional/legacy/mapping_spec.lua
+++ b/test/functional/legacy/mapping_spec.lua
@@ -131,11 +131,11 @@ describe('mapping', function()
command('set selectmode=mouse')
command('nnoremap <LeftDrag> <LeftDrag><Cmd><CR>')
- sleep(10)
+ poke_eventloop()
meths.input_mouse('left', 'press', '', 0, 0, 0)
- sleep(10)
+ poke_eventloop()
meths.input_mouse('left', 'drag', '', 0, 0, 1)
- sleep(10)
+ poke_eventloop()
eq('s', eval('mode()'))
end)
@@ -144,22 +144,22 @@ describe('mapping', function()
command('inoremap <LeftDrag> <LeftDrag><Cmd>let g:dragged = 1<CR>')
feed('i')
- sleep(10)
+ poke_eventloop()
meths.input_mouse('left', 'press', '', 0, 0, 0)
- sleep(10)
+ poke_eventloop()
meths.input_mouse('left', 'drag', '', 0, 0, 1)
- sleep(10)
+ poke_eventloop()
eq(1, eval('g:dragged'))
eq('v', eval('mode()'))
feed([[<C-\><C-N>]])
command([[inoremap <LeftDrag> <LeftDrag><C-\><C-N>]])
feed('i')
- sleep(10)
+ poke_eventloop()
meths.input_mouse('left', 'press', '', 0, 0, 0)
- sleep(10)
+ poke_eventloop()
meths.input_mouse('left', 'drag', '', 0, 0, 1)
- sleep(10)
+ poke_eventloop()
eq('n', eval('mode()'))
end)
diff --git a/test/functional/legacy/messages_spec.lua b/test/functional/legacy/messages_spec.lua
index 51c2406933..159cf7a551 100644
--- a/test/functional/legacy/messages_spec.lua
+++ b/test/functional/legacy/messages_spec.lua
@@ -337,6 +337,95 @@ describe('messages', function()
end)
end)
+ describe('mode is cleared when', function()
+ before_each(function()
+ screen = Screen.new(40, 6)
+ screen:set_default_attr_ids({
+ [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
+ [2] = {bold = true}, -- ModeMsg
+ [3] = {bold = true, reverse=true}, -- StatusLine
+ })
+ screen:attach()
+ end)
+
+ -- oldtest: Test_mode_message_at_leaving_insert_by_ctrl_c()
+ it('leaving Insert mode with Ctrl-C vim-patch:8.1.1189', function()
+ exec([[
+ func StatusLine() abort
+ return ""
+ endfunc
+ set statusline=%!StatusLine()
+ set laststatus=2
+ ]])
+ feed('i')
+ screen:expect([[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {3: }|
+ {2:-- INSERT --} |
+ ]])
+ feed('<C-C>')
+ screen:expect([[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {3: }|
+ |
+ ]])
+ end)
+
+ -- oldtest: Test_mode_message_at_leaving_insert_with_esc_mapped()
+ it('leaving Insert mode with ESC in the middle of a mapping vim-patch:8.1.1192', function()
+ exec([[
+ set laststatus=2
+ inoremap <Esc> <Esc>00
+ ]])
+ feed('i')
+ screen:expect([[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {3:[No Name] }|
+ {2:-- INSERT --} |
+ ]])
+ feed('<Esc>')
+ screen:expect([[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {3:[No Name] }|
+ |
+ ]])
+ end)
+
+ -- oldtest: Test_mode_updated_after_ctrl_c()
+ it('pressing Ctrl-C in i_CTRL-O', function()
+ feed('i<C-O>')
+ screen:expect([[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {2:-- (insert) --} |
+ ]])
+ feed('<C-C>')
+ screen:expect([[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]])
+ end)
+ end)
+
-- oldtest: Test_ask_yesno()
it('y/n prompt works', function()
screen = Screen.new(75, 6)
diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua
index f9647f5b6a..4226bcebac 100644
--- a/test/functional/lua/diagnostic_spec.lua
+++ b/test/functional/lua/diagnostic_spec.lua
@@ -128,6 +128,28 @@ describe('vim.diagnostic', function()
eq('Diagnostic #1', result[1].message)
end)
+ it('removes diagnostics from the cache when a buffer is removed', function()
+ eq(2, exec_lua [[
+ vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
+ local other_bufnr = vim.fn.bufadd('test | test')
+ local lines = vim.api.nvim_buf_get_lines(diagnostic_bufnr, 0, -1, true)
+ vim.api.nvim_buf_set_lines(other_bufnr, 0, 1, false, lines)
+ vim.cmd('bunload! ' .. other_bufnr)
+
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
+ make_error('Diagnostic #1', 1, 1, 1, 1),
+ make_error('Diagnostic #2', 2, 1, 2, 1),
+ })
+ vim.diagnostic.set(diagnostic_ns, other_bufnr, {
+ make_error('Diagnostic #3', 3, 1, 3, 1),
+ })
+ vim.api.nvim_set_current_buf(other_bufnr)
+ vim.opt_local.buflisted = true
+ vim.cmd('bwipeout!')
+ return #vim.diagnostic.get()
+ ]])
+ end)
+
it('resolves buffer number 0 to the current buffer', function()
eq(2, exec_lua [[
vim.api.nvim_set_current_buf(diagnostic_bufnr)
diff --git a/test/functional/lua/luaeval_spec.lua b/test/functional/lua/luaeval_spec.lua
index 1322155595..9f313eab9e 100644
--- a/test/functional/lua/luaeval_spec.lua
+++ b/test/functional/lua/luaeval_spec.lua
@@ -467,7 +467,6 @@ describe('v:lua', function()
end
end
end
- vim.api.nvim_buf_set_option(0, 'omnifunc', 'v:lua.mymod.omni')
]])
end)
@@ -515,6 +514,7 @@ describe('v:lua', function()
[5] = {bold = true, foreground = Screen.colors.SeaGreen4},
})
screen:attach()
+ meths.buf_set_option(0, 'omnifunc', 'v:lua.mymod.omni')
feed('isome st<c-x><c-o>')
screen:expect{grid=[[
some stuff^ |
@@ -526,6 +526,9 @@ describe('v:lua', function()
{1:~ }|
{4:-- Omni completion (^O^N^P) }{5:match 1 of 3} |
]]}
+ meths.set_option('operatorfunc', 'v:lua.mymod.noisy')
+ feed('<Esc>g@g@')
+ eq("hey line", meths.get_current_line())
end)
it('supports packages', function()
diff --git a/test/functional/lua/overrides_spec.lua b/test/functional/lua/overrides_spec.lua
index 9b51af1eec..32c1615a45 100644
--- a/test/functional/lua/overrides_spec.lua
+++ b/test/functional/lua/overrides_spec.lua
@@ -144,13 +144,14 @@ describe('debug.debug', function()
before_each(function()
screen = Screen.new()
screen:attach()
- screen:set_default_attr_ids({
- [0] = {bold=true, foreground=255},
- E = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
- cr = {bold = true, foreground = Screen.colors.SeaGreen4},
- })
- command("set display-=msgsep")
+ screen:set_default_attr_ids {
+ [0] = {bold=true, foreground=255};
+ [1] = {bold = true, reverse = true};
+ E = {foreground = Screen.colors.Grey100, background = Screen.colors.Red};
+ cr = {bold = true, foreground = Screen.colors.SeaGreen4};
+ }
end)
+
it('works', function()
command([[lua
function Test(a)
@@ -160,9 +161,8 @@ describe('debug.debug', function()
end
]])
feed(':lua Test()\n')
- screen:expect([[
- {0:~ }|
- {0:~ }|
+ screen:expect{grid=[[
+ |
{0:~ }|
{0:~ }|
{0:~ }|
@@ -173,11 +173,13 @@ describe('debug.debug', function()
{0:~ }|
{0:~ }|
{0:~ }|
+ {1: }|
nil |
lua_debug> ^ |
- ]])
+ ]]}
feed('print("TEST")\n')
screen:expect([[
+ |
{0:~ }|
{0:~ }|
{0:~ }|
@@ -186,8 +188,7 @@ describe('debug.debug', function()
{0:~ }|
{0:~ }|
{0:~ }|
- {0:~ }|
- {0:~ }|
+ {1: }|
nil |
lua_debug> print("TEST") |
TEST |
@@ -195,10 +196,10 @@ describe('debug.debug', function()
]])
feed('<C-c>')
screen:expect{grid=[[
+ |
{0:~ }|
{0:~ }|
- {0:~ }|
- {0:~ }|
+ {1: }|
nil |
lua_debug> print("TEST") |
TEST |
@@ -212,6 +213,7 @@ describe('debug.debug', function()
]]}
feed('<C-l>:lua Test()\n')
screen:expect([[
+ |
{0:~ }|
{0:~ }|
{0:~ }|
@@ -222,19 +224,18 @@ describe('debug.debug', function()
{0:~ }|
{0:~ }|
{0:~ }|
- {0:~ }|
- {0:~ }|
+ {1: }|
nil |
lua_debug> ^ |
]])
feed('\n')
screen:expect{grid=[[
+ |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
- {0:~ }|
- {0:~ }|
+ {1: }|
nil |
lua_debug> |
{E:E5108: Error executing lua [string ":lua"]:5: attempt}|
@@ -268,6 +269,7 @@ describe('debug.debug', function()
feed("conttt<cr>") -- misspelled cont; invalid syntax
screen:expect{grid=[[
+ |
{0:~ }|
{0:~ }|
{0:~ }|
@@ -276,8 +278,7 @@ describe('debug.debug', function()
{0:~ }|
{0:~ }|
{0:~ }|
- {0:~ }|
- {0:~ }|
+ {1: }|
lua_debug> conttt |
{E:E5115: Error while loading debug string: (debug comma}|
{E:nd):1: '=' expected near '<eof>'} |
@@ -286,14 +287,14 @@ describe('debug.debug', function()
feed("cont<cr>") -- exactly "cont", exit now
screen:expect{grid=[[
+ |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
- {0:~ }|
- {0:~ }|
+ {1: }|
lua_debug> conttt |
{E:E5115: Error while loading debug string: (debug comma}|
{E:nd):1: '=' expected near '<eof>'} |
diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua
index 2b249b7a69..f2fb661b70 100644
--- a/test/functional/lua/vim_spec.lua
+++ b/test/functional/lua/vim_spec.lua
@@ -2721,6 +2721,39 @@ describe('lua stdlib', function()
]]
end)
end)
+
+ describe('vim.iconv', function()
+ it('can convert strings', function()
+ eq('hello', exec_lua[[
+ return vim.iconv('hello', 'latin1', 'utf-8')
+ ]])
+ end)
+
+ it('can validate arguments', function()
+ eq({false, 'Expected at least 3 arguments'}, exec_lua[[
+ return {pcall(vim.iconv, 'hello')}
+ ]])
+
+ eq({false, 'bad argument #3 to \'?\' (expected string)'}, exec_lua[[
+ return {pcall(vim.iconv, 'hello', 'utf-8', true)}
+ ]])
+ end)
+
+ it('can handle bad encodings', function()
+ eq(NIL, exec_lua[[
+ return vim.iconv('hello', 'foo', 'bar')
+ ]])
+ end)
+
+ it('can handle strings with NUL bytes', function()
+ eq(7, exec_lua[[
+ local a = string.char(97, 98, 99, 0, 100, 101, 102) -- abc\0def
+ return string.len(vim.iconv(a, 'latin1', 'utf-8'))
+ ]])
+ end)
+
+ end)
+
end)
describe('lua: builtin modules', function()
diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua
index 9244ca0974..4e2f2ab63e 100644
--- a/test/functional/options/defaults_spec.lua
+++ b/test/functional/options/defaults_spec.lua
@@ -161,6 +161,36 @@ describe('startup defaults', function()
~ |~ |
|
]])
+
+ -- change "vert" character to single-cell
+ funcs.setcellwidths({{0x2502, 0x2502, 1}})
+ screen:expect([[
+ 1 │1 |
+ ^+-- 2 lines: 2----------│+-- 2 lines: 2---------|
+ 4 │4 |
+ ~ │~ |
+ |
+ ]])
+
+ -- change "vert" character to double-cell
+ funcs.setcellwidths({{0x2502, 0x2502, 2}})
+ screen:expect([[
+ 1 |1 |
+ ^+-- 2 lines: 2----------|+-- 2 lines: 2---------|
+ 4 |4 |
+ ~ |~ |
+ |
+ ]])
+
+ -- "vert" character should still default to single-byte fillchars because of setcellwidths().
+ command('set ambiwidth=single')
+ screen:expect([[
+ 1 |1 |
+ ^+-- 2 lines: 2··········|+-- 2 lines: 2·········|
+ 4 |4 |
+ ~ |~ |
+ |
+ ]])
end)
end)
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua
index cd7415de90..fa731f6faf 100644
--- a/test/functional/plugin/lsp_spec.lua
+++ b/test/functional/plugin/lsp_spec.lua
@@ -3181,4 +3181,32 @@ describe('LSP', function()
}
end)
end)
+
+ describe('cmd', function()
+ it('can connect to lsp server via rpc.connect', function()
+ local result = exec_lua [[
+ local uv = vim.loop
+ local server = uv.new_tcp()
+ local init = nil
+ server:bind('127.0.0.1', 0)
+ server:listen(127, function(err)
+ assert(not err, err)
+ local socket = uv.new_tcp()
+ server:accept(socket)
+ socket:read_start(require('vim.lsp.rpc').create_read_loop(function(body)
+ init = body
+ socket:close()
+ end))
+ end)
+ local port = server:getsockname().port
+ vim.lsp.start({ name = 'dummy', cmd = vim.lsp.rpc.connect('127.0.0.1', port) })
+ vim.wait(1000, function() return init ~= nil end)
+ assert(init, "server must receive `initialize` request")
+ server:close()
+ server:shutdown()
+ return vim.json.decode(init)
+ ]]
+ eq(result.method, "initialize")
+ end)
+ end)
end)
diff --git a/test/functional/plugin/man_spec.lua b/test/functional/plugin/man_spec.lua
index c8da5a711f..9304aa6da9 100644
--- a/test/functional/plugin/man_spec.lua
+++ b/test/functional/plugin/man_spec.lua
@@ -6,6 +6,12 @@ local funcs = helpers.funcs
local nvim_prog = helpers.nvim_prog
local matches = helpers.matches
+clear()
+if funcs.executable('man') == 0 then
+ pending('missing "man" command', function() end)
+ return
+end
+
describe(':Man', function()
before_each(function()
clear()
diff --git a/test/functional/provider/clipboard_spec.lua b/test/functional/provider/clipboard_spec.lua
index 5bdfec574e..fbaef3ae00 100644
--- a/test/functional/provider/clipboard_spec.lua
+++ b/test/functional/provider/clipboard_spec.lua
@@ -96,9 +96,9 @@ describe('clipboard', function()
[0] = {bold = true, foreground = Screen.colors.Blue},
[1] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
[2] = {bold = true, foreground = Screen.colors.SeaGreen4},
+ [3] = {bold = true, reverse = true};
})
screen:attach()
- command("set display-=msgsep")
end)
it('unnamed register works without provider', function()
@@ -123,10 +123,10 @@ describe('clipboard', function()
command("let g:clipboard = 'bogus'")
feed_command('redir @+> | bogus_cmd | redir END')
screen:expect{grid=[[
- {0:~ }|
- clipboard: No provider. Try ":checkhealth" or ":h clipboard". |
- {1:E492: Not an editor command: bogus_cmd | redir END} |
- {2:Press ENTER or type command to continue}^ |
+ {3: }|
+ clipboard: No provider. Try ":checkhealth" or ":h clipboard". |
+ {1:E492: Not an editor command: bogus_cmd | redir END} |
+ {2:Press ENTER or type command to continue}^ |
]]}
end)
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index eee759d2be..4f444316c3 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -297,6 +297,199 @@ describe('TUI', function()
]], attrs)
end)
+ it('accepts mouse wheel events #19992', function()
+ child_session:request('nvim_command', [[
+ set number nostartofline nowrap mousescroll=hor:1,ver:1
+ call setline(1, repeat([join(range(10), '----')], 10))
+ vsplit
+ ]])
+ screen:expect([[
+ {11: 1 }{1:0}----1----2----3----4│{11: 1 }0----1----2----3----|
+ {11: 2 }0----1----2----3----4│{11: 2 }0----1----2----3----|
+ {11: 3 }0----1----2----3----4│{11: 3 }0----1----2----3----|
+ {11: 4 }0----1----2----3----4│{11: 4 }0----1----2----3----|
+ {5:[No Name] [+] }{1:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ -- <ScrollWheelDown> in active window
+ feed_data('\027[<65;8;1M')
+ screen:expect([[
+ {11: 2 }{1:0}----1----2----3----4│{11: 1 }0----1----2----3----|
+ {11: 3 }0----1----2----3----4│{11: 2 }0----1----2----3----|
+ {11: 4 }0----1----2----3----4│{11: 3 }0----1----2----3----|
+ {11: 5 }0----1----2----3----4│{11: 4 }0----1----2----3----|
+ {5:[No Name] [+] }{1:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ -- <ScrollWheelDown> in inactive window
+ feed_data('\027[<65;48;1M')
+ screen:expect([[
+ {11: 2 }{1:0}----1----2----3----4│{11: 2 }0----1----2----3----|
+ {11: 3 }0----1----2----3----4│{11: 3 }0----1----2----3----|
+ {11: 4 }0----1----2----3----4│{11: 4 }0----1----2----3----|
+ {11: 5 }0----1----2----3----4│{11: 5 }0----1----2----3----|
+ {5:[No Name] [+] }{1:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ -- <ScrollWheelRight> in active window
+ feed_data('\027[<67;8;1M')
+ screen:expect([[
+ {11: 2 }{1:-}---1----2----3----4-│{11: 2 }0----1----2----3----|
+ {11: 3 }----1----2----3----4-│{11: 3 }0----1----2----3----|
+ {11: 4 }----1----2----3----4-│{11: 4 }0----1----2----3----|
+ {11: 5 }----1----2----3----4-│{11: 5 }0----1----2----3----|
+ {5:[No Name] [+] }{1:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ -- <ScrollWheelRight> in inactive window
+ feed_data('\027[<67;48;1M')
+ screen:expect([[
+ {11: 2 }{1:-}---1----2----3----4-│{11: 2 }----1----2----3----4|
+ {11: 3 }----1----2----3----4-│{11: 3 }----1----2----3----4|
+ {11: 4 }----1----2----3----4-│{11: 4 }----1----2----3----4|
+ {11: 5 }----1----2----3----4-│{11: 5 }----1----2----3----4|
+ {5:[No Name] [+] }{1:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ -- <S-ScrollWheelDown> in active window
+ feed_data('\027[<69;8;1M')
+ screen:expect([[
+ {11: 5 }{1:-}---1----2----3----4-│{11: 2 }----1----2----3----4|
+ {11: 6 }----1----2----3----4-│{11: 3 }----1----2----3----4|
+ {11: 7 }----1----2----3----4-│{11: 4 }----1----2----3----4|
+ {11: 8 }----1----2----3----4-│{11: 5 }----1----2----3----4|
+ {5:[No Name] [+] }{1:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ -- <S-ScrollWheelDown> in inactive window
+ feed_data('\027[<69;48;1M')
+ screen:expect([[
+ {11: 5 }{1:-}---1----2----3----4-│{11: 5 }----1----2----3----4|
+ {11: 6 }----1----2----3----4-│{11: 6 }----1----2----3----4|
+ {11: 7 }----1----2----3----4-│{11: 7 }----1----2----3----4|
+ {11: 8 }----1----2----3----4-│{11: 8 }----1----2----3----4|
+ {5:[No Name] [+] }{1:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ -- <S-ScrollWheelRight> in active window
+ feed_data('\027[<71;8;1M')
+ screen:expect([[
+ {11: 5 }{1:-}---6----7----8----9 │{11: 5 }----1----2----3----4|
+ {11: 6 }----6----7----8----9 │{11: 6 }----1----2----3----4|
+ {11: 7 }----6----7----8----9 │{11: 7 }----1----2----3----4|
+ {11: 8 }----6----7----8----9 │{11: 8 }----1----2----3----4|
+ {5:[No Name] [+] }{1:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ -- <S-ScrollWheelRight> in inactive window
+ feed_data('\027[<71;48;1M')
+ screen:expect([[
+ {11: 5 }{1:-}---6----7----8----9 │{11: 5 }5----6----7----8----|
+ {11: 6 }----6----7----8----9 │{11: 6 }5----6----7----8----|
+ {11: 7 }----6----7----8----9 │{11: 7 }5----6----7----8----|
+ {11: 8 }----6----7----8----9 │{11: 8 }5----6----7----8----|
+ {5:[No Name] [+] }{1:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ -- <ScrollWheelUp> in active window
+ feed_data('\027[<64;8;1M')
+ screen:expect([[
+ {11: 4 }----6----7----8----9 │{11: 5 }5----6----7----8----|
+ {11: 5 }{1:-}---6----7----8----9 │{11: 6 }5----6----7----8----|
+ {11: 6 }----6----7----8----9 │{11: 7 }5----6----7----8----|
+ {11: 7 }----6----7----8----9 │{11: 8 }5----6----7----8----|
+ {5:[No Name] [+] }{1:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ -- <ScrollWheelUp> in inactive window
+ feed_data('\027[<64;48;1M')
+ screen:expect([[
+ {11: 4 }----6----7----8----9 │{11: 4 }5----6----7----8----|
+ {11: 5 }{1:-}---6----7----8----9 │{11: 5 }5----6----7----8----|
+ {11: 6 }----6----7----8----9 │{11: 6 }5----6----7----8----|
+ {11: 7 }----6----7----8----9 │{11: 7 }5----6----7----8----|
+ {5:[No Name] [+] }{1:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ -- <ScrollWheelLeft> in active window
+ feed_data('\027[<66;8;1M')
+ screen:expect([[
+ {11: 4 }5----6----7----8----9│{11: 4 }5----6----7----8----|
+ {11: 5 }5{1:-}---6----7----8----9│{11: 5 }5----6----7----8----|
+ {11: 6 }5----6----7----8----9│{11: 6 }5----6----7----8----|
+ {11: 7 }5----6----7----8----9│{11: 7 }5----6----7----8----|
+ {5:[No Name] [+] }{1:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ -- <ScrollWheelLeft> in inactive window
+ feed_data('\027[<66;48;1M')
+ screen:expect([[
+ {11: 4 }5----6----7----8----9│{11: 4 }-5----6----7----8---|
+ {11: 5 }5{1:-}---6----7----8----9│{11: 5 }-5----6----7----8---|
+ {11: 6 }5----6----7----8----9│{11: 6 }-5----6----7----8---|
+ {11: 7 }5----6----7----8----9│{11: 7 }-5----6----7----8---|
+ {5:[No Name] [+] }{1:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ -- <S-ScrollWheelUp> in active window
+ feed_data('\027[<68;8;1M')
+ screen:expect([[
+ {11: 1 }5----6----7----8----9│{11: 4 }-5----6----7----8---|
+ {11: 2 }5----6----7----8----9│{11: 5 }-5----6----7----8---|
+ {11: 3 }5----6----7----8----9│{11: 6 }-5----6----7----8---|
+ {11: 4 }5{1:-}---6----7----8----9│{11: 7 }-5----6----7----8---|
+ {5:[No Name] [+] }{1:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ -- <S-ScrollWheelUp> in inactive window
+ feed_data('\027[<68;48;1M')
+ screen:expect([[
+ {11: 1 }5----6----7----8----9│{11: 1 }-5----6----7----8---|
+ {11: 2 }5----6----7----8----9│{11: 2 }-5----6----7----8---|
+ {11: 3 }5----6----7----8----9│{11: 3 }-5----6----7----8---|
+ {11: 4 }5{1:-}---6----7----8----9│{11: 4 }-5----6----7----8---|
+ {5:[No Name] [+] }{1:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ -- <S-ScrollWheelLeft> in active window
+ feed_data('\027[<70;8;1M')
+ screen:expect([[
+ {11: 1 }0----1----2----3----4│{11: 1 }-5----6----7----8---|
+ {11: 2 }0----1----2----3----4│{11: 2 }-5----6----7----8---|
+ {11: 3 }0----1----2----3----4│{11: 3 }-5----6----7----8---|
+ {11: 4 }0----1----2----3----{1:4}│{11: 4 }-5----6----7----8---|
+ {5:[No Name] [+] }{1:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ -- <S-ScrollWheelLeft> in inactive window
+ feed_data('\027[<70;48;1M')
+ screen:expect([[
+ {11: 1 }0----1----2----3----4│{11: 1 }0----1----2----3----|
+ {11: 2 }0----1----2----3----4│{11: 2 }0----1----2----3----|
+ {11: 3 }0----1----2----3----4│{11: 3 }0----1----2----3----|
+ {11: 4 }0----1----2----3----{1:4}│{11: 4 }0----1----2----3----|
+ {5:[No Name] [+] }{1:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ end)
+
it('accepts keypad keys from kitty keyboard protocol #19180', function()
feed_data('i')
feed_data(funcs.nr2char(57399)) -- KP_0
@@ -1145,6 +1338,47 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]=])
end)
+
+ it('allows grid to assume wider ambiguous-width characters than host terminal #19686', function()
+ child_session:request('nvim_buf_set_lines', 0, 0, 0, true, { ('℃'):rep(60), ('℃'):rep(60) })
+ child_session:request('nvim_win_set_option', 0, 'cursorline', true)
+ child_session:request('nvim_win_set_option', 0, 'list', true)
+ child_session:request('nvim_win_set_option', 0, 'listchars', 'eol:$')
+ local attrs = screen:get_default_attr_ids()
+ attrs[11] = {underline = true} -- CursorLine
+ attrs[12] = {underline = true, reverse = true} -- CursorLine and TermCursor
+ attrs[13] = {underline = true, foreground = 12} -- CursorLine and NonText
+ feed_data('gg')
+ local singlewidth_screen = [[
+ {12:℃}{11:℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃}|
+ {11:℃℃℃℃℃℃℃℃℃℃}{13:$}{11: }|
+ ℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃|
+ ℃℃℃℃℃℃℃℃℃℃{4:$} |
+ {5:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]]
+ -- When grid assumes "℃" to be double-width but host terminal assumes it to be single-width, the
+ -- second cell of "℃" is a space and the attributes of the "℃" are applied to it.
+ local doublewidth_screen = [[
+ {12:℃}{11: ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ }|
+ {11:℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ }|
+ {11:℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ }{13:$}{11: }|
+ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ >{4:@@@}|
+ {5:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]]
+ screen:expect(singlewidth_screen, attrs)
+ child_session:request('nvim_set_option', 'ambiwidth', 'double')
+ screen:expect(doublewidth_screen, attrs)
+ child_session:request('nvim_set_option', 'ambiwidth', 'single')
+ screen:expect(singlewidth_screen, attrs)
+ child_session:request('nvim_call_function', 'setcellwidths', {{{0x2103, 0x2103, 2}}})
+ screen:expect(doublewidth_screen, attrs)
+ child_session:request('nvim_call_function', 'setcellwidths', {{{0x2103, 0x2103, 1}}})
+ screen:expect(singlewidth_screen, attrs)
+ end)
end)
describe('TUI', function()
diff --git a/test/functional/treesitter/highlight_spec.lua b/test/functional/treesitter/highlight_spec.lua
index 5ec0a8a060..4b0bd1eb50 100644
--- a/test/functional/treesitter/highlight_spec.lua
+++ b/test/functional/treesitter/highlight_spec.lua
@@ -6,11 +6,14 @@ local insert = helpers.insert
local exec_lua = helpers.exec_lua
local feed = helpers.feed
local pending_c_parser = helpers.pending_c_parser
+local command = helpers.command
+local meths = helpers.meths
+local eq = helpers.eq
before_each(clear)
local hl_query = [[
- (ERROR) @ErrorMsg
+ (ERROR) @error
"if" @keyword
"else" @keyword
@@ -23,23 +26,24 @@ local hl_query = [[
"enum" @type
"extern" @type
- (string_literal) @string.nonexistent-specializer-for-string.should-fallback-to-string
+ ; nonexistent specializer for string should fallback to string
+ (string_literal) @string.nonexistent_specializer
(number_literal) @number
(char_literal) @string
(type_identifier) @type
- ((type_identifier) @Special (#eq? @Special "LuaRef"))
+ ((type_identifier) @constant.builtin (#eq? @constant.builtin "LuaRef"))
(primitive_type) @type
(sized_type_specifier) @type
; Use lua regexes
- ((identifier) @Identifier (#contains? @Identifier "lua_"))
+ ((identifier) @function (#contains? @function "lua_"))
((identifier) @Constant (#lua-match? @Constant "^[A-Z_]+$"))
- ((identifier) @Normal (#vim-match? @Constant "^lstate$"))
+ ((identifier) @Normal (#vim-match? @Normal "^lstate$"))
- ((binary_expression left: (identifier) @WarningMsg.left right: (identifier) @WarningMsg.right) (#eq? @WarningMsg.left @WarningMsg.right))
+ ((binary_expression left: (identifier) @warning.left right: (identifier) @warning.right) (#eq? @warning.left @warning.right))
(comment) @comment
]]
@@ -103,6 +107,7 @@ describe('treesitter highlighting', function()
}
exec_lua([[ hl_query = ... ]], hl_query)
+ command [[ hi link @warning WarningMsg ]]
end)
it('is updated with edits', function()
@@ -547,7 +552,7 @@ describe('treesitter highlighting', function()
-- This will change ONLY the literal strings to look like comments
-- The only literal string is the "vim.schedule: expected function" in this test.
- exec_lua [[vim.cmd("highlight link cString comment")]]
+ exec_lua [[vim.cmd("highlight link @string.nonexistent_specializer comment")]]
screen:expect{grid=[[
{2:/// Schedule Lua callback on main loop's event queue} |
{3:static} {3:int} {11:nlua_schedule}({3:lua_State} *{3:const} lstate) |
@@ -612,6 +617,11 @@ describe('treesitter highlighting', function()
-- bold will not be overwritten at the moment
[12] = {background = Screen.colors.Red, bold = true, foreground = Screen.colors.Grey100};
}}
+
+ eq({
+ {capture='Error', priority='101'};
+ {capture='type'};
+ }, exec_lua [[ return vim.treesitter.get_captures_at_position(0, 0, 2) ]])
end)
it("allows to use captures with dots (don't use fallback when specialization of foo exists)", function()
@@ -642,11 +652,13 @@ describe('treesitter highlighting', function()
|
]]}
+ command [[
+ hi link @foo.bar Type
+ hi link @foo String
+ ]]
exec_lua [[
local parser = vim.treesitter.get_parser(0, "c", {})
local highlighter = vim.treesitter.highlighter
- highlighter.hl_map['foo.bar'] = 'Type'
- highlighter.hl_map['foo'] = 'String'
test_hl = highlighter.new(parser, {queries = {c = "(primitive_type) @foo.bar (string_literal) @foo"}})
]]
@@ -670,6 +682,29 @@ describe('treesitter highlighting', function()
{1:~ }|
|
]]}
+
+ -- clearing specialization reactivates fallback
+ command [[ hi clear @foo.bar ]]
+ screen:expect{grid=[[
+ {5:char}* x = {5:"Will somebody ever read this?"}; |
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
end)
it("supports conceal attribute", function()
@@ -712,32 +747,26 @@ describe('treesitter highlighting', function()
]]}
end)
- it("hl_map has the correct fallback behavior", function()
- exec_lua [[
- local hl_map = vim.treesitter.highlighter.hl_map
- hl_map["foo"] = 1
- hl_map["foo.bar"] = 2
- hl_map["foo.bar.baz"] = 3
-
- assert(hl_map["foo"] == 1)
- assert(hl_map["foo.a.b.c.d"] == 1)
- assert(hl_map["foo.bar"] == 2)
- assert(hl_map["foo.bar.a.b.c.d"] == 2)
- assert(hl_map["foo.bar.baz"] == 3)
- assert(hl_map["foo.bar.baz.d"] == 3)
-
- hl_map["FOO"] = 1
- hl_map["FOO.BAR"] = 2
- assert(hl_map["FOO.BAR.BAZ"] == 2)
-
- hl_map["foo.missing.exists"] = 3
- assert(hl_map["foo.missing"] == 1)
- assert(hl_map["foo.missing.exists"] == 3)
- assert(hl_map["foo.missing.exists.bar"] == 3)
- assert(hl_map["total.nonsense.but.a.lot.of.dots"] == nil)
- -- It will not perform a second look up of this variable but return a sentinel value
- assert(hl_map["total.nonsense.but.a.lot.of.dots"] == "__notfound")
- ]]
-
+ it("@foo.bar groups has the correct fallback behavior", function()
+ local get_hl = function(name) return meths.get_hl_by_name(name,1).foreground end
+ meths.set_hl(0, "@foo", {fg = 1})
+ meths.set_hl(0, "@foo.bar", {fg = 2})
+ meths.set_hl(0, "@foo.bar.baz", {fg = 3})
+
+ eq(1, get_hl"@foo")
+ eq(1, get_hl"@foo.a.b.c.d")
+ eq(2, get_hl"@foo.bar")
+ eq(2, get_hl"@foo.bar.a.b.c.d")
+ eq(3, get_hl"@foo.bar.baz")
+ eq(3, get_hl"@foo.bar.baz.d")
+
+ -- lookup is case insensitive
+ eq(2, get_hl"@FOO.BAR.SPAM")
+
+ meths.set_hl(0, "@foo.missing.exists", {fg = 3})
+ eq(1, get_hl"@foo.missing")
+ eq(3, get_hl"@foo.missing.exists")
+ eq(3, get_hl"@foo.missing.exists.bar")
+ eq(nil, get_hl"@total.nonsense.but.a.lot.of.dots")
end)
end)
diff --git a/test/functional/treesitter/language_spec.lua b/test/functional/treesitter/language_spec.lua
index 30585be328..8e9941d797 100644
--- a/test/functional/treesitter/language_spec.lua
+++ b/test/functional/treesitter/language_spec.lua
@@ -7,10 +7,11 @@ local exec_lua = helpers.exec_lua
local pcall_err = helpers.pcall_err
local matches = helpers.matches
local pending_c_parser = helpers.pending_c_parser
+local insert = helpers.insert
before_each(clear)
-describe('treesitter API', function()
+describe('treesitter language API', function()
-- error tests not requiring a parser library
it('handles missing language', function()
eq("Error executing lua: .../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers",
@@ -26,6 +27,11 @@ describe('treesitter API', function()
eq("Error executing lua: .../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers",
pcall_err(exec_lua, "parser = vim.treesitter.inspect_language('borklang')"))
+
+ if not pending_c_parser(pending) then
+ matches("Error executing lua: Failed to load parser: uv_dlsym: .+",
+ pcall_err(exec_lua, 'vim.treesitter.require_language("c", nil, false, "borklang")'))
+ end
end)
it('inspects language', function()
@@ -79,5 +85,35 @@ describe('treesitter API', function()
eq("Error executing lua: .../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers",
pcall_err(exec_lua, "new_parser = vim.treesitter.get_parser(0)"))
end)
+
+ it('retrieve the tree given a range', function ()
+ if pending_c_parser(pending) then return end
+ insert([[
+ int main() {
+ int x = 3;
+ }]])
+
+ exec_lua([[
+ langtree = vim.treesitter.get_parser(0, "c")
+ tree = langtree:tree_for_range({1, 3, 1, 3})
+ ]])
+
+ eq('<node translation_unit>', exec_lua('return tostring(tree:root())'))
+ end)
+
+ it('retrieve the node given a range', function ()
+ if pending_c_parser(pending) then return end
+ insert([[
+ int main() {
+ int x = 3;
+ }]])
+
+ exec_lua([[
+ langtree = vim.treesitter.get_parser(0, "c")
+ node = langtree:named_node_for_range({1, 3, 1, 3})
+ ]])
+
+ eq('<node primitive_type>', exec_lua('return tostring(node)'))
+ end)
end)
diff --git a/test/functional/treesitter/node_spec.lua b/test/functional/treesitter/node_spec.lua
index 21c287644e..87ce1b973c 100644
--- a/test/functional/treesitter/node_spec.lua
+++ b/test/functional/treesitter/node_spec.lua
@@ -59,4 +59,53 @@ describe('treesitter node API', function()
exec_lua 'node = node:prev_named_sibling()'
eq('int x', lua_eval('node_text(node)'))
end)
+
+ it('can retrieve the children of a node', function()
+ insert([[
+ int main() {
+ int x = 3;
+ }]])
+
+ local len = exec_lua([[
+ tree = vim.treesitter.get_parser(0, "c"):parse()[1]
+ node = tree:root():child(0)
+ children = node:named_children()
+
+ return #children
+ ]])
+
+ eq(3, len)
+ eq('<node compound_statement>', lua_eval('tostring(children[3])'))
+ end)
+
+ it('can retrieve the tree root given a node', function()
+ insert([[
+ int main() {
+ int x = 3;
+ }]])
+
+ exec_lua([[
+ tree = vim.treesitter.get_parser(0, "c"):parse()[1]
+ root = tree:root()
+ node = root:child(0):child(2)
+ ]])
+
+ eq(lua_eval('tostring(root)'), lua_eval('tostring(node:root())'))
+ end)
+
+ it('can compute the byte length of a node', function()
+ insert([[
+ int main() {
+ int x = 3;
+ }]])
+
+ exec_lua([[
+ tree = vim.treesitter.get_parser(0, "c"):parse()[1]
+ root = tree:root()
+ child = root:child(0):child(0)
+ ]])
+
+ eq(28, lua_eval('root:byte_length()'))
+ eq(3, lua_eval('child:byte_length()'))
+ end)
end)
diff --git a/test/functional/treesitter/utils_spec.lua b/test/functional/treesitter/utils_spec.lua
new file mode 100644
index 0000000000..4f4c18a748
--- /dev/null
+++ b/test/functional/treesitter/utils_spec.lua
@@ -0,0 +1,33 @@
+local helpers = require('test.functional.helpers')(after_each)
+
+local clear = helpers.clear
+local insert = helpers.insert
+local eq = helpers.eq
+local exec_lua = helpers.exec_lua
+local pending_c_parser = helpers.pending_c_parser
+
+before_each(clear)
+
+describe('treesitter utils', function()
+ before_each(clear)
+
+ it('can find an ancestor', function()
+ if pending_c_parser(pending) then return end
+
+ insert([[
+ int main() {
+ int x = 3;
+ }]])
+
+ exec_lua([[
+ parser = vim.treesitter.get_parser(0, "c")
+ tree = parser:parse()[1]
+ root = tree:root()
+ ancestor = root:child(0)
+ child = ancestor:child(0)
+ ]])
+
+ eq(true, exec_lua('return vim.treesitter.is_ancestor(ancestor, child)'))
+ eq(false, exec_lua('return vim.treesitter.is_ancestor(child, ancestor)'))
+ end)
+end)
diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua
index 384761ab17..fa5771a8b3 100644
--- a/test/functional/ui/cmdline_highlight_spec.lua
+++ b/test/functional/ui/cmdline_highlight_spec.lua
@@ -24,7 +24,6 @@ before_each(function()
clear()
screen = Screen.new(40, 8)
screen:attach()
- command("set display-=msgsep")
source([[
highlight RBP1 guibg=Red
highlight RBP2 guibg=Yellow
@@ -152,6 +151,7 @@ before_each(function()
SB={foreground = Screen.colors.Blue4},
E={foreground = Screen.colors.Red, background = Screen.colors.Blue},
M={bold = true},
+ MSEP={bold = true, reverse = true};
})
end)
@@ -298,22 +298,22 @@ describe('Command-line coloring', function()
function()
set_color_cb('SplittedMultibyteStart')
start_prompt('echo "«')
- screen:expect([[
- {EOB:~ }|
- {EOB:~ }|
+ screen:expect{grid=[[
+ |
{EOB:~ }|
{EOB:~ }|
+ {MSEP: }|
:echo " |
{ERR:E5405: Chunk 0 start 7 splits multibyte }|
{ERR:character} |
:echo "«^ |
- ]])
+ ]]}
feed('»')
screen:expect([[
+ |
{EOB:~ }|
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {MSEP: }|
:echo " |
{ERR:E5405: Chunk 0 start 7 splits multibyte }|
{ERR:character} |
@@ -325,10 +325,10 @@ describe('Command-line coloring', function()
set_color_cb('SplittedMultibyteEnd')
start_prompt('echo "«')
screen:expect([[
+ |
{EOB:~ }|
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {MSEP: }|
:echo " |
{ERR:E5406: Chunk 0 end 7 splits multibyte ch}|
{ERR:aracter} |
@@ -339,10 +339,10 @@ describe('Command-line coloring', function()
set_color_cb('Echoerring')
start_prompt('e')
screen:expect([[
+ |
{EOB:~ }|
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {MSEP: }|
: |
{ERR:E5407: Callback has thrown an exception:}|
{ERR: Vim(echoerr):HERE} |
@@ -398,10 +398,10 @@ describe('Command-line coloring', function()
set_color_cb('Throwing')
start_prompt('e')
screen:expect([[
+ |
{EOB:~ }|
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {MSEP: }|
: |
{ERR:E5407: Callback has thrown an exception:}|
{ERR: ABC} |
@@ -412,10 +412,10 @@ describe('Command-line coloring', function()
set_color_cb('SplittedMultibyteStart')
start_prompt('let x = "«»«»«»«»«»"')
screen:expect([[
+ |
{EOB:~ }|
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {MSEP: }|
:let x = " |
{ERR:E5405: Chunk 0 start 10 splits multibyte}|
{ERR: character} |
@@ -453,10 +453,10 @@ describe('Command-line coloring', function()
screen:sleep(500)
feed('<C-c>')
screen:expect([[
+ |
{EOB:~ }|
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {MSEP: }|
: |
{ERR:E5407: Callback has thrown an exception:}|
{ERR: Keyboard interrupt} |
@@ -517,11 +517,11 @@ describe('Command-line coloring', function()
set_color_cb('ReturningGlobal', '')
start_prompt('#')
screen:expect([[
+ |
{EOB:~ }|
{EOB:~ }|
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {MSEP: }|
: |
{ERR:E5400: Callback should return list} |
:#^ |
@@ -531,11 +531,11 @@ describe('Command-line coloring', function()
set_color_cb('ReturningGlobal', {{0, 1, 'Normal'}, 42})
start_prompt('#')
screen:expect([[
+ |
{EOB:~ }|
{EOB:~ }|
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {MSEP: }|
: |
{ERR:E5401: List item 1 is not a List} |
:#^ |
@@ -545,10 +545,10 @@ describe('Command-line coloring', function()
set_color_cb('ReturningGlobal2', {{0, 1, 'Normal'}, {1}})
start_prompt('+')
screen:expect([[
+ |
{EOB:~ }|
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {MSEP: }|
:+ |
{ERR:E5402: List item 1 has incorrect length:}|
{ERR: 1 /= 3} |
@@ -559,10 +559,10 @@ describe('Command-line coloring', function()
set_color_cb('ReturningGlobal2', {{0, 1, 'Normal'}, {2, 3, 'Normal'}})
start_prompt('+')
screen:expect([[
+ |
{EOB:~ }|
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {MSEP: }|
:+ |
{ERR:E5403: Chunk 1 start 2 not in range [1, }|
{ERR:2)} |
@@ -573,10 +573,10 @@ describe('Command-line coloring', function()
set_color_cb('ReturningGlobal2', {{0, 1, 'Normal'}, {1, 3, 'Normal'}})
start_prompt('+')
screen:expect([[
+ |
{EOB:~ }|
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {MSEP: }|
:+ |
{ERR:E5404: Chunk 1 end 3 not in range (1, 2]}|
|
@@ -800,10 +800,10 @@ describe('Ex commands coloring', function()
it('does not crash when using `n` in debug mode', function()
feed(':debug execute "echo 1"\n')
screen:expect([[
+ |
{EOB:~ }|
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {MSEP: }|
Entering Debug mode. Type "cont" to con|
tinue. |
cmd: execute "echo 1" |
@@ -811,8 +811,8 @@ describe('Ex commands coloring', function()
]])
feed('n\n')
screen:expect([[
- {EOB:~ }|
- {EOB:~ }|
+ |
+ {MSEP: }|
Entering Debug mode. Type "cont" to con|
tinue. |
cmd: execute "echo 1" |
@@ -836,10 +836,10 @@ describe('Ex commands coloring', function()
command("cnoremap <expr> x execute('throw 42')[-1]")
feed(':#x')
screen:expect([[
+ |
{EOB:~ }|
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {MSEP: }|
:# |
{ERR:Error detected while processing :} |
{ERR:E605: Exception not caught: 42} |
@@ -847,9 +847,9 @@ describe('Ex commands coloring', function()
]])
feed('<CR>')
screen:expect([[
+ |
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {MSEP: }|
:# |
{ERR:Error detected while processing :} |
{ERR:E605: Exception not caught: 42} |
@@ -864,9 +864,9 @@ describe('Ex commands coloring', function()
meths.set_var('Nvim_color_cmdline', 42)
feed(':#')
screen:expect([[
+ |
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {MSEP: }|
: |
{ERR:E5408: Unable to get g:Nvim_color_cmdlin}|
{ERR:e callback: Vim:E6000: Argument is not a}|
diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua
index 9af5d386db..789f1c6487 100644
--- a/test/functional/ui/decorations_spec.lua
+++ b/test/functional/ui/decorations_spec.lua
@@ -193,7 +193,7 @@ describe('decorations providers', function()
|
]]}
- meths._set_hl_ns(ns1)
+ meths.set_hl_ns(ns1)
screen:expect{grid=[[
{10: 1 }{11:// just to see if there was an accid}|
{10: }{11:ent} |
@@ -219,7 +219,7 @@ describe('decorations providers', function()
local ns2 = a.nvim_create_namespace 'ns2'
a.nvim_set_decoration_provider (ns2, {
on_win = function (_, win, buf)
- a.nvim__set_hl_ns(win == thewin and _G.ns1 or ns2)
+ a.nvim_set_hl_ns_fast(win == thewin and _G.ns1 or ns2)
end;
})
]]
@@ -266,7 +266,7 @@ describe('decorations providers', function()
]]}
meths.set_hl(ns1, 'LinkGroup', {fg = 'Blue'})
- meths._set_hl_ns(ns1)
+ meths.set_hl_ns(ns1)
screen:expect{grid=[[
// just to see if there was an accident |
@@ -302,7 +302,7 @@ describe('decorations providers', function()
]]}
meths.set_hl(ns1, 'LinkGroup', {fg = 'Blue', default=true})
- meths._set_hl_ns(ns1)
+ meths.set_hl_ns(ns1)
feed 'k'
screen:expect{grid=[[
@@ -1681,7 +1681,7 @@ l5
screen:expect{grid=[[
S4S1^l1 |
- S2x l2 |
+ x S2l2 |
S5{1: }l3 |
{1: }l4 |
{1: }l5 |
@@ -1779,6 +1779,34 @@ l5
]]}
end)
+ it('works with priority #19716', function()
+ screen:try_resize(20, 3)
+ insert(example_text)
+ feed 'gg'
+
+ helpers.command('sign define Oldsign text=O3')
+ helpers.command([[exe 'sign place 42 line=1 name=Oldsign priority=10 buffer=' . bufnr('')]])
+
+ meths.buf_set_extmark(0, ns, 0, -1, {sign_text='S4', priority=100})
+ meths.buf_set_extmark(0, ns, 0, -1, {sign_text='S2', priority=5})
+ meths.buf_set_extmark(0, ns, 0, -1, {sign_text='S5', priority=200})
+ meths.buf_set_extmark(0, ns, 0, -1, {sign_text='S1', priority=1})
+
+ screen:expect{grid=[[
+ S1S2O3S4S5^l1 |
+ {1: }l2 |
+ |
+ ]]}
+
+ -- Check truncation works too
+ meths.win_set_option(0, 'signcolumn', 'auto')
+
+ screen:expect{grid=[[
+ S5^l1 |
+ {1: }l2 |
+ |
+ ]]}
+ end)
end)
describe('decorations: virt_text', function()
diff --git a/test/functional/ui/fold_spec.lua b/test/functional/ui/fold_spec.lua
index c79fc2989c..6bb8bb81c6 100644
--- a/test/functional/ui/fold_spec.lua
+++ b/test/functional/ui/fold_spec.lua
@@ -1904,4 +1904,11 @@ describe("folded lines", function()
describe('without ext_multigrid', function()
with_ext_multigrid(false)
end)
+
+ it('no folds remains if :delete makes buffer empty #19671', function()
+ funcs.setline(1, {'foo', 'bar', 'baz'})
+ command('2,3fold')
+ command('%delete')
+ eq(0, funcs.foldlevel(1))
+ end)
end)
diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua
index e065a727f3..5ffe9ddaad 100644
--- a/test/functional/ui/highlight_spec.lua
+++ b/test/functional/ui/highlight_spec.lua
@@ -3,9 +3,10 @@ local Screen = require('test.functional.ui.screen')
local os = require('os')
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local command, exec = helpers.command, helpers.exec
-local eval, exc_exec = helpers.eval, helpers.exc_exec
+local eval = helpers.eval
local feed_command, eq = helpers.feed_command, helpers.eq
local curbufmeths = helpers.curbufmeths
+local meths = helpers.meths
describe('colorscheme compatibility', function()
before_each(function()
@@ -92,16 +93,22 @@ describe('highlight defaults', function()
before_each(function()
clear()
screen = Screen.new()
+ screen:set_default_attr_ids {
+ [0] = {bold=true, foreground=Screen.colors.Blue};
+ [1] = {reverse = true, bold = true};
+ [2] = {reverse = true};
+ [3] = {bold = true};
+ [4] = {bold = true, foreground = Screen.colors.SeaGreen};
+ [5] = {foreground = Screen.colors.Red1, background = Screen.colors.WebGreen};
+ [6] = {background = Screen.colors.Red1, foreground = Screen.colors.Grey100};
+ [7] = {foreground = Screen.colors.Red};
+ [8] = {foreground = Screen.colors.Blue};
+ [9] = {italic = true};
+ }
screen:attach()
- command("set display-=msgsep")
end)
it('window status bar', function()
- screen:set_default_attr_ids({
- [0] = {bold=true, foreground=Screen.colors.Blue},
- [1] = {reverse = true, bold = true}, -- StatusLine
- [2] = {reverse = true} -- StatusLineNC
- })
feed_command('sp', 'vsp', 'vsp')
screen:expect([[
^ │ │ |
@@ -200,31 +207,29 @@ describe('highlight defaults', function()
^ |
{0:~ }|
{0:~ }|
- {1:-- INSERT --} |
- ]], {[0] = {bold=true, foreground=Screen.colors.Blue},
- [1] = {bold = true}})
+ {3:-- INSERT --} |
+ ]])
end)
it('end of file markers', function()
screen:try_resize(53, 4)
screen:expect([[
^ |
- {1:~ }|
- {1:~ }|
+ {0:~ }|
+ {0:~ }|
|
- ]], {[1] = {bold = true, foreground = Screen.colors.Blue}})
+ ]])
end)
it('"wait return" text', function()
screen:try_resize(53, 4)
feed(':ls<cr>')
screen:expect([[
- {0:~ }|
+ {1: }|
:ls |
1 %a "[No Name]" line 1 |
- {1:Press ENTER or type command to continue}^ |
- ]], {[0] = {bold=true, foreground=Screen.colors.Blue},
- [1] = {bold = true, foreground = Screen.colors.SeaGreen}})
+ {4:Press ENTER or type command to continue}^ |
+ ]])
feed('<cr>') -- skip the "Press ENTER..." state or tests will hang
end)
@@ -237,8 +242,7 @@ describe('highlight defaults', function()
{0:~ }|
{0:~ }|
-- INSERT -- |
- ]], {[0] = {bold=true, foreground=Screen.colors.Blue},
- [1] = {bold=true}})
+ ]])
feed('<esc>')
feed_command('highlight CustomHLGroup guifg=red guibg=green')
feed_command('highlight link ModeMsg CustomHLGroup')
@@ -247,9 +251,8 @@ describe('highlight defaults', function()
^ |
{0:~ }|
{0:~ }|
- {1:-- INSERT --} |
- ]], {[0] = {bold=true, foreground=Screen.colors.Blue},
- [1] = {foreground = Screen.colors.Red, background = Screen.colors.Green}})
+ {5:-- INSERT --} |
+ ]])
end)
it('can be cleared by assigning NONE', function()
@@ -258,14 +261,11 @@ describe('highlight defaults', function()
feed_command('hi link TmpKeyword ErrorMsg')
insert('neovim')
screen:expect([[
- {1:neovi^m} |
+ {6:neovi^m} |
{0:~ }|
{0:~ }|
|
- ]], {
- [0] = {bold=true, foreground=Screen.colors.Blue},
- [1] = {foreground = Screen.colors.White, background = Screen.colors.Red}
- })
+ ]])
feed_command("hi ErrorMsg term=NONE cterm=NONE ctermfg=NONE ctermbg=NONE"
.. " gui=NONE guifg=NONE guibg=NONE guisp=NONE")
screen:expect([[
@@ -273,7 +273,7 @@ describe('highlight defaults', function()
{0:~ }|
{0:~ }|
|
- ]], {[0] = {bold=true, foreground=Screen.colors.Blue}})
+ ]])
end)
it('linking updates window highlight immediately #16552', function()
@@ -283,7 +283,7 @@ describe('highlight defaults', function()
{0:~ }|
{0:~ }|
|
- ]], {[0] = {bold=true, foreground=Screen.colors.Blue}})
+ ]])
feed_command("hi NonTextAlt guifg=Red")
feed_command("hi! link NonText NonTextAlt")
screen:expect([[
@@ -305,56 +305,44 @@ describe('highlight defaults', function()
feed_command('set listchars=space:.,tab:>-,trail:*,eol:¬ list')
insert(' ne \t o\tv im ')
screen:expect([[
- ne{0:.>----.}o{0:>-----}v{0:..}im{0:*^*¬} |
- {0:~ }|
- {0:~ }|
+ ne{7:.>----.}o{7:>-----}v{7:..}im{7:*^*¬} |
+ {7:~ }|
+ {7:~ }|
|
- ]], {
- [0] = {foreground=Screen.colors.Red},
- [1] = {foreground=Screen.colors.Blue},
- })
+ ]])
feed_command('highlight Whitespace gui=NONE guifg=#0000FF')
screen:expect([[
- ne{1:.>----.}o{1:>-----}v{1:..}im{1:*^*}{0:¬} |
- {0:~ }|
- {0:~ }|
+ ne{8:.>----.}o{8:>-----}v{8:..}im{8:*^*}{7:¬} |
+ {7:~ }|
+ {7:~ }|
:highlight Whitespace gui=NONE guifg=#0000FF |
- ]], {
- [0] = {foreground=Screen.colors.Red},
- [1] = {foreground=Screen.colors.Blue},
- })
+ ]])
end)
it('are sent to UIs', function()
screen:try_resize(53, 4)
- screen:set_default_attr_ids({
- [0] = {},
- [1] = {bold = true, foreground = Screen.colors.Blue1},
- [2] = {bold = true, reverse = true},
- [3] = {italic=true}
- })
screen:expect{grid=[[
^ |
- {1:~ }|
- {1:~ }|
+ {0:~ }|
+ {0:~ }|
|
- ]], hl_groups={EndOfBuffer=1, MsgSeparator=2}}
+ ]], hl_groups={EndOfBuffer=0, MsgSeparator=1}}
command('highlight EndOfBuffer gui=italic')
screen:expect{grid=[[
^ |
- {3:~ }|
- {3:~ }|
+ {9:~ }|
+ {9:~ }|
|
- ]], hl_groups={EndOfBuffer=3, MsgSeparator=2}}
+ ]], hl_groups={EndOfBuffer=9, MsgSeparator=1}}
command('highlight clear EndOfBuffer')
screen:expect{grid=[[
^ |
- {1:~ }|
- {1:~ }|
+ {0:~ }|
+ {0:~ }|
|
- ]], hl_groups={EndOfBuffer=1, MsgSeparator=2}}
+ ]], hl_groups={EndOfBuffer=0, MsgSeparator=1}}
end)
end)
@@ -1787,6 +1775,7 @@ describe("'winhighlight' highlight", function()
[26] = {background = Screen.colors.Red},
[27] = {background = Screen.colors.DarkBlue, bold = true, foreground = Screen.colors.Green1},
[28] = {bold = true, foreground = Screen.colors.Brown},
+ [29] = {foreground = Screen.colors.Blue1, background = Screen.colors.Red, bold = true};
})
command("hi Background1 guibg=DarkBlue")
command("hi Background2 guibg=DarkGreen")
@@ -1820,7 +1809,7 @@ describe("'winhighlight' highlight", function()
]])
end)
- it('handles invalid values', function()
+ it('handles undefined groups', function()
command("set winhl=Normal:Background1")
screen:expect([[
{1:^ }|
@@ -1833,19 +1822,44 @@ describe("'winhighlight' highlight", function()
|
]])
- eq('Vim(set):E474: Invalid argument: winhl=xxx:yyy',
- exc_exec("set winhl=xxx:yyy"))
- eq('Normal:Background1', eval('&winhl'))
+ command("set winhl=xxx:yyy")
+ eq('xxx:yyy', eval('&winhl'))
screen:expect{grid=[[
- {1:^ }|
- {2:~ }|
- {2:~ }|
- {2:~ }|
- {2:~ }|
- {2:~ }|
- {2:~ }|
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]]}
+ end)
+
+ it('can be changed to define different groups', function()
+ command("set winhl=EndOfBuffer:Background1")
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ command("set winhl=Normal:ErrorMsg")
+ screen:expect{grid=[[
+ {15:^ }|
+ {29:~ }|
+ {29:~ }|
+ {29:~ }|
+ {29:~ }|
+ {29:~ }|
+ {29:~ }|
|
- ]], unchanged=true}
+ ]]}
end)
it('works local to the window', function()
@@ -2270,4 +2284,236 @@ describe("'winhighlight' highlight", function()
|
]])
end)
+
+
+ it("can override syntax groups", function()
+ command('syntax on')
+ command('syntax keyword Foobar foobar')
+ command('syntax keyword Article the')
+ command('hi Foobar guibg=#FF0000')
+ command('hi Article guifg=#00FF00 gui=bold')
+ insert('the foobar was foobar')
+ screen:expect([[
+ {25:the} {26:foobar} was {26:fooba}|
+ {26:^r} |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+
+ command('split')
+ command('set winhl=Foobar:Background1,Article:ErrorMsg')
+ screen:expect{grid=[[
+ {15:the} {1:foobar} was {1:fooba}|
+ {1:^r} |
+ {0:~ }|
+ {3:[No Name] [+] }|
+ {25:the} {26:foobar} was {26:fooba}|
+ {26:r} |
+ {4:[No Name] [+] }|
+ |
+ ]]}
+ end)
+
+ it('can be disabled in newly opened window #19823', function()
+ command('split | set winhl=Normal:ErrorMsg | set winhl=')
+ screen:expect{grid=[[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {3:[No Name] }|
+ |
+ {0:~ }|
+ {4:[No Name] }|
+ |
+ ]]}
+
+ helpers.assert_alive()
+ end)
+
+ it('can redraw statusline on cursor movement', function()
+ screen:try_resize(40, 8)
+ exec [[
+ set statusline=%f%=%#Background1#%l,%c%V\ %P
+ split
+ ]]
+ insert [[
+ some text
+ more text]]
+ screen:expect{grid=[[
+ some text |
+ more tex^t |
+ {0:~ }|
+ {3:[No Name] }{1:2,9 All}|
+ some text |
+ more text |
+ {4:[No Name] }{1:1,1 All}|
+ |
+ ]]}
+
+ command 'set winhl=Background1:Background2'
+ screen:expect{grid=[[
+ some text |
+ more tex^t |
+ {0:~ }|
+ {3:[No Name] }{5:2,9 All}|
+ some text |
+ more text |
+ {4:[No Name] }{1:1,1 All}|
+ |
+ ]]}
+
+ feed 'k'
+ screen:expect{grid=[[
+ some tex^t |
+ more text |
+ {0:~ }|
+ {3:[No Name] }{5:1,9 All}|
+ some text |
+ more text |
+ {4:[No Name] }{1:1,1 All}|
+ |
+ ]]}
+ end)
+end)
+
+describe('highlight namespaces', function()
+ local screen
+ local ns1, ns2
+
+ before_each(function()
+ clear()
+ screen = Screen.new(25,10)
+ screen:attach()
+ screen:set_default_attr_ids {
+ [1] = {foreground = Screen.colors.Blue, bold = true};
+ [2] = {background = Screen.colors.DarkGrey};
+ [3] = {italic = true, foreground = Screen.colors.DarkCyan, background = Screen.colors.DarkOrange4};
+ [4] = {background = Screen.colors.Magenta4};
+ [5] = {background = Screen.colors.Magenta4, foreground = Screen.colors.Crimson};
+ [6] = {bold = true, reverse = true};
+ [7] = {reverse = true};
+ [8] = {foreground = Screen.colors.Gray20};
+ }
+
+ ns1 = meths.create_namespace 'grungy'
+ ns2 = meths.create_namespace 'ultrared'
+
+ meths.set_hl(ns1, 'Normal', {bg='DarkGrey'})
+ meths.set_hl(ns1, 'NonText', {bg='DarkOrange4', fg='DarkCyan', italic=true})
+ meths.set_hl(ns2, 'Normal', {bg='DarkMagenta'})
+ meths.set_hl(ns2, 'NonText', {fg='Crimson'})
+ end)
+
+ it('can be used globally', function()
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ meths.set_hl_ns(ns1)
+ screen:expect{grid=[[
+ {2:^ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ |
+ ]]}
+
+ meths.set_hl_ns(ns2)
+ screen:expect{grid=[[
+ {4:^ }|
+ {5:~ }|
+ {5:~ }|
+ {5:~ }|
+ {5:~ }|
+ {5:~ }|
+ {5:~ }|
+ {5:~ }|
+ {5:~ }|
+ |
+ ]]}
+
+ meths.set_hl_ns(0)
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ end)
+
+ it('can be used per window', function()
+ local win1 = meths.get_current_win()
+ command 'split'
+ local win2 = meths.get_current_win()
+ command 'split'
+
+ meths.win_set_hl_ns(win1, ns1)
+ meths.win_set_hl_ns(win2, ns2)
+
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {6:[No Name] }|
+ {4: }|
+ {5:~ }|
+ {7:[No Name] }|
+ {2: }|
+ {3:~ }|
+ {7:[No Name] }|
+ |
+ ]]}
+ end)
+
+ it('redraws correctly when ns=0', function()
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ meths.set_hl(0, 'EndOfBuffer', {fg='#333333'})
+ screen:expect{grid=[[
+ ^ |
+ {8:~ }|
+ {8:~ }|
+ {8:~ }|
+ {8:~ }|
+ {8:~ }|
+ {8:~ }|
+ {8:~ }|
+ {8:~ }|
+ |
+ ]]}
+ end)
end)
diff --git a/test/functional/ui/hlstate_spec.lua b/test/functional/ui/hlstate_spec.lua
index df7f34aa7f..dc74d6d401 100644
--- a/test/functional/ui/hlstate_spec.lua
+++ b/test/functional/ui/hlstate_spec.lua
@@ -119,13 +119,15 @@ describe('ext_hlstate detailed highlights', function()
[3] = {{bold = true, reverse = true}, {{hi_name = "StatusLine", ui_name = "StatusLine", kind = "ui"}}},
[4] = {{reverse = true}, {{hi_name = "StatusLineNC", ui_name = "StatusLineNC", kind = "ui"}}},
[5] = {{background = Screen.colors.Red, foreground = Screen.colors.Grey100}, {{hi_name = "ErrorMsg", ui_name = "LineNr", kind = "ui"}}},
- [6] = {{bold = true, reverse = true}, {{hi_name = "MsgSeparator", ui_name = "Normal", kind = "ui"}}},
+ [6] = {{bold = true, reverse = true}, {{hi_name = "Normal", ui_name = "Normal", kind = "ui"}}},
[7] = {{foreground = Screen.colors.Brown, bold = true, reverse = true}, {6, 1}},
- [8] = {{foreground = Screen.colors.Blue1, bold = true, reverse = true}, {6, 2}},
- [9] = {{bold = true, foreground = Screen.colors.Brown}, {{hi_name = "Statement", ui_name = "NormalNC", kind = "ui"}}},
+ [8] = {{foreground = Screen.colors.Blue1, bold = true, reverse = true}, {6, 14}},
+ [9] = {{bold = true, foreground = Screen.colors.Brown}, {{hi_name = "NormalNC", ui_name = "NormalNC", kind = "ui"}}},
[10] = {{bold = true, foreground = Screen.colors.Brown}, {9, 1}},
- [11] = {{bold = true, foreground = Screen.colors.Blue1}, {9, 2}},
+ [11] = {{bold = true, foreground = Screen.colors.Blue1}, {9, 14}},
[12] = {{}, {{hi_name = "MsgArea", ui_name = "MsgArea", kind = "ui"}}},
+ [13] = {{background = Screen.colors.Red1, foreground = Screen.colors.Gray100}, {{ui_name = "LineNr", kind = "ui", hi_name = "LineNr"}}};
+ [14] = {{bold = true, foreground = Screen.colors.Blue}, {{ui_name = "EndOfBuffer", kind = "ui", hi_name = "EndOfBuffer"}}};
})
command("set number")
@@ -143,16 +145,16 @@ describe('ext_hlstate detailed highlights', function()
]])
command("set winhl=LineNr:ErrorMsg")
- screen:expect([[
- {5: 1 }^ |
- {2:~ }|
- {2:~ }|
+ screen:expect{grid=[[
+ {13: 1 }^ |
+ {14:~ }|
+ {14:~ }|
{3:[No Name] }|
{1: 1 } |
{2:~ }|
{4:[No Name] }|
{12: }|
- ]])
+ ]]}
command("set winhl=Normal:MsgSeparator,NormalNC:Statement")
screen:expect([[
diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua
index d8dd546a8d..9ca4673efe 100644
--- a/test/functional/ui/inccommand_spec.lua
+++ b/test/functional/ui/inccommand_spec.lua
@@ -66,7 +66,6 @@ local function common_setup(screen, inccommand, text)
command("syntax on")
command("set nohlsearch")
command("hi Substitute guifg=red guibg=yellow")
- command("set display-=msgsep")
screen:attach()
screen:set_default_attr_ids({
[1] = {foreground = Screen.colors.Fuchsia},
@@ -142,11 +141,11 @@ describe(":substitute, 'inccommand' preserves", function()
feed_command("ls")
screen:expect([[
+ BAC |
{15:~ }|
{15:~ }|
{15:~ }|
- {15:~ }|
- {15:~ }|
+ {11: }|
:ls |
1 %a + "[No Name]" |
line 1 |
@@ -1469,14 +1468,14 @@ describe("inccommand=nosplit", function()
-- non-modifier prefix
feed(':silent tabedit %s/tw/to')
screen:expect([[
+ Inc substitution on |
two lines |
Inc substitution on |
two lines |
|
{15:~ }|
{15:~ }|
- {15:~ }|
- {15:~ }|
+ {11: }|
:silent tabedit %s/t|
w/to^ |
]])
@@ -2656,6 +2655,7 @@ describe(":substitute", function()
feed("\\rѫ ab \\rXXXX")
screen:expect([[
+ 7 8 9 |
K L M |
{12:JLKR £} |
{12:ѫ ab } |
@@ -2667,8 +2667,7 @@ describe(":substitute", function()
{12:ѫ ab } |
{11:[No Name] [+] }|
| 7| {12:JLKR £} |
- | 8|{12: ѫ ab } |
- {10:[Preview] }|
+ {11: }|
:%s/[a-z]/JLKR £\rѫ ab \rXXX|
X^ |
]])
@@ -3001,8 +3000,8 @@ it('long :%s/ with inccommand does not collapse cmdline', function()
feed(':%s/AAAAAAA', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A')
screen:expect([[
- {15:~ }|
- {15:~ }|
+ |
+ {11: }|
:%s/AAAAAAAA|
AAAAAAAAAAAA|
AAAAAAA^ |
diff --git a/test/functional/ui/inccommand_user_spec.lua b/test/functional/ui/inccommand_user_spec.lua
index b5816f6fe6..0b25d4f8d2 100644
--- a/test/functional/ui/inccommand_user_spec.lua
+++ b/test/functional/ui/inccommand_user_spec.lua
@@ -7,61 +7,82 @@ local feed = helpers.feed
local command = helpers.command
local assert_alive = helpers.assert_alive
--- Implements a :Replace command that works like :substitute.
+-- Implements a :Replace command that works like :substitute and has multibuffer support.
local setup_replace_cmd = [[
- local function show_replace_preview(buf, use_preview_win, preview_ns, preview_buf, matches)
+ local function show_replace_preview(use_preview_win, preview_ns, preview_buf, matches)
-- Find the width taken by the largest line number, used for padding the line numbers
local highest_lnum = math.max(matches[#matches][1], 1)
local highest_lnum_width = math.floor(math.log10(highest_lnum))
local preview_buf_line = 0
-
- vim.g.prevns = preview_ns
- vim.g.prevbuf = preview_buf
+ local multibuffer = #matches > 1
for _, match in ipairs(matches) do
- local lnum = match[1]
- local line_matches = match[2]
- local prefix
-
- if use_preview_win then
- prefix = string.format(
- '|%s%d| ',
- string.rep(' ', highest_lnum_width - math.floor(math.log10(lnum))),
- lnum
- )
+ local buf = match[1]
+ local buf_matches = match[2]
+
+ if multibuffer and #buf_matches > 0 and use_preview_win then
+ local bufname = vim.api.nvim_buf_get_name(buf)
+
+ if bufname == "" then
+ bufname = string.format("Buffer #%d", buf)
+ end
vim.api.nvim_buf_set_lines(
preview_buf,
preview_buf_line,
preview_buf_line,
0,
- { prefix .. vim.api.nvim_buf_get_lines(buf, lnum - 1, lnum, false)[1] }
+ { bufname .. ':' }
)
+
+ preview_buf_line = preview_buf_line + 1
end
- for _, line_match in ipairs(line_matches) do
- vim.api.nvim_buf_add_highlight(
- buf,
- preview_ns,
- 'Substitute',
- lnum - 1,
- line_match[1],
- line_match[2]
- )
+ for _, buf_match in ipairs(buf_matches) do
+ local lnum = buf_match[1]
+ local line_matches = buf_match[2]
+ local prefix
if use_preview_win then
- vim.api.nvim_buf_add_highlight(
+ prefix = string.format(
+ '|%s%d| ',
+ string.rep(' ', highest_lnum_width - math.floor(math.log10(lnum))),
+ lnum
+ )
+
+ vim.api.nvim_buf_set_lines(
preview_buf,
+ preview_buf_line,
+ preview_buf_line,
+ 0,
+ { prefix .. vim.api.nvim_buf_get_lines(buf, lnum - 1, lnum, false)[1] }
+ )
+ end
+
+ for _, line_match in ipairs(line_matches) do
+ vim.api.nvim_buf_add_highlight(
+ buf,
preview_ns,
'Substitute',
- preview_buf_line,
- #prefix + line_match[1],
- #prefix + line_match[2]
+ lnum - 1,
+ line_match[1],
+ line_match[2]
)
+
+ if use_preview_win then
+ vim.api.nvim_buf_add_highlight(
+ preview_buf,
+ preview_ns,
+ 'Substitute',
+ preview_buf_line,
+ #prefix + line_match[1],
+ #prefix + line_match[2]
+ )
+ end
end
- end
- preview_buf_line = preview_buf_line + 1
+ preview_buf_line = preview_buf_line + 1
+ end
end
if use_preview_win then
@@ -72,94 +93,121 @@ local setup_replace_cmd = [[
end
local function do_replace(opts, preview, preview_ns, preview_buf)
- local pat1 = opts.fargs[1] or ''
+ local pat1 = opts.fargs[1]
+
+ if not pat1 then return end
+
local pat2 = opts.fargs[2] or ''
local line1 = opts.line1
local line2 = opts.line2
-
- local buf = vim.api.nvim_get_current_buf()
- local lines = vim.api.nvim_buf_get_lines(buf, line1 - 1, line2, 0)
local matches = {}
- for i, line in ipairs(lines) do
- local startidx, endidx = 0, 0
- local line_matches = {}
- local num = 1
+ -- Get list of valid and listed buffers
+ local buffers = vim.tbl_filter(
+ function(buf)
+ if not (vim.api.nvim_buf_is_valid(buf) and vim.bo[buf].buflisted and buf ~= preview_buf)
+ then
+ return false
+ end
- while startidx ~= -1 do
- local match = vim.fn.matchstrpos(line, pat1, 0, num)
- startidx, endidx = match[2], match[3]
+ -- Check if there's at least one window using the buffer
+ for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do
+ if vim.api.nvim_win_get_buf(win) == buf then
+ return true
+ end
+ end
- if startidx ~= -1 then
- line_matches[#line_matches+1] = { startidx, endidx }
- end
+ return false
+ end,
+ vim.api.nvim_list_bufs()
+ )
- num = num + 1
- end
+ for _, buf in ipairs(buffers) do
+ local lines = vim.api.nvim_buf_get_lines(buf, line1 - 1, line2, false)
+ local buf_matches = {}
- if #line_matches > 0 then
- matches[#matches+1] = { line1 + i - 1, line_matches }
- end
- end
+ for i, line in ipairs(lines) do
+ local startidx, endidx = 0, 0
+ local line_matches = {}
+ local num = 1
- local new_lines = {}
+ while startidx ~= -1 do
+ local match = vim.fn.matchstrpos(line, pat1, 0, num)
+ startidx, endidx = match[2], match[3]
- for _, match in ipairs(matches) do
- local lnum = match[1]
- local line_matches = match[2]
- local line = lines[lnum - line1 + 1]
- local pat_width_differences = {}
-
- -- If previewing, only replace the text in current buffer if pat2 isn't empty
- -- Otherwise, always replace the text
- if pat2 ~= '' or not preview then
- if preview then
- for _, line_match in ipairs(line_matches) do
- local startidx, endidx = unpack(line_match)
- local pat_match = line:sub(startidx + 1, endidx)
-
- pat_width_differences[#pat_width_differences+1] =
- #vim.fn.substitute(pat_match, pat1, pat2, 'g') - #pat_match
+ if startidx ~= -1 then
+ line_matches[#line_matches+1] = { startidx, endidx }
end
+
+ num = num + 1
end
- new_lines[lnum] = vim.fn.substitute(line, pat1, pat2, 'g')
+ if #line_matches > 0 then
+ buf_matches[#buf_matches+1] = { line1 + i - 1, line_matches }
+ end
end
- -- Highlight the matches if previewing
- if preview then
- local idx_offset = 0
- for i, line_match in ipairs(line_matches) do
- local startidx, endidx = unpack(line_match)
- -- Starting index of replacement text
- local repl_startidx = startidx + idx_offset
- -- Ending index of the replacement text (if pat2 isn't empty)
- local repl_endidx
-
- if pat2 ~= '' then
- repl_endidx = endidx + idx_offset + pat_width_differences[i]
- else
- repl_endidx = endidx + idx_offset
+ local new_lines = {}
+
+ for _, buf_match in ipairs(buf_matches) do
+ local lnum = buf_match[1]
+ local line_matches = buf_match[2]
+ local line = lines[lnum - line1 + 1]
+ local pat_width_differences = {}
+
+ -- If previewing, only replace the text in current buffer if pat2 isn't empty
+ -- Otherwise, always replace the text
+ if pat2 ~= '' or not preview then
+ if preview then
+ for _, line_match in ipairs(line_matches) do
+ local startidx, endidx = unpack(line_match)
+ local pat_match = line:sub(startidx + 1, endidx)
+
+ pat_width_differences[#pat_width_differences+1] =
+ #vim.fn.substitute(pat_match, pat1, pat2, 'g') - #pat_match
+ end
end
- if pat2 ~= '' then
- idx_offset = idx_offset + pat_width_differences[i]
- end
+ new_lines[lnum] = vim.fn.substitute(line, pat1, pat2, 'g')
+ end
- line_matches[i] = { repl_startidx, repl_endidx }
+ -- Highlight the matches if previewing
+ if preview then
+ local idx_offset = 0
+ for i, line_match in ipairs(line_matches) do
+ local startidx, endidx = unpack(line_match)
+ -- Starting index of replacement text
+ local repl_startidx = startidx + idx_offset
+ -- Ending index of the replacement text (if pat2 isn't empty)
+ local repl_endidx
+
+ if pat2 ~= '' then
+ repl_endidx = endidx + idx_offset + pat_width_differences[i]
+ else
+ repl_endidx = endidx + idx_offset
+ end
+
+ if pat2 ~= '' then
+ idx_offset = idx_offset + pat_width_differences[i]
+ end
+
+ line_matches[i] = { repl_startidx, repl_endidx }
+ end
end
end
- end
- for lnum, line in pairs(new_lines) do
- vim.api.nvim_buf_set_lines(buf, lnum - 1, lnum, false, { line })
+ for lnum, line in pairs(new_lines) do
+ vim.api.nvim_buf_set_lines(buf, lnum - 1, lnum, false, { line })
+ end
+
+ matches[#matches+1] = { buf, buf_matches }
end
if preview then
local lnum = vim.api.nvim_win_get_cursor(0)[1]
-- Use preview window only if preview buffer is provided and range isn't just the current line
local use_preview_win = (preview_buf ~= nil) and (line1 ~= lnum or line2 ~= lnum)
- return show_replace_preview(buf, use_preview_win, preview_ns, preview_buf, matches)
+ return show_replace_preview(use_preview_win, preview_ns, preview_buf, matches)
end
end
@@ -354,3 +402,120 @@ describe("'inccommand' for user commands", function()
assert_alive()
end)
end)
+
+describe("'inccommand' with multiple buffers", function()
+ local screen
+
+ before_each(function()
+ clear()
+ screen = Screen.new(40, 17)
+ screen:set_default_attr_ids({
+ [1] = {background = Screen.colors.Yellow1},
+ [2] = {foreground = Screen.colors.Blue1, bold = true},
+ [3] = {reverse = true},
+ [4] = {reverse = true, bold = true}
+ })
+ screen:attach()
+ exec_lua(setup_replace_cmd)
+ command('set cmdwinheight=10')
+ insert[[
+ foo bar baz
+ bar baz foo
+ baz foo bar
+ ]]
+ command('vsplit | enew')
+ insert[[
+ bar baz foo
+ baz foo bar
+ foo bar baz
+ ]]
+ end)
+
+ it('works', function()
+ command('set inccommand=nosplit')
+ feed(':Replace foo bar')
+ screen:expect([[
+ bar baz {1:bar} │ {1:bar} bar baz |
+ baz {1:bar} bar │ bar baz {1:bar} |
+ {1:bar} bar baz │ baz {1:bar} bar |
+ │ |
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {4:[No Name] [+] }{3:[No Name] [+] }|
+ :Replace foo bar^ |
+ ]])
+ feed('<CR>')
+ screen:expect([[
+ bar baz bar │ bar bar baz |
+ baz bar bar │ bar baz bar |
+ bar bar baz │ baz bar bar |
+ ^ │ |
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {4:[No Name] [+] }{3:[No Name] [+] }|
+ :Replace foo bar |
+ ]])
+ end)
+
+ it('works with inccommand=split', function()
+ command('set inccommand=split')
+ feed(':Replace foo bar')
+ screen:expect([[
+ bar baz {1:bar} │ {1:bar} bar baz |
+ baz {1:bar} bar │ bar baz {1:bar} |
+ {1:bar} bar baz │ baz {1:bar} bar |
+ │ |
+ {4:[No Name] [+] }{3:[No Name] [+] }|
+ Buffer #1: |
+ |1| {1:bar} bar baz |
+ |2| bar baz {1:bar} |
+ |3| baz {1:bar} bar |
+ Buffer #2: |
+ |1| bar baz {1:bar} |
+ |2| baz {1:bar} bar |
+ |3| {1:bar} bar baz |
+ |
+ {2:~ }|
+ {3:[Preview] }|
+ :Replace foo bar^ |
+ ]])
+ feed('<CR>')
+ screen:expect([[
+ bar baz bar │ bar bar baz |
+ baz bar bar │ bar baz bar |
+ bar bar baz │ baz bar bar |
+ ^ │ |
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {2:~ }│{2:~ }|
+ {4:[No Name] [+] }{3:[No Name] [+] }|
+ :Replace foo bar |
+ ]])
+ end)
+end)
diff --git a/test/functional/ui/input_spec.lua b/test/functional/ui/input_spec.lua
index 0f4e97088c..05d55b94fb 100644
--- a/test/functional/ui/input_spec.lua
+++ b/test/functional/ui/input_spec.lua
@@ -321,13 +321,14 @@ describe('input non-printable chars', function()
it("doesn't crash when echoing them back", function()
write_file("Xtest-overwrite", [[foobar]])
local screen = Screen.new(60,8)
- screen:set_default_attr_ids({
- [1] = {bold = true, foreground = Screen.colors.Blue1},
- [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
- [3] = {bold = true, foreground = Screen.colors.SeaGreen4}
- })
+ screen:set_default_attr_ids {
+ [1] = {bold = true, foreground = Screen.colors.Blue1};
+ [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red};
+ [3] = {bold = true, foreground = Screen.colors.SeaGreen4};
+ [4] = {bold = true, reverse = true};
+ }
screen:attach()
- command("set display-=msgsep shortmess-=F")
+ command("set shortmess-=F")
feed_command("e Xtest-overwrite")
screen:expect([[
@@ -346,11 +347,11 @@ describe('input non-printable chars', function()
write_file("Xtest-overwrite", [[smurf]])
feed_command("w")
screen:expect([[
+ foobar |
{1:~ }|
{1:~ }|
{1:~ }|
- {1:~ }|
- {1:~ }|
+ {4: }|
"Xtest-overwrite" |
{2:WARNING: The file has been changed since reading it!!!} |
{3:Do you really want to write to it (y/n)?}^ |
@@ -358,10 +359,10 @@ describe('input non-printable chars', function()
feed("u")
screen:expect([[
+ foobar |
{1:~ }|
{1:~ }|
- {1:~ }|
- {1:~ }|
+ {4: }|
"Xtest-overwrite" |
{2:WARNING: The file has been changed since reading it!!!} |
{3:Do you really want to write to it (y/n)?}u |
@@ -370,9 +371,9 @@ describe('input non-printable chars', function()
feed("\005")
screen:expect([[
+ foobar |
{1:~ }|
- {1:~ }|
- {1:~ }|
+ {4: }|
"Xtest-overwrite" |
{2:WARNING: The file has been changed since reading it!!!} |
{3:Do you really want to write to it (y/n)?}u |
@@ -382,8 +383,8 @@ describe('input non-printable chars', function()
feed("n")
screen:expect([[
- {1:~ }|
- {1:~ }|
+ foobar |
+ {4: }|
"Xtest-overwrite" |
{2:WARNING: The file has been changed since reading it!!!} |
{3:Do you really want to write to it (y/n)?}u |
diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua
index e7eaedba2d..522c9ccba2 100644
--- a/test/functional/ui/messages_spec.lua
+++ b/test/functional/ui/messages_spec.lua
@@ -1077,10 +1077,10 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim
]]}
end)
- it('redraws NOT_VALID correctly after message', function()
- -- edge case: only one window was set NOT_VALID. Original report
+ it('redraws UPD_NOT_VALID correctly after message', function()
+ -- edge case: only one window was set UPD_NOT_VALID. Original report
-- used :make, but fake it using one command to set the current
- -- window NOT_VALID and another to show a long message.
+ -- window UPD_NOT_VALID and another to show a long message.
command("set more")
feed(':new<cr><c-w><c-w>')
screen:expect{grid=[[
@@ -1243,6 +1243,19 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim
|
]])
end)
+
+ it('echo messages are shown correctly when getchar() immediately follows', function()
+ feed([[:echo 'foo' | echo 'bar' | call getchar()<CR>]])
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {3: }|
+ foo |
+ bar^ |
+ ]])
+ end)
end)
describe('ui/ext_messages', function()
diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua
index e389b7ab89..9896b11218 100644
--- a/test/functional/ui/mouse_spec.lua
+++ b/test/functional/ui/mouse_spec.lua
@@ -32,7 +32,7 @@ describe('ui/mouse/input', function()
[6] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
[7] = {bold = true, foreground = Screen.colors.SeaGreen4},
})
- command("set display-=msgsep mousemodel=extend")
+ command("set mousemodel=extend")
feed('itesting<cr>mouse<cr>support and selection<esc>')
screen:expect([[
testing |
diff --git a/test/functional/ui/multigrid_spec.lua b/test/functional/ui/multigrid_spec.lua
index b30aa67fd3..78a1e8c677 100644
--- a/test/functional/ui/multigrid_spec.lua
+++ b/test/functional/ui/multigrid_spec.lua
@@ -3,7 +3,9 @@ local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
local feed, command, insert = helpers.feed, helpers.command, helpers.insert
local eq = helpers.eq
+local funcs = helpers.funcs
local meths = helpers.meths
+local curwin = helpers.curwin
local poke_eventloop = helpers.poke_eventloop
@@ -871,6 +873,15 @@ describe('ext_multigrid', function()
before_each(function()
screen:try_resize_grid(2, 60, 20)
end)
+
+ it('winwidth() winheight() getwininfo() return inner width and height #19743', function()
+ eq(60, funcs.winwidth(0))
+ eq(20, funcs.winheight(0))
+ local win_info = funcs.getwininfo(curwin().id)[1]
+ eq(60, win_info.width)
+ eq(20, win_info.height)
+ end)
+
it('gets written till grid width', function()
insert(('a'):rep(60).."\n")
diff --git a/test/functional/ui/output_spec.lua b/test/functional/ui/output_spec.lua
index 71c6410013..9bb067ed8e 100644
--- a/test/functional/ui/output_spec.lua
+++ b/test/functional/ui/output_spec.lua
@@ -100,45 +100,52 @@ describe("shell command :!", function()
pending('missing printf')
end
local screen = Screen.new(50, 4)
+ screen:set_default_attr_ids {
+ [1] = {bold = true, reverse = true};
+ [2] = {bold = true, foreground = Screen.colors.SeaGreen};
+ [3] = {foreground = Screen.colors.Blue};
+ }
screen:attach()
- command("set display-=msgsep")
-- Print TAB chars. #2958
feed([[:!printf '1\t2\t3'<CR>]])
- screen:expect([[
- ~ |
+ screen:expect{grid=[[
+ {1: }|
:!printf '1\t2\t3' |
1 2 3 |
- Press ENTER or type command to continue^ |
- ]])
+ {2:Press ENTER or type command to continue}^ |
+ ]]}
feed([[<CR>]])
+
-- Print BELL control code. #4338
screen.bell = false
feed([[:!printf '\007\007\007\007text'<CR>]])
screen:expect{grid=[[
- ~ |
+ {1: }|
:!printf '\007\007\007\007text' |
text |
- Press ENTER or type command to continue^ |
+ {2:Press ENTER or type command to continue}^ |
]], condition=function()
eq(true, screen.bell)
end}
feed([[<CR>]])
+
-- Print BS control code.
feed([[:echo system('printf ''\010\n''')<CR>]])
screen:expect([[
- ~ |
- ^H |
+ {1: }|
+ {3:^H} |
|
- Press ENTER or type command to continue^ |
+ {2:Press ENTER or type command to continue}^ |
]])
feed([[<CR>]])
+
-- Print LF control code.
feed([[:!printf '\n'<CR>]])
screen:expect([[
:!printf '\n' |
|
|
- Press ENTER or type command to continue^ |
+ {2:Press ENTER or type command to continue}^ |
]])
feed([[<CR>]])
end)
diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua
index 7b0005bcf1..dcd4ad3d9a 100644
--- a/test/functional/ui/popupmenu_spec.lua
+++ b/test/functional/ui/popupmenu_spec.lua
@@ -7,7 +7,6 @@ local insert = helpers.insert
local meths = helpers.meths
local command = helpers.command
local funcs = helpers.funcs
-local get_pathsep = helpers.get_pathsep
local eq = helpers.eq
local pcall_err = helpers.pcall_err
local exec_lua = helpers.exec_lua
@@ -1785,6 +1784,8 @@ describe('builtin popupmenu', function()
screen:try_resize(32,10)
command('set wildmenu')
command('set wildoptions=pum')
+ command('set shellslash')
+ command("cd test/functional/fixtures/wildpum")
feed(':sign ')
screen:expect([[
@@ -1800,7 +1801,7 @@ describe('builtin popupmenu', function()
:sign ^ |
]])
- feed('<tab>')
+ feed('<Tab>')
screen:expect([[
|
{1:~ }|
@@ -1814,21 +1815,215 @@ describe('builtin popupmenu', function()
:sign define^ |
]])
- feed('<left>')
+ feed('<Right><Right>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }{n: define }{1: }|
+ {1:~ }{n: jump }{1: }|
+ {1:~ }{s: list }{1: }|
+ {1:~ }{n: place }{1: }|
+ {1:~ }{n: undefine }{1: }|
+ {1:~ }{n: unplace }{1: }|
+ :sign list^ |
+ ]])
+
+ feed('<C-N>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }{n: define }{1: }|
+ {1:~ }{n: jump }{1: }|
+ {1:~ }{n: list }{1: }|
+ {1:~ }{s: place }{1: }|
+ {1:~ }{n: undefine }{1: }|
+ {1:~ }{n: unplace }{1: }|
+ :sign place^ |
+ ]])
+
+ feed('<C-P>')
screen:expect([[
|
{1:~ }|
{1:~ }|
{1:~ }{n: define }{1: }|
{1:~ }{n: jump }{1: }|
+ {1:~ }{s: list }{1: }|
+ {1:~ }{n: place }{1: }|
+ {1:~ }{n: undefine }{1: }|
+ {1:~ }{n: unplace }{1: }|
+ :sign list^ |
+ ]])
+
+ feed('<Left>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }{n: define }{1: }|
+ {1:~ }{s: jump }{1: }|
{1:~ }{n: list }{1: }|
{1:~ }{n: place }{1: }|
{1:~ }{n: undefine }{1: }|
{1:~ }{n: unplace }{1: }|
+ :sign jump^ |
+ ]])
+
+ -- pressing <C-E> should end completion and go back to the original match
+ feed('<C-E>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
:sign ^ |
]])
- feed('<left>')
+ -- pressing <C-Y> should select the current match and end completion
+ feed('<Tab><C-P><C-P><C-Y>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ :sign unplace^ |
+ ]])
+
+ -- showing popup menu in different columns in the cmdline
+ feed('<C-U>sign define <Tab>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }{s: culhl= }{1: }|
+ {1:~ }{n: icon= }{1: }|
+ {1:~ }{n: linehl= }{1: }|
+ {1:~ }{n: numhl= }{1: }|
+ {1:~ }{n: text= }{1: }|
+ {1:~ }{n: texthl= }{1: }|
+ :sign define culhl=^ |
+ ]])
+
+ feed('<Space><Tab>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }{s: culhl= }{1: }|
+ {1:~ }{n: icon= }{1: }|
+ {1:~ }{n: linehl= }{1: }|
+ {1:~ }{n: numhl= }{1: }|
+ {1:~ }{n: text= }{1: }|
+ {1:~ }{n: texthl= }{1: }|
+ :sign define culhl= culhl=^ |
+ ]])
+
+ feed('<C-U>e Xdi<Tab><Tab>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }{s: XdirA/ }{1: }|
+ {1:~ }{n: XfileA }{1: }|
+ :e Xdir/XdirA/^ |
+ ]])
+
+ -- Pressing <Down> on a directory name should go into that directory
+ feed('<Down>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }{s: XdirB/ }{1: }|
+ {1:~ }{n: XfileB }{1: }|
+ :e Xdir/XdirA/XdirB/^ |
+ ]])
+
+ -- Pressing <Up> on a directory name should go to the parent directory
+ feed('<Up>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }{s: XdirA/ }{1: }|
+ {1:~ }{n: XfileA }{1: }|
+ :e Xdir/XdirA/^ |
+ ]])
+
+ -- Pressing <C-A> when the popup menu is displayed should list all the
+ -- matches and remove the popup menu
+ feed(':<C-U>sign <Tab><C-A>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {4: }|
+ :sign define jump list place und|
+ efine unplace^ |
+ ]])
+
+ -- Pressing <Left> after that should move the cursor
+ feed('<Left>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {4: }|
+ :sign define jump list place und|
+ efine unplac^e |
+ ]])
+ feed('<End>')
+
+ -- Pressing <C-D> when the popup menu is displayed should remove the popup
+ -- menu
+ feed('<C-U>sign <Tab><C-D>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {4: }|
+ :sign define |
+ define |
+ :sign define^ |
+ ]])
+
+ -- Pressing <S-Tab> should open the popup menu with the last entry selected
+ feed('<C-U><CR>:sign <S-Tab><C-P>')
screen:expect([[
|
{1:~ }|
@@ -1837,23 +2032,195 @@ describe('builtin popupmenu', function()
{1:~ }{n: jump }{1: }|
{1:~ }{n: list }{1: }|
{1:~ }{n: place }{1: }|
+ {1:~ }{s: undefine }{1: }|
+ {1:~ }{n: unplace }{1: }|
+ :sign undefine^ |
+ ]])
+
+ -- Pressing <Esc> should close the popup menu and cancel the cmd line
+ feed('<C-U><CR>:sign <Tab><Esc>')
+ screen:expect([[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]])
+
+ -- Typing a character when the popup is open, should close the popup
+ feed(':sign <Tab>x')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ :sign definex^ |
+ ]])
+
+ -- When the popup is open, entering the cmdline window should close the popup
+ feed('<C-U>sign <Tab><C-F>')
+ screen:expect([[
+ |
+ {3:[No Name] }|
+ {1::}sign define |
+ {1::}sign define^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {4:[Command Line] }|
+ :sign define |
+ ]])
+ feed(':q<CR>')
+
+ -- After the last popup menu item, <C-N> should show the original string
+ feed(':sign u<Tab><C-N><C-N>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
{1:~ }{n: undefine }{1: }|
- {1:~ }{s: unplace }{1: }|
- :sign unplace^ |
+ {1:~ }{n: unplace }{1: }|
+ :sign u^ |
]])
- feed('x')
+ -- Use the popup menu for the command name
+ feed('<C-U>bu<Tab>')
screen:expect([[
|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
+ {s: bufdo }{1: }|
+ {n: buffer }{1: }|
+ {n: buffers }{1: }|
+ {n: bunload }{1: }|
+ :bufdo^ |
+ ]])
+
+ -- Pressing <BS> should remove the popup menu and erase the last character
+ feed('<C-E><C-U>sign <Tab><BS>')
+ screen:expect([[
+ |
+ {1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
- :sign unplacex^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ :sign defin^ |
+ ]])
+
+ -- Pressing <C-W> should remove the popup menu and erase the previous word
+ feed('<C-E><C-U>sign <Tab><C-W>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ :sign ^ |
+ ]])
+
+ -- Pressing <C-U> should remove the popup menu and erase the entire line
+ feed('<C-E><C-U>sign <Tab><C-U>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ :^ |
+ ]])
+
+ -- Using <C-E> to cancel the popup menu and then pressing <Up> should recall
+ -- the cmdline from history
+ feed('sign xyz<Esc>:sign <Tab><C-E><Up>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ :sign xyz^ |
+ ]])
+
+ feed('<esc>')
+
+ -- Check "list" still works
+ command('set wildmode=longest,list')
+ feed(':cn<Tab>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {4: }|
+ :cn |
+ cnewer cnoreabbrev |
+ cnext cnoremap |
+ cnfile cnoremenu |
+ :cn^ |
+ ]])
+ feed('s')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {4: }|
+ :cn |
+ cnewer cnoreabbrev |
+ cnext cnoremap |
+ cnfile cnoremenu |
+ :cns^ |
+ ]])
+
+ feed('<esc>')
+ command('set wildmode=full')
+
+ -- Tests a directory name contained full-width characters.
+ feed(':e あいう/<Tab>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }{s: 123 }{1: }|
+ {1:~ }{n: abc }{1: }|
+ {1:~ }{n: xyz }{1: }|
+ :e あいう/123^ |
]])
feed('<esc>')
@@ -1927,12 +2294,12 @@ describe('builtin popupmenu', function()
:b långfile^ |
]])
- -- special case: when patterns ends with "/", show menu items aligned
- -- after the "/"
feed('<esc>')
command("close")
command('set wildmode=full')
- command("cd test/functional/fixtures/")
+
+ -- special case: when patterns ends with "/", show menu items aligned
+ -- after the "/"
feed(':e compdir/<tab>')
screen:expect([[
|
@@ -1949,7 +2316,7 @@ describe('builtin popupmenu', function()
{1:~ }|
{1:~ }{s: file1 }{1: }|
{1:~ }{n: file2 }{1: }|
- :e compdir]]..get_pathsep()..[[file1^ |
+ :e compdir/file1^ |
]])
end)
@@ -2007,7 +2374,9 @@ describe('builtin popupmenu', function()
command('set wildoptions=pum')
command('set wildmode=longest,full')
- feed(':sign u<tab>')
+ -- With 'wildmode' set to 'longest,full', completing a match should display
+ -- the longest match, the wildmenu should not be displayed.
+ feed(':sign u<Tab>')
screen:expect{grid=[[
|
{1:~ }|
@@ -2020,7 +2389,8 @@ describe('builtin popupmenu', function()
]]}
eq(0, funcs.wildmenumode())
- feed('<tab>')
+ -- pressing <Tab> should display the wildmenu
+ feed('<Tab>')
screen:expect{grid=[[
|
{1:~ }|
@@ -2032,6 +2402,19 @@ describe('builtin popupmenu', function()
:sign undefine^ |
]]}
eq(1, funcs.wildmenumode())
+
+ -- pressing <Tab> second time should select the next entry in the menu
+ feed('<Tab>')
+ screen:expect{grid=[[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }{n: undefine }{1: }|
+ {1:~ }{s: unplace }{1: }|
+ :sign unplace^ |
+ ]]}
end)
it("'pumblend' RGB-color", function()
diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua
index ea98705394..6ee9e7b393 100644
--- a/test/functional/ui/screen.lua
+++ b/test/functional/ui/screen.lua
@@ -546,7 +546,7 @@ function Screen:_wait(check, flags)
return true
end
- run_session(self._session, flags.request_cb, notification_cb, nil, minimal_timeout)
+ local eof = run_session(self._session, flags.request_cb, notification_cb, nil, minimal_timeout)
if not did_flush then
err = "no flush received"
elseif not checked then
@@ -557,9 +557,9 @@ function Screen:_wait(check, flags)
end
end
- if not success_seen then
+ if not success_seen and not eof then
did_miminal_timeout = true
- run_session(self._session, flags.request_cb, notification_cb, nil, timeout-minimal_timeout)
+ eof = run_session(self._session, flags.request_cb, notification_cb, nil, timeout-minimal_timeout)
end
local did_warn = false
@@ -600,8 +600,10 @@ between asynchronous (feed(), nvim_input()) and synchronous API calls.
if err then
+ if eof then err = err..'\n\n'..eof[2] end
busted.fail(err, 3)
elseif did_warn then
+ if eof then print(eof[2]) end
local tb = debug.traceback()
local index = string.find(tb, '\n%s*%[C]')
print(string.sub(tb,1,index))
diff --git a/test/functional/ui/statusline_spec.lua b/test/functional/ui/statusline_spec.lua
index f3735c8e4c..add5144e1b 100644
--- a/test/functional/ui/statusline_spec.lua
+++ b/test/functional/ui/statusline_spec.lua
@@ -394,7 +394,7 @@ describe('global statusline', function()
meths.input_mouse('left', 'drag', '', 0, 14, 10)
eq(1, meths.get_option('cmdheight'))
meths.input_mouse('left', 'drag', '', 0, 15, 10)
- eq(0, meths.get_option('cmdheight'))
+ eq(1, meths.get_option('cmdheight'))
meths.input_mouse('left', 'drag', '', 0, 14, 10)
eq(1, meths.get_option('cmdheight'))
end)
diff --git a/test/functional/ui/wildmode_spec.lua b/test/functional/ui/wildmode_spec.lua
index 98398bc7a1..58ffa3bda8 100644
--- a/test/functional/ui/wildmode_spec.lua
+++ b/test/functional/ui/wildmode_spec.lua
@@ -461,20 +461,20 @@ end)
describe('command line completion', function()
local screen
before_each(function()
+ clear()
screen = Screen.new(40, 5)
screen:set_default_attr_ids({
[1] = {bold = true, foreground = Screen.colors.Blue1},
[2] = {foreground = Screen.colors.Grey0, background = Screen.colors.Yellow},
[3] = {bold = true, reverse = true},
})
+ screen:attach()
end)
after_each(function()
os.remove('Xtest-functional-viml-compl-dir')
end)
it('lists directories with empty PATH', function()
- clear()
- screen:attach()
local tmp = funcs.tempname()
command('e '.. tmp)
command('cd %:h')
@@ -491,8 +491,6 @@ 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>')
@@ -521,6 +519,58 @@ describe('command line completion', function()
:!echo $XTEST_1AaあB^ |
]])
end)
+
+ it('does not leak memory with <S-Tab> with wildmenu and only one match #19874', function()
+ meths.set_option('wildmenu', true)
+ meths.set_option('wildmode', 'full')
+ meths.set_option('wildoptions', 'pum')
+
+ feed(':sign unpla<S-Tab>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ :sign unplace^ |
+ ]])
+
+ feed('<Space>buff<Tab>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ :sign unplace buffer=^ |
+ ]])
+ end)
+
+ it('does not show matches with <S-Tab> without wildmenu with wildmode=full', function()
+ meths.set_option('wildmenu', false)
+ meths.set_option('wildmode', 'full')
+
+ feed(':sign <S-Tab>')
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ :sign unplace^ |
+ ]])
+ end)
+
+ it('shows matches with <S-Tab> without wildmenu with wildmode=list', function()
+ meths.set_option('wildmenu', false)
+ meths.set_option('wildmode', 'list')
+
+ feed(':sign <S-Tab>')
+ screen:expect([[
+ {3: }|
+ :sign define |
+ define list undefine |
+ jump place unplace |
+ :sign unplace^ |
+ ]])
+ end)
end)
describe('ui/ext_wildmenu', function()
diff --git a/test/functional/ui/winbar_spec.lua b/test/functional/ui/winbar_spec.lua
index 60fa10da87..ece27ec3ff 100644
--- a/test/functional/ui/winbar_spec.lua
+++ b/test/functional/ui/winbar_spec.lua
@@ -7,6 +7,8 @@ local meths = helpers.meths
local eq = helpers.eq
local poke_eventloop = helpers.poke_eventloop
local feed = helpers.feed
+local funcs = helpers.funcs
+local curwin = helpers.curwin
local pcall_err = helpers.pcall_err
describe('winbar', function()
@@ -48,6 +50,11 @@ describe('winbar', function()
{3:~ }|
|
]])
+ -- winbar is excluded from the heights returned by winheight() and getwininfo()
+ eq(11, funcs.winheight(0))
+ local win_info = funcs.getwininfo(curwin().id)[1]
+ eq(11, win_info.height)
+ eq(1, win_info.winbar)
end)
it('works with custom \'fillchars\' value', function()
@@ -579,47 +586,95 @@ describe('winbar', function()
end)
end)
-it('local winbar works with tabs', function()
- clear()
- local screen = Screen.new(60, 13)
- screen:attach()
- screen:set_default_attr_ids({
- [1] = {bold = true},
- [2] = {reverse = true},
- [3] = {bold = true, foreground = Screen.colors.Blue},
- [4] = {underline = true, background = Screen.colors.LightGray}
- })
- meths.set_option_value('winbar', 'foo', { scope = 'local', win = 0 })
- command('tabnew')
- screen:expect([[
- {4: [No Name] }{1: [No Name] }{2: }{4:X}|
- ^ |
- {3:~ }|
- {3:~ }|
- {3:~ }|
- {3:~ }|
- {3:~ }|
- {3:~ }|
- {3:~ }|
- {3:~ }|
- {3:~ }|
- {3:~ }|
- |
- ]])
- command('tabnext')
- screen:expect{grid=[[
- {1: [No Name] }{4: [No Name] }{2: }{4:X}|
- {1:foo }|
- ^ |
- {3:~ }|
- {3:~ }|
- {3:~ }|
- {3:~ }|
- {3:~ }|
- {3:~ }|
- {3:~ }|
- {3:~ }|
- {3:~ }|
- |
- ]]}
+describe('local winbar with tabs', function()
+ local screen
+ before_each(function()
+ clear()
+ screen = Screen.new(60, 10)
+ screen:attach()
+ screen:set_default_attr_ids({
+ [1] = {bold = true},
+ [2] = {reverse = true},
+ [3] = {bold = true, foreground = Screen.colors.Blue},
+ [4] = {underline = true, background = Screen.colors.LightGray}
+ })
+ meths.set_option_value('winbar', 'foo', { scope = 'local', win = 0 })
+ end)
+
+ it('works', function()
+ command('tabnew')
+ screen:expect([[
+ {4: [No Name] }{1: [No Name] }{2: }{4:X}|
+ ^ |
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ |
+ ]])
+ command('tabnext')
+ screen:expect{grid=[[
+ {1: [No Name] }{4: [No Name] }{2: }{4:X}|
+ {1:foo }|
+ ^ |
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ |
+ ]]}
+ end)
+
+ it('can edit new empty buffer #19458', function()
+ insert [[
+ some
+ goofy
+ text]]
+ screen:expect{grid=[[
+ {1:foo }|
+ some |
+ goofy |
+ tex^t |
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ |
+ ]]}
+
+ -- this used to throw an E315 ml_get error
+ command 'tabedit'
+ screen:expect{grid=[[
+ {4: + [No Name] }{1: [No Name] }{2: }{4:X}|
+ ^ |
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ |
+ ]]}
+
+ command 'tabprev'
+ screen:expect{grid=[[
+ {1: + [No Name] }{4: [No Name] }{2: }{4:X}|
+ {1:foo }|
+ some |
+ goofy |
+ tex^t |
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ {3:~ }|
+ |
+ ]]}
+ end)
end)
diff --git a/test/functional/vimscript/eval_spec.lua b/test/functional/vimscript/eval_spec.lua
index 0c2ca8de78..d4fa7afe89 100644
--- a/test/functional/vimscript/eval_spec.lua
+++ b/test/functional/vimscript/eval_spec.lua
@@ -10,11 +10,13 @@
-- test/functional/vimscript/functions_spec.lua
local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
local lfs = require('lfs')
local clear = helpers.clear
local eq = helpers.eq
local exc_exec = helpers.exc_exec
+local exec = helpers.exec
local eval = helpers.eval
local command = helpers.command
local write_file = helpers.write_file
@@ -144,3 +146,104 @@ describe('List support code', function()
end
end)
end)
+
+-- oldtest: Test_deep_nest()
+it('Error when if/for/while/try/function is nested too deep',function()
+ clear()
+ local screen = Screen.new(80, 24)
+ screen:attach()
+ meths.set_option('laststatus', 2)
+ exec([[
+ " Deep nesting of if ... endif
+ func Test1()
+ let @a = join(repeat(['if v:true'], 51), "\n")
+ let @a ..= "\n"
+ let @a ..= join(repeat(['endif'], 51), "\n")
+ @a
+ let @a = ''
+ endfunc
+
+ " Deep nesting of for ... endfor
+ func Test2()
+ let @a = join(repeat(['for i in [1]'], 51), "\n")
+ let @a ..= "\n"
+ let @a ..= join(repeat(['endfor'], 51), "\n")
+ @a
+ let @a = ''
+ endfunc
+
+ " Deep nesting of while ... endwhile
+ func Test3()
+ let @a = join(repeat(['while v:true'], 51), "\n")
+ let @a ..= "\n"
+ let @a ..= join(repeat(['endwhile'], 51), "\n")
+ @a
+ let @a = ''
+ endfunc
+
+ " Deep nesting of try ... endtry
+ func Test4()
+ let @a = join(repeat(['try'], 51), "\n")
+ let @a ..= "\necho v:true\n"
+ let @a ..= join(repeat(['endtry'], 51), "\n")
+ @a
+ let @a = ''
+ endfunc
+
+ " Deep nesting of function ... endfunction
+ func Test5()
+ let @a = join(repeat(['function X()'], 51), "\n")
+ let @a ..= "\necho v:true\n"
+ let @a ..= join(repeat(['endfunction'], 51), "\n")
+ @a
+ let @a = ''
+ endfunc
+ ]])
+ screen:expect({any = '%[No Name%]'})
+ feed(':call Test1()<CR>')
+ screen:expect({any = 'E579: '})
+ feed('<C-C>')
+ screen:expect({any = '%[No Name%]'})
+ feed(':call Test2()<CR>')
+ screen:expect({any = 'E585: '})
+ feed('<C-C>')
+ screen:expect({any = '%[No Name%]'})
+ feed(':call Test3()<CR>')
+ screen:expect({any = 'E585: '})
+ feed('<C-C>')
+ screen:expect({any = '%[No Name%]'})
+ feed(':call Test4()<CR>')
+ screen:expect({any = 'E601: '})
+ feed('<C-C>')
+ screen:expect({any = '%[No Name%]'})
+ feed(':call Test5()<CR>')
+ screen:expect({any = 'E1058: '})
+end)
+
+describe("uncaught exception", function()
+ before_each(clear)
+ after_each(function()
+ os.remove('throw1.vim')
+ os.remove('throw2.vim')
+ os.remove('throw3.vim')
+ end)
+
+ it('is not forgotten #13490', function()
+ command('autocmd BufWinEnter * throw "i am error"')
+ eq('i am error', exc_exec('try | new | endtry'))
+
+ -- Like Vim, throwing here aborts the processing of the script, but does not stop :runtime!
+ -- from processing the others.
+ -- Only the first thrown exception should be rethrown from the :try below, though.
+ for i = 1, 3 do
+ write_file('throw' .. i .. '.vim', ([[
+ let result ..= '%d'
+ throw 'throw%d'
+ let result ..= 'X'
+ ]]):format(i, i))
+ end
+ command('set runtimepath+=. | let result = ""')
+ eq('throw1', exc_exec('try | runtime! throw*.vim | endtry'))
+ eq('123', eval('result'))
+ end)
+end)
diff --git a/test/functional/vimscript/input_spec.lua b/test/functional/vimscript/input_spec.lua
index 554d15e550..f50b39c2c5 100644
--- a/test/functional/vimscript/input_spec.lua
+++ b/test/functional/vimscript/input_spec.lua
@@ -8,7 +8,8 @@ local clear = helpers.clear
local source = helpers.source
local command = helpers.command
local exc_exec = helpers.exc_exec
-local nvim_async = helpers.nvim_async
+local pcall_err = helpers.pcall_err
+local async_meths = helpers.async_meths
local NIL = helpers.NIL
local screen
@@ -449,6 +450,78 @@ describe('inputdialog()', function()
end)
describe('confirm()', function()
+ -- oldtest: Test_confirm()
+ it('works', function()
+ meths.set_option('more', false) -- Avoid hit-enter prompt
+ meths.set_option('laststatus', 2)
+ -- screen:expect() calls are needed to avoid feeding input too early
+ screen:expect({any = '%[No Name%]'})
+
+ async_meths.command([[let a = confirm('Press O to proceed')]])
+ screen:expect({any = '{CONFIRM:.+: }'})
+ feed('o')
+ screen:expect({any = '%[No Name%]'})
+ eq(1, meths.get_var('a'))
+
+ async_meths.command([[let a = 'Are you sure?'->confirm("&Yes\n&No")]])
+ screen:expect({any = '{CONFIRM:.+: }'})
+ feed('y')
+ screen:expect({any = '%[No Name%]'})
+ eq(1, meths.get_var('a'))
+
+ async_meths.command([[let a = confirm('Are you sure?', "&Yes\n&No")]])
+ screen:expect({any = '{CONFIRM:.+: }'})
+ feed('n')
+ screen:expect({any = '%[No Name%]'})
+ eq(2, meths.get_var('a'))
+
+ -- Not possible to match Vim's CTRL-C test here as CTRL-C always sets got_int in Nvim.
+
+ -- confirm() should return 0 when pressing ESC.
+ async_meths.command([[let a = confirm('Are you sure?', "&Yes\n&No")]])
+ screen:expect({any = '{CONFIRM:.+: }'})
+ feed('<Esc>')
+ screen:expect({any = '%[No Name%]'})
+ eq(0, meths.get_var('a'))
+
+ -- Default choice is returned when pressing <CR>.
+ async_meths.command([[let a = confirm('Are you sure?', "&Yes\n&No")]])
+ screen:expect({any = '{CONFIRM:.+: }'})
+ feed('<CR>')
+ screen:expect({any = '%[No Name%]'})
+ eq(1, meths.get_var('a'))
+
+ async_meths.command([[let a = confirm('Are you sure?', "&Yes\n&No", 2)]])
+ screen:expect({any = '{CONFIRM:.+: }'})
+ feed('<CR>')
+ screen:expect({any = '%[No Name%]'})
+ eq(2, meths.get_var('a'))
+
+ async_meths.command([[let a = confirm('Are you sure?', "&Yes\n&No", 0)]])
+ screen:expect({any = '{CONFIRM:.+: }'})
+ feed('<CR>')
+ screen:expect({any = '%[No Name%]'})
+ eq(0, meths.get_var('a'))
+
+ -- Test with the {type} 4th argument
+ for _, type in ipairs({'Error', 'Question', 'Info', 'Warning', 'Generic'}) do
+ async_meths.command(([[let a = confirm('Are you sure?', "&Yes\n&No", 1, '%s')]]):format(type))
+ screen:expect({any = '{CONFIRM:.+: }'})
+ feed('y')
+ screen:expect({any = '%[No Name%]'})
+ eq(1, meths.get_var('a'))
+ end
+
+ eq('Vim(call):E730: using List as a String',
+ pcall_err(command, 'call confirm([])'))
+ eq('Vim(call):E730: using List as a String',
+ pcall_err(command, 'call confirm("Are you sure?", [])'))
+ eq('Vim(call):E745: Using a List as a Number',
+ pcall_err(command, 'call confirm("Are you sure?", "&Yes\n&No\n", [])'))
+ eq('Vim(call):E730: using List as a String',
+ pcall_err(command, 'call confirm("Are you sure?", "&Yes\n&No\n", 0, [])'))
+ end)
+
it("shows dialog even if :silent #8788", function()
command("autocmd BufNewFile * call confirm('test')")
@@ -483,7 +556,7 @@ describe('confirm()', function()
feed(':call nvim_command("edit x")<cr>')
check_and_clear(':call nvim_command("edit |\n')
- nvim_async('command', 'edit x')
+ async_meths.command('edit x')
check_and_clear(' |\n')
end)
end)
diff --git a/test/functional/vimscript/null_spec.lua b/test/functional/vimscript/null_spec.lua
index f23f00bcc5..2451da983e 100644
--- a/test/functional/vimscript/null_spec.lua
+++ b/test/functional/vimscript/null_spec.lua
@@ -135,7 +135,7 @@ describe('NULL', function()
null_test('does not make Neovim crash when v:oldfiles gets assigned to that', ':let v:oldfiles = L|oldfiles', 0)
null_expr_test('does not make complete() crash or error out',
'execute(":normal i\\<C-r>=complete(1, L)[-1]\\n")',
- '', '\n', function()
+ 0, '', function()
eq({''}, curbufmeths.get_lines(0, -1, false))
end)
null_expr_test('is accepted by setmatches()', 'setmatches(L)', 0, 0)
diff --git a/test/functional/vimscript/special_vars_spec.lua b/test/functional/vimscript/special_vars_spec.lua
index 97a12d490d..14ccbc3827 100644
--- a/test/functional/vimscript/special_vars_spec.lua
+++ b/test/functional/vimscript/special_vars_spec.lua
@@ -125,9 +125,9 @@ describe('Special values', function()
end)
it('work with . (concat) properly', function()
- eq("true", eval('"" . v:true'))
- eq("null", eval('"" . v:null'))
- eq("false", eval('"" . v:false'))
+ eq("v:true", eval('"" . v:true'))
+ eq("v:null", eval('"" . v:null'))
+ eq("v:false", eval('"" . v:false'))
end)
it('work with type()', function()