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