diff options
| author | Josh Rahm <joshuarahm@gmail.com> | 2023-11-30 20:35:25 +0000 |
|---|---|---|
| committer | Josh Rahm <joshuarahm@gmail.com> | 2023-11-30 20:35:25 +0000 |
| commit | 1b7b916b7631ddf73c38e3a0070d64e4636cb2f3 (patch) | |
| tree | cd08258054db80bb9a11b1061bb091c70b76926a /test/functional/terminal/tui_spec.lua | |
| parent | eaa89c11d0f8aefbb512de769c6c82f61a8baca3 (diff) | |
| parent | 4a8bf24ac690004aedf5540fa440e788459e5e34 (diff) | |
| download | rneovim-aucmd_textputpost.tar.gz rneovim-aucmd_textputpost.tar.bz2 rneovim-aucmd_textputpost.zip | |
Merge remote-tracking branch 'upstream/master' into aucmd_textputpostaucmd_textputpost
Diffstat (limited to 'test/functional/terminal/tui_spec.lua')
| -rw-r--r-- | test/functional/terminal/tui_spec.lua | 921 |
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 --} | + ]]) |