blob: 80f5db61d7ac0bf0cabae1f3fdba100d18db8496 [file] [log] [blame]
Bram Moolenaarc6df10e2017-07-29 20:15:08 +02001" Tests for the terminal window.
Bram Moolenaar1112c0f2020-07-01 21:53:50 +02002" This is split in two, because it can take a lot of time.
Bram Moolenaar18aa13d2020-07-11 13:09:36 +02003" See test_terminal2.vim and test_terminal3.vim for further tests.
Bram Moolenaarc6df10e2017-07-29 20:15:08 +02004
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02005source check.vim
6CheckFeature terminal
Bram Moolenaarc6df10e2017-07-29 20:15:08 +02007
8source shared.vim
Bram Moolenaar25cdd9c2018-03-10 20:28:12 +01009source screendump.vim
Bram Moolenaar91689ea2020-05-11 22:04:53 +020010source mouse.vim
Bram Moolenaar1112c0f2020-07-01 21:53:50 +020011source term_util.vim
Bram Moolenaarc6df10e2017-07-29 20:15:08 +020012
Bram Moolenaarb81bc772017-08-11 22:45:01 +020013let s:python = PythonProg()
Bram Moolenaarddd33082019-06-03 23:07:25 +020014let $PROMPT_COMMAND=''
Bram Moolenaarb81bc772017-08-11 22:45:01 +020015
Bram Moolenaar20e6cd02017-08-01 20:25:22 +020016func Test_terminal_basic()
ichizokae1bd872022-01-20 14:57:29 +000017 call test_override('vterm_title', 1)
Bram Moolenaar606cb8b2018-05-03 20:40:20 +020018 au TerminalOpen * let b:done = 'yes'
Bram Moolenaar05aafed2017-08-11 19:12:11 +020019 let buf = Run_shell_in_terminal({})
Bram Moolenaarb00fdf62017-09-21 22:16:21 +020020
Bram Moolenaar2bb7b6b2017-08-13 20:58:33 +020021 call assert_equal('t', mode())
Bram Moolenaarb00fdf62017-09-21 22:16:21 +020022 call assert_equal('yes', b:done)
Bram Moolenaar2bb7b6b2017-08-13 20:58:33 +020023 call assert_match('%aR[^\n]*running]', execute('ls'))
Bram Moolenaar0751f512018-03-29 16:37:16 +020024 call assert_match('%aR[^\n]*running]', execute('ls R'))
25 call assert_notmatch('%[^\n]*running]', execute('ls F'))
26 call assert_notmatch('%[^\n]*running]', execute('ls ?'))
Bram Moolenaar004a6782020-04-11 17:09:31 +020027 call assert_fails('set modifiable', 'E946:')
Bram Moolenaar2bb7b6b2017-08-13 20:58:33 +020028
Bram Moolenaar7a39dd72019-06-23 00:50:15 +020029 call StopShellInTerminal(buf)
Bram Moolenaar2bb7b6b2017-08-13 20:58:33 +020030 call assert_equal('n', mode())
31 call assert_match('%aF[^\n]*finished]', execute('ls'))
Bram Moolenaar0751f512018-03-29 16:37:16 +020032 call assert_match('%aF[^\n]*finished]', execute('ls F'))
33 call assert_notmatch('%[^\n]*finished]', execute('ls R'))
34 call assert_notmatch('%[^\n]*finished]', execute('ls ?'))
Bram Moolenaar20e6cd02017-08-01 20:25:22 +020035
Bram Moolenaar94053a52017-08-01 21:44:33 +020036 " closing window wipes out the terminal buffer a with finished job
37 close
38 call assert_equal("", bufname(buf))
39
Bram Moolenaar606cb8b2018-05-03 20:40:20 +020040 au! TerminalOpen
ichizokae1bd872022-01-20 14:57:29 +000041 call test_override('ALL', 0)
Bram Moolenaar20e6cd02017-08-01 20:25:22 +020042 unlet g:job
43endfunc
44
Bram Moolenaar00806bc2020-11-05 19:36:38 +010045func Test_terminal_no_name()
46 let buf = Run_shell_in_terminal({})
47 call assert_match('^!', bufname(buf))
48 0file
49 call assert_equal("", bufname(buf))
50 call assert_match('\[No Name\]', execute('file'))
51 call StopShellInTerminal(buf)
Bram Moolenaar00806bc2020-11-05 19:36:38 +010052endfunc
53
Bram Moolenaar28ed4df2019-10-26 16:21:40 +020054func Test_terminal_TerminalWinOpen()
55 au TerminalWinOpen * let b:done = 'yes'
56 let buf = Run_shell_in_terminal({})
57 call assert_equal('yes', b:done)
58 call StopShellInTerminal(buf)
59 " closing window wipes out the terminal buffer with the finished job
60 close
61
62 if has("unix")
63 terminal ++hidden ++open sleep 1
64 sleep 1
65 call assert_fails("echo b:done", 'E121:')
66 endif
67
68 au! TerminalWinOpen
69endfunc
70
Bram Moolenaar20e6cd02017-08-01 20:25:22 +020071func Test_terminal_make_change()
Bram Moolenaar05aafed2017-08-11 19:12:11 +020072 let buf = Run_shell_in_terminal({})
Bram Moolenaar7a39dd72019-06-23 00:50:15 +020073 call StopShellInTerminal(buf)
Bram Moolenaar20e6cd02017-08-01 20:25:22 +020074
75 setlocal modifiable
76 exe "normal Axxx\<Esc>"
Bram Moolenaar28ee8922020-10-28 20:20:00 +010077 call assert_fails(buf . 'bwipe', 'E89:')
Bram Moolenaar20e6cd02017-08-01 20:25:22 +020078 undo
79
Bram Moolenaarc6df10e2017-07-29 20:15:08 +020080 exe buf . 'bwipe'
81 unlet g:job
82endfunc
83
Bram Moolenaar5b868a82019-02-25 06:11:53 +010084func Test_terminal_paste_register()
85 let @" = "text to paste"
86
87 let buf = Run_shell_in_terminal({})
88 " Wait for the shell to display a prompt
89 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))})
90
91 call feedkeys("echo \<C-W>\"\" \<C-W>\"=37 + 5\<CR>\<CR>", 'xt')
92 call WaitForAssert({-> assert_match("echo text to paste 42$", getline(1))})
Bram Moolenaar7ee80f72019-09-08 20:55:06 +020093 call WaitForAssert({-> assert_equal('text to paste 42', 2->getline())})
Bram Moolenaar5b868a82019-02-25 06:11:53 +010094
95 exe buf . 'bwipe!'
96 unlet g:job
97endfunc
98
Bram Moolenaar94053a52017-08-01 21:44:33 +020099func Test_terminal_wipe_buffer()
Bram Moolenaar05aafed2017-08-11 19:12:11 +0200100 let buf = Run_shell_in_terminal({})
Yee Cheng Chin15b314f2022-10-09 18:53:32 +0100101 call assert_fails(buf . 'bwipe', 'E948:')
Bram Moolenaareb44a682017-08-03 22:44:55 +0200102 exe buf . 'bwipe!'
Bram Moolenaar50182fa2018-04-28 21:34:40 +0200103 call WaitForAssert({-> assert_equal('dead', job_status(g:job))})
Bram Moolenaar94053a52017-08-01 21:44:33 +0200104 call assert_equal("", bufname(buf))
105
106 unlet g:job
107endfunc
108
Yee Cheng Chin15b314f2022-10-09 18:53:32 +0100109" Test that using ':confirm bwipe' on terminal works
110func Test_terminal_confirm_wipe_buffer()
111 CheckUnix
112 CheckNotGui
113 CheckFeature dialog_con
114 let buf = Run_shell_in_terminal({})
115 call assert_fails(buf . 'bwipe', 'E948:')
116 call feedkeys('n', 'L')
117 call assert_fails('confirm ' .. buf .. 'bwipe', 'E517:')
118 call assert_equal(buf, bufnr())
119 call assert_equal(1, &modified)
120 call feedkeys('y', 'L')
121 exe 'confirm ' .. buf .. 'bwipe'
122 call assert_notequal(buf, bufnr())
123 call WaitForAssert({-> assert_equal('dead', job_status(g:job))})
124 call assert_equal("", bufname(buf))
125
126 unlet g:job
127endfunc
128
129" Test that using :b! will hide the terminal
130func Test_terminal_goto_buffer()
131 let buf_mod = bufnr()
132 let buf_term = Run_shell_in_terminal({})
133 call assert_equal(buf_term, bufnr())
134 call assert_fails(buf_mod . 'b', 'E948:')
135 exe buf_mod . 'b!'
136 call assert_equal(buf_mod, bufnr())
137 call assert_equal('run', job_status(g:job))
138 call assert_notequal('', bufname(buf_term))
139 exec buf_mod .. 'bwipe!'
140 exec buf_term .. 'bwipe!'
141
142 unlet g:job
143endfunc
144
145" Test that using ':confirm :b' will kill terminal
146func Test_terminal_confirm_goto_buffer()
147 CheckUnix
148 CheckNotGui
149 CheckFeature dialog_con
150 let buf_mod = bufnr()
151 let buf_term = Run_shell_in_terminal({})
152 call feedkeys('n', 'L')
153 exe 'confirm ' .. buf_mod .. 'b'
154 call assert_equal(buf_term, bufnr())
155 call feedkeys('y', 'L')
156 exec 'confirm ' .. buf_mod .. 'b'
157 call assert_equal(buf_mod, bufnr())
158 call WaitForAssert({-> assert_equal('dead', job_status(g:job))})
159 call assert_equal("", bufname(buf_term))
160 exec buf_mod .. 'bwipe!'
161
162 unlet g:job
163endfunc
164
165" Test that using :close! will hide the terminal
166func Test_terminal_close_win()
167 let buf = Run_shell_in_terminal({})
168 call assert_equal(buf, bufnr())
169 call assert_fails('close', 'E948:')
170 close!
171 call assert_notequal(buf, bufnr())
172 call assert_equal('run', job_status(g:job))
173 call assert_notequal('', bufname(buf))
174 exec buf .. 'bwipe!'
175
176 unlet g:job
177endfunc
178
179" Test that using ':confirm close' will kill terminal
180func Test_terminal_confirm_close_win()
181 CheckUnix
182 CheckNotGui
183 CheckFeature dialog_con
184 let buf = Run_shell_in_terminal({})
185 call feedkeys('n', 'L')
186 confirm close
187 call assert_equal(buf, bufnr())
188 call feedkeys('y', 'L')
189 confirm close
190 call assert_notequal(buf, bufnr())
191 call WaitForAssert({-> assert_equal('dead', job_status(g:job))})
192 call assert_equal("", bufname(buf))
193
194 unlet g:job
195endfunc
196
197" Test that using :quit! will kill the terminal
198func Test_terminal_quit()
199 let buf = Run_shell_in_terminal({})
200 call assert_equal(buf, bufnr())
201 call assert_fails('quit', 'E948:')
202 quit!
203 call assert_notequal(buf, bufnr())
204 call WaitForAssert({-> assert_equal('dead', job_status(g:job))})
205 exec buf .. 'bwipe!'
206
207 unlet g:job
208endfunc
209
210" Test that using ':confirm quit' will kill terminal
211func Test_terminal_confirm_quit()
212 CheckUnix
213 CheckNotGui
214 CheckFeature dialog_con
215 let buf = Run_shell_in_terminal({})
216 call feedkeys('n', 'L')
217 confirm quit
218 call assert_equal(buf, bufnr())
219 call feedkeys('y', 'L')
220 confirm quit
221 call assert_notequal(buf, bufnr())
222 call WaitForAssert({-> assert_equal('dead', job_status(g:job))})
223
224 unlet g:job
225endfunc
226
227" Test :q or :next
228
Bram Moolenaar8adb0d02017-09-17 19:08:02 +0200229func Test_terminal_split_quit()
230 let buf = Run_shell_in_terminal({})
Bram Moolenaar8adb0d02017-09-17 19:08:02 +0200231 split
232 quit!
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200233 call TermWait(buf)
Bram Moolenaar8adb0d02017-09-17 19:08:02 +0200234 sleep 50m
235 call assert_equal('run', job_status(g:job))
236
237 quit!
Bram Moolenaar50182fa2018-04-28 21:34:40 +0200238 call WaitForAssert({-> assert_equal('dead', job_status(g:job))})
Bram Moolenaar8adb0d02017-09-17 19:08:02 +0200239
240 exe buf . 'bwipe'
241 unlet g:job
242endfunc
243
Bram Moolenaarc9f8b842020-11-24 19:36:16 +0100244func Test_terminal_hide_buffer_job_running()
Bram Moolenaar05aafed2017-08-11 19:12:11 +0200245 let buf = Run_shell_in_terminal({})
Bram Moolenaar97a80e42017-08-30 13:31:49 +0200246 setlocal bufhidden=hide
Bram Moolenaar94053a52017-08-01 21:44:33 +0200247 quit
248 for nr in range(1, winnr('$'))
249 call assert_notequal(winbufnr(nr), buf)
250 endfor
251 call assert_true(bufloaded(buf))
252 call assert_true(buflisted(buf))
253
254 exe 'split ' . buf . 'buf'
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200255 call StopShellInTerminal(buf)
Bram Moolenaar94053a52017-08-01 21:44:33 +0200256 exe buf . 'bwipe'
257
258 unlet g:job
259endfunc
260
Bram Moolenaarc9f8b842020-11-24 19:36:16 +0100261func Test_terminal_hide_buffer_job_finished()
262 term echo hello
263 let buf = bufnr()
264 setlocal bufhidden=hide
265 call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))})
266 call assert_true(bufloaded(buf))
267 call assert_true(buflisted(buf))
268 edit Xasdfasdf
269 call assert_true(bufloaded(buf))
270 call assert_true(buflisted(buf))
271 exe buf .. 'buf'
272 call assert_equal(buf, bufnr())
273 setlocal bufhidden=
274 edit Xasdfasdf
275 call assert_false(bufloaded(buf))
276 call assert_false(buflisted(buf))
277 bwipe Xasdfasdf
278endfunc
279
Bram Moolenaar3ad69532021-11-19 17:01:08 +0000280func Test_terminal_rename_buffer()
281 let cmd = Get_cat_123_cmd()
282 let buf = term_start(cmd, {'term_name': 'foo'})
283 call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))})
284 call assert_equal('foo', bufname())
285 call assert_match('foo.*finished', execute('ls'))
286 file bar
287 call assert_equal('bar', bufname())
288 call assert_match('bar.*finished', execute('ls'))
289 exe 'bwipe! ' .. buf
290endfunc
291
Bram Moolenaar1e115362019-01-09 23:01:02 +0100292func s:Nasty_exit_cb(job, st)
Bram Moolenaar3c3a80d2017-08-03 17:06:45 +0200293 exe g:buf . 'bwipe!'
294 let g:buf = 0
295endfunc
296
Bram Moolenaar9d189612017-09-09 18:11:00 +0200297func Get_cat_123_cmd()
298 if has('win32')
Bram Moolenaaraa5df7e2019-02-03 14:53:10 +0100299 if !has('conpty')
300 return 'cmd /c "cls && color 2 && echo 123"'
301 else
302 " When clearing twice, extra sequence is not output.
303 return 'cmd /c "cls && cls && color 2 && echo 123"'
304 endif
Bram Moolenaar9d189612017-09-09 18:11:00 +0200305 else
306 call writefile(["\<Esc>[32m123"], 'Xtext')
307 return "cat Xtext"
308 endif
309endfunc
310
Bram Moolenaar3c3a80d2017-08-03 17:06:45 +0200311func Test_terminal_nasty_cb()
Bram Moolenaar33a43be2017-08-06 21:36:22 +0200312 let cmd = Get_cat_123_cmd()
Bram Moolenaar3c3a80d2017-08-03 17:06:45 +0200313 let g:buf = term_start(cmd, {'exit_cb': function('s:Nasty_exit_cb')})
314 let g:job = term_getjob(g:buf)
315
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200316 call WaitForAssert({-> assert_equal("dead", job_status(g:job))})
317 call WaitForAssert({-> assert_equal(0, g:buf)})
Bram Moolenaar3c3a80d2017-08-03 17:06:45 +0200318 unlet g:job
Bram Moolenaaraa5df7e2019-02-03 14:53:10 +0100319 unlet g:buf
Bram Moolenaar3c3a80d2017-08-03 17:06:45 +0200320 call delete('Xtext')
321endfunc
322
Bram Moolenaarc6df10e2017-07-29 20:15:08 +0200323func Check_123(buf)
Bram Moolenaar5c838a32017-08-02 22:10:34 +0200324 let l = term_scrape(a:buf, 0)
325 call assert_true(len(l) == 0)
326 let l = term_scrape(a:buf, 999)
327 call assert_true(len(l) == 0)
Bram Moolenaar7ee80f72019-09-08 20:55:06 +0200328 let l = a:buf->term_scrape(1)
Bram Moolenaarc6df10e2017-07-29 20:15:08 +0200329 call assert_true(len(l) > 0)
330 call assert_equal('1', l[0].chars)
331 call assert_equal('2', l[1].chars)
332 call assert_equal('3', l[2].chars)
333 call assert_equal('#00e000', l[0].fg)
Bram Moolenaar7ee80f72019-09-08 20:55:06 +0200334 call assert_equal(0, term_getattr(l[0].attr, 'bold'))
335 call assert_equal(0, l[0].attr->term_getattr('italic'))
Bram Moolenaar81df6352018-12-22 18:25:30 +0100336 if has('win32')
337 " On Windows 'background' always defaults to dark, even though the terminal
338 " may use a light background. Therefore accept both white and black.
339 call assert_match('#ffffff\|#000000', l[0].bg)
Bram Moolenaarc6df10e2017-07-29 20:15:08 +0200340 else
Bram Moolenaar81df6352018-12-22 18:25:30 +0100341 if &background == 'light'
342 call assert_equal('#ffffff', l[0].bg)
343 else
344 call assert_equal('#000000', l[0].bg)
345 endif
Bram Moolenaarc6df10e2017-07-29 20:15:08 +0200346 endif
347
Bram Moolenaar5c838a32017-08-02 22:10:34 +0200348 let l = term_getline(a:buf, -1)
349 call assert_equal('', l)
350 let l = term_getline(a:buf, 0)
351 call assert_equal('', l)
352 let l = term_getline(a:buf, 999)
353 call assert_equal('', l)
Bram Moolenaar9c844842017-08-01 18:41:21 +0200354 let l = term_getline(a:buf, 1)
Bram Moolenaarc6df10e2017-07-29 20:15:08 +0200355 call assert_equal('123', l)
356endfunc
357
Bram Moolenaar33a43be2017-08-06 21:36:22 +0200358func Test_terminal_scrape_123()
359 let cmd = Get_cat_123_cmd()
Bram Moolenaarc6df10e2017-07-29 20:15:08 +0200360 let buf = term_start(cmd)
361
362 let termlist = term_list()
363 call assert_equal(1, len(termlist))
364 call assert_equal(buf, termlist[0])
365
Bram Moolenaarf144a3f2017-07-30 18:02:12 +0200366 " Nothing happens with invalid buffer number
367 call term_wait(1234)
368
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200369 call TermWait(buf)
Bram Moolenaar17833372017-09-04 22:23:19 +0200370 " On MS-Windows we first get a startup message of two lines, wait for the
Bram Moolenaar1bfdc072017-09-05 20:19:42 +0200371 " "cls" to happen, after that we have one line with three characters.
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200372 call WaitForAssert({-> assert_equal(3, len(term_scrape(buf, 1)))})
Bram Moolenaarc6df10e2017-07-29 20:15:08 +0200373 call Check_123(buf)
374
375 " Must still work after the job ended.
Bram Moolenaarab8b1c12017-11-04 19:24:31 +0100376 let job = term_getjob(buf)
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200377 call WaitForAssert({-> assert_equal("dead", job_status(job))})
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200378 call TermWait(buf)
Bram Moolenaarc6df10e2017-07-29 20:15:08 +0200379 call Check_123(buf)
380
381 exe buf . 'bwipe'
Bram Moolenaarf144a3f2017-07-30 18:02:12 +0200382 call delete('Xtext')
Bram Moolenaarc6df10e2017-07-29 20:15:08 +0200383endfunc
Bram Moolenaarcfcc0222017-08-05 17:13:48 +0200384
Bram Moolenaar33a43be2017-08-06 21:36:22 +0200385func Test_terminal_scrape_multibyte()
Bram Moolenaar33a43be2017-08-06 21:36:22 +0200386 call writefile(["léttまrs"], 'Xtext')
387 if has('win32')
Bram Moolenaar36783932017-08-14 23:07:30 +0200388 " Run cmd with UTF-8 codepage to make the type command print the expected
389 " multibyte characters.
Bram Moolenaarab8b1c12017-11-04 19:24:31 +0100390 let buf = term_start("cmd /K chcp 65001")
391 call term_sendkeys(buf, "type Xtext\<CR>")
Bram Moolenaar7ee80f72019-09-08 20:55:06 +0200392 eval buf->term_sendkeys("exit\<CR>")
Bram Moolenaarab8b1c12017-11-04 19:24:31 +0100393 let line = 4
Bram Moolenaar33a43be2017-08-06 21:36:22 +0200394 else
Bram Moolenaarab8b1c12017-11-04 19:24:31 +0100395 let buf = term_start("cat Xtext")
396 let line = 1
Bram Moolenaar33a43be2017-08-06 21:36:22 +0200397 endif
Bram Moolenaar33a43be2017-08-06 21:36:22 +0200398
Bram Moolenaarab8b1c12017-11-04 19:24:31 +0100399 call WaitFor({-> len(term_scrape(buf, line)) >= 7 && term_scrape(buf, line)[0].chars == "l"})
400 let l = term_scrape(buf, line)
Bram Moolenaar33a43be2017-08-06 21:36:22 +0200401 call assert_true(len(l) >= 7)
402 call assert_equal('l', l[0].chars)
403 call assert_equal('é', l[1].chars)
404 call assert_equal(1, l[1].width)
405 call assert_equal('t', l[2].chars)
406 call assert_equal('t', l[3].chars)
407 call assert_equal('ま', l[4].chars)
408 call assert_equal(2, l[4].width)
409 call assert_equal('r', l[5].chars)
410 call assert_equal('s', l[6].chars)
411
Bram Moolenaarab8b1c12017-11-04 19:24:31 +0100412 let job = term_getjob(buf)
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200413 call WaitForAssert({-> assert_equal("dead", job_status(job))})
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200414 call TermWait(buf)
Bram Moolenaar33a43be2017-08-06 21:36:22 +0200415
Bram Moolenaarab8b1c12017-11-04 19:24:31 +0100416 exe buf . 'bwipe'
Bram Moolenaar33a43be2017-08-06 21:36:22 +0200417 call delete('Xtext')
418endfunc
419
Bram Moolenaar8b896142020-08-02 15:05:05 +0200420func Test_terminal_one_column()
421 " This creates a terminal, displays a double-wide character and makes the
422 " window one column wide. This used to cause a crash.
423 let width = &columns
424 botright vert term
425 let buf = bufnr('$')
Bram Moolenaar733d2592020-08-20 18:59:06 +0200426 call TermWait(buf, 100)
Bram Moolenaar8b896142020-08-02 15:05:05 +0200427 exe "set columns=" .. (width / 2)
428 redraw
429 call term_sendkeys(buf, "キ")
Bram Moolenaar733d2592020-08-20 18:59:06 +0200430 call TermWait(buf, 10)
Bram Moolenaar8b896142020-08-02 15:05:05 +0200431 exe "set columns=" .. width
432 exe buf . 'bwipe!'
433endfunc
434
Bram Moolenaarf8d57a52017-08-07 20:38:42 +0200435func Test_terminal_scroll()
436 call writefile(range(1, 200), 'Xtext')
437 if has('win32')
438 let cmd = 'cmd /c "type Xtext"'
439 else
440 let cmd = "cat Xtext"
441 endif
442 let buf = term_start(cmd)
443
Bram Moolenaarab8b1c12017-11-04 19:24:31 +0100444 let job = term_getjob(buf)
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200445 call WaitForAssert({-> assert_equal("dead", job_status(job))})
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200446 call TermWait(buf)
Bram Moolenaarf8d57a52017-08-07 20:38:42 +0200447
Bram Moolenaarbfcfd572020-03-25 21:27:22 +0100448 " wait until the scrolling stops
449 while 1
450 let scrolled = buf->term_getscrolled()
451 sleep 20m
452 if scrolled == buf->term_getscrolled()
453 break
454 endif
455 endwhile
456
Bram Moolenaarf8d57a52017-08-07 20:38:42 +0200457 call assert_equal('1', getline(1))
Bram Moolenaar82b9ca02017-08-08 23:06:46 +0200458 call assert_equal('1', term_getline(buf, 1 - scrolled))
Bram Moolenaarf8d57a52017-08-07 20:38:42 +0200459 call assert_equal('49', getline(49))
Bram Moolenaar82b9ca02017-08-08 23:06:46 +0200460 call assert_equal('49', term_getline(buf, 49 - scrolled))
Bram Moolenaarf8d57a52017-08-07 20:38:42 +0200461 call assert_equal('200', getline(200))
Bram Moolenaar82b9ca02017-08-08 23:06:46 +0200462 call assert_equal('200', term_getline(buf, 200 - scrolled))
Bram Moolenaarf8d57a52017-08-07 20:38:42 +0200463
464 exe buf . 'bwipe'
465 call delete('Xtext')
466endfunc
467
Bram Moolenaar6e72cd02018-04-14 21:31:35 +0200468func Test_terminal_scrollback()
Bram Moolenaar33c5e9f2018-05-26 18:58:51 +0200469 let buf = Run_shell_in_terminal({'term_rows': 15})
Bram Moolenaar6d150f72018-04-21 20:03:20 +0200470 set termwinscroll=100
Bram Moolenaar6e72cd02018-04-14 21:31:35 +0200471 call writefile(range(150), 'Xtext')
472 if has('win32')
473 call term_sendkeys(buf, "type Xtext\<CR>")
474 else
475 call term_sendkeys(buf, "cat Xtext\<CR>")
476 endif
477 let rows = term_getsize(buf)[0]
Bram Moolenaar6c672192018-04-15 13:28:42 +0200478 " On MS-Windows there is an empty line, check both last line and above it.
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200479 call WaitForAssert({-> assert_match( '149', term_getline(buf, rows - 1) . term_getline(buf, rows - 2))})
Bram Moolenaar6e72cd02018-04-14 21:31:35 +0200480 let lines = line('$')
Bram Moolenaarac3e8302018-04-15 13:10:44 +0200481 call assert_inrange(91, 100, lines)
Bram Moolenaar6e72cd02018-04-14 21:31:35 +0200482
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200483 call StopShellInTerminal(buf)
Bram Moolenaar6e72cd02018-04-14 21:31:35 +0200484 exe buf . 'bwipe'
Bram Moolenaar6d150f72018-04-21 20:03:20 +0200485 set termwinscroll&
Bram Moolenaar29ae2232019-02-14 21:22:01 +0100486 call delete('Xtext')
487endfunc
488
489func Test_terminal_postponed_scrollback()
Bram Moolenaaradbde3f2019-09-08 22:57:14 +0200490 " tail -f only works on Unix
491 CheckUnix
Bram Moolenaar29ae2232019-02-14 21:22:01 +0100492
493 call writefile(range(50), 'Xtext')
494 call writefile([
Bram Moolenaar5ff7df52019-02-15 01:06:13 +0100495 \ 'set shell=/bin/sh noruler',
Bram Moolenaar29ae2232019-02-14 21:22:01 +0100496 \ 'terminal',
Bram Moolenaar7e841e32019-02-15 00:26:14 +0100497 \ 'sleep 200m',
Bram Moolenaar5ff7df52019-02-15 01:06:13 +0100498 \ 'call feedkeys("tail -n 100 -f Xtext\<CR>", "xt")',
499 \ 'sleep 100m',
Bram Moolenaar29ae2232019-02-14 21:22:01 +0100500 \ 'call feedkeys("\<C-W>N", "xt")',
501 \ ], 'XTest_postponed')
502 let buf = RunVimInTerminal('-S XTest_postponed', {})
503 " Check that the Xtext lines are displayed and in Terminal-Normal mode
Bram Moolenaarddbfe232020-03-15 20:33:40 +0100504 call VerifyScreenDump(buf, 'Test_terminal_scrollback_1', {})
Bram Moolenaar29ae2232019-02-14 21:22:01 +0100505
506 silent !echo 'one more line' >>Xtext
Bram Moolenaar700dfaa2019-04-13 14:21:19 +0200507 " Screen will not change, move cursor to get a different dump
Bram Moolenaar29ae2232019-02-14 21:22:01 +0100508 call term_sendkeys(buf, "k")
Bram Moolenaarddbfe232020-03-15 20:33:40 +0100509 call VerifyScreenDump(buf, 'Test_terminal_scrollback_2', {})
Bram Moolenaar29ae2232019-02-14 21:22:01 +0100510
511 " Back to Terminal-Job mode, text will scroll and show the extra line.
512 call term_sendkeys(buf, "a")
Bram Moolenaarddbfe232020-03-15 20:33:40 +0100513 call VerifyScreenDump(buf, 'Test_terminal_scrollback_3', {})
Bram Moolenaar29ae2232019-02-14 21:22:01 +0100514
Bram Moolenaarddbfe232020-03-15 20:33:40 +0100515 " stop "tail -f"
Bram Moolenaar29ae2232019-02-14 21:22:01 +0100516 call term_sendkeys(buf, "\<C-C>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200517 call TermWait(buf, 25)
Bram Moolenaarddbfe232020-03-15 20:33:40 +0100518 " stop shell
Bram Moolenaar29ae2232019-02-14 21:22:01 +0100519 call term_sendkeys(buf, "exit\<CR>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200520 call TermWait(buf, 50)
Bram Moolenaarddbfe232020-03-15 20:33:40 +0100521 " close terminal window
Bram Moolenaar3a05ce62020-03-11 19:30:01 +0100522 let tsk_ret = term_sendkeys(buf, ":q\<CR>")
523
524 " check type of term_sendkeys() return value
525 echo type(tsk_ret)
526
Bram Moolenaar29ae2232019-02-14 21:22:01 +0100527 call StopVimInTerminal(buf)
528 call delete('XTest_postponed')
529 call delete('Xtext')
Bram Moolenaar6e72cd02018-04-14 21:31:35 +0200530endfunc
531
Bram Moolenaar81aa0f52019-02-14 23:23:19 +0100532" Run diff on two dumps with different size.
533func Test_terminal_dumpdiff_size()
534 call assert_equal(1, winnr('$'))
535 call term_dumpdiff('dumps/Test_incsearch_search_01.dump', 'dumps/Test_popup_command_01.dump')
536 call assert_equal(2, winnr('$'))
537 call assert_match('Test_incsearch_search_01.dump', getline(10))
538 call assert_match(' +++++$', getline(11))
539 call assert_match('Test_popup_command_01.dump', getline(31))
540 call assert_equal(repeat('+', 75), getline(30))
541 quit
542endfunc
543
Bram Moolenaarcfcc0222017-08-05 17:13:48 +0200544func Test_terminal_size()
Bram Moolenaar33a43be2017-08-06 21:36:22 +0200545 let cmd = Get_cat_123_cmd()
Bram Moolenaarcfcc0222017-08-05 17:13:48 +0200546
Bram Moolenaarb2412082017-08-20 18:09:14 +0200547 exe 'terminal ++rows=5 ' . cmd
Bram Moolenaarcfcc0222017-08-05 17:13:48 +0200548 let size = term_getsize('')
549 bwipe!
550 call assert_equal(5, size[0])
551
Bram Moolenaar08d384f2017-08-11 21:51:23 +0200552 call term_start(cmd, {'term_rows': 6})
553 let size = term_getsize('')
554 bwipe!
555 call assert_equal(6, size[0])
556
Bram Moolenaarcfcc0222017-08-05 17:13:48 +0200557 vsplit
Bram Moolenaarb2412082017-08-20 18:09:14 +0200558 exe 'terminal ++rows=5 ++cols=33 ' . cmd
Bram Moolenaar7ee80f72019-09-08 20:55:06 +0200559 call assert_equal([5, 33], ''->term_getsize())
Bram Moolenaara42d3632018-04-14 17:05:38 +0200560
561 call term_setsize('', 6, 0)
562 call assert_equal([6, 33], term_getsize(''))
563
Bram Moolenaar7ee80f72019-09-08 20:55:06 +0200564 eval ''->term_setsize(0, 35)
Bram Moolenaara42d3632018-04-14 17:05:38 +0200565 call assert_equal([6, 35], term_getsize(''))
566
567 call term_setsize('', 7, 30)
568 call assert_equal([7, 30], term_getsize(''))
569
Bram Moolenaarcfcc0222017-08-05 17:13:48 +0200570 bwipe!
Bram Moolenaar6e72cd02018-04-14 21:31:35 +0200571 call assert_fails("call term_setsize('', 7, 30)", "E955:")
Bram Moolenaarcfcc0222017-08-05 17:13:48 +0200572
Bram Moolenaar08d384f2017-08-11 21:51:23 +0200573 call term_start(cmd, {'term_rows': 6, 'term_cols': 36})
574 let size = term_getsize('')
575 bwipe!
576 call assert_equal([6, 36], size)
577
Bram Moolenaarb2412082017-08-20 18:09:14 +0200578 exe 'vertical terminal ++cols=20 ' . cmd
Bram Moolenaarcfcc0222017-08-05 17:13:48 +0200579 let size = term_getsize('')
580 bwipe!
581 call assert_equal(20, size[1])
582
Bram Moolenaar7ee80f72019-09-08 20:55:06 +0200583 eval cmd->term_start({'vertical': 1, 'term_cols': 26})
Bram Moolenaar08d384f2017-08-11 21:51:23 +0200584 let size = term_getsize('')
585 bwipe!
586 call assert_equal(26, size[1])
587
Bram Moolenaarcfcc0222017-08-05 17:13:48 +0200588 split
Bram Moolenaarb2412082017-08-20 18:09:14 +0200589 exe 'vertical terminal ++rows=6 ++cols=20 ' . cmd
Bram Moolenaarcfcc0222017-08-05 17:13:48 +0200590 let size = term_getsize('')
591 bwipe!
592 call assert_equal([6, 20], size)
Bram Moolenaar08d384f2017-08-11 21:51:23 +0200593
594 call term_start(cmd, {'vertical': 1, 'term_rows': 7, 'term_cols': 27})
595 let size = term_getsize('')
596 bwipe!
597 call assert_equal([7, 27], size)
Bram Moolenaar9d654a82017-09-03 19:52:17 +0200598
Bram Moolenaar5300be62021-11-13 10:27:40 +0000599 call assert_fails("call term_start(cmd, {'term_rows': -1})", 'E475:')
600 call assert_fails("call term_start(cmd, {'term_rows': 1001})", 'E475:')
Bram Moolenaar73e28dc2022-09-17 21:08:33 +0100601 call assert_fails("call term_start(cmd, {'term_rows': 10.0})", 'E805:')
Bram Moolenaar88137392021-11-12 16:01:15 +0000602
Bram Moolenaar9d654a82017-09-03 19:52:17 +0200603 call delete('Xtext')
Bram Moolenaarda43b612017-08-11 22:27:50 +0200604endfunc
605
Bram Moolenaareba13e42021-02-23 17:47:23 +0100606func Test_terminal_zero_height()
607 split
608 wincmd j
609 anoremenu 1.1 WinBar.test :
610 terminal ++curwin
611 wincmd k
612 wincmd _
613 redraw
614
615 call term_sendkeys(bufnr(), "exit\r")
616 bwipe!
617endfunc
618
Bram Moolenaarda43b612017-08-11 22:27:50 +0200619func Test_terminal_curwin()
620 let cmd = Get_cat_123_cmd()
621 call assert_equal(1, winnr('$'))
622
Bram Moolenaarb1009092020-05-31 16:04:42 +0200623 split Xdummy
624 call setline(1, 'dummy')
625 write
626 call assert_equal(1, getbufinfo('Xdummy')[0].loaded)
Bram Moolenaarda43b612017-08-11 22:27:50 +0200627 exe 'terminal ++curwin ' . cmd
628 call assert_equal(2, winnr('$'))
Bram Moolenaarb1009092020-05-31 16:04:42 +0200629 call assert_equal(0, getbufinfo('Xdummy')[0].loaded)
Bram Moolenaarda43b612017-08-11 22:27:50 +0200630 bwipe!
631
Bram Moolenaarb1009092020-05-31 16:04:42 +0200632 split Xdummy
Bram Moolenaarda43b612017-08-11 22:27:50 +0200633 call term_start(cmd, {'curwin': 1})
634 call assert_equal(2, winnr('$'))
635 bwipe!
636
Bram Moolenaarb1009092020-05-31 16:04:42 +0200637 split Xdummy
Bram Moolenaarda43b612017-08-11 22:27:50 +0200638 call setline(1, 'change')
639 call assert_fails('terminal ++curwin ' . cmd, 'E37:')
640 call assert_equal(2, winnr('$'))
641 exe 'terminal! ++curwin ' . cmd
642 call assert_equal(2, winnr('$'))
643 bwipe!
644
Bram Moolenaarb1009092020-05-31 16:04:42 +0200645 split Xdummy
Bram Moolenaarda43b612017-08-11 22:27:50 +0200646 call setline(1, 'change')
647 call assert_fails("call term_start(cmd, {'curwin': 1})", 'E37:')
648 call assert_equal(2, winnr('$'))
649 bwipe!
650
Bram Moolenaarb1009092020-05-31 16:04:42 +0200651 split Xdummy
Bram Moolenaarda43b612017-08-11 22:27:50 +0200652 bwipe!
Bram Moolenaar9d654a82017-09-03 19:52:17 +0200653 call delete('Xtext')
Bram Moolenaarb1009092020-05-31 16:04:42 +0200654 call delete('Xdummy')
Bram Moolenaarcfcc0222017-08-05 17:13:48 +0200655endfunc
Bram Moolenaardd693ce2017-08-10 23:15:19 +0200656
Bram Moolenaarff546792017-11-21 14:47:57 +0100657func s:get_sleep_cmd()
Bram Moolenaarb81bc772017-08-11 22:45:01 +0200658 if s:python != ''
659 let cmd = s:python . " test_short_sleep.py"
Bram Moolenaarc8523e22018-06-03 18:22:02 +0200660 " 500 was not enough for Travis
661 let waittime = 900
Bram Moolenaardd693ce2017-08-10 23:15:19 +0200662 else
Bram Moolenaarb81bc772017-08-11 22:45:01 +0200663 echo 'This will take five seconds...'
664 let waittime = 2000
665 if has('win32')
666 let cmd = $windir . '\system32\timeout.exe 1'
667 else
668 let cmd = 'sleep 1'
669 endif
Bram Moolenaardd693ce2017-08-10 23:15:19 +0200670 endif
Bram Moolenaarff546792017-11-21 14:47:57 +0100671 return [cmd, waittime]
672endfunc
673
674func Test_terminal_finish_open_close()
675 call assert_equal(1, winnr('$'))
676
677 let [cmd, waittime] = s:get_sleep_cmd()
Bram Moolenaarb81bc772017-08-11 22:45:01 +0200678
Bram Moolenaar1dd98332018-03-16 22:54:53 +0100679 " shell terminal closes automatically
680 terminal
681 let buf = bufnr('%')
682 call assert_equal(2, winnr('$'))
683 " Wait for the shell to display a prompt
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200684 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))})
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200685 call StopShellInTerminal(buf)
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200686 call WaitForAssert({-> assert_equal(1, winnr('$'))}, waittime)
Bram Moolenaar1dd98332018-03-16 22:54:53 +0100687
688 " shell terminal that does not close automatically
689 terminal ++noclose
690 let buf = bufnr('%')
691 call assert_equal(2, winnr('$'))
692 " Wait for the shell to display a prompt
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200693 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))})
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200694 call StopShellInTerminal(buf)
Bram Moolenaar1dd98332018-03-16 22:54:53 +0100695 call assert_equal(2, winnr('$'))
696 quit
697 call assert_equal(1, winnr('$'))
698
Bram Moolenaardd693ce2017-08-10 23:15:19 +0200699 exe 'terminal ++close ' . cmd
Bram Moolenaardd693ce2017-08-10 23:15:19 +0200700 call assert_equal(2, winnr('$'))
Bram Moolenaardd693ce2017-08-10 23:15:19 +0200701 wincmd p
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200702 call WaitForAssert({-> assert_equal(1, winnr('$'))}, waittime)
Bram Moolenaardd693ce2017-08-10 23:15:19 +0200703
704 call term_start(cmd, {'term_finish': 'close'})
705 call assert_equal(2, winnr('$'))
Bram Moolenaardd693ce2017-08-10 23:15:19 +0200706 wincmd p
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200707 call WaitForAssert({-> assert_equal(1, winnr('$'))}, waittime)
Bram Moolenaardd693ce2017-08-10 23:15:19 +0200708 call assert_equal(1, winnr('$'))
709
710 exe 'terminal ++open ' . cmd
Bram Moolenaar97a80e42017-08-30 13:31:49 +0200711 close!
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200712 call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime)
Bram Moolenaardd693ce2017-08-10 23:15:19 +0200713 bwipe
714
715 call term_start(cmd, {'term_finish': 'open'})
Bram Moolenaar97a80e42017-08-30 13:31:49 +0200716 close!
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200717 call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime)
Bram Moolenaar8cad9302017-08-12 14:32:32 +0200718 bwipe
Bram Moolenaardd693ce2017-08-10 23:15:19 +0200719
Bram Moolenaar8cad9302017-08-12 14:32:32 +0200720 exe 'terminal ++hidden ++open ' . cmd
721 call assert_equal(1, winnr('$'))
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200722 call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime)
Bram Moolenaar8cad9302017-08-12 14:32:32 +0200723 bwipe
724
725 call term_start(cmd, {'term_finish': 'open', 'hidden': 1})
726 call assert_equal(1, winnr('$'))
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200727 call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime)
Bram Moolenaardd693ce2017-08-10 23:15:19 +0200728 bwipe
Bram Moolenaar37c45832017-08-12 16:01:04 +0200729
730 call assert_fails("call term_start(cmd, {'term_opencmd': 'open'})", 'E475:')
731 call assert_fails("call term_start(cmd, {'term_opencmd': 'split %x'})", 'E475:')
732 call assert_fails("call term_start(cmd, {'term_opencmd': 'split %d and %s'})", 'E475:')
733 call assert_fails("call term_start(cmd, {'term_opencmd': 'split % and %d'})", 'E475:')
734
Bram Moolenaar47c5ea42020-11-12 15:12:15 +0100735 call term_start(cmd, {'term_finish': 'open', 'term_opencmd': '4split | buffer %d | let g:result = "opened the buffer in a window"'})
Bram Moolenaar97a80e42017-08-30 13:31:49 +0200736 close!
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200737 call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime)
Bram Moolenaar37c45832017-08-12 16:01:04 +0200738 call assert_equal(4, winheight(0))
Bram Moolenaar47c5ea42020-11-12 15:12:15 +0100739 call assert_equal('opened the buffer in a window', g:result)
740 unlet g:result
Bram Moolenaar37c45832017-08-12 16:01:04 +0200741 bwipe
Bram Moolenaardd693ce2017-08-10 23:15:19 +0200742endfunc
Bram Moolenaar05aafed2017-08-11 19:12:11 +0200743
744func Test_terminal_cwd()
Bram Moolenaar077ff432019-10-28 00:42:21 +0100745 if has('win32')
746 let cmd = 'cmd /c cd'
747 else
748 CheckExecutable pwd
749 let cmd = 'pwd'
Bram Moolenaar05aafed2017-08-11 19:12:11 +0200750 endif
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100751 call mkdir('Xtermdir')
752 let buf = term_start(cmd, {'cwd': 'Xtermdir'})
Bram Moolenaaree7c8d92022-09-22 12:57:06 +0100753 " if the path is very long it may be split over two lines, join them
754 " together
755 call WaitForAssert({-> assert_equal('Xtermdir', fnamemodify(getline(1) .. getline(2), ":t"))})
Bram Moolenaar05aafed2017-08-11 19:12:11 +0200756
757 exe buf . 'bwipe'
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100758 call delete('Xtermdir', 'rf')
Bram Moolenaar05aafed2017-08-11 19:12:11 +0200759endfunc
760
Bram Moolenaar839e81e2018-10-19 16:53:39 +0200761func Test_terminal_cwd_failure()
762 " Case 1: Provided directory is not actually a directory. Attempt to make
763 " the file executable as well.
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100764 call writefile([], 'Xtcfile')
Dominique Pelle91a874e2022-09-03 10:59:32 +0100765 call setfperm('Xtcfile', 'rwx------')
766 call assert_fails("call term_start(&shell, {'cwd': 'Xtcfile'})", 'E475:')
767 call delete('Xtcfile')
Bram Moolenaar839e81e2018-10-19 16:53:39 +0200768
769 " Case 2: Directory does not exist.
770 call assert_fails("call term_start(&shell, {'cwd': 'Xdir'})", 'E475:')
771
772 " Case 3: Directory exists but is not accessible.
Bram Moolenaar0b38f542018-11-03 21:47:16 +0100773 " Skip this for root, it will be accessible anyway.
Bram Moolenaar07282f02019-10-10 16:46:17 +0200774 if !IsRoot()
Bram Moolenaar0b38f542018-11-03 21:47:16 +0100775 call mkdir('XdirNoAccess', '', '0600')
776 " return early if the directory permissions could not be set properly
777 if getfperm('XdirNoAccess')[2] == 'x'
778 call delete('XdirNoAccess', 'rf')
779 return
780 endif
781 call assert_fails("call term_start(&shell, {'cwd': 'XdirNoAccess'})", 'E475:')
782 call delete('XdirNoAccess', 'rf')
Bram Moolenaar839e81e2018-10-19 16:53:39 +0200783 endif
Bram Moolenaar839e81e2018-10-19 16:53:39 +0200784endfunc
785
Bram Moolenaar52dbb5e2017-11-21 18:11:27 +0100786func Test_terminal_servername()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200787 CheckFeature clientserver
Bram Moolenaard7a137f2018-06-12 18:05:24 +0200788 call s:test_environment("VIM_SERVERNAME", v:servername)
789endfunc
790
791func Test_terminal_version()
792 call s:test_environment("VIM_TERMINAL", string(v:version))
793endfunc
794
795func s:test_environment(name, value)
Bram Moolenaar012eb662018-03-13 17:55:27 +0100796 let buf = Run_shell_in_terminal({})
Bram Moolenaar52dbb5e2017-11-21 18:11:27 +0100797 " Wait for the shell to display a prompt
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200798 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))})
Bram Moolenaar52dbb5e2017-11-21 18:11:27 +0100799 if has('win32')
Bram Moolenaard7a137f2018-06-12 18:05:24 +0200800 call term_sendkeys(buf, "echo %" . a:name . "%\r")
Bram Moolenaar52dbb5e2017-11-21 18:11:27 +0100801 else
Bram Moolenaard7a137f2018-06-12 18:05:24 +0200802 call term_sendkeys(buf, "echo $" . a:name . "\r")
Bram Moolenaar52dbb5e2017-11-21 18:11:27 +0100803 endif
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200804 call TermWait(buf)
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200805 call StopShellInTerminal(buf)
Bram Moolenaard7a137f2018-06-12 18:05:24 +0200806 call WaitForAssert({-> assert_equal(a:value, getline(2))})
Bram Moolenaar52dbb5e2017-11-21 18:11:27 +0100807
Bram Moolenaar012eb662018-03-13 17:55:27 +0100808 exe buf . 'bwipe'
809 unlet buf
Bram Moolenaar52dbb5e2017-11-21 18:11:27 +0100810endfunc
811
Bram Moolenaar05aafed2017-08-11 19:12:11 +0200812func Test_terminal_env()
Bram Moolenaar012eb662018-03-13 17:55:27 +0100813 let buf = Run_shell_in_terminal({'env': {'TESTENV': 'correct'}})
Bram Moolenaar51c23682017-08-14 21:45:00 +0200814 " Wait for the shell to display a prompt
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200815 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))})
Bram Moolenaarba6febd2017-10-30 21:56:23 +0100816 if has('win32')
Bram Moolenaar012eb662018-03-13 17:55:27 +0100817 call term_sendkeys(buf, "echo %TESTENV%\r")
Bram Moolenaarba6febd2017-10-30 21:56:23 +0100818 else
Bram Moolenaar012eb662018-03-13 17:55:27 +0100819 call term_sendkeys(buf, "echo $TESTENV\r")
Bram Moolenaarba6febd2017-10-30 21:56:23 +0100820 endif
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200821 eval buf->TermWait()
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200822 call StopShellInTerminal(buf)
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200823 call WaitForAssert({-> assert_equal('correct', getline(2))})
Bram Moolenaar05aafed2017-08-11 19:12:11 +0200824
Bram Moolenaar012eb662018-03-13 17:55:27 +0100825 exe buf . 'bwipe'
Bram Moolenaar05aafed2017-08-11 19:12:11 +0200826endfunc
Bram Moolenaar679653e2017-08-13 14:13:19 +0200827
Bram Moolenaardcaa6132017-08-13 17:13:09 +0200828func Test_terminal_list_args()
829 let buf = term_start([&shell, &shellcmdflag, 'echo "123"'])
Yee Cheng Chin15b314f2022-10-09 18:53:32 +0100830 call assert_fails(buf . 'bwipe', 'E948:')
Bram Moolenaardcaa6132017-08-13 17:13:09 +0200831 exe buf . 'bwipe!'
832 call assert_equal("", bufname(buf))
833endfunction
Bram Moolenaar97bd5e62017-08-18 20:50:30 +0200834
835func Test_terminal_noblock()
Bram Moolenaarf08b0eb2021-10-16 13:00:14 +0100836 let g:test_is_flaky = 1
Bram Moolenaarab8b1c12017-11-04 19:24:31 +0100837 let buf = term_start(&shell)
Zdenek Dohnaldd2dfb32022-02-23 14:25:17 +0000838 " Starting a terminal can be slow, esp. on busy CI machines.
839 let wait_time = 7500
Bram Moolenaarf3710ee2020-03-24 12:12:30 +0100840 let letters = 'abcdefghijklmnopqrstuvwxyz'
Bram Moolenaar39536dd2019-01-29 22:58:21 +0100841 if has('bsd') || has('mac') || has('sun')
Bram Moolenaard8d85bf2017-09-03 18:08:00 +0200842 " The shell or something else has a problem dealing with more than 1000
Bram Moolenaarf3710ee2020-03-24 12:12:30 +0100843 " characters at the same time. It's very slow too.
Bram Moolenaard8d85bf2017-09-03 18:08:00 +0200844 let len = 1000
Bram Moolenaard06dbf32020-03-24 10:33:00 +0100845 let wait_time = 15000
Bram Moolenaarf3710ee2020-03-24 12:12:30 +0100846 let letters = 'abcdefghijklm'
Bram Moolenaaraa5df7e2019-02-03 14:53:10 +0100847 " NPFS is used in Windows, nonblocking mode does not work properly.
848 elseif has('win32')
849 let len = 1
Bram Moolenaard8d85bf2017-09-03 18:08:00 +0200850 else
851 let len = 5000
852 endif
Bram Moolenaar97bd5e62017-08-18 20:50:30 +0200853
Bram Moolenaard06dbf32020-03-24 10:33:00 +0100854 " Send a lot of text lines, should be buffered properly.
Bram Moolenaarf3710ee2020-03-24 12:12:30 +0100855 for c in split(letters, '\zs')
Bram Moolenaarab8b1c12017-11-04 19:24:31 +0100856 call term_sendkeys(buf, 'echo ' . repeat(c, len) . "\<cr>")
Bram Moolenaar97bd5e62017-08-18 20:50:30 +0200857 endfor
Bram Moolenaarab8b1c12017-11-04 19:24:31 +0100858 call term_sendkeys(buf, "echo done\<cr>")
Bram Moolenaareef05312017-08-20 20:21:23 +0200859
860 " On MS-Windows there is an extra empty line below "done". Find "done" in
861 " the last-but-one or the last-but-two line.
Bram Moolenaarab8b1c12017-11-04 19:24:31 +0100862 let lnum = term_getsize(buf)[0] - 1
Bram Moolenaard06dbf32020-03-24 10:33:00 +0100863 call WaitForAssert({-> assert_match('done', term_getline(buf, lnum - 1) .. '//' .. term_getline(buf, lnum))}, wait_time)
Bram Moolenaarab8b1c12017-11-04 19:24:31 +0100864 let line = term_getline(buf, lnum)
Bram Moolenaareef05312017-08-20 20:21:23 +0200865 if line !~ 'done'
Bram Moolenaarab8b1c12017-11-04 19:24:31 +0100866 let line = term_getline(buf, lnum - 1)
Bram Moolenaareef05312017-08-20 20:21:23 +0200867 endif
868 call assert_match('done', line)
Bram Moolenaar97bd5e62017-08-18 20:50:30 +0200869
Bram Moolenaarab8b1c12017-11-04 19:24:31 +0100870 let g:job = term_getjob(buf)
Bram Moolenaar7a39dd72019-06-23 00:50:15 +0200871 call StopShellInTerminal(buf)
Bram Moolenaard21f8b52017-08-19 15:40:01 +0200872 unlet g:job
Bram Moolenaar97bd5e62017-08-18 20:50:30 +0200873 bwipe
874endfunc
Bram Moolenaar37819ed2017-08-20 19:33:47 +0200875
876func Test_terminal_write_stdin()
Bram Moolenaar21109272020-01-30 16:27:20 +0100877 " TODO: enable once writing to stdin works on MS-Windows
878 CheckNotMSWindows
879 CheckExecutable wc
Bram Moolenaar62eb2392022-06-15 17:52:44 +0100880 let g:test_is_flaky = 1
Bram Moolenaar21109272020-01-30 16:27:20 +0100881
Bram Moolenaar37819ed2017-08-20 19:33:47 +0200882 call setline(1, ['one', 'two', 'three'])
883 %term wc
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200884 call WaitForAssert({-> assert_match('3', getline("$"))})
Bram Moolenaar3346cc42017-09-02 14:54:21 +0200885 let nrs = split(getline('$'))
Bram Moolenaar37819ed2017-08-20 19:33:47 +0200886 call assert_equal(['3', '3', '14'], nrs)
Bram Moolenaar21109272020-01-30 16:27:20 +0100887 %bwipe!
Bram Moolenaar37819ed2017-08-20 19:33:47 +0200888
889 call setline(1, ['one', 'two', 'three', 'four'])
890 2,3term wc
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200891 call WaitForAssert({-> assert_match('2', getline("$"))})
Bram Moolenaar3346cc42017-09-02 14:54:21 +0200892 let nrs = split(getline('$'))
Bram Moolenaar37819ed2017-08-20 19:33:47 +0200893 call assert_equal(['2', '2', '10'], nrs)
Bram Moolenaar21109272020-01-30 16:27:20 +0100894 %bwipe!
895endfunc
Bram Moolenaar37819ed2017-08-20 19:33:47 +0200896
Bram Moolenaar21109272020-01-30 16:27:20 +0100897func Test_terminal_eof_arg()
Bram Moolenaara161cb52020-04-30 19:09:35 +0200898 call CheckPython(s:python)
Bram Moolenaar62eb2392022-06-15 17:52:44 +0100899 let g:test_is_flaky = 1
Bram Moolenaardada6d22017-09-02 17:18:35 +0200900
Bram Moolenaar21109272020-01-30 16:27:20 +0100901 call setline(1, ['print("hello")'])
Bram Moolenaara161cb52020-04-30 19:09:35 +0200902 exe '1term ++eof=exit(123) ' .. s:python
Bram Moolenaar21109272020-01-30 16:27:20 +0100903 " MS-Windows echoes the input, Unix doesn't.
904 if has('win32')
905 call WaitFor({-> getline('$') =~ 'exit(123)'})
906 call assert_equal('hello', getline(line('$') - 1))
907 else
908 call WaitFor({-> getline('$') =~ 'hello'})
909 call assert_equal('hello', getline('$'))
Bram Moolenaardada6d22017-09-02 17:18:35 +0200910 endif
Bram Moolenaar21109272020-01-30 16:27:20 +0100911 call assert_equal(123, bufnr()->term_getjob()->job_info().exitval)
912 %bwipe!
913endfunc
Bram Moolenaardada6d22017-09-02 17:18:35 +0200914
Bram Moolenaar21109272020-01-30 16:27:20 +0100915func Test_terminal_eof_arg_win32_ctrl_z()
916 CheckMSWindows
Bram Moolenaara161cb52020-04-30 19:09:35 +0200917 call CheckPython(s:python)
Bram Moolenaar62eb2392022-06-15 17:52:44 +0100918 let g:test_is_flaky = 1
Bram Moolenaar21109272020-01-30 16:27:20 +0100919
920 call setline(1, ['print("hello")'])
Bram Moolenaara161cb52020-04-30 19:09:35 +0200921 exe '1term ++eof=<C-Z> ' .. s:python
Bram Moolenaar21109272020-01-30 16:27:20 +0100922 call WaitForAssert({-> assert_match('\^Z', getline(line('$') - 1))})
923 call assert_match('\^Z', getline(line('$') - 1))
924 %bwipe!
925endfunc
926
927func Test_terminal_duplicate_eof_arg()
Bram Moolenaara161cb52020-04-30 19:09:35 +0200928 call CheckPython(s:python)
Bram Moolenaar62eb2392022-06-15 17:52:44 +0100929 let g:test_is_flaky = 1
Bram Moolenaar21109272020-01-30 16:27:20 +0100930
Bram Moolenaar62eb2392022-06-15 17:52:44 +0100931 " Check the last specified ++eof arg is used and does not leak memory.
Bram Moolenaar21109272020-01-30 16:27:20 +0100932 new
933 call setline(1, ['print("hello")'])
Bram Moolenaara161cb52020-04-30 19:09:35 +0200934 exe '1term ++eof=<C-Z> ++eof=exit(123) ' .. s:python
Bram Moolenaar21109272020-01-30 16:27:20 +0100935 " MS-Windows echoes the input, Unix doesn't.
936 if has('win32')
937 call WaitFor({-> getline('$') =~ 'exit(123)'})
938 call assert_equal('hello', getline(line('$') - 1))
939 else
940 call WaitFor({-> getline('$') =~ 'hello'})
941 call assert_equal('hello', getline('$'))
942 endif
943 call assert_equal(123, bufnr()->term_getjob()->job_info().exitval)
944 %bwipe!
Bram Moolenaar37819ed2017-08-20 19:33:47 +0200945endfunc
Bram Moolenaar13ebb032017-08-26 22:02:51 +0200946
947func Test_terminal_no_cmd()
Bram Moolenaarf08b0eb2021-10-16 13:00:14 +0100948 let g:test_is_flaky = 1
Bram Moolenaar13ebb032017-08-26 22:02:51 +0200949 let buf = term_start('NONE', {})
950 call assert_notequal(0, buf)
951
Bram Moolenaar2dc9d262017-09-08 14:39:30 +0200952 let pty = job_info(term_getjob(buf))['tty_out']
Bram Moolenaar13ebb032017-08-26 22:02:51 +0200953 call assert_notequal('', pty)
Bram Moolenaarcfc15232019-01-23 22:33:18 +0100954 if has('gui_running') && !has('win32')
955 " In the GUI job_start() doesn't work, it does not read from the pty.
Bram Moolenaar2dc9d262017-09-08 14:39:30 +0200956 call system('echo "look here" > ' . pty)
Bram Moolenaarcfc15232019-01-23 22:33:18 +0100957 else
958 " Otherwise using a job works on all systems.
959 call job_start([&shell, &shellcmdflag, 'echo "look here" > ' . pty])
Bram Moolenaar2dc9d262017-09-08 14:39:30 +0200960 endif
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200961 call WaitForAssert({-> assert_match('look here', term_getline(buf, 1))})
Bram Moolenaar2dc9d262017-09-08 14:39:30 +0200962
Bram Moolenaar13ebb032017-08-26 22:02:51 +0200963 bwipe!
964endfunc
Bram Moolenaar9d654a82017-09-03 19:52:17 +0200965
966func Test_terminal_special_chars()
967 " this file name only works on Unix
Bram Moolenaaradbde3f2019-09-08 22:57:14 +0200968 CheckUnix
969
Bram Moolenaar9d654a82017-09-03 19:52:17 +0200970 call mkdir('Xdir with spaces')
971 call writefile(['x'], 'Xdir with spaces/quoted"file')
972 term ls Xdir\ with\ spaces/quoted\"file
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200973 call WaitForAssert({-> assert_match('quoted"file', term_getline('', 1))})
Bram Moolenaar95ffd432020-02-23 13:29:31 +0100974 " make sure the job has finished
975 call WaitForAssert({-> assert_match('finish', term_getstatus(bufnr()))})
Bram Moolenaar9d654a82017-09-03 19:52:17 +0200976
977 call delete('Xdir with spaces', 'rf')
978 bwipe
979endfunc
Bram Moolenaare88fc7a2017-09-03 20:59:40 +0200980
981func Test_terminal_wrong_options()
982 call assert_fails('call term_start(&shell, {
983 \ "in_io": "file",
984 \ "in_name": "xxx",
985 \ "out_io": "file",
986 \ "out_name": "xxx",
987 \ "err_io": "file",
988 \ "err_name": "xxx"
989 \ })', 'E474:')
990 call assert_fails('call term_start(&shell, {
991 \ "out_buf": bufnr("%")
992 \ })', 'E474:')
993 call assert_fails('call term_start(&shell, {
994 \ "err_buf": bufnr("%")
995 \ })', 'E474:')
996endfunc
997
998func Test_terminal_redir_file()
Bram Moolenaarf08b0eb2021-10-16 13:00:14 +0100999 let g:test_is_flaky = 1
Bram Moolenaarf25329c2018-05-06 21:49:32 +02001000 let cmd = Get_cat_123_cmd()
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001001 let buf = term_start(cmd, {'out_io': 'file', 'out_name': 'Xtrfile'})
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02001002 call TermWait(buf)
Bram Moolenaaraa5df7e2019-02-03 14:53:10 +01001003 " ConPTY may precede escape sequence. There are things that are not so.
1004 if !has('conpty')
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001005 call WaitForAssert({-> assert_notequal(0, len(readfile("Xtrfile")))})
1006 call assert_match('123', readfile('Xtrfile')[0])
Bram Moolenaaraa5df7e2019-02-03 14:53:10 +01001007 endif
Bram Moolenaarf25329c2018-05-06 21:49:32 +02001008 let g:job = term_getjob(buf)
1009 call WaitForAssert({-> assert_equal("dead", job_status(g:job))})
Bram Moolenaarc69950a2020-07-22 22:23:40 +02001010
1011 if has('win32')
1012 " On Windows we cannot delete a file being used by a process. When
1013 " job_status() returns "dead", the process remains for a short time.
1014 " Just wait for a moment.
1015 sleep 50m
1016 endif
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001017 call delete('Xtrfile')
Bram Moolenaarf25329c2018-05-06 21:49:32 +02001018 bwipe
Bram Moolenaare88fc7a2017-09-03 20:59:40 +02001019
1020 if has('unix')
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001021 call writefile(['one line'], 'Xtrfile')
1022 let buf = term_start('cat', {'in_io': 'file', 'in_name': 'Xtrfile'})
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02001023 call TermWait(buf)
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +02001024 call WaitForAssert({-> assert_equal('one line', term_getline(buf, 1))})
Bram Moolenaar8b53b792017-09-05 20:29:25 +02001025 let g:job = term_getjob(buf)
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +02001026 call WaitForAssert({-> assert_equal('dead', job_status(g:job))})
Bram Moolenaare88fc7a2017-09-03 20:59:40 +02001027 bwipe
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001028 call delete('Xtrfile')
Bram Moolenaare88fc7a2017-09-03 20:59:40 +02001029 endif
1030endfunc
Bram Moolenaar69fbc9e2017-09-14 20:37:57 +02001031
1032func TerminalTmap(remap)
1033 let buf = Run_shell_in_terminal({})
Bram Moolenaarf4a2ed02021-03-23 16:25:09 +01001034 " Wait for the shell to display a prompt
1035 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))})
Bram Moolenaar69fbc9e2017-09-14 20:37:57 +02001036 call assert_equal('t', mode())
1037
1038 if a:remap
1039 tmap 123 456
1040 else
1041 tnoremap 123 456
1042 endif
Bram Moolenaar461fe502017-12-05 12:30:03 +01001043 " don't use abcde, it's an existing command
1044 tmap 456 abxde
Bram Moolenaar69fbc9e2017-09-14 20:37:57 +02001045 call assert_equal('456', maparg('123', 't'))
Bram Moolenaar461fe502017-12-05 12:30:03 +01001046 call assert_equal('abxde', maparg('456', 't'))
Bram Moolenaar69fbc9e2017-09-14 20:37:57 +02001047 call feedkeys("123", 'tx')
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +02001048 call WaitForAssert({-> assert_match('abxde\|456', term_getline(buf, term_getcursor(buf)[0]))})
Bram Moolenaar69fbc9e2017-09-14 20:37:57 +02001049 let lnum = term_getcursor(buf)[0]
1050 if a:remap
Bram Moolenaar461fe502017-12-05 12:30:03 +01001051 call assert_match('abxde', term_getline(buf, lnum))
Bram Moolenaar69fbc9e2017-09-14 20:37:57 +02001052 else
1053 call assert_match('456', term_getline(buf, lnum))
1054 endif
1055
1056 call term_sendkeys(buf, "\r")
Bram Moolenaar7a39dd72019-06-23 00:50:15 +02001057 call StopShellInTerminal(buf)
Bram Moolenaar69fbc9e2017-09-14 20:37:57 +02001058
1059 tunmap 123
1060 tunmap 456
1061 call assert_equal('', maparg('123', 't'))
Yegappan Lakshmanan1104a6d2022-03-31 12:34:15 +01001062 exe buf . 'bwipe'
Bram Moolenaar69fbc9e2017-09-14 20:37:57 +02001063 unlet g:job
1064endfunc
1065
1066func Test_terminal_tmap()
1067 call TerminalTmap(1)
1068 call TerminalTmap(0)
1069endfunc
Bram Moolenaar059db5c2017-10-15 22:42:23 +02001070
1071func Test_terminal_wall()
1072 let buf = Run_shell_in_terminal({})
1073 wall
Bram Moolenaar7a39dd72019-06-23 00:50:15 +02001074 call StopShellInTerminal(buf)
Bram Moolenaar059db5c2017-10-15 22:42:23 +02001075 exe buf . 'bwipe'
1076 unlet g:job
1077endfunc
Bram Moolenaar6daeef12017-10-15 22:56:49 +02001078
Bram Moolenaar7a760922018-02-19 23:10:02 +01001079func Test_terminal_wqall()
1080 let buf = Run_shell_in_terminal({})
Bram Moolenaare2e40752020-09-04 21:18:46 +02001081 call assert_fails('wqall', 'E948:')
Bram Moolenaar7a39dd72019-06-23 00:50:15 +02001082 call StopShellInTerminal(buf)
Bram Moolenaar7a760922018-02-19 23:10:02 +01001083 exe buf . 'bwipe'
1084 unlet g:job
1085endfunc
1086
Bram Moolenaar6daeef12017-10-15 22:56:49 +02001087func Test_terminal_composing_unicode()
Bram Moolenaarf08b0eb2021-10-16 13:00:14 +01001088 let g:test_is_flaky = 1
Bram Moolenaar6daeef12017-10-15 22:56:49 +02001089 let save_enc = &encoding
1090 set encoding=utf-8
1091
1092 if has('win32')
1093 let cmd = "cmd /K chcp 65001"
1094 let lnum = [3, 6, 9]
1095 else
1096 let cmd = &shell
1097 let lnum = [1, 3, 5]
1098 endif
1099
1100 enew
Bram Moolenaarc98cdb32020-09-06 21:13:00 +02001101 let buf = term_start(cmd, {'curwin': 1})
Bram Moolenaar3e1c6172017-11-02 16:58:00 +01001102 let g:job = term_getjob(buf)
Bram Moolenaar41d42992020-05-03 16:29:50 +02001103 call WaitFor({-> term_getline(buf, 1) !=# ''}, 1000)
Bram Moolenaar6daeef12017-10-15 22:56:49 +02001104
Bram Moolenaarebe74b72018-04-21 23:34:43 +02001105 if has('win32')
1106 call assert_equal('cmd', job_info(g:job).cmd[0])
1107 else
1108 call assert_equal(&shell, job_info(g:job).cmd[0])
1109 endif
1110
Bram Moolenaar6daeef12017-10-15 22:56:49 +02001111 " ascii + composing
1112 let txt = "a\u0308bc"
Bram Moolenaar41d42992020-05-03 16:29:50 +02001113 call term_sendkeys(buf, "echo " . txt)
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02001114 call TermWait(buf, 25)
Bram Moolenaar6daeef12017-10-15 22:56:49 +02001115 call assert_match("echo " . txt, term_getline(buf, lnum[0]))
Bram Moolenaar41d42992020-05-03 16:29:50 +02001116 call term_sendkeys(buf, "\<cr>")
1117 call WaitForAssert({-> assert_equal(txt, term_getline(buf, lnum[0] + 1))}, 1000)
Bram Moolenaar6daeef12017-10-15 22:56:49 +02001118 let l = term_scrape(buf, lnum[0] + 1)
1119 call assert_equal("a\u0308", l[0].chars)
1120 call assert_equal("b", l[1].chars)
1121 call assert_equal("c", l[2].chars)
1122
Bram Moolenaar4549dad2021-02-08 21:29:48 +01001123 " multibyte + composing: がぎぐげご
Bram Moolenaar6daeef12017-10-15 22:56:49 +02001124 let txt = "\u304b\u3099\u304e\u304f\u3099\u3052\u3053\u3099"
Bram Moolenaar41d42992020-05-03 16:29:50 +02001125 call term_sendkeys(buf, "echo " . txt)
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02001126 call TermWait(buf, 25)
Bram Moolenaar6daeef12017-10-15 22:56:49 +02001127 call assert_match("echo " . txt, term_getline(buf, lnum[1]))
Bram Moolenaar41d42992020-05-03 16:29:50 +02001128 call term_sendkeys(buf, "\<cr>")
1129 call WaitForAssert({-> assert_equal(txt, term_getline(buf, lnum[1] + 1))}, 1000)
Bram Moolenaar6daeef12017-10-15 22:56:49 +02001130 let l = term_scrape(buf, lnum[1] + 1)
1131 call assert_equal("\u304b\u3099", l[0].chars)
Bram Moolenaar4549dad2021-02-08 21:29:48 +01001132 call assert_equal(2, l[0].width)
1133 call assert_equal("\u304e", l[1].chars)
1134 call assert_equal(2, l[1].width)
1135 call assert_equal("\u304f\u3099", l[2].chars)
1136 call assert_equal(2, l[2].width)
1137 call assert_equal("\u3052", l[3].chars)
1138 call assert_equal(2, l[3].width)
1139 call assert_equal("\u3053\u3099", l[4].chars)
1140 call assert_equal(2, l[4].width)
Bram Moolenaar6daeef12017-10-15 22:56:49 +02001141
1142 " \u00a0 + composing
1143 let txt = "abc\u00a0\u0308"
Bram Moolenaar41d42992020-05-03 16:29:50 +02001144 call term_sendkeys(buf, "echo " . txt)
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02001145 call TermWait(buf, 25)
Bram Moolenaar6daeef12017-10-15 22:56:49 +02001146 call assert_match("echo " . txt, term_getline(buf, lnum[2]))
Bram Moolenaar41d42992020-05-03 16:29:50 +02001147 call term_sendkeys(buf, "\<cr>")
1148 call WaitForAssert({-> assert_equal(txt, term_getline(buf, lnum[2] + 1))}, 1000)
Bram Moolenaar6daeef12017-10-15 22:56:49 +02001149 let l = term_scrape(buf, lnum[2] + 1)
1150 call assert_equal("\u00a0\u0308", l[3].chars)
1151
1152 call term_sendkeys(buf, "exit\r")
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +02001153 call WaitForAssert({-> assert_equal('dead', job_status(g:job))})
Bram Moolenaar6daeef12017-10-15 22:56:49 +02001154 bwipe!
Bram Moolenaar3e1c6172017-11-02 16:58:00 +01001155 unlet g:job
Bram Moolenaar6daeef12017-10-15 22:56:49 +02001156 let &encoding = save_enc
1157endfunc
Bram Moolenaarff546792017-11-21 14:47:57 +01001158
1159func Test_terminal_aucmd_on_close()
1160 fun Nop()
1161 let s:called = 1
1162 endfun
1163
1164 aug repro
1165 au!
1166 au BufWinLeave * call Nop()
1167 aug END
1168
1169 let [cmd, waittime] = s:get_sleep_cmd()
1170
1171 call assert_equal(1, winnr('$'))
1172 new
1173 call setline(1, ['one', 'two'])
1174 exe 'term ++close ' . cmd
1175 wincmd p
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +02001176 call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime)
Bram Moolenaarff546792017-11-21 14:47:57 +01001177 call assert_equal(1, s:called)
1178 bwipe!
1179
1180 unlet s:called
1181 au! repro
1182 delfunc Nop
1183endfunc
Bram Moolenaarede35bb2018-01-26 20:05:18 +01001184
1185func Test_terminal_term_start_empty_command()
1186 let cmd = "call term_start('', {'curwin' : 1, 'term_finish' : 'close'})"
Bram Moolenaare2e40752020-09-04 21:18:46 +02001187 call assert_fails(cmd, 'E474:')
Bram Moolenaarede35bb2018-01-26 20:05:18 +01001188 let cmd = "call term_start('', {'curwin' : 1, 'term_finish' : 'close'})"
Bram Moolenaare2e40752020-09-04 21:18:46 +02001189 call assert_fails(cmd, 'E474:')
Bram Moolenaarede35bb2018-01-26 20:05:18 +01001190 let cmd = "call term_start({}, {'curwin' : 1, 'term_finish' : 'close'})"
Bram Moolenaare2e40752020-09-04 21:18:46 +02001191 call assert_fails(cmd, 'E474:')
Bram Moolenaarede35bb2018-01-26 20:05:18 +01001192 let cmd = "call term_start(0, {'curwin' : 1, 'term_finish' : 'close'})"
Bram Moolenaare2e40752020-09-04 21:18:46 +02001193 call assert_fails(cmd, 'E474:')
Bram Moolenaarca68ae12020-03-30 19:32:53 +02001194 let cmd = "call term_start('', {'term_name' : []})"
Bram Moolenaare2e40752020-09-04 21:18:46 +02001195 call assert_fails(cmd, 'E730:')
Bram Moolenaarca68ae12020-03-30 19:32:53 +02001196 let cmd = "call term_start('', {'term_finish' : 'axby'})"
Bram Moolenaare2e40752020-09-04 21:18:46 +02001197 call assert_fails(cmd, 'E475:')
Bram Moolenaarca68ae12020-03-30 19:32:53 +02001198 let cmd = "call term_start('', {'eof_chars' : []})"
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001199 call assert_fails(cmd, 'E730:')
Bram Moolenaarca68ae12020-03-30 19:32:53 +02001200 let cmd = "call term_start('', {'term_kill' : []})"
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001201 call assert_fails(cmd, 'E730:')
Bram Moolenaarca68ae12020-03-30 19:32:53 +02001202 let cmd = "call term_start('', {'tty_type' : []})"
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001203 call assert_fails(cmd, 'E730:')
Bram Moolenaarca68ae12020-03-30 19:32:53 +02001204 let cmd = "call term_start('', {'tty_type' : 'abc'})"
1205 call assert_fails(cmd, 'E475:')
1206 let cmd = "call term_start('', {'term_highlight' : []})"
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001207 call assert_fails(cmd, 'E730:')
Bram Moolenaar87202262020-05-24 17:23:45 +02001208 if has('gui') || has('termguicolors')
Bram Moolenaarca68ae12020-03-30 19:32:53 +02001209 let cmd = "call term_start('', {'ansi_colors' : 'abc'})"
1210 call assert_fails(cmd, 'E475:')
1211 let cmd = "call term_start('', {'ansi_colors' : [[]]})"
1212 call assert_fails(cmd, 'E730:')
1213 let cmd = "call term_start('', {'ansi_colors' : repeat(['blue'], 18)})"
Bram Moolenaar87202262020-05-24 17:23:45 +02001214 if has('gui_running') || has('termguicolors')
1215 call assert_fails(cmd, 'E475:')
1216 else
1217 call assert_fails(cmd, 'E254:')
1218 endif
Bram Moolenaarca68ae12020-03-30 19:32:53 +02001219 endif
Bram Moolenaarede35bb2018-01-26 20:05:18 +01001220endfunc
Bram Moolenaarb50773c2018-01-30 22:31:19 +01001221
1222func Test_terminal_response_to_control_sequence()
Bram Moolenaaradbde3f2019-09-08 22:57:14 +02001223 CheckUnix
Bram Moolenaarb50773c2018-01-30 22:31:19 +01001224
1225 let buf = Run_shell_in_terminal({})
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +02001226 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))})
Bram Moolenaarb50773c2018-01-30 22:31:19 +01001227
Bram Moolenaar086eb872018-03-25 21:24:12 +02001228 call term_sendkeys(buf, "cat\<CR>")
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +02001229 call WaitForAssert({-> assert_match('cat', term_getline(buf, 1))})
Bram Moolenaard4a282f2018-02-02 18:22:31 +01001230
Bram Moolenaar086eb872018-03-25 21:24:12 +02001231 " Request the cursor position.
1232 call term_sendkeys(buf, "\x1b[6n\<CR>")
Bram Moolenaard4a282f2018-02-02 18:22:31 +01001233
1234 " Wait for output from tty to display, below an empty line.
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +02001235 call WaitForAssert({-> assert_match('3;1R', term_getline(buf, 4))})
Bram Moolenaarb50773c2018-01-30 22:31:19 +01001236
Bram Moolenaar086eb872018-03-25 21:24:12 +02001237 " End "cat" gently.
1238 call term_sendkeys(buf, "\<CR>\<C-D>")
1239
Bram Moolenaar7a39dd72019-06-23 00:50:15 +02001240 call StopShellInTerminal(buf)
Bram Moolenaarb50773c2018-01-30 22:31:19 +01001241 exe buf . 'bwipe'
1242 unlet g:job
1243endfunc
Bram Moolenaar25cdd9c2018-03-10 20:28:12 +01001244
Bram Moolenaarc2958582021-12-14 11:16:31 +00001245" Run this first, it fails when run after other tests.
1246func Test_aa_terminal_focus_events()
Bram Moolenaara48d4e42021-12-08 22:13:38 +00001247 CheckNotGui
1248 CheckUnix
1249 CheckRunVimInTerminal
1250
1251 let save_term = &term
1252 let save_ttymouse = &ttymouse
1253 set term=xterm ttymouse=xterm2
1254
1255 let lines =<< trim END
1256 set term=xterm ttymouse=xterm2
Bram Moolenaare5050712021-12-09 10:51:05 +00001257 au FocusLost * call setline(1, 'I am lost') | set nomod
1258 au FocusGained * call setline(1, 'I am back') | set nomod
Bram Moolenaara48d4e42021-12-08 22:13:38 +00001259 END
1260 call writefile(lines, 'XtermFocus')
1261 let buf = RunVimInTerminal('-S XtermFocus', #{rows: 6})
1262
1263 " Send a focus event to ourselves, it should be forwarded to the terminal
1264 call feedkeys("\<Esc>[O", "Lx!")
Bram Moolenaara48d4e42021-12-08 22:13:38 +00001265 call VerifyScreenDump(buf, 'Test_terminal_focus_1', {})
1266
1267 call feedkeys("\<Esc>[I", "Lx!")
Bram Moolenaara48d4e42021-12-08 22:13:38 +00001268 call VerifyScreenDump(buf, 'Test_terminal_focus_2', {})
1269
Bram Moolenaare5050712021-12-09 10:51:05 +00001270 " check that a command line being edited is redrawn in place
1271 call term_sendkeys(buf, ":" .. repeat('x', 80))
1272 call TermWait(buf)
1273 call feedkeys("\<Esc>[O", "Lx!")
Bram Moolenaare5050712021-12-09 10:51:05 +00001274 call VerifyScreenDump(buf, 'Test_terminal_focus_3', {})
1275 call term_sendkeys(buf, "\<Esc>")
1276
Bram Moolenaara48d4e42021-12-08 22:13:38 +00001277 call StopVimInTerminal(buf)
1278 call delete('XtermFocus')
1279 let &term = save_term
1280 let &ttymouse = save_ttymouse
1281endfunc
1282
Bram Moolenaar3e8d3852018-03-20 17:43:01 +01001283" Run Vim, start a terminal in that Vim with the kill argument,
1284" :qall works.
1285func Run_terminal_qall_kill(line1, line2)
1286 " 1. Open a terminal window and wait for the prompt to appear
1287 " 2. set kill using term_setkill()
1288 " 3. make Vim exit, it will kill the shell
1289 let after = [
1290 \ a:line1,
1291 \ 'let buf = bufnr("%")',
1292 \ 'while term_getline(buf, 1) =~ "^\\s*$"',
1293 \ ' sleep 10m',
1294 \ 'endwhile',
1295 \ a:line2,
1296 \ 'au VimLeavePre * call writefile(["done"], "Xdone")',
1297 \ 'qall',
1298 \ ]
1299 if !RunVim([], after, '')
Bram Moolenaar25cdd9c2018-03-10 20:28:12 +01001300 return
1301 endif
Bram Moolenaar3e8d3852018-03-20 17:43:01 +01001302 call assert_equal("done", readfile("Xdone")[0])
1303 call delete("Xdone")
Bram Moolenaar25cdd9c2018-03-10 20:28:12 +01001304endfunc
1305
1306" Run Vim in a terminal, then start a terminal in that Vim with a kill
1307" argument, check that :qall works.
Bram Moolenaar3e8d3852018-03-20 17:43:01 +01001308func Test_terminal_qall_kill_arg()
1309 call Run_terminal_qall_kill('term ++kill=kill', '')
1310endfunc
1311
1312" Run Vim, start a terminal in that Vim, set the kill argument with
1313" term_setkill(), check that :qall works.
Bram Moolenaar25cdd9c2018-03-10 20:28:12 +01001314func Test_terminal_qall_kill_func()
Bram Moolenaar7ee80f72019-09-08 20:55:06 +02001315 call Run_terminal_qall_kill('term', 'eval buf->term_setkill("kill")')
Bram Moolenaar3e8d3852018-03-20 17:43:01 +01001316endfunc
1317
1318" Run Vim, start a terminal in that Vim without the kill argument,
1319" check that :qall does not exit, :qall! does.
1320func Test_terminal_qall_exit()
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001321 let after =<< trim [CODE]
1322 term
1323 let buf = bufnr("%")
1324 while term_getline(buf, 1) =~ "^\\s*$"
1325 sleep 10m
1326 endwhile
1327 set nomore
1328 au VimLeavePre * call writefile(["too early"], "Xdone")
1329 qall
1330 au! VimLeavePre * exe buf . "bwipe!" | call writefile(["done"], "Xdone")
1331 cquit
1332 [CODE]
1333
Bram Moolenaar3e8d3852018-03-20 17:43:01 +01001334 if !RunVim([], after, '')
Bram Moolenaar25cdd9c2018-03-10 20:28:12 +01001335 return
1336 endif
Bram Moolenaar3e8d3852018-03-20 17:43:01 +01001337 call assert_equal("done", readfile("Xdone")[0])
1338 call delete("Xdone")
Bram Moolenaar25cdd9c2018-03-10 20:28:12 +01001339endfunc
Bram Moolenaar435acdb2018-03-10 20:51:25 +01001340
1341" Run Vim in a terminal, then start a terminal in that Vim without a kill
1342" argument, check that :confirm qall works.
1343func Test_terminal_qall_prompt()
Bram Moolenaarc2585492019-09-22 21:29:53 +02001344 CheckRunVimInTerminal
Bram Moolenaare564c702022-06-14 15:00:28 +01001345
Bram Moolenaar435acdb2018-03-10 20:51:25 +01001346 let buf = RunVimInTerminal('', {})
1347
Bram Moolenaar99f4b6e2022-06-14 19:52:16 +01001348 " the shell may set the window title, we don't want that here
Bram Moolenaar377d92a2022-06-14 21:22:12 +01001349 call term_sendkeys(buf, ":call test_override('vterm_title', 1)\<CR>")
Bram Moolenaar99f4b6e2022-06-14 19:52:16 +01001350
Bram Moolenaar435acdb2018-03-10 20:51:25 +01001351 " Open a terminal window and wait for the prompt to appear
1352 call term_sendkeys(buf, ":term\<CR>")
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +02001353 call WaitForAssert({-> assert_match('\[running]', term_getline(buf, 10))})
1354 call WaitForAssert({-> assert_notmatch('^\s*$', term_getline(buf, 1))})
Bram Moolenaar435acdb2018-03-10 20:51:25 +01001355
1356 " make Vim exit, it will prompt to kill the shell
1357 call term_sendkeys(buf, "\<C-W>:confirm qall\<CR>")
Yee Cheng Chin15b314f2022-10-09 18:53:32 +01001358 call WaitForAssert({-> assert_match('\[Y\]es, (N)o:', term_getline(buf, 20))})
Bram Moolenaar435acdb2018-03-10 20:51:25 +01001359 call term_sendkeys(buf, "y")
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +02001360 call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))})
Bram Moolenaar435acdb2018-03-10 20:51:25 +01001361
1362 " close the terminal window where Vim was running
1363 quit
1364endfunc
Bram Moolenaarb852c3e2018-03-11 16:55:36 +01001365
Bram Moolenaar4d14bac2019-10-20 21:15:15 +02001366" Run Vim in a terminal, then start a terminal window with a shell and check
1367" that Vim exits if it is closed.
1368func Test_terminal_exit()
1369 CheckRunVimInTerminal
1370
1371 let lines =<< trim END
1372 let winid = win_getid()
1373 help
1374 term
1375 let termid = win_getid()
1376 call win_gotoid(winid)
1377 close
1378 call win_gotoid(termid)
1379 END
1380 call writefile(lines, 'XtermExit')
1381 let buf = RunVimInTerminal('-S XtermExit', #{rows: 10})
1382 let job = term_getjob(buf)
1383 call WaitForAssert({-> assert_equal("run", job_status(job))})
1384
1385 " quit the shell, it will make Vim exit
1386 call term_sendkeys(buf, "exit\<CR>")
1387 call WaitForAssert({-> assert_equal("dead", job_status(job))})
1388
1389 call delete('XtermExit')
1390endfunc
1391
Bram Moolenaar012eb662018-03-13 17:55:27 +01001392func Test_terminal_open_autocmd()
Bram Moolenaarb852c3e2018-03-11 16:55:36 +01001393 augroup repro
1394 au!
1395 au TerminalOpen * let s:called += 1
1396 augroup END
1397
1398 let s:called = 0
1399
1400 " Open a terminal window with :terminal
1401 terminal
1402 call assert_equal(1, s:called)
1403 bwipe!
1404
1405 " Open a terminal window with term_start()
1406 call term_start(&shell)
1407 call assert_equal(2, s:called)
1408 bwipe!
1409
1410 " Open a hidden terminal buffer with :terminal
1411 terminal ++hidden
1412 call assert_equal(3, s:called)
1413 for buf in term_list()
1414 exe buf . "bwipe!"
1415 endfor
1416
1417 " Open a hidden terminal buffer with term_start()
1418 let buf = term_start(&shell, {'hidden': 1})
1419 call assert_equal(4, s:called)
1420 exe buf . "bwipe!"
1421
1422 unlet s:called
1423 au! repro
Bram Moolenaarf4d61bc2020-11-14 14:22:28 +01001424endfunc
1425
1426func Test_open_term_from_cmd()
1427 CheckUnix
1428 CheckRunVimInTerminal
1429
1430 let lines =<< trim END
1431 call setline(1, ['a', 'b', 'c'])
1432 3
1433 set incsearch
1434 cnoremap <F3> <Cmd>call term_start(['/bin/sh', '-c', ':'])<CR>
1435 END
1436 call writefile(lines, 'Xopenterm')
1437 let buf = RunVimInTerminal('-S Xopenterm', {})
1438
1439 " this opens a window, incsearch should not use the old cursor position
1440 call term_sendkeys(buf, "/\<F3>")
1441 call VerifyScreenDump(buf, 'Test_terminal_from_cmd', {})
1442 call term_sendkeys(buf, "\<Esc>")
1443 call term_sendkeys(buf, ":q\<CR>")
1444
1445 call StopVimInTerminal(buf)
1446 call delete('Xopenterm')
1447endfunc
Bram Moolenaar45d2a642018-03-24 14:30:32 +01001448
Bram Moolenaar4549dad2021-02-08 21:29:48 +01001449func Test_combining_double_width()
1450 CheckUnix
1451 CheckRunVimInTerminal
1452
1453 call writefile(["\xe3\x83\x9b\xe3\x82\x9a"], 'Xonedouble')
1454 let lines =<< trim END
1455 call term_start(['/bin/sh', '-c', 'cat Xonedouble'])
1456 END
1457 call writefile(lines, 'Xcombining')
1458 let buf = RunVimInTerminal('-S Xcombining', #{rows: 9})
1459
1460 " this opens a window, incsearch should not use the old cursor position
1461 call VerifyScreenDump(buf, 'Test_terminal_combining', {})
1462 call term_sendkeys(buf, ":q\<CR>")
1463
1464 call StopVimInTerminal(buf)
1465 call delete('Xonedouble')
1466 call delete('Xcombining')
1467endfunc
1468
Bram Moolenaar02764712020-11-14 20:21:55 +01001469func Test_terminal_popup_with_cmd()
1470 " this was crashing
1471 let buf = term_start(&shell, #{hidden: v:true})
1472 let s:winid = popup_create(buf, {})
1473 tnoremap <F3> <Cmd>call popup_close(s:winid)<CR>
1474 call feedkeys("\<F3>", 'xt')
1475
1476 tunmap <F3>
1477 exe 'bwipe! ' .. buf
1478 unlet s:winid
1479endfunc
1480
Bram Moolenaar8adc8d92020-11-16 20:47:31 +01001481func Test_terminal_popup_bufload()
1482 let termbuf = term_start(&shell, #{hidden: v:true, term_finish: 'close'})
1483 let winid = popup_create(termbuf, {})
1484 sleep 50m
1485
1486 let newbuf = bufadd('')
1487 call bufload(newbuf)
1488 call setbufline(newbuf, 1, 'foobar')
1489
1490 " must not have switched to another window
1491 call assert_equal(winid, win_getid())
1492
Bram Moolenaare6329e42020-11-16 21:10:34 +01001493 call StopShellInTerminal(termbuf)
1494 call WaitFor({-> win_getid() != winid})
Bram Moolenaar8adc8d92020-11-16 20:47:31 +01001495 exe 'bwipe! ' .. newbuf
1496endfunc
1497
Bram Moolenaar3194e5b2021-12-13 21:59:09 +00001498func Test_terminal_popup_two_windows()
Bram Moolenaar0407d272021-12-13 22:17:44 +00001499 CheckRunVimInTerminal
Bram Moolenaar3194e5b2021-12-13 21:59:09 +00001500 CheckUnix
1501
1502 " use "sh" instead of "&shell" in the hope it will use a short prompt
1503 let lines =<< trim END
1504 let termbuf = term_start('sh', #{hidden: v:true, term_finish: 'close'})
1505 exe 'buffer ' .. termbuf
1506
1507 let winid = popup_create(termbuf, #{line: 2, minwidth: 30, border: []})
1508 sleep 50m
1509
1510 call term_sendkeys(termbuf, "echo 'test'")
1511 END
1512 call writefile(lines, 'XpopupScript')
1513 let buf = RunVimInTerminal('-S XpopupScript', {})
1514
1515 " typed text appears both in normal window and in popup
1516 call WaitForAssert({-> assert_match("echo 'test'", term_getline(buf, 1))})
1517 call WaitForAssert({-> assert_match("echo 'test'", term_getline(buf, 3))})
1518
Bram Moolenaar0407d272021-12-13 22:17:44 +00001519 call term_sendkeys(buf, "\<CR>\<CR>exit\<CR>")
1520 call TermWait(buf)
1521 call term_sendkeys(buf, ":q\<CR>")
Bram Moolenaar3194e5b2021-12-13 21:59:09 +00001522 call StopVimInTerminal(buf)
1523 call delete('XpopupScript')
1524endfunc
1525
Bram Moolenaare41decc2020-11-14 21:34:59 +01001526func Test_terminal_popup_insert_cmd()
1527 CheckUnix
1528
1529 inoremap <F3> <Cmd>call StartTermInPopup()<CR>
1530 func StartTermInPopup()
Bram Moolenaar27f4f6b2020-11-16 21:02:28 +01001531 call term_start(['/bin/sh', '-c', 'cat'], #{hidden: v:true, term_finish: 'close'})->popup_create(#{highlight: 'Pmenu'})
Bram Moolenaare41decc2020-11-14 21:34:59 +01001532 endfunc
1533 call feedkeys("i\<F3>")
1534 sleep 10m
1535 call assert_equal('n', mode())
1536
1537 call feedkeys("\<C-D>", 'xt')
Bram Moolenaar17ab28d2020-11-18 12:24:01 +01001538 call WaitFor({-> popup_list() == []})
Bram Moolenaare41decc2020-11-14 21:34:59 +01001539 delfunc StartTermInPopup
1540 iunmap <F3>
1541endfunc
1542
Bram Moolenaar45d2a642018-03-24 14:30:32 +01001543func Check_dump01(off)
1544 call assert_equal('one two three four five', trim(getline(a:off + 1)))
1545 call assert_equal('~ Select Word', trim(getline(a:off + 7)))
Bram Moolenaar1834d372018-03-29 17:40:46 +02001546 call assert_equal(':popup PopUp', trim(getline(a:off + 20)))
Bram Moolenaar45d2a642018-03-24 14:30:32 +01001547endfunc
1548
Bram Moolenaarf06b0b62018-03-29 17:22:24 +02001549func Test_terminal_dumpwrite_composing()
Bram Moolenaarc2585492019-09-22 21:29:53 +02001550 CheckRunVimInTerminal
Bram Moolenaar3194e5b2021-12-13 21:59:09 +00001551
Bram Moolenaarf06b0b62018-03-29 17:22:24 +02001552 let save_enc = &encoding
1553 set encoding=utf-8
1554 call assert_equal(1, winnr('$'))
1555
1556 let text = " a\u0300 e\u0302 o\u0308"
1557 call writefile([text], 'Xcomposing')
Bram Moolenaar77bfd752018-04-30 18:03:10 +02001558 let buf = RunVimInTerminal('--cmd "set encoding=utf-8" Xcomposing', {})
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +02001559 call WaitForAssert({-> assert_match(text, term_getline(buf, 1))})
Bram Moolenaar7ee80f72019-09-08 20:55:06 +02001560 eval 'Xdump'->term_dumpwrite(buf)
Bram Moolenaarf06b0b62018-03-29 17:22:24 +02001561 let dumpline = readfile('Xdump')[0]
1562 call assert_match('|à| |ê| |ö', dumpline)
1563
1564 call StopVimInTerminal(buf)
1565 call delete('Xcomposing')
1566 call delete('Xdump')
1567 let &encoding = save_enc
1568endfunc
1569
Bram Moolenaar91689ea2020-05-11 22:04:53 +02001570" Tests for failures in the term_dumpwrite() function
1571func Test_terminal_dumpwrite_errors()
1572 CheckRunVimInTerminal
1573 call assert_fails("call term_dumpwrite({}, 'Xtest.dump')", 'E728:')
1574 let buf = RunVimInTerminal('', {})
Bram Moolenaar733d2592020-08-20 18:59:06 +02001575 call TermWait(buf)
Yegappan Lakshmanan04c4c572022-08-30 19:48:24 +01001576 call assert_fails("call term_dumpwrite(buf, 'Xtest.dump', '')", 'E1206:')
Bram Moolenaar91689ea2020-05-11 22:04:53 +02001577 call assert_fails("call term_dumpwrite(buf, [])", 'E730:')
1578 call writefile([], 'Xtest.dump')
1579 call assert_fails("call term_dumpwrite(buf, 'Xtest.dump')", 'E953:')
1580 call delete('Xtest.dump')
1581 call assert_fails("call term_dumpwrite(buf, '')", 'E482:')
1582 call assert_fails("call term_dumpwrite(buf, test_null_string())", 'E482:')
Bram Moolenaar98f16712020-05-22 13:34:01 +02001583 call test_garbagecollect_now()
Bram Moolenaara46765a2020-11-01 20:58:26 +01001584 call StopVimInTerminal(buf, 0)
Bram Moolenaar733d2592020-08-20 18:59:06 +02001585 call TermWait(buf)
Bram Moolenaar91689ea2020-05-11 22:04:53 +02001586 call assert_fails("call term_dumpwrite(buf, 'Xtest.dump')", 'E958:')
1587 call assert_fails('call term_sendkeys([], ":q\<CR>")', 'E745:')
1588 call assert_equal(0, term_sendkeys(buf, ":q\<CR>"))
1589endfunc
1590
Bram Moolenaar45d2a642018-03-24 14:30:32 +01001591" just testing basic functionality.
1592func Test_terminal_dumpload()
Bram Moolenaar87abab92019-06-03 21:14:59 +02001593 let curbuf = winbufnr('')
Bram Moolenaar45d2a642018-03-24 14:30:32 +01001594 call assert_equal(1, winnr('$'))
Bram Moolenaar87abab92019-06-03 21:14:59 +02001595 let buf = term_dumpload('dumps/Test_popup_command_01.dump')
Bram Moolenaar45d2a642018-03-24 14:30:32 +01001596 call assert_equal(2, winnr('$'))
1597 call assert_equal(20, line('$'))
1598 call Check_dump01(0)
Bram Moolenaar87abab92019-06-03 21:14:59 +02001599
1600 " Load another dump in the same window
Bram Moolenaar7ee80f72019-09-08 20:55:06 +02001601 let buf2 = 'dumps/Test_diff_01.dump'->term_dumpload({'bufnr': buf})
Bram Moolenaar87abab92019-06-03 21:14:59 +02001602 call assert_equal(buf, buf2)
1603 call assert_notequal('one two three four five', trim(getline(1)))
1604
1605 " Load the first dump again in the same window
1606 let buf2 = term_dumpload('dumps/Test_popup_command_01.dump', {'bufnr': buf})
1607 call assert_equal(buf, buf2)
1608 call Check_dump01(0)
1609
1610 call assert_fails("call term_dumpload('dumps/Test_popup_command_01.dump', {'bufnr': curbuf})", 'E475:')
1611 call assert_fails("call term_dumpload('dumps/Test_popup_command_01.dump', {'bufnr': 9999})", 'E86:')
1612 new
1613 let closedbuf = winbufnr('')
1614 quit
1615 call assert_fails("call term_dumpload('dumps/Test_popup_command_01.dump', {'bufnr': closedbuf})", 'E475:')
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001616 call assert_fails('call term_dumpload([])', 'E730:')
Bram Moolenaar91689ea2020-05-11 22:04:53 +02001617 call assert_fails('call term_dumpload("xabcy.dump")', 'E485:')
Bram Moolenaar87abab92019-06-03 21:14:59 +02001618
Bram Moolenaar45d2a642018-03-24 14:30:32 +01001619 quit
1620endfunc
1621
Bram Moolenaar17efc7f2019-10-16 18:11:31 +02001622func Test_terminal_dumpload_dump()
1623 CheckRunVimInTerminal
1624
1625 let lines =<< trim END
1626 call term_dumpload('dumps/Test_popupwin_22.dump', #{term_rows: 12})
1627 END
1628 call writefile(lines, 'XtermDumpload')
1629 let buf = RunVimInTerminal('-S XtermDumpload', #{rows: 15})
1630 call VerifyScreenDump(buf, 'Test_terminal_dumpload', {})
1631
1632 call StopVimInTerminal(buf)
1633 call delete('XtermDumpload')
1634endfunc
1635
Bram Moolenaar45d2a642018-03-24 14:30:32 +01001636func Test_terminal_dumpdiff()
1637 call assert_equal(1, winnr('$'))
Bram Moolenaar7ee80f72019-09-08 20:55:06 +02001638 eval 'dumps/Test_popup_command_01.dump'->term_dumpdiff('dumps/Test_popup_command_02.dump')
Bram Moolenaar45d2a642018-03-24 14:30:32 +01001639 call assert_equal(2, winnr('$'))
1640 call assert_equal(62, line('$'))
1641 call Check_dump01(0)
1642 call Check_dump01(42)
1643 call assert_equal(' bbbbbbbbbbbbbbbbbb ', getline(26)[0:29])
1644 quit
Bram Moolenaar91689ea2020-05-11 22:04:53 +02001645
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001646 call assert_fails('call term_dumpdiff("X1.dump", [])', 'E730:')
Bram Moolenaar91689ea2020-05-11 22:04:53 +02001647 call assert_fails('call term_dumpdiff("X1.dump", "X2.dump")', 'E485:')
1648 call writefile([], 'X1.dump')
1649 call assert_fails('call term_dumpdiff("X1.dump", "X2.dump")', 'E485:')
1650 call delete('X1.dump')
Bram Moolenaar45d2a642018-03-24 14:30:32 +01001651endfunc
Bram Moolenaar897e63c2018-03-24 17:16:33 +01001652
Bram Moolenaarc3ef8962019-02-15 00:16:13 +01001653func Test_terminal_dumpdiff_swap()
1654 call assert_equal(1, winnr('$'))
1655 call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_03.dump')
1656 call assert_equal(2, winnr('$'))
1657 call assert_equal(62, line('$'))
1658 call assert_match('Test_popup_command_01.dump', getline(21))
1659 call assert_match('Test_popup_command_03.dump', getline(42))
1660 call assert_match('Undo', getline(3))
1661 call assert_match('three four five', getline(45))
1662
1663 normal s
1664 call assert_match('Test_popup_command_03.dump', getline(21))
1665 call assert_match('Test_popup_command_01.dump', getline(42))
1666 call assert_match('three four five', getline(3))
1667 call assert_match('Undo', getline(45))
1668 quit
Bram Moolenaar98f16712020-05-22 13:34:01 +02001669
1670 " Diff two terminal dump files with different number of rows
1671 " Swap the diffs
1672 call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_winline_rnu.dump')
1673 call assert_match('Test_popup_command_01.dump', getline(21))
1674 call assert_match('Test_winline_rnu.dump', getline(42))
1675 normal s
1676 call assert_match('Test_winline_rnu.dump', getline(6))
1677 call assert_match('Test_popup_command_01.dump', getline(27))
1678 quit
Bram Moolenaarc3ef8962019-02-15 00:16:13 +01001679endfunc
1680
Bram Moolenaar897e63c2018-03-24 17:16:33 +01001681func Test_terminal_dumpdiff_options()
1682 set laststatus=0
1683 call assert_equal(1, winnr('$'))
1684 let height = winheight(0)
1685 call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump', {'vertical': 1, 'term_cols': 33})
1686 call assert_equal(2, winnr('$'))
1687 call assert_equal(height, winheight(winnr()))
1688 call assert_equal(33, winwidth(winnr()))
1689 call assert_equal('dump diff dumps/Test_popup_command_01.dump', bufname('%'))
1690 quit
1691
1692 call assert_equal(1, winnr('$'))
Bram Moolenaar897e63c2018-03-24 17:16:33 +01001693 call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump', {'vertical': 0, 'term_rows': 13, 'term_name': 'something else'})
1694 call assert_equal(2, winnr('$'))
Bram Moolenaare809a4e2019-07-04 17:35:05 +02001695 call assert_equal(&columns, winwidth(0))
1696 call assert_equal(13, winheight(0))
Bram Moolenaar897e63c2018-03-24 17:16:33 +01001697 call assert_equal('something else', bufname('%'))
1698 quit
1699
1700 call assert_equal(1, winnr('$'))
1701 call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump', {'curwin': 1})
1702 call assert_equal(1, winnr('$'))
Bram Moolenaarca68ae12020-03-30 19:32:53 +02001703 call assert_fails("call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump', {'bufnr': -1})", 'E475:')
Bram Moolenaar897e63c2018-03-24 17:16:33 +01001704 bwipe
1705
1706 set laststatus&
1707endfunc
Bram Moolenaar8fbaeb12018-03-25 18:20:17 +02001708
Bram Moolenaar10772302019-01-20 18:25:54 +01001709" When drawing the statusline the cursor position may not have been updated
1710" yet.
1711" 1. create a terminal, make it show 2 lines
1712" 2. 0.5 sec later: leave terminal window, execute "i"
1713" 3. 0.5 sec later: clear terminal window, now it's 1 line
1714" 4. 0.5 sec later: redraw, including statusline (used to trigger bug)
1715" 4. 0.5 sec later: should be done, clean up
1716func Test_terminal_statusline()
Bram Moolenaaradbde3f2019-09-08 22:57:14 +02001717 CheckUnix
Bram Moolenaar81035272021-12-16 18:02:07 +00001718 CheckFeature timers
Bram Moolenaaradbde3f2019-09-08 22:57:14 +02001719
Bram Moolenaar10772302019-01-20 18:25:54 +01001720 set statusline=x
1721 terminal
1722 let tbuf = bufnr('')
1723 call term_sendkeys(tbuf, "clear; echo a; echo b; sleep 1; clear\n")
1724 call timer_start(500, { tid -> feedkeys("\<C-w>j", 'tx') })
1725 call timer_start(1500, { tid -> feedkeys("\<C-l>", 'tx') })
1726 au BufLeave * if &buftype == 'terminal' | silent! normal i | endif
1727
1728 sleep 2
1729 exe tbuf . 'bwipe!'
1730 au! BufLeave
1731 set statusline=
1732endfunc
Bram Moolenaarfa1e90c2019-04-06 17:47:40 +02001733
Bram Moolenaar81035272021-12-16 18:02:07 +00001734func CheckTerminalWindowWorks(buf)
1735 call WaitForAssert({-> assert_match('!sh \[running\]', term_getline(a:buf, 10))})
1736 call term_sendkeys(a:buf, "exit\<CR>")
1737 call WaitForAssert({-> assert_match('!sh \[finished\]', term_getline(a:buf, 10))})
1738 call term_sendkeys(a:buf, ":q\<CR>")
1739 call WaitForAssert({-> assert_match('^\~', term_getline(a:buf, 10))})
1740endfunc
1741
1742func Test_start_terminal_from_timer()
1743 CheckUnix
1744 CheckFeature timers
1745
1746 " Open a terminal window from a timer, typed text goes to the terminal
1747 call writefile(["call timer_start(100, { -> term_start('sh') })"], 'XtimerTerm')
1748 let buf = RunVimInTerminal('-S XtimerTerm', {})
1749 call CheckTerminalWindowWorks(buf)
1750
1751 " do the same in Insert mode
1752 call term_sendkeys(buf, ":call timer_start(200, { -> term_start('sh') })\<CR>a")
1753 call CheckTerminalWindowWorks(buf)
1754
1755 call StopVimInTerminal(buf)
1756 call delete('XtimerTerm')
1757endfunc
1758
Bram Moolenaarf43e7ac2020-09-29 21:23:25 +02001759func Test_terminal_window_focus()
1760 let winid1 = win_getid()
1761 terminal
1762 let winid2 = win_getid()
1763 call feedkeys("\<C-W>j", 'xt')
1764 call assert_equal(winid1, win_getid())
1765 call feedkeys("\<C-W>k", 'xt')
1766 call assert_equal(winid2, win_getid())
1767 " can use a cursor key here
1768 call feedkeys("\<C-W>\<Down>", 'xt')
1769 call assert_equal(winid1, win_getid())
1770 call feedkeys("\<C-W>\<Up>", 'xt')
1771 call assert_equal(winid2, win_getid())
1772
1773 bwipe!
1774endfunc
1775
Bram Moolenaar18aa13d2020-07-11 13:09:36 +02001776func Api_drop_common(options)
1777 call assert_equal(1, winnr('$'))
1778
1779 " Use the title termcap entries to output the escape sequence.
1780 call writefile([
1781 \ 'set title',
1782 \ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"',
1783 \ 'let &titlestring = ''["drop","Xtextfile"' . a:options . ']''',
1784 \ 'redraw',
1785 \ "set t_ts=",
1786 \ ], 'Xscript')
1787 let buf = RunVimInTerminal('-S Xscript', {})
1788 call WaitFor({-> bufnr('Xtextfile') > 0})
1789 call assert_equal('Xtextfile', expand('%:t'))
1790 call assert_true(winnr('$') >= 3)
1791 return buf
1792endfunc
1793
1794func Test_terminal_api_drop_newwin()
1795 CheckRunVimInTerminal
1796 let buf = Api_drop_common('')
1797 call assert_equal(0, &bin)
1798 call assert_equal('', &fenc)
1799
1800 call StopVimInTerminal(buf)
1801 call delete('Xscript')
1802 bwipe Xtextfile
1803endfunc
1804
1805func Test_terminal_api_drop_newwin_bin()
1806 CheckRunVimInTerminal
1807 let buf = Api_drop_common(',{"bin":1}')
1808 call assert_equal(1, &bin)
1809
1810 call StopVimInTerminal(buf)
1811 call delete('Xscript')
1812 bwipe Xtextfile
1813endfunc
1814
1815func Test_terminal_api_drop_newwin_binary()
1816 CheckRunVimInTerminal
1817 let buf = Api_drop_common(',{"binary":1}')
1818 call assert_equal(1, &bin)
1819
1820 call StopVimInTerminal(buf)
1821 call delete('Xscript')
1822 bwipe Xtextfile
1823endfunc
1824
1825func Test_terminal_api_drop_newwin_nobin()
1826 CheckRunVimInTerminal
1827 set binary
1828 let buf = Api_drop_common(',{"nobin":1}')
1829 call assert_equal(0, &bin)
1830
1831 call StopVimInTerminal(buf)
1832 call delete('Xscript')
1833 bwipe Xtextfile
1834 set nobinary
1835endfunc
1836
1837func Test_terminal_api_drop_newwin_nobinary()
1838 CheckRunVimInTerminal
1839 set binary
1840 let buf = Api_drop_common(',{"nobinary":1}')
1841 call assert_equal(0, &bin)
1842
1843 call StopVimInTerminal(buf)
1844 call delete('Xscript')
1845 bwipe Xtextfile
1846 set nobinary
1847endfunc
1848
1849func Test_terminal_api_drop_newwin_ff()
1850 CheckRunVimInTerminal
1851 let buf = Api_drop_common(',{"ff":"dos"}')
1852 call assert_equal("dos", &ff)
1853
1854 call StopVimInTerminal(buf)
1855 call delete('Xscript')
1856 bwipe Xtextfile
1857endfunc
1858
1859func Test_terminal_api_drop_newwin_fileformat()
1860 CheckRunVimInTerminal
1861 let buf = Api_drop_common(',{"fileformat":"dos"}')
1862 call assert_equal("dos", &ff)
1863
1864 call StopVimInTerminal(buf)
1865 call delete('Xscript')
1866 bwipe Xtextfile
1867endfunc
1868
1869func Test_terminal_api_drop_newwin_enc()
1870 CheckRunVimInTerminal
1871 let buf = Api_drop_common(',{"enc":"utf-16"}')
1872 call assert_equal("utf-16", &fenc)
1873
1874 call StopVimInTerminal(buf)
1875 call delete('Xscript')
1876 bwipe Xtextfile
1877endfunc
1878
1879func Test_terminal_api_drop_newwin_encoding()
1880 CheckRunVimInTerminal
1881 let buf = Api_drop_common(',{"encoding":"utf-16"}')
1882 call assert_equal("utf-16", &fenc)
1883
1884 call StopVimInTerminal(buf)
1885 call delete('Xscript')
1886 bwipe Xtextfile
1887endfunc
1888
1889func Test_terminal_api_drop_oldwin()
1890 CheckRunVimInTerminal
1891 let firstwinid = win_getid()
1892 split Xtextfile
1893 let textfile_winid = win_getid()
1894 call assert_equal(2, winnr('$'))
1895 call win_gotoid(firstwinid)
1896
1897 " Use the title termcap entries to output the escape sequence.
1898 call writefile([
1899 \ 'set title',
1900 \ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"',
1901 \ 'let &titlestring = ''["drop","Xtextfile"]''',
1902 \ 'redraw',
1903 \ "set t_ts=",
1904 \ ], 'Xscript')
1905 let buf = RunVimInTerminal('-S Xscript', {'rows': 10})
1906 call WaitForAssert({-> assert_equal('Xtextfile', expand('%:t'))})
1907 call assert_equal(textfile_winid, win_getid())
1908
1909 call StopVimInTerminal(buf)
1910 call delete('Xscript')
1911 bwipe Xtextfile
1912endfunc
1913
1914func Tapi_TryThis(bufnum, arg)
1915 let g:called_bufnum = a:bufnum
1916 let g:called_arg = a:arg
1917endfunc
1918
1919func WriteApiCall(funcname)
1920 " Use the title termcap entries to output the escape sequence.
1921 call writefile([
1922 \ 'set title',
1923 \ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"',
1924 \ 'let &titlestring = ''["call","' . a:funcname . '",["hello",123]]''',
1925 \ 'redraw',
1926 \ "set t_ts=",
1927 \ ], 'Xscript')
1928endfunc
1929
1930func Test_terminal_api_call()
1931 CheckRunVimInTerminal
1932
1933 unlet! g:called_bufnum
1934 unlet! g:called_arg
1935
1936 call WriteApiCall('Tapi_TryThis')
1937
1938 " Default
1939 let buf = RunVimInTerminal('-S Xscript', {})
1940 call WaitFor({-> exists('g:called_bufnum')})
1941 call assert_equal(buf, g:called_bufnum)
1942 call assert_equal(['hello', 123], g:called_arg)
1943 call StopVimInTerminal(buf)
1944
1945 unlet! g:called_bufnum
1946 unlet! g:called_arg
1947
1948 " Enable explicitly
1949 let buf = RunVimInTerminal('-S Xscript', {'term_api': 'Tapi_Try'})
1950 call WaitFor({-> exists('g:called_bufnum')})
1951 call assert_equal(buf, g:called_bufnum)
1952 call assert_equal(['hello', 123], g:called_arg)
1953 call StopVimInTerminal(buf)
1954
1955 unlet! g:called_bufnum
1956 unlet! g:called_arg
1957
1958 func! ApiCall_TryThis(bufnum, arg)
1959 let g:called_bufnum2 = a:bufnum
1960 let g:called_arg2 = a:arg
1961 endfunc
1962
1963 call WriteApiCall('ApiCall_TryThis')
1964
1965 " Use prefix match
1966 let buf = RunVimInTerminal('-S Xscript', {'term_api': 'ApiCall_'})
1967 call WaitFor({-> exists('g:called_bufnum2')})
1968 call assert_equal(buf, g:called_bufnum2)
1969 call assert_equal(['hello', 123], g:called_arg2)
1970 call StopVimInTerminal(buf)
1971
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001972 call assert_fails("call term_start('ls', {'term_api' : []})", 'E730:')
Bram Moolenaar18aa13d2020-07-11 13:09:36 +02001973
1974 unlet! g:called_bufnum2
1975 unlet! g:called_arg2
1976
1977 call delete('Xscript')
1978 delfunction! ApiCall_TryThis
1979 unlet! g:called_bufnum2
1980 unlet! g:called_arg2
1981endfunc
1982
1983func Test_terminal_api_call_fails()
1984 CheckRunVimInTerminal
1985
1986 func! TryThis(bufnum, arg)
1987 let g:called_bufnum3 = a:bufnum
1988 let g:called_arg3 = a:arg
1989 endfunc
1990
1991 call WriteApiCall('TryThis')
1992
1993 unlet! g:called_bufnum3
1994 unlet! g:called_arg3
1995
1996 " Not permitted
1997 call ch_logfile('Xlog', 'w')
1998 let buf = RunVimInTerminal('-S Xscript', {'term_api': ''})
1999 call WaitForAssert({-> assert_match('Unpermitted function: TryThis', string(readfile('Xlog')))})
2000 call assert_false(exists('g:called_bufnum3'))
2001 call assert_false(exists('g:called_arg3'))
2002 call StopVimInTerminal(buf)
2003
2004 " No match
2005 call ch_logfile('Xlog', 'w')
2006 let buf = RunVimInTerminal('-S Xscript', {'term_api': 'TryThat'})
2007 call WaitFor({-> string(readfile('Xlog')) =~ 'Unpermitted function: TryThis'})
2008 call assert_false(exists('g:called_bufnum3'))
2009 call assert_false(exists('g:called_arg3'))
2010 call StopVimInTerminal(buf)
2011
2012 call delete('Xscript')
2013 call ch_logfile('')
2014 call delete('Xlog')
2015 delfunction! TryThis
2016 unlet! g:called_bufnum3
2017 unlet! g:called_arg3
2018endfunc
2019
2020let s:caught_e937 = 0
2021
2022func Tapi_Delete(bufnum, arg)
2023 try
2024 execute 'bdelete!' a:bufnum
2025 catch /E937:/
2026 let s:caught_e937 = 1
2027 endtry
2028endfunc
2029
2030func Test_terminal_api_call_fail_delete()
2031 CheckRunVimInTerminal
2032
2033 call WriteApiCall('Tapi_Delete')
2034 let buf = RunVimInTerminal('-S Xscript', {})
2035 call WaitForAssert({-> assert_equal(1, s:caught_e937)})
2036
2037 call StopVimInTerminal(buf)
2038 call delete('Xscript')
2039 call ch_logfile('', '')
2040endfunc
2041
2042func Test_terminal_setapi_and_call()
2043 CheckRunVimInTerminal
2044
2045 call WriteApiCall('Tapi_TryThis')
2046 call ch_logfile('Xlog', 'w')
2047
2048 unlet! g:called_bufnum
2049 unlet! g:called_arg
2050
2051 let buf = RunVimInTerminal('-S Xscript', {'term_api': ''})
2052 call WaitForAssert({-> assert_match('Unpermitted function: Tapi_TryThis', string(readfile('Xlog')))})
2053 call assert_false(exists('g:called_bufnum'))
2054 call assert_false(exists('g:called_arg'))
2055
2056 eval buf->term_setapi('Tapi_')
2057 call term_sendkeys(buf, ":set notitle\<CR>")
2058 call term_sendkeys(buf, ":source Xscript\<CR>")
2059 call WaitFor({-> exists('g:called_bufnum')})
2060 call assert_equal(buf, g:called_bufnum)
2061 call assert_equal(['hello', 123], g:called_arg)
2062
2063 call StopVimInTerminal(buf)
2064
2065 call delete('Xscript')
2066 call ch_logfile('')
2067 call delete('Xlog')
2068 unlet! g:called_bufnum
2069 unlet! g:called_arg
2070endfunc
2071
2072func Test_terminal_api_arg()
2073 CheckRunVimInTerminal
2074
2075 call WriteApiCall('Tapi_TryThis')
2076 call ch_logfile('Xlog', 'w')
2077
2078 unlet! g:called_bufnum
2079 unlet! g:called_arg
2080
2081 execute 'term ++api= ' .. GetVimCommandCleanTerm() .. '-S Xscript'
2082 let buf = bufnr('%')
2083 call WaitForAssert({-> assert_match('Unpermitted function: Tapi_TryThis', string(readfile('Xlog')))})
2084 call assert_false(exists('g:called_bufnum'))
2085 call assert_false(exists('g:called_arg'))
2086
2087 call StopVimInTerminal(buf)
2088
2089 call ch_logfile('Xlog', 'w')
2090
2091 execute 'term ++api=Tapi_ ' .. GetVimCommandCleanTerm() .. '-S Xscript'
2092 let buf = bufnr('%')
2093 call WaitFor({-> exists('g:called_bufnum')})
2094 call assert_equal(buf, g:called_bufnum)
2095 call assert_equal(['hello', 123], g:called_arg)
2096
2097 call StopVimInTerminal(buf)
2098
2099 call delete('Xscript')
2100 call ch_logfile('')
2101 call delete('Xlog')
2102 unlet! g:called_bufnum
2103 unlet! g:called_arg
2104endfunc
2105
2106func Test_terminal_ansicolors_default()
2107 CheckFunction term_getansicolors
2108
2109 let colors = [
2110 \ '#000000', '#e00000',
2111 \ '#00e000', '#e0e000',
2112 \ '#0000e0', '#e000e0',
2113 \ '#00e0e0', '#e0e0e0',
2114 \ '#808080', '#ff4040',
2115 \ '#40ff40', '#ffff40',
2116 \ '#4040ff', '#ff40ff',
2117 \ '#40ffff', '#ffffff',
2118 \]
2119
2120 let buf = Run_shell_in_terminal({})
2121 call assert_equal(colors, term_getansicolors(buf))
2122 call StopShellInTerminal(buf)
Bram Moolenaar18aa13d2020-07-11 13:09:36 +02002123 call assert_equal([], term_getansicolors(buf))
2124
2125 exe buf . 'bwipe'
2126endfunc
2127
2128let s:test_colors = [
2129 \ '#616e64', '#0d0a79',
2130 \ '#6d610d', '#0a7373',
2131 \ '#690d0a', '#6d696e',
2132 \ '#0d0a6f', '#616e0d',
2133 \ '#0a6479', '#6d0d0a',
2134 \ '#617373', '#0d0a69',
2135 \ '#6d690d', '#0a6e6f',
2136 \ '#610d0a', '#6e6479',
2137 \]
2138
2139func Test_terminal_ansicolors_global()
2140 CheckFeature termguicolors
2141 CheckFunction term_getansicolors
2142
LemonBoyb2b3acb2022-05-20 10:10:34 +01002143 if has('vtp') && !has('vcon') && !has('gui_running')
2144 throw 'Skipped: does not support termguicolors'
2145 endif
2146
2147 set tgc
Bram Moolenaar18aa13d2020-07-11 13:09:36 +02002148 let g:terminal_ansi_colors = reverse(copy(s:test_colors))
2149 let buf = Run_shell_in_terminal({})
2150 call assert_equal(g:terminal_ansi_colors, term_getansicolors(buf))
2151 call StopShellInTerminal(buf)
LemonBoyb2b3acb2022-05-20 10:10:34 +01002152 set tgc&
Bram Moolenaar18aa13d2020-07-11 13:09:36 +02002153
2154 exe buf . 'bwipe'
2155 unlet g:terminal_ansi_colors
2156endfunc
2157
2158func Test_terminal_ansicolors_func()
2159 CheckFeature termguicolors
2160 CheckFunction term_getansicolors
2161
LemonBoyb2b3acb2022-05-20 10:10:34 +01002162 if has('vtp') && !has('vcon') && !has('gui_running')
2163 throw 'Skipped: does not support termguicolors'
2164 endif
2165
2166 set tgc
Bram Moolenaar18aa13d2020-07-11 13:09:36 +02002167 let g:terminal_ansi_colors = reverse(copy(s:test_colors))
2168 let buf = Run_shell_in_terminal({'ansi_colors': s:test_colors})
2169 call assert_equal(s:test_colors, term_getansicolors(buf))
2170
2171 call term_setansicolors(buf, g:terminal_ansi_colors)
2172 call assert_equal(g:terminal_ansi_colors, buf->term_getansicolors())
2173
2174 let colors = [
2175 \ 'ivory', 'AliceBlue',
2176 \ 'grey67', 'dark goldenrod',
2177 \ 'SteelBlue3', 'PaleVioletRed4',
2178 \ 'MediumPurple2', 'yellow2',
2179 \ 'RosyBrown3', 'OrangeRed2',
2180 \ 'white smoke', 'navy blue',
2181 \ 'grey47', 'gray97',
2182 \ 'MistyRose2', 'DodgerBlue4',
2183 \]
2184 eval buf->term_setansicolors(colors)
2185
2186 let colors[4] = 'Invalid'
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02002187 call assert_fails('call term_setansicolors(buf, colors)', 'E254:')
Bram Moolenaard83392a2022-09-01 12:22:46 +01002188 call assert_fails('call term_setansicolors(buf, {})', 'E1211:')
LemonBoyb2b3acb2022-05-20 10:10:34 +01002189 set tgc&
Bram Moolenaar18aa13d2020-07-11 13:09:36 +02002190
2191 call StopShellInTerminal(buf)
Bram Moolenaar18aa13d2020-07-11 13:09:36 +02002192 call assert_equal(0, term_setansicolors(buf, []))
2193 exe buf . 'bwipe'
2194endfunc
2195
2196func Test_terminal_all_ansi_colors()
2197 CheckRunVimInTerminal
2198
2199 " Use all the ANSI colors.
2200 call writefile([
2201 \ 'call setline(1, "AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPP XXYYZZ")',
2202 \ 'hi Tblack ctermfg=0 ctermbg=8',
2203 \ 'hi Tdarkred ctermfg=1 ctermbg=9',
2204 \ 'hi Tdarkgreen ctermfg=2 ctermbg=10',
2205 \ 'hi Tbrown ctermfg=3 ctermbg=11',
2206 \ 'hi Tdarkblue ctermfg=4 ctermbg=12',
2207 \ 'hi Tdarkmagenta ctermfg=5 ctermbg=13',
2208 \ 'hi Tdarkcyan ctermfg=6 ctermbg=14',
2209 \ 'hi Tlightgrey ctermfg=7 ctermbg=15',
2210 \ 'hi Tdarkgrey ctermfg=8 ctermbg=0',
2211 \ 'hi Tred ctermfg=9 ctermbg=1',
2212 \ 'hi Tgreen ctermfg=10 ctermbg=2',
2213 \ 'hi Tyellow ctermfg=11 ctermbg=3',
2214 \ 'hi Tblue ctermfg=12 ctermbg=4',
2215 \ 'hi Tmagenta ctermfg=13 ctermbg=5',
2216 \ 'hi Tcyan ctermfg=14 ctermbg=6',
2217 \ 'hi Twhite ctermfg=15 ctermbg=7',
2218 \ 'hi TdarkredBold ctermfg=1 cterm=bold',
2219 \ 'hi TgreenBold ctermfg=10 cterm=bold',
2220 \ 'hi TmagentaBold ctermfg=13 cterm=bold ctermbg=5',
2221 \ '',
2222 \ 'call matchadd("Tblack", "A")',
2223 \ 'call matchadd("Tdarkred", "B")',
2224 \ 'call matchadd("Tdarkgreen", "C")',
2225 \ 'call matchadd("Tbrown", "D")',
2226 \ 'call matchadd("Tdarkblue", "E")',
2227 \ 'call matchadd("Tdarkmagenta", "F")',
2228 \ 'call matchadd("Tdarkcyan", "G")',
2229 \ 'call matchadd("Tlightgrey", "H")',
2230 \ 'call matchadd("Tdarkgrey", "I")',
2231 \ 'call matchadd("Tred", "J")',
2232 \ 'call matchadd("Tgreen", "K")',
2233 \ 'call matchadd("Tyellow", "L")',
2234 \ 'call matchadd("Tblue", "M")',
2235 \ 'call matchadd("Tmagenta", "N")',
2236 \ 'call matchadd("Tcyan", "O")',
2237 \ 'call matchadd("Twhite", "P")',
2238 \ 'call matchadd("TdarkredBold", "X")',
2239 \ 'call matchadd("TgreenBold", "Y")',
2240 \ 'call matchadd("TmagentaBold", "Z")',
2241 \ 'redraw',
2242 \ ], 'Xcolorscript')
2243 let buf = RunVimInTerminal('-S Xcolorscript', {'rows': 10})
2244 call VerifyScreenDump(buf, 'Test_terminal_all_ansi_colors', {})
2245
2246 call term_sendkeys(buf, ":q\<CR>")
2247 call StopVimInTerminal(buf)
2248 call delete('Xcolorscript')
2249endfunc
2250
Bram Moolenaar1e6bbfb2021-04-03 13:19:26 +02002251function On_BufFilePost()
2252 doautocmd <nomodeline> User UserEvent
2253endfunction
2254
2255func Test_terminal_nested_autocmd()
2256 new
2257 call setline(1, range(500))
2258 $
2259 let lastline = line('.')
2260
2261 augroup TermTest
2262 autocmd BufFilePost * call On_BufFilePost()
2263 autocmd User UserEvent silent
2264 augroup END
2265
2266 let cmd = Get_cat_123_cmd()
2267 let buf = term_start(cmd, #{term_finish: 'close', hidden: 1})
2268 call assert_equal(lastline, line('.'))
2269
Bram Moolenaar64374752021-04-03 17:22:29 +02002270 let job = term_getjob(buf)
2271 call WaitForAssert({-> assert_equal("dead", job_status(job))})
Bram Moolenaar1e6bbfb2021-04-03 13:19:26 +02002272 call delete('Xtext')
2273 augroup TermTest
2274 au!
2275 augroup END
2276endfunc
2277
Bram Moolenaaraeed2a62021-04-29 20:18:45 +02002278func Test_terminal_adds_jump()
2279 clearjumps
2280 call term_start("ls", #{curwin: 1})
2281 call assert_equal(1, getjumplist()[0]->len())
2282 bwipe!
2283endfunc
2284
Bram Moolenaareea32af2021-11-21 14:51:13 +00002285func Close_cb(ch, ctx)
2286 call term_wait(a:ctx.bufnr)
2287 let g:close_done = 'done'
2288endfunc
2289
2290func Test_term_wait_in_close_cb()
2291 let g:close_done = ''
2292 let ctx = {}
2293 let ctx.bufnr = term_start('echo "HELLO WORLD"',
2294 \ {'close_cb': {ch -> Close_cb(ch, ctx)}})
2295
2296 call WaitForAssert({-> assert_equal("done", g:close_done)})
2297
2298 unlet g:close_done
2299 bwipe!
2300endfunc
2301
Bram Moolenaar91689ea2020-05-11 22:04:53 +02002302
Bram Moolenaarca68ae12020-03-30 19:32:53 +02002303" vim: shiftwidth=2 sts=2 expandtab