blob: 0f03731845054531f3d34ee1b6b84f8ac49af00e [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 Moolenaar7a39dd72019-06-23 00:50:15 +020058func RunVimInTerminal(arguments, options)
59 " If Vim doesn't exit a swap file remains, causing other tests to fail.
60 " Remove it here.
61 call delete(".swp")
62
63 if exists('$COLORFGBG')
64 " Clear $COLORFGBG to avoid 'background' being set to "dark", which will
65 " only be corrected if the response to t_RB is received, which may be too
66 " late.
67 let $COLORFGBG = ''
68 endif
69
70 " Make a horizontal and vertical split, so that we can get exactly the right
71 " size terminal window. Works only when the current window is full width.
72 call assert_equal(&columns, winwidth(0))
73 split
74 vsplit
75
76 " Always do this with 256 colors and a light background.
77 set t_Co=256 background=light
78 hi Normal ctermfg=NONE ctermbg=NONE
79
Bram Moolenaarb936b792020-09-04 18:34:09 +020080 " Make the window 20 lines high and 75 columns, unless told otherwise or
81 " 'termwinsize' is set.
Bram Moolenaar7a39dd72019-06-23 00:50:15 +020082 let rows = get(a:options, 'rows', 20)
83 let cols = get(a:options, 'cols', 75)
84 let statusoff = get(a:options, 'statusoff', 1)
85
Bram Moolenaara45551a2020-06-09 15:57:37 +020086 if get(a:options, 'keep_t_u7', 0)
87 let reset_u7 = ''
88 else
89 let reset_u7 = ' --cmd "set t_u7=" '
90 endif
91
92 let cmd = GetVimCommandCleanTerm() .. reset_u7 .. a:arguments
Bram Moolenaar7a39dd72019-06-23 00:50:15 +020093
Bram Moolenaarb936b792020-09-04 18:34:09 +020094 let options = #{curwin: 1}
95 if &termwinsize == ''
96 let options.term_rows = rows
97 let options.term_cols = cols
98 endif
99
Bram Moolenaard2842ea2019-09-26 23:08:54 +0200100 " Accept other options whose name starts with 'term_'.
101 call extend(options, filter(copy(a:options), 'v:key =~# "^term_"'))
102
103 let buf = term_start(cmd, options)
104
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200105 if &termwinsize == ''
106 " in the GUI we may end up with a different size, try to set it.
107 if term_getsize(buf) != [rows, cols]
108 call term_setsize(buf, rows, cols)
109 endif
110 call assert_equal([rows, cols], term_getsize(buf))
111 else
112 let rows = term_getsize(buf)[0]
113 let cols = term_getsize(buf)[1]
114 endif
115
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200116 call TermWait(buf)
Bram Moolenaarcde0ff32020-04-04 14:00:39 +0200117
Bram Moolenaar101f4812020-06-16 23:18:51 +0200118 if get(a:options, 'wait_for_ruler', 1)
119 " Wait for "All" or "Top" of the ruler to be shown in the last line or in
120 " the status line of the last window. This can be quite slow (e.g. when
121 " using valgrind).
122 " If it fails then show the terminal contents for debugging.
123 try
124 call WaitFor({-> len(term_getline(buf, rows)) >= cols - 1 || len(term_getline(buf, rows - statusoff)) >= cols - 1})
125 catch /timed out after/
126 let lines = map(range(1, rows), {key, val -> term_getline(buf, val)})
127 call assert_report('RunVimInTerminal() failed, screen contents: ' . join(lines, "<NL>"))
128 endtry
129 endif
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200130
Bram Moolenaar3cdcb092020-03-18 19:18:10 +0100131 " Starting a terminal to run Vim is always considered flaky.
Bram Moolenaar30d53e22020-03-18 21:10:44 +0100132 let g:test_is_flaky = 1
Bram Moolenaar3cdcb092020-03-18 19:18:10 +0100133
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200134 return buf
135endfunc
136
137" Stop a Vim running in terminal buffer "buf".
Bram Moolenaara46765a2020-11-01 20:58:26 +0100138func StopVimInTerminal(buf, kill = 1)
Bram Moolenaar3cdcb092020-03-18 19:18:10 +0100139 " Using a terminal to run Vim is always considered flaky.
Bram Moolenaar30d53e22020-03-18 21:10:44 +0100140 let g:test_is_flaky = 1
Bram Moolenaar3cdcb092020-03-18 19:18:10 +0100141
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200142 call assert_equal("running", term_getstatus(a:buf))
143
James McCoydbe6ef12022-12-31 11:44:57 +0000144 " Wait for all the pending updates to terminal to complete
145 call TermWait(a:buf)
146
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200147 " CTRL-O : works both in Normal mode and Insert mode to start a command line.
148 " In Command-line it's inserted, the CTRL-U removes it again.
149 call term_sendkeys(a:buf, "\<C-O>:\<C-U>qa!\<cr>")
150
Bram Moolenaar91689ea2020-05-11 22:04:53 +0200151 " Wait for all the pending updates to terminal to complete
152 call TermWait(a:buf)
153
Bram Moolenaar645cd3e2020-11-01 20:04:57 +0100154 " Wait for the terminal to end.
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200155 call WaitForAssert({-> assert_equal("finished", term_getstatus(a:buf))})
Bram Moolenaar645cd3e2020-11-01 20:04:57 +0100156
157 " If the buffer still exists forcefully wipe it.
Bram Moolenaara46765a2020-11-01 20:58:26 +0100158 if a:kill && bufexists(a:buf)
Bram Moolenaar645cd3e2020-11-01 20:04:57 +0100159 exe a:buf .. 'bwipe!'
160 endif
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200161endfunc
Bram Moolenaarcde0ff32020-04-04 14:00:39 +0200162
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200163" Open a terminal with a shell, assign the job to g:job and return the buffer
164" number.
165func Run_shell_in_terminal(options)
166 if has('win32')
Bram Moolenaar3a6aadb2021-04-04 15:28:59 +0200167 let buf = term_start([&shell, '/k'], a:options)
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200168 else
169 let buf = term_start(&shell, a:options)
170 endif
171 let g:test_is_flaky = 1
172
173 let termlist = term_list()
174 call assert_equal(1, len(termlist))
175 call assert_equal(buf, termlist[0])
176
177 let g:job = term_getjob(buf)
178 call assert_equal(v:t_job, type(g:job))
179
180 let string = string({'job': buf->term_getjob()})
181 call assert_match("{'job': 'process \\d\\+ run'}", string)
182
Bram Moolenaarced2b382022-01-13 15:25:32 +0000183 " On slower systems it may take a bit of time before the shell is ready to
184 " accept keys. This mainly matters when using term_sendkeys() next.
185 call TermWait(buf)
186
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200187 return buf
188endfunc
189
Bram Moolenaar03dfde22021-02-14 13:17:22 +0100190" Return concatenated lines in terminal.
191func Term_getlines(buf, lines)
192 return join(map(a:lines, 'term_getline(a:buf, v:val)'), '')
193endfunc
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200194
Bram Moolenaar9f145572022-11-27 12:45:41 +0000195
Bram Moolenaarcde0ff32020-04-04 14:00:39 +0200196" vim: shiftwidth=2 sts=2 expandtab