diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-01-25 18:31:31 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-01-25 18:31:31 +0000 |
commit | 9243becbedbb6a1592208051f8fa2b090dcc5e7d (patch) | |
tree | 607c2a862ec3f4399b8766383f6f8e04c4aa43b4 /test/functional/terminal | |
parent | 9e40b6e9e1bc67f2d856adb837ee64dd0e25b717 (diff) | |
parent | 3c48d3c83fc21dbc0841f9210f04bdb073d73cd1 (diff) | |
download | rneovim-usermarks.tar.gz rneovim-usermarks.tar.bz2 rneovim-usermarks.zip |
Merge remote-tracking branch 'upstream/master' into usermarksusermarks
Diffstat (limited to 'test/functional/terminal')
-rw-r--r-- | test/functional/terminal/altscreen_spec.lua | 12 | ||||
-rw-r--r-- | test/functional/terminal/api_spec.lua | 13 | ||||
-rw-r--r-- | test/functional/terminal/buffer_spec.lua | 20 | ||||
-rw-r--r-- | test/functional/terminal/channel_spec.lua | 15 | ||||
-rw-r--r-- | test/functional/terminal/cursor_spec.lua | 12 | ||||
-rw-r--r-- | test/functional/terminal/edit_spec.lua | 2 | ||||
-rw-r--r-- | test/functional/terminal/ex_terminal_spec.lua | 26 | ||||
-rw-r--r-- | test/functional/terminal/helpers.lua | 34 | ||||
-rw-r--r-- | test/functional/terminal/highlight_spec.lua | 20 | ||||
-rw-r--r-- | test/functional/terminal/mouse_spec.lua | 44 | ||||
-rw-r--r-- | test/functional/terminal/scrollback_spec.lua | 29 | ||||
-rw-r--r-- | test/functional/terminal/tui_spec.lua | 781 | ||||
-rw-r--r-- | test/functional/terminal/window_spec.lua | 15 | ||||
-rw-r--r-- | test/functional/terminal/window_split_tab_spec.lua | 4 |
14 files changed, 849 insertions, 178 deletions
diff --git a/test/functional/terminal/altscreen_spec.lua b/test/functional/terminal/altscreen_spec.lua index 155a156d15..cbe5e06005 100644 --- a/test/functional/terminal/altscreen_spec.lua +++ b/test/functional/terminal/altscreen_spec.lua @@ -6,7 +6,7 @@ local feed_data = thelpers.feed_data local enter_altscreen = thelpers.enter_altscreen local exit_altscreen = thelpers.exit_altscreen -if helpers.pending_win32(pending) then return end +if helpers.skip(helpers.is_os('win')) then return end describe(':terminal altscreen', function() local screen @@ -126,13 +126,13 @@ describe(':terminal altscreen', function() wait_removal() feed('<c-\\><c-n>4k') screen:expect([[ - ^line3 | + ^ | | | rows: 4, cols: 50 | | ]]) - eq(8, curbuf('line_count')) + eq(9, curbuf('line_count')) end) describe('and after exit', function() @@ -142,15 +142,11 @@ describe(':terminal altscreen', function() end) it('restore buffer state', function() - -- FIXME(tarruda): Note that the last line was lost after restoring the - -- screen. This is a libvterm bug: When the main screen is restored it - -- seems to "cut" lines that would have been left below the new visible - -- screen. screen:expect([[ - line4 | line5 | line6 | line7 | + line8 | {3:-- TERMINAL --} | ]]) end) diff --git a/test/functional/terminal/api_spec.lua b/test/functional/terminal/api_spec.lua index 5305b8af9c..724791343d 100644 --- a/test/functional/terminal/api_spec.lua +++ b/test/functional/terminal/api_spec.lua @@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each) local child_session = require('test.functional.terminal.helpers') local ok = helpers.ok -if helpers.pending_win32(pending) then return end +if helpers.skip(helpers.is_os('win')) then return end describe('api', function() local screen @@ -19,6 +19,16 @@ describe('api', function() end) it("qa! RPC request during insert-mode", function() + screen:expect{grid=[[ + {1: } | + {4:~ }| + {4:~ }| + {4:~ }| + {4:~ }| + | + {3:-- TERMINAL --} | + ]]} + -- Start the socket from the child nvim. child_session.feed_data(":echo serverstart('"..socket_name.."')\n") @@ -67,4 +77,3 @@ describe('api', function() socket_session1:request("nvim_command", "qa!") end) end) - diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua index 23430a620b..9c8b983ff7 100644 --- a/test/functional/terminal/buffer_spec.lua +++ b/test/functional/terminal/buffer_spec.lua @@ -4,6 +4,7 @@ local assert_alive = helpers.assert_alive local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim local poke_eventloop = helpers.poke_eventloop local eval, feed_command, source = helpers.eval, helpers.feed_command, helpers.source +local pcall_err = helpers.pcall_err local eq, neq = helpers.eq, helpers.neq local meths = helpers.meths local retry = helpers.retry @@ -14,6 +15,8 @@ local matches = helpers.matches local exec_lua = helpers.exec_lua local sleep = helpers.sleep local funcs = helpers.funcs +local is_os = helpers.is_os +local skip = helpers.skip describe(':terminal buffer', function() local screen @@ -199,7 +202,7 @@ describe(':terminal buffer', function() -- Save the buffer number of the terminal for later testing. local tbuf = eval('bufnr("%")') - local exitcmd = helpers.iswin() + local exitcmd = helpers.is_os('win') and "['cmd', '/c', 'exit']" or "['sh', '-c', 'exit']" source([[ @@ -261,7 +264,7 @@ describe(':terminal buffer', function() end) it('it works with set rightleft #11438', function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) local columns = eval('&columns') feed(string.rep('a', columns)) command('set rightleft') @@ -339,6 +342,11 @@ describe(':terminal buffer', function() ]]} eq('t', funcs.mode(1)) end) + + it('writing to an existing file with :w fails #13549', function() + eq('Vim(write):E13: File exists (add ! to override)', + pcall_err(command, 'write test/functional/fixtures/tty-test.c')) + end) end) describe('No heap-buffer-overflow when using', function() @@ -404,6 +412,14 @@ describe('on_lines does not emit out-of-bounds line indexes when', function() feed_command('bdelete!') eq('', exec_lua([[return _G.cb_error]])) end) + + it('runs TextChangedT event', function() + meths.set_var('called', 0) + command('autocmd TextChangedT * ++once let g:called = 1') + feed_command('terminal') + feed('iaa') + eq(1, meths.get_var('called')) + end) end) it('terminal truncates number of composing characters to 5', function() diff --git a/test/functional/terminal/channel_spec.lua b/test/functional/terminal/channel_spec.lua index b5f3c2bd31..2ca7cdb0a2 100644 --- a/test/functional/terminal/channel_spec.lua +++ b/test/functional/terminal/channel_spec.lua @@ -7,6 +7,7 @@ local command = helpers.command local pcall_err = helpers.pcall_err local feed = helpers.feed local poke_eventloop = helpers.poke_eventloop +local is_os = helpers.is_os describe('terminal channel is closed and later released if', function() local screen @@ -92,3 +93,17 @@ describe('terminal channel is closed and later released if', function() eq(chans - 1, eval('len(nvim_list_chans())')) end) end) + +it('chansend sends lines to terminal channel in proper order', function() + clear() + local screen = Screen.new(100, 20) + screen:attach() + local shells = is_os('win') and {'cmd.exe', 'pwsh.exe -nop', 'powershell.exe -nop'} or {'sh'} + for _, sh in ipairs(shells) do + command([[bdelete! | let id = termopen(']] .. sh .. [[')]]) + command([[call chansend(id, ['echo "hello"', 'echo "world"', ''])]]) + screen:expect{ + any=[[echo "hello".*echo "world"]] + } + end +end) diff --git a/test/functional/terminal/cursor_spec.lua b/test/functional/terminal/cursor_spec.lua index 2d1c790d2f..98ac03211a 100644 --- a/test/functional/terminal/cursor_spec.lua +++ b/test/functional/terminal/cursor_spec.lua @@ -9,6 +9,8 @@ local matches = helpers.matches local feed_command = helpers.feed_command local hide_cursor = thelpers.hide_cursor local show_cursor = thelpers.show_cursor +local is_os = helpers.is_os +local skip = helpers.skip describe(':terminal cursor', function() local screen @@ -88,7 +90,7 @@ describe(':terminal cursor', function() describe('when invisible', function() it('is not highlighted and is detached from screen cursor', function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) hide_cursor() screen:expect([[ tty ready | @@ -361,7 +363,7 @@ describe('buffer cursor position is correct in terminal without number column', end) describe('in a line with single-cell composed multibyte characters and no trailing spaces,', function() - if helpers.pending_win32(pending) then return end -- These tests fail on Windows. Encoding problem? + if skip(is_os('win'), "Encoding problem?") then return end before_each(function() setup_ex_register('µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳') @@ -444,7 +446,7 @@ describe('buffer cursor position is correct in terminal without number column', end) describe('in a line with double-cell multibyte characters and no trailing spaces,', function() - if helpers.pending_win32(pending) then return end -- These tests fail on Windows. Encoding problem? + skip(is_os('win'), "Encoding problem?") before_each(function() setup_ex_register('哦哦哦哦哦哦哦哦') @@ -741,7 +743,7 @@ describe('buffer cursor position is correct in terminal with number column', fun end) describe('in a line with single-cell composed multibyte characters and no trailing spaces,', function() - if helpers.pending_win32(pending) then return end -- These tests fail on Windows. Encoding problem? + if skip(is_os('win'), "Encoding problem?") then return end before_each(function() setup_ex_register('µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳') @@ -824,7 +826,7 @@ describe('buffer cursor position is correct in terminal with number column', fun end) describe('in a line with double-cell multibyte characters and no trailing spaces,', function() - if helpers.pending_win32(pending) then return end -- These tests fail on Windows. Encoding problem? + skip(is_os('win'), "Encoding problem?") before_each(function() setup_ex_register('哦哦哦哦哦哦哦哦') diff --git a/test/functional/terminal/edit_spec.lua b/test/functional/terminal/edit_spec.lua index aeb4b7cc2e..80287bb3d0 100644 --- a/test/functional/terminal/edit_spec.lua +++ b/test/functional/terminal/edit_spec.lua @@ -36,7 +36,7 @@ describe(':edit term://*', function() end) it("runs TermOpen early enough to set buffer-local 'scrollback'", function() - if helpers.pending_win32(pending) then return end + if helpers.skip(helpers.is_os('win')) then return end local columns, lines = 20, 4 local scr = get_screen(columns, lines) local rep = 97 diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua index 23b69319f0..6b7e93a864 100644 --- a/test/functional/terminal/ex_terminal_spec.lua +++ b/test/functional/terminal/ex_terminal_spec.lua @@ -8,8 +8,10 @@ local feed_command, eval = helpers.feed_command, helpers.eval local funcs = helpers.funcs local retry = helpers.retry local ok = helpers.ok -local iswin = helpers.iswin local command = helpers.command +local skip = helpers.skip +local is_os = helpers.is_os +local is_ci = helpers.is_ci describe(':terminal', function() local screen @@ -45,8 +47,8 @@ describe(':terminal', function() end) it("reads output buffer on terminal reporting #4151", function() - if helpers.pending_win32(pending) then return end - if iswin() then + skip(is_ci('cirrus') or is_os('win')) + if is_os('win') then feed_command([[terminal powershell -NoProfile -NoLogo -Command Write-Host -NoNewline "\"$([char]27)[6n\""; Start-Sleep -Milliseconds 500 ]]) else feed_command([[terminal printf '\e[6n'; sleep 0.5 ]]) @@ -55,7 +57,7 @@ describe(':terminal', function() end) it("in normal-mode :split does not move cursor", function() - if iswin() then + if is_os('win') then feed_command([[terminal for /L \\%I in (1,0,2) do ( echo foo & ping -w 100 -n 1 127.0.0.1 > nul )]]) else feed_command([[terminal while true; do echo foo; sleep .1; done]]) @@ -142,7 +144,7 @@ describe(':terminal (with fake shell)', function() end it('with no argument, acts like termopen()', function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) terminal_with_fake_shell() retry(nil, 4 * screen.timeout, function() screen:expect([[ @@ -166,7 +168,7 @@ describe(':terminal (with fake shell)', function() end) it("with no argument, but 'shell' has arguments, acts like termopen()", function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) nvim('set_option', 'shell', testprg('shell-test')..' -t jeff') terminal_with_fake_shell() screen:expect([[ @@ -178,7 +180,7 @@ describe(':terminal (with fake shell)', function() end) it('executes a given command through the shell', function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) command('set shellxquote=') -- win: avoid extra quotes terminal_with_fake_shell('echo hi') screen:expect([[ @@ -190,7 +192,7 @@ describe(':terminal (with fake shell)', function() end) it("executes a given command through the shell, when 'shell' has arguments", function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) nvim('set_option', 'shell', testprg('shell-test')..' -t jeff') command('set shellxquote=') -- win: avoid extra quotes terminal_with_fake_shell('echo hi') @@ -203,7 +205,7 @@ describe(':terminal (with fake shell)', function() end) it('allows quotes and slashes', function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) command('set shellxquote=') -- win: avoid extra quotes terminal_with_fake_shell([[echo 'hello' \ "world"]]) screen:expect([[ @@ -240,7 +242,7 @@ describe(':terminal (with fake shell)', function() end) it('works with :find', function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) terminal_with_fake_shell() screen:expect([[ ^ready $ | @@ -251,7 +253,7 @@ describe(':terminal (with fake shell)', function() eq('term://', string.match(eval('bufname("%")'), "^term://")) feed([[<C-\><C-N>]]) feed_command([[find */shadacat.py]]) - if iswin() then + if is_os('win') then eq('scripts\\shadacat.py', eval('bufname("%")')) else eq('scripts/shadacat.py', eval('bufname("%")')) @@ -259,7 +261,7 @@ describe(':terminal (with fake shell)', function() end) it('works with gf', function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) command('set shellxquote=') -- win: avoid extra quotes terminal_with_fake_shell([[echo "scripts/shadacat.py"]]) retry(nil, 4 * screen.timeout, function() diff --git a/test/functional/terminal/helpers.lua b/test/functional/terminal/helpers.lua index bcfd3559e6..7247361649 100644 --- a/test/functional/terminal/helpers.lua +++ b/test/functional/terminal/helpers.lua @@ -4,19 +4,31 @@ local helpers = require('test.functional.helpers')(nil) local Screen = require('test.functional.ui.screen') local testprg = helpers.testprg +local exec_lua = helpers.exec_lua local feed_command, nvim = helpers.feed_command, helpers.nvim local function feed_data(data) - -- A string containing NUL bytes is not converted to a Blob when - -- calling nvim_set_var() API, so convert it using Lua instead. - nvim('exec_lua', 'vim.g.term_data = ...', {data}) - nvim('command', 'call jobsend(b:terminal_job_id, term_data)') + if type(data) == 'table' then + data = table.concat(data, '\n') + end + exec_lua('vim.api.nvim_chan_send(vim.b.terminal_job_id, ...)', data) end local function feed_termcode(data) - -- feed with the job API - nvim('command', 'call jobsend(b:terminal_job_id, "\\x1b'..data..'")') + feed_data('\027' .. data) +end + +local function make_lua_executor(session) + return function(code, ...) + local status, rv = session:request('nvim_exec_lua', code, {...}) + if not status then + session:stop() + error(rv[2]) + end + return rv + end end + -- some helpers for controlling the terminal. the codes were taken from -- infocmp xterm-256color which is less what libvterm understands -- civis/cnorm @@ -31,6 +43,8 @@ local function set_bg(num) feed_termcode('[48;5;'..num..'m') end local function set_bold() feed_termcode('[1m') end local function set_italic() feed_termcode('[3m') end local function set_underline() feed_termcode('[4m') end +local function set_underdouble() feed_termcode('[4:2m') end +local function set_undercurl() feed_termcode('[4:3m') end local function set_strikethrough() feed_termcode('[9m') end local function clear_attrs() feed_termcode('[0;10m') end -- mouse @@ -60,7 +74,10 @@ local function screen_setup(extra_rows, command, cols, opts) [9] = {foreground = 4}, [10] = {foreground = 121}, -- "Press ENTER" in embedded :terminal session. [11] = {foreground = tonumber('0x00000b')}, - [12] = {reverse = true, foreground = tonumber('0x000079')}, + [12] = {underline = true}, + [13] = {underline = true, reverse = true}, + [14] = {underline = true, reverse = true, bold = true}, + [15] = {underline = true, foreground = 12}, }) screen:attach(opts or {rgb=false}) @@ -107,6 +124,7 @@ end return { feed_data = feed_data, feed_termcode = feed_termcode, + make_lua_executor = make_lua_executor, hide_cursor = hide_cursor, show_cursor = show_cursor, enter_altscreen = enter_altscreen, @@ -116,6 +134,8 @@ return { set_bold = set_bold, set_italic = set_italic, set_underline = set_underline, + set_underdouble = set_underdouble, + set_undercurl = set_undercurl, set_strikethrough = set_strikethrough, clear_attrs = clear_attrs, enable_mouse = enable_mouse, diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua index 28ca07d815..2ac45771d4 100644 --- a/test/functional/terminal/highlight_spec.lua +++ b/test/functional/terminal/highlight_spec.lua @@ -7,6 +7,8 @@ local nvim_prog_abs = helpers.nvim_prog_abs local eq, eval = helpers.eq, helpers.eval local funcs = helpers.funcs local nvim_set = helpers.nvim_set +local is_os = helpers.is_os +local skip = helpers.skip describe(':terminal highlight', function() local screen @@ -26,6 +28,8 @@ describe(':terminal highlight', function() [9] = {foreground = 130}, [10] = {reverse = true}, [11] = {background = 11}, + [12] = {bold = true, underdouble = true}, + [13] = {italic = true, undercurl = true}, }) screen:attach({rgb=false}) command(("enew | call termopen(['%s'])"):format(testprg('tty-test'))) @@ -56,7 +60,7 @@ describe(':terminal highlight', function() end) local function pass_attrs() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) screen:expect(sub([[ tty ready | {NUM:text}text{10: } | @@ -71,7 +75,7 @@ describe(':terminal highlight', function() it('will pass the corresponding attributes', pass_attrs) it('will pass the corresponding attributes on scrollback', function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) pass_attrs() local lines = {} for i = 1, 8 do @@ -114,6 +118,14 @@ describe(':terminal highlight', function() thelpers.set_underline() thelpers.set_strikethrough() end) + descr('bold and underdouble', 12, function() + thelpers.set_bold() + thelpers.set_underdouble() + end) + descr('italics and undercurl', 13, function() + thelpers.set_italic() + thelpers.set_undercurl() + end) end) it(':terminal highlight has lower precedence than editor #9964', function() @@ -187,7 +199,7 @@ describe(':terminal highlight forwarding', function() end) it('will handle cterm and rgb attributes', function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) thelpers.set_fg(3) thelpers.feed_data('text') thelpers.feed_termcode('[38:2:255:128:0m') @@ -239,7 +251,7 @@ describe(':terminal highlight with custom palette', function() end) it('will use the custom color', function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) thelpers.set_fg(3) thelpers.feed_data('text') thelpers.clear_attrs() diff --git a/test/functional/terminal/mouse_spec.lua b/test/functional/terminal/mouse_spec.lua index 6e2c851df7..50c8f5e7df 100644 --- a/test/functional/terminal/mouse_spec.lua +++ b/test/functional/terminal/mouse_spec.lua @@ -3,6 +3,8 @@ local thelpers = require('test.functional.terminal.helpers') local clear, eq, eval = helpers.clear, helpers.eq, helpers.eval local feed, nvim, command = helpers.feed, helpers.nvim, helpers.command local feed_data = thelpers.feed_data +local is_os = helpers.is_os +local skip = helpers.skip describe(':terminal mouse', function() local screen @@ -66,7 +68,7 @@ describe(':terminal mouse', function() end) it('does not leave terminal mode on left-release', function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) feed('<LeftRelease>') eq('t', eval('mode(1)')) end) @@ -87,7 +89,7 @@ describe(':terminal mouse', function() end) it('will forward mouse press, drag and release to the program', function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) feed('<LeftMouse><1,2>') screen:expect([[ line27 | @@ -131,7 +133,7 @@ describe(':terminal mouse', function() end) it('will forward mouse scroll to the program', function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) feed('<ScrollWheelUp><0,0>') screen:expect([[ line27 | @@ -145,7 +147,7 @@ describe(':terminal mouse', function() end) it('dragging and scrolling do not interfere with each other', function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) feed('<LeftMouse><1,2>') screen:expect([[ line27 | @@ -199,7 +201,7 @@ describe(':terminal mouse', function() end) it('will forward mouse clicks to the program with the correct even if set nu', function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) command('set number') -- When the display area such as a number is clicked, it returns to the -- normal mode. @@ -230,7 +232,7 @@ describe(':terminal mouse', function() end) describe('with a split window and other buffer', function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) before_each(function() feed('<c-\\><c-n>:vsp<cr>') screen:expect([[ @@ -287,7 +289,7 @@ describe(':terminal mouse', function() ]]) end) - it('wont lose focus if another window is scrolled', function() + it("won't lose focus if another window is scrolled", function() feed('<ScrollWheelUp><4,0><ScrollWheelUp><4,0>') screen:expect([[ {7: 21 }line │line30 | @@ -310,6 +312,34 @@ describe(':terminal mouse', function() ]]) end) + it("scrolling another window respects 'mousescroll'", function() + command('set mousescroll=ver:1') + feed('<ScrollWheelUp><4,0>') + screen:expect([[ + {7: 26 }line │line30 | + {7: 27 }line │rows: 5, cols: 25 | + {7: 28 }line │rows: 5, cols: 24 | + {7: 29 }line │mouse enabled | + {7: 30 }line │{1: } | + ========== ========== | + {3:-- TERMINAL --} | + ]]) + command('set mousescroll=ver:10') + feed('<ScrollWheelUp><4,0>') + screen:expect([[ + {7: 16 }line │line30 | + {7: 17 }line │rows: 5, cols: 25 | + {7: 18 }line │rows: 5, cols: 24 | + {7: 19 }line │mouse enabled | + {7: 20 }line │{1: } | + ========== ========== | + {3:-- TERMINAL --} | + ]]) + command('set mousescroll=ver:0') + feed('<ScrollWheelUp><4,0>') + screen:expect_unchanged() + end) + it('will lose focus if another window is clicked', function() feed('<LeftMouse><5,1>') screen:expect([[ diff --git a/test/functional/terminal/scrollback_spec.lua b/test/functional/terminal/scrollback_spec.lua index b491cb2735..a4899c8219 100644 --- a/test/functional/terminal/scrollback_spec.lua +++ b/test/functional/terminal/scrollback_spec.lua @@ -3,7 +3,6 @@ local helpers = require('test.functional.helpers')(after_each) local thelpers = require('test.functional.terminal.helpers') local clear, eq, curbuf = helpers.clear, helpers.eq, helpers.curbuf local feed, testprg, feed_command = helpers.feed, helpers.testprg, helpers.feed_command -local iswin = helpers.iswin local eval = helpers.eval local command = helpers.command local matches = helpers.matches @@ -15,6 +14,8 @@ local feed_data = thelpers.feed_data local pcall_err = helpers.pcall_err local exec_lua = helpers.exec_lua local assert_alive = helpers.assert_alive +local skip = helpers.skip +local is_os = helpers.is_os describe(':terminal scrollback', function() local screen @@ -139,7 +140,7 @@ describe(':terminal scrollback', function() describe('and height decreased by 1', function() - if helpers.pending_win32(pending) then return end + if skip(is_os('win')) then return end local function will_hide_top_line() feed([[<C-\><C-N>]]) screen:try_resize(screen._width - 2, screen._height - 1) @@ -185,7 +186,7 @@ describe(':terminal scrollback', function() -- XXX: Can't test this reliably on Windows unless the cursor is _moved_ -- by the resize. http://docs.libuv.org/en/v1.x/signal.html -- See also: https://github.com/rprichard/winpty/issues/110 - if helpers.pending_win32(pending) then return end + if skip(is_os('win')) then return end describe('and the height is decreased by 2', function() before_each(function() @@ -264,7 +265,7 @@ describe(':terminal scrollback', function() -- XXX: Can't test this reliably on Windows unless the cursor is _moved_ -- by the resize. http://docs.libuv.org/en/v1.x/signal.html -- See also: https://github.com/rprichard/winpty/issues/110 - if helpers.pending_win32(pending) then return end + if skip(is_os('win')) then return end local function pop_then_push() screen:try_resize(screen._width, screen._height + 1) screen:expect([[ @@ -346,7 +347,7 @@ end) describe(':terminal prints more lines than the screen height and exits', function() it('will push extra lines to scrollback', function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) clear() local screen = Screen.new(30, 7) screen:attach({rgb=false}) @@ -396,21 +397,21 @@ describe("'scrollback' option", function() it('set to 0 behaves as 1', function() local screen - if iswin() then + if is_os('win') then screen = thelpers.screen_setup(nil, "['cmd.exe']", 30) else screen = thelpers.screen_setup(nil, "['sh']", 30) end curbufmeths.set_option('scrollback', 0) - feed_data(('%s REP 31 line%s'):format(testprg('shell-test'), iswin() and '\r' or '\n')) + feed_data(('%s REP 31 line%s'):format(testprg('shell-test'), is_os('win') and '\r' or '\n')) screen:expect{any='30: line '} retry(nil, nil, function() expect_lines(7) end) end) it('deletes lines (only) if necessary', function() local screen - if iswin() then + if is_os('win') then command([[let $PROMPT='$$']]) screen = thelpers.screen_setup(nil, "['cmd.exe']", 30) else @@ -423,7 +424,7 @@ describe("'scrollback' option", function() -- Wait for prompt. screen:expect{any='%$'} - feed_data(('%s REP 31 line%s'):format(testprg('shell-test'), iswin() and '\r' or '\n')) + feed_data(('%s REP 31 line%s'):format(testprg('shell-test'), is_os('win') and '\r' or '\n')) screen:expect{any='30: line '} retry(nil, nil, function() expect_lines(33, 2) end) @@ -436,8 +437,8 @@ describe("'scrollback' option", function() -- 'scrollback' option is synchronized with the internal sb_buffer. command('sleep 100m') - feed_data(('%s REP 41 line%s'):format(testprg('shell-test'), iswin() and '\r' or '\n')) - if iswin() then + feed_data(('%s REP 41 line%s'):format(testprg('shell-test'), is_os('win') and '\r' or '\n')) + if is_os('win') then screen:expect{grid=[[ 37: line | 38: line | @@ -461,8 +462,8 @@ describe("'scrollback' option", function() expect_lines(58) -- Verify off-screen state - matches((iswin() and '^36: line[ ]*$' or '^35: line[ ]*$'), eval("getline(line('w0') - 1)")) - matches((iswin() and '^27: line[ ]*$' or '^26: line[ ]*$'), eval("getline(line('w0') - 10)")) + matches((is_os('win') and '^36: line[ ]*$' or '^35: line[ ]*$'), eval("getline(line('w0') - 1)")) + matches((is_os('win') and '^27: line[ ]*$' or '^26: line[ ]*$'), eval("getline(line('w0') - 10)")) end) it('deletes extra lines immediately', function() @@ -606,7 +607,7 @@ describe("pending scrollback line handling", function() end) it("does not crash after nvim_buf_call #14891", function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) exec_lua [[ local a = vim.api local bufnr = a.nvim_create_buf(false, true) diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index 99f69ef556..b28728057f 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -5,15 +5,15 @@ -- http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Bracketed-Paste-Mode local helpers = require('test.functional.helpers')(after_each) -local uname = helpers.uname local thelpers = require('test.functional.terminal.helpers') local Screen = require('test.functional.ui.screen') -local assert_alive = helpers.assert_alive local eq = helpers.eq local feed_command = helpers.feed_command local feed_data = thelpers.feed_data local clear = helpers.clear local command = helpers.command +local dedent = helpers.dedent +local exec = helpers.exec local testprg = helpers.testprg local retry = helpers.retry local nvim_prog = helpers.nvim_prog @@ -21,16 +21,25 @@ 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 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 feed = helpers.feed +local eval = helpers.eval -if helpers.pending_win32(pending) then return end +if helpers.skip(helpers.is_os('win')) then return end describe('TUI', function() local screen local child_session + local child_exec_lua before_each(function() clear() - local child_server = helpers.new_pipename() + 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)) @@ -44,6 +53,7 @@ describe('TUI', function() {3:-- TERMINAL --} | ]]) child_session = helpers.connect(child_server) + child_exec_lua = thelpers.make_lua_executor(child_session) end) -- Wait for mode in the child Nvim (avoid "typeahead race" #10826). @@ -66,7 +76,16 @@ describe('TUI', function() it('rapid resize #7572 #7628', function() -- Need buffer rows to provoke the behavior. - feed_data(":edit test/functional/fixtures/bigfile.txt:") + 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;;;; | + 0002;<control>;Cc;0;BN;;;;;N;START OF TEXT;;;; | + 0003;<control>;Cc;0;BN;;;;;N;END OF TEXT;;;; | + {5:test/functional/fixtures/bigfile.txt }| + :edit test/functional/fixtures/bigfile.txt | + {3:-- TERMINAL --} | + ]]) command('call jobresize(b:terminal_job_id, 58, 9)') command('call jobresize(b:terminal_job_id, 62, 13)') command('call jobresize(b:terminal_job_id, 100, 42)') @@ -83,25 +102,9 @@ describe('TUI', function() command('call jobresize(b:terminal_job_id, 1, 4)') screen:try_resize(57, 17) command('call jobresize(b:terminal_job_id, 57, 17)') - assert_alive() - end) - - it('resize at startup', function() - -- Issues: #17285 #15044 #11330 - screen:try_resize(50, 10) - feed_command([[call termopen([v:progpath, '--clean', '--cmd', 'let start = reltime() | while v:true | if reltimefloat(reltime(start)) > 2 | break | endif | endwhile']) | sleep 500m | vs new]]) - screen:expect([[ - {1: } │ | - {4:~ }│{4:~ }| - {4:~ }│{4:~ }| - {4:~ }│{4:~ }| - {4:~ }│{4:~ }| - {4:~ }│{5:[No Name] 0,0-1 All}| - {4:~ }│ | - {5:new }{MATCH:<.*[/\]nvim }| - | - {3:-- TERMINAL --} | - ]]) + retry(nil, nil, function() + eq({true, 57}, {child_session:request('nvim_win_get_width', 0)}) + end) end) it('accepts resize while pager is active', function() @@ -297,6 +300,199 @@ describe('TUI', function() ]], attrs) end) + it('accepts mouse wheel events #19992', function() + child_session:request('nvim_command', [[ + set number nostartofline nowrap mousescroll=hor:1,ver:1 + call setline(1, repeat([join(range(10), '----')], 10)) + vsplit + ]]) + screen:expect([[ + {11: 1 }{1:0}----1----2----3----4│{11: 1 }0----1----2----3----| + {11: 2 }0----1----2----3----4│{11: 2 }0----1----2----3----| + {11: 3 }0----1----2----3----4│{11: 3 }0----1----2----3----| + {11: 4 }0----1----2----3----4│{11: 4 }0----1----2----3----| + {5:[No Name] [+] }{1:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]) + -- <ScrollWheelDown> in active window + feed_data('\027[<65;8;1M') + screen:expect([[ + {11: 2 }{1:0}----1----2----3----4│{11: 1 }0----1----2----3----| + {11: 3 }0----1----2----3----4│{11: 2 }0----1----2----3----| + {11: 4 }0----1----2----3----4│{11: 3 }0----1----2----3----| + {11: 5 }0----1----2----3----4│{11: 4 }0----1----2----3----| + {5:[No Name] [+] }{1:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]) + -- <ScrollWheelDown> in inactive window + feed_data('\027[<65;48;1M') + screen:expect([[ + {11: 2 }{1:0}----1----2----3----4│{11: 2 }0----1----2----3----| + {11: 3 }0----1----2----3----4│{11: 3 }0----1----2----3----| + {11: 4 }0----1----2----3----4│{11: 4 }0----1----2----3----| + {11: 5 }0----1----2----3----4│{11: 5 }0----1----2----3----| + {5:[No Name] [+] }{1:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]) + -- <ScrollWheelRight> in active window + feed_data('\027[<67;8;1M') + screen:expect([[ + {11: 2 }{1:-}---1----2----3----4-│{11: 2 }0----1----2----3----| + {11: 3 }----1----2----3----4-│{11: 3 }0----1----2----3----| + {11: 4 }----1----2----3----4-│{11: 4 }0----1----2----3----| + {11: 5 }----1----2----3----4-│{11: 5 }0----1----2----3----| + {5:[No Name] [+] }{1:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]) + -- <ScrollWheelRight> in inactive window + feed_data('\027[<67;48;1M') + screen:expect([[ + {11: 2 }{1:-}---1----2----3----4-│{11: 2 }----1----2----3----4| + {11: 3 }----1----2----3----4-│{11: 3 }----1----2----3----4| + {11: 4 }----1----2----3----4-│{11: 4 }----1----2----3----4| + {11: 5 }----1----2----3----4-│{11: 5 }----1----2----3----4| + {5:[No Name] [+] }{1:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]) + -- <S-ScrollWheelDown> in active window + feed_data('\027[<69;8;1M') + screen:expect([[ + {11: 5 }{1:-}---1----2----3----4-│{11: 2 }----1----2----3----4| + {11: 6 }----1----2----3----4-│{11: 3 }----1----2----3----4| + {11: 7 }----1----2----3----4-│{11: 4 }----1----2----3----4| + {11: 8 }----1----2----3----4-│{11: 5 }----1----2----3----4| + {5:[No Name] [+] }{1:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]) + -- <S-ScrollWheelDown> in inactive window + feed_data('\027[<69;48;1M') + screen:expect([[ + {11: 5 }{1:-}---1----2----3----4-│{11: 5 }----1----2----3----4| + {11: 6 }----1----2----3----4-│{11: 6 }----1----2----3----4| + {11: 7 }----1----2----3----4-│{11: 7 }----1----2----3----4| + {11: 8 }----1----2----3----4-│{11: 8 }----1----2----3----4| + {5:[No Name] [+] }{1:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]) + -- <S-ScrollWheelRight> in active window + feed_data('\027[<71;8;1M') + screen:expect([[ + {11: 5 }{1:-}---6----7----8----9 │{11: 5 }----1----2----3----4| + {11: 6 }----6----7----8----9 │{11: 6 }----1----2----3----4| + {11: 7 }----6----7----8----9 │{11: 7 }----1----2----3----4| + {11: 8 }----6----7----8----9 │{11: 8 }----1----2----3----4| + {5:[No Name] [+] }{1:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]) + -- <S-ScrollWheelRight> in inactive window + feed_data('\027[<71;48;1M') + screen:expect([[ + {11: 5 }{1:-}---6----7----8----9 │{11: 5 }5----6----7----8----| + {11: 6 }----6----7----8----9 │{11: 6 }5----6----7----8----| + {11: 7 }----6----7----8----9 │{11: 7 }5----6----7----8----| + {11: 8 }----6----7----8----9 │{11: 8 }5----6----7----8----| + {5:[No Name] [+] }{1:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]) + -- <ScrollWheelUp> in active window + feed_data('\027[<64;8;1M') + screen:expect([[ + {11: 4 }----6----7----8----9 │{11: 5 }5----6----7----8----| + {11: 5 }{1:-}---6----7----8----9 │{11: 6 }5----6----7----8----| + {11: 6 }----6----7----8----9 │{11: 7 }5----6----7----8----| + {11: 7 }----6----7----8----9 │{11: 8 }5----6----7----8----| + {5:[No Name] [+] }{1:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]) + -- <ScrollWheelUp> in inactive window + feed_data('\027[<64;48;1M') + screen:expect([[ + {11: 4 }----6----7----8----9 │{11: 4 }5----6----7----8----| + {11: 5 }{1:-}---6----7----8----9 │{11: 5 }5----6----7----8----| + {11: 6 }----6----7----8----9 │{11: 6 }5----6----7----8----| + {11: 7 }----6----7----8----9 │{11: 7 }5----6----7----8----| + {5:[No Name] [+] }{1:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]) + -- <ScrollWheelLeft> in active window + feed_data('\027[<66;8;1M') + screen:expect([[ + {11: 4 }5----6----7----8----9│{11: 4 }5----6----7----8----| + {11: 5 }5{1:-}---6----7----8----9│{11: 5 }5----6----7----8----| + {11: 6 }5----6----7----8----9│{11: 6 }5----6----7----8----| + {11: 7 }5----6----7----8----9│{11: 7 }5----6----7----8----| + {5:[No Name] [+] }{1:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]) + -- <ScrollWheelLeft> in inactive window + feed_data('\027[<66;48;1M') + screen:expect([[ + {11: 4 }5----6----7----8----9│{11: 4 }-5----6----7----8---| + {11: 5 }5{1:-}---6----7----8----9│{11: 5 }-5----6----7----8---| + {11: 6 }5----6----7----8----9│{11: 6 }-5----6----7----8---| + {11: 7 }5----6----7----8----9│{11: 7 }-5----6----7----8---| + {5:[No Name] [+] }{1:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]) + -- <S-ScrollWheelUp> in active window + feed_data('\027[<68;8;1M') + screen:expect([[ + {11: 1 }5----6----7----8----9│{11: 4 }-5----6----7----8---| + {11: 2 }5----6----7----8----9│{11: 5 }-5----6----7----8---| + {11: 3 }5----6----7----8----9│{11: 6 }-5----6----7----8---| + {11: 4 }5{1:-}---6----7----8----9│{11: 7 }-5----6----7----8---| + {5:[No Name] [+] }{1:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]) + -- <S-ScrollWheelUp> in inactive window + feed_data('\027[<68;48;1M') + screen:expect([[ + {11: 1 }5----6----7----8----9│{11: 1 }-5----6----7----8---| + {11: 2 }5----6----7----8----9│{11: 2 }-5----6----7----8---| + {11: 3 }5----6----7----8----9│{11: 3 }-5----6----7----8---| + {11: 4 }5{1:-}---6----7----8----9│{11: 4 }-5----6----7----8---| + {5:[No Name] [+] }{1:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]) + -- <S-ScrollWheelLeft> in active window + feed_data('\027[<70;8;1M') + screen:expect([[ + {11: 1 }0----1----2----3----4│{11: 1 }-5----6----7----8---| + {11: 2 }0----1----2----3----4│{11: 2 }-5----6----7----8---| + {11: 3 }0----1----2----3----4│{11: 3 }-5----6----7----8---| + {11: 4 }0----1----2----3----{1:4}│{11: 4 }-5----6----7----8---| + {5:[No Name] [+] }{1:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]) + -- <S-ScrollWheelLeft> in inactive window + feed_data('\027[<70;48;1M') + screen:expect([[ + {11: 1 }0----1----2----3----4│{11: 1 }0----1----2----3----| + {11: 2 }0----1----2----3----4│{11: 2 }0----1----2----3----| + {11: 3 }0----1----2----3----4│{11: 3 }0----1----2----3----| + {11: 4 }0----1----2----3----{1:4}│{11: 4 }0----1----2----3----| + {5:[No Name] [+] }{1:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]) + end) + it('accepts keypad keys from kitty keyboard protocol #19180', function() feed_data('i') feed_data(funcs.nr2char(57399)) -- KP_0 @@ -440,37 +636,83 @@ describe('TUI', function() tabnew highlight Tabline ctermbg=NONE ctermfg=NONE cterm=underline ]]) - local attrs = screen:get_default_attr_ids() - attrs[11] = {underline = true} screen:expect([[ - {11: + [No Name] + [No Name] }{3: [No Name] }{1: }{11:X}| + {12: + [No Name] + [No Name] }{3: [No Name] }{1: }{12:X}| {1: } | {4:~ }| {4:~ }| {5:[No Name] }| | {3:-- TERMINAL --} | - ]], attrs) + ]]) feed_data('\027[57421;5u') -- CTRL + KP_PAGE_UP screen:expect([[ - {11: + [No Name] }{3: + [No Name] }{11: [No Name] }{1: }{11:X}| + {12: + [No Name] }{3: + [No Name] }{12: [No Name] }{1: }{12:X}| 0123456789/*-{1:+} | = | {4:~ }| {5:[No Name] [+] }| | {3:-- TERMINAL --} | - ]], attrs) + ]]) feed_data('\027[57422;5u') -- CTRL + KP_PAGE_DOWN screen:expect([[ - {11: + [No Name] + [No Name] }{3: [No Name] }{1: }{11:X}| + {12: + [No Name] + [No Name] }{3: [No Name] }{1: }{12:X}| {1: } | {4:~ }| {4:~ }| {5:[No Name] }| | {3:-- TERMINAL --} | - ]], attrs) + ]]) + 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) + screen:expect([[ + {1:p}opup menu test | + {4:~ }| + {4:~ }| + {4:~ }| + {5:[No Name] [+] }| + :let g:menustr = 'bar' | + {3:-- TERMINAL --} | + ]]) + meths.input_mouse('left', 'release', '', 0, 2, 6) + screen:expect_unchanged() end) it('paste: Insert mode', function() @@ -574,12 +816,11 @@ describe('TUI', function() end) it('paste: terminal mode', function() - if os.getenv('GITHUB_ACTIONS') ~= nil then + if is_ci('github') then pending("tty-test complains about not owning the terminal -- actions/runner#241") - return end - feed_data(':set statusline=^^^^^^^\n') - feed_data(':terminal '..testprg('tty-test')..'\n') + child_exec_lua('vim.o.statusline="^^^^^^^"') + child_exec_lua('vim.cmd.terminal(...)', testprg('tty-test')) feed_data('i') screen:expect{grid=[[ tty ready | @@ -841,8 +1082,7 @@ describe('TUI', function() wait_for_mode('i') -- "bracketed paste" feed_data('\027[200~'..expected..'\027[201~') - -- FIXME: Data race between the two feeds - if uname() == 'freebsd' then screen:sleep(1) end + expect_child_buf_lines({expected}) feed_data(' end') expected = expected..' end' screen:expect([[ @@ -961,6 +1201,15 @@ 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 --} | + ]]} -- Send split "start paste" sequence. feed_data('\027[2') feed_data('00~pasted from terminal\027[201~') @@ -977,6 +1226,15 @@ 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 --} | + ]]} -- Send split "stop paste" sequence. feed_data('\027[200~pasted from terminal\027[20') feed_data('1~') @@ -1002,6 +1260,15 @@ describe('TUI', function() 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 screen:expect([[ pasted{1: } | @@ -1041,6 +1308,7 @@ describe('TUI', function() [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') @@ -1061,9 +1329,9 @@ describe('TUI', function() feed_data(':set termguicolors\n') screen:expect([[ {7:^}{8:G} | - {9:~ }| - {9:~ }| - {9:~ }| + {9:~}{10: }| + {9:~}{10: }| + {9:~}{10: }| {3:[No Name] [+] }| :set termguicolors | {4:-- TERMINAL --} | @@ -1082,9 +1350,8 @@ describe('TUI', function() end) it('forwards :term palette colors with termguicolors', function() - if os.getenv('GITHUB_ACTIONS') ~= nil then + if is_ci('github') then pending("tty-test complains about not owning the terminal -- actions/runner#241") - return end screen:set_rgb_cterm(true) screen:set_default_attr_ids({ @@ -1095,12 +1362,9 @@ describe('TUI', function() [5] = {{foreground = tonumber('0xff8000')}, {}}, }) - feed_data(':set statusline=^^^^^^^\n') - feed_data(':set termguicolors\n') - feed_data(':terminal '..testprg('tty-test')..'\n') - -- Depending on platform the above might or might not fit in the cmdline - -- so clear it for consistent behavior. - feed_data(':\027') + 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=[[ {1:t}ty ready | | @@ -1139,7 +1403,7 @@ describe('TUI', function() | {4:~ }| {5: }| - [[['chan', 0], ['height', 6], ['override', v:false| + [[['chan', 1], ['height', 6], ['override', v:false| ], ['rgb', v:false], ['width', 50]]] | {10:Press ENTER or type command to continue}{1: } | {3:-- TERMINAL --} | @@ -1147,18 +1411,14 @@ 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, 0, true, { ('℃'):rep(60), ('℃'):rep(60) }) + 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:$') - local attrs = screen:get_default_attr_ids() - attrs[11] = {underline = true} -- CursorLine - attrs[12] = {underline = true, reverse = true} -- CursorLine and TermCursor - attrs[13] = {underline = true, foreground = 12} -- CursorLine and NonText feed_data('gg') local singlewidth_screen = [[ - {12:℃}{11:℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃}| - {11:℃℃℃℃℃℃℃℃℃℃}{13:$}{11: }| + {13:℃}{12:℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃}| + {12:℃℃℃℃℃℃℃℃℃℃}{15:$}{12: }| ℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃℃| ℃℃℃℃℃℃℃℃℃℃{4:$} | {5:[No Name] [+] }| @@ -1168,23 +1428,83 @@ describe('TUI', function() -- When grid assumes "℃" to be double-width but host terminal assumes it to be single-width, the -- second cell of "℃" is a space and the attributes of the "℃" are applied to it. local doublewidth_screen = [[ - {12:℃}{11: ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ }| - {11:℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ }| - {11:℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ }{13:$}{11: }| + {13:℃}{12: ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ }| + {12:℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ }| + {12:℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ }{15:$}{12: }| ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ ℃ >{4:@@@}| {5:[No Name] [+] }| | {3:-- TERMINAL --} | ]] - screen:expect(singlewidth_screen, attrs) + screen:expect(singlewidth_screen) child_session:request('nvim_set_option', 'ambiwidth', 'double') - screen:expect(doublewidth_screen, attrs) + screen:expect(doublewidth_screen) child_session:request('nvim_set_option', 'ambiwidth', 'single') - screen:expect(singlewidth_screen, attrs) + screen:expect(singlewidth_screen) child_session:request('nvim_call_function', 'setcellwidths', {{{0x2103, 0x2103, 2}}}) - screen:expect(doublewidth_screen, attrs) + screen:expect(doublewidth_screen) child_session:request('nvim_call_function', 'setcellwidths', {{{0x2103, 0x2103, 1}}}) - screen:expect(singlewidth_screen, attrs) + screen:expect(singlewidth_screen) + 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) + retry(nil, nil, function() + eq({true, 831}, {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 cursor_address that comes after will overflow the 65535-byte buffer. + local line = ('a'):rep(63857) .. '℃' + child_session:notify('nvim_exec_lua', [[ + vim.api.nvim_buf_set_lines(0, 0, -1, true, {...}) + vim.o.cursorline = true + ]], {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(828) + .. '{12:' .. ('a'):rep(24) .. '℃' .. (' '):rep(52) .. '}|\n' .. dedent([[ + b | + {5:[No Name] [+] }| + | + {3:-- TERMINAL --} |]])) + end) + + it('visual bell (padding) does not crash #21610', function() + feed_data ':set visualbell\n' + screen:expect{grid=[[ + {1: } | + {4:~ }| + {4:~ }| + {4:~ }| + {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=[[ + {1: } | + {4:~ }| + {4:~ }| + {4:~ }| + {5:[No Name] }| + {3:-- INSERT --} | + {3:-- TERMINAL --} | + ]]} end) end) @@ -1194,6 +1514,35 @@ describe('TUI', function() os.remove('testF') end) + 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}, + }) + screen:attach() + 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:~ }│{5:[No Name] 0,0-1 All}| + {2:~ }│ | + {5:new }{MATCH:<.*[/\]nvim }| + | + ]]) + end) + it('with non-tty (pipe) stdout/stderr', function() 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"') @@ -1212,6 +1561,15 @@ describe('TUI', function() 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=[[ + {1: } | + {4:~ }| + {4:~ }| + {4:~ }| + {5:[No Name] }| + | + {3:-- TERMINAL --} | + ]]} command([[call chansend(b:terminal_job_id, "\<C-h>")]]) screen:expect([[ @@ -1238,6 +1596,15 @@ describe('TUI UIEnter/UILeave', function() ..[[, "--cmd", "autocmd VimEnter * :call add(g:evs, 'VimEnter')"]] ..']' ) + screen:expect{grid=[[ + {1: } | + {4:~ }| + {4:~ }| + {4:~ }| + {5:[No Name] }| + | + {3:-- TERMINAL --} | + ]]} feed_data(":echo g:evs\n") screen:expect{grid=[[ {1: } | @@ -1258,61 +1625,88 @@ describe('TUI FocusGained/FocusLost', function() clear() screen = thelpers.screen_setup(0, '["'..nvim_prog ..'", "-u", "NONE", "-i", "NONE", "--cmd", "set noswapfile noshowcmd noruler"]') - feed_data(":autocmd FocusGained * echo 'gained'\n") - feed_data(":autocmd FocusLost * echo 'lost'\n") - feed_data("\034\016") -- CTRL-\ CTRL-N - end) - - it('in normal-mode', function() - retry(2, 3 * screen.timeout, function() - feed_data('\027[I') - screen:expect([[ + screen:expect{grid=[[ {1: } | {4:~ }| {4:~ }| {4:~ }| {5:[No Name] }| - gained | + | {3:-- TERMINAL --} | - ]]) + ]]} + feed_data(":autocmd FocusGained * echo 'gained'\n") + feed_data(":autocmd FocusLost * echo 'lost'\n") + feed_data("\034\016") -- CTRL-\ CTRL-N + end) - feed_data('\027[O') - screen:expect([[ + it('in normal-mode', function() + screen:expect{grid=[[ {1: } | {4:~ }| {4:~ }| {4:~ }| {5:[No Name] }| - lost | + :autocmd FocusLost * echo 'lost' | {3:-- TERMINAL --} | - ]]) + ]]} + retry(2, 3 * screen.timeout, function() + feed_data('\027[I') + screen:expect([[ + {1: } | + {4:~ }| + {4:~ }| + {4:~ }| + {5:[No Name] }| + gained | + {3:-- TERMINAL --} | + ]]) + + feed_data('\027[O') + screen:expect([[ + {1: } | + {4:~ }| + {4:~ }| + {4:~ }| + {5:[No Name] }| + lost | + {3:-- TERMINAL --} | + ]]) end) end) it('in insert-mode', function() feed_command('set noshowmode') feed_data('i') - retry(2, 3 * screen.timeout, function() - feed_data('\027[I') - screen:expect([[ - {1: } | - {4:~ }| - {4:~ }| - {4:~ }| - {5:[No Name] }| - gained | - {3:-- TERMINAL --} | - ]]) - feed_data('\027[O') - screen:expect([[ + screen:expect{grid=[[ {1: } | {4:~ }| {4:~ }| {4:~ }| {5:[No Name] }| - lost | + :set noshowmode | {3:-- TERMINAL --} | - ]]) + ]]} + retry(2, 3 * screen.timeout, function() + feed_data('\027[I') + screen:expect([[ + {1: } | + {4:~ }| + {4:~ }| + {4:~ }| + {5:[No Name] }| + gained | + {3:-- TERMINAL --} | + ]]) + feed_data('\027[O') + screen:expect([[ + {1: } | + {4:~ }| + {4:~ }| + {4:~ }| + {5:[No Name] }| + lost | + {3:-- TERMINAL --} | + ]]) end) end) @@ -1349,6 +1743,15 @@ describe('TUI FocusGained/FocusLost', function() feed_data(":autocmd!\n") feed_data(":autocmd FocusLost * call append(line('$'), 'lost')\n") feed_data(":autocmd FocusGained * call append(line('$'), 'gained')\n") + screen:expect{grid=[[ + {1: } | + {4:~ }| + {4:~ }| + {4:~ }| + {5:[No Name] }| + | + {3:-- TERMINAL --} | + ]]} retry(2, 3 * screen.timeout, function() -- Enter cmdline-mode. feed_data(':') @@ -1407,9 +1810,18 @@ describe('TUI FocusGained/FocusLost', 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=[[ + msg1 | + msg2 | + msg3 | + msg4 | + msg5 | + {10:Press ENTER or type command to continue}{1: } | + {3:-- TERMINAL --} | + ]]} feed_data('\027[I') feed_data('\027[I') - screen:expect([[ + screen:expect{grid=[[ msg1 | msg2 | msg3 | @@ -1417,7 +1829,7 @@ describe('TUI FocusGained/FocusLost', function() msg5 | {10:Press ENTER or type command to continue}{1: } | {3:-- TERMINAL --} | - ]]) + ]], unchanged=true} end) end) @@ -1425,7 +1837,6 @@ end) -- does not initialize the TUI. describe("TUI 't_Co' (terminal colors)", function() local screen - local is_freebsd = (uname() == 'freebsd') local function assert_term_colors(term, colorterm, maxcolors) helpers.clear({env={TERM=term}, args={}}) @@ -1528,7 +1939,7 @@ describe("TUI 't_Co' (terminal colors)", function() -- which is raised to 16 by COLORTERM. it("TERM=screen no COLORTERM uses 8/256 colors", function() - if is_freebsd then + if is_os('freebsd') then assert_term_colors("screen", nil, 256) else assert_term_colors("screen", nil, 8) @@ -1536,7 +1947,7 @@ describe("TUI 't_Co' (terminal colors)", function() end) it("TERM=screen COLORTERM=screen uses 16/256 colors", function() - if is_freebsd then + if is_os('freebsd') then assert_term_colors("screen", "screen", 256) else assert_term_colors("screen", "screen", 16) @@ -1699,8 +2110,6 @@ end) -- does not initialize the TUI. describe("TUI 'term' option", function() local screen - local is_bsd = not not string.find(uname(), 'bsd') - local is_macos = not not string.find(uname(), 'darwin') local function assert_term(term_envvar, term_expected) clear() @@ -1726,11 +2135,11 @@ describe("TUI 'term' option", function() end) it('gets system-provided term if $TERM is valid', function() - if uname() == "openbsd" then + if is_os('openbsd') then assert_term("xterm", "xterm") - elseif is_bsd then -- BSD lacks terminfo, builtin is always used. + elseif is_os('bsd') then -- BSD lacks terminfo, builtin is always used. assert_term("xterm", "builtin_xterm") - elseif is_macos then + elseif is_os('mac') then local status, _ = pcall(assert_term, "xterm", "xterm") if not status then pending("macOS: unibilium could not find terminfo") @@ -1788,7 +2197,7 @@ describe("TUI", function() 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')) + eq('--- Terminal info --- {{{\n', string.match(log, '%-%-%- Terminal.-\n')) -- }}} ok(#log > 50) end) end) @@ -1912,3 +2321,163 @@ describe('TUI bg color', function() 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() + 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)) + + feed_data("iHello, World") + screen_server:expect{grid=[[ + Hello, World{1: } | + {4:~ }| + {4:~ }| + {4:~ }| + {5:[No Name] [+] }| + {3:-- INSERT --} | + {3:-- TERMINAL --} | + ]]} + feed_data("\027") + screen_server:expect{grid=[[ + Hello, Worl{1:d} | + {4:~ }| + {4:~ }| + {4:~ }| + {5:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]} + + set_session(client_super) + local screen_client = thelpers.screen_setup(0, + string.format([=[["%s", "-u", "NONE", "-i", "NONE", "--server", "%s", "--remote-ui"]]=], + nvim_prog, server_pipe)) + + screen_client:expect{grid=[[ + Hello, Worl{1:d} | + {4:~ }| + {4:~ }| + {4:~ }| + {5:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]} + + feed_data(":q!\n") + + server_super:close() + client_super:close() + end) + + it("connects to remote instance (--headless)", function() + local server = helpers.spawn_argv(false) -- equivalent to clear() + local client_super = spawn_argv(true) + + set_session(server) + local server_pipe = eval'v:servername' + feed'iHalloj!<esc>' + + set_session(client_super) + local screen = thelpers.screen_setup(0, + string.format([=[["%s", "-u", "NONE", "-i", "NONE", "--server", "%s", "--remote-ui"]]=], + nvim_prog, server_pipe)) + + screen:expect{grid=[[ + Halloj{1:!} | + {4:~ }| + {4:~ }| + {4:~ }| + {4:~ }| + | + {3:-- TERMINAL --} | + ]]} + + client_super:close() + server:close() + end) + + + it("throws error when no server exists", function() + clear() + local screen = thelpers.screen_setup(0, + string.format([=[["%s", "-u", "NONE", "-i", "NONE", "--server", "127.0.0.1:2436546", "--remote-ui"]]=], + nvim_prog), 60) + + screen:expect([[ + Remote ui failed to start: {MATCH:.*}| + | + [Process exited 1]{1: } | + | + | + | + {3:-- TERMINAL --} | + ]]) + end) + + it("exits when server quits", 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)) + + feed_data("iHello, World") + screen_server:expect{grid=[[ + Hello, World{1: } | + {4:~ }| + {4:~ }| + {4:~ }| + {5:[No Name] [+] }| + {3:-- INSERT --} | + {3:-- TERMINAL --} | + ]]} + feed_data("\027") + screen_server:expect{grid=[[ + Hello, Worl{1:d} | + {4:~ }| + {4:~ }| + {4:~ }| + {5:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]} + + set_session(client_super) + local screen_client = thelpers.screen_setup(0, + string.format([=[["%s", "-u", "NONE", "-i", "NONE", "--server", "%s", "--remote-ui"]]=], + nvim_prog, server_pipe)) + + screen_client:expect{grid=[[ + Hello, Worl{1:d} | + {4:~ }| + {4:~ }| + {4:~ }| + {5:[No Name] [+] }| + | + {3:-- TERMINAL --} | + ]]} + + -- quitting the server + set_session(server_super) + feed_data(":q!\n") + screen_server:expect({any="Process exited 0"}) + + -- assert that client has exited + screen_client:expect({any="Process exited 0"}) + + server_super:close() + client_super:close() + end) +end) diff --git a/test/functional/terminal/window_spec.lua b/test/functional/terminal/window_spec.lua index 0d3295cf32..80e9d78400 100644 --- a/test/functional/terminal/window_spec.lua +++ b/test/functional/terminal/window_spec.lua @@ -3,11 +3,12 @@ local thelpers = require('test.functional.terminal.helpers') local feed_data = thelpers.feed_data local feed, clear = helpers.feed, helpers.clear local poke_eventloop = helpers.poke_eventloop -local iswin = helpers.iswin local command = helpers.command local retry = helpers.retry local eq = helpers.eq local eval = helpers.eval +local skip = helpers.skip +local is_os = helpers.is_os describe(':terminal window', function() local screen @@ -18,7 +19,7 @@ describe(':terminal window', function() end) it('sets topline correctly #8556', function() - if helpers.pending_win32(pending) then return end + skip(is_os('win')) -- Test has hardcoded assumptions of dimensions. eq(7, eval('&lines')) feed_data('\n\n\n') -- Add blank lines. @@ -54,9 +55,7 @@ describe(':terminal window', function() {3:-- TERMINAL --} | ]]) - if iswin() then - return -- win: :terminal resize is unreliable #7007 - end + skip(is_os('win'), 'win: :terminal resize is unreliable #7007') -- numberwidth=9 feed([[<C-\><C-N>]]) @@ -172,7 +171,7 @@ describe(':terminal with multigrid', function() ]]) screen:try_resize_grid(2, 20, 10) - if iswin() then + if is_os('win') then screen:expect{any="rows: 10, cols: 20"} else screen:expect([[ @@ -201,7 +200,7 @@ describe(':terminal with multigrid', function() end screen:try_resize_grid(2, 70, 3) - if iswin() then + if is_os('win') then screen:expect{any="rows: 3, cols: 70"} else screen:expect([[ @@ -223,7 +222,7 @@ describe(':terminal with multigrid', function() end screen:try_resize_grid(2, 0, 0) - if iswin() then + if is_os('win') then screen:expect{any="rows: 6, cols: 50"} else screen:expect([[ diff --git a/test/functional/terminal/window_split_tab_spec.lua b/test/functional/terminal/window_split_tab_spec.lua index b62d173cea..1d77e1e92e 100644 --- a/test/functional/terminal/window_split_tab_spec.lua +++ b/test/functional/terminal/window_split_tab_spec.lua @@ -8,9 +8,9 @@ local command = helpers.command local eq = helpers.eq local eval = helpers.eval local meths = helpers.meths -local iswin = helpers.iswin local sleep = helpers.sleep local retry = helpers.retry +local is_os = helpers.is_os describe(':terminal', function() local screen @@ -96,7 +96,7 @@ describe(':terminal', function() local w1, h1 = screen._width - 3, screen._height - 2 local w2, h2 = w1 - 6, h1 - 3 - if iswin() then + if is_os('win') then -- win: SIGWINCH is unreliable, use a weaker test. #7506 retry(3, 30000, function() screen:try_resize(w1, h1) |