blob: 88e2b33d083b106b8d41bfcd1177c997c00f36d8 [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
Bram Moolenaar7a39dd72019-06-23 00:50:15 +020059func RunVimInTerminal(arguments, options)
60 " If Vim doesn't exit a swap file remains, causing other tests to fail.
61 " Remove it here.
62 call delete(".swp")
63
64 if exists('$COLORFGBG')
65 " Clear $COLORFGBG to avoid 'background' being set to "dark", which will
66 " only be corrected if the response to t_RB is received, which may be too
67 " late.
68 let $COLORFGBG = ''
69 endif
70
71 " Make a horizontal and vertical split, so that we can get exactly the right
72 " size terminal window. Works only when the current window is full width.
73 call assert_equal(&columns, winwidth(0))
74 split
75 vsplit
76
77 " Always do this with 256 colors and a light background.
78 set t_Co=256 background=light
79 hi Normal ctermfg=NONE ctermbg=NONE
80
Bram Moolenaarb936b792020-09-04 18:34:09 +020081 " Make the window 20 lines high and 75 columns, unless told otherwise or
82 " 'termwinsize' is set.
Bram Moolenaar7a39dd72019-06-23 00:50:15 +020083 let rows = get(a:options, 'rows', 20)
84 let cols = get(a:options, 'cols', 75)
85 let statusoff = get(a:options, 'statusoff', 1)
86
Bram Moolenaara45551a2020-06-09 15:57:37 +020087 if get(a:options, 'keep_t_u7', 0)
88 let reset_u7 = ''
89 else
90 let reset_u7 = ' --cmd "set t_u7=" '
91 endif
92
93 let cmd = GetVimCommandCleanTerm() .. reset_u7 .. a:arguments
Bram Moolenaar7a39dd72019-06-23 00:50:15 +020094
Bram Moolenaar7ac50232023-03-07 21:05:04 +000095 if get(a:options, 'no_clean', 0)
96 let cmd = substitute(cmd, '--clean', '', '')
97 endif
98
Bram Moolenaarb936b792020-09-04 18:34:09 +020099 let options = #{curwin: 1}
100 if &termwinsize == ''
101 let options.term_rows = rows
102 let options.term_cols = cols
103 endif
104
Bram Moolenaard2842ea2019-09-26 23:08:54 +0200105 " Accept other options whose name starts with 'term_'.
106 call extend(options, filter(copy(a:options), 'v:key =~# "^term_"'))
107
108 let buf = term_start(cmd, options)
109
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200110 if &termwinsize == ''
111 " in the GUI we may end up with a different size, try to set it.
112 if term_getsize(buf) != [rows, cols]
113 call term_setsize(buf, rows, cols)
114 endif
115 call assert_equal([rows, cols], term_getsize(buf))
116 else
117 let rows = term_getsize(buf)[0]
118 let cols = term_getsize(buf)[1]
119 endif
120
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200121 call TermWait(buf)
Bram Moolenaarcde0ff32020-04-04 14:00:39 +0200122
Bram Moolenaar101f4812020-06-16 23:18:51 +0200123 if get(a:options, 'wait_for_ruler', 1)
124 " Wait for "All" or "Top" of the ruler to be shown in the last line or in
125 " the status line of the last window. This can be quite slow (e.g. when
126 " using valgrind).
127 " If it fails then show the terminal contents for debugging.
128 try
129 call WaitFor({-> len(term_getline(buf, rows)) >= cols - 1 || len(term_getline(buf, rows - statusoff)) >= cols - 1})
130 catch /timed out after/
131 let lines = map(range(1, rows), {key, val -> term_getline(buf, val)})
132 call assert_report('RunVimInTerminal() failed, screen contents: ' . join(lines, "<NL>"))
133 endtry
134 endif
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200135
Bram Moolenaar3cdcb092020-03-18 19:18:10 +0100136 " Starting a terminal to run Vim is always considered flaky.
Bram Moolenaar30d53e22020-03-18 21:10:44 +0100137 let g:test_is_flaky = 1
Bram Moolenaar3cdcb092020-03-18 19:18:10 +0100138
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200139 return buf
140endfunc
141
142" Stop a Vim running in terminal buffer "buf".
Bram Moolenaara46765a2020-11-01 20:58:26 +0100143func StopVimInTerminal(buf, kill = 1)
Bram Moolenaar3cdcb092020-03-18 19:18:10 +0100144 " Using a terminal to run Vim is always considered flaky.
Bram Moolenaar30d53e22020-03-18 21:10:44 +0100145 let g:test_is_flaky = 1
Bram Moolenaar3cdcb092020-03-18 19:18:10 +0100146
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200147 call assert_equal("running", term_getstatus(a:buf))
148
James McCoydbe6ef12022-12-31 11:44:57 +0000149 " Wait for all the pending updates to terminal to complete
150 call TermWait(a:buf)
151
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200152 " CTRL-O : works both in Normal mode and Insert mode to start a command line.
153 " In Command-line it's inserted, the CTRL-U removes it again.
154 call term_sendkeys(a:buf, "\<C-O>:\<C-U>qa!\<cr>")
155
Bram Moolenaar91689ea2020-05-11 22:04:53 +0200156 " Wait for all the pending updates to terminal to complete
157 call TermWait(a:buf)
158
Bram Moolenaar645cd3e2020-11-01 20:04:57 +0100159 " Wait for the terminal to end.
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200160 call WaitForAssert({-> assert_equal("finished", term_getstatus(a:buf))})
Bram Moolenaar645cd3e2020-11-01 20:04:57 +0100161
162 " If the buffer still exists forcefully wipe it.
Bram Moolenaara46765a2020-11-01 20:58:26 +0100163 if a:kill && bufexists(a:buf)
Bram Moolenaar645cd3e2020-11-01 20:04:57 +0100164 exe a:buf .. 'bwipe!'
165 endif
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200166endfunc
Bram Moolenaarcde0ff32020-04-04 14:00:39 +0200167
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200168" Open a terminal with a shell, assign the job to g:job and return the buffer
169" number.
170func Run_shell_in_terminal(options)
171 if has('win32')
Bram Moolenaar3a6aadb2021-04-04 15:28:59 +0200172 let buf = term_start([&shell, '/k'], a:options)
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200173 else
174 let buf = term_start(&shell, a:options)
175 endif
176 let g:test_is_flaky = 1
177
178 let termlist = term_list()
179 call assert_equal(1, len(termlist))
180 call assert_equal(buf, termlist[0])
181
182 let g:job = term_getjob(buf)
183 call assert_equal(v:t_job, type(g:job))
184
185 let string = string({'job': buf->term_getjob()})
186 call assert_match("{'job': 'process \\d\\+ run'}", string)
187
Bram Moolenaarced2b382022-01-13 15:25:32 +0000188 " On slower systems it may take a bit of time before the shell is ready to
189 " accept keys. This mainly matters when using term_sendkeys() next.
190 call TermWait(buf)
191
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200192 return buf
193endfunc
194
Bram Moolenaar03dfde22021-02-14 13:17:22 +0100195" Return concatenated lines in terminal.
196func Term_getlines(buf, lines)
197 return join(map(a:lines, 'term_getline(a:buf, v:val)'), '')
198endfunc
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200199
Bram Moolenaar9f145572022-11-27 12:45:41 +0000200
Bram Moolenaarcde0ff32020-04-04 14:00:39 +0200201" vim: shiftwidth=2 sts=2 expandtab