1" Functions about terminal shared by several tests 2 3" Only load this script once. 4if exists('*CanRunVimInTerminal') 5 finish 6endif 7 8" For most tests we need to be able to run terminal Vim with 256 colors. On 9" MS-Windows the console only has 16 colors and the GUI can't run in a 10" terminal. 11func CanRunVimInTerminal() 12 return has('terminal') && !has('win32') 13endfunc 14 15" Skip the rest if there is no terminal feature at all. 16if !has('terminal') 17 finish 18endif 19 20" Stops the shell running in terminal "buf". 21func StopShellInTerminal(buf) 22 call term_sendkeys(a:buf, "exit\r") 23 let job = term_getjob(a:buf) 24 call WaitFor({-> job_status(job) == "dead"}) 25endfunc 26 27" Wrapper around term_wait() to allow more time for re-runs of flaky tests 28" The second argument is the minimum time to wait in msec, 10 if omitted. 29func TermWait(buf, ...) 30 let wait_time = a:0 ? a:1 : 10 31 if exists('g:run_nr') 32 if g:run_nr == 2 33 let wait_time *= 4 34 elseif g:run_nr > 2 35 let wait_time *= 10 36 endif 37 endif 38 call term_wait(a:buf, wait_time) 39 40 " In case it wasn't set yet. 41 let g:test_is_flaky = 1 42endfunc 43 44" Run Vim with "arguments" in a new terminal window. 45" By default uses a size of 20 lines and 75 columns. 46" Returns the buffer number of the terminal. 47" 48" Options is a dictionary, these items are recognized: 49" "keep_t_u7" - when 1 do not make t_u7 empty (resetting t_u7 avoids clearing 50" parts of line 2 and 3 on the display) 51" "rows" - height of the terminal window (max. 20) 52" "cols" - width of the terminal window (max. 78) 53" "statusoff" - number of lines the status is offset from default 54func RunVimInTerminal(arguments, options) 55 " If Vim doesn't exit a swap file remains, causing other tests to fail. 56 " Remove it here. 57 call delete(".swp") 58 59 if exists('$COLORFGBG') 60 " Clear $COLORFGBG to avoid 'background' being set to "dark", which will 61 " only be corrected if the response to t_RB is received, which may be too 62 " late. 63 let $COLORFGBG = '' 64 endif 65 66 " Make a horizontal and vertical split, so that we can get exactly the right 67 " size terminal window. Works only when the current window is full width. 68 call assert_equal(&columns, winwidth(0)) 69 split 70 vsplit 71 72 " Always do this with 256 colors and a light background. 73 set t_Co=256 background=light 74 hi Normal ctermfg=NONE ctermbg=NONE 75 76 " Make the window 20 lines high and 75 columns, unless told otherwise or 77 " 'termwinsize' is set. 78 let rows = get(a:options, 'rows', 20) 79 let cols = get(a:options, 'cols', 75) 80 let statusoff = get(a:options, 'statusoff', 1) 81 82 if get(a:options, 'keep_t_u7', 0) 83 let reset_u7 = '' 84 else 85 let reset_u7 = ' --cmd "set t_u7=" ' 86 endif 87 88 let cmd = GetVimCommandCleanTerm() .. reset_u7 .. a:arguments 89 90 let options = #{curwin: 1} 91 if &termwinsize == '' 92 let options.term_rows = rows 93 let options.term_cols = cols 94 endif 95 96 " Accept other options whose name starts with 'term_'. 97 call extend(options, filter(copy(a:options), 'v:key =~# "^term_"')) 98 99 let buf = term_start(cmd, options) 100 101 if &termwinsize == '' 102 " in the GUI we may end up with a different size, try to set it. 103 if term_getsize(buf) != [rows, cols] 104 call term_setsize(buf, rows, cols) 105 endif 106 call assert_equal([rows, cols], term_getsize(buf)) 107 else 108 let rows = term_getsize(buf)[0] 109 let cols = term_getsize(buf)[1] 110 endif 111 112 call TermWait(buf) 113 114 if get(a:options, 'wait_for_ruler', 1) 115 " Wait for "All" or "Top" of the ruler to be shown in the last line or in 116 " the status line of the last window. This can be quite slow (e.g. when 117 " using valgrind). 118 " If it fails then show the terminal contents for debugging. 119 try 120 call WaitFor({-> len(term_getline(buf, rows)) >= cols - 1 || len(term_getline(buf, rows - statusoff)) >= cols - 1}) 121 catch /timed out after/ 122 let lines = map(range(1, rows), {key, val -> term_getline(buf, val)}) 123 call assert_report('RunVimInTerminal() failed, screen contents: ' . join(lines, "<NL>")) 124 endtry 125 endif 126 127 " Starting a terminal to run Vim is always considered flaky. 128 let g:test_is_flaky = 1 129 130 return buf 131endfunc 132 133" Stop a Vim running in terminal buffer "buf". 134func StopVimInTerminal(buf) 135 " Using a terminal to run Vim is always considered flaky. 136 let g:test_is_flaky = 1 137 138 call assert_equal("running", term_getstatus(a:buf)) 139 140 " CTRL-O : works both in Normal mode and Insert mode to start a command line. 141 " In Command-line it's inserted, the CTRL-U removes it again. 142 call term_sendkeys(a:buf, "\<C-O>:\<C-U>qa!\<cr>") 143 144 " Wait for all the pending updates to terminal to complete 145 call TermWait(a:buf) 146 147 call WaitForAssert({-> assert_equal("finished", term_getstatus(a:buf))}) 148 only! 149endfunc 150 151" Open a terminal with a shell, assign the job to g:job and return the buffer 152" number. 153func Run_shell_in_terminal(options) 154 if has('win32') 155 let buf = term_start([&shell,'/k'], a:options) 156 else 157 let buf = term_start(&shell, a:options) 158 endif 159 let g:test_is_flaky = 1 160 161 let termlist = term_list() 162 call assert_equal(1, len(termlist)) 163 call assert_equal(buf, termlist[0]) 164 165 let g:job = term_getjob(buf) 166 call assert_equal(v:t_job, type(g:job)) 167 168 let string = string({'job': buf->term_getjob()}) 169 call assert_match("{'job': 'process \\d\\+ run'}", string) 170 171 return buf 172endfunc 173 174 175" vim: shiftwidth=2 sts=2 expandtab 176