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