aboutsummaryrefslogtreecommitdiff
path: root/test/functional/terminal
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/terminal')
-rw-r--r--test/functional/terminal/api_spec.lua8
-rw-r--r--test/functional/terminal/buffer_spec.lua1
-rw-r--r--test/functional/terminal/channel_spec.lua87
-rw-r--r--test/functional/terminal/cursor_spec.lua60
-rw-r--r--test/functional/terminal/edit_spec.lua5
-rw-r--r--test/functional/terminal/ex_terminal_spec.lua17
-rw-r--r--test/functional/terminal/helpers.lua10
-rw-r--r--test/functional/terminal/highlight_spec.lua25
-rw-r--r--test/functional/terminal/mouse_spec.lua30
-rw-r--r--test/functional/terminal/scrollback_spec.lua47
-rw-r--r--test/functional/terminal/tui_spec.lua260
-rw-r--r--test/functional/terminal/window_spec.lua1
12 files changed, 475 insertions, 76 deletions
diff --git a/test/functional/terminal/api_spec.lua b/test/functional/terminal/api_spec.lua
index e28cc03597..5305b8af9c 100644
--- a/test/functional/terminal/api_spec.lua
+++ b/test/functional/terminal/api_spec.lua
@@ -6,7 +6,7 @@ if helpers.pending_win32(pending) then return end
describe('api', function()
local screen
- local socket_name = "Xtest_functional_api.sock"
+ local socket_name = "./Xtest_functional_api.sock"
before_each(function()
helpers.clear()
@@ -29,7 +29,7 @@ describe('api', function()
{4:~ }|
{4:~ }|
{4:~ }|
- ]]..socket_name..[[ |
+ ]]..socket_name..[[ |
{3:-- TERMINAL --} |
]])
@@ -48,8 +48,8 @@ describe('api', function()
{3:-- TERMINAL --} |
]])
- ok(socket_session1:request("nvim_ui_attach", 42, 6, {rgb=true}))
- ok(socket_session2:request("nvim_ui_attach", 25, 30, {rgb=true}))
+ ok((socket_session1:request("nvim_ui_attach", 42, 6, {rgb=true})))
+ ok((socket_session2:request("nvim_ui_attach", 25, 30, {rgb=true})))
socket_session1:notify("nvim_input", "\n[socket 1] this is more than 25 columns")
socket_session2:notify("nvim_input", "\n[socket 2] input")
diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua
index beb43e0271..1cef771f0d 100644
--- a/test/functional/terminal/buffer_spec.lua
+++ b/test/functional/terminal/buffer_spec.lua
@@ -258,6 +258,7 @@ describe(':terminal buffer', function()
end)
it('it works with set rightleft #11438', function()
+ if helpers.pending_win32(pending) then return end
local columns = eval('&columns')
feed(string.rep('a', columns))
command('set rightleft')
diff --git a/test/functional/terminal/channel_spec.lua b/test/functional/terminal/channel_spec.lua
index 7223f5ba61..b5f3c2bd31 100644
--- a/test/functional/terminal/channel_spec.lua
+++ b/test/functional/terminal/channel_spec.lua
@@ -1,45 +1,94 @@
local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
local eq = helpers.eq
+local eval = helpers.eval
local command = helpers.command
local pcall_err = helpers.pcall_err
local feed = helpers.feed
-local sleep = helpers.sleep
local poke_eventloop = helpers.poke_eventloop
-describe('associated channel is closed and later freed for terminal', function()
- before_each(clear)
+describe('terminal channel is closed and later released if', function()
+ local screen
+
+ before_each(function()
+ clear()
+ screen = Screen.new()
+ screen:attach()
+ end)
it('opened by nvim_open_term() and deleted by :bdelete!', function()
command([[let id = nvim_open_term(0, {})]])
- -- channel hasn't been freed yet
- eq("Vim(call):Can't send data to closed stream", pcall_err(command, [[bdelete! | call chansend(id, 'test')]]))
- -- channel has been freed after one main loop iteration
- eq("Vim(call):E900: Invalid channel id", pcall_err(command, [[call chansend(id, 'test')]]))
+ local chans = eval('len(nvim_list_chans())')
+ -- channel hasn't been released yet
+ eq("Vim(call):Can't send data to closed stream",
+ pcall_err(command, [[bdelete! | call chansend(id, 'test')]]))
+ -- channel has been released after one main loop iteration
+ eq(chans - 1, eval('len(nvim_list_chans())'))
+ end)
+
+ it('opened by nvim_open_term(), closed by chanclose(), and deleted by pressing a key', function()
+ command('let id = nvim_open_term(0, {})')
+ local chans = eval('len(nvim_list_chans())')
+ -- channel has been closed but not released
+ eq("Vim(call):Can't send data to closed stream",
+ pcall_err(command, [[call chanclose(id) | call chansend(id, 'test')]]))
+ screen:expect({any='%[Terminal closed%]'})
+ eq(chans, eval('len(nvim_list_chans())'))
+ -- delete terminal
+ feed('i<CR>')
+ -- need to first process input
+ poke_eventloop()
+ -- channel has been released after another main loop iteration
+ eq(chans - 1, eval('len(nvim_list_chans())'))
+ end)
+
+ it('opened by nvim_open_term(), closed by chanclose(), and deleted by :bdelete', function()
+ command('let id = nvim_open_term(0, {})')
+ local chans = eval('len(nvim_list_chans())')
+ -- channel has been closed but not released
+ eq("Vim(call):Can't send data to closed stream",
+ pcall_err(command, [[call chanclose(id) | call chansend(id, 'test')]]))
+ screen:expect({any='%[Terminal closed%]'})
+ eq(chans, eval('len(nvim_list_chans())'))
+ -- channel still hasn't been released yet
+ eq("Vim(call):Can't send data to closed stream",
+ pcall_err(command, [[bdelete | call chansend(id, 'test')]]))
+ -- channel has been released after one main loop iteration
+ eq(chans - 1, eval('len(nvim_list_chans())'))
end)
it('opened by termopen(), exited, and deleted by pressing a key', function()
command([[let id = termopen('echo')]])
- sleep(500)
- -- process has exited
- eq("Vim(call):Can't send data to closed stream", pcall_err(command, [[call chansend(id, 'test')]]))
+ local chans = eval('len(nvim_list_chans())')
+ -- wait for process to exit
+ screen:expect({any='%[Process exited 0%]'})
+ -- process has exited but channel has't been released
+ eq("Vim(call):Can't send data to closed stream",
+ pcall_err(command, [[call chansend(id, 'test')]]))
+ eq(chans, eval('len(nvim_list_chans())'))
-- delete terminal
feed('i<CR>')
-- need to first process input
poke_eventloop()
- -- channel has been freed after another main loop iteration
- eq("Vim(call):E900: Invalid channel id", pcall_err(command, [[call chansend(id, 'test')]]))
+ -- channel has been released after another main loop iteration
+ eq(chans - 1, eval('len(nvim_list_chans())'))
end)
-- This indirectly covers #16264
it('opened by termopen(), exited, and deleted by :bdelete', function()
command([[let id = termopen('echo')]])
- sleep(500)
- -- process has exited
- eq("Vim(call):Can't send data to closed stream", pcall_err(command, [[call chansend(id, 'test')]]))
- -- channel hasn't been freed yet
- eq("Vim(call):Can't send data to closed stream", pcall_err(command, [[bdelete | call chansend(id, 'test')]]))
- -- channel has been freed after one main loop iteration
- eq("Vim(call):E900: Invalid channel id", pcall_err(command, [[call chansend(id, 'test')]]))
+ local chans = eval('len(nvim_list_chans())')
+ -- wait for process to exit
+ screen:expect({any='%[Process exited 0%]'})
+ -- process has exited but channel hasn't been released
+ eq("Vim(call):Can't send data to closed stream",
+ pcall_err(command, [[call chansend(id, 'test')]]))
+ eq(chans, eval('len(nvim_list_chans())'))
+ -- channel still hasn't been released yet
+ eq("Vim(call):Can't send data to closed stream",
+ pcall_err(command, [[bdelete | call chansend(id, 'test')]]))
+ -- channel has been released after one main loop iteration
+ eq(chans - 1, eval('len(nvim_list_chans())'))
end)
end)
diff --git a/test/functional/terminal/cursor_spec.lua b/test/functional/terminal/cursor_spec.lua
index e9495f45a2..2d1c790d2f 100644
--- a/test/functional/terminal/cursor_spec.lua
+++ b/test/functional/terminal/cursor_spec.lua
@@ -2,9 +2,10 @@ local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local thelpers = require('test.functional.terminal.helpers')
local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim
-local nvim_dir, command = helpers.nvim_dir, helpers.command
+local testprg, command = helpers.testprg, helpers.command
local nvim_prog = helpers.nvim_prog
local eq, eval = helpers.eq, helpers.eval
+local matches = helpers.matches
local feed_command = helpers.feed_command
local hide_cursor = thelpers.hide_cursor
local show_cursor = thelpers.show_cursor
@@ -87,6 +88,7 @@ describe(':terminal cursor', function()
describe('when invisible', function()
it('is not highlighted and is detached from screen cursor', function()
+ if helpers.pending_win32(pending) then return end
hide_cursor()
screen:expect([[
tty ready |
@@ -148,7 +150,7 @@ describe('cursor with customized highlighting', function()
[3] = {bold = true},
})
screen:attach({rgb=false})
- command('call termopen(["'..nvim_dir..'/tty-test"])')
+ command('call termopen(["'..testprg('tty-test')..'"])')
feed_command('startinsert')
end)
@@ -523,6 +525,33 @@ describe('buffer cursor position is correct in terminal without number column',
eq({6, 1}, eval('nvim_win_get_cursor(0)'))
end)
end)
+
+ it('at the end of a line with trailing spaces #16234', function()
+ setup_ex_register('aaaaaaaa ')
+ feed('<C-R>r')
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :aaaaaaaa {1: } |
+ {3:-- TERMINAL --} |
+ ]])
+ matches('^:aaaaaaaa [ ]*$', eval('nvim_get_current_line()'))
+ eq({6, 13}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ |
+ |
+ |
+ |
+ Entering Ex mode. Type "visual" to go to Normal mode. |
+ :aaaaaaaa ^ {2: } |
+ |
+ ]])
+ eq({6, 12}, eval('nvim_win_get_cursor(0)'))
+ end)
end)
describe('buffer cursor position is correct in terminal with number column', function()
@@ -876,4 +905,31 @@ describe('buffer cursor position is correct in terminal with number column', fun
eq({6, 1}, eval('nvim_win_get_cursor(0)'))
end)
end)
+
+ it('at the end of a line with trailing spaces #16234', function()
+ setup_ex_register('aaaaaaaa ')
+ feed('<C-R>r')
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:aaaaaaaa {1: } |
+ {3:-- TERMINAL --} |
+ ]])
+ matches('^:aaaaaaaa [ ]*$', eval('nvim_get_current_line()'))
+ eq({6, 13}, eval('nvim_win_get_cursor(0)'))
+ feed([[<C-\><C-N>]])
+ screen:expect([[
+ {7: 1 } |
+ {7: 2 } |
+ {7: 3 } |
+ {7: 4 } |
+ {7: 5 }Entering Ex mode. Type "visual" to go to Normal mode. |
+ {7: 6 }:aaaaaaaa ^ {2: } |
+ |
+ ]])
+ eq({6, 12}, eval('nvim_win_get_cursor(0)'))
+ end)
end)
diff --git a/test/functional/terminal/edit_spec.lua b/test/functional/terminal/edit_spec.lua
index fabc5524ed..aeb4b7cc2e 100644
--- a/test/functional/terminal/edit_spec.lua
+++ b/test/functional/terminal/edit_spec.lua
@@ -3,7 +3,7 @@ local screen = require('test.functional.ui.screen')
local curbufmeths = helpers.curbufmeths
local curwinmeths = helpers.curwinmeths
-local nvim_dir = helpers.nvim_dir
+local testprg = helpers.testprg
local command = helpers.command
local funcs = helpers.funcs
local meths = helpers.meths
@@ -21,7 +21,7 @@ describe(':edit term://*', function()
before_each(function()
clear()
- meths.set_option('shell', nvim_dir .. '/shell-test')
+ meths.set_option('shell', testprg('shell-test'))
meths.set_option('shellcmdflag', 'EXE')
end)
@@ -36,6 +36,7 @@ describe(':edit term://*', function()
end)
it("runs TermOpen early enough to set buffer-local 'scrollback'", function()
+ if helpers.pending_win32(pending) then return end
local columns, lines = 20, 4
local scr = get_screen(columns, lines)
local rep = 97
diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua
index 065dd72485..23b69319f0 100644
--- a/test/functional/terminal/ex_terminal_spec.lua
+++ b/test/functional/terminal/ex_terminal_spec.lua
@@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local assert_alive = helpers.assert_alive
local clear, poke_eventloop, nvim = helpers.clear, helpers.poke_eventloop, helpers.nvim
-local nvim_dir, source, eq = helpers.nvim_dir, helpers.source, helpers.eq
+local testprg, source, eq = helpers.testprg, helpers.source, helpers.eq
local feed = helpers.feed
local feed_command, eval = helpers.feed_command, helpers.eval
local funcs = helpers.funcs
@@ -28,7 +28,7 @@ describe(':terminal', function()
echomsg "msg3"
]])
-- Invoke a command that emits frequent terminal activity.
- feed([[:terminal "]]..nvim_dir..[[/shell-test" REP 9999 !terminal_output!<cr>]])
+ feed([[:terminal "]]..testprg('shell-test')..[[" REP 9999 !terminal_output!<cr>]])
feed([[<C-\><C-N>]])
poke_eventloop()
-- Wait for some terminal activity.
@@ -131,7 +131,7 @@ describe(':terminal (with fake shell)', function()
screen = Screen.new(50, 4)
screen:attach({rgb=false})
-- shell-test.c is a fake shell that prints its arguments and exits.
- nvim('set_option', 'shell', nvim_dir..'/shell-test')
+ nvim('set_option', 'shell', testprg('shell-test'))
nvim('set_option', 'shellcmdflag', 'EXE')
end)
@@ -142,6 +142,7 @@ describe(':terminal (with fake shell)', function()
end
it('with no argument, acts like termopen()', function()
+ if helpers.pending_win32(pending) then return end
terminal_with_fake_shell()
retry(nil, 4 * screen.timeout, function()
screen:expect([[
@@ -165,7 +166,8 @@ describe(':terminal (with fake shell)', function()
end)
it("with no argument, but 'shell' has arguments, acts like termopen()", function()
- nvim('set_option', 'shell', nvim_dir..'/shell-test -t jeff')
+ if helpers.pending_win32(pending) then return end
+ nvim('set_option', 'shell', testprg('shell-test')..' -t jeff')
terminal_with_fake_shell()
screen:expect([[
^jeff $ |
@@ -176,6 +178,7 @@ describe(':terminal (with fake shell)', function()
end)
it('executes a given command through the shell', function()
+ if helpers.pending_win32(pending) then return end
command('set shellxquote=') -- win: avoid extra quotes
terminal_with_fake_shell('echo hi')
screen:expect([[
@@ -187,7 +190,8 @@ describe(':terminal (with fake shell)', function()
end)
it("executes a given command through the shell, when 'shell' has arguments", function()
- nvim('set_option', 'shell', nvim_dir..'/shell-test -t jeff')
+ if helpers.pending_win32(pending) then return end
+ nvim('set_option', 'shell', testprg('shell-test')..' -t jeff')
command('set shellxquote=') -- win: avoid extra quotes
terminal_with_fake_shell('echo hi')
screen:expect([[
@@ -199,6 +203,7 @@ describe(':terminal (with fake shell)', function()
end)
it('allows quotes and slashes', function()
+ if helpers.pending_win32(pending) then return end
command('set shellxquote=') -- win: avoid extra quotes
terminal_with_fake_shell([[echo 'hello' \ "world"]])
screen:expect([[
@@ -235,6 +240,7 @@ describe(':terminal (with fake shell)', function()
end)
it('works with :find', function()
+ if helpers.pending_win32(pending) then return end
terminal_with_fake_shell()
screen:expect([[
^ready $ |
@@ -253,6 +259,7 @@ describe(':terminal (with fake shell)', function()
end)
it('works with gf', function()
+ if helpers.pending_win32(pending) then return end
command('set shellxquote=') -- win: avoid extra quotes
terminal_with_fake_shell([[echo "scripts/shadacat.py"]])
retry(nil, 4 * screen.timeout, function()
diff --git a/test/functional/terminal/helpers.lua b/test/functional/terminal/helpers.lua
index d909888613..bcfd3559e6 100644
--- a/test/functional/terminal/helpers.lua
+++ b/test/functional/terminal/helpers.lua
@@ -3,11 +3,13 @@
-- operate on the _host_ session, _not_ the child session.
local helpers = require('test.functional.helpers')(nil)
local Screen = require('test.functional.ui.screen')
-local nvim_dir = helpers.nvim_dir
+local testprg = helpers.testprg
local feed_command, nvim = helpers.feed_command, helpers.nvim
local function feed_data(data)
- nvim('set_var', 'term_data', data)
+ -- A string containing NUL bytes is not converted to a Blob when
+ -- calling nvim_set_var() API, so convert it using Lua instead.
+ nvim('exec_lua', 'vim.g.term_data = ...', {data})
nvim('command', 'call jobsend(b:terminal_job_id, term_data)')
end
@@ -35,7 +37,7 @@ local function clear_attrs() feed_termcode('[0;10m') end
local function enable_mouse() feed_termcode('[?1002h') end
local function disable_mouse() feed_termcode('[?1002l') end
-local default_command = '["'..nvim_dir..'/tty-test'..'"]'
+local default_command = '["'..testprg('tty-test')..'"]'
local function screen_setup(extra_rows, command, cols, opts)
extra_rows = extra_rows and extra_rows or 0
@@ -94,7 +96,7 @@ local function screen_setup(extra_rows, command, cols, opts)
table.insert(expected, '{3:-- TERMINAL --}' .. ((' '):rep(cols - 14)))
screen:expect(table.concat(expected, '|\n')..'|')
else
- -- This eval also acts as a wait().
+ -- This eval also acts as a poke_eventloop().
if 0 == nvim('eval', "exists('b:terminal_job_id')") then
error("terminal job failed to start")
end
diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua
index 8d3f0218af..28ca07d815 100644
--- a/test/functional/terminal/highlight_spec.lua
+++ b/test/functional/terminal/highlight_spec.lua
@@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local thelpers = require('test.functional.terminal.helpers')
local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim
-local nvim_dir, command = helpers.nvim_dir, helpers.command
+local testprg, command = helpers.testprg, helpers.command
local nvim_prog_abs = helpers.nvim_prog_abs
local eq, eval = helpers.eq, helpers.eval
local funcs = helpers.funcs
@@ -28,7 +28,7 @@ describe(':terminal highlight', function()
[11] = {background = 11},
})
screen:attach({rgb=false})
- command('enew | call termopen(["'..nvim_dir..'/tty-test"])')
+ command(("enew | call termopen(['%s'])"):format(testprg('tty-test')))
feed('i')
screen:expect([[
tty ready |
@@ -173,7 +173,7 @@ describe(':terminal highlight forwarding', function()
[4] = {{foreground = tonumber('0xff8000')}, {}},
})
screen:attach()
- command('enew | call termopen(["'..nvim_dir..'/tty-test"])')
+ command(("enew | call termopen(['%s'])"):format(testprg('tty-test')))
feed('i')
screen:expect([[
tty ready |
@@ -214,7 +214,7 @@ describe(':terminal highlight with custom palette', function()
clear()
screen = Screen.new(50, 7)
screen:set_default_attr_ids({
- [1] = {foreground = tonumber('0x123456')}, -- no fg_indexed when overriden
+ [1] = {foreground = tonumber('0x123456')}, -- no fg_indexed when overridden
[2] = {foreground = 12},
[3] = {bold = true, reverse = true},
[5] = {background = 11},
@@ -225,7 +225,7 @@ describe(':terminal highlight with custom palette', function()
})
screen:attach({rgb=true})
nvim('set_var', 'terminal_color_3', '#123456')
- command('enew | call termopen(["'..nvim_dir..'/tty-test"])')
+ command(("enew | call termopen(['%s'])"):format(testprg('tty-test')))
feed('i')
screen:expect([[
tty ready |
@@ -304,10 +304,17 @@ describe('synIDattr()', function()
eq('79', eval('synIDattr(hlID("Keyword"), "fg")'))
end)
- it('returns "1" if group has "strikethrough" attribute', function()
- eq('', eval('synIDattr(hlID("Normal"), "strikethrough")'))
- eq('1', eval('synIDattr(hlID("Keyword"), "strikethrough")'))
- eq('1', eval('synIDattr(hlID("Keyword"), "strikethrough", "gui")'))
+ it('returns "1" if group has given highlight attribute', function()
+ local hl_attrs = {
+ 'underline', 'undercurl', 'underdouble', 'underdotted', 'underdashed', 'strikethrough'
+ }
+ for _,hl_attr in ipairs(hl_attrs) do
+ local context = 'using ' .. hl_attr .. ' attr'
+ command('highlight Keyword cterm=' .. hl_attr .. ' gui=' .. hl_attr)
+ eq('', eval('synIDattr(hlID("Normal"), "'.. hl_attr .. '")'), context)
+ eq('1', eval('synIDattr(hlID("Keyword"), "' .. hl_attr .. '")'), context)
+ eq('1', eval('synIDattr(hlID("Keyword"), "' .. hl_attr .. '", "gui")'), context)
+ end
end)
end)
diff --git a/test/functional/terminal/mouse_spec.lua b/test/functional/terminal/mouse_spec.lua
index 780a0b9b5a..6e2c851df7 100644
--- a/test/functional/terminal/mouse_spec.lua
+++ b/test/functional/terminal/mouse_spec.lua
@@ -1,7 +1,7 @@
local helpers = require('test.functional.helpers')(after_each)
local thelpers = require('test.functional.terminal.helpers')
local clear, eq, eval = helpers.clear, helpers.eq, helpers.eval
-local feed, nvim = helpers.feed, helpers.nvim
+local feed, nvim, command = helpers.feed, helpers.nvim, helpers.command
local feed_data = thelpers.feed_data
describe(':terminal mouse', function()
@@ -10,9 +10,9 @@ describe(':terminal mouse', function()
before_each(function()
clear()
nvim('set_option', 'statusline', '==========')
- nvim('command', 'highlight StatusLine cterm=NONE')
- nvim('command', 'highlight StatusLineNC cterm=NONE')
- nvim('command', 'highlight VertSplit cterm=NONE')
+ command('highlight StatusLine cterm=NONE')
+ command('highlight StatusLineNC cterm=NONE')
+ command('highlight VertSplit cterm=NONE')
screen = thelpers.screen_setup()
local lines = {}
for i = 1, 30 do
@@ -38,6 +38,26 @@ describe(':terminal mouse', function()
eq('nt', eval('mode(1)'))
end)
+ it('will exit focus and trigger Normal mode mapping on mouse click', function()
+ command('let g:got_leftmouse = 0')
+ command('nnoremap <LeftMouse> <Cmd>let g:got_leftmouse = 1<CR>')
+ eq('t', eval('mode(1)'))
+ eq(0, eval('g:got_leftmouse'))
+ feed('<LeftMouse>')
+ eq('nt', eval('mode(1)'))
+ eq(1, eval('g:got_leftmouse'))
+ end)
+
+ it('will exit focus and trigger Normal mode mapping on mouse click with modifier', function()
+ command('let g:got_ctrl_leftmouse = 0')
+ command('nnoremap <C-LeftMouse> <Cmd>let g:got_ctrl_leftmouse = 1<CR>')
+ eq('t', eval('mode(1)'))
+ eq(0, eval('g:got_ctrl_leftmouse'))
+ feed('<C-LeftMouse>')
+ eq('nt', eval('mode(1)'))
+ eq(1, eval('g:got_ctrl_leftmouse'))
+ end)
+
it('will exit focus on <C-\\> + mouse-scroll', function()
eq('t', eval('mode(1)'))
feed('<C-\\>')
@@ -180,7 +200,7 @@ describe(':terminal mouse', function()
it('will forward mouse clicks to the program with the correct even if set nu', function()
if helpers.pending_win32(pending) then return end
- nvim('command', 'set number')
+ command('set number')
-- When the display area such as a number is clicked, it returns to the
-- normal mode.
feed('<LeftMouse><3,0>')
diff --git a/test/functional/terminal/scrollback_spec.lua b/test/functional/terminal/scrollback_spec.lua
index 11bdc73a47..b491cb2735 100644
--- a/test/functional/terminal/scrollback_spec.lua
+++ b/test/functional/terminal/scrollback_spec.lua
@@ -2,10 +2,11 @@ local Screen = require('test.functional.ui.screen')
local helpers = require('test.functional.helpers')(after_each)
local thelpers = require('test.functional.terminal.helpers')
local clear, eq, curbuf = helpers.clear, helpers.eq, helpers.curbuf
-local feed, nvim_dir, feed_command = helpers.feed, helpers.nvim_dir, helpers.feed_command
+local feed, testprg, feed_command = helpers.feed, helpers.testprg, helpers.feed_command
local iswin = helpers.iswin
local eval = helpers.eval
local command = helpers.command
+local matches = helpers.matches
local poke_eventloop = helpers.poke_eventloop
local retry = helpers.retry
local curbufmeths = helpers.curbufmeths
@@ -345,10 +346,11 @@ end)
describe(':terminal prints more lines than the screen height and exits', function()
it('will push extra lines to scrollback', function()
+ if helpers.pending_win32(pending) then return end
clear()
local screen = Screen.new(30, 7)
screen:attach({rgb=false})
- feed_command('call termopen(["'..nvim_dir..'/tty-test", "10"]) | startinsert')
+ feed_command(("call termopen(['%s', '10']) | startinsert"):format(testprg('tty-test')))
poke_eventloop()
screen:expect([[
line6 |
@@ -380,7 +382,7 @@ describe("'scrollback' option", function()
local function set_fake_shell()
-- shell-test.c is a fake shell that prints its arguments and exits.
- nvim('set_option', 'shell', nvim_dir..'/shell-test')
+ nvim('set_option', 'shell', testprg('shell-test'))
nvim('set_option', 'shellcmdflag', 'EXE')
end
@@ -401,7 +403,7 @@ describe("'scrollback' option", function()
end
curbufmeths.set_option('scrollback', 0)
- feed_data(nvim_dir..'/shell-test REP 31 line'..(iswin() and '\r' or '\n'))
+ feed_data(('%s REP 31 line%s'):format(testprg('shell-test'), iswin() and '\r' or '\n'))
screen:expect{any='30: line '}
retry(nil, nil, function() expect_lines(7) end)
end)
@@ -421,7 +423,7 @@ describe("'scrollback' option", function()
-- Wait for prompt.
screen:expect{any='%$'}
- feed_data(nvim_dir.."/shell-test REP 31 line"..(iswin() and '\r' or '\n'))
+ feed_data(('%s REP 31 line%s'):format(testprg('shell-test'), iswin() and '\r' or '\n'))
screen:expect{any='30: line '}
retry(nil, nil, function() expect_lines(33, 2) end)
@@ -434,7 +436,7 @@ describe("'scrollback' option", function()
-- 'scrollback' option is synchronized with the internal sb_buffer.
command('sleep 100m')
- feed_data(nvim_dir.."/shell-test REP 41 line"..(iswin() and '\r' or '\n'))
+ feed_data(('%s REP 41 line%s'):format(testprg('shell-test'), iswin() and '\r' or '\n'))
if iswin() then
screen:expect{grid=[[
37: line |
@@ -459,8 +461,36 @@ describe("'scrollback' option", function()
expect_lines(58)
-- Verify off-screen state
- eq((iswin() and '36: line' or '35: line'), eval("getline(line('w0') - 1)"))
- eq((iswin() and '27: line' or '26: line'), eval("getline(line('w0') - 10)"))
+ matches((iswin() and '^36: line[ ]*$' or '^35: line[ ]*$'), eval("getline(line('w0') - 1)"))
+ matches((iswin() and '^27: line[ ]*$' or '^26: line[ ]*$'), eval("getline(line('w0') - 10)"))
+ end)
+
+ it('deletes extra lines immediately', function()
+ -- Scrollback is 10 on screen_setup
+ local screen = thelpers.screen_setup(nil, nil, 30)
+ local lines = {}
+ for i = 1, 30 do
+ table.insert(lines, 'line'..tostring(i))
+ end
+ table.insert(lines, '')
+ feed_data(lines)
+ screen:expect([[
+ line26 |
+ line27 |
+ line28 |
+ line29 |
+ line30 |
+ {1: } |
+ {3:-- TERMINAL --} |
+ ]])
+ local term_height = 6 -- Actual terminal screen height, not the scrollback
+ -- Initial
+ local scrollback = curbufmeths.get_option('scrollback')
+ eq(scrollback + term_height, eval('line("$")'))
+ -- Reduction
+ scrollback = scrollback - 2
+ curbufmeths.set_option('scrollback', scrollback)
+ eq(scrollback + term_height, eval('line("$")'))
end)
it('defaults to 10000 in :terminal buffers', function()
@@ -576,6 +606,7 @@ describe("pending scrollback line handling", function()
end)
it("does not crash after nvim_buf_call #14891", function()
+ if helpers.pending_win32(pending) then return end
exec_lua [[
local a = vim.api
local bufnr = a.nvim_create_buf(false, true)
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index faf44fa01d..dd88379344 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -14,12 +14,13 @@ local feed_command = helpers.feed_command
local feed_data = thelpers.feed_data
local clear = helpers.clear
local command = helpers.command
-local nvim_dir = helpers.nvim_dir
+local testprg = helpers.testprg
local retry = helpers.retry
local nvim_prog = helpers.nvim_prog
local nvim_set = helpers.nvim_set
local ok = helpers.ok
local read_file = helpers.read_file
+local funcs = helpers.funcs
if helpers.pending_win32(pending) then return end
@@ -85,6 +86,24 @@ describe('TUI', function()
assert_alive()
end)
+ it('resize at startup', function()
+ -- Issues: #17285 #15044 #11330
+ screen:try_resize(50, 10)
+ feed_command([[call termopen([v:progpath, '--clean', '--cmd', 'let start = reltime() | while v:true | if reltimefloat(reltime(start)) > 2 | break | endif | endwhile']) | sleep 500m | vs new]])
+ screen:expect([[
+ {1: } │ |
+ {4:~ }│{4:~ }|
+ {4:~ }│{4:~ }|
+ {4:~ }│{4:~ }|
+ {4:~ }│{4:~ }|
+ {4:~ }│{5:[No Name] 0,0-1 All}|
+ {4:~ }│ |
+ {5:new }{MATCH:<.*[/\]nvim }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ end)
+
it('accepts resize while pager is active', function()
child_session:request("nvim_command", [[
set more
@@ -214,7 +233,7 @@ describe('TUI', function()
]])
end)
- it('interprets ESC+key as ALT chord', function()
+ it('interprets ESC+key as ALT chord in i_CTRL-V', function()
-- Vim represents ALT/META by setting the "high bit" of the modified key:
-- ALT+j inserts "ê". Nvim does not (#3982).
feed_data('i\022\027j')
@@ -229,6 +248,38 @@ describe('TUI', function()
]])
end)
+ it('interprets <Esc>[27u as <Esc>', function()
+ feed_command('nnoremap <M-;> <Nop>')
+ feed_command('nnoremap <Esc> AESC<Esc>')
+ feed_command('nnoremap ; Asemicolon<Esc>')
+ feed_data('\027[27u;')
+ screen:expect([[
+ ESCsemicolo{1:n} |
+ {4:~ }|
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ -- <Esc>; should be recognized as <M-;> when <M-;> is mapped
+ feed_data('\027;')
+ screen:expect_unchanged()
+ end)
+
+ it('interprets <Esc><Nul> as <M-C-Space> #17198', function()
+ feed_data('i\022\027\000')
+ screen:expect([[
+ <M-C-Space>{1: } |
+ {4:~ }|
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] [+] }|
+ {3:-- INSERT --} |
+ {3:-- TERMINAL --} |
+ ]])
+ end)
+
it('accepts ASCII control sequences', function()
feed_data('i')
feed_data('\022\007') -- ctrl+g
@@ -247,6 +298,179 @@ describe('TUI', function()
]], attrs)
end)
+ it('accepts keypad keys from kitty keyboard protocol #19180', function()
+ feed_data('i')
+ feed_data(funcs.nr2char(57399)) -- KP_0
+ feed_data(funcs.nr2char(57400)) -- KP_1
+ feed_data(funcs.nr2char(57401)) -- KP_2
+ feed_data(funcs.nr2char(57402)) -- KP_3
+ feed_data(funcs.nr2char(57403)) -- KP_4
+ feed_data(funcs.nr2char(57404)) -- KP_5
+ feed_data(funcs.nr2char(57405)) -- KP_6
+ feed_data(funcs.nr2char(57406)) -- KP_7
+ feed_data(funcs.nr2char(57407)) -- KP_8
+ feed_data(funcs.nr2char(57408)) -- KP_9
+ feed_data(funcs.nr2char(57409)) -- KP_DECIMAL
+ feed_data(funcs.nr2char(57410)) -- KP_DIVIDE
+ feed_data(funcs.nr2char(57411)) -- KP_MULTIPLY
+ feed_data(funcs.nr2char(57412)) -- KP_SUBTRACT
+ feed_data(funcs.nr2char(57413)) -- KP_ADD
+ feed_data(funcs.nr2char(57414)) -- KP_ENTER
+ feed_data(funcs.nr2char(57415)) -- KP_EQUAL
+ screen:expect([[
+ 0123456789./*-+ |
+ ={1: } |
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] [+] }|
+ {3:-- INSERT --} |
+ {3:-- TERMINAL --} |
+ ]])
+ feed_data(funcs.nr2char(57417)) -- KP_LEFT
+ screen:expect([[
+ 0123456789./*-+ |
+ {1:=} |
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] [+] }|
+ {3:-- INSERT --} |
+ {3:-- TERMINAL --} |
+ ]])
+ feed_data(funcs.nr2char(57418)) -- KP_RIGHT
+ screen:expect([[
+ 0123456789./*-+ |
+ ={1: } |
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] [+] }|
+ {3:-- INSERT --} |
+ {3:-- TERMINAL --} |
+ ]])
+ feed_data(funcs.nr2char(57419)) -- KP_UP
+ screen:expect([[
+ 0{1:1}23456789./*-+ |
+ = |
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] [+] }|
+ {3:-- INSERT --} |
+ {3:-- TERMINAL --} |
+ ]])
+ feed_data(funcs.nr2char(57420)) -- KP_DOWN
+ screen:expect([[
+ 0123456789./*-+ |
+ ={1: } |
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] [+] }|
+ {3:-- INSERT --} |
+ {3:-- TERMINAL --} |
+ ]])
+ feed_data(funcs.nr2char(57425)) -- KP_INSERT
+ screen:expect([[
+ 0123456789./*-+ |
+ ={1: } |
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] [+] }|
+ {3:-- REPLACE --} |
+ {3:-- TERMINAL --} |
+ ]])
+ feed_data('\027[27u') -- ESC
+ screen:expect([[
+ 0123456789./*-+ |
+ {1:=} |
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ feed_data('\027[57417;5u') -- CTRL + KP_LEFT
+ screen:expect([[
+ {1:0}123456789./*-+ |
+ = |
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ feed_data('\027[57418;2u') -- SHIFT + KP_RIGHT
+ screen:expect([[
+ 0123456789{1:.}/*-+ |
+ = |
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ feed_data(funcs.nr2char(57426)) -- KP_DELETE
+ screen:expect([[
+ 0123456789{1:/}*-+ |
+ = |
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ feed_data(funcs.nr2char(57423)) -- KP_HOME
+ screen:expect([[
+ {1:0}123456789/*-+ |
+ = |
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ feed_data(funcs.nr2char(57424)) -- KP_END
+ screen:expect([[
+ 0123456789/*-{1:+} |
+ = |
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ feed_data(':tab split\r:tabnew\r')
+ feed_data(':highlight Tabline ctermbg=NONE ctermfg=NONE cterm=underline\r')
+ local attrs = screen:get_default_attr_ids()
+ attrs[11] = {underline = true}
+ screen:expect([[
+ {11: + [No Name] + [No Name] }{3: [No Name] }{1: }{11:X}|
+ {1: } |
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] }|
+ |
+ {3:-- TERMINAL --} |
+ ]], attrs)
+ feed_data('\027[57421;5u') -- CTRL + KP_PAGE_UP
+ screen:expect([[
+ {11: + [No Name] }{3: + [No Name] }{11: [No Name] }{1: }{11:X}|
+ 0123456789/*-{1:+} |
+ = |
+ {4:~ }|
+ {5:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]], attrs)
+ feed_data('\027[57422;5u') -- CTRL + KP_PAGE_DOWN
+ screen:expect([[
+ {11: + [No Name] + [No Name] }{3: [No Name] }{1: }{11:X}|
+ {1: } |
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] }|
+ |
+ {3:-- TERMINAL --} |
+ ]], attrs)
+ end)
+
it('paste: Insert mode', function()
-- "bracketed paste"
feed_data('i""\027i\027[200~')
@@ -271,7 +495,7 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
feed_data('\027[201~') -- End paste.
- feed_data('\027\000') -- ESC: go to Normal mode.
+ feed_data('\027[27u') -- ESC: go to Normal mode.
wait_for_mode('n')
screen:expect([[
"pasted from termina{1:l}" |
@@ -323,7 +547,7 @@ describe('TUI', function()
feed_data('just paste it™')
feed_data('\027[201~')
screen:expect{grid=[[
- thisjust paste it™{1:3} is here |
+ thisjust paste it{1:™}3 is here |
|
{4:~ }|
{4:~ }|
@@ -353,7 +577,7 @@ describe('TUI', function()
return
end
feed_data(':set statusline=^^^^^^^\n')
- feed_data(':terminal '..nvim_dir..'/tty-test\n')
+ feed_data(':terminal '..testprg('tty-test')..'\n')
feed_data('i')
screen:expect{grid=[[
tty ready |
@@ -379,7 +603,7 @@ describe('TUI', function()
end)
it('paste: normal-mode (+CRLF #10872)', function()
- feed_data(':set ruler')
+ feed_data(':set ruler | echo')
wait_for_mode('c')
feed_data('\n')
wait_for_mode('n')
@@ -423,13 +647,13 @@ describe('TUI', function()
expect_child_buf_lines(expected_crlf)
feed_data('u')
expect_child_buf_lines({''})
+ feed_data(':echo')
+ wait_for_mode('c')
+ feed_data('\n')
+ wait_for_mode('n')
-- CRLF input
feed_data('\027[200~'..table.concat(expected_lf,'\r\n')..'\027[201~')
- screen:expect{
- grid=expected_grid1:gsub(
- ':set ruler *',
- '3 fewer lines; before #1 0 seconds ago '),
- attr_ids=expected_attr}
+ screen:expect{grid=expected_grid1, attr_ids=expected_attr}
expect_child_buf_lines(expected_crlf)
end)
@@ -453,7 +677,7 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]]}
-- Dot-repeat/redo.
- feed_data('\027\000')
+ feed_data('\027[27u')
wait_for_mode('n')
feed_data('.')
screen:expect{grid=[[
@@ -499,7 +723,7 @@ describe('TUI', function()
vim.paste = function(lines, phase) error("fake fail") end
]], {})
-- Prepare something for dot-repeat/redo.
- feed_data('ifoo\n\027\000')
+ feed_data('ifoo\n\027[27u')
wait_for_mode('n')
screen:expect{grid=[[
foo |
@@ -541,7 +765,7 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]]}
-- Editor should still work after failed/drained paste.
- feed_data('ityped input...\027\000')
+ feed_data('ityped input...\027[27u')
screen:expect{grid=[[
foo |
foo |
@@ -575,7 +799,7 @@ describe('TUI', function()
vim.paste = function(lines, phase) return false end
]], {})
feed_data('\027[200~line A\nline B\n\027[201~')
- feed_data('ifoo\n\027\000')
+ feed_data('ifoo\n\027[27u')
expect_child_buf_lines({'foo',''})
end)
@@ -669,7 +893,7 @@ describe('TUI', function()
{3:-- INSERT --} |
{3:-- TERMINAL --} |
]])
- feed_data('\027\000') -- ESC: go to Normal mode.
+ feed_data('\027[27u') -- ESC: go to Normal mode.
wait_for_mode('n')
-- Dot-repeat/redo.
feed_data('.')
@@ -871,7 +1095,7 @@ describe('TUI', function()
feed_data(':set statusline=^^^^^^^\n')
feed_data(':set termguicolors\n')
- feed_data(':terminal '..nvim_dir..'/tty-test\n')
+ feed_data(':terminal '..testprg('tty-test')..'\n')
-- Depending on platform the above might or might not fit in the cmdline
-- so clear it for consistent behavior.
feed_data(':\027')
@@ -1098,7 +1322,7 @@ describe('TUI FocusGained/FocusLost', function()
end)
it('in terminal-mode', function()
- feed_data(':set shell='..nvim_dir..'/shell-test\n')
+ feed_data(':set shell='..testprg('shell-test')..'\n')
feed_data(':set noshowmode laststatus=0\n')
feed_data(':terminal\n')
diff --git a/test/functional/terminal/window_spec.lua b/test/functional/terminal/window_spec.lua
index 9f278fd157..0d3295cf32 100644
--- a/test/functional/terminal/window_spec.lua
+++ b/test/functional/terminal/window_spec.lua
@@ -18,6 +18,7 @@ describe(':terminal window', function()
end)
it('sets topline correctly #8556', function()
+ if helpers.pending_win32(pending) then return end
-- Test has hardcoded assumptions of dimensions.
eq(7, eval('&lines'))
feed_data('\n\n\n') -- Add blank lines.