1" Tests for the terminal window.
2" This is split in two, because it can take a lot of time.
3" See test_terminal2.vim and test_terminal3.vim for further tests.
4
5source check.vim
6CheckFeature terminal
7
8source shared.vim
9source screendump.vim
10source mouse.vim
11source term_util.vim
12
13let s:python = PythonProg()
14let $PROMPT_COMMAND=''
15
16func Test_terminal_basic()
17  au TerminalOpen * let b:done = 'yes'
18  let buf = Run_shell_in_terminal({})
19
20  call assert_equal('t', mode())
21  call assert_equal('yes', b:done)
22  call assert_match('%aR[^\n]*running]', execute('ls'))
23  call assert_match('%aR[^\n]*running]', execute('ls R'))
24  call assert_notmatch('%[^\n]*running]', execute('ls F'))
25  call assert_notmatch('%[^\n]*running]', execute('ls ?'))
26  call assert_fails('set modifiable', 'E946:')
27
28  call StopShellInTerminal(buf)
29  call TermWait(buf)
30  call assert_equal('n', mode())
31  call assert_match('%aF[^\n]*finished]', execute('ls'))
32  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 ?'))
35
36  " closing window wipes out the terminal buffer a with finished job
37  close
38  call assert_equal("", bufname(buf))
39
40  au! TerminalOpen
41  unlet g:job
42endfunc
43
44func Test_terminal_no_name()
45  let buf = Run_shell_in_terminal({})
46  call assert_match('^!', bufname(buf))
47  0file
48  call assert_equal("", bufname(buf))
49  call assert_match('\[No Name\]', execute('file'))
50  call StopShellInTerminal(buf)
51  call TermWait(buf)
52endfunc
53
54func 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
71func Test_terminal_make_change()
72  let buf = Run_shell_in_terminal({})
73  call StopShellInTerminal(buf)
74  call TermWait(buf)
75
76  setlocal modifiable
77  exe "normal Axxx\<Esc>"
78  call assert_fails(buf . 'bwipe', 'E89:')
79  undo
80
81  exe buf . 'bwipe'
82  unlet g:job
83endfunc
84
85func Test_terminal_paste_register()
86  let @" = "text to paste"
87
88  let buf = Run_shell_in_terminal({})
89  " Wait for the shell to display a prompt
90  call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))})
91
92  call feedkeys("echo \<C-W>\"\" \<C-W>\"=37 + 5\<CR>\<CR>", 'xt')
93  call WaitForAssert({-> assert_match("echo text to paste 42$", getline(1))})
94  call WaitForAssert({-> assert_equal('text to paste 42',       2->getline())})
95
96  exe buf . 'bwipe!'
97  unlet g:job
98endfunc
99
100func Test_terminal_wipe_buffer()
101  let buf = Run_shell_in_terminal({})
102  call assert_fails(buf . 'bwipe', 'E89:')
103  exe buf . 'bwipe!'
104  call WaitForAssert({-> assert_equal('dead', job_status(g:job))})
105  call assert_equal("", bufname(buf))
106
107  unlet g:job
108endfunc
109
110func Test_terminal_split_quit()
111  let buf = Run_shell_in_terminal({})
112  call TermWait(buf)
113  split
114  quit!
115  call TermWait(buf)
116  sleep 50m
117  call assert_equal('run', job_status(g:job))
118
119  quit!
120  call WaitForAssert({-> assert_equal('dead', job_status(g:job))})
121
122  exe buf . 'bwipe'
123  unlet g:job
124endfunc
125
126func Test_terminal_hide_buffer_job_running()
127  let buf = Run_shell_in_terminal({})
128  setlocal bufhidden=hide
129  quit
130  for nr in range(1, winnr('$'))
131    call assert_notequal(winbufnr(nr), buf)
132  endfor
133  call assert_true(bufloaded(buf))
134  call assert_true(buflisted(buf))
135
136  exe 'split ' . buf . 'buf'
137  call StopShellInTerminal(buf)
138  exe buf . 'bwipe'
139
140  unlet g:job
141endfunc
142
143func Test_terminal_hide_buffer_job_finished()
144  term echo hello
145  let buf = bufnr()
146  setlocal bufhidden=hide
147  call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))})
148  call assert_true(bufloaded(buf))
149  call assert_true(buflisted(buf))
150  edit Xasdfasdf
151  call assert_true(bufloaded(buf))
152  call assert_true(buflisted(buf))
153  exe buf .. 'buf'
154  call assert_equal(buf, bufnr())
155  setlocal bufhidden=
156  edit Xasdfasdf
157  call assert_false(bufloaded(buf))
158  call assert_false(buflisted(buf))
159  bwipe Xasdfasdf
160endfunc
161
162func s:Nasty_exit_cb(job, st)
163  exe g:buf . 'bwipe!'
164  let g:buf = 0
165endfunc
166
167func Get_cat_123_cmd()
168  if has('win32')
169    if !has('conpty')
170      return 'cmd /c "cls && color 2 && echo 123"'
171    else
172      " When clearing twice, extra sequence is not output.
173      return 'cmd /c "cls && cls && color 2 && echo 123"'
174    endif
175  else
176    call writefile(["\<Esc>[32m123"], 'Xtext')
177    return "cat Xtext"
178  endif
179endfunc
180
181func Test_terminal_nasty_cb()
182  let cmd = Get_cat_123_cmd()
183  let g:buf = term_start(cmd, {'exit_cb': function('s:Nasty_exit_cb')})
184  let g:job = term_getjob(g:buf)
185
186  call WaitForAssert({-> assert_equal("dead", job_status(g:job))})
187  call WaitForAssert({-> assert_equal(0, g:buf)})
188  unlet g:job
189  unlet g:buf
190  call delete('Xtext')
191endfunc
192
193func Check_123(buf)
194  let l = term_scrape(a:buf, 0)
195  call assert_true(len(l) == 0)
196  let l = term_scrape(a:buf, 999)
197  call assert_true(len(l) == 0)
198  let l = a:buf->term_scrape(1)
199  call assert_true(len(l) > 0)
200  call assert_equal('1', l[0].chars)
201  call assert_equal('2', l[1].chars)
202  call assert_equal('3', l[2].chars)
203  call assert_equal('#00e000', l[0].fg)
204  call assert_equal(0, term_getattr(l[0].attr, 'bold'))
205  call assert_equal(0, l[0].attr->term_getattr('italic'))
206  if has('win32')
207    " On Windows 'background' always defaults to dark, even though the terminal
208    " may use a light background.  Therefore accept both white and black.
209    call assert_match('#ffffff\|#000000', l[0].bg)
210  else
211    if &background == 'light'
212      call assert_equal('#ffffff', l[0].bg)
213    else
214      call assert_equal('#000000', l[0].bg)
215    endif
216  endif
217
218  let l = term_getline(a:buf, -1)
219  call assert_equal('', l)
220  let l = term_getline(a:buf, 0)
221  call assert_equal('', l)
222  let l = term_getline(a:buf, 999)
223  call assert_equal('', l)
224  let l = term_getline(a:buf, 1)
225  call assert_equal('123', l)
226endfunc
227
228func Test_terminal_scrape_123()
229  let cmd = Get_cat_123_cmd()
230  let buf = term_start(cmd)
231
232  let termlist = term_list()
233  call assert_equal(1, len(termlist))
234  call assert_equal(buf, termlist[0])
235
236  " Nothing happens with invalid buffer number
237  call term_wait(1234)
238
239  call TermWait(buf)
240  " On MS-Windows we first get a startup message of two lines, wait for the
241  " "cls" to happen, after that we have one line with three characters.
242  call WaitForAssert({-> assert_equal(3, len(term_scrape(buf, 1)))})
243  call Check_123(buf)
244
245  " Must still work after the job ended.
246  let job = term_getjob(buf)
247  call WaitForAssert({-> assert_equal("dead", job_status(job))})
248  call TermWait(buf)
249  call Check_123(buf)
250
251  exe buf . 'bwipe'
252  call delete('Xtext')
253endfunc
254
255func Test_terminal_scrape_multibyte()
256  call writefile(["léttまrs"], 'Xtext')
257  if has('win32')
258    " Run cmd with UTF-8 codepage to make the type command print the expected
259    " multibyte characters.
260    let buf = term_start("cmd /K chcp 65001")
261    call term_sendkeys(buf, "type Xtext\<CR>")
262    eval buf->term_sendkeys("exit\<CR>")
263    let line = 4
264  else
265    let buf = term_start("cat Xtext")
266    let line = 1
267  endif
268
269  call WaitFor({-> len(term_scrape(buf, line)) >= 7 && term_scrape(buf, line)[0].chars == "l"})
270  let l = term_scrape(buf, line)
271  call assert_true(len(l) >= 7)
272  call assert_equal('l', l[0].chars)
273  call assert_equal('é', l[1].chars)
274  call assert_equal(1, l[1].width)
275  call assert_equal('t', l[2].chars)
276  call assert_equal('t', l[3].chars)
277  call assert_equal('ま', l[4].chars)
278  call assert_equal(2, l[4].width)
279  call assert_equal('r', l[5].chars)
280  call assert_equal('s', l[6].chars)
281
282  let job = term_getjob(buf)
283  call WaitForAssert({-> assert_equal("dead", job_status(job))})
284  call TermWait(buf)
285
286  exe buf . 'bwipe'
287  call delete('Xtext')
288endfunc
289
290func Test_terminal_one_column()
291  " This creates a terminal, displays a double-wide character and makes the
292  " window one column wide.  This used to cause a crash.
293  let width = &columns
294  botright vert term
295  let buf = bufnr('$')
296  call TermWait(buf, 100)
297  exe "set columns=" .. (width / 2)
298  redraw
299  call term_sendkeys(buf, "キ")
300  call TermWait(buf, 10)
301  exe "set columns=" .. width
302  exe buf . 'bwipe!'
303endfunc
304
305func Test_terminal_scroll()
306  call writefile(range(1, 200), 'Xtext')
307  if has('win32')
308    let cmd = 'cmd /c "type Xtext"'
309  else
310    let cmd = "cat Xtext"
311  endif
312  let buf = term_start(cmd)
313
314  let job = term_getjob(buf)
315  call WaitForAssert({-> assert_equal("dead", job_status(job))})
316  call TermWait(buf)
317
318  " wait until the scrolling stops
319  while 1
320    let scrolled = buf->term_getscrolled()
321    sleep 20m
322    if scrolled == buf->term_getscrolled()
323      break
324    endif
325  endwhile
326
327  call assert_equal('1', getline(1))
328  call assert_equal('1', term_getline(buf, 1 - scrolled))
329  call assert_equal('49', getline(49))
330  call assert_equal('49', term_getline(buf, 49 - scrolled))
331  call assert_equal('200', getline(200))
332  call assert_equal('200', term_getline(buf, 200 - scrolled))
333
334  exe buf . 'bwipe'
335  call delete('Xtext')
336endfunc
337
338func Test_terminal_scrollback()
339  let buf = Run_shell_in_terminal({'term_rows': 15})
340  set termwinscroll=100
341  call writefile(range(150), 'Xtext')
342  if has('win32')
343    call term_sendkeys(buf, "type Xtext\<CR>")
344  else
345    call term_sendkeys(buf, "cat Xtext\<CR>")
346  endif
347  let rows = term_getsize(buf)[0]
348  " On MS-Windows there is an empty line, check both last line and above it.
349  call WaitForAssert({-> assert_match( '149', term_getline(buf, rows - 1) . term_getline(buf, rows - 2))})
350  let lines = line('$')
351  call assert_inrange(91, 100, lines)
352
353  call StopShellInTerminal(buf)
354  call TermWait(buf)
355  exe buf . 'bwipe'
356  set termwinscroll&
357  call delete('Xtext')
358endfunc
359
360func Test_terminal_postponed_scrollback()
361  " tail -f only works on Unix
362  CheckUnix
363
364  call writefile(range(50), 'Xtext')
365  call writefile([
366	\ 'set shell=/bin/sh noruler',
367	\ 'terminal',
368	\ 'sleep 200m',
369	\ 'call feedkeys("tail -n 100 -f Xtext\<CR>", "xt")',
370	\ 'sleep 100m',
371	\ 'call feedkeys("\<C-W>N", "xt")',
372	\ ], 'XTest_postponed')
373  let buf = RunVimInTerminal('-S XTest_postponed', {})
374  " Check that the Xtext lines are displayed and in Terminal-Normal mode
375  call VerifyScreenDump(buf, 'Test_terminal_scrollback_1', {})
376
377  silent !echo 'one more line' >>Xtext
378  " Screen will not change, move cursor to get a different dump
379  call term_sendkeys(buf, "k")
380  call VerifyScreenDump(buf, 'Test_terminal_scrollback_2', {})
381
382  " Back to Terminal-Job mode, text will scroll and show the extra line.
383  call term_sendkeys(buf, "a")
384  call VerifyScreenDump(buf, 'Test_terminal_scrollback_3', {})
385
386  " stop "tail -f"
387  call term_sendkeys(buf, "\<C-C>")
388  call TermWait(buf, 25)
389  " stop shell
390  call term_sendkeys(buf, "exit\<CR>")
391  call TermWait(buf, 50)
392  " close terminal window
393  let tsk_ret = term_sendkeys(buf, ":q\<CR>")
394
395  " check type of term_sendkeys() return value
396  echo type(tsk_ret)
397
398  call StopVimInTerminal(buf)
399  call delete('XTest_postponed')
400  call delete('Xtext')
401endfunc
402
403" Run diff on two dumps with different size.
404func Test_terminal_dumpdiff_size()
405  call assert_equal(1, winnr('$'))
406  call term_dumpdiff('dumps/Test_incsearch_search_01.dump', 'dumps/Test_popup_command_01.dump')
407  call assert_equal(2, winnr('$'))
408  call assert_match('Test_incsearch_search_01.dump', getline(10))
409  call assert_match('      +++++$', getline(11))
410  call assert_match('Test_popup_command_01.dump', getline(31))
411  call assert_equal(repeat('+', 75), getline(30))
412  quit
413endfunc
414
415func Test_terminal_size()
416  let cmd = Get_cat_123_cmd()
417
418  exe 'terminal ++rows=5 ' . cmd
419  let size = term_getsize('')
420  bwipe!
421  call assert_equal(5, size[0])
422
423  call term_start(cmd, {'term_rows': 6})
424  let size = term_getsize('')
425  bwipe!
426  call assert_equal(6, size[0])
427
428  vsplit
429  exe 'terminal ++rows=5 ++cols=33 ' . cmd
430  call assert_equal([5, 33], ''->term_getsize())
431
432  call term_setsize('', 6, 0)
433  call assert_equal([6, 33], term_getsize(''))
434
435  eval ''->term_setsize(0, 35)
436  call assert_equal([6, 35], term_getsize(''))
437
438  call term_setsize('', 7, 30)
439  call assert_equal([7, 30], term_getsize(''))
440
441  bwipe!
442  call assert_fails("call term_setsize('', 7, 30)", "E955:")
443
444  call term_start(cmd, {'term_rows': 6, 'term_cols': 36})
445  let size = term_getsize('')
446  bwipe!
447  call assert_equal([6, 36], size)
448
449  exe 'vertical terminal ++cols=20 ' . cmd
450  let size = term_getsize('')
451  bwipe!
452  call assert_equal(20, size[1])
453
454  eval cmd->term_start({'vertical': 1, 'term_cols': 26})
455  let size = term_getsize('')
456  bwipe!
457  call assert_equal(26, size[1])
458
459  split
460  exe 'vertical terminal ++rows=6 ++cols=20 ' . cmd
461  let size = term_getsize('')
462  bwipe!
463  call assert_equal([6, 20], size)
464
465  call term_start(cmd, {'vertical': 1, 'term_rows': 7, 'term_cols': 27})
466  let size = term_getsize('')
467  bwipe!
468  call assert_equal([7, 27], size)
469
470  call delete('Xtext')
471endfunc
472
473func Test_terminal_curwin()
474  let cmd = Get_cat_123_cmd()
475  call assert_equal(1, winnr('$'))
476
477  split Xdummy
478  call setline(1, 'dummy')
479  write
480  call assert_equal(1, getbufinfo('Xdummy')[0].loaded)
481  exe 'terminal ++curwin ' . cmd
482  call assert_equal(2, winnr('$'))
483  call assert_equal(0, getbufinfo('Xdummy')[0].loaded)
484  bwipe!
485
486  split Xdummy
487  call term_start(cmd, {'curwin': 1})
488  call assert_equal(2, winnr('$'))
489  bwipe!
490
491  split Xdummy
492  call setline(1, 'change')
493  call assert_fails('terminal ++curwin ' . cmd, 'E37:')
494  call assert_equal(2, winnr('$'))
495  exe 'terminal! ++curwin ' . cmd
496  call assert_equal(2, winnr('$'))
497  bwipe!
498
499  split Xdummy
500  call setline(1, 'change')
501  call assert_fails("call term_start(cmd, {'curwin': 1})", 'E37:')
502  call assert_equal(2, winnr('$'))
503  bwipe!
504
505  split Xdummy
506  bwipe!
507  call delete('Xtext')
508  call delete('Xdummy')
509endfunc
510
511func s:get_sleep_cmd()
512  if s:python != ''
513    let cmd = s:python . " test_short_sleep.py"
514    " 500 was not enough for Travis
515    let waittime = 900
516  else
517    echo 'This will take five seconds...'
518    let waittime = 2000
519    if has('win32')
520      let cmd = $windir . '\system32\timeout.exe 1'
521    else
522      let cmd = 'sleep 1'
523    endif
524  endif
525  return [cmd, waittime]
526endfunc
527
528func Test_terminal_finish_open_close()
529  call assert_equal(1, winnr('$'))
530
531  let [cmd, waittime] = s:get_sleep_cmd()
532
533  " shell terminal closes automatically
534  terminal
535  let buf = bufnr('%')
536  call assert_equal(2, winnr('$'))
537  " Wait for the shell to display a prompt
538  call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))})
539  call StopShellInTerminal(buf)
540  call WaitForAssert({-> assert_equal(1, winnr('$'))}, waittime)
541
542  " shell terminal that does not close automatically
543  terminal ++noclose
544  let buf = bufnr('%')
545  call assert_equal(2, winnr('$'))
546  " Wait for the shell to display a prompt
547  call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))})
548  call StopShellInTerminal(buf)
549  call assert_equal(2, winnr('$'))
550  quit
551  call assert_equal(1, winnr('$'))
552
553  exe 'terminal ++close ' . cmd
554  call assert_equal(2, winnr('$'))
555  wincmd p
556  call WaitForAssert({-> assert_equal(1, winnr('$'))}, waittime)
557
558  call term_start(cmd, {'term_finish': 'close'})
559  call assert_equal(2, winnr('$'))
560  wincmd p
561  call WaitForAssert({-> assert_equal(1, winnr('$'))}, waittime)
562  call assert_equal(1, winnr('$'))
563
564  exe 'terminal ++open ' . cmd
565  close!
566  call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime)
567  bwipe
568
569  call term_start(cmd, {'term_finish': 'open'})
570  close!
571  call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime)
572  bwipe
573
574  exe 'terminal ++hidden ++open ' . cmd
575  call assert_equal(1, winnr('$'))
576  call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime)
577  bwipe
578
579  call term_start(cmd, {'term_finish': 'open', 'hidden': 1})
580  call assert_equal(1, winnr('$'))
581  call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime)
582  bwipe
583
584  call assert_fails("call term_start(cmd, {'term_opencmd': 'open'})", 'E475:')
585  call assert_fails("call term_start(cmd, {'term_opencmd': 'split %x'})", 'E475:')
586  call assert_fails("call term_start(cmd, {'term_opencmd': 'split %d and %s'})", 'E475:')
587  call assert_fails("call term_start(cmd, {'term_opencmd': 'split % and %d'})", 'E475:')
588
589  call term_start(cmd, {'term_finish': 'open', 'term_opencmd': '4split | buffer %d | let g:result = "opened the buffer in a window"'})
590  close!
591  call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime)
592  call assert_equal(4, winheight(0))
593  call assert_equal('opened the buffer in a window', g:result)
594  unlet g:result
595  bwipe
596endfunc
597
598func Test_terminal_cwd()
599  if has('win32')
600    let cmd = 'cmd /c cd'
601  else
602    CheckExecutable pwd
603    let cmd = 'pwd'
604  endif
605  call mkdir('Xdir')
606  let buf = term_start(cmd, {'cwd': 'Xdir'})
607  call WaitForAssert({-> assert_equal('Xdir', fnamemodify(getline(1), ":t"))})
608
609  exe buf . 'bwipe'
610  call delete('Xdir', 'rf')
611endfunc
612
613func Test_terminal_cwd_failure()
614  " Case 1: Provided directory is not actually a directory.  Attempt to make
615  " the file executable as well.
616  call writefile([], 'Xfile')
617  call setfperm('Xfile', 'rwx------')
618  call assert_fails("call term_start(&shell, {'cwd': 'Xfile'})", 'E475:')
619  call delete('Xfile')
620
621  " Case 2: Directory does not exist.
622  call assert_fails("call term_start(&shell, {'cwd': 'Xdir'})", 'E475:')
623
624  " Case 3: Directory exists but is not accessible.
625  " Skip this for root, it will be accessible anyway.
626  if !IsRoot()
627    call mkdir('XdirNoAccess', '', '0600')
628    " return early if the directory permissions could not be set properly
629    if getfperm('XdirNoAccess')[2] == 'x'
630      call delete('XdirNoAccess', 'rf')
631      return
632    endif
633    call assert_fails("call term_start(&shell, {'cwd': 'XdirNoAccess'})", 'E475:')
634    call delete('XdirNoAccess', 'rf')
635  endif
636endfunc
637
638func Test_terminal_servername()
639  CheckFeature clientserver
640  call s:test_environment("VIM_SERVERNAME", v:servername)
641endfunc
642
643func Test_terminal_version()
644  call s:test_environment("VIM_TERMINAL", string(v:version))
645endfunc
646
647func s:test_environment(name, value)
648  let buf = Run_shell_in_terminal({})
649  " Wait for the shell to display a prompt
650  call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))})
651  if has('win32')
652    call term_sendkeys(buf, "echo %" . a:name . "%\r")
653  else
654    call term_sendkeys(buf, "echo $" . a:name . "\r")
655  endif
656  call TermWait(buf)
657  call StopShellInTerminal(buf)
658  call WaitForAssert({-> assert_equal(a:value, getline(2))})
659
660  exe buf . 'bwipe'
661  unlet buf
662endfunc
663
664func Test_terminal_env()
665  let buf = Run_shell_in_terminal({'env': {'TESTENV': 'correct'}})
666  " Wait for the shell to display a prompt
667  call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))})
668  if has('win32')
669    call term_sendkeys(buf, "echo %TESTENV%\r")
670  else
671    call term_sendkeys(buf, "echo $TESTENV\r")
672  endif
673  eval buf->TermWait()
674  call StopShellInTerminal(buf)
675  call WaitForAssert({-> assert_equal('correct', getline(2))})
676
677  exe buf . 'bwipe'
678endfunc
679
680func Test_terminal_list_args()
681  let buf = term_start([&shell, &shellcmdflag, 'echo "123"'])
682  call assert_fails(buf . 'bwipe', 'E89:')
683  exe buf . 'bwipe!'
684  call assert_equal("", bufname(buf))
685endfunction
686
687func Test_terminal_noblock()
688  let buf = term_start(&shell)
689  let wait_time = 5000
690  let letters = 'abcdefghijklmnopqrstuvwxyz'
691  if has('bsd') || has('mac') || has('sun')
692    " The shell or something else has a problem dealing with more than 1000
693    " characters at the same time.  It's very slow too.
694    let len = 1000
695    let wait_time = 15000
696    let letters = 'abcdefghijklm'
697  " NPFS is used in Windows, nonblocking mode does not work properly.
698  elseif has('win32')
699    let len = 1
700  else
701    let len = 5000
702  endif
703
704  " Send a lot of text lines, should be buffered properly.
705  for c in split(letters, '\zs')
706    call term_sendkeys(buf, 'echo ' . repeat(c, len) . "\<cr>")
707  endfor
708  call term_sendkeys(buf, "echo done\<cr>")
709
710  " On MS-Windows there is an extra empty line below "done".  Find "done" in
711  " the last-but-one or the last-but-two line.
712  let lnum = term_getsize(buf)[0] - 1
713  call WaitForAssert({-> assert_match('done', term_getline(buf, lnum - 1) .. '//' .. term_getline(buf, lnum))}, wait_time)
714  let line = term_getline(buf, lnum)
715  if line !~ 'done'
716    let line = term_getline(buf, lnum - 1)
717  endif
718  call assert_match('done', line)
719
720  let g:job = term_getjob(buf)
721  call StopShellInTerminal(buf)
722  call TermWait(buf)
723  unlet g:job
724  bwipe
725endfunc
726
727func Test_terminal_write_stdin()
728  " TODO: enable once writing to stdin works on MS-Windows
729  CheckNotMSWindows
730  CheckExecutable wc
731
732  call setline(1, ['one', 'two', 'three'])
733  %term wc
734  call WaitForAssert({-> assert_match('3', getline("$"))})
735  let nrs = split(getline('$'))
736  call assert_equal(['3', '3', '14'], nrs)
737  %bwipe!
738
739  call setline(1, ['one', 'two', 'three', 'four'])
740  2,3term wc
741  call WaitForAssert({-> assert_match('2', getline("$"))})
742  let nrs = split(getline('$'))
743  call assert_equal(['2', '2', '10'], nrs)
744  %bwipe!
745endfunc
746
747func Test_terminal_eof_arg()
748  call CheckPython(s:python)
749
750  call setline(1, ['print("hello")'])
751  exe '1term ++eof=exit(123) ' .. s:python
752  " MS-Windows echoes the input, Unix doesn't.
753  if has('win32')
754    call WaitFor({-> getline('$') =~ 'exit(123)'})
755    call assert_equal('hello', getline(line('$') - 1))
756  else
757    call WaitFor({-> getline('$') =~ 'hello'})
758    call assert_equal('hello', getline('$'))
759  endif
760  call assert_equal(123, bufnr()->term_getjob()->job_info().exitval)
761  %bwipe!
762endfunc
763
764func Test_terminal_eof_arg_win32_ctrl_z()
765  CheckMSWindows
766  call CheckPython(s:python)
767
768  call setline(1, ['print("hello")'])
769  exe '1term ++eof=<C-Z> ' .. s:python
770  call WaitForAssert({-> assert_match('\^Z', getline(line('$') - 1))})
771  call assert_match('\^Z', getline(line('$') - 1))
772  %bwipe!
773endfunc
774
775func Test_terminal_duplicate_eof_arg()
776  call CheckPython(s:python)
777
778  " Check the last specified ++eof arg is used and should not memory leak.
779  new
780  call setline(1, ['print("hello")'])
781  exe '1term ++eof=<C-Z> ++eof=exit(123) ' .. s:python
782  " MS-Windows echoes the input, Unix doesn't.
783  if has('win32')
784    call WaitFor({-> getline('$') =~ 'exit(123)'})
785    call assert_equal('hello', getline(line('$') - 1))
786  else
787    call WaitFor({-> getline('$') =~ 'hello'})
788    call assert_equal('hello', getline('$'))
789  endif
790  call assert_equal(123, bufnr()->term_getjob()->job_info().exitval)
791  %bwipe!
792endfunc
793
794func Test_terminal_no_cmd()
795  let buf = term_start('NONE', {})
796  call assert_notequal(0, buf)
797
798  let pty = job_info(term_getjob(buf))['tty_out']
799  call assert_notequal('', pty)
800  if has('gui_running') && !has('win32')
801    " In the GUI job_start() doesn't work, it does not read from the pty.
802    call system('echo "look here" > ' . pty)
803  else
804    " Otherwise using a job works on all systems.
805    call job_start([&shell, &shellcmdflag, 'echo "look here" > ' . pty])
806  endif
807  call WaitForAssert({-> assert_match('look here', term_getline(buf, 1))})
808
809  bwipe!
810endfunc
811
812func Test_terminal_special_chars()
813  " this file name only works on Unix
814  CheckUnix
815
816  call mkdir('Xdir with spaces')
817  call writefile(['x'], 'Xdir with spaces/quoted"file')
818  term ls Xdir\ with\ spaces/quoted\"file
819  call WaitForAssert({-> assert_match('quoted"file', term_getline('', 1))})
820  " make sure the job has finished
821  call WaitForAssert({-> assert_match('finish', term_getstatus(bufnr()))})
822
823  call delete('Xdir with spaces', 'rf')
824  bwipe
825endfunc
826
827func Test_terminal_wrong_options()
828  call assert_fails('call term_start(&shell, {
829	\ "in_io": "file",
830	\ "in_name": "xxx",
831	\ "out_io": "file",
832	\ "out_name": "xxx",
833	\ "err_io": "file",
834	\ "err_name": "xxx"
835	\ })', 'E474:')
836  call assert_fails('call term_start(&shell, {
837	\ "out_buf": bufnr("%")
838	\ })', 'E474:')
839  call assert_fails('call term_start(&shell, {
840	\ "err_buf": bufnr("%")
841	\ })', 'E474:')
842endfunc
843
844func Test_terminal_redir_file()
845  let cmd = Get_cat_123_cmd()
846  let buf = term_start(cmd, {'out_io': 'file', 'out_name': 'Xfile'})
847  call TermWait(buf)
848  " ConPTY may precede escape sequence. There are things that are not so.
849  if !has('conpty')
850    call WaitForAssert({-> assert_notequal(0, len(readfile("Xfile")))})
851    call assert_match('123', readfile('Xfile')[0])
852  endif
853  let g:job = term_getjob(buf)
854  call WaitForAssert({-> assert_equal("dead", job_status(g:job))})
855
856  if has('win32')
857    " On Windows we cannot delete a file being used by a process.  When
858    " job_status() returns "dead", the process remains for a short time.
859    " Just wait for a moment.
860    sleep 50m
861  endif
862  call delete('Xfile')
863  bwipe
864
865  if has('unix')
866    call writefile(['one line'], 'Xfile')
867    let buf = term_start('cat', {'in_io': 'file', 'in_name': 'Xfile'})
868    call TermWait(buf)
869    call WaitForAssert({-> assert_equal('one line', term_getline(buf, 1))})
870    let g:job = term_getjob(buf)
871    call WaitForAssert({-> assert_equal('dead', job_status(g:job))})
872    bwipe
873    call delete('Xfile')
874  endif
875endfunc
876
877func TerminalTmap(remap)
878  let buf = Run_shell_in_terminal({})
879  call assert_equal('t', mode())
880
881  if a:remap
882    tmap 123 456
883  else
884    tnoremap 123 456
885  endif
886  " don't use abcde, it's an existing command
887  tmap 456 abxde
888  call assert_equal('456', maparg('123', 't'))
889  call assert_equal('abxde', maparg('456', 't'))
890  call feedkeys("123", 'tx')
891  call WaitForAssert({-> assert_match('abxde\|456', term_getline(buf, term_getcursor(buf)[0]))})
892  let lnum = term_getcursor(buf)[0]
893  if a:remap
894    call assert_match('abxde', term_getline(buf, lnum))
895  else
896    call assert_match('456', term_getline(buf, lnum))
897  endif
898
899  call term_sendkeys(buf, "\r")
900  call StopShellInTerminal(buf)
901  call TermWait(buf)
902
903  tunmap 123
904  tunmap 456
905  call assert_equal('', maparg('123', 't'))
906  close
907  unlet g:job
908endfunc
909
910func Test_terminal_tmap()
911  call TerminalTmap(1)
912  call TerminalTmap(0)
913endfunc
914
915func Test_terminal_wall()
916  let buf = Run_shell_in_terminal({})
917  wall
918  call StopShellInTerminal(buf)
919  call TermWait(buf)
920  exe buf . 'bwipe'
921  unlet g:job
922endfunc
923
924func Test_terminal_wqall()
925  let buf = Run_shell_in_terminal({})
926  call assert_fails('wqall', 'E948:')
927  call StopShellInTerminal(buf)
928  call TermWait(buf)
929  exe buf . 'bwipe'
930  unlet g:job
931endfunc
932
933func Test_terminal_composing_unicode()
934  let save_enc = &encoding
935  set encoding=utf-8
936
937  if has('win32')
938    let cmd = "cmd /K chcp 65001"
939    let lnum = [3, 6, 9]
940  else
941    let cmd = &shell
942    let lnum = [1, 3, 5]
943  endif
944
945  enew
946  let buf = term_start(cmd, {'curwin': 1})
947  let g:job = term_getjob(buf)
948  call WaitFor({-> term_getline(buf, 1) !=# ''}, 1000)
949
950  if has('win32')
951    call assert_equal('cmd', job_info(g:job).cmd[0])
952  else
953    call assert_equal(&shell, job_info(g:job).cmd[0])
954  endif
955
956  " ascii + composing
957  let txt = "a\u0308bc"
958  call term_sendkeys(buf, "echo " . txt)
959  call TermWait(buf, 25)
960  call assert_match("echo " . txt, term_getline(buf, lnum[0]))
961  call term_sendkeys(buf, "\<cr>")
962  call WaitForAssert({-> assert_equal(txt, term_getline(buf, lnum[0] + 1))}, 1000)
963  let l = term_scrape(buf, lnum[0] + 1)
964  call assert_equal("a\u0308", l[0].chars)
965  call assert_equal("b", l[1].chars)
966  call assert_equal("c", l[2].chars)
967
968  " multibyte + composing
969  let txt = "\u304b\u3099\u304e\u304f\u3099\u3052\u3053\u3099"
970  call term_sendkeys(buf, "echo " . txt)
971  call TermWait(buf, 25)
972  call assert_match("echo " . txt, term_getline(buf, lnum[1]))
973  call term_sendkeys(buf, "\<cr>")
974  call WaitForAssert({-> assert_equal(txt, term_getline(buf, lnum[1] + 1))}, 1000)
975  let l = term_scrape(buf, lnum[1] + 1)
976  call assert_equal("\u304b\u3099", l[0].chars)
977  call assert_equal("\u304e", l[2].chars)
978  call assert_equal("\u304f\u3099", l[3].chars)
979  call assert_equal("\u3052", l[5].chars)
980  call assert_equal("\u3053\u3099", l[6].chars)
981
982  " \u00a0 + composing
983  let txt = "abc\u00a0\u0308"
984  call term_sendkeys(buf, "echo " . txt)
985  call TermWait(buf, 25)
986  call assert_match("echo " . txt, term_getline(buf, lnum[2]))
987  call term_sendkeys(buf, "\<cr>")
988  call WaitForAssert({-> assert_equal(txt, term_getline(buf, lnum[2] + 1))}, 1000)
989  let l = term_scrape(buf, lnum[2] + 1)
990  call assert_equal("\u00a0\u0308", l[3].chars)
991
992  call term_sendkeys(buf, "exit\r")
993  call WaitForAssert({-> assert_equal('dead', job_status(g:job))})
994  bwipe!
995  unlet g:job
996  let &encoding = save_enc
997endfunc
998
999func Test_terminal_aucmd_on_close()
1000  fun Nop()
1001    let s:called = 1
1002  endfun
1003
1004  aug repro
1005      au!
1006      au BufWinLeave * call Nop()
1007  aug END
1008
1009  let [cmd, waittime] = s:get_sleep_cmd()
1010
1011  call assert_equal(1, winnr('$'))
1012  new
1013  call setline(1, ['one', 'two'])
1014  exe 'term ++close ' . cmd
1015  wincmd p
1016  call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime)
1017  call assert_equal(1, s:called)
1018  bwipe!
1019
1020  unlet s:called
1021  au! repro
1022  delfunc Nop
1023endfunc
1024
1025func Test_terminal_term_start_empty_command()
1026  let cmd = "call term_start('', {'curwin' : 1, 'term_finish' : 'close'})"
1027  call assert_fails(cmd, 'E474:')
1028  let cmd = "call term_start('', {'curwin' : 1, 'term_finish' : 'close'})"
1029  call assert_fails(cmd, 'E474:')
1030  let cmd = "call term_start({}, {'curwin' : 1, 'term_finish' : 'close'})"
1031  call assert_fails(cmd, 'E474:')
1032  let cmd = "call term_start(0, {'curwin' : 1, 'term_finish' : 'close'})"
1033  call assert_fails(cmd, 'E474:')
1034  let cmd = "call term_start('', {'term_name' : []})"
1035  call assert_fails(cmd, 'E730:')
1036  let cmd = "call term_start('', {'term_finish' : 'axby'})"
1037  call assert_fails(cmd, 'E475:')
1038  let cmd = "call term_start('', {'eof_chars' : []})"
1039  call assert_fails(cmd, 'E730:')
1040  let cmd = "call term_start('', {'term_kill' : []})"
1041  call assert_fails(cmd, 'E730:')
1042  let cmd = "call term_start('', {'tty_type' : []})"
1043  call assert_fails(cmd, 'E730:')
1044  let cmd = "call term_start('', {'tty_type' : 'abc'})"
1045  call assert_fails(cmd, 'E475:')
1046  let cmd = "call term_start('', {'term_highlight' : []})"
1047  call assert_fails(cmd, 'E730:')
1048  if has('gui') || has('termguicolors')
1049    let cmd = "call term_start('', {'ansi_colors' : 'abc'})"
1050    call assert_fails(cmd, 'E475:')
1051    let cmd = "call term_start('', {'ansi_colors' : [[]]})"
1052    call assert_fails(cmd, 'E730:')
1053    let cmd = "call term_start('', {'ansi_colors' : repeat(['blue'], 18)})"
1054    if has('gui_running') || has('termguicolors')
1055      call assert_fails(cmd, 'E475:')
1056    else
1057      call assert_fails(cmd, 'E254:')
1058    endif
1059  endif
1060endfunc
1061
1062func Test_terminal_response_to_control_sequence()
1063  CheckUnix
1064
1065  let buf = Run_shell_in_terminal({})
1066  call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))})
1067
1068  call term_sendkeys(buf, "cat\<CR>")
1069  call WaitForAssert({-> assert_match('cat', term_getline(buf, 1))})
1070
1071  " Request the cursor position.
1072  call term_sendkeys(buf, "\x1b[6n\<CR>")
1073
1074  " Wait for output from tty to display, below an empty line.
1075  call WaitForAssert({-> assert_match('3;1R', term_getline(buf, 4))})
1076
1077  " End "cat" gently.
1078  call term_sendkeys(buf, "\<CR>\<C-D>")
1079
1080  call StopShellInTerminal(buf)
1081  exe buf . 'bwipe'
1082  unlet g:job
1083endfunc
1084
1085" Run Vim, start a terminal in that Vim with the kill argument,
1086" :qall works.
1087func Run_terminal_qall_kill(line1, line2)
1088  " 1. Open a terminal window and wait for the prompt to appear
1089  " 2. set kill using term_setkill()
1090  " 3. make Vim exit, it will kill the shell
1091  let after = [
1092	\ a:line1,
1093	\ 'let buf = bufnr("%")',
1094	\ 'while term_getline(buf, 1) =~ "^\\s*$"',
1095	\ '  sleep 10m',
1096	\ 'endwhile',
1097	\ a:line2,
1098	\ 'au VimLeavePre * call writefile(["done"], "Xdone")',
1099	\ 'qall',
1100	\ ]
1101  if !RunVim([], after, '')
1102    return
1103  endif
1104  call assert_equal("done", readfile("Xdone")[0])
1105  call delete("Xdone")
1106endfunc
1107
1108" Run Vim in a terminal, then start a terminal in that Vim with a kill
1109" argument, check that :qall works.
1110func Test_terminal_qall_kill_arg()
1111  call Run_terminal_qall_kill('term ++kill=kill', '')
1112endfunc
1113
1114" Run Vim, start a terminal in that Vim, set the kill argument with
1115" term_setkill(), check that :qall works.
1116func Test_terminal_qall_kill_func()
1117  call Run_terminal_qall_kill('term', 'eval buf->term_setkill("kill")')
1118endfunc
1119
1120" Run Vim, start a terminal in that Vim without the kill argument,
1121" check that :qall does not exit, :qall! does.
1122func Test_terminal_qall_exit()
1123  let after =<< trim [CODE]
1124    term
1125    let buf = bufnr("%")
1126    while term_getline(buf, 1) =~ "^\\s*$"
1127      sleep 10m
1128    endwhile
1129    set nomore
1130    au VimLeavePre * call writefile(["too early"], "Xdone")
1131    qall
1132    au! VimLeavePre * exe buf . "bwipe!" | call writefile(["done"], "Xdone")
1133    cquit
1134  [CODE]
1135
1136  if !RunVim([], after, '')
1137    return
1138  endif
1139  call assert_equal("done", readfile("Xdone")[0])
1140  call delete("Xdone")
1141endfunc
1142
1143" Run Vim in a terminal, then start a terminal in that Vim without a kill
1144" argument, check that :confirm qall works.
1145func Test_terminal_qall_prompt()
1146  CheckRunVimInTerminal
1147  let buf = RunVimInTerminal('', {})
1148
1149  " Open a terminal window and wait for the prompt to appear
1150  call term_sendkeys(buf, ":term\<CR>")
1151  call WaitForAssert({-> assert_match('\[running]', term_getline(buf, 10))})
1152  call WaitForAssert({-> assert_notmatch('^\s*$', term_getline(buf, 1))})
1153
1154  " make Vim exit, it will prompt to kill the shell
1155  call term_sendkeys(buf, "\<C-W>:confirm qall\<CR>")
1156  call WaitForAssert({-> assert_match('ancel:', term_getline(buf, 20))})
1157  call term_sendkeys(buf, "y")
1158  call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))})
1159
1160  " close the terminal window where Vim was running
1161  quit
1162endfunc
1163
1164" Run Vim in a terminal, then start a terminal window with a shell and check
1165" that Vim exits if it is closed.
1166func Test_terminal_exit()
1167  CheckRunVimInTerminal
1168
1169  let lines =<< trim END
1170     let winid = win_getid()
1171     help
1172     term
1173     let termid = win_getid()
1174     call win_gotoid(winid)
1175     close
1176     call win_gotoid(termid)
1177  END
1178  call writefile(lines, 'XtermExit')
1179  let buf = RunVimInTerminal('-S XtermExit', #{rows: 10})
1180  let job = term_getjob(buf)
1181  call WaitForAssert({-> assert_equal("run", job_status(job))})
1182
1183  " quit the shell, it will make Vim exit
1184  call term_sendkeys(buf, "exit\<CR>")
1185  call WaitForAssert({-> assert_equal("dead", job_status(job))})
1186
1187  call delete('XtermExit')
1188endfunc
1189
1190func Test_terminal_open_autocmd()
1191  augroup repro
1192    au!
1193    au TerminalOpen * let s:called += 1
1194  augroup END
1195
1196  let s:called = 0
1197
1198  " Open a terminal window with :terminal
1199  terminal
1200  call assert_equal(1, s:called)
1201  bwipe!
1202
1203  " Open a terminal window with term_start()
1204  call term_start(&shell)
1205  call assert_equal(2, s:called)
1206  bwipe!
1207
1208  " Open a hidden terminal buffer with :terminal
1209  terminal ++hidden
1210  call assert_equal(3, s:called)
1211  for buf in term_list()
1212    exe buf . "bwipe!"
1213  endfor
1214
1215  " Open a hidden terminal buffer with term_start()
1216  let buf = term_start(&shell, {'hidden': 1})
1217  call assert_equal(4, s:called)
1218  exe buf . "bwipe!"
1219
1220  unlet s:called
1221  au! repro
1222endfunc
1223
1224func Test_open_term_from_cmd()
1225  CheckUnix
1226  CheckRunVimInTerminal
1227
1228  let lines =<< trim END
1229      call setline(1, ['a', 'b', 'c'])
1230      3
1231      set incsearch
1232      cnoremap <F3> <Cmd>call term_start(['/bin/sh', '-c', ':'])<CR>
1233  END
1234  call writefile(lines, 'Xopenterm')
1235  let buf = RunVimInTerminal('-S Xopenterm', {})
1236
1237  " this opens a window, incsearch should not use the old cursor position
1238  call term_sendkeys(buf, "/\<F3>")
1239  call VerifyScreenDump(buf, 'Test_terminal_from_cmd', {})
1240  call term_sendkeys(buf, "\<Esc>")
1241  call term_sendkeys(buf, ":q\<CR>")
1242
1243  call StopVimInTerminal(buf)
1244  call delete('Xopenterm')
1245endfunc
1246
1247func Test_terminal_popup_with_cmd()
1248  " this was crashing
1249  let buf = term_start(&shell, #{hidden: v:true})
1250  let s:winid = popup_create(buf, {})
1251  tnoremap <F3> <Cmd>call popup_close(s:winid)<CR>
1252  call feedkeys("\<F3>", 'xt')
1253
1254  tunmap  <F3>
1255  exe 'bwipe! ' .. buf
1256  unlet s:winid
1257endfunc
1258
1259func Test_terminal_popup_bufload()
1260  let termbuf = term_start(&shell, #{hidden: v:true, term_finish: 'close'})
1261  let winid = popup_create(termbuf, {})
1262  sleep 50m
1263
1264  let newbuf = bufadd('')
1265  call bufload(newbuf)
1266  call setbufline(newbuf, 1, 'foobar')
1267
1268  " must not have switched to another window
1269  call assert_equal(winid, win_getid())
1270
1271  call StopShellInTerminal(termbuf)
1272  call WaitFor({-> win_getid() != winid})
1273  exe 'bwipe! ' .. newbuf
1274endfunc
1275
1276func Test_terminal_popup_insert_cmd()
1277  CheckUnix
1278
1279  inoremap <F3> <Cmd>call StartTermInPopup()<CR>
1280  func StartTermInPopup()
1281    call term_start(['/bin/sh', '-c', 'cat'], #{hidden: v:true, term_finish: 'close'})->popup_create(#{highlight: 'Pmenu'})
1282  endfunc
1283  call feedkeys("i\<F3>")
1284  sleep 10m
1285  call assert_equal('n', mode())
1286
1287  call feedkeys("\<C-D>", 'xt')
1288  call WaitFor({-> popup_list() == []})
1289  delfunc StartTermInPopup
1290  iunmap <F3>
1291endfunc
1292
1293func Check_dump01(off)
1294  call assert_equal('one two three four five', trim(getline(a:off + 1)))
1295  call assert_equal('~           Select Word', trim(getline(a:off + 7)))
1296  call assert_equal(':popup PopUp', trim(getline(a:off + 20)))
1297endfunc
1298
1299func Test_terminal_dumpwrite_composing()
1300  CheckRunVimInTerminal
1301  let save_enc = &encoding
1302  set encoding=utf-8
1303  call assert_equal(1, winnr('$'))
1304
1305  let text = " a\u0300 e\u0302 o\u0308"
1306  call writefile([text], 'Xcomposing')
1307  let buf = RunVimInTerminal('--cmd "set encoding=utf-8" Xcomposing', {})
1308  call WaitForAssert({-> assert_match(text, term_getline(buf, 1))})
1309  eval 'Xdump'->term_dumpwrite(buf)
1310  let dumpline = readfile('Xdump')[0]
1311  call assert_match('|à| |ê| |ö', dumpline)
1312
1313  call StopVimInTerminal(buf)
1314  call delete('Xcomposing')
1315  call delete('Xdump')
1316  let &encoding = save_enc
1317endfunc
1318
1319" Tests for failures in the term_dumpwrite() function
1320func Test_terminal_dumpwrite_errors()
1321  CheckRunVimInTerminal
1322  call assert_fails("call term_dumpwrite({}, 'Xtest.dump')", 'E728:')
1323  let buf = RunVimInTerminal('', {})
1324  call TermWait(buf)
1325  call assert_fails("call term_dumpwrite(buf, 'Xtest.dump', '')", 'E715:')
1326  call assert_fails("call term_dumpwrite(buf, [])", 'E730:')
1327  call writefile([], 'Xtest.dump')
1328  call assert_fails("call term_dumpwrite(buf, 'Xtest.dump')", 'E953:')
1329  call delete('Xtest.dump')
1330  call assert_fails("call term_dumpwrite(buf, '')", 'E482:')
1331  call assert_fails("call term_dumpwrite(buf, test_null_string())", 'E482:')
1332  call test_garbagecollect_now()
1333  call StopVimInTerminal(buf, 0)
1334  call TermWait(buf)
1335  call assert_fails("call term_dumpwrite(buf, 'Xtest.dump')", 'E958:')
1336  call assert_fails('call term_sendkeys([], ":q\<CR>")', 'E745:')
1337  call assert_equal(0, term_sendkeys(buf, ":q\<CR>"))
1338endfunc
1339
1340" just testing basic functionality.
1341func Test_terminal_dumpload()
1342  let curbuf = winbufnr('')
1343  call assert_equal(1, winnr('$'))
1344  let buf = term_dumpload('dumps/Test_popup_command_01.dump')
1345  call assert_equal(2, winnr('$'))
1346  call assert_equal(20, line('$'))
1347  call Check_dump01(0)
1348
1349  " Load another dump in the same window
1350  let buf2 = 'dumps/Test_diff_01.dump'->term_dumpload({'bufnr': buf})
1351  call assert_equal(buf, buf2)
1352  call assert_notequal('one two three four five', trim(getline(1)))
1353
1354  " Load the first dump again in the same window
1355  let buf2 = term_dumpload('dumps/Test_popup_command_01.dump', {'bufnr': buf})
1356  call assert_equal(buf, buf2)
1357  call Check_dump01(0)
1358
1359  call assert_fails("call term_dumpload('dumps/Test_popup_command_01.dump', {'bufnr': curbuf})", 'E475:')
1360  call assert_fails("call term_dumpload('dumps/Test_popup_command_01.dump', {'bufnr': 9999})", 'E86:')
1361  new
1362  let closedbuf = winbufnr('')
1363  quit
1364  call assert_fails("call term_dumpload('dumps/Test_popup_command_01.dump', {'bufnr': closedbuf})", 'E475:')
1365  call assert_fails('call term_dumpload([])', 'E730:')
1366  call assert_fails('call term_dumpload("xabcy.dump")', 'E485:')
1367
1368  quit
1369endfunc
1370
1371func Test_terminal_dumpload_dump()
1372  CheckRunVimInTerminal
1373
1374  let lines =<< trim END
1375     call term_dumpload('dumps/Test_popupwin_22.dump', #{term_rows: 12})
1376  END
1377  call writefile(lines, 'XtermDumpload')
1378  let buf = RunVimInTerminal('-S XtermDumpload', #{rows: 15})
1379  call VerifyScreenDump(buf, 'Test_terminal_dumpload', {})
1380
1381  call StopVimInTerminal(buf)
1382  call delete('XtermDumpload')
1383endfunc
1384
1385func Test_terminal_dumpdiff()
1386  call assert_equal(1, winnr('$'))
1387  eval 'dumps/Test_popup_command_01.dump'->term_dumpdiff('dumps/Test_popup_command_02.dump')
1388  call assert_equal(2, winnr('$'))
1389  call assert_equal(62, line('$'))
1390  call Check_dump01(0)
1391  call Check_dump01(42)
1392  call assert_equal('           bbbbbbbbbbbbbbbbbb ', getline(26)[0:29])
1393  quit
1394
1395  call assert_fails('call term_dumpdiff("X1.dump", [])', 'E730:')
1396  call assert_fails('call term_dumpdiff("X1.dump", "X2.dump")', 'E485:')
1397  call writefile([], 'X1.dump')
1398  call assert_fails('call term_dumpdiff("X1.dump", "X2.dump")', 'E485:')
1399  call delete('X1.dump')
1400endfunc
1401
1402func Test_terminal_dumpdiff_swap()
1403  call assert_equal(1, winnr('$'))
1404  call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_03.dump')
1405  call assert_equal(2, winnr('$'))
1406  call assert_equal(62, line('$'))
1407  call assert_match('Test_popup_command_01.dump', getline(21))
1408  call assert_match('Test_popup_command_03.dump', getline(42))
1409  call assert_match('Undo', getline(3))
1410  call assert_match('three four five', getline(45))
1411
1412  normal s
1413  call assert_match('Test_popup_command_03.dump', getline(21))
1414  call assert_match('Test_popup_command_01.dump', getline(42))
1415  call assert_match('three four five', getline(3))
1416  call assert_match('Undo', getline(45))
1417  quit
1418
1419  " Diff two terminal dump files with different number of rows
1420  " Swap the diffs
1421  call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_winline_rnu.dump')
1422  call assert_match('Test_popup_command_01.dump', getline(21))
1423  call assert_match('Test_winline_rnu.dump', getline(42))
1424  normal s
1425  call assert_match('Test_winline_rnu.dump', getline(6))
1426  call assert_match('Test_popup_command_01.dump', getline(27))
1427  quit
1428endfunc
1429
1430func Test_terminal_dumpdiff_options()
1431  set laststatus=0
1432  call assert_equal(1, winnr('$'))
1433  let height = winheight(0)
1434  call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump', {'vertical': 1, 'term_cols': 33})
1435  call assert_equal(2, winnr('$'))
1436  call assert_equal(height, winheight(winnr()))
1437  call assert_equal(33, winwidth(winnr()))
1438  call assert_equal('dump diff dumps/Test_popup_command_01.dump', bufname('%'))
1439  quit
1440
1441  call assert_equal(1, winnr('$'))
1442  call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump', {'vertical': 0, 'term_rows': 13, 'term_name': 'something else'})
1443  call assert_equal(2, winnr('$'))
1444  call assert_equal(&columns, winwidth(0))
1445  call assert_equal(13, winheight(0))
1446  call assert_equal('something else', bufname('%'))
1447  quit
1448
1449  call assert_equal(1, winnr('$'))
1450  call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump', {'curwin': 1})
1451  call assert_equal(1, winnr('$'))
1452  call assert_fails("call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump', {'bufnr': -1})", 'E475:')
1453  bwipe
1454
1455  set laststatus&
1456endfunc
1457
1458" When drawing the statusline the cursor position may not have been updated
1459" yet.
1460" 1. create a terminal, make it show 2 lines
1461" 2. 0.5 sec later: leave terminal window, execute "i"
1462" 3. 0.5 sec later: clear terminal window, now it's 1 line
1463" 4. 0.5 sec later: redraw, including statusline (used to trigger bug)
1464" 4. 0.5 sec later: should be done, clean up
1465func Test_terminal_statusline()
1466  CheckUnix
1467
1468  set statusline=x
1469  terminal
1470  let tbuf = bufnr('')
1471  call term_sendkeys(tbuf, "clear; echo a; echo b; sleep 1; clear\n")
1472  call timer_start(500, { tid -> feedkeys("\<C-w>j", 'tx') })
1473  call timer_start(1500, { tid -> feedkeys("\<C-l>", 'tx') })
1474  au BufLeave * if &buftype == 'terminal' | silent! normal i | endif
1475
1476  sleep 2
1477  exe tbuf . 'bwipe!'
1478  au! BufLeave
1479  set statusline=
1480endfunc
1481
1482func Test_terminal_window_focus()
1483  let winid1 = win_getid()
1484  terminal
1485  let winid2 = win_getid()
1486  call feedkeys("\<C-W>j", 'xt')
1487  call assert_equal(winid1, win_getid())
1488  call feedkeys("\<C-W>k", 'xt')
1489  call assert_equal(winid2, win_getid())
1490  " can use a cursor key here
1491  call feedkeys("\<C-W>\<Down>", 'xt')
1492  call assert_equal(winid1, win_getid())
1493  call feedkeys("\<C-W>\<Up>", 'xt')
1494  call assert_equal(winid2, win_getid())
1495
1496  bwipe!
1497endfunc
1498
1499func Api_drop_common(options)
1500  call assert_equal(1, winnr('$'))
1501
1502  " Use the title termcap entries to output the escape sequence.
1503  call writefile([
1504	\ 'set title',
1505	\ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"',
1506	\ 'let &titlestring = ''["drop","Xtextfile"' . a:options . ']''',
1507	\ 'redraw',
1508	\ "set t_ts=",
1509	\ ], 'Xscript')
1510  let buf = RunVimInTerminal('-S Xscript', {})
1511  call WaitFor({-> bufnr('Xtextfile') > 0})
1512  call assert_equal('Xtextfile', expand('%:t'))
1513  call assert_true(winnr('$') >= 3)
1514  return buf
1515endfunc
1516
1517func Test_terminal_api_drop_newwin()
1518  CheckRunVimInTerminal
1519  let buf = Api_drop_common('')
1520  call assert_equal(0, &bin)
1521  call assert_equal('', &fenc)
1522
1523  call StopVimInTerminal(buf)
1524  call delete('Xscript')
1525  bwipe Xtextfile
1526endfunc
1527
1528func Test_terminal_api_drop_newwin_bin()
1529  CheckRunVimInTerminal
1530  let buf = Api_drop_common(',{"bin":1}')
1531  call assert_equal(1, &bin)
1532
1533  call StopVimInTerminal(buf)
1534  call delete('Xscript')
1535  bwipe Xtextfile
1536endfunc
1537
1538func Test_terminal_api_drop_newwin_binary()
1539  CheckRunVimInTerminal
1540  let buf = Api_drop_common(',{"binary":1}')
1541  call assert_equal(1, &bin)
1542
1543  call StopVimInTerminal(buf)
1544  call delete('Xscript')
1545  bwipe Xtextfile
1546endfunc
1547
1548func Test_terminal_api_drop_newwin_nobin()
1549  CheckRunVimInTerminal
1550  set binary
1551  let buf = Api_drop_common(',{"nobin":1}')
1552  call assert_equal(0, &bin)
1553
1554  call StopVimInTerminal(buf)
1555  call delete('Xscript')
1556  bwipe Xtextfile
1557  set nobinary
1558endfunc
1559
1560func Test_terminal_api_drop_newwin_nobinary()
1561  CheckRunVimInTerminal
1562  set binary
1563  let buf = Api_drop_common(',{"nobinary":1}')
1564  call assert_equal(0, &bin)
1565
1566  call StopVimInTerminal(buf)
1567  call delete('Xscript')
1568  bwipe Xtextfile
1569  set nobinary
1570endfunc
1571
1572func Test_terminal_api_drop_newwin_ff()
1573  CheckRunVimInTerminal
1574  let buf = Api_drop_common(',{"ff":"dos"}')
1575  call assert_equal("dos", &ff)
1576
1577  call StopVimInTerminal(buf)
1578  call delete('Xscript')
1579  bwipe Xtextfile
1580endfunc
1581
1582func Test_terminal_api_drop_newwin_fileformat()
1583  CheckRunVimInTerminal
1584  let buf = Api_drop_common(',{"fileformat":"dos"}')
1585  call assert_equal("dos", &ff)
1586
1587  call StopVimInTerminal(buf)
1588  call delete('Xscript')
1589  bwipe Xtextfile
1590endfunc
1591
1592func Test_terminal_api_drop_newwin_enc()
1593  CheckRunVimInTerminal
1594  let buf = Api_drop_common(',{"enc":"utf-16"}')
1595  call assert_equal("utf-16", &fenc)
1596
1597  call StopVimInTerminal(buf)
1598  call delete('Xscript')
1599  bwipe Xtextfile
1600endfunc
1601
1602func Test_terminal_api_drop_newwin_encoding()
1603  CheckRunVimInTerminal
1604  let buf = Api_drop_common(',{"encoding":"utf-16"}')
1605  call assert_equal("utf-16", &fenc)
1606
1607  call StopVimInTerminal(buf)
1608  call delete('Xscript')
1609  bwipe Xtextfile
1610endfunc
1611
1612func Test_terminal_api_drop_oldwin()
1613  CheckRunVimInTerminal
1614  let firstwinid = win_getid()
1615  split Xtextfile
1616  let textfile_winid = win_getid()
1617  call assert_equal(2, winnr('$'))
1618  call win_gotoid(firstwinid)
1619
1620  " Use the title termcap entries to output the escape sequence.
1621  call writefile([
1622	\ 'set title',
1623	\ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"',
1624	\ 'let &titlestring = ''["drop","Xtextfile"]''',
1625	\ 'redraw',
1626	\ "set t_ts=",
1627	\ ], 'Xscript')
1628  let buf = RunVimInTerminal('-S Xscript', {'rows': 10})
1629  call WaitForAssert({-> assert_equal('Xtextfile', expand('%:t'))})
1630  call assert_equal(textfile_winid, win_getid())
1631
1632  call StopVimInTerminal(buf)
1633  call delete('Xscript')
1634  bwipe Xtextfile
1635endfunc
1636
1637func Tapi_TryThis(bufnum, arg)
1638  let g:called_bufnum = a:bufnum
1639  let g:called_arg = a:arg
1640endfunc
1641
1642func WriteApiCall(funcname)
1643  " Use the title termcap entries to output the escape sequence.
1644  call writefile([
1645	\ 'set title',
1646	\ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"',
1647	\ 'let &titlestring = ''["call","' . a:funcname . '",["hello",123]]''',
1648	\ 'redraw',
1649	\ "set t_ts=",
1650	\ ], 'Xscript')
1651endfunc
1652
1653func Test_terminal_api_call()
1654  CheckRunVimInTerminal
1655
1656  unlet! g:called_bufnum
1657  unlet! g:called_arg
1658
1659  call WriteApiCall('Tapi_TryThis')
1660
1661  " Default
1662  let buf = RunVimInTerminal('-S Xscript', {})
1663  call WaitFor({-> exists('g:called_bufnum')})
1664  call assert_equal(buf, g:called_bufnum)
1665  call assert_equal(['hello', 123], g:called_arg)
1666  call StopVimInTerminal(buf)
1667
1668  unlet! g:called_bufnum
1669  unlet! g:called_arg
1670
1671  " Enable explicitly
1672  let buf = RunVimInTerminal('-S Xscript', {'term_api': 'Tapi_Try'})
1673  call WaitFor({-> exists('g:called_bufnum')})
1674  call assert_equal(buf, g:called_bufnum)
1675  call assert_equal(['hello', 123], g:called_arg)
1676  call StopVimInTerminal(buf)
1677
1678  unlet! g:called_bufnum
1679  unlet! g:called_arg
1680
1681  func! ApiCall_TryThis(bufnum, arg)
1682    let g:called_bufnum2 = a:bufnum
1683    let g:called_arg2 = a:arg
1684  endfunc
1685
1686  call WriteApiCall('ApiCall_TryThis')
1687
1688  " Use prefix match
1689  let buf = RunVimInTerminal('-S Xscript', {'term_api': 'ApiCall_'})
1690  call WaitFor({-> exists('g:called_bufnum2')})
1691  call assert_equal(buf, g:called_bufnum2)
1692  call assert_equal(['hello', 123], g:called_arg2)
1693  call StopVimInTerminal(buf)
1694
1695  call assert_fails("call term_start('ls', {'term_api' : []})", 'E730:')
1696
1697  unlet! g:called_bufnum2
1698  unlet! g:called_arg2
1699
1700  call delete('Xscript')
1701  delfunction! ApiCall_TryThis
1702  unlet! g:called_bufnum2
1703  unlet! g:called_arg2
1704endfunc
1705
1706func Test_terminal_api_call_fails()
1707  CheckRunVimInTerminal
1708
1709  func! TryThis(bufnum, arg)
1710    let g:called_bufnum3 = a:bufnum
1711    let g:called_arg3 = a:arg
1712  endfunc
1713
1714  call WriteApiCall('TryThis')
1715
1716  unlet! g:called_bufnum3
1717  unlet! g:called_arg3
1718
1719  " Not permitted
1720  call ch_logfile('Xlog', 'w')
1721  let buf = RunVimInTerminal('-S Xscript', {'term_api': ''})
1722  call WaitForAssert({-> assert_match('Unpermitted function: TryThis', string(readfile('Xlog')))})
1723  call assert_false(exists('g:called_bufnum3'))
1724  call assert_false(exists('g:called_arg3'))
1725  call StopVimInTerminal(buf)
1726
1727  " No match
1728  call ch_logfile('Xlog', 'w')
1729  let buf = RunVimInTerminal('-S Xscript', {'term_api': 'TryThat'})
1730  call WaitFor({-> string(readfile('Xlog')) =~ 'Unpermitted function: TryThis'})
1731  call assert_false(exists('g:called_bufnum3'))
1732  call assert_false(exists('g:called_arg3'))
1733  call StopVimInTerminal(buf)
1734
1735  call delete('Xscript')
1736  call ch_logfile('')
1737  call delete('Xlog')
1738  delfunction! TryThis
1739  unlet! g:called_bufnum3
1740  unlet! g:called_arg3
1741endfunc
1742
1743let s:caught_e937 = 0
1744
1745func Tapi_Delete(bufnum, arg)
1746  try
1747    execute 'bdelete!' a:bufnum
1748  catch /E937:/
1749    let s:caught_e937 = 1
1750  endtry
1751endfunc
1752
1753func Test_terminal_api_call_fail_delete()
1754  CheckRunVimInTerminal
1755
1756  call WriteApiCall('Tapi_Delete')
1757  let buf = RunVimInTerminal('-S Xscript', {})
1758  call WaitForAssert({-> assert_equal(1, s:caught_e937)})
1759
1760  call StopVimInTerminal(buf)
1761  call delete('Xscript')
1762  call ch_logfile('', '')
1763endfunc
1764
1765func Test_terminal_setapi_and_call()
1766  CheckRunVimInTerminal
1767
1768  call WriteApiCall('Tapi_TryThis')
1769  call ch_logfile('Xlog', 'w')
1770
1771  unlet! g:called_bufnum
1772  unlet! g:called_arg
1773
1774  let buf = RunVimInTerminal('-S Xscript', {'term_api': ''})
1775  call WaitForAssert({-> assert_match('Unpermitted function: Tapi_TryThis', string(readfile('Xlog')))})
1776  call assert_false(exists('g:called_bufnum'))
1777  call assert_false(exists('g:called_arg'))
1778
1779  eval buf->term_setapi('Tapi_')
1780  call term_sendkeys(buf, ":set notitle\<CR>")
1781  call term_sendkeys(buf, ":source Xscript\<CR>")
1782  call WaitFor({-> exists('g:called_bufnum')})
1783  call assert_equal(buf, g:called_bufnum)
1784  call assert_equal(['hello', 123], g:called_arg)
1785
1786  call StopVimInTerminal(buf)
1787
1788  call delete('Xscript')
1789  call ch_logfile('')
1790  call delete('Xlog')
1791  unlet! g:called_bufnum
1792  unlet! g:called_arg
1793endfunc
1794
1795func Test_terminal_api_arg()
1796  CheckRunVimInTerminal
1797
1798  call WriteApiCall('Tapi_TryThis')
1799  call ch_logfile('Xlog', 'w')
1800
1801  unlet! g:called_bufnum
1802  unlet! g:called_arg
1803
1804  execute 'term ++api= ' .. GetVimCommandCleanTerm() .. '-S Xscript'
1805  let buf = bufnr('%')
1806  call WaitForAssert({-> assert_match('Unpermitted function: Tapi_TryThis', string(readfile('Xlog')))})
1807  call assert_false(exists('g:called_bufnum'))
1808  call assert_false(exists('g:called_arg'))
1809
1810  call StopVimInTerminal(buf)
1811
1812  call ch_logfile('Xlog', 'w')
1813
1814  execute 'term ++api=Tapi_ ' .. GetVimCommandCleanTerm() .. '-S Xscript'
1815  let buf = bufnr('%')
1816  call WaitFor({-> exists('g:called_bufnum')})
1817  call assert_equal(buf, g:called_bufnum)
1818  call assert_equal(['hello', 123], g:called_arg)
1819
1820  call StopVimInTerminal(buf)
1821
1822  call delete('Xscript')
1823  call ch_logfile('')
1824  call delete('Xlog')
1825  unlet! g:called_bufnum
1826  unlet! g:called_arg
1827endfunc
1828
1829func Test_terminal_ansicolors_default()
1830  CheckFunction term_getansicolors
1831
1832  let colors = [
1833	\ '#000000', '#e00000',
1834	\ '#00e000', '#e0e000',
1835	\ '#0000e0', '#e000e0',
1836	\ '#00e0e0', '#e0e0e0',
1837	\ '#808080', '#ff4040',
1838	\ '#40ff40', '#ffff40',
1839	\ '#4040ff', '#ff40ff',
1840	\ '#40ffff', '#ffffff',
1841	\]
1842
1843  let buf = Run_shell_in_terminal({})
1844  call assert_equal(colors, term_getansicolors(buf))
1845  call StopShellInTerminal(buf)
1846  call TermWait(buf)
1847  call assert_equal([], term_getansicolors(buf))
1848
1849  exe buf . 'bwipe'
1850endfunc
1851
1852let s:test_colors = [
1853	\ '#616e64', '#0d0a79',
1854	\ '#6d610d', '#0a7373',
1855	\ '#690d0a', '#6d696e',
1856	\ '#0d0a6f', '#616e0d',
1857	\ '#0a6479', '#6d0d0a',
1858	\ '#617373', '#0d0a69',
1859	\ '#6d690d', '#0a6e6f',
1860	\ '#610d0a', '#6e6479',
1861	\]
1862
1863func Test_terminal_ansicolors_global()
1864  CheckFeature termguicolors
1865  CheckFunction term_getansicolors
1866
1867  let g:terminal_ansi_colors = reverse(copy(s:test_colors))
1868  let buf = Run_shell_in_terminal({})
1869  call assert_equal(g:terminal_ansi_colors, term_getansicolors(buf))
1870  call StopShellInTerminal(buf)
1871  call TermWait(buf)
1872
1873  exe buf . 'bwipe'
1874  unlet g:terminal_ansi_colors
1875endfunc
1876
1877func Test_terminal_ansicolors_func()
1878  CheckFeature termguicolors
1879  CheckFunction term_getansicolors
1880
1881  let g:terminal_ansi_colors = reverse(copy(s:test_colors))
1882  let buf = Run_shell_in_terminal({'ansi_colors': s:test_colors})
1883  call assert_equal(s:test_colors, term_getansicolors(buf))
1884
1885  call term_setansicolors(buf, g:terminal_ansi_colors)
1886  call assert_equal(g:terminal_ansi_colors, buf->term_getansicolors())
1887
1888  let colors = [
1889	\ 'ivory', 'AliceBlue',
1890	\ 'grey67', 'dark goldenrod',
1891	\ 'SteelBlue3', 'PaleVioletRed4',
1892	\ 'MediumPurple2', 'yellow2',
1893	\ 'RosyBrown3', 'OrangeRed2',
1894	\ 'white smoke', 'navy blue',
1895	\ 'grey47', 'gray97',
1896	\ 'MistyRose2', 'DodgerBlue4',
1897	\]
1898  eval buf->term_setansicolors(colors)
1899
1900  let colors[4] = 'Invalid'
1901  call assert_fails('call term_setansicolors(buf, colors)', 'E254:')
1902  call assert_fails('call term_setansicolors(buf, {})', 'E714:')
1903
1904  call StopShellInTerminal(buf)
1905  call TermWait(buf)
1906  call assert_equal(0, term_setansicolors(buf, []))
1907  exe buf . 'bwipe'
1908endfunc
1909
1910func Test_terminal_all_ansi_colors()
1911  CheckRunVimInTerminal
1912
1913  " Use all the ANSI colors.
1914  call writefile([
1915	\ 'call setline(1, "AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPP XXYYZZ")',
1916	\ 'hi Tblack ctermfg=0 ctermbg=8',
1917	\ 'hi Tdarkred ctermfg=1 ctermbg=9',
1918	\ 'hi Tdarkgreen ctermfg=2 ctermbg=10',
1919	\ 'hi Tbrown ctermfg=3 ctermbg=11',
1920	\ 'hi Tdarkblue ctermfg=4 ctermbg=12',
1921	\ 'hi Tdarkmagenta ctermfg=5 ctermbg=13',
1922	\ 'hi Tdarkcyan ctermfg=6 ctermbg=14',
1923	\ 'hi Tlightgrey ctermfg=7 ctermbg=15',
1924	\ 'hi Tdarkgrey ctermfg=8 ctermbg=0',
1925	\ 'hi Tred ctermfg=9 ctermbg=1',
1926	\ 'hi Tgreen ctermfg=10 ctermbg=2',
1927	\ 'hi Tyellow ctermfg=11 ctermbg=3',
1928	\ 'hi Tblue ctermfg=12 ctermbg=4',
1929	\ 'hi Tmagenta ctermfg=13 ctermbg=5',
1930	\ 'hi Tcyan ctermfg=14 ctermbg=6',
1931	\ 'hi Twhite ctermfg=15 ctermbg=7',
1932	\ 'hi TdarkredBold ctermfg=1 cterm=bold',
1933	\ 'hi TgreenBold ctermfg=10 cterm=bold',
1934	\ 'hi TmagentaBold ctermfg=13 cterm=bold ctermbg=5',
1935	\ '',
1936	\ 'call  matchadd("Tblack", "A")',
1937	\ 'call  matchadd("Tdarkred", "B")',
1938	\ 'call  matchadd("Tdarkgreen", "C")',
1939	\ 'call  matchadd("Tbrown", "D")',
1940	\ 'call  matchadd("Tdarkblue", "E")',
1941	\ 'call  matchadd("Tdarkmagenta", "F")',
1942	\ 'call  matchadd("Tdarkcyan", "G")',
1943	\ 'call  matchadd("Tlightgrey", "H")',
1944	\ 'call  matchadd("Tdarkgrey", "I")',
1945	\ 'call  matchadd("Tred", "J")',
1946	\ 'call  matchadd("Tgreen", "K")',
1947	\ 'call  matchadd("Tyellow", "L")',
1948	\ 'call  matchadd("Tblue", "M")',
1949	\ 'call  matchadd("Tmagenta", "N")',
1950	\ 'call  matchadd("Tcyan", "O")',
1951	\ 'call  matchadd("Twhite", "P")',
1952	\ 'call  matchadd("TdarkredBold", "X")',
1953	\ 'call  matchadd("TgreenBold", "Y")',
1954	\ 'call  matchadd("TmagentaBold", "Z")',
1955	\ 'redraw',
1956	\ ], 'Xcolorscript')
1957  let buf = RunVimInTerminal('-S Xcolorscript', {'rows': 10})
1958  call VerifyScreenDump(buf, 'Test_terminal_all_ansi_colors', {})
1959
1960  call term_sendkeys(buf, ":q\<CR>")
1961  call StopVimInTerminal(buf)
1962  call delete('Xcolorscript')
1963endfunc
1964
1965
1966" vim: shiftwidth=2 sts=2 expandtab
1967