blob: 1a06db7eb17dc2b53c40f1fe97ac469b836fbb10 [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)
Bram Moolenaar3a6aadb2021-04-04 15:28:59 +020026 call WaitForAssert({-> assert_equal("dead", job_status(job))})
Bram Moolenaarced2b382022-01-13 15:25:32 +000027 call TermWait(a:buf)
Bram Moolenaar7a39dd72019-06-23 00:50:15 +020028endfunc
29
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +020030" Wrapper around term_wait() to allow more time for re-runs of flaky tests
31" The second argument is the minimum time to wait in msec, 10 if omitted.
32func TermWait(buf, ...)
33 let wait_time = a:0 ? a:1 : 10
Bram Moolenaarceb2e772020-06-18 18:33:59 +020034 if exists('g:run_nr')
35 if g:run_nr == 2
36 let wait_time *= 4
37 elseif g:run_nr > 2
38 let wait_time *= 10
39 endif
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +020040 endif
41 call term_wait(a:buf, wait_time)
42
43 " In case it wasn't set yet.
44 let g:test_is_flaky = 1
45endfunc
46
Bram Moolenaar7a39dd72019-06-23 00:50:15 +020047" Run Vim with "arguments" in a new terminal window.
48" By default uses a size of 20 lines and 75 columns.
49" Returns the buffer number of the terminal.
50"
51" Options is a dictionary, these items are recognized:
Bram Moolenaara45551a2020-06-09 15:57:37 +020052" "keep_t_u7" - when 1 do not make t_u7 empty (resetting t_u7 avoids clearing
53" parts of line 2 and 3 on the display)
Bram Moolenaar7a39dd72019-06-23 00:50:15 +020054" "rows" - height of the terminal window (max. 20)
55" "cols" - width of the terminal window (max. 78)
56" "statusoff" - number of lines the status is offset from default
Bram Moolenaar6bf1b522020-09-23 17:41:26 +020057" "wait_for_ruler" - if zero then don't wait for ruler to show
Bram Moolenaar7ac50232023-03-07 21:05:04 +000058" "no_clean" - if non-zero then remove "--clean" from the command
Aapo Rantalainene2528ae2023-08-31 17:58:13 +020059" "cmd" - run any other command, e.g. "xxd" (used in xxd test)
Bram Moolenaar7a39dd72019-06-23 00:50:15 +020060func RunVimInTerminal(arguments, options)
61 " If Vim doesn't exit a swap file remains, causing other tests to fail.
62 " Remove it here.
63 call delete(".swp")
64
65 if exists('$COLORFGBG')
66 " Clear $COLORFGBG to avoid 'background' being set to "dark", which will
67 " only be corrected if the response to t_RB is received, which may be too
68 " late.
69 let $COLORFGBG = ''
70 endif
71
72 " Make a horizontal and vertical split, so that we can get exactly the right
73 " size terminal window. Works only when the current window is full width.
74 call assert_equal(&columns, winwidth(0))
75 split
76 vsplit
77
78 " Always do this with 256 colors and a light background.
79 set t_Co=256 background=light
80 hi Normal ctermfg=NONE ctermbg=NONE
81
Bram Moolenaarb936b792020-09-04 18:34:09 +020082 " Make the window 20 lines high and 75 columns, unless told otherwise or
83 " 'termwinsize' is set.
Bram Moolenaar7a39dd72019-06-23 00:50:15 +020084 let rows = get(a:options, 'rows', 20)
85 let cols = get(a:options, 'cols', 75)
86 let statusoff = get(a:options, 'statusoff', 1)
87
Bram Moolenaara45551a2020-06-09 15:57:37 +020088 if get(a:options, 'keep_t_u7', 0)
89 let reset_u7 = ''
90 else
91 let reset_u7 = ' --cmd "set t_u7=" '
92 endif
93
Aapo Rantalainene2528ae2023-08-31 17:58:13 +020094 if empty(get(a:options, 'cmd', ''))
95 let cmd = GetVimCommandCleanTerm() .. reset_u7 .. a:arguments
96 else
97 let cmd = get(a:options, 'cmd')
98 endif
Bram Moolenaar7a39dd72019-06-23 00:50:15 +020099
Bram Moolenaar7ac50232023-03-07 21:05:04 +0000100 if get(a:options, 'no_clean', 0)
101 let cmd = substitute(cmd, '--clean', '', '')
102 endif
103
Bram Moolenaarb936b792020-09-04 18:34:09 +0200104 let options = #{curwin: 1}
105 if &termwinsize == ''
106 let options.term_rows = rows
107 let options.term_cols = cols
108 endif
109
Bram Moolenaard2842ea2019-09-26 23:08:54 +0200110 " Accept other options whose name starts with 'term_'.
111 call extend(options, filter(copy(a:options), 'v:key =~# "^term_"'))
112
113 let buf = term_start(cmd, options)
114
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200115 if &termwinsize == ''
116 " in the GUI we may end up with a different size, try to set it.
117 if term_getsize(buf) != [rows, cols]
118 call term_setsize(buf, rows, cols)
119 endif
120 call assert_equal([rows, cols], term_getsize(buf))
121 else
122 let rows = term_getsize(buf)[0]
123 let cols = term_getsize(buf)[1]
124 endif
125
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200126 call TermWait(buf)
Bram Moolenaarcde0ff32020-04-04 14:00:39 +0200127
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200128 if get(a:options, 'wait_for_ruler', 1) && empty(get(a:options, 'cmd', ''))
Bram Moolenaar101f4812020-06-16 23:18:51 +0200129 " Wait for "All" or "Top" of the ruler to be shown in the last line or in
130 " the status line of the last window. This can be quite slow (e.g. when
131 " using valgrind).
132 " If it fails then show the terminal contents for debugging.
133 try
134 call WaitFor({-> len(term_getline(buf, rows)) >= cols - 1 || len(term_getline(buf, rows - statusoff)) >= cols - 1})
135 catch /timed out after/
136 let lines = map(range(1, rows), {key, val -> term_getline(buf, val)})
137 call assert_report('RunVimInTerminal() failed, screen contents: ' . join(lines, "<NL>"))
138 endtry
139 endif
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200140
Bram Moolenaar3cdcb092020-03-18 19:18:10 +0100141 " Starting a terminal to run Vim is always considered flaky.
Bram Moolenaar30d53e22020-03-18 21:10:44 +0100142 let g:test_is_flaky = 1
Bram Moolenaar3cdcb092020-03-18 19:18:10 +0100143
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200144 return buf
145endfunc
146
147" Stop a Vim running in terminal buffer "buf".
Bram Moolenaara46765a2020-11-01 20:58:26 +0100148func StopVimInTerminal(buf, kill = 1)
Bram Moolenaar3cdcb092020-03-18 19:18:10 +0100149 " Using a terminal to run Vim is always considered flaky.
Bram Moolenaar30d53e22020-03-18 21:10:44 +0100150 let g:test_is_flaky = 1
Bram Moolenaar3cdcb092020-03-18 19:18:10 +0100151
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200152 call assert_equal("running", term_getstatus(a:buf))
153
James McCoydbe6ef12022-12-31 11:44:57 +0000154 " Wait for all the pending updates to terminal to complete
155 call TermWait(a:buf)
156
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200157 " CTRL-O : works both in Normal mode and Insert mode to start a command line.
158 " In Command-line it's inserted, the CTRL-U removes it again.
159 call term_sendkeys(a:buf, "\<C-O>:\<C-U>qa!\<cr>")
160
Bram Moolenaar91689ea2020-05-11 22:04:53 +0200161 " Wait for all the pending updates to terminal to complete
162 call TermWait(a:buf)
163
Bram Moolenaar645cd3e2020-11-01 20:04:57 +0100164 " Wait for the terminal to end.
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200165 call WaitForAssert({-> assert_equal("finished", term_getstatus(a:buf))})
Bram Moolenaar645cd3e2020-11-01 20:04:57 +0100166
167 " If the buffer still exists forcefully wipe it.
Bram Moolenaara46765a2020-11-01 20:58:26 +0100168 if a:kill && bufexists(a:buf)
Bram Moolenaar645cd3e2020-11-01 20:04:57 +0100169 exe a:buf .. 'bwipe!'
170 endif
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200171endfunc
Bram Moolenaarcde0ff32020-04-04 14:00:39 +0200172
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200173" Open a terminal with a shell, assign the job to g:job and return the buffer
174" number.
175func Run_shell_in_terminal(options)
176 if has('win32')
Milly4f5681d2024-10-20 11:06:00 +0200177 let buf = term_start([&shell, '/D', '/k'], a:options)
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200178 else
179 let buf = term_start(&shell, a:options)
180 endif
181 let g:test_is_flaky = 1
182
183 let termlist = term_list()
184 call assert_equal(1, len(termlist))
185 call assert_equal(buf, termlist[0])
186
187 let g:job = term_getjob(buf)
188 call assert_equal(v:t_job, type(g:job))
189
190 let string = string({'job': buf->term_getjob()})
191 call assert_match("{'job': 'process \\d\\+ run'}", string)
192
Bram Moolenaarced2b382022-01-13 15:25:32 +0000193 " On slower systems it may take a bit of time before the shell is ready to
194 " accept keys. This mainly matters when using term_sendkeys() next.
195 call TermWait(buf)
196
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200197 return buf
198endfunc
199
Bram Moolenaar03dfde22021-02-14 13:17:22 +0100200" Return concatenated lines in terminal.
201func Term_getlines(buf, lines)
202 return join(map(a:lines, 'term_getline(a:buf, v:val)'), '')
203endfunc
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200204
Bram Moolenaar9f145572022-11-27 12:45:41 +0000205
Bram Moolenaarcde0ff32020-04-04 14:00:39 +0200206" vim: shiftwidth=2 sts=2 expandtab