aboutsummaryrefslogtreecommitdiff
path: root/test/functional/terminal/tui_spec.lua
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/terminal/tui_spec.lua')
-rw-r--r--test/functional/terminal/tui_spec.lua2132
1 files changed, 1222 insertions, 910 deletions
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index b17eed00f9..94690524d3 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -20,16 +20,19 @@ 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
-local meths = helpers.meths
+local fn = helpers.fn
+local api = helpers.api
local is_ci = helpers.is_ci
local is_os = helpers.is_os
local new_pipename = helpers.new_pipename
local spawn_argv = helpers.spawn_argv
local set_session = helpers.set_session
local write_file = helpers.write_file
+local eval = helpers.eval
-if helpers.skip(is_os('win')) then return end
+if helpers.skip(is_os('win')) then
+ return
+end
describe('TUI', function()
local screen
@@ -39,14 +42,21 @@ describe('TUI', function()
before_each(function()
clear()
local child_server = new_pipename()
- screen = thelpers.screen_setup(0,
- string.format([=[["%s", "--listen", "%s", "-u", "NONE", "-i", "NONE", "--cmd", "%s laststatus=2 background=dark"]]=],
- nvim_prog, child_server, nvim_set))
+ screen = thelpers.setup_child_nvim({
+ '--listen',
+ child_server,
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ nvim_set .. ' notermguicolors laststatus=2 background=dark',
+ '--cmd',
+ 'colorscheme vim',
+ })
screen:expect([[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
|
{3:-- TERMINAL --} |
@@ -75,7 +85,7 @@ describe('TUI', function()
it('rapid resize #7572 #7628', function()
helpers.skip(helpers.is_asan(), 'Test extra unstable with ASAN. See #23762')
-- Need buffer rows to provoke the behavior.
- feed_data(":edit test/functional/fixtures/bigfile.txt\n")
+ feed_data(':edit test/functional/fixtures/bigfile.txt\n')
screen:expect([[
{1:0}000;<control>;Cc;0;BN;;;;;N;NULL;;;; |
0001;<control>;Cc;0;BN;;;;;N;START OF HEADING;;;; |
@@ -102,21 +112,26 @@ describe('TUI', function()
screen:try_resize(57, 17)
command('call jobresize(b:terminal_job_id, 57, 17)')
retry(nil, nil, function()
- eq({true, 57}, {child_session:request('nvim_win_get_width', 0)})
+ eq({ true, 57 }, { child_session:request('nvim_win_get_width', 0) })
end)
end)
it('accepts resize while pager is active', function()
- child_session:request('nvim_exec2', [[
+ child_session:request(
+ 'nvim_exec2',
+ [[
set more
func! ManyErr()
for i in range(20)
echoerr "FAIL ".i
endfor
endfunc
- ]], {})
+ ]],
+ {}
+ )
feed_data(':call ManyErr()\r')
- screen:expect{grid=[[
+ screen:expect {
+ grid = [[
{8:Error detected while processing function ManyErr:} |
{11:line 2:} |
{8:FAIL 0} |
@@ -124,24 +139,27 @@ describe('TUI', function()
{8:FAIL 2} |
{10:-- More --}{1: } |
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
- screen:try_resize(50,10)
- screen:expect{grid=[[
+ screen:try_resize(50, 10)
+ screen:expect {
+ grid = [[
:call ManyErr() |
{8:Error detected while processing function ManyErr:} |
{11:line 2:} |
{8:FAIL 0} |
{8:FAIL 1} |
{8:FAIL 2} |
- |
- |
+ |*2
{10:-- More --}{1: } |
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
feed_data('j')
- screen:expect{grid=[[
+ screen:expect {
+ grid = [[
{8:Error detected while processing function ManyErr:} |
{11:line 2:} |
{8:FAIL 0} |
@@ -152,10 +170,12 @@ describe('TUI', function()
{8:FAIL 5} |
{10:-- More --}{1: } |
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
- screen:try_resize(50,7)
- screen:expect{grid=[[
+ screen:try_resize(50, 7)
+ screen:expect {
+ grid = [[
{8:FAIL 1} |
{8:FAIL 2} |
{8:FAIL 3} |
@@ -163,28 +183,34 @@ describe('TUI', function()
{8:FAIL 5} |
{10:-- More --}{1: } |
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
- screen:try_resize(50,5)
- screen:expect{grid=[[
+ screen:try_resize(50, 5)
+ screen:expect {
+ grid = [[
{8:FAIL 3} |
{8:FAIL 4} |
{8:FAIL 5} |
{10:-- More --}{1: } |
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
feed_data('g')
- screen:expect{grid=[[
+ screen:expect {
+ grid = [[
:call ManyErr() |
{8:Error detected while processing function ManyErr:} |
{11:line 2:} |
{10:-- More --}{1: } |
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
- screen:try_resize(50,10)
- screen:expect{grid=[[
+ screen:try_resize(50, 10)
+ screen:expect {
+ grid = [[
:call ManyErr() |
{8:Error detected while processing function ManyErr:} |
{11:line 2:} |
@@ -195,21 +221,19 @@ describe('TUI', function()
{8:FAIL 4} |
{10:-- More --}{1: } |
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
feed_data('\003')
- screen:expect{grid=[[
+ screen:expect {
+ grid = [[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*6
{5:[No Name] }|
|
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
end)
it('accepts basic utf-8 input', function()
@@ -238,8 +262,8 @@ describe('TUI', function()
it('interprets leading <Esc> byte as ALT modifier in normal-mode', function()
local keys = 'dfghjkl'
for c in keys:gmatch('.') do
- feed_data(':nnoremap <a-'..c..'> ialt-'..c..'<cr><esc>\r')
- feed_data('\027'..c)
+ feed_data(':nnoremap <a-' .. c .. '> ialt-' .. c .. '<cr><esc>\r')
+ feed_data('\027' .. c)
end
screen:expect([[
alt-j |
@@ -268,9 +292,7 @@ describe('TUI', function()
feed_data('i\022\027j')
screen:expect([[
<M-j>{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
@@ -278,17 +300,19 @@ describe('TUI', function()
end)
it('interprets <Esc>[27u as <Esc>', function()
- child_session:request('nvim_exec2', [[
+ child_session:request(
+ 'nvim_exec2',
+ [[
nnoremap <M-;> <Nop>
nnoremap <Esc> AESC<Esc>
nnoremap ; Asemicolon<Esc>
- ]], {})
+ ]],
+ {}
+ )
feed_data('\027[27u;')
screen:expect([[
ESCsemicolo{1:n} |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
@@ -302,9 +326,7 @@ describe('TUI', function()
feed_data('i\022\027\000')
screen:expect([[
<M-C-Space>{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
@@ -316,25 +338,25 @@ describe('TUI', function()
feed_data('\022\007') -- ctrl+g
feed_data('\022\022') -- ctrl+v
feed_data('\022\013') -- ctrl+m
- local attrs = screen:get_default_attr_ids()
- attrs[11] = {foreground = 81}
screen:expect([[
- {11:^G^V^M}{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {6:^G^V^M}{1: } |
+ {4:~ }|*3
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
- ]], attrs)
+ ]])
end)
local function test_mouse_wheel(esc)
- child_session:request('nvim_exec2', [[
+ child_session:request(
+ 'nvim_exec2',
+ [[
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----|
@@ -348,7 +370,7 @@ describe('TUI', function()
if esc then
feed_data('\027[<65;8;1M')
else
- meths.input_mouse('wheel', 'down', '', 0, 0, 7)
+ api.nvim_input_mouse('wheel', 'down', '', 0, 0, 7)
end
screen:expect([[
{11: 2 }{1:0}----1----2----3----4│{11: 1 }0----1----2----3----|
@@ -363,7 +385,7 @@ describe('TUI', function()
if esc then
feed_data('\027[<65;48;1M')
else
- meths.input_mouse('wheel', 'down', '', 0, 0, 47)
+ api.nvim_input_mouse('wheel', 'down', '', 0, 0, 47)
end
screen:expect([[
{11: 2 }{1:0}----1----2----3----4│{11: 2 }0----1----2----3----|
@@ -378,7 +400,7 @@ describe('TUI', function()
if esc then
feed_data('\027[<67;8;1M')
else
- meths.input_mouse('wheel', 'right', '', 0, 0, 7)
+ api.nvim_input_mouse('wheel', 'right', '', 0, 0, 7)
end
screen:expect([[
{11: 2 }{1:-}---1----2----3----4-│{11: 2 }0----1----2----3----|
@@ -393,7 +415,7 @@ describe('TUI', function()
if esc then
feed_data('\027[<67;48;1M')
else
- meths.input_mouse('wheel', 'right', '', 0, 0, 47)
+ api.nvim_input_mouse('wheel', 'right', '', 0, 0, 47)
end
screen:expect([[
{11: 2 }{1:-}---1----2----3----4-│{11: 2 }----1----2----3----4|
@@ -408,7 +430,7 @@ describe('TUI', function()
if esc then
feed_data('\027[<69;8;1M')
else
- meths.input_mouse('wheel', 'down', 'S', 0, 0, 7)
+ api.nvim_input_mouse('wheel', 'down', 'S', 0, 0, 7)
end
screen:expect([[
{11: 5 }{1:-}---1----2----3----4-│{11: 2 }----1----2----3----4|
@@ -423,7 +445,7 @@ describe('TUI', function()
if esc then
feed_data('\027[<69;48;1M')
else
- meths.input_mouse('wheel', 'down', 'S', 0, 0, 47)
+ api.nvim_input_mouse('wheel', 'down', 'S', 0, 0, 47)
end
screen:expect([[
{11: 5 }{1:-}---1----2----3----4-│{11: 5 }----1----2----3----4|
@@ -438,7 +460,7 @@ describe('TUI', function()
if esc then
feed_data('\027[<71;8;1M')
else
- meths.input_mouse('wheel', 'right', 'S', 0, 0, 7)
+ api.nvim_input_mouse('wheel', 'right', 'S', 0, 0, 7)
end
screen:expect([[
{11: 5 }{1:-}---6----7----8----9 │{11: 5 }----1----2----3----4|
@@ -453,7 +475,7 @@ describe('TUI', function()
if esc then
feed_data('\027[<71;48;1M')
else
- meths.input_mouse('wheel', 'right', 'S', 0, 0, 47)
+ api.nvim_input_mouse('wheel', 'right', 'S', 0, 0, 47)
end
screen:expect([[
{11: 5 }{1:-}---6----7----8----9 │{11: 5 }5----6----7----8----|
@@ -468,7 +490,7 @@ describe('TUI', function()
if esc then
feed_data('\027[<64;8;1M')
else
- meths.input_mouse('wheel', 'up', '', 0, 0, 7)
+ api.nvim_input_mouse('wheel', 'up', '', 0, 0, 7)
end
screen:expect([[
{11: 4 }----6----7----8----9 │{11: 5 }5----6----7----8----|
@@ -483,7 +505,7 @@ describe('TUI', function()
if esc then
feed_data('\027[<64;48;1M')
else
- meths.input_mouse('wheel', 'up', '', 0, 0, 47)
+ api.nvim_input_mouse('wheel', 'up', '', 0, 0, 47)
end
screen:expect([[
{11: 4 }----6----7----8----9 │{11: 4 }5----6----7----8----|
@@ -498,7 +520,7 @@ describe('TUI', function()
if esc then
feed_data('\027[<66;8;1M')
else
- meths.input_mouse('wheel', 'left', '', 0, 0, 7)
+ api.nvim_input_mouse('wheel', 'left', '', 0, 0, 7)
end
screen:expect([[
{11: 4 }5----6----7----8----9│{11: 4 }5----6----7----8----|
@@ -513,7 +535,7 @@ describe('TUI', function()
if esc then
feed_data('\027[<66;48;1M')
else
- meths.input_mouse('wheel', 'left', '', 0, 0, 47)
+ api.nvim_input_mouse('wheel', 'left', '', 0, 0, 47)
end
screen:expect([[
{11: 4 }5----6----7----8----9│{11: 4 }-5----6----7----8---|
@@ -528,7 +550,7 @@ describe('TUI', function()
if esc then
feed_data('\027[<68;8;1M')
else
- meths.input_mouse('wheel', 'up', 'S', 0, 0, 7)
+ api.nvim_input_mouse('wheel', 'up', 'S', 0, 0, 7)
end
screen:expect([[
{11: 1 }5----6----7----8----9│{11: 4 }-5----6----7----8---|
@@ -543,7 +565,7 @@ describe('TUI', function()
if esc then
feed_data('\027[<68;48;1M')
else
- meths.input_mouse('wheel', 'up', 'S', 0, 0, 47)
+ api.nvim_input_mouse('wheel', 'up', 'S', 0, 0, 47)
end
screen:expect([[
{11: 1 }5----6----7----8----9│{11: 1 }-5----6----7----8---|
@@ -558,7 +580,7 @@ describe('TUI', function()
if esc then
feed_data('\027[<70;8;1M')
else
- meths.input_mouse('wheel', 'left', 'S', 0, 0, 7)
+ api.nvim_input_mouse('wheel', 'left', 'S', 0, 0, 7)
end
screen:expect([[
{11: 1 }0----1----2----3----4│{11: 1 }-5----6----7----8---|
@@ -573,7 +595,7 @@ describe('TUI', function()
if esc then
feed_data('\027[<70;48;1M')
else
- meths.input_mouse('wheel', 'left', 'S', 0, 0, 47)
+ api.nvim_input_mouse('wheel', 'left', 'S', 0, 0, 47)
end
screen:expect([[
{11: 1 }0----1----2----3----4│{11: 1 }0----1----2----3----|
@@ -597,7 +619,9 @@ describe('TUI', function()
end)
local function test_mouse_popup(esc)
- child_session:request('nvim_exec2', [[
+ child_session:request(
+ 'nvim_exec2',
+ [[
call setline(1, 'popup menu test')
set mouse=a mousemodel=popup
@@ -607,11 +631,13 @@ describe('TUI', function()
menu PopUp.baz :let g:menustr = 'baz'<CR>
highlight Pmenu ctermbg=NONE ctermfg=NONE cterm=underline,reverse
highlight PmenuSel ctermbg=NONE ctermfg=NONE cterm=underline,reverse,bold
- ]], {})
+ ]],
+ {}
+ )
if esc then
feed_data('\027[<2;5;1M')
else
- meths.input_mouse('right', 'press', '', 0, 0, 4)
+ api.nvim_input_mouse('right', 'press', '', 0, 0, 4)
end
screen:expect([[
{1:p}opup menu test |
@@ -625,13 +651,27 @@ describe('TUI', function()
if esc then
feed_data('\027[<2;5;1m')
else
- meths.input_mouse('right', 'release', '', 0, 0, 4)
+ api.nvim_input_mouse('right', 'release', '', 0, 0, 4)
end
screen:expect_unchanged()
if esc then
+ feed_data('\027[<64;5;1M')
+ else
+ api.nvim_input_mouse('wheel', 'up', '', 0, 0, 4)
+ end
+ screen:expect([[
+ {1:p}opup menu test |
+ {4:~ }{14: foo }{4: }|
+ {4:~ }{13: bar }{4: }|
+ {4:~ }{13: baz }{4: }|
+ {5:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ if esc then
feed_data('\027[<35;7;4M')
else
- meths.input_mouse('move', '', '', 0, 3, 6)
+ api.nvim_input_mouse('move', '', '', 0, 3, 6)
end
screen:expect([[
{1:p}opup menu test |
@@ -643,15 +683,27 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
if esc then
+ feed_data('\027[<65;7;4M')
+ else
+ api.nvim_input_mouse('wheel', 'down', '', 0, 3, 6)
+ end
+ screen:expect([[
+ {1:p}opup menu test |
+ {4:~ }{13: foo }{4: }|
+ {4:~ }{14: bar }{4: }|
+ {4:~ }{13: baz }{4: }|
+ {5:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ if esc then
feed_data('\027[<0;7;3M')
else
- meths.input_mouse('left', 'press', '', 0, 2, 6)
+ api.nvim_input_mouse('left', 'press', '', 0, 2, 6)
end
screen:expect([[
{1:p}opup menu test |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] [+] }|
:let g:menustr = 'bar' |
{3:-- TERMINAL --} |
@@ -659,18 +711,17 @@ describe('TUI', function()
if esc then
feed_data('\027[<0;7;3m')
else
- meths.input_mouse('left', 'release', '', 0, 2, 6)
+ api.nvim_input_mouse('left', 'release', '', 0, 2, 6)
end
screen:expect_unchanged()
if esc then
feed_data('\027[<2;45;3M')
else
- meths.input_mouse('right', 'press', '', 0, 2, 44)
+ api.nvim_input_mouse('right', 'press', '', 0, 2, 44)
end
screen:expect([[
{1:p}opup menu test |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{4:~ }{13: foo }{4: }|
{5:[No Name] [+] }{13: bar }{5: }|
:let g:menustr = 'bar' {13: baz } |
@@ -679,12 +730,11 @@ describe('TUI', function()
if esc then
feed_data('\027[<34;48;6M')
else
- meths.input_mouse('right', 'drag', '', 0, 5, 47)
+ api.nvim_input_mouse('right', 'drag', '', 0, 5, 47)
end
screen:expect([[
{1:p}opup menu test |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{4:~ }{13: foo }{4: }|
{5:[No Name] [+] }{13: bar }{5: }|
:let g:menustr = 'bar' {14: baz } |
@@ -693,13 +743,11 @@ describe('TUI', function()
if esc then
feed_data('\027[<2;48;6m')
else
- meths.input_mouse('right', 'release', '', 0, 5, 47)
+ api.nvim_input_mouse('right', 'release', '', 0, 5, 47)
end
screen:expect([[
{1:p}opup menu test |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] [+] }|
:let g:menustr = 'baz' |
{3:-- TERMINAL --} |
@@ -718,78 +766,72 @@ describe('TUI', function()
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
+ feed_data(fn.nr2char(57399)) -- KP_0
+ feed_data(fn.nr2char(57400)) -- KP_1
+ feed_data(fn.nr2char(57401)) -- KP_2
+ feed_data(fn.nr2char(57402)) -- KP_3
+ feed_data(fn.nr2char(57403)) -- KP_4
+ feed_data(fn.nr2char(57404)) -- KP_5
+ feed_data(fn.nr2char(57405)) -- KP_6
+ feed_data(fn.nr2char(57406)) -- KP_7
+ feed_data(fn.nr2char(57407)) -- KP_8
+ feed_data(fn.nr2char(57408)) -- KP_9
+ feed_data(fn.nr2char(57409)) -- KP_DECIMAL
+ feed_data(fn.nr2char(57410)) -- KP_DIVIDE
+ feed_data(fn.nr2char(57411)) -- KP_MULTIPLY
+ feed_data(fn.nr2char(57412)) -- KP_SUBTRACT
+ feed_data(fn.nr2char(57413)) -- KP_ADD
+ feed_data(fn.nr2char(57414)) -- KP_ENTER
+ feed_data(fn.nr2char(57415)) -- KP_EQUAL
screen:expect([[
0123456789./*-+ |
={1: } |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
]])
- feed_data(funcs.nr2char(57417)) -- KP_LEFT
+ feed_data(fn.nr2char(57417)) -- KP_LEFT
screen:expect([[
0123456789./*-+ |
{1:=} |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
]])
- feed_data(funcs.nr2char(57418)) -- KP_RIGHT
+ feed_data(fn.nr2char(57418)) -- KP_RIGHT
screen:expect([[
0123456789./*-+ |
={1: } |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
]])
- feed_data(funcs.nr2char(57419)) -- KP_UP
+ feed_data(fn.nr2char(57419)) -- KP_UP
screen:expect([[
0{1:1}23456789./*-+ |
= |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
]])
- feed_data(funcs.nr2char(57420)) -- KP_DOWN
+ feed_data(fn.nr2char(57420)) -- KP_DOWN
screen:expect([[
0123456789./*-+ |
={1: } |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
]])
- feed_data(funcs.nr2char(57425)) -- KP_INSERT
+ feed_data(fn.nr2char(57425)) -- KP_INSERT
screen:expect([[
0123456789./*-+ |
={1: } |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] [+] }|
{3:-- REPLACE --} |
{3:-- TERMINAL --} |
@@ -798,8 +840,7 @@ describe('TUI', function()
screen:expect([[
0123456789./*-+ |
{1:=} |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
@@ -808,8 +849,7 @@ describe('TUI', function()
screen:expect([[
{1:0}123456789./*-+ |
= |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
@@ -818,52 +858,51 @@ describe('TUI', function()
screen:expect([[
0123456789{1:.}/*-+ |
= |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
]])
- feed_data(funcs.nr2char(57426)) -- KP_DELETE
+ feed_data(fn.nr2char(57426)) -- KP_DELETE
screen:expect([[
0123456789{1:/}*-+ |
= |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
]])
- feed_data(funcs.nr2char(57423)) -- KP_HOME
+ feed_data(fn.nr2char(57423)) -- KP_HOME
screen:expect([[
{1:0}123456789/*-+ |
= |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
]])
- feed_data(funcs.nr2char(57424)) -- KP_END
+ feed_data(fn.nr2char(57424)) -- KP_END
screen:expect([[
0123456789/*-{1:+} |
= |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
]])
- child_session:request('nvim_exec2', [[
+ child_session:request(
+ 'nvim_exec2',
+ [[
tab split
tabnew
highlight Tabline ctermbg=NONE ctermfg=NONE cterm=underline
- ]], {})
+ ]],
+ {}
+ )
screen:expect([[
{12: + [No Name] + [No Name] }{3: [No Name] }{1: }{12:X}|
{1: } |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] }|
|
{3:-- TERMINAL --} |
@@ -882,8 +921,7 @@ describe('TUI', function()
screen:expect([[
{12: + [No Name] + [No Name] }{3: [No Name] }{1: }{12:X}|
{1: } |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] }|
|
{3:-- TERMINAL --} |
@@ -892,20 +930,19 @@ describe('TUI', function()
it('supports Super and Meta modifiers', function()
feed_data('i')
- feed_data('\022\027[106;9u') -- Super + j
- feed_data('\022\027[107;33u') -- Meta + k
- feed_data('\022\027[13;41u') -- Super + Meta + Enter
- feed_data('\022\027[127;48u') -- Shift + Alt + Ctrl + Super + Meta + Backspace
+ feed_data('\022\027[106;9u') -- Super + j
+ feed_data('\022\027[107;33u') -- Meta + k
+ feed_data('\022\027[13;41u') -- Super + Meta + Enter
+ feed_data('\022\027[127;48u') -- Shift + Alt + Ctrl + Super + Meta + Backspace
feed_data('\n')
- feed_data('\022\027[57376;9u') -- Super + F13
- feed_data('\022\027[57377;33u') -- Meta + F14
- feed_data('\022\027[57378;41u') -- Super + Meta + F15
- feed_data('\022\027[57379;48u') -- Shift + Alt + Ctrl + Super + Meta + F16
+ feed_data('\022\027[57376;9u') -- Super + F13
+ feed_data('\022\027[57377;33u') -- Meta + F14
+ feed_data('\022\027[57378;41u') -- Super + Meta + F15
+ feed_data('\022\027[57379;48u') -- Shift + Alt + Ctrl + Super + Meta + F16
screen:expect([[
<D-j><T-k><T-D-CR><M-T-C-S-D-BS> |
<D-F13><T-F14><T-D-F15><M-T-C-S-D-F16>{1: } |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
@@ -917,61 +954,54 @@ describe('TUI', function()
feed_data('i""\027i\027[200~')
screen:expect([[
"{1:"} |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
]])
feed_data('pasted from terminal')
- expect_child_buf_lines({'"pasted from terminal"'})
+ expect_child_buf_lines({ '"pasted from terminal"' })
screen:expect([[
"pasted from terminal{1:"} |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
]])
- feed_data('\027[201~') -- End paste.
- feed_data('\027[27u') -- ESC: go to Normal mode.
+ feed_data('\027[201~') -- End paste.
+ feed_data('\027[27u') -- ESC: go to Normal mode.
wait_for_mode('n')
screen:expect([[
"pasted from termina{1:l}" |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
]])
-- Dot-repeat/redo.
feed_data('2.')
- expect_child_buf_lines({'"pasted from terminapasted from terminalpasted from terminall"'})
+ expect_child_buf_lines({ '"pasted from terminapasted from terminalpasted from terminall"' })
screen:expect([[
"pasted from terminapasted from terminalpasted fro|
m termina{1:l}l" |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
]])
-- Undo.
feed_data('u')
- expect_child_buf_lines({'"pasted from terminal"'})
+ expect_child_buf_lines({ '"pasted from terminal"' })
feed_data('u')
- expect_child_buf_lines({'""'})
+ expect_child_buf_lines({ '""' })
feed_data('u')
- expect_child_buf_lines({''})
+ expect_child_buf_lines({ '' })
end)
it('paste: select-mode', function()
feed_data('ithis is line 1\nthis is line 2\nline 3 is here\n\027')
wait_for_mode('n')
- screen:expect{grid=[[
+ screen:expect([[
this is line 1 |
this is line 2 |
line 3 is here |
@@ -979,33 +1009,40 @@ describe('TUI', function()
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]]}
+ ]])
-- Select-mode. Use <C-n> to move down.
feed_data('gg04lgh\14\14')
- wait_for_mode('s')
+ screen:expect([[
+ this{16: is line 1} |
+ {16:this is line 2} |
+ {16:line}{1: }3 is here |
+ |
+ {5:[No Name] [+] }|
+ {3:-- SELECT --} |
+ {3:-- TERMINAL --} |
+ ]])
feed_data('\027[200~')
feed_data('just paste it™')
feed_data('\027[201~')
- screen:expect{grid=[[
+ screen:expect([[
thisjust paste it{1:™}3 is here |
|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]]}
+ ]])
-- Undo.
feed_data('u')
- expect_child_buf_lines{
+ expect_child_buf_lines {
'this is line 1',
'this is line 2',
'line 3 is here',
'',
}
-- Redo.
- feed_data('\18') -- <C-r>
- expect_child_buf_lines{
+ feed_data('\18') -- <C-r>
+ expect_child_buf_lines {
'thisjust paste it™3 is here',
'',
}
@@ -1013,32 +1050,28 @@ describe('TUI', function()
it('paste: terminal mode', function()
if is_ci('github') then
- pending("tty-test complains about not owning the terminal -- actions/runner#241")
+ pending('tty-test complains about not owning the terminal -- actions/runner#241')
end
child_exec_lua('vim.o.statusline="^^^^^^^"')
child_exec_lua('vim.cmd.terminal(...)', testprg('tty-test'))
feed_data('i')
- screen:expect{grid=[[
+ screen:expect([[
tty ready |
{1: } |
- |
- |
+ |*2
{5:^^^^^^^ }|
- {3:-- TERMINAL --} |
- {3:-- TERMINAL --} |
- ]]}
+ {3:-- TERMINAL --} |*2
+ ]])
feed_data('\027[200~')
feed_data('hallo')
feed_data('\027[201~')
- screen:expect{grid=[[
+ screen:expect([[
tty ready |
hallo{1: } |
- |
- |
+ |*2
{5:^^^^^^^ }|
- {3:-- TERMINAL --} |
- {3:-- TERMINAL --} |
- ]]}
+ {3:-- TERMINAL --} |*2
+ ]])
end)
it('paste: normal-mode (+CRLF #10872)', function()
@@ -1046,99 +1079,98 @@ describe('TUI', function()
wait_for_mode('c')
feed_data('\n')
wait_for_mode('n')
- local expected_lf = {'line 1', 'ESC:\027 / CR: \rx'}
- local expected_crlf = {'line 1', 'ESC:\027 / CR: ', 'x'}
+ local expected_lf = { 'line 1', 'ESC:\027 / CR: \rx' }
+ local expected_crlf = { 'line 1', 'ESC:\027 / CR: ', 'x' }
local expected_grid1 = [[
line 1 |
- ESC:{11:^[} / CR: |
+ ESC:{6:^[} / CR: |
{1:x} |
{4:~ }|
{5:[No Name] [+] 3,1 All}|
|
{3:-- TERMINAL --} |
]]
- local expected_attr = {
- [1] = {reverse = true},
- [3] = {bold = true},
- [4] = {foreground = tonumber('0x00000c')},
- [5] = {bold = true, reverse = true},
- [11] = {foreground = tonumber('0x000051')},
- [12] = {reverse = true, foreground = tonumber('0x000051')},
- }
-- "bracketed paste"
- feed_data('\027[200~'..table.concat(expected_lf,'\n')..'\027[201~')
- screen:expect{grid=expected_grid1, attr_ids=expected_attr}
+ feed_data('\027[200~' .. table.concat(expected_lf, '\n') .. '\027[201~')
+ screen:expect(expected_grid1)
-- Dot-repeat/redo.
feed_data('.')
- screen:expect{grid=[[
- ESC:{11:^[} / CR: |
+ screen:expect([[
+ ESC:{6:^[} / CR: |
xline 1 |
- ESC:{11:^[} / CR: |
+ ESC:{6:^[} / CR: |
{1:x} |
{5:[No Name] [+] 5,1 Bot}|
|
{3:-- TERMINAL --} |
- ]], attr_ids=expected_attr}
+ ]])
-- Undo.
feed_data('u')
expect_child_buf_lines(expected_crlf)
feed_data('u')
- expect_child_buf_lines({''})
+ 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, attr_ids=expected_attr}
+ feed_data('\027[200~' .. table.concat(expected_lf, '\r\n') .. '\027[201~')
+ screen:expect(expected_grid1)
expect_child_buf_lines(expected_crlf)
end)
it('paste: cmdline-mode inserts 1 line', function()
- feed_data('ifoo\n') -- Insert some text (for dot-repeat later).
- feed_data('\027:""') -- Enter Cmdline-mode.
- feed_data('\027[D') -- <Left> to place cursor between quotes.
+ feed_data('ifoo\n') -- Insert some text (for dot-repeat later).
+ feed_data('\027:""') -- Enter Cmdline-mode.
+ feed_data('\027[D') -- <Left> to place cursor between quotes.
wait_for_mode('c')
+ screen:expect([[
+ foo |
+ |
+ {4:~ }|*2
+ {5:[No Name] [+] }|
+ :"{1:"} |
+ {3:-- TERMINAL --} |
+ ]])
-- "bracketed paste"
feed_data('\027[200~line 1\nline 2\n')
wait_for_mode('c')
feed_data('line 3\nline 4\n\027[201~')
wait_for_mode('c')
- screen:expect{grid=[[
+ screen:expect([[
foo |
|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] [+] }|
:"line 1{1:"} |
{3:-- TERMINAL --} |
- ]]}
+ ]])
-- Dot-repeat/redo.
feed_data('\027[27u')
wait_for_mode('n')
feed_data('.')
- screen:expect{grid=[[
- foo |
- foo |
+ screen:expect([[
+ foo |*2
{1: } |
{4:~ }|
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]]}
+ ]])
end)
it('paste: cmdline-mode collects chunks of unfinished line', function()
local function expect_cmdline(expected)
retry(nil, nil, function()
- local _, cmdline = child_session:request(
- 'nvim_call_function', 'getcmdline', {})
+ local _, cmdline = child_session:request('nvim_call_function', 'getcmdline', {})
eq(expected, cmdline)
+ local _, pos = child_session:request('nvim_call_function', 'getcmdpos', {})
+ eq(#expected, pos) -- Cursor is just before the last char.
end)
end
- feed_data('\027:""') -- Enter Cmdline-mode.
- feed_data('\027[D') -- <Left> to place cursor between quotes.
- wait_for_mode('c')
+ feed_data('\027:""') -- Enter Cmdline-mode.
+ feed_data('\027[D') -- <Left> to place cursor between quotes.
+ expect_cmdline('""')
feed_data('\027[200~stuff 1 ')
expect_cmdline('"stuff 1 "')
-- Discards everything after the first line.
@@ -1153,27 +1185,30 @@ describe('TUI', function()
end)
it('paste: recovers from vim.paste() failure', function()
- child_session:request('nvim_exec_lua', [[
+ child_session:request(
+ 'nvim_exec_lua',
+ [[
_G.save_paste_fn = vim.paste
-- Stack traces for this test are non-deterministic, so disable them
_G.debug.traceback = function(msg) return msg end
vim.paste = function(lines, phase) error("fake fail") end
- ]], {})
+ ]],
+ {}
+ )
-- Prepare something for dot-repeat/redo.
feed_data('ifoo\n\027[27u')
wait_for_mode('n')
- screen:expect{grid=[[
+ screen:expect([[
foo |
{1: } |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]]}
+ ]])
-- Start pasting...
feed_data('\027[200~line 1\nline 2\n')
- screen:expect{grid=[[
+ screen:expect([[
foo |
|
{5: }|
@@ -1181,44 +1216,39 @@ describe('TUI', function()
{8:ake fail} |
{10:Press ENTER or type command to continue}{1: } |
{3:-- TERMINAL --} |
- ]]}
+ ]])
-- Remaining chunks are discarded after vim.paste() failure.
feed_data('line 3\nline 4\n')
feed_data('line 5\nline 6\n')
feed_data('line 7\nline 8\n')
-- Stop paste.
feed_data('\027[201~')
- feed_data('\n') -- <CR>
- expect_child_buf_lines({'foo',''})
- --Dot-repeat/redo is not modified by failed paste.
+ feed_data('\n') -- <CR> to dismiss hit-enter prompt
+ expect_child_buf_lines({ 'foo', '' })
+ -- Dot-repeat/redo is not modified by failed paste.
feed_data('.')
- screen:expect{grid=[[
- foo |
- foo |
+ screen:expect([[
+ foo |*2
{1: } |
{4:~ }|
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]]}
+ ]])
-- Editor should still work after failed/drained paste.
feed_data('ityped input...\027[27u')
- screen:expect{grid=[[
- foo |
- foo |
+ screen:expect([[
+ foo |*2
typed input..{1:.} |
{4:~ }|
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]]}
+ ]])
-- Paste works if vim.paste() succeeds.
- child_session:request('nvim_exec_lua', [[
- vim.paste = _G.save_paste_fn
- ]], {})
+ child_session:request('nvim_exec_lua', [[vim.paste = _G.save_paste_fn]], {})
feed_data('\027[200~line A\nline B\n\027[201~')
- feed_data('\n') -- <CR>
- screen:expect{grid=[[
+ screen:expect([[
foo |
typed input...line A |
line B |
@@ -1226,28 +1256,36 @@ describe('TUI', function()
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]]}
+ ]])
end)
it('paste: vim.paste() cancel (retval=false) #10865', function()
-- This test only exercises the "cancel" case. Use-case would be "dangling
-- paste", but that is not implemented yet. #10865
- child_session:request('nvim_exec_lua', [[
+ child_session:request(
+ 'nvim_exec_lua',
+ [[
vim.paste = function(lines, phase) return false end
- ]], {})
+ ]],
+ {}
+ )
feed_data('\027[200~line A\nline B\n\027[201~')
feed_data('ifoo\n\027[27u')
- expect_child_buf_lines({'foo',''})
+ expect_child_buf_lines({ 'foo', '' })
end)
it("paste: 'nomodifiable' buffer", function()
child_session:request('nvim_command', 'set nomodifiable')
- child_session:request('nvim_exec_lua', [[
+ child_session:request(
+ 'nvim_exec_lua',
+ [[
-- Truncate the error message to hide the line number
_G.debug.traceback = function(msg) return msg:sub(-49) end
- ]], {})
+ ]],
+ {}
+ )
feed_data('\027[200~fail 1\nfail 2\n\027[201~')
- screen:expect{grid=[[
+ screen:expect([[
|
{4:~ }|
{5: }|
@@ -1255,11 +1293,11 @@ describe('TUI', function()
{8:hanges, 'modifiable' is off} |
{10:Press ENTER or type command to continue}{1: } |
{3:-- TERMINAL --} |
- ]]}
- feed_data('\n') -- <Enter>
+ ]])
+ feed_data('\n') -- <Enter> to dismiss hit-enter prompt
child_session:request('nvim_command', 'set modifiable')
feed_data('\027[200~success 1\nsuccess 2\n\027[201~')
- screen:expect{grid=[[
+ screen:expect([[
success 1 |
success 2 |
{1: } |
@@ -1267,7 +1305,7 @@ describe('TUI', function()
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]]}
+ ]])
end)
it('paste: exactly 64 bytes #10311', function()
@@ -1275,20 +1313,19 @@ describe('TUI', function()
feed_data('i')
wait_for_mode('i')
-- "bracketed paste"
- feed_data('\027[200~'..expected..'\027[201~')
- expect_child_buf_lines({expected})
+ feed_data('\027[200~' .. expected .. '\027[201~')
+ expect_child_buf_lines({ expected })
feed_data(' end')
- expected = expected..' end'
+ expected = expected .. ' end'
screen:expect([[
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz|
zzzzzzzzzzzzzz end{1: } |
- {4:~ }|
- {4:~ }|
+ {4:~ }|*2
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
]])
- expect_child_buf_lines({expected})
+ expect_child_buf_lines({ expected })
end)
it('paste: less-than sign in cmdline #11088', function()
@@ -1296,16 +1333,14 @@ describe('TUI', function()
feed_data(':')
wait_for_mode('c')
-- "bracketed paste"
- feed_data('\027[200~'..expected..'\027[201~')
- screen:expect{grid=[[
+ feed_data('\027[200~' .. expected .. '\027[201~')
+ screen:expect([[
|
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
:<{1: } |
{3:-- TERMINAL --} |
- ]]}
+ ]])
end)
it('paste: big burst of input', function()
@@ -1317,7 +1352,7 @@ describe('TUI', function()
feed_data('i')
wait_for_mode('i')
-- "bracketed paste"
- feed_data('\027[200~'..table.concat(t, '\n')..'\027[201~')
+ feed_data('\027[200~' .. table.concat(t, '\n') .. '\027[201~')
expect_child_buf_lines(t)
feed_data(' end')
screen:expect([[
@@ -1329,7 +1364,7 @@ describe('TUI', function()
{3:-- INSERT --} |
{3:-- TERMINAL --} |
]])
- feed_data('\027[27u') -- ESC: go to Normal mode.
+ feed_data('\027[27u') -- ESC: go to Normal mode.
wait_for_mode('n')
-- Dot-repeat/redo.
feed_data('.')
@@ -1347,9 +1382,10 @@ describe('TUI', function()
it('paste: forwards spurious "start paste" code', function()
-- If multiple "start paste" sequences are sent without a corresponding
-- "stop paste" sequence, only the first occurrence should be consumed.
-
+ feed_data('i')
+ wait_for_mode('i')
-- Send the "start paste" sequence.
- feed_data('i\027[200~')
+ feed_data('\027[200~')
feed_data('\npasted from terminal (1)\n')
-- Send spurious "start paste" sequence.
feed_data('\027[200~')
@@ -1357,7 +1393,7 @@ describe('TUI', function()
-- Send the "stop paste" sequence.
feed_data('\027[201~')
- screen:expect{grid=[[
+ screen:expect([[
|
pasted from terminal (1) |
{6:^[}[200~ |
@@ -1365,27 +1401,19 @@ describe('TUI', function()
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
- ]], attr_ids={
- [1] = {reverse = true},
- [2] = {background = tonumber('0x00000b')},
- [3] = {bold = true},
- [4] = {foreground = tonumber('0x00000c')},
- [5] = {bold = true, reverse = true},
- [6] = {foreground = tonumber('0x000051')},
- }}
+ ]])
end)
it('paste: ignores spurious "stop paste" code', function()
-- If "stop paste" sequence is received without a preceding "start paste"
-- sequence, it should be ignored.
feed_data('i')
+ wait_for_mode('i')
-- Send "stop paste" sequence.
feed_data('\027[201~')
screen:expect([[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
@@ -1394,23 +1422,13 @@ describe('TUI', function()
it('paste: split "start paste" code', function()
feed_data('i')
- screen:expect{grid=[[
- {1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
- {5:[No Name] }|
- {3:-- INSERT --} |
- {3:-- TERMINAL --} |
- ]]}
+ wait_for_mode('i')
-- Send split "start paste" sequence.
feed_data('\027[2')
feed_data('00~pasted from terminal\027[201~')
screen:expect([[
pasted from terminal{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
@@ -1419,23 +1437,13 @@ describe('TUI', function()
it('paste: split "stop paste" code', function()
feed_data('i')
- screen:expect{grid=[[
- {1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
- {5:[No Name] }|
- {3:-- INSERT --} |
- {3:-- TERMINAL --} |
- ]]}
+ wait_for_mode('i')
-- Send split "stop paste" sequence.
feed_data('\027[200~pasted from terminal\027[20')
feed_data('1~')
screen:expect([[
pasted from terminal{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
@@ -1443,7 +1451,9 @@ describe('TUI', function()
end)
it('paste: streamed paste with isolated "stop paste" code', function()
- child_session:request('nvim_exec_lua', [[
+ child_session:request(
+ 'nvim_exec_lua',
+ [[
_G.paste_phases = {}
vim.paste = (function(overridden)
return function(lines, phase)
@@ -1451,57 +1461,47 @@ describe('TUI', function()
overridden(lines, phase)
end
end)(vim.paste)
- ]], {})
+ ]],
+ {}
+ )
feed_data('i')
- screen:expect{grid=[[
- {1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
- {5:[No Name] }|
- {3:-- INSERT --} |
- {3:-- TERMINAL --} |
- ]]}
- feed_data('\027[200~pasted') -- phase 1
+ wait_for_mode('i')
+ feed_data('\027[200~pasted') -- phase 1
screen:expect([[
pasted{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
]])
- feed_data(' from terminal') -- phase 2
+ feed_data(' from terminal') -- phase 2
screen:expect([[
pasted from terminal{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
]])
-- Send isolated "stop paste" sequence.
- feed_data('\027[201~') -- phase 3
+ feed_data('\027[201~') -- phase 3
screen:expect_unchanged()
local _, rv = child_session:request('nvim_exec_lua', [[return _G.paste_phases]], {})
- eq({1, 2, 3}, rv)
+ eq({ 1, 2, 3 }, rv)
end)
it('allows termguicolors to be set at runtime', function()
screen:set_option('rgb', true)
screen:set_default_attr_ids({
- [1] = {reverse = true},
- [2] = {foreground = tonumber('0x4040ff'), fg_indexed=true},
- [3] = {bold = true, reverse = true},
- [4] = {bold = true},
- [5] = {reverse = true, foreground = tonumber('0xe0e000'), fg_indexed=true},
- [6] = {foreground = tonumber('0xe0e000'), fg_indexed=true},
- [7] = {reverse = true, foreground = Screen.colors.SeaGreen4},
- [8] = {foreground = Screen.colors.SeaGreen4},
- [9] = {bold = true, foreground = Screen.colors.Blue1},
- [10] = {foreground = Screen.colors.Blue},
+ [1] = { reverse = true },
+ [2] = { foreground = tonumber('0x4040ff'), fg_indexed = true },
+ [3] = { bold = true, reverse = true },
+ [4] = { bold = true },
+ [5] = { reverse = true, foreground = tonumber('0xe0e000'), fg_indexed = true },
+ [6] = { foreground = tonumber('0xe0e000'), fg_indexed = true },
+ [7] = { reverse = true, foreground = Screen.colors.SeaGreen4 },
+ [8] = { foreground = Screen.colors.SeaGreen4 },
+ [9] = { bold = true, foreground = Screen.colors.Blue1 },
+ [10] = { foreground = Screen.colors.Blue },
})
feed_data(':hi SpecialKey ctermfg=3 guifg=SeaGreen\n')
@@ -1511,9 +1511,7 @@ describe('TUI', function()
feed_data(':set termguicolors?\n')
screen:expect([[
{5:^}{6:G} |
- {2:~ }|
- {2:~ }|
- {2:~ }|
+ {2:~ }|*3
{3:[No Name] [+] }|
notermguicolors |
{4:-- TERMINAL --} |
@@ -1522,9 +1520,7 @@ describe('TUI', function()
feed_data(':set termguicolors\n')
screen:expect([[
{7:^}{8:G} |
- {9:~}{10: }|
- {9:~}{10: }|
- {9:~}{10: }|
+ {9:~}{10: }|*3
{3:[No Name] [+] }|
:set termguicolors |
{4:-- TERMINAL --} |
@@ -1533,9 +1529,7 @@ describe('TUI', function()
feed_data(':set notermguicolors\n')
screen:expect([[
{5:^}{6:G} |
- {2:~ }|
- {2:~ }|
- {2:~ }|
+ {2:~ }|*3
{3:[No Name] [+] }|
:set notermguicolors |
{4:-- TERMINAL --} |
@@ -1544,50 +1538,54 @@ describe('TUI', function()
it('forwards :term palette colors with termguicolors', function()
if is_ci('github') then
- pending("tty-test complains about not owning the terminal -- actions/runner#241")
+ pending('tty-test complains about not owning the terminal -- actions/runner#241')
end
screen:set_rgb_cterm(true)
screen:set_default_attr_ids({
- [1] = {{reverse = true}, {reverse = true}},
- [2] = {{bold = true, reverse = true}, {bold = true, reverse = true}},
- [3] = {{bold = true}, {bold = true}},
- [4] = {{fg_indexed = true, foreground = tonumber('0xe0e000')}, {foreground = 3}},
- [5] = {{foreground = tonumber('0xff8000')}, {}},
+ [1] = { { reverse = true }, { reverse = true } },
+ [2] = { { bold = true, reverse = true }, { bold = true, reverse = true } },
+ [3] = { { bold = true }, { bold = true } },
+ [4] = { { fg_indexed = true, foreground = tonumber('0xe0e000') }, { foreground = 3 } },
+ [5] = { { foreground = tonumber('0xff8000') }, {} },
})
child_exec_lua('vim.o.statusline="^^^^^^^"')
child_exec_lua('vim.o.termguicolors=true')
child_exec_lua('vim.cmd.terminal(...)', testprg('tty-test'))
- screen:expect{grid=[[
+ screen:expect {
+ grid = [[
{1:t}ty ready |
- |
- |
- |
+ |*3
{2:^^^^^^^ }|
|
{3:-- TERMINAL --} |
- ]]}
- feed_data(':call chansend(&channel, "\\033[38;5;3mtext\\033[38:2:255:128:0mcolor\\033[0;10mtext")\n')
- screen:expect{grid=[[
+ ]],
+ }
+ feed_data(
+ ':call chansend(&channel, "\\033[38;5;3mtext\\033[38:2:255:128:0mcolor\\033[0;10mtext")\n'
+ )
+ screen:expect {
+ grid = [[
{1:t}ty ready |
{4:text}{5:color}text |
- |
- |
+ |*2
{2:^^^^^^^ }|
|
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
feed_data(':set notermguicolors\n')
- screen:expect{grid=[[
+ screen:expect {
+ grid = [[
{1:t}ty ready |
{4:text}colortext |
- |
- |
+ |*2
{2:^^^^^^^ }|
:set notermguicolors |
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
end)
it('in nvim_list_uis()', function()
@@ -1613,7 +1611,7 @@ describe('TUI', function()
term_background = '',
term_colors = 256,
term_name = exp_term,
- width = 50
+ width = 50,
},
}
local _, rv = child_session:request('nvim_list_uis')
@@ -1621,10 +1619,17 @@ describe('TUI', function()
end)
it('allows grid to assume wider ambiguous-width characters than host terminal #19686', function()
- child_session:request('nvim_buf_set_lines', 0, 0, -1, true, { ('℃'):rep(60), ('℃'):rep(60) })
+ child_session:request(
+ 'nvim_buf_set_lines',
+ 0,
+ 0,
+ -1,
+ true,
+ { ('℃'):rep(60), ('℃'):rep(60) }
+ )
child_session:request('nvim_set_option_value', 'cursorline', true, {})
child_session:request('nvim_set_option_value', 'list', true, {})
- child_session:request('nvim_set_option_value', 'listchars', 'eol:$', {win=0})
+ child_session:request('nvim_set_option_value', 'listchars', 'eol:$', { win = 0 })
feed_data('gg')
local singlewidth_screen = [[
{13:℃}{12:℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃}|
@@ -1651,9 +1656,9 @@ describe('TUI', function()
screen:expect(doublewidth_screen)
child_session:request('nvim_set_option_value', 'ambiwidth', 'single', {})
screen:expect(singlewidth_screen)
- child_session:request('nvim_call_function', 'setcellwidths', {{{0x2103, 0x2103, 2}}})
+ child_session:request('nvim_call_function', 'setcellwidths', { { { 0x2103, 0x2103, 2 } } })
screen:expect(doublewidth_screen)
- child_session:request('nvim_call_function', 'setcellwidths', {{{0x2103, 0x2103, 1}}})
+ child_session:request('nvim_call_function', 'setcellwidths', { { { 0x2103, 0x2103, 1 } } })
screen:expect(singlewidth_screen)
end)
@@ -1661,92 +1666,106 @@ describe('TUI', function()
helpers.skip(is_os('mac'), 'FIXME: crashes/errors on macOS')
screen:try_resize(77, 855)
retry(nil, nil, function()
- eq({true, 852}, {child_session:request('nvim_win_get_height', 0)})
+ eq({ true, 852 }, { child_session:request('nvim_win_get_height', 0) })
end)
-- Use full screen message so that redrawing afterwards is more deterministic.
child_session:notify('nvim_command', 'intro')
- screen:expect({any = 'Nvim'})
+ screen:expect({ any = 'Nvim' })
-- Going to top-left corner needs 3 bytes.
-- Setting underline attribute needs 9 bytes.
- -- The whole line needs 3 + 9 + 65515 + 3 = 65530 bytes.
+ -- The whole line needs 3 + 9 + 65513 + 3 = 65528 bytes.
-- The cursor_address that comes after will overflow the 65535-byte buffer.
- local line = ('a'):rep(65515) .. '℃'
- child_session:notify('nvim_exec_lua', [[
+ local line = ('a'):rep(65513) .. '℃'
+ child_session:notify(
+ 'nvim_exec_lua',
+ [[
vim.api.nvim_buf_set_lines(0, 0, -1, true, {...})
vim.o.cursorline = true
- ]], {line, 'b'})
+ ]],
+ { line, 'b' }
+ )
-- Close the :intro message and redraw the lines.
feed_data('\n')
screen:expect(
- '{13:a}{12:' .. ('a'):rep(76) .. '}|\n'
- .. ('{12:' .. ('a'):rep(77) .. '}|\n'):rep(849)
- .. '{12:' .. ('a'):rep(65) .. '℃' .. (' '):rep(11) .. '}|\n' .. dedent([[
+ '{13:a}{12:'
+ .. ('a'):rep(76)
+ .. '}|\n'
+ .. ('{12:' .. ('a'):rep(77) .. '}|\n'):rep(849)
+ .. '{12:'
+ .. ('a'):rep(63)
+ .. '℃'
+ .. (' '):rep(13)
+ .. '}|\n'
+ .. dedent([[
b |
{5:[No Name] [+] }|
|
- {3:-- TERMINAL --} |]]))
+ {3:-- TERMINAL --} |]])
+ )
end)
it('visual bell (padding) does not crash #21610', function()
feed_data ':set visualbell\n'
- screen:expect{grid=[[
+ screen:expect {
+ grid = [[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
:set visualbell |
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
-- move left is enough to invoke the bell
feed_data 'h'
-- visual change to show we process events after this
feed_data 'i'
- screen:expect{grid=[[
+ screen:expect {
+ grid = [[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
end)
it('no assert failure on deadly signal #21896', function()
exec_lua([[vim.uv.kill(vim.fn.jobpid(vim.bo.channel), 'sigterm')]])
- screen:expect{grid=[[
+ screen:expect {
+ grid = [[
Vim: Caught deadly signal 'SIGTERM' |
- |
- |
+ |*2
[Process exited 1]{1: } |
- |
- |
+ |*2
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
end)
it('no stack-use-after-scope with cursor color #22432', function()
screen:set_option('rgb', true)
command('set termguicolors')
- child_session:request('nvim_exec2', [[
+ child_session:request(
+ 'nvim_exec2',
+ [[
set tgc
hi Cursor guifg=Red guibg=Green
set guicursor=n:block-Cursor/lCursor
- ]], {})
+ ]],
+ {}
+ )
screen:set_default_attr_ids({
- [1] = {reverse = true},
- [2] = {bold = true, foreground = Screen.colors.Blue},
- [3] = {foreground = Screen.colors.Blue},
- [4] = {reverse = true, bold = true},
- [5] = {bold = true},
+ [1] = { reverse = true },
+ [2] = { bold = true, foreground = Screen.colors.Blue },
+ [3] = { foreground = Screen.colors.Blue },
+ [4] = { reverse = true, bold = true },
+ [5] = { bold = true },
})
screen:expect([[
{1: } |
- {2:~}{3: }|
- {2:~}{3: }|
- {2:~}{3: }|
+ {2:~}{3: }|*3
{4:[No Name] }|
|
{5:-- TERMINAL --} |
@@ -1754,9 +1773,7 @@ describe('TUI', function()
feed_data('i')
screen:expect([[
{1: } |
- {2:~}{3: }|
- {2:~}{3: }|
- {2:~}{3: }|
+ {2:~}{3: }|*3
{4:[No Name] }|
{5:-- INSERT --} |
{5:-- TERMINAL --} |
@@ -1764,12 +1781,10 @@ describe('TUI', function()
end)
it('redraws on SIGWINCH even if terminal size is unchanged #23411', function()
- child_session:request('nvim_echo', {{'foo'}}, false, {})
+ child_session:request('nvim_echo', { { 'foo' } }, false, {})
screen:expect([[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
foo |
{3:-- TERMINAL --} |
@@ -1777,9 +1792,7 @@ describe('TUI', function()
exec_lua([[vim.uv.kill(vim.fn.jobpid(vim.bo.channel), 'sigwinch')]])
screen:expect([[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
|
{3:-- TERMINAL --} |
@@ -1787,14 +1800,14 @@ describe('TUI', function()
end)
it('supports hiding cursor', function()
- child_session:request('nvim_command',
- "let g:id = jobstart([v:progpath, '--clean', '--headless'])")
+ child_session:request(
+ 'nvim_command',
+ "let g:id = jobstart([v:progpath, '--clean', '--headless'])"
+ )
feed_data(':call jobwait([g:id])\n')
screen:expect([[
|
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
:call jobwait([g:id]) |
{3:-- TERMINAL --} |
@@ -1802,14 +1815,73 @@ describe('TUI', function()
feed_data('\003')
screen:expect([[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
Type :qa and press <Enter> to exit Nvim |
{3:-- TERMINAL --} |
]])
end)
+
+ it('cursor is not hidden on incsearch with no match', function()
+ feed_data('ifoo\027')
+ feed_data('/foo')
+ screen:expect([[
+ {1:foo} |
+ {4:~ }|*3
+ {5:[No Name] [+] }|
+ /foo{1: } |
+ {3:-- TERMINAL --} |
+ ]])
+ screen:sleep(10)
+ feed_data('b')
+ screen:expect([[
+ foo |
+ {4:~ }|*3
+ {5:[No Name] [+] }|
+ /foob{1: } |
+ {3:-- TERMINAL --} |
+ ]])
+ screen:sleep(10)
+ feed_data('a')
+ screen:expect([[
+ foo |
+ {4:~ }|*3
+ {5:[No Name] [+] }|
+ /fooba{1: } |
+ {3:-- TERMINAL --} |
+ ]])
+ end)
+
+ it('emits hyperlinks with OSC 8', function()
+ exec_lua([[
+ local buf = vim.api.nvim_get_current_buf()
+ _G.urls = {}
+ vim.api.nvim_create_autocmd('TermRequest', {
+ buffer = buf,
+ callback = function(args)
+ local req = args.data
+ if not req then
+ return
+ end
+ local url = req:match('\027]8;;(.*)$')
+ if url ~= nil then
+ table.insert(_G.urls, url)
+ end
+ end,
+ })
+ ]])
+ child_exec_lua([[
+ vim.api.nvim_buf_set_lines(0, 0, 0, true, {'Hello'})
+ local ns = vim.api.nvim_create_namespace('test')
+ vim.api.nvim_buf_set_extmark(0, ns, 0, 1, {
+ end_col = 3,
+ url = 'https://example.com',
+ })
+ ]])
+ retry(nil, 1000, function()
+ eq({ 'https://example.com', '' }, exec_lua([[return _G.urls]]))
+ end)
+ end)
end)
describe('TUI', function()
@@ -1818,25 +1890,34 @@ describe('TUI', function()
it('resize at startup #17285 #15044 #11330', function()
local screen = Screen.new(50, 10)
screen:set_default_attr_ids({
- [1] = {reverse = true},
- [2] = {bold = true, foreground = Screen.colors.Blue},
- [3] = {bold = true},
- [4] = {foreground = tonumber('0x4040ff'), fg_indexed = true},
- [5] = {bold = true, reverse = true},
+ [1] = { reverse = true },
+ [2] = { bold = true, foreground = Screen.colors.Blue },
+ [3] = { bold = true },
+ [4] = { foreground = tonumber('0x4040ff'), fg_indexed = true },
+ [5] = { bold = true, reverse = true },
})
screen:attach()
+ fn.termopen({
+ nvim_prog,
+ '--clean',
+ '--cmd',
+ 'colorscheme vim',
+ '--cmd',
+ 'set notermguicolors',
+ '--cmd',
+ 'let start = reltime() | while v:true | if reltimefloat(reltime(start)) > 2 | break | endif | endwhile',
+ }, {
+ env = {
+ VIMRUNTIME = os.getenv('VIMRUNTIME'),
+ },
+ })
exec([[
- 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([[
^ │ |
- {2:~ }│{4:~ }|
- {2:~ }│{4:~ }|
- {2:~ }│{4:~ }|
- {2:~ }│{4:~ }|
- {2:~ }│{4:~ }|
+ {2:~ }│{4:~ }|*5
{2:~ }│{5:[No Name] 0,0-1 All}|
{2:~ }│ |
{5:new }{1:{MATCH:<.*[/\]nvim }}|
@@ -1849,43 +1930,53 @@ describe('TUI', function()
pending('missing LuaJIT FFI')
end
local script_file = 'Xargv0.lua'
- write_file(script_file, [=[
+ write_file(
+ script_file,
+ [=[
local ffi = require('ffi')
ffi.cdef([[int execl(const char *, const char *, ...);]])
- ffi.C.execl(vim.v.progpath, 'Xargv0nvim', '--clean')
- ]=])
+ ffi.C.execl(vim.v.progpath, 'Xargv0nvim', '--clean', nil)
+ ]=]
+ )
finally(function()
os.remove(script_file)
end)
- local screen = thelpers.screen_setup(0, string.format([=[["%s", "--clean", "-l", "%s"]]=],
- nvim_prog, script_file))
- screen:expect{grid=[[
+ local screen = thelpers.setup_child_nvim({ '--clean', '-l', script_file })
+ screen:expect {
+ grid = [[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
- {5:[No Name] 0,0-1 All}|
+ ~ |*3
+ [No Name] 0,0-1 All|
|
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
feed_data(':put =v:argv + [v:progname]\n')
- screen:expect{grid=[[
+ screen:expect {
+ grid = [[
Xargv0nvim |
--embed |
--clean |
{1:X}argv0nvim |
- {5:[No Name] [+] 5,1 Bot}|
+ [No Name] [+] 5,1 Bot|
4 more lines |
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
end)
it('with non-tty (pipe) stdout/stderr', function()
finally(function()
os.remove('testF')
end)
- local screen = thelpers.screen_setup(0, '"'..nvim_prog
- ..' -u NONE -i NONE --cmd \'set noswapfile noshowcmd noruler\' --cmd \'normal iabc\' > /dev/null 2>&1 && cat testF && rm testF"')
+ local screen = thelpers.screen_setup(
+ 0,
+ ('"%s" -u NONE -i NONE --cmd "set noswapfile noshowcmd noruler" --cmd "normal iabc" > /dev/null 2>&1 && cat testF && rm testF'):format(
+ nvim_prog
+ ),
+ nil,
+ { VIMRUNTIME = os.getenv('VIMRUNTIME') }
+ )
feed_data(':w testF\n:q\n')
screen:expect([[
:w testF |
@@ -1899,24 +1990,32 @@ describe('TUI', function()
end)
it('<C-h> #10134', function()
- local screen = thelpers.screen_setup(0, '["'..nvim_prog
- ..[[", "-u", "NONE", "-i", "NONE", "--cmd", "set noruler", "--cmd", ':nnoremap <C-h> :echomsg "\<C-h\>"<CR>']]..']')
- screen:expect{grid=[[
+ local screen = thelpers.setup_child_nvim({
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ 'colorscheme vim',
+ '--cmd',
+ 'set noruler notermguicolors',
+ '--cmd',
+ ':nnoremap <C-h> :echomsg "\\<C-h\\>"<CR>',
+ })
+ screen:expect {
+ grid = [[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
|
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
command([[call chansend(b:terminal_job_id, "\<C-h>")]])
screen:expect([[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
<C-h> |
{3:-- TERMINAL --} |
@@ -1924,19 +2023,31 @@ describe('TUI', function()
end)
it('draws line with many trailing spaces correctly #24955', function()
- local screen = thelpers.screen_setup(0, '["'..nvim_prog..[[", "-u", "NONE", "-i", "NONE"]]
- ..[[, "--cmd", "call setline(1, ['1st line' .. repeat(' ', 153), '2nd line'])"]]..']', 80)
- screen:expect{grid=[[
+ local screen = thelpers.setup_child_nvim({
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ 'set notermguicolors',
+ '--cmd',
+ 'colorscheme vim',
+ '--cmd',
+ 'call setline(1, ["1st line" .. repeat(" ", 153), "2nd line"])',
+ }, { cols = 80 })
+ screen:expect {
+ grid = [[
{1:1}st line |
- |
- |
+ |*2
2nd line |
{5:[No Name] [+] 1,1 All}|
|
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
feed_data('$')
- screen:expect{grid=[[
+ screen:expect {
+ grid = [[
1st line |
|
{1: } |
@@ -1944,41 +2055,93 @@ describe('TUI', function()
{5:[No Name] [+] 1,161 All}|
|
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
+ end)
+
+ it('no heap-buffer-overflow when changing &columns', function()
+ -- Set a different bg colour and change $TERM to something dumber so the `print_spaces()`
+ -- codepath in `clear_region()` is hit.
+ local screen = thelpers.setup_child_nvim({
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ 'set notermguicolors | highlight Normal ctermbg=red',
+ '--cmd',
+ 'call setline(1, ["a"->repeat(&columns)])',
+ }, { env = { TERM = 'ansi' } })
+
+ screen:expect {
+ grid = [[
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
+ ~ |*3
+ [No Name] [+] 1,1 All|
+ |
+ -- TERMINAL -- |
+ ]],
+ attr_ids = {},
+ }
+
+ feed_data(':set columns=12\n')
+ screen:expect {
+ grid = [[
+ aaaaaaaaaaaa |*4
+ < [+] 1,1 |
+ |
+ -- TERMINAL -- |
+ ]],
+ attr_ids = {},
+ }
+
+ -- Wider than TUI, so screen state will look weird.
+ -- Wait for the statusline to redraw to confirm that the TUI lives and ASAN is happy.
+ feed_data(':set columns=99|set stl=redrawn%m\n')
+ screen:expect({ any = 'redrawn%[%+%]' })
end)
end)
describe('TUI UIEnter/UILeave', function()
it('fires exactly once, after VimEnter', function()
clear()
- local screen = thelpers.screen_setup(0,
- '["'..nvim_prog..'", "-u", "NONE", "-i", "NONE"'
- ..[[, "--cmd", "set noswapfile noshowcmd noruler"]]
- ..[[, "--cmd", "let g:evs = []"]]
- ..[[, "--cmd", "autocmd UIEnter * :call add(g:evs, 'UIEnter')"]]
- ..[[, "--cmd", "autocmd UILeave * :call add(g:evs, 'UILeave')"]]
- ..[[, "--cmd", "autocmd VimEnter * :call add(g:evs, 'VimEnter')"]]
- ..']'
- )
- screen:expect{grid=[[
+ local screen = thelpers.setup_child_nvim({
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ 'colorscheme vim',
+ '--cmd',
+ 'set noswapfile noshowcmd noruler notermguicolors',
+ '--cmd',
+ 'let g:evs = []',
+ '--cmd',
+ 'autocmd UIEnter * :call add(g:evs, "UIEnter")',
+ '--cmd',
+ 'autocmd UILeave * :call add(g:evs, "UILeave")',
+ '--cmd',
+ 'autocmd VimEnter * :call add(g:evs, "VimEnter")',
+ })
+ screen:expect {
+ grid = [[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
|
{3:-- TERMINAL --} |
- ]]}
- feed_data(":echo g:evs\n")
- screen:expect{grid=[[
+ ]],
+ }
+ feed_data(':echo g:evs\n')
+ screen:expect {
+ grid = [[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
['VimEnter', 'UIEnter'] |
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
end)
end)
@@ -1989,25 +2152,36 @@ describe('TUI FocusGained/FocusLost', function()
before_each(function()
clear()
local child_server = new_pipename()
- screen = thelpers.screen_setup(0,
- string.format(
- [=[["%s", "--listen", "%s", "-u", "NONE", "-i", "NONE", "--cmd", "set noswapfile noshowcmd noruler"]]=],
- nvim_prog, child_server))
+ screen = thelpers.setup_child_nvim({
+ '--listen',
+ child_server,
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ 'colorscheme vim',
+ '--cmd',
+ 'set noswapfile noshowcmd noruler notermguicolors background=dark',
+ })
+
screen:expect([[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
|
{3:-- TERMINAL --} |
]])
child_session = helpers.connect(child_server)
- child_session:request('nvim_exec2', [[
+ child_session:request(
+ 'nvim_exec2',
+ [[
autocmd FocusGained * echo 'gained'
autocmd FocusLost * echo 'lost'
- ]], {})
- feed_data("\034\016") -- CTRL-\ CTRL-N
+ ]],
+ {}
+ )
+ feed_data('\034\016') -- CTRL-\ CTRL-N
end)
it('in normal-mode', function()
@@ -2015,9 +2189,7 @@ describe('TUI FocusGained/FocusLost', function()
feed_data('\027[I')
screen:expect([[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
gained |
{3:-- TERMINAL --} |
@@ -2026,9 +2198,7 @@ describe('TUI FocusGained/FocusLost', function()
feed_data('\027[O')
screen:expect([[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
lost |
{3:-- TERMINAL --} |
@@ -2039,22 +2209,20 @@ describe('TUI FocusGained/FocusLost', function()
it('in insert-mode', function()
feed_data(':set noshowmode\r')
feed_data('i')
- screen:expect{grid=[[
+ screen:expect {
+ grid = [[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
:set noshowmode |
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
retry(2, 3 * screen.timeout, function()
feed_data('\027[I')
screen:expect([[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
gained |
{3:-- TERMINAL --} |
@@ -2062,9 +2230,7 @@ describe('TUI FocusGained/FocusLost', function()
feed_data('\027[O')
screen:expect([[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
lost |
{3:-- TERMINAL --} |
@@ -2079,34 +2245,37 @@ describe('TUI FocusGained/FocusLost', function()
feed_data('\027[I')
screen:expect([[
|
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
:{1: } |
{3:-- TERMINAL --} |
]])
feed_data('\027[O')
- screen:expect{grid=[[
+ screen:expect {
+ grid = [[
|
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
:{1: } |
{3:-- TERMINAL --} |
- ]], unchanged=true}
+ ]],
+ unchanged = true,
+ }
end)
it('in cmdline-mode', function()
-- Set up autocmds that modify the buffer, instead of just calling :echo.
-- This is how we can test handling of focus gained/lost during cmdline-mode.
-- See commit: 5cc87d4dabd02167117be7a978b5c8faaa975419.
- child_session:request('nvim_exec2', [[
+ child_session:request(
+ 'nvim_exec2',
+ [[
autocmd!
autocmd FocusLost * call append(line('$'), 'lost')
autocmd FocusGained * call append(line('$'), 'gained')
- ]], {})
+ ]],
+ {}
+ )
retry(2, 3 * screen.timeout, function()
-- Enter cmdline-mode.
feed_data(':')
@@ -2118,44 +2287,46 @@ describe('TUI FocusGained/FocusLost', function()
-- Exit cmdline-mode. Redraws from timers/events are blocked during
-- cmdline-mode, so the buffer won't be updated until we exit cmdline-mode.
feed_data('\n')
- screen:expect{any='lost'..(' '):rep(46)..'|\ngained'}
+ screen:expect { any = 'lost' .. (' '):rep(46) .. '|\ngained' }
end)
end)
it('in terminal-mode', function()
- feed_data(':set shell='..testprg('shell-test')..' shellcmdflag=EXE\n')
+ feed_data(':set shell=' .. testprg('shell-test') .. ' shellcmdflag=EXE\n')
feed_data(':set noshowmode laststatus=0\n')
feed_data(':terminal zia\n')
-- Wait for terminal to be ready.
- screen:expect{grid=[[
+ screen:expect {
+ grid = [[
{1:r}eady $ zia |
|
[Process exited 0] |
- |
- |
+ |*2
:terminal zia |
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
feed_data('\027[I')
- screen:expect{grid=[[
+ screen:expect {
+ grid = [[
{1:r}eady $ zia |
|
[Process exited 0] |
- |
- |
+ |*2
gained |
{3:-- TERMINAL --} |
- ]], timeout=(4 * screen.timeout)}
+ ]],
+ timeout = (4 * screen.timeout),
+ }
feed_data('\027[O')
screen:expect([[
{1:r}eady $ zia |
|
[Process exited 0] |
- |
- |
+ |*2
lost |
{3:-- TERMINAL --} |
]])
@@ -2164,8 +2335,9 @@ describe('TUI FocusGained/FocusLost', function()
it('in press-enter prompt', function()
feed_data(":echom 'msg1'|echom 'msg2'|echom 'msg3'|echom 'msg4'|echom 'msg5'\n")
-- Execute :messages to provoke the press-enter prompt.
- feed_data(":messages\n")
- screen:expect{grid=[[
+ feed_data(':messages\n')
+ screen:expect {
+ grid = [[
msg1 |
msg2 |
msg3 |
@@ -2173,10 +2345,12 @@ describe('TUI FocusGained/FocusLost', function()
msg5 |
{10:Press ENTER or type command to continue}{1: } |
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
feed_data('\027[I')
feed_data('\027[I')
- screen:expect{grid=[[
+ screen:expect {
+ grid = [[
msg1 |
msg2 |
msg3 |
@@ -2184,7 +2358,9 @@ describe('TUI FocusGained/FocusLost', function()
msg5 |
{10:Press ENTER or type command to continue}{1: } |
{3:-- TERMINAL --} |
- ]], unchanged=true}
+ ]],
+ unchanged = true,
+ }
end)
end)
@@ -2194,97 +2370,108 @@ describe("TUI 't_Co' (terminal colors)", function()
local screen
local function assert_term_colors(term, colorterm, maxcolors)
- clear({env={TERM=term}, args={}})
- -- This is ugly because :term/termopen() forces TERM=xterm-256color.
- -- TODO: Revisit this after jobstart/termopen accept `env` dict.
- screen = thelpers.screen_setup(0, string.format(
- [=[['sh', '-c', 'LANG=C TERM=%s %s %s -u NONE -i NONE --cmd "%s"']]=],
- term or "",
- (colorterm ~= nil and "COLORTERM="..colorterm or ""),
- nvim_prog,
- nvim_set))
+ clear({ env = { TERM = term }, args = {} })
+ screen = thelpers.setup_child_nvim({
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ 'colorscheme vim',
+ '--cmd',
+ nvim_set .. ' notermguicolors',
+ }, {
+ env = {
+ LANG = 'C',
+ TERM = term or '',
+ COLORTERM = colorterm or '',
+ },
+ })
local tline
- if maxcolors == 8 or maxcolors == 16 then
- tline = "~ "
+ if maxcolors == 8 then
+ tline = '{9:~ }'
+ elseif maxcolors == 16 then
+ tline = '~ '
else
- tline = "{4:~ }"
+ tline = '{4:~ }'
end
- screen:expect(string.format([[
+ screen:expect(string.format(
+ [[
{1: } |
- %s|
- %s|
- %s|
- %s|
+ %s|*4
|
{3:-- TERMINAL --} |
- ]], tline, tline, tline, tline))
+ ]],
+ tline
+ ))
- feed_data(":echo &t_Co\n")
- screen:expect(string.format([[
+ feed_data(':echo &t_Co\n')
+ screen:expect(string.format(
+ [[
{1: } |
- %s|
- %s|
- %s|
- %s|
+ %s|*4
%-3s |
{3:-- TERMINAL --} |
- ]], tline, tline, tline, tline, tostring(maxcolors and maxcolors or "")))
+ ]],
+ tline,
+ tostring(maxcolors and maxcolors or '')
+ ))
end
-- ansi and no terminal type at all:
- it("no TERM uses 8 colors", function()
+ it('no TERM uses 8 colors', function()
assert_term_colors(nil, nil, 8)
end)
- it("TERM=ansi no COLORTERM uses 8 colors", function()
- assert_term_colors("ansi", nil, 8)
+ it('TERM=ansi no COLORTERM uses 8 colors', function()
+ assert_term_colors('ansi', nil, 8)
end)
- it("TERM=ansi with COLORTERM=anything-no-number uses 16 colors", function()
- assert_term_colors("ansi", "yet-another-term", 16)
+ it('TERM=ansi with COLORTERM=anything-no-number uses 16 colors', function()
+ assert_term_colors('ansi', 'yet-another-term', 16)
end)
- it("unknown TERM COLORTERM with 256 in name uses 256 colors", function()
- assert_term_colors("ansi", "yet-another-term-256color", 256)
+ it('unknown TERM COLORTERM with 256 in name uses 256 colors', function()
+ assert_term_colors('ansi', 'yet-another-term-256color', 256)
end)
- it("TERM=ansi-256color sets 256 colours", function()
- assert_term_colors("ansi-256color", nil, 256)
+ it('TERM=ansi-256color sets 256 colours', function()
+ assert_term_colors('ansi-256color', nil, 256)
end)
-- Unknown terminal types:
- it("unknown TERM no COLORTERM sets 8 colours", function()
- assert_term_colors("yet-another-term", nil, 8)
+ it('unknown TERM no COLORTERM sets 8 colours', function()
+ assert_term_colors('yet-another-term', nil, 8)
end)
- it("unknown TERM with COLORTERM=anything-no-number uses 16 colors", function()
- assert_term_colors("yet-another-term", "yet-another-term", 16)
+ it('unknown TERM with COLORTERM=anything-no-number uses 16 colors', function()
+ assert_term_colors('yet-another-term', 'yet-another-term', 16)
end)
- it("unknown TERM with 256 in name sets 256 colours", function()
- assert_term_colors("yet-another-term-256color", nil, 256)
+ it('unknown TERM with 256 in name sets 256 colours', function()
+ assert_term_colors('yet-another-term-256color', nil, 256)
end)
- it("unknown TERM COLORTERM with 256 in name uses 256 colors", function()
- assert_term_colors("yet-another-term", "yet-another-term-256color", 256)
+ it('unknown TERM COLORTERM with 256 in name uses 256 colors', function()
+ assert_term_colors('yet-another-term', 'yet-another-term-256color', 256)
end)
-- Linux kernel terminal emulator:
- it("TERM=linux uses 256 colors", function()
- assert_term_colors("linux", nil, 256)
+ it('TERM=linux uses 256 colors', function()
+ assert_term_colors('linux', nil, 256)
end)
- it("TERM=linux-16color uses 256 colors", function()
- assert_term_colors("linux-16color", nil, 256)
+ it('TERM=linux-16color uses 256 colors', function()
+ assert_term_colors('linux-16color', nil, 256)
end)
- it("TERM=linux-256color uses 256 colors", function()
- assert_term_colors("linux-256color", nil, 256)
+ it('TERM=linux-256color uses 256 colors', function()
+ assert_term_colors('linux-256color', nil, 256)
end)
-- screen:
@@ -2293,28 +2480,28 @@ describe("TUI 't_Co' (terminal colors)", function()
-- Linux and MacOS have a screen entry in external terminfo with 8 colours,
-- which is raised to 16 by COLORTERM.
- it("TERM=screen no COLORTERM uses 8/256 colors", function()
+ it('TERM=screen no COLORTERM uses 8/256 colors', function()
if is_os('freebsd') then
- assert_term_colors("screen", nil, 256)
+ assert_term_colors('screen', nil, 256)
else
- assert_term_colors("screen", nil, 8)
+ assert_term_colors('screen', nil, 8)
end
end)
- it("TERM=screen COLORTERM=screen uses 16/256 colors", function()
+ it('TERM=screen COLORTERM=screen uses 16/256 colors', function()
if is_os('freebsd') then
- assert_term_colors("screen", "screen", 256)
+ assert_term_colors('screen', 'screen', 256)
else
- assert_term_colors("screen", "screen", 16)
+ assert_term_colors('screen', 'screen', 16)
end
end)
- it("TERM=screen COLORTERM=screen-256color uses 256 colors", function()
- assert_term_colors("screen", "screen-256color", 256)
+ it('TERM=screen COLORTERM=screen-256color uses 256 colors', function()
+ assert_term_colors('screen', 'screen-256color', 256)
end)
- it("TERM=screen-256color no COLORTERM uses 256 colors", function()
- assert_term_colors("screen-256color", nil, 256)
+ it('TERM=screen-256color no COLORTERM uses 256 colors', function()
+ assert_term_colors('screen-256color', nil, 256)
end)
-- tmux:
@@ -2323,38 +2510,38 @@ describe("TUI 't_Co' (terminal colors)", function()
-- Linux has a tmux entry in external terminfo with 8 colours,
-- which is raised to 256.
- it("TERM=tmux no COLORTERM uses 256 colors", function()
- assert_term_colors("tmux", nil, 256)
+ it('TERM=tmux no COLORTERM uses 256 colors', function()
+ assert_term_colors('tmux', nil, 256)
end)
- it("TERM=tmux COLORTERM=tmux uses 256 colors", function()
- assert_term_colors("tmux", "tmux", 256)
+ it('TERM=tmux COLORTERM=tmux uses 256 colors', function()
+ assert_term_colors('tmux', 'tmux', 256)
end)
- it("TERM=tmux COLORTERM=tmux-256color uses 256 colors", function()
- assert_term_colors("tmux", "tmux-256color", 256)
+ it('TERM=tmux COLORTERM=tmux-256color uses 256 colors', function()
+ assert_term_colors('tmux', 'tmux-256color', 256)
end)
- it("TERM=tmux-256color no COLORTERM uses 256 colors", function()
- assert_term_colors("tmux-256color", nil, 256)
+ it('TERM=tmux-256color no COLORTERM uses 256 colors', function()
+ assert_term_colors('tmux-256color', nil, 256)
end)
-- xterm and imitators:
- it("TERM=xterm uses 256 colors", function()
- assert_term_colors("xterm", nil, 256)
+ it('TERM=xterm uses 256 colors', function()
+ assert_term_colors('xterm', nil, 256)
end)
- it("TERM=xterm COLORTERM=gnome-terminal uses 256 colors", function()
- assert_term_colors("xterm", "gnome-terminal", 256)
+ it('TERM=xterm COLORTERM=gnome-terminal uses 256 colors', function()
+ assert_term_colors('xterm', 'gnome-terminal', 256)
end)
- it("TERM=xterm COLORTERM=mate-terminal uses 256 colors", function()
- assert_term_colors("xterm", "mate-terminal", 256)
+ it('TERM=xterm COLORTERM=mate-terminal uses 256 colors', function()
+ assert_term_colors('xterm', 'mate-terminal', 256)
end)
- it("TERM=xterm-256color uses 256 colors", function()
- assert_term_colors("xterm-256color", nil, 256)
+ it('TERM=xterm-256color uses 256 colors', function()
+ assert_term_colors('xterm-256color', nil, 256)
end)
-- rxvt and stterm:
@@ -2364,44 +2551,44 @@ describe("TUI 't_Co' (terminal colors)", function()
-- Linux has an rxvt, an st, and an st-16color entry in external terminfo
-- with 8, 8, and 16 colours respectively, which are raised to 256.
- it("TERM=rxvt no COLORTERM uses 256 colors", function()
- assert_term_colors("rxvt", nil, 256)
+ it('TERM=rxvt no COLORTERM uses 256 colors', function()
+ assert_term_colors('rxvt', nil, 256)
end)
- it("TERM=rxvt COLORTERM=rxvt uses 256 colors", function()
- assert_term_colors("rxvt", "rxvt", 256)
+ it('TERM=rxvt COLORTERM=rxvt uses 256 colors', function()
+ assert_term_colors('rxvt', 'rxvt', 256)
end)
- it("TERM=rxvt-256color uses 256 colors", function()
- assert_term_colors("rxvt-256color", nil, 256)
+ it('TERM=rxvt-256color uses 256 colors', function()
+ assert_term_colors('rxvt-256color', nil, 256)
end)
- it("TERM=st no COLORTERM uses 256 colors", function()
- assert_term_colors("st", nil, 256)
+ it('TERM=st no COLORTERM uses 256 colors', function()
+ assert_term_colors('st', nil, 256)
end)
- it("TERM=st COLORTERM=st uses 256 colors", function()
- assert_term_colors("st", "st", 256)
+ it('TERM=st COLORTERM=st uses 256 colors', function()
+ assert_term_colors('st', 'st', 256)
end)
- it("TERM=st COLORTERM=st-256color uses 256 colors", function()
- assert_term_colors("st", "st-256color", 256)
+ it('TERM=st COLORTERM=st-256color uses 256 colors', function()
+ assert_term_colors('st', 'st-256color', 256)
end)
- it("TERM=st-16color no COLORTERM uses 8/256 colors", function()
- assert_term_colors("st", nil, 256)
+ it('TERM=st-16color no COLORTERM uses 8/256 colors', function()
+ assert_term_colors('st', nil, 256)
end)
- it("TERM=st-16color COLORTERM=st uses 16/256 colors", function()
- assert_term_colors("st", "st", 256)
+ it('TERM=st-16color COLORTERM=st uses 16/256 colors', function()
+ assert_term_colors('st', 'st', 256)
end)
- it("TERM=st-16color COLORTERM=st-256color uses 256 colors", function()
- assert_term_colors("st", "st-256color", 256)
+ it('TERM=st-16color COLORTERM=st-256color uses 256 colors', function()
+ assert_term_colors('st', 'st-256color', 256)
end)
- it("TERM=st-256color uses 256 colors", function()
- assert_term_colors("st-256color", nil, 256)
+ it('TERM=st-256color uses 256 colors', function()
+ assert_term_colors('st-256color', nil, 256)
end)
-- gnome and vte:
@@ -2411,54 +2598,53 @@ describe("TUI 't_Co' (terminal colors)", function()
-- external terminfo with 8, 8, 256, and 256 colours respectively, which are
-- raised to 256.
- it("TERM=gnome no COLORTERM uses 256 colors", function()
- assert_term_colors("gnome", nil, 256)
+ it('TERM=gnome no COLORTERM uses 256 colors', function()
+ assert_term_colors('gnome', nil, 256)
end)
- it("TERM=gnome COLORTERM=gnome uses 256 colors", function()
- assert_term_colors("gnome", "gnome", 256)
+ it('TERM=gnome COLORTERM=gnome uses 256 colors', function()
+ assert_term_colors('gnome', 'gnome', 256)
end)
- it("TERM=gnome COLORTERM=gnome-256color uses 256 colors", function()
- assert_term_colors("gnome", "gnome-256color", 256)
+ it('TERM=gnome COLORTERM=gnome-256color uses 256 colors', function()
+ assert_term_colors('gnome', 'gnome-256color', 256)
end)
- it("TERM=gnome-256color uses 256 colors", function()
- assert_term_colors("gnome-256color", nil, 256)
+ it('TERM=gnome-256color uses 256 colors', function()
+ assert_term_colors('gnome-256color', nil, 256)
end)
- it("TERM=vte no COLORTERM uses 256 colors", function()
- assert_term_colors("vte", nil, 256)
+ it('TERM=vte no COLORTERM uses 256 colors', function()
+ assert_term_colors('vte', nil, 256)
end)
- it("TERM=vte COLORTERM=vte uses 256 colors", function()
- assert_term_colors("vte", "vte", 256)
+ it('TERM=vte COLORTERM=vte uses 256 colors', function()
+ assert_term_colors('vte', 'vte', 256)
end)
- it("TERM=vte COLORTERM=vte-256color uses 256 colors", function()
- assert_term_colors("vte", "vte-256color", 256)
+ it('TERM=vte COLORTERM=vte-256color uses 256 colors', function()
+ assert_term_colors('vte', 'vte-256color', 256)
end)
- it("TERM=vte-256color uses 256 colors", function()
- assert_term_colors("vte-256color", nil, 256)
+ it('TERM=vte-256color uses 256 colors', function()
+ assert_term_colors('vte-256color', nil, 256)
end)
-- others:
-- TODO(blueyed): this is made pending, since it causes failure + later hang
-- when using non-compatible libvterm (#9494/#10179).
- pending("TERM=interix uses 8 colors", function()
- assert_term_colors("interix", nil, 8)
+ pending('TERM=interix uses 8 colors', function()
+ assert_term_colors('interix', nil, 8)
end)
- it("TERM=iTerm.app uses 256 colors", function()
- assert_term_colors("iTerm.app", nil, 256)
+ it('TERM=iTerm.app uses 256 colors', function()
+ assert_term_colors('iTerm.app', nil, 256)
end)
- it("TERM=iterm uses 256 colors", function()
- assert_term_colors("iterm", nil, 256)
+ it('TERM=iterm uses 256 colors', function()
+ assert_term_colors('iterm', nil, 256)
end)
-
end)
-- These tests require `thelpers` because --headless/--embed
@@ -2468,39 +2654,43 @@ describe("TUI 'term' option", function()
local function assert_term(term_envvar, term_expected)
clear()
- -- This is ugly because :term/termopen() forces TERM=xterm-256color.
- -- TODO: Revisit this after jobstart/termopen accept `env` dict.
- local cmd = string.format(
- [=[['sh', '-c', 'LANG=C TERM=%s %s -u NONE -i NONE --cmd "%s"']]=],
- term_envvar or "",
- nvim_prog,
- nvim_set)
- screen = thelpers.screen_setup(0, cmd)
+ screen = thelpers.setup_child_nvim({
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ nvim_set .. ' notermguicolors',
+ }, {
+ env = {
+ LANG = 'C',
+ TERM = term_envvar or '',
+ },
+ })
local full_timeout = screen.timeout
- screen.timeout = 250 -- We want screen:expect() to fail quickly.
- retry(nil, 2 * full_timeout, function() -- Wait for TUI thread to set 'term'.
+ retry(nil, 2 * full_timeout, function() -- Wait for TUI thread to set 'term'.
feed_data(":echo 'term='.(&term)\n")
- screen:expect{any='term='..term_expected}
+ screen:expect { any = 'term=' .. term_expected, timeout = 250 }
end)
end
it('gets builtin term if $TERM is invalid', function()
- assert_term("foo", "builtin_ansi")
+ assert_term('foo', 'builtin_ansi')
end)
it('gets system-provided term if $TERM is valid', function()
if is_os('openbsd') then
- assert_term("xterm", "xterm")
- elseif is_os('bsd') then -- BSD lacks terminfo, builtin is always used.
- assert_term("xterm", "builtin_xterm")
+ assert_term('xterm', 'xterm')
+ elseif is_os('bsd') then -- BSD lacks terminfo, builtin is always used.
+ assert_term('xterm', 'builtin_xterm')
elseif is_os('mac') then
- local status, _ = pcall(assert_term, "xterm", "xterm")
+ local status, _ = pcall(assert_term, 'xterm', 'xterm')
if not status then
- pending("macOS: unibilium could not find terminfo")
+ pending('macOS: unibilium could not find terminfo')
end
else
- assert_term("xterm", "xterm")
+ assert_term('xterm', 'xterm')
end
end)
@@ -2510,12 +2700,11 @@ describe("TUI 'term' option", function()
assert_term('conemu', 'builtin_conemu')
assert_term('vtpcon', 'builtin_vtpcon')
end)
-
end)
-- These tests require `thelpers` because --headless/--embed
-- does not initialize the TUI.
-describe("TUI", function()
+describe('TUI', function()
local screen
local logfile = 'Xtest_tui_verbose_log'
after_each(function()
@@ -2525,284 +2714,398 @@ describe("TUI", function()
-- Runs (child) `nvim` in a TTY (:terminal), to start the builtin TUI.
local function nvim_tui(extra_args)
clear()
- -- This is ugly because :term/termopen() forces TERM=xterm-256color.
- -- TODO: Revisit this after jobstart/termopen accept `env` dict.
- local cmd = string.format(
- [=[['sh', '-c', 'LANG=C %s -u NONE -i NONE %s --cmd "%s"']]=],
- nvim_prog,
- extra_args or "",
- nvim_set)
- screen = thelpers.screen_setup(0, cmd)
+ screen = thelpers.setup_child_nvim({
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ 'colorscheme vim',
+ '--cmd',
+ nvim_set .. ' notermguicolors',
+ extra_args,
+ }, {
+ env = {
+ LANG = 'C',
+ },
+ })
end
it('-V3log logs terminfo values', function()
- nvim_tui('-V3'..logfile)
+ nvim_tui('-V3' .. logfile)
-- Wait for TUI to start.
feed_data('Gitext')
screen:expect([[
text{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*4
{3:-- INSERT --} |
{3:-- TERMINAL --} |
]])
- retry(nil, 3000, function() -- Wait for log file to be flushed.
+ retry(nil, 3000, function() -- Wait for log file to be flushed.
local log = read_file('Xtest_tui_verbose_log') or ''
eq('--- Terminal info --- {{{\n', string.match(log, '%-%-%- Terminal.-\n')) -- }}}
ok(#log > 50)
end)
end)
-end)
-
--- See test/unit/tui_spec.lua for unit tests.
-describe('TUI bg color', function()
- local screen
-
- local function setup_bg_test()
- clear()
- screen = thelpers.screen_setup(0, '["'..nvim_prog
- ..'", "-u", "NONE", "-i", "NONE", "--cmd", "set noswapfile", '
- ..'"-c", "autocmd OptionSet background echo \\"did OptionSet, yay!\\""]')
- end
-
- before_each(setup_bg_test)
+ it('does not crash on large inputs #26099', function()
+ nvim_tui()
- it('triggers OptionSet event on unsplit terminal-response', function()
screen:expect([[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
- {5:[No Name] 0,0-1 All}|
+ {4:~ }|*4
|
{3:-- TERMINAL --} |
]])
- feed_data('\027]11;rgb:ffff/ffff/ffff\027\\')
- screen:expect{any='did OptionSet, yay!'}
- feed_data(':echo "new_bg=".&background\n')
- screen:expect{any='new_bg=light'}
+ feed_data(string.format('\027]52;c;%s\027\\', string.rep('A', 8192)))
- setup_bg_test()
- screen:expect([[
+ screen:expect {
+ grid = [[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
- {5:[No Name] 0,0-1 All}|
+ {4:~ }|*4
|
{3:-- TERMINAL --} |
+ ]],
+ unchanged = true,
+ }
+ end)
+
+ it('queries the terminal for truecolor support', function()
+ clear()
+ exec_lua([[
+ vim.api.nvim_create_autocmd('TermRequest', {
+ callback = function(args)
+ local req = args.data
+ local payload = req:match('^\027P%+q([%x;]+)$')
+ if payload then
+ local t = {}
+ for cap in vim.gsplit(payload, ';') do
+ local resp = string.format('\027P1+r%s\027\\', payload)
+ vim.api.nvim_chan_send(vim.bo[args.buf].channel, resp)
+ t[vim.text.hexdecode(cap)] = true
+ end
+ vim.g.xtgettcap = t
+ return true
+ end
+ end,
+ })
]])
- feed_data('\027]11;rgba:ffff/ffff/ffff/8000\027\\')
- screen:expect{any='did OptionSet, yay!'}
- feed_data(':echo "new_bg=".&background\n')
- screen:expect{any='new_bg=light'}
+ local child_server = new_pipename()
+ screen = thelpers.setup_child_nvim({
+ '--listen',
+ child_server,
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ }, {
+ env = {
+ VIMRUNTIME = os.getenv('VIMRUNTIME'),
+
+ -- Force COLORTERM to be unset and use a TERM that does not contain Tc or RGB in terminfo.
+ -- This will force the nested nvim instance to query with XTGETTCAP
+ COLORTERM = '',
+ TERM = 'xterm-256colors',
+ },
+ })
+
+ screen:expect({ any = '%[No Name%]' })
+
+ local child_session = helpers.connect(child_server)
+ retry(nil, 1000, function()
+ eq({
+ Tc = true,
+ RGB = true,
+ setrgbf = true,
+ setrgbb = true,
+ }, eval("get(g:, 'xtgettcap', '')"))
+ eq({ true, 1 }, { child_session:request('nvim_eval', '&termguicolors') })
+ end)
end)
- it('triggers OptionSet event with split terminal-response', function()
- screen:expect([[
- {1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
- {5:[No Name] 0,0-1 All}|
- |
- {3:-- TERMINAL --} |
+ it('queries the terminal for OSC 52 support', function()
+ clear()
+ exec_lua([[
+ vim.api.nvim_create_autocmd('TermRequest', {
+ callback = function(args)
+ local req = args.data
+ local payload = req:match('^\027P%+q([%x;]+)$')
+ if payload and vim.text.hexdecode(payload) == 'Ms' then
+ vim.g.xtgettcap = 'Ms'
+ local resp = string.format('\027P1+r%s=%s\027\\', payload, vim.text.hexencode('\027]52;;\027\\'))
+ vim.api.nvim_chan_send(vim.bo[args.buf].channel, resp)
+ return true
+ end
+ end,
+ })
]])
- -- Send a background response with the OSC command part split.
- feed_data('\027]11;rgb')
- feed_data(':ffff/ffff/ffff\027\\')
- screen:expect{any='did OptionSet, yay!'}
- feed_data(':echo "new_bg=".&background\n')
- screen:expect{any='new_bg=light'}
+ local child_server = new_pipename()
+ screen = thelpers.setup_child_nvim({
+ '--listen',
+ child_server,
+ -- Use --clean instead of -u NONE to load the osc52 plugin
+ '--clean',
+ }, {
+ env = {
+ VIMRUNTIME = os.getenv('VIMRUNTIME'),
+
+ -- Only queries when SSH_TTY is set
+ SSH_TTY = '/dev/pts/1',
+ },
+ })
- setup_bg_test()
- screen:expect([[
- {1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
- {5:[No Name] 0,0-1 All}|
- |
- {3:-- TERMINAL --} |
- ]])
- -- Send a background response with the Pt portion split.
- feed_data('\027]11;rgba:ffff/fff')
- feed_data('f/ffff/8000\027\\')
- screen:expect{any='did OptionSet, yay!'}
+ screen:expect({ any = '%[No Name%]' })
- feed_data(':echo "new_bg=".&background\n')
- screen:expect{any='new_bg=light'}
+ local child_session = helpers.connect(child_server)
+ retry(nil, 1000, function()
+ eq('Ms', eval("get(g:, 'xtgettcap', '')"))
+ eq({ true, 'OSC 52' }, { child_session:request('nvim_eval', 'g:clipboard.name') })
+ end)
end)
+end)
- it('not triggers OptionSet event with invalid terminal-response', function()
- screen:expect([[
- {1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
- {5:[No Name] 0,0-1 All}|
- |
- {3:-- TERMINAL --} |
- ]])
- feed_data('\027]11;rgb:ffff/ffff/ffff/8000\027\\')
- screen:expect_unchanged()
+describe('TUI bg color', function()
+ before_each(clear)
+
+ it('is properly set in a nested Nvim instance when background=dark', function()
+ command('highlight clear Normal')
+ command('set background=dark') -- set outer Nvim background
+ local child_server = new_pipename()
+ local screen = thelpers.setup_child_nvim({
+ '--listen',
+ child_server,
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ 'colorscheme vim',
+ '--cmd',
+ 'set noswapfile',
+ })
+ screen:expect({ any = '%[No Name%]' })
+ local child_session = helpers.connect(child_server)
+ retry(nil, nil, function()
+ eq({ true, 'dark' }, { child_session:request('nvim_eval', '&background') })
+ end)
+ end)
- feed_data(':echo "new_bg=".&background\n')
- screen:expect{any='new_bg=dark'}
+ it('is properly set in a nested Nvim instance when background=light', function()
+ command('highlight clear Normal')
+ command('set background=light') -- set outer Nvim background
+ local child_server = new_pipename()
+ local screen = thelpers.setup_child_nvim({
+ '--listen',
+ child_server,
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ 'colorscheme vim',
+ '--cmd',
+ 'set noswapfile',
+ })
+ screen:expect({ any = '%[No Name%]' })
+ local child_session = helpers.connect(child_server)
+ retry(nil, nil, function()
+ eq({ true, 'light' }, { child_session:request('nvim_eval', '&background') })
+ end)
+ end)
+
+ it('queries the terminal for background color', function()
+ exec_lua([[
+ vim.api.nvim_create_autocmd('TermRequest', {
+ callback = function(args)
+ local req = args.data
+ if req == '\027]11;?' then
+ vim.g.oscrequest = true
+ return true
+ end
+ end,
+ })
+ ]])
+ thelpers.setup_child_nvim({
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ 'colorscheme vim',
+ '--cmd',
+ 'set noswapfile',
+ })
+ retry(nil, 1000, function()
+ eq(true, eval("get(g:, 'oscrequest', v:false)"))
+ end)
+ end)
- setup_bg_test()
+ it('triggers OptionSet from automatic background processing', function()
+ local screen = thelpers.setup_child_nvim({
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ 'colorscheme vim',
+ '--cmd',
+ 'set noswapfile',
+ '-c',
+ 'autocmd OptionSet background echo "did OptionSet, yay!"',
+ })
screen:expect([[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {3:~} |*3
{5:[No Name] 0,0-1 All}|
- |
+ did OptionSet, yay! |
{3:-- TERMINAL --} |
]])
- feed_data('\027]11;rgba:ffff/foo/ffff/8000\027\\')
- screen:expect_unchanged()
-
- feed_data(':echo "new_bg=".&background\n')
- screen:expect{any='new_bg=dark'}
end)
end)
-- These tests require `thelpers` because --headless/--embed
-- does not initialize the TUI.
-describe("TUI as a client", function()
-
- it("connects to remote instance (with its own TUI)", function()
+describe('TUI as a client', function()
+ it('connects to remote instance (with its own TUI)', function()
local server_super = spawn_argv(false) -- equivalent to clear()
local client_super = spawn_argv(true)
set_session(server_super)
local server_pipe = new_pipename()
- local screen_server = thelpers.screen_setup(0,
- string.format([=[["%s", "--listen", "%s", "-u", "NONE", "-i", "NONE", "--cmd", "%s laststatus=2 background=dark"]]=],
- nvim_prog, server_pipe, nvim_set))
+ local screen_server = thelpers.setup_child_nvim({
+ '--listen',
+ server_pipe,
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ 'colorscheme vim',
+ '--cmd',
+ nvim_set .. ' notermguicolors laststatus=2 background=dark',
+ })
- feed_data("iHello, World")
- screen_server:expect{grid=[[
+ feed_data('iHello, World')
+ screen_server:expect {
+ grid = [[
Hello, World{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
- ]]}
- feed_data("\027")
- screen_server:expect{grid=[[
+ ]],
+ }
+ feed_data('\027')
+ screen_server:expect {
+ grid = [[
Hello, Worl{1:d} |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
set_session(client_super)
- local screen_client = thelpers.screen_setup(0,
- string.format([=[["%s", "--server", "%s", "--remote-ui"]]=],
- nvim_prog, server_pipe))
+ local screen_client = thelpers.setup_child_nvim({
+ '--server',
+ server_pipe,
+ '--remote-ui',
+ })
- screen_client:expect{grid=[[
+ screen_client:expect {
+ grid = [[
Hello, Worl{1:d} |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
-- grid smaller than containing terminal window is cleared properly
feed_data(":call setline(1,['a'->repeat(&columns)]->repeat(&lines))\n")
- feed_data("0:set lines=3\n")
- screen_server:expect{grid=[[
+ feed_data('0:set lines=3\n')
+ screen_server:expect {
+ grid = [[
{1:a}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
{5:[No Name] [+] }|
- |
- |
- |
- |
+ |*4
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
- feed_data(":q!\n")
+ feed_data(':q!\n')
server_super:close()
client_super:close()
end)
- it("connects to remote instance (--headless)", function()
+ it('connects to remote instance (--headless)', function()
local server = spawn_argv(false) -- equivalent to clear()
local client_super = spawn_argv(true)
set_session(server)
- local server_pipe = meths.get_vvar('servername')
+ local server_pipe = api.nvim_get_vvar('servername')
server:request('nvim_input', 'iHalloj!<Esc>')
+ server:request('nvim_command', 'set notermguicolors')
set_session(client_super)
- local screen_client = thelpers.screen_setup(0,
- string.format([=[["%s", "--server", "%s", "--remote-ui"]]=],
- nvim_prog, server_pipe))
+ local screen_client = thelpers.setup_child_nvim({
+ '--server',
+ server_pipe,
+ '--remote-ui',
+ })
- screen_client:expect{grid=[[
+ screen_client:expect {
+ grid = [[
Halloj{1:!} |
- {4:~ }|
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*4
|
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
-- No heap-use-after-free when receiving UI events after deadly signal #22184
server:request('nvim_input', ('a'):rep(1000))
exec_lua([[vim.uv.kill(vim.fn.jobpid(vim.bo.channel), 'sigterm')]])
- screen_client:expect{grid=[[
+ screen_client:expect {
+ grid = [[
Vim: Caught deadly signal 'SIGTERM' |
- |
- |
+ |*2
[Process exited 1]{1: } |
- |
- |
+ |*2
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
- eq(0, meths.get_vvar('shell_error'))
+ eq(0, api.nvim_get_vvar('shell_error'))
-- exits on input eof #22244
- funcs.system({nvim_prog, '--server', server_pipe, '--remote-ui'})
- eq(1, meths.get_vvar('shell_error'))
+ fn.system({ nvim_prog, '--server', server_pipe, '--remote-ui' })
+ eq(1, api.nvim_get_vvar('shell_error'))
client_super:close()
server:close()
end)
- it("throws error when no server exists", function()
+ it('throws error when no server exists', function()
clear()
- local screen = thelpers.screen_setup(0,
- string.format([=[["%s", "--server", "127.0.0.1:2436546", "--remote-ui"]]=],
- nvim_prog), 60)
+ local screen = thelpers.setup_child_nvim({
+ '--server',
+ '127.0.0.1:2436546',
+ '--remote-ui',
+ }, { cols = 60 })
screen:expect([[
Remote ui failed to start: {MATCH:.*}|
|
[Process exited 1]{1: } |
- |
- |
- |
+ |*3
{3:-- TERMINAL --} |
]])
end)
@@ -2813,89 +3116,98 @@ describe("TUI as a client", function()
set_session(server_super)
local server_pipe = new_pipename()
- local screen_server = thelpers.screen_setup(0,
- string.format([=[["%s", "--listen", "%s", "-u", "NONE", "-i", "NONE", "--cmd", "%s laststatus=2 background=dark"]]=],
- nvim_prog, server_pipe, nvim_set))
- screen_server:expect{grid=[[
+ local screen_server = thelpers.setup_child_nvim({
+ '--listen',
+ server_pipe,
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ 'colorscheme vim',
+ '--cmd',
+ nvim_set .. ' notermguicolors laststatus=2 background=dark',
+ })
+ screen_server:expect {
+ grid = [[
{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] }|
|
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
- feed_data("iHello, World")
- screen_server:expect{grid=[[
+ feed_data('iHello, World')
+ screen_server:expect {
+ grid = [[
Hello, World{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
- ]]}
- feed_data("\027")
- screen_server:expect{grid=[[
+ ]],
+ }
+ feed_data('\027')
+ screen_server:expect {
+ grid = [[
Hello, Worl{1:d} |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
set_session(client_super)
- local screen_client = thelpers.screen_setup(0,
- string.format([=[["%s", "--server", "%s", "--remote-ui"]]=],
- nvim_prog, server_pipe))
+ local screen_client = thelpers.setup_child_nvim({
+ '--server',
+ server_pipe,
+ '--remote-ui',
+ })
- screen_client:expect{grid=[[
+ screen_client:expect {
+ grid = [[
Hello, Worl{1:d} |
- {4:~ }|
- {4:~ }|
- {4:~ }|
+ {4:~ }|*3
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
-- quitting the server
set_session(server_super)
- feed_data(status and ':' .. status .. 'cquit!\n' or ":quit!\n")
+ feed_data(status and ':' .. status .. 'cquit!\n' or ':quit!\n')
status = status and status or 0
- screen_server:expect{grid=[[
+ screen_server:expect {
+ grid = [[
|
[Process exited ]] .. status .. [[]{1: }{MATCH:%s+}|
- |
- |
- |
- |
+ |*4
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
-- assert that client has exited
- screen_client:expect{grid=[[
+ screen_client:expect {
+ grid = [[
|
[Process exited ]] .. status .. [[]{1: }{MATCH:%s+}|
- |
- |
- |
- |
+ |*4
{3:-- TERMINAL --} |
- ]]}
+ ]],
+ }
server_super:close()
client_super:close()
end
- describe("exits when server quits", function()
- it("with :quit", function()
+ describe('exits when server quits', function()
+ it('with :quit', function()
test_remote_tui_quit()
end)
- it("with :cquit", function()
+ it('with :cquit', function()
test_remote_tui_quit(42)
end)
end)