From 05531d00799287ab92008ecbcab52777766c632b Mon Sep 17 00:00:00 2001 From: Aliaksei Budavei <0x000c70@gmail.com> Date: Wed, 17 Dec 2025 22:08:19 +0100 Subject: [PATCH] patch 9.1.1995: tests: flaky test_cmdline.vim causes test failures Problem: Data races between test buffers are currently addressed by relying on arbitrary execution delays or blissfully dismissed. Solution: Prefer more deterministic synchronisation between test buffers for test cases that generate screendump files with expected results (Aliaksei Budavei) closes: #18920 Signed-off-by: Aliaksei Budavei <0x000c70@gmail.com> Signed-off-by: Christian Brabandt --- src/testdir/test_cmdline.vim | 263 ++++++++++++++++++++++++++++------- src/version.c | 2 + 2 files changed, 215 insertions(+), 50 deletions(-) diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim index e8310c5530..10246b883b 100644 --- a/src/testdir/test_cmdline.vim +++ b/src/testdir/test_cmdline.vim @@ -176,32 +176,40 @@ func Test_wildmenu_screendump() call writefile(lines, 'XTest_wildmenu', 'D') " Test simple wildmenu - let buf = RunVimInTerminal('-S XTest_wildmenu', {'rows': 8}) + let rows = 8 + let buf = RunVimInTerminal('-S XTest_wildmenu', {'rows': rows}) call term_sendkeys(buf, ":vim\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':vim9cmd') + 1)], g:test_timeout, ((rows - 1), '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':vim9script') + 1)], g:test_timeout, ((rows - 1), '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':vimgrep') + 1)], g:test_timeout, ((rows - 1), '\\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':vim') + 1)], g:test_timeout, ((rows - 1), '\:set wildchar=\") call term_sendkeys(buf, ":vim\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':vim9cmd') + 1)], g:test_timeout, ((rows - 1), '\ is a hard-coded method to escape while wildchar=. Make " sure clean up is properly done in edge case like this. call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [1, 1], g:test_timeout, (rows, '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('Command? ') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_input_func_1', {}) call term_sendkeys(buf, "ech\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('Command? echo') + 1)], g:test_timeout, ((rows - 1), '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('Command? echo ') + 1)], g:test_timeout, ((rows - 1), '^\~\s\+$')) call VerifyScreenDump(buf, 'Test_wildmenu_input_func_3', {}) call term_sendkeys(buf, "bufn\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('Command? echo bufname(') + 1)], g:test_timeout, ((rows - 1), '\") call term_sendkeys(buf, ":set wildoptions+=pum\") call term_sendkeys(buf, ":call input('Command? ', '', 'command')\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('Command? ') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_input_func_5', {}) call term_sendkeys(buf, "ech\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('Command? echo') + 1)], g:test_timeout, ((rows - 1), '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('Command? echo ') + 1)], g:test_timeout, ((rows - 1), '^\~\s\+$')) call VerifyScreenDump(buf, 'Test_wildmenu_input_func_7', {}) call term_sendkeys(buf, "bufn\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('Command? echo bufname(') + 1)], g:test_timeout, ((rows - 1), '\") @@ -248,11 +265,14 @@ func Test_redraw_in_autocmd() END call writefile(lines, 'XTest_redraw', 'D') - let buf = RunVimInTerminal('-S XTest_redraw', {'rows': 8}) + let rows = 8 + let buf = RunVimInTerminal('-S XTest_redraw', {'rows': rows}) call term_sendkeys(buf, ":for i in range(3)\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(': ') + 1)]) call VerifyScreenDump(buf, 'Test_redraw_in_autocmd_1', {}) call term_sendkeys(buf, "let i =") + call WaitForTermCurPosAndLinesToMatch(buf, [(rows - 1), (strlen(': let i =') + 1)], g:test_timeout, (rows, '^$')) call VerifyScreenDump(buf, 'Test_redraw_in_autocmd_2', {}) " clean up @@ -270,22 +290,28 @@ func Test_redrawstatus_in_autocmd() END call writefile(lines, 'XTest_redrawstatus', 'D') - let buf = RunVimInTerminal('-S XTest_redrawstatus', {'rows': 8}) + let rows = 8 + let buf = RunVimInTerminal('-S XTest_redrawstatus', {'rows': rows}) " :redrawstatus is postponed if messages have scrolled call term_sendkeys(buf, ":echo \"one\\ntwo\\nthree\\nfour\"\") call term_sendkeys(buf, ":foobar") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':foobar') + 1)]) call VerifyScreenDump(buf, 'Test_redrawstatus_in_autocmd_1', {}) " it is not postponed if messages have not scrolled call term_sendkeys(buf, "\:for in in range(3)") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':for in in range(3)') + 1)], g:test_timeout, ((rows - 1), ':for in in range(3)$')) call VerifyScreenDump(buf, 'Test_redrawstatus_in_autocmd_2', {}) " with cmdheight=1 messages have scrolled when typing :endfor call term_sendkeys(buf, "\:endfor") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(': :endfor') + 1)], g:test_timeout, (rows, '^: :endfor$')) call VerifyScreenDump(buf, 'Test_redrawstatus_in_autocmd_3', {}) call term_sendkeys(buf, "\:set cmdheight=2\") " with cmdheight=2 messages haven't scrolled when typing :for or :endfor call term_sendkeys(buf, ":for in in range(3)") + call WaitForTermCurPosAndLinesToMatch(buf, [(rows - 1), (strlen(':for in in range(3)') + 1)], g:test_timeout, ((rows - 2), ':for in in range(3)$')) call VerifyScreenDump(buf, 'Test_redrawstatus_in_autocmd_4', {}) call term_sendkeys(buf, "\:endfor") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(': :endfor') + 1)], g:test_timeout, ((rows - 2), '::endfor$')) call VerifyScreenDump(buf, 'Test_redrawstatus_in_autocmd_5', {}) " clean up @@ -314,37 +340,50 @@ func Test_changing_cmdheight() END call writefile(lines, 'XTest_cmdheight', 'D') - let buf = RunVimInTerminal('-S XTest_cmdheight', {'rows': 8}) + let rows = 8 + let buf = RunVimInTerminal('-S XTest_cmdheight', {'rows': rows}) call term_sendkeys(buf, ":resize -3\") + call WaitForTermCurPosAndLinesToMatch(buf, [1, 1], g:test_timeout, (4, '\") + call WaitForTermCurPosAndLinesToMatch(buf, [1, 1], g:test_timeout, (3, '\") + call WaitForTermCurPosAndLinesToMatch(buf, [1, 1], g:test_timeout, (3, '\") + call WaitForTermCurPosAndLinesToMatch(buf, [1, 1], g:test_timeout, (5, '\") call term_sendkeys(buf, ":set cmdheight=1\") + call WaitForTermCurPosAndLinesToMatch(buf, [1, 1], g:test_timeout, ((rows - 1), '\") + call WaitForTermCurPosAndLinesToMatch(buf, [1, 1], g:test_timeout, (rows, '^\.$')) + " setting 'cmdheight' works after outputting two messages call term_sendkeys(buf, ":call EchoTwo()\") + call WaitForTermCurPosAndLinesToMatch(buf, [1, 1], g:test_timeout, ((rows - 1), '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('Press ENTER or type command to continue') + 1)]) call VerifyScreenDump(buf, 'Test_changing_cmdheight_7', {}) " window commands do not reduce 'cmdheight' to value lower than :set by user call term_sendkeys(buf, "\:wincmd _\") + call WaitForTermCurPosAndLinesToMatch(buf, [1, 1], g:test_timeout, ((rows - 2), '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('Press ENTER or type command to continue') + 1)]) call VerifyScreenDump(buf, 'Test_verbose_option_1', {}) " clean up @@ -2019,10 +2061,11 @@ func Test_cmdlineclear_tabenter() [SCRIPT] call writefile(lines, 'XtestCmdlineClearTabenter', 'D') - let buf = RunVimInTerminal('-S XtestCmdlineClearTabenter', #{rows: 10}) - call TermWait(buf, 25) + let rows = 10 + let buf = RunVimInTerminal('-S XtestCmdlineClearTabenter', #{rows: rows}) " in one tab make the command line higher with CTRL-W - call term_sendkeys(buf, ":tabnew\\-\-gtgt") + call WaitForTermCurPosAndLinesToMatch(buf, [2, 1], g:test_timeout, (rows, '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign define') + 1)], g:test_timeout, ((rows - 1), '\ call term_sendkeys(buf, "\\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign list') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_02', {}) " going down the popup menu using call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign place') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_03', {}) " going up the popup menu using call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign list') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_04', {}) " going up the popup menu using call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign jump') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_05', {}) " pressing should end completion and go back to the original match call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign ') + 1)], g:test_timeout, ((rows - 1), '\~\s\+$')) call VerifyScreenDump(buf, 'Test_wildmenu_pum_06', {}) " pressing should select the current match and end completion call term_sendkeys(buf, "\\\\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign unplace') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_07', {}) " With 'wildmode' set to 'longest,full', completing a match should display " the longest match, the wildmenu should not be displayed. call term_sendkeys(buf, ":\set wildmode=longest,full\") - call TermWait(buf) call term_sendkeys(buf, ":sign u\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign un') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_08', {}) " pressing should display the wildmenu call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign undefine') + 1)], g:test_timeout, ((rows - 1), '\ second time should select the next entry in the menu call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign unplace') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_10', {}) call term_sendkeys(buf, ":\set wildmode=full\") " showing popup menu in different columns in the cmdline call term_sendkeys(buf, ":sign define \") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign define culhl=') + 1)], g:test_timeout, ((rows - 1), '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign define culhl= culhl=') + 1)], g:test_timeout, ((rows - 1), '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign define culhl= culhl= culhl=') + 1)], g:test_timeout, ((rows - 1), '\e Xnamedi\\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':e Xnamedir/XdirA/') + 1)], g:test_timeout, ((rows - 1), '\ on a directory name should go into that directory call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':e Xnamedir/XdirA/XdirB/') + 1)], g:test_timeout, ((rows - 1), '\ on a directory name should go to the parent directory call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':e Xnamedir/XdirA/') + 1)], g:test_timeout, ((rows - 1), '\ when the popup menu is displayed should list all the - " matches but the popup menu should still remain + " matches but the popup menu should still remain (FIXME: the menu goes away) call term_sendkeys(buf, "\sign \\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign define jump list place undefine unplace') + 1)], g:test_timeout, ((rows - 1), '\~\s\+$')) call VerifyScreenDump(buf, 'Test_wildmenu_pum_17', {}) " Pressing when the popup menu is displayed should remove the popup " menu call term_sendkeys(buf, "\sign \\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign define') + 1)], g:test_timeout, ((rows - 1), '^define$')) call VerifyScreenDump(buf, 'Test_wildmenu_pum_18', {}) " Pressing should open the popup menu with the last entry selected call term_sendkeys(buf, "\\:sign \\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign undefine') + 1)], g:test_timeout, ((rows - 1), '\ should close the popup menu and cancel the cmd line call term_sendkeys(buf, "\\:sign \\") + call WaitForTermCurPosAndLinesToMatch(buf, [1, 1], g:test_timeout, (rows, '^$'), ((rows - 1), '^\~\s\+$')) call VerifyScreenDump(buf, 'Test_wildmenu_pum_20', {}) " Typing a character when the popup is open, should close the popup call term_sendkeys(buf, ":sign \x") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign definex') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_21', {}) " When the popup is open, entering the cmdline window should close the popup call term_sendkeys(buf, "\sign \\") + call WaitForTermCurPosAndLinesToMatch(buf, [6, (strlen(':sign define') + 1)], g:test_timeout, (rows, '^You discovered the command-line window! You can close it with ":q"\.')) + call WaitFor({buf_ -> {-> term_scrape(buf, 6)->slice(1, 5)->filter({_, v -> v.fg == '#af5f00'})->len() == 4}}(buf), g:test_timeout) call VerifyScreenDump(buf, 'Test_wildmenu_pum_22', {}) call term_sendkeys(buf, ":q\") " After the last popup menu item, should show the original string call term_sendkeys(buf, ":sign u\\\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign u') + 1)], g:test_timeout, ((rows - 1), '\bu\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':bufdo') + 1)], g:test_timeout, ((rows - 1), '\\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':bufdo') + 0)], g:test_timeout, ((rows - 1), '\~\s\+$')) call VerifyScreenDump(buf, 'Test_wildmenu_pum_25', {}) " Pressing should remove the popup menu and erase the last character call term_sendkeys(buf, "\\sign \\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign defin') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_26', {}) " Pressing should remove the popup menu and erase the previous word call term_sendkeys(buf, "\\sign \\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign ') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_27', {}) " Pressing should remove the popup menu and erase the entire line call term_sendkeys(buf, "\\sign \\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_28', {}) " Using to cancel the popup menu and then pressing should recall " the cmdline from history call term_sendkeys(buf, "sign xyz\:sign \\\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign xyz') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_29', {}) " Check that when "longest" produces no result, "list" works call term_sendkeys(buf, "\set wildmode=longest,list\") call term_sendkeys(buf, ":cn\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':cn') + 1)], g:test_timeout, ((rows - 1), '\") call VerifyScreenDump(buf, 'Test_wildmenu_pum_30', {}) call term_sendkeys(buf, "s") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':cns') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_31', {}) " Tests a directory name contained full-width characters. @@ -2912,35 +2988,41 @@ func Test_wildmenu_pum() call term_sendkeys(buf, "\set wildmode&\") call term_sendkeys(buf, ":\e Xnamedir/あいう/\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strwidth(':e Xnamedir/あいう/123') + 1)], g:test_timeout, ((rows - 1), '\ when the popup menu is displayed should list all the " matches and pressing a key after that should remove the popup menu call term_sendkeys(buf, "\set wildmode=full\") call term_sendkeys(buf, ":sign \\x") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign define jump list place undefine unplacex') + 1)], g:test_timeout, ((rows - 1), '\~\s\+$')) call VerifyScreenDump(buf, 'Test_wildmenu_pum_33', {}) " Pressing when the popup menu is displayed should list all the " matches and pressing after that should move the cursor call term_sendkeys(buf, "\abc\") call term_sendkeys(buf, ":sign \\\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign define jump list place undefine unplace') + 0)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_34', {}) " When displays a lot of matches (screen scrolls), all the matches " should be displayed correctly on the screen. call term_sendkeys(buf, "\\Tcmd \\\\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(' aaa') + 0)], g:test_timeout, (rows, '^\saaaa$')) call VerifyScreenDump(buf, 'Test_wildmenu_pum_35', {}) " After using to expand all the filename matches, pressing " should not open the popup menu again. call term_sendkeys(buf, "\\:cd Xnamedir/XdirA\") call term_sendkeys(buf, ":e \\\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':e XdirB/ XfileB') + 1)], g:test_timeout, ((rows - 1), '\~\s\+$')) call VerifyScreenDump(buf, 'Test_wildmenu_pum_36', {}) call term_sendkeys(buf, "\\:cd -\") " After using to expand all the matches, pressing used to " crash Vim call term_sendkeys(buf, ":sign \\\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign define jump list place undefine unplace') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_37', {}) " After removing the pum the command line is redrawn @@ -2948,6 +3030,7 @@ func Test_wildmenu_pum() call term_sendkeys(buf, ":edit bar\") call term_sendkeys(buf, ":ls\") call term_sendkeys(buf, ":com\ ") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':comclear ') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_38', {}) call term_sendkeys(buf, "\\") @@ -2955,50 +3038,65 @@ func Test_wildmenu_pum() call term_sendkeys(buf, ":call SetupStatusline()\") call term_sendkeys(buf, ":si\") call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [1, 1], g:test_timeout, ((rows - 1), '^status\s\+$')) call VerifyScreenDump(buf, 'Test_wildmenu_pum_39', {}) " Esc still works to abort the command when 'tabline' is set call term_sendkeys(buf, ":call SetupTabline()\") call term_sendkeys(buf, ":si\") call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [2, 1], g:test_timeout, ((rows - 1), '^bar\s\+$')) call VerifyScreenDump(buf, 'Test_wildmenu_pum_40', {}) " popup is cleared also when 'lazyredraw' is set call term_sendkeys(buf, ":set showtabline=1 laststatus=1 lazyredraw\") call term_sendkeys(buf, ":call DoFeedKeys()\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':abbreviate') + 1)], g:test_timeout, ((rows - 1), '\") " Pressing should scroll the menu downward call term_sendkeys(buf, ":sign \\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign undefine') + 1)], g:test_timeout, ((rows - 1), '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign unplace') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_43', {}) call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign ') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_44', {}) call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign define') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_45', {}) call term_sendkeys(buf, "\sign \\\\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign unplace') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_46', {}) " Pressing should scroll the menu upward call term_sendkeys(buf, "\sign \\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign ') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_47', {}) call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign unplace') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_48', {}) call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign jump') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_49', {}) call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign define') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_50', {}) " pressing to end completion should work in middle of the line too call term_sendkeys(buf, "\:set wildchazz\\\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':set wildcharzz') - 1)], g:test_timeout, ((rows - 1), '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':set wildchazz') - 1)], g:test_timeout, ((rows - 1), '\~\s\+$')) call VerifyScreenDump(buf, 'Test_wildmenu_pum_52', {}) " pressing should select the current match and end completion call term_sendkeys(buf, "\:set wildchazz\\\\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':set wildcharzz') - 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_53', {}) call term_sendkeys(buf, "\:set showtabline& laststatus& lazyredraw&\") @@ -3006,58 +3104,66 @@ func Test_wildmenu_pum() " "longest:list" shows list whether it finds a candidate or not call term_sendkeys(buf, ":set wildmode=longest:list,full wildoptions&\") call term_sendkeys(buf, ":cn\") - call TermWait(buf, 50) + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':cn') + 1)], g:test_timeout, ((rows - 1), '\") - call TermWait(buf, 50) + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':cnewer') + 1)], g:test_timeout, ((rows - 1), '\:sign u\") - call TermWait(buf, 50) + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign un') + 1)], g:test_timeout, ((rows - 1), '\:set wildmode=longest:full,full\") call term_sendkeys(buf, ":sign u\") - call TermWait(buf, 50) + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign un') + 1)], g:test_timeout, ((rows - 1), '\") - call TermWait(buf, 50) + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign undefine') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_59', {}) call term_sendkeys(buf, "\:cn\") - call TermWait(buf, 50) + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':cn') + 1)], g:test_timeout, ((rows - 1), '\") - call TermWait(buf, 50) + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':cnewer') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_61', {}) " If "longest,full" finds a candidate, wildmenu is not shown call term_sendkeys(buf, "\:set wildmode=longest,full\") call term_sendkeys(buf, ":sign u\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign un') + 1)], g:test_timeout, ((rows - 1), '\~\s\+$')) call VerifyScreenDump(buf, 'Test_wildmenu_pum_62', {}) " Subsequent wildchar shows wildmenu call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign undefine') + 1)], g:test_timeout, ((rows - 1), '\:set wildmode=longest,noselect\") call term_sendkeys(buf, ":cn\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':cn') + 1)], g:test_timeout, ((rows - 1), '\:set wildmode=longest,full\") call term_sendkeys(buf, ":set wildoptions=pum\") call term_sendkeys(buf, ":sign un\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign undefine') + 1)], g:test_timeout, ((rows - 1), '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign unplace') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_10', {}) " Similarly for "longest,noselect:full" call term_sendkeys(buf, "\:set wildmode=longest,noselect:full\") call term_sendkeys(buf, ":sign un\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign un') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_65', {}) call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign undefine') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_09', {}) call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign unplace') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_10', {}) call term_sendkeys(buf, "\\") @@ -3094,11 +3200,14 @@ func Test_wildmenu_with_pum_foldexpr() normal ggzfj END call writefile(lines, 'Xpumfold', 'D') - let buf = RunVimInTerminal('-S Xpumfold', #{rows: 10}) + let rows = 10 + let buf = RunVimInTerminal('-S Xpumfold', #{rows: rows}) call term_sendkeys(buf, ":set\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':set') + 1)], g:test_timeout, ((rows - 1), '\") + call WaitForTermCurPosAndLinesToMatch(buf, [1, 1], g:test_timeout, (rows, '\:sign \") - call term_wait(buf) + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign define') + 1)], g:test_timeout, ((rows - 1), '\ END call writefile(lines, 'XwildmenuTest', 'D') - let buf = RunVimInTerminal('-S XwildmenuTest', #{rows: 10}) + let rows = 10 + let buf = RunVimInTerminal('-S XwildmenuTest', #{rows: rows}) call term_sendkeys(buf, ":\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':!') + 1)], g:test_timeout, ((rows - 1), '^\s>\s\+$')) call VerifyScreenDump(buf, 'Test_wildmenu_pum_odd_wildchar_1', {}) " being a wildchar takes priority over its original functionality call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':#') + 1)]) + call WaitFor({buf_ -> {-> term_scrape(buf_, 2)->slice(0, 15)->map({_, v -> v.bg}) == repeat(['#e0e0e0'], 15)}}(buf), g:test_timeout) call VerifyScreenDump(buf, 'Test_wildmenu_pum_odd_wildchar_2', {}) call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [1, 1], g:test_timeout, (rows, '\ is hard-coded to escape " command-line, and we need to make sure to clean up properly. call term_sendkeys(buf, ":set wildchar=\") call term_sendkeys(buf, ":\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':!') + 1)], g:test_timeout, ((rows - 1), '^\s>\s\+$')) call VerifyScreenDump(buf, 'Test_wildmenu_pum_odd_wildchar_1', {}) call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [1, 1], g:test_timeout, (rows, '\ can also be wildchar. however will still escape cmdline " and we again need to make sure we clean up properly. call term_sendkeys(buf, ":set wildchar=\") call term_sendkeys(buf, ":\\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':!') + 1)], g:test_timeout, ((rows - 1), '^\s>\s\+$')) call VerifyScreenDump(buf, 'Test_wildmenu_pum_odd_wildchar_1', {}) call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [1, 1], g:test_timeout, (rows, '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign define') + 1)], g:test_timeout, ((rows - 1), '\:set keymap=dvorak\") - call TermWait(buf) " ";gul" -> "sign" when using Dvorak keymap. call term_sendkeys(buf, ":\;gul \") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign define') + 1)], g:test_timeout, ((rows - 1), '\:set keymap&\") + call term_sendkeys(buf, "\") call StopVimInTerminal(buf) endfunc @@ -3212,9 +3331,11 @@ func Test_wildmenu_pum_hl_nonfirst() END call writefile(lines, 'Xwildmenu_pum_hl_nonf', 'D') - let buf = RunVimInTerminal('-S Xwildmenu_pum_hl_nonf', #{rows: 10, cols: 50}) + let rows = 10 + let buf = RunVimInTerminal('-S Xwildmenu_pum_hl_nonf', #{rows: rows, cols: 50}) call term_sendkeys(buf, ":MyCmd ne\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':MyCmd ne') + 1)], g:test_timeout, ((rows - 1), '\") call StopVimInTerminal(buf) @@ -3230,21 +3351,27 @@ func Test_wildmenu_pum_hl_match() hi PmenuMatch ctermfg=4 ctermbg=225 END call writefile(lines, 'Xwildmenu_pum_hl', 'D') - let buf = RunVimInTerminal('-S Xwildmenu_pum_hl', #{rows: 10, cols: 50}) + let rows = 10 + let buf = RunVimInTerminal('-S Xwildmenu_pum_hl', #{rows: rows, cols: 50}) call term_sendkeys(buf, ":sign plc\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign place') + 1)], g:test_timeout, ((rows - 1), '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign unplace') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_hl_match_2', {}) call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign plc') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_hl_match_3', {}) call term_sendkeys(buf, "\:set wildoptions-=fuzzy\") - call TermWait(buf) call term_sendkeys(buf, ":sign un\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign undefine') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_hl_match_4', {}) call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign unplace') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_hl_match_5', {}) call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':sign un') + 1)]) call VerifyScreenDump(buf, 'Test_wildmenu_pum_hl_match_6', {}) call term_sendkeys(buf, "\") @@ -3266,13 +3393,15 @@ func Test_wildmenu_pum_hl_match_list() endfunc END call writefile(lines, 'Xwildmenu_pum_hl', 'D') - let buf = RunVimInTerminal('-S Xwildmenu_pum_hl', #{rows: 10, cols: 50}) + let rows = 10 + let buf = RunVimInTerminal('-S Xwildmenu_pum_hl', #{rows: rows, cols: 50}) call term_sendkeys(buf, ":ListT hewo\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':ListT hello/world') + 1)], g:test_timeout, ((rows - 1), '\:set wildoptions-=fuzzy\") - call TermWait(buf) call term_sendkeys(buf, ":ListT hewo\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':ListT hello/world') + 1)], g:test_timeout, ((rows - 1), '\") @@ -3294,13 +3423,15 @@ func Test_wildmenu_pum_hl_match_findfunc() set findfunc=FindComplete END call writefile(lines, 'Xwildmenu_pum_hl', 'D') - let buf = RunVimInTerminal('-S Xwildmenu_pum_hl', #{rows: 10, cols: 50}) + let rows = 10 + let buf = RunVimInTerminal('-S Xwildmenu_pum_hl', #{rows: rows, cols: 50}) call term_sendkeys(buf, ":find hewo\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':find hello/world') + 1)], g:test_timeout, ((rows - 1), '\:set wildoptions-=fuzzy\") - call TermWait(buf) call term_sendkeys(buf, ":find hewo\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':find hello/world') + 1)], g:test_timeout, ((rows - 1), '\") @@ -4346,6 +4477,7 @@ func Test_rulerformat_position() call term_sendkeys(buf, ":set ruler rulerformat=longish\") call term_sendkeys(buf, ":set laststatus=0 winwidth=1\") call term_sendkeys(buf, "\v\|\p") + call WaitForTermCurPosAndLinesToMatch(buf, [1, 20], g:test_timeout, (1, '|$')) call VerifyScreenDump(buf, 'Test_rulerformat_position', {}) " clean up @@ -4363,10 +4495,11 @@ func Test_rulerformat_function() END call writefile(lines, 'Xrulerformat_function', 'D') - let buf = RunVimInTerminal('-S Xrulerformat_function', #{rows: 2, cols: 40}) + let rows = 2 + let buf = RunVimInTerminal('-S Xrulerformat_function', #{rows: rows, cols: 40}) call term_sendkeys(buf, ":set ruler rulerformat=%!TestRulerFn()\") call term_sendkeys(buf, ":redraw!\") - call term_wait(buf) + call WaitForTermCurPosAndLinesToMatch(buf, [1, 1], g:test_timeout, (rows, '^\s\+10,20\s\+30%$')) call VerifyScreenDump(buf, 'Test_rulerformat_function', {}) " clean up @@ -4786,45 +4919,57 @@ func Test_search_wildmenu_screendump() call setline(1, ['the', 'these', 'the', 'foobar', 'thethe', 'thethere']) [SCRIPT] call writefile(lines, 'XTest_search_wildmenu', 'D') - let buf = RunVimInTerminal('-S XTest_search_wildmenu', {'rows': 10}) + let rows = 10 + let buf = RunVimInTerminal('-S XTest_search_wildmenu', {'rows': rows}) " Pattern has newline at EOF call term_sendkeys(buf, "gg2j/e\\n\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('/e\nfoobar') + 1)], g:test_timeout, ((rows - 1), '\:set wim=longest,full\") call term_sendkeys(buf, "gg/t\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('/the') + 1)]) call VerifyScreenDump(buf, 'Test_search_wildmenu_2', {}) " list:full call term_sendkeys(buf, "\:set wim=list,full\") call term_sendkeys(buf, "gg/t\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('/t') + 1)], g:test_timeout, ((rows - 1), '\:set wim=noselect,full\") call term_sendkeys(buf, "gg/t\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('/t') + 1)], g:test_timeout, ((rows - 1), '\gg/t.*\\n.*\\n.\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('/t.*\n.*\n.') + 1)], g:test_timeout, ((rows - 1), escape('\:set wim=full\") call term_sendkeys(buf, ":set incsearch hlsearch\") call term_sendkeys(buf, "/th") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('/th') + 1)]) + call WaitFor({buf_ -> {-> term_scrape(buf, 6)->filter({_, v -> v.bg == '#ffff40'})->len() == 4}}(buf), g:test_timeout) call VerifyScreenDump(buf, 'Test_search_wildmenu_6', {}) call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('/these') + 1)], g:test_timeout, ((rows - 1), '\\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('/the') + 1)]) + call WaitFor({buf_ -> {-> term_scrape(buf, 6)->filter({_, v -> v.bg == '#ffff40'})->len() == 6}}(buf), g:test_timeout) call VerifyScreenDump(buf, 'Test_search_wildmenu_8', {}) " 'incsearch' highlight is restored after dismissing popup (Ctrl_E) call term_sendkeys(buf, "\:set wop=pum is hls&\") call term_sendkeys(buf, "gg/th\\") - call TermWait(buf, 50) + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('/th') + 1)]) + call WaitFor({buf_ -> {-> term_scrape(buf, 2)->filter({_, v -> term_getattr(v.attr, 'reverse')})->len() == 2}}(buf), g:test_timeout) call VerifyScreenDump(buf, 'Test_search_wildmenu_9', {}) call term_sendkeys(buf, "\") @@ -4845,10 +4990,11 @@ func Test_search_wildmenu_iminsert() call cursor(2, 42) [SCRIPT] call writefile(lines, 'XTest_search_wildmenu', 'D') - let buf = RunVimInTerminal('-S XTest_search_wildmenu', {'rows': 12}) + let rows = 12 + let buf = RunVimInTerminal('-S XTest_search_wildmenu', {'rows': rows}) call term_sendkeys(buf, "/gl\") - call TermWait(buf, 50) + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('/global') + 1)], g:test_timeout, ((rows - 1), '\") @@ -4936,14 +5082,15 @@ func Test_pum_scroll_noselect() set noruler [SCRIPT] call writefile(lines, 'XTest_pum_scroll', 'D') - let buf = RunVimInTerminal('-S XTest_pum_scroll', {'rows': 10}) + let rows = 10 + let buf = RunVimInTerminal('-S XTest_pum_scroll', {'rows': rows}) call term_sendkeys(buf, ":TestCmd \" . repeat("\", 20)) - call TermWait(buf, 50) + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':TestCmd a20') + 1)], g:test_timeout, ((rows - 1), '\:TestCmd \") - call TermWait(buf, 50) + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':TestCmd ') + 1)], g:test_timeout, ((rows - 1), '\") @@ -5030,29 +5177,36 @@ func Test_wildtrigger_update_screen() cnoremap =wildtrigger()[-1] [SCRIPT] call writefile(lines, 'XTest_wildtrigger', 'D') - let buf = RunVimInTerminal('-S XTest_wildtrigger', {'rows': 10}) + let rows = 10 + let buf = RunVimInTerminal('-S XTest_wildtrigger', {'rows': rows}) call term_sendkeys(buf, ":TestCmd a\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':TermCmd a') + 1)], g:test_timeout, ((rows - 1), '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':TermCmd ax') + 1)], g:test_timeout, ((rows - 1), '^\~\s\+$')) call VerifyScreenDump(buf, 'Test_wildtrigger_update_screen_3', {}) call term_sendkeys(buf, "\\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':TermCmd a') + 1)], g:test_timeout, ((rows - 1), '\") + call WaitForTermCurPosAndLinesToMatch(buf, [1, 1], g:test_timeout, (rows, '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':e $TESTDIR/') + 1)], g:test_timeout, ((rows - 1), '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':e a/b/c/') + 1)], g:test_timeout, ((rows - 1), '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':e $TESTDIR/') + 1)], g:test_timeout, ((rows - 1), '\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':DoubleEntry ') + 1)], g:test_timeout, ((rows - 1), '\$')) call VerifyScreenDump(buf, 'Test_long_line_noselect_1', {}) call term_sendkeys(buf, "\:DoubleEntry \\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen('ong entry') + 1)], g:test_timeout, ((rows - 3), '\$')) call VerifyScreenDump(buf, 'Test_long_line_noselect_2', {}) call term_sendkeys(buf, "\:DoubleEntry \\\") + call WaitForTermCurPosAndLinesToMatch(buf, [(rows - 2), (strlen(':DoubleEntry ') + 1)], g:test_timeout, ((rows - 3), '\$')) call VerifyScreenDump(buf, 'Test_long_line_noselect_3', {}) " clean up @@ -5175,10 +5337,11 @@ func Test_update_screen_after_wildtrigger() autocmd CmdlineChanged : if getcmdcompltype() != 'shellcmd' | call wildtrigger() | endif [SCRIPT] call writefile(lines, 'XTest_wildtrigger', 'D') - let buf = RunVimInTerminal('-S XTest_wildtrigger', {'rows': 10}) + let rows = 10 + let buf = RunVimInTerminal('-S XTest_wildtrigger', {'rows': rows}) call term_sendkeys(buf, ":term foo") - call TermWait(buf, 50) + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':term foo') + 1)]) call VerifyScreenDump(buf, 'Test_update_screen_wildtrigger_1', {}) call term_sendkeys(buf, "\") diff --git a/src/version.c b/src/version.c index e1b4394909..02a1cc7f25 100644 --- a/src/version.c +++ b/src/version.c @@ -734,6 +734,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1995, /**/ 1994, /**/ -- 2.47.3