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.lua921
1 files changed, 667 insertions, 254 deletions
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index 1d9e7b8e11..b17eed00f9 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -8,7 +8,6 @@ local helpers = require('test.functional.helpers')(after_each)
local thelpers = require('test.functional.terminal.helpers')
local Screen = require('test.functional.ui.screen')
local eq = helpers.eq
-local feed_command = helpers.feed_command
local feed_data = thelpers.feed_data
local clear = helpers.clear
local command = helpers.command
@@ -28,10 +27,9 @@ 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 feed = helpers.feed
-local eval = helpers.eval
+local write_file = helpers.write_file
-if helpers.skip(helpers.is_os('win')) then return end
+if helpers.skip(is_os('win')) then return end
describe('TUI', function()
local screen
@@ -69,13 +67,13 @@ describe('TUI', function()
local function expect_child_buf_lines(expected)
assert(type({}) == type(expected))
retry(nil, nil, function()
- local _, buflines = child_session:request(
- 'nvim_buf_get_lines', 0, 0, -1, false)
+ local _, buflines = child_session:request('nvim_buf_get_lines', 0, 0, -1, false)
eq(expected, buflines)
end)
end
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")
screen:expect([[
@@ -109,14 +107,14 @@ describe('TUI', function()
end)
it('accepts resize while pager is active', function()
- child_session:request("nvim_command", [[
- set more
- func! ManyErr()
- for i in range(10)
- echoerr "FAIL ".i
- endfor
- endfunc
- ]])
+ 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=[[
{8:Error detected while processing function ManyErr:} |
@@ -128,7 +126,35 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]]}
- feed_data('d')
+ 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} |
+ |
+ |
+ {10:-- More --}{1: } |
+ {3:-- TERMINAL --} |
+ ]]}
+
+ feed_data('j')
+ screen:expect{grid=[[
+ {8:Error detected while processing function ManyErr:} |
+ {11:line 2:} |
+ {8:FAIL 0} |
+ {8:FAIL 1} |
+ {8:FAIL 2} |
+ {8:FAIL 3} |
+ {8:FAIL 4} |
+ {8:FAIL 5} |
+ {10:-- More --}{1: } |
+ {3:-- TERMINAL --} |
+ ]]}
+
+ screen:try_resize(50,7)
screen:expect{grid=[[
{8:FAIL 1} |
{8:FAIL 2} |
@@ -212,7 +238,7 @@ 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_command('nnoremap <a-'..c..'> ialt-'..c..'<cr><esc>')
+ feed_data(':nnoremap <a-'..c..'> ialt-'..c..'<cr><esc>\r')
feed_data('\027'..c)
end
screen:expect([[
@@ -252,9 +278,11 @@ 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>')
+ child_session:request('nvim_exec2', [[
+ nnoremap <M-;> <Nop>
+ nnoremap <Esc> AESC<Esc>
+ nnoremap ; Asemicolon<Esc>
+ ]], {})
feed_data('\027[27u;')
screen:expect([[
ESCsemicolo{1:n} |
@@ -291,22 +319,22 @@ describe('TUI', function()
local attrs = screen:get_default_attr_ids()
attrs[11] = {foreground = 81}
screen:expect([[
- {11:^G^V^M}{1: } |
- {4:~ }|
- {4:~ }|
- {4:~ }|
- {5:[No Name] [+] }|
- {3:-- INSERT --} |
- {3:-- TERMINAL --} |
+ {11:^G^V^M}{1: } |
+ {4:~ }|
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] [+] }|
+ {3:-- INSERT --} |
+ {3:-- TERMINAL --} |
]], attrs)
end)
- it('accepts mouse wheel events #19992', function()
- child_session:request('nvim_command', [[
+ local function test_mouse_wheel(esc)
+ 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----|
@@ -317,7 +345,11 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
-- <ScrollWheelDown> in active window
- feed_data('\027[<65;8;1M')
+ if esc then
+ feed_data('\027[<65;8;1M')
+ else
+ meths.input_mouse('wheel', 'down', '', 0, 0, 7)
+ end
screen:expect([[
{11: 2 }{1:0}----1----2----3----4│{11: 1 }0----1----2----3----|
{11: 3 }0----1----2----3----4│{11: 2 }0----1----2----3----|
@@ -328,7 +360,11 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
-- <ScrollWheelDown> in inactive window
- feed_data('\027[<65;48;1M')
+ if esc then
+ feed_data('\027[<65;48;1M')
+ else
+ meths.input_mouse('wheel', 'down', '', 0, 0, 47)
+ end
screen:expect([[
{11: 2 }{1:0}----1----2----3----4│{11: 2 }0----1----2----3----|
{11: 3 }0----1----2----3----4│{11: 3 }0----1----2----3----|
@@ -339,7 +375,11 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
-- <ScrollWheelRight> in active window
- feed_data('\027[<67;8;1M')
+ if esc then
+ feed_data('\027[<67;8;1M')
+ else
+ meths.input_mouse('wheel', 'right', '', 0, 0, 7)
+ end
screen:expect([[
{11: 2 }{1:-}---1----2----3----4-│{11: 2 }0----1----2----3----|
{11: 3 }----1----2----3----4-│{11: 3 }0----1----2----3----|
@@ -350,7 +390,11 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
-- <ScrollWheelRight> in inactive window
- feed_data('\027[<67;48;1M')
+ if esc then
+ feed_data('\027[<67;48;1M')
+ else
+ meths.input_mouse('wheel', 'right', '', 0, 0, 47)
+ end
screen:expect([[
{11: 2 }{1:-}---1----2----3----4-│{11: 2 }----1----2----3----4|
{11: 3 }----1----2----3----4-│{11: 3 }----1----2----3----4|
@@ -361,7 +405,11 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
-- <S-ScrollWheelDown> in active window
- feed_data('\027[<69;8;1M')
+ if esc then
+ feed_data('\027[<69;8;1M')
+ else
+ meths.input_mouse('wheel', 'down', 'S', 0, 0, 7)
+ end
screen:expect([[
{11: 5 }{1:-}---1----2----3----4-│{11: 2 }----1----2----3----4|
{11: 6 }----1----2----3----4-│{11: 3 }----1----2----3----4|
@@ -372,7 +420,11 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
-- <S-ScrollWheelDown> in inactive window
- feed_data('\027[<69;48;1M')
+ if esc then
+ feed_data('\027[<69;48;1M')
+ else
+ meths.input_mouse('wheel', 'down', 'S', 0, 0, 47)
+ end
screen:expect([[
{11: 5 }{1:-}---1----2----3----4-│{11: 5 }----1----2----3----4|
{11: 6 }----1----2----3----4-│{11: 6 }----1----2----3----4|
@@ -383,7 +435,11 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
-- <S-ScrollWheelRight> in active window
- feed_data('\027[<71;8;1M')
+ if esc then
+ feed_data('\027[<71;8;1M')
+ else
+ meths.input_mouse('wheel', 'right', 'S', 0, 0, 7)
+ end
screen:expect([[
{11: 5 }{1:-}---6----7----8----9 │{11: 5 }----1----2----3----4|
{11: 6 }----6----7----8----9 │{11: 6 }----1----2----3----4|
@@ -394,7 +450,11 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
-- <S-ScrollWheelRight> in inactive window
- feed_data('\027[<71;48;1M')
+ if esc then
+ feed_data('\027[<71;48;1M')
+ else
+ meths.input_mouse('wheel', 'right', 'S', 0, 0, 47)
+ end
screen:expect([[
{11: 5 }{1:-}---6----7----8----9 │{11: 5 }5----6----7----8----|
{11: 6 }----6----7----8----9 │{11: 6 }5----6----7----8----|
@@ -405,7 +465,11 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
-- <ScrollWheelUp> in active window
- feed_data('\027[<64;8;1M')
+ if esc then
+ feed_data('\027[<64;8;1M')
+ else
+ meths.input_mouse('wheel', 'up', '', 0, 0, 7)
+ end
screen:expect([[
{11: 4 }----6----7----8----9 │{11: 5 }5----6----7----8----|
{11: 5 }{1:-}---6----7----8----9 │{11: 6 }5----6----7----8----|
@@ -416,7 +480,11 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
-- <ScrollWheelUp> in inactive window
- feed_data('\027[<64;48;1M')
+ if esc then
+ feed_data('\027[<64;48;1M')
+ else
+ meths.input_mouse('wheel', 'up', '', 0, 0, 47)
+ end
screen:expect([[
{11: 4 }----6----7----8----9 │{11: 4 }5----6----7----8----|
{11: 5 }{1:-}---6----7----8----9 │{11: 5 }5----6----7----8----|
@@ -427,7 +495,11 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
-- <ScrollWheelLeft> in active window
- feed_data('\027[<66;8;1M')
+ if esc then
+ feed_data('\027[<66;8;1M')
+ else
+ meths.input_mouse('wheel', 'left', '', 0, 0, 7)
+ end
screen:expect([[
{11: 4 }5----6----7----8----9│{11: 4 }5----6----7----8----|
{11: 5 }5{1:-}---6----7----8----9│{11: 5 }5----6----7----8----|
@@ -438,7 +510,11 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
-- <ScrollWheelLeft> in inactive window
- feed_data('\027[<66;48;1M')
+ if esc then
+ feed_data('\027[<66;48;1M')
+ else
+ meths.input_mouse('wheel', 'left', '', 0, 0, 47)
+ end
screen:expect([[
{11: 4 }5----6----7----8----9│{11: 4 }-5----6----7----8---|
{11: 5 }5{1:-}---6----7----8----9│{11: 5 }-5----6----7----8---|
@@ -449,7 +525,11 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
-- <S-ScrollWheelUp> in active window
- feed_data('\027[<68;8;1M')
+ if esc then
+ feed_data('\027[<68;8;1M')
+ else
+ meths.input_mouse('wheel', 'up', 'S', 0, 0, 7)
+ end
screen:expect([[
{11: 1 }5----6----7----8----9│{11: 4 }-5----6----7----8---|
{11: 2 }5----6----7----8----9│{11: 5 }-5----6----7----8---|
@@ -460,7 +540,11 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
-- <S-ScrollWheelUp> in inactive window
- feed_data('\027[<68;48;1M')
+ if esc then
+ feed_data('\027[<68;48;1M')
+ else
+ meths.input_mouse('wheel', 'up', 'S', 0, 0, 47)
+ end
screen:expect([[
{11: 1 }5----6----7----8----9│{11: 1 }-5----6----7----8---|
{11: 2 }5----6----7----8----9│{11: 2 }-5----6----7----8---|
@@ -471,7 +555,11 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
-- <S-ScrollWheelLeft> in active window
- feed_data('\027[<70;8;1M')
+ if esc then
+ feed_data('\027[<70;8;1M')
+ else
+ meths.input_mouse('wheel', 'left', 'S', 0, 0, 7)
+ end
screen:expect([[
{11: 1 }0----1----2----3----4│{11: 1 }-5----6----7----8---|
{11: 2 }0----1----2----3----4│{11: 2 }-5----6----7----8---|
@@ -482,7 +570,11 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
-- <S-ScrollWheelLeft> in inactive window
- feed_data('\027[<70;48;1M')
+ if esc then
+ feed_data('\027[<70;48;1M')
+ else
+ meths.input_mouse('wheel', 'left', 'S', 0, 0, 47)
+ end
screen:expect([[
{11: 1 }0----1----2----3----4│{11: 1 }0----1----2----3----|
{11: 2 }0----1----2----3----4│{11: 2 }0----1----2----3----|
@@ -492,6 +584,136 @@ describe('TUI', function()
|
{3:-- TERMINAL --} |
]])
+ end
+
+ describe('accepts mouse wheel events', function()
+ it('(mouse events sent to host)', function()
+ test_mouse_wheel(false)
+ end)
+
+ it('(escape sequences sent to child)', function()
+ test_mouse_wheel(true)
+ end)
+ end)
+
+ local function test_mouse_popup(esc)
+ child_session:request('nvim_exec2', [[
+ call setline(1, 'popup menu test')
+ set mouse=a mousemodel=popup
+
+ aunmenu PopUp
+ menu PopUp.foo :let g:menustr = 'foo'<CR>
+ menu PopUp.bar :let g:menustr = 'bar'<CR>
+ 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)
+ end
+ screen:expect([[
+ {1:p}opup menu test |
+ {4:~ }{13: foo }{4: }|
+ {4:~ }{13: bar }{4: }|
+ {4:~ }{13: baz }{4: }|
+ {5:[No Name] [+] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ if esc then
+ feed_data('\027[<2;5;1m')
+ else
+ meths.input_mouse('right', 'release', '', 0, 0, 4)
+ end
+ screen:expect_unchanged()
+ if esc then
+ feed_data('\027[<35;7;4M')
+ else
+ meths.input_mouse('move', '', '', 0, 3, 6)
+ end
+ screen:expect([[
+ {1:p}opup menu test |
+ {4:~ }{13: foo }{4: }|
+ {4:~ }{13: bar }{4: }|
+ {4:~ }{14: 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)
+ end
+ screen:expect([[
+ {1:p}opup menu test |
+ {4:~ }|
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] [+] }|
+ :let g:menustr = 'bar' |
+ {3:-- TERMINAL --} |
+ ]])
+ if esc then
+ feed_data('\027[<0;7;3m')
+ else
+ meths.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)
+ end
+ screen:expect([[
+ {1:p}opup menu test |
+ {4:~ }|
+ {4:~ }|
+ {4:~ }{13: foo }{4: }|
+ {5:[No Name] [+] }{13: bar }{5: }|
+ :let g:menustr = 'bar' {13: baz } |
+ {3:-- TERMINAL --} |
+ ]])
+ if esc then
+ feed_data('\027[<34;48;6M')
+ else
+ meths.input_mouse('right', 'drag', '', 0, 5, 47)
+ end
+ screen:expect([[
+ {1:p}opup menu test |
+ {4:~ }|
+ {4:~ }|
+ {4:~ }{13: foo }{4: }|
+ {5:[No Name] [+] }{13: bar }{5: }|
+ :let g:menustr = 'bar' {14: baz } |
+ {3:-- TERMINAL --} |
+ ]])
+ if esc then
+ feed_data('\027[<2;48;6m')
+ else
+ meths.input_mouse('right', 'release', '', 0, 5, 47)
+ end
+ screen:expect([[
+ {1:p}opup menu test |
+ {4:~ }|
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] [+] }|
+ :let g:menustr = 'baz' |
+ {3:-- TERMINAL --} |
+ ]])
+ end
+
+ describe('mouse events work with right-click menu', function()
+ it('(mouse events sent to host)', function()
+ test_mouse_popup(false)
+ end)
+
+ it('(escape sequences sent to child)', function()
+ test_mouse_popup(true)
+ end)
end)
it('accepts keypad keys from kitty keyboard protocol #19180', function()
@@ -632,11 +854,11 @@ describe('TUI', function()
|
{3:-- TERMINAL --} |
]])
- child_session:request('nvim_command', [[
+ 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: } |
@@ -668,52 +890,26 @@ describe('TUI', function()
]])
end)
- it('mouse events work with right-click menu', function()
- child_session:request('nvim_command', [[
- call setline(1, 'popup menu test')
- set mouse=a mousemodel=popup
-
- aunmenu PopUp
- menu PopUp.foo :let g:menustr = 'foo'<CR>
- menu PopUp.bar :let g:menustr = 'bar'<CR>
- 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
- ]])
- meths.input_mouse('right', 'press', '', 0, 0, 4)
- screen:expect([[
- {1:p}opup menu test |
- {4:~ }{13: foo }{4: }|
- {4:~ }{13: bar }{4: }|
- {4:~ }{13: baz }{4: }|
- {5:[No Name] [+] }|
- |
- {3:-- TERMINAL --} |
- ]])
- meths.input_mouse('right', 'release', '', 0, 0, 4)
- screen:expect_unchanged()
- meths.input_mouse('move', '', '', 0, 3, 6)
- screen:expect([[
- {1:p}opup menu test |
- {4:~ }{13: foo }{4: }|
- {4:~ }{13: bar }{4: }|
- {4:~ }{14: baz }{4: }|
- {5:[No Name] [+] }|
- |
- {3:-- TERMINAL --} |
- ]])
- meths.input_mouse('left', 'press', '', 0, 2, 6)
+ 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('\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
screen:expect([[
- {1:p}opup menu test |
- {4:~ }|
+ <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:~ }|
{5:[No Name] [+] }|
- :let g:menustr = 'bar' |
+ {3:-- INSERT --} |
{3:-- TERMINAL --} |
]])
- meths.input_mouse('left', 'release', '', 0, 2, 6)
- screen:expect_unchanged()
end)
it('paste: Insert mode', function()
@@ -753,8 +949,7 @@ describe('TUI', function()
]])
-- 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" |
@@ -807,13 +1002,13 @@ describe('TUI', function()
'this is line 2',
'line 3 is here',
'',
- }
+ }
-- Redo.
feed_data('\18') -- <C-r>
expect_child_buf_lines{
'thisjust paste it™3 is here',
'',
- }
+ }
end)
it('paste: terminal mode', function()
@@ -875,17 +1070,15 @@ describe('TUI', function()
screen:expect{grid=expected_grid1, attr_ids=expected_attr}
-- Dot-repeat/redo.
feed_data('.')
- screen:expect{
- grid=[[
- ESC:{11:^[} / CR: |
- xline 1 |
- ESC:{11:^[} / CR: |
- {1:x} |
- {5:[No Name] [+] 5,1 Bot}|
- |
- {3:-- TERMINAL --} |
- ]],
- attr_ids=expected_attr}
+ screen:expect{grid=[[
+ ESC:{11:^[} / CR: |
+ xline 1 |
+ ESC:{11:^[} / 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)
@@ -1172,8 +1365,7 @@ describe('TUI', function()
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
- ]],
- attr_ids={
+ ]], attr_ids={
[1] = {reverse = true},
[2] = {background = tonumber('0x00000b')},
[3] = {bold = true},
@@ -1352,7 +1544,7 @@ 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({
@@ -1398,24 +1590,41 @@ describe('TUI', function()
]]}
end)
- it('is included in nvim_list_uis()', function()
- feed_data(':echo map(nvim_list_uis(), {k,v -> sort(items(filter(v, {k,v -> k[:3] !=# "ext_" })))})\r')
- screen:expect([=[
- |
- {4:~ }|
- {5: }|
- [[['chan', 1], ['height', 6], ['override', v:false|
- ], ['rgb', v:false], ['width', 50]]] |
- {10:Press ENTER or type command to continue}{1: } |
- {3:-- TERMINAL --} |
- ]=])
+ it('in nvim_list_uis()', function()
+ -- $TERM in :terminal.
+ local exp_term = is_os('bsd') and 'builtin_xterm' or 'xterm-256color'
+ local expected = {
+ {
+ chan = 1,
+ ext_cmdline = false,
+ ext_hlstate = false,
+ ext_linegrid = true,
+ ext_messages = false,
+ ext_multigrid = false,
+ ext_popupmenu = false,
+ ext_tabline = false,
+ ext_termcolors = true,
+ ext_wildmenu = false,
+ height = 6,
+ override = false,
+ rgb = false,
+ stdin_tty = true,
+ stdout_tty = true,
+ term_background = '',
+ term_colors = 256,
+ term_name = exp_term,
+ width = 50
+ },
+ }
+ local _, rv = child_session:request('nvim_list_uis')
+ eq(expected, rv)
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_win_set_option', 0, 'cursorline', true)
- child_session:request('nvim_win_set_option', 0, 'list', true)
- child_session:request('nvim_win_set_option', 0, 'listchars', 'eol:$')
+ 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})
feed_data('gg')
local singlewidth_screen = [[
{13:℃}{12:℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃}|
@@ -1426,21 +1635,21 @@ describe('TUI', function()
|
{3:-- TERMINAL --} |
]]
- -- When grid assumes "℃" to be double-width but host terminal assumes it to be single-width, the
- -- second cell of "℃" is a space and the attributes of the "℃" are applied to it.
+ -- When grid assumes "℃" to be double-width but host terminal assumes it to be single-width,
+ -- the second cell of "℃" is a space and the attributes of the "℃" are applied to it.
local doublewidth_screen = [[
{13:℃}{12: ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ }|
{12:℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ }|
{12:℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ }{15:$}{12: }|
- ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ >{4:@@@}|
+ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ {4:@@@@}|
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
]]
screen:expect(singlewidth_screen)
- child_session:request('nvim_set_option', 'ambiwidth', 'double')
+ child_session:request('nvim_set_option_value', 'ambiwidth', 'double', {})
screen:expect(doublewidth_screen)
- child_session:request('nvim_set_option', 'ambiwidth', 'single')
+ child_session:request('nvim_set_option_value', 'ambiwidth', 'single', {})
screen:expect(singlewidth_screen)
child_session:request('nvim_call_function', 'setcellwidths', {{{0x2103, 0x2103, 2}}})
screen:expect(doublewidth_screen)
@@ -1449,22 +1658,19 @@ describe('TUI', function()
end)
it('draws correctly when cursor_address overflows #21643', function()
- helpers.skip(helpers.is_os('mac'), 'FIXME: crashes/errors on macOS')
- screen:try_resize(77, 834)
+ helpers.skip(is_os('mac'), 'FIXME: crashes/errors on macOS')
+ screen:try_resize(77, 855)
retry(nil, nil, function()
- eq({true, 831}, {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'})
-- Going to top-left corner needs 3 bytes.
-- Setting underline attribute needs 9 bytes.
- -- With screen width 77, 63857 characters need 829 full screen lines.
- -- Drawing each full screen line needs 77 + 2 = 79 bytes (2 bytes for CR LF).
- -- The incomplete screen line needs 24 + 3 = 27 bytes.
- -- The whole line needs 3 + 9 + 79 * 829 + 27 = 65530 bytes.
+ -- The whole line needs 3 + 9 + 65515 + 3 = 65530 bytes.
-- The cursor_address that comes after will overflow the 65535-byte buffer.
- local line = ('a'):rep(63857) .. '℃'
+ local line = ('a'):rep(65515) .. '℃'
child_session:notify('nvim_exec_lua', [[
vim.api.nvim_buf_set_lines(0, 0, -1, true, {...})
vim.o.cursorline = true
@@ -1473,8 +1679,8 @@ describe('TUI', function()
feed_data('\n')
screen:expect(
'{13:a}{12:' .. ('a'):rep(76) .. '}|\n'
- .. ('{12:' .. ('a'):rep(77) .. '}|\n'):rep(828)
- .. '{12:' .. ('a'):rep(24) .. '℃' .. (' '):rep(52) .. '}|\n' .. dedent([[
+ .. ('{12:' .. ('a'):rep(77) .. '}|\n'):rep(849)
+ .. '{12:' .. ('a'):rep(65) .. '℃' .. (' '):rep(11) .. '}|\n' .. dedent([[
b |
{5:[No Name] [+] }|
|
@@ -1509,16 +1715,105 @@ describe('TUI', function()
end)
it('no assert failure on deadly signal #21896', function()
- exec_lua([[vim.loop.kill(vim.fn.jobpid(vim.bo.channel), 'sigterm')]])
- screen:expect({any = '%[Process exited 1%]'})
+ exec_lua([[vim.uv.kill(vim.fn.jobpid(vim.bo.channel), 'sigterm')]])
+ screen:expect{grid=[[
+ Vim: Caught deadly signal 'SIGTERM' |
+ |
+ |
+ [Process exited 1]{1: } |
+ |
+ |
+ {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', [[
+ 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},
+ })
+ screen:expect([[
+ {1: } |
+ {2:~}{3: }|
+ {2:~}{3: }|
+ {2:~}{3: }|
+ {4:[No Name] }|
+ |
+ {5:-- TERMINAL --} |
+ ]])
+ feed_data('i')
+ screen:expect([[
+ {1: } |
+ {2:~}{3: }|
+ {2:~}{3: }|
+ {2:~}{3: }|
+ {4:[No Name] }|
+ {5:-- INSERT --} |
+ {5:-- TERMINAL --} |
+ ]])
+ end)
+
+ it('redraws on SIGWINCH even if terminal size is unchanged #23411', function()
+ child_session:request('nvim_echo', {{'foo'}}, false, {})
+ screen:expect([[
+ {1: } |
+ {4:~ }|
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] }|
+ foo |
+ {3:-- TERMINAL --} |
+ ]])
+ exec_lua([[vim.uv.kill(vim.fn.jobpid(vim.bo.channel), 'sigwinch')]])
+ screen:expect([[
+ {1: } |
+ {4:~ }|
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] }|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+ end)
+
+ it('supports hiding cursor', function()
+ 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:~ }|
+ {5:[No Name] }|
+ :call jobwait([g:id]) |
+ {3:-- TERMINAL --} |
+ ]])
+ feed_data('\003')
+ screen:expect([[
+ {1: } |
+ {4:~ }|
+ {4:~ }|
+ {4:~ }|
+ {5:[No Name] }|
+ Type :qa and press <Enter> to exit Nvim |
+ {3:-- TERMINAL --} |
+ ]])
end)
end)
describe('TUI', function()
before_each(clear)
- after_each(function()
- os.remove('testF')
- end)
it('resize at startup #17285 #15044 #11330', function()
local screen = Screen.new(50, 10)
@@ -1544,12 +1839,51 @@ describe('TUI', function()
{2:~ }│{4:~ }|
{2:~ }│{5:[No Name] 0,0-1 All}|
{2:~ }│ |
- {5:new }{MATCH:<.*[/\]nvim }|
+ {5:new }{1:{MATCH:<.*[/\]nvim }}|
|
]])
end)
+ it('argv[0] can be overridden #23953', function()
+ if not exec_lua('return pcall(require, "ffi")') then
+ pending('missing LuaJIT FFI')
+ end
+ local script_file = 'Xargv0.lua'
+ write_file(script_file, [=[
+ local ffi = require('ffi')
+ ffi.cdef([[int execl(const char *, const char *, ...);]])
+ ffi.C.execl(vim.v.progpath, 'Xargv0nvim', '--clean')
+ ]=])
+ 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=[[
+ {1: } |
+ {4:~ }|
+ {4:~