1" Tests for the terminal window.
2
3if !has('terminal')
4  finish
5endif
6
7source shared.vim
8
9let s:python = PythonProg()
10
11" Open a terminal with a shell, assign the job to g:job and return the buffer
12" number.
13func Run_shell_in_terminal(options)
14  if has('win32')
15    let buf = term_start([&shell,'/k'], a:options)
16  else
17    let buf = term_start(&shell, a:options)
18  endif
19
20  let termlist = term_list()
21  call assert_equal(1, len(termlist))
22  call assert_equal(buf, termlist[0])
23
24  let g:job = term_getjob(buf)
25  call assert_equal(v:t_job, type(g:job))
26
27  let string = string({'job': term_getjob(buf)})
28  call assert_match("{'job': 'process \\d\\+ run'}", string)
29
30  return buf
31endfunc
32
33" Stops the shell started by Run_shell_in_terminal().
34func Stop_shell_in_terminal(buf)
35  call term_sendkeys(a:buf, "exit\r")
36  call WaitFor('job_status(g:job) == "dead"')
37  call assert_equal('dead', job_status(g:job))
38endfunc
39
40func Test_terminal_basic()
41  au BufWinEnter * if &buftype == 'terminal' | let b:done = 'yes' | endif
42  let buf = Run_shell_in_terminal({})
43
44  if has("unix")
45    call assert_match('^/dev/', job_info(g:job).tty_out)
46    call assert_match('^/dev/', term_gettty(''))
47  else
48    call assert_match('^\\\\.\\pipe\\', job_info(g:job).tty_out)
49    call assert_match('^\\\\.\\pipe\\', term_gettty(''))
50  endif
51  call assert_equal('t', mode())
52  call assert_equal('yes', b:done)
53  call assert_match('%aR[^\n]*running]', execute('ls'))
54
55  call Stop_shell_in_terminal(buf)
56  call term_wait(buf)
57  call assert_equal('n', mode())
58  call assert_match('%aF[^\n]*finished]', execute('ls'))
59
60  " closing window wipes out the terminal buffer a with finished job
61  close
62  call assert_equal("", bufname(buf))
63
64  au! BufWinEnter
65  unlet g:job
66endfunc
67
68func Test_terminal_make_change()
69  let buf = Run_shell_in_terminal({})
70  call Stop_shell_in_terminal(buf)
71  call term_wait(buf)
72
73  setlocal modifiable
74  exe "normal Axxx\<Esc>"
75  call assert_fails(buf . 'bwipe', 'E517')
76  undo
77
78  exe buf . 'bwipe'
79  unlet g:job
80endfunc
81
82func Test_terminal_wipe_buffer()
83  let buf = Run_shell_in_terminal({})
84  call assert_fails(buf . 'bwipe', 'E517')
85  exe buf . 'bwipe!'
86  call WaitFor('job_status(g:job) == "dead"')
87  call assert_equal('dead', job_status(g:job))
88  call assert_equal("", bufname(buf))
89
90  unlet g:job
91endfunc
92
93func Test_terminal_split_quit()
94  let buf = Run_shell_in_terminal({})
95  call term_wait(buf)
96  split
97  quit!
98  call term_wait(buf)
99  sleep 50m
100  call assert_equal('run', job_status(g:job))
101
102  quit!
103  call WaitFor('job_status(g:job) == "dead"')
104  call assert_equal('dead', job_status(g:job))
105
106  exe buf . 'bwipe'
107  unlet g:job
108endfunc
109
110func Test_terminal_hide_buffer()
111  let buf = Run_shell_in_terminal({})
112  setlocal bufhidden=hide
113  quit
114  for nr in range(1, winnr('$'))
115    call assert_notequal(winbufnr(nr), buf)
116  endfor
117  call assert_true(bufloaded(buf))
118  call assert_true(buflisted(buf))
119
120  exe 'split ' . buf . 'buf'
121  call Stop_shell_in_terminal(buf)
122  exe buf . 'bwipe'
123
124  unlet g:job
125endfunc
126
127func! s:Nasty_exit_cb(job, st)
128  exe g:buf . 'bwipe!'
129  let g:buf = 0
130endfunc
131
132func Get_cat_123_cmd()
133  if has('win32')
134    return 'cmd /c "cls && color 2 && echo 123"'
135  else
136    call writefile(["\<Esc>[32m123"], 'Xtext')
137    return "cat Xtext"
138  endif
139endfunc
140
141func Test_terminal_nasty_cb()
142  let cmd = Get_cat_123_cmd()
143  let g:buf = term_start(cmd, {'exit_cb': function('s:Nasty_exit_cb')})
144  let g:job = term_getjob(g:buf)
145
146  call WaitFor('job_status(g:job) == "dead"')
147  call WaitFor('g:buf == 0')
148  unlet g:buf
149  unlet g:job
150  call delete('Xtext')
151endfunc
152
153func Check_123(buf)
154  let l = term_scrape(a:buf, 0)
155  call assert_true(len(l) == 0)
156  let l = term_scrape(a:buf, 999)
157  call assert_true(len(l) == 0)
158  let l = term_scrape(a:buf, 1)
159  call assert_true(len(l) > 0)
160  call assert_equal('1', l[0].chars)
161  call assert_equal('2', l[1].chars)
162  call assert_equal('3', l[2].chars)
163  call assert_equal('#00e000', l[0].fg)
164  if &background == 'light'
165    call assert_equal('#ffffff', l[0].bg)
166  else
167    call assert_equal('#000000', l[0].bg)
168  endif
169
170  let l = term_getline(a:buf, -1)
171  call assert_equal('', l)
172  let l = term_getline(a:buf, 0)
173  call assert_equal('', l)
174  let l = term_getline(a:buf, 999)
175  call assert_equal('', l)
176  let l = term_getline(a:buf, 1)
177  call assert_equal('123', l)
178endfunc
179
180func Test_terminal_scrape_123()
181  let cmd = Get_cat_123_cmd()
182  let buf = term_start(cmd)
183
184  let termlist = term_list()
185  call assert_equal(1, len(termlist))
186  call assert_equal(buf, termlist[0])
187
188  " Nothing happens with invalid buffer number
189  call term_wait(1234)
190
191  call term_wait(buf)
192  " On MS-Windows we first get a startup message of two lines, wait for the
193  " "cls" to happen, after that we have one line with three characters.
194  call WaitFor({-> len(term_scrape(buf, 1)) == 3})
195  call Check_123(buf)
196
197  " Must still work after the job ended.
198  let job = term_getjob(buf)
199  call WaitFor({-> job_status(job) == "dead"})
200  call term_wait(buf)
201  call Check_123(buf)
202
203  exe buf . 'bwipe'
204  call delete('Xtext')
205endfunc
206
207func Test_terminal_scrape_multibyte()
208  if !has('multi_byte')
209    return
210  endif
211  call writefile(["léttまrs"], 'Xtext')
212  if has('win32')
213    " Run cmd with UTF-8 codepage to make the type command print the expected
214    " multibyte characters.
215    let buf = term_start("cmd /K chcp 65001")
216    call term_sendkeys(buf, "type Xtext\<CR>")
217    call term_sendkeys(buf, "exit\<CR>")
218    let line = 4
219  else
220    let buf = term_start("cat Xtext")
221    let line = 1
222  endif
223
224  call WaitFor({-> len(term_scrape(buf, line)) >= 7 && term_scrape(buf, line)[0].chars == "l"})
225  let l = term_scrape(buf, line)
226  call assert_true(len(l) >= 7)
227  call assert_equal('l', l[0].chars)
228  call assert_equal('é', l[1].chars)
229  call assert_equal(1, l[1].width)
230  call assert_equal('t', l[2].chars)
231  call assert_equal('t', l[3].chars)
232  call assert_equal('ま', l[4].chars)
233  call assert_equal(2, l[4].width)
234  call assert_equal('r', l[5].chars)
235  call assert_equal('s', l[6].chars)
236
237  let job = term_getjob(buf)
238  call WaitFor({-> job_status(job) == "dead"})
239  call term_wait(buf)
240
241  exe buf . 'bwipe'
242  call delete('Xtext')
243endfunc
244
245func Test_terminal_scroll()
246  call writefile(range(1, 200), 'Xtext')
247  if has('win32')
248    let cmd = 'cmd /c "type Xtext"'
249  else
250    let cmd = "cat Xtext"
251  endif
252  let buf = term_start(cmd)
253
254  let job = term_getjob(buf)
255  call WaitFor({-> job_status(job) == "dead"})
256  call term_wait(buf)
257  if has('win32')
258    " TODO: this should not be needed
259    sleep 100m
260  endif
261
262  let scrolled = term_getscrolled(buf)
263  call assert_equal('1', getline(1))
264  call assert_equal('1', term_getline(buf, 1 - scrolled))
265  call assert_equal('49', getline(49))
266  call assert_equal('49', term_getline(buf, 49 - scrolled))
267  call assert_equal('200', getline(200))
268  call assert_equal('200', term_getline(buf, 200 - scrolled))
269
270  exe buf . 'bwipe'
271  call delete('Xtext')
272endfunc
273
274func Test_terminal_size()
275  let cmd = Get_cat_123_cmd()
276
277  exe 'terminal ++rows=5 ' . cmd
278  let size = term_getsize('')
279  bwipe!
280  call assert_equal(5, size[0])
281
282  call term_start(cmd, {'term_rows': 6})
283  let size = term_getsize('')
284  bwipe!
285  call assert_equal(6, size[0])
286
287  vsplit
288  exe 'terminal ++rows=5 ++cols=33 ' . cmd
289  let size = term_getsize('')
290  bwipe!
291  call assert_equal([5, 33], size)
292
293  call term_start(cmd, {'term_rows': 6, 'term_cols': 36})
294  let size = term_getsize('')
295  bwipe!
296  call assert_equal([6, 36], size)
297
298  exe 'vertical terminal ++cols=20 ' . cmd
299  let size = term_getsize('')
300  bwipe!
301  call assert_equal(20, size[1])
302
303  call term_start(cmd, {'vertical': 1, 'term_cols': 26})
304  let size = term_getsize('')
305  bwipe!
306  call assert_equal(26, size[1])
307
308  split
309  exe 'vertical terminal ++rows=6 ++cols=20 ' . cmd
310  let size = term_getsize('')
311  bwipe!
312  call assert_equal([6, 20], size)
313
314  call term_start(cmd, {'vertical': 1, 'term_rows': 7, 'term_cols': 27})
315  let size = term_getsize('')
316  bwipe!
317  call assert_equal([7, 27], size)
318
319  call delete('Xtext')
320endfunc
321
322func Test_terminal_curwin()
323  let cmd = Get_cat_123_cmd()
324  call assert_equal(1, winnr('$'))
325
326  split dummy
327  exe 'terminal ++curwin ' . cmd
328  call assert_equal(2, winnr('$'))
329  bwipe!
330
331  split dummy
332  call term_start(cmd, {'curwin': 1})
333  call assert_equal(2, winnr('$'))
334  bwipe!
335
336  split dummy
337  call setline(1, 'change')
338  call assert_fails('terminal ++curwin ' . cmd, 'E37:')
339  call assert_equal(2, winnr('$'))
340  exe 'terminal! ++curwin ' . cmd
341  call assert_equal(2, winnr('$'))
342  bwipe!
343
344  split dummy
345  call setline(1, 'change')
346  call assert_fails("call term_start(cmd, {'curwin': 1})", 'E37:')
347  call assert_equal(2, winnr('$'))
348  bwipe!
349
350  split dummy
351  bwipe!
352  call delete('Xtext')
353endfunc
354
355func s:get_sleep_cmd()
356  if s:python != ''
357    let cmd = s:python . " test_short_sleep.py"
358    let waittime = 500
359  else
360    echo 'This will take five seconds...'
361    let waittime = 2000
362    if has('win32')
363      let cmd = $windir . '\system32\timeout.exe 1'
364    else
365      let cmd = 'sleep 1'
366    endif
367  endif
368  return [cmd, waittime]
369endfunc
370
371func Test_terminal_finish_open_close()
372  call assert_equal(1, winnr('$'))
373
374  let [cmd, waittime] = s:get_sleep_cmd()
375
376  exe 'terminal ++close ' . cmd
377  call assert_equal(2, winnr('$'))
378  wincmd p
379  call WaitFor("winnr('$') == 1", waittime)
380
381  call term_start(cmd, {'term_finish': 'close'})
382  call assert_equal(2, winnr('$'))
383  wincmd p
384  call WaitFor("winnr('$') == 1", waittime)
385  call assert_equal(1, winnr('$'))
386
387  exe 'terminal ++open ' . cmd
388  close!
389  call WaitFor("winnr('$') == 2", waittime)
390  call assert_equal(2, winnr('$'))
391  bwipe
392
393  call term_start(cmd, {'term_finish': 'open'})
394  close!
395  call WaitFor("winnr('$') == 2", waittime)
396  call assert_equal(2, winnr('$'))
397  bwipe
398
399  exe 'terminal ++hidden ++open ' . cmd
400  call assert_equal(1, winnr('$'))
401  call WaitFor("winnr('$') == 2", waittime)
402  call assert_equal(2, winnr('$'))
403  bwipe
404
405  call term_start(cmd, {'term_finish': 'open', 'hidden': 1})
406  call assert_equal(1, winnr('$'))
407  call WaitFor("winnr('$') == 2", waittime)
408  call assert_equal(2, winnr('$'))
409  bwipe
410
411  call assert_fails("call term_start(cmd, {'term_opencmd': 'open'})", 'E475:')
412  call assert_fails("call term_start(cmd, {'term_opencmd': 'split %x'})", 'E475:')
413  call assert_fails("call term_start(cmd, {'term_opencmd': 'split %d and %s'})", 'E475:')
414  call assert_fails("call term_start(cmd, {'term_opencmd': 'split % and %d'})", 'E475:')
415
416  call term_start(cmd, {'term_finish': 'open', 'term_opencmd': '4split | buffer %d'})
417  close!
418  call WaitFor("winnr('$') == 2", waittime)
419  call assert_equal(2, winnr('$'))
420  call assert_equal(4, winheight(0))
421  bwipe
422endfunc
423
424func Test_terminal_cwd()
425  if !executable('pwd')
426    return
427  endif
428  call mkdir('Xdir')
429  let buf = term_start('pwd', {'cwd': 'Xdir'})
430  call WaitFor('"Xdir" == fnamemodify(getline(1), ":t")')
431  call assert_equal('Xdir', fnamemodify(getline(1), ":t"))
432
433  exe buf . 'bwipe'
434  call delete('Xdir', 'rf')
435endfunc
436
437func Test_terminal_servername()
438  if !has('clientserver')
439    return
440  endif
441  let g:buf = Run_shell_in_terminal({})
442  " Wait for the shell to display a prompt
443  call WaitFor('term_getline(g:buf, 1) != ""')
444  if has('win32')
445    call term_sendkeys(g:buf, "echo %VIM_SERVERNAME%\r")
446  else
447    call term_sendkeys(g:buf, "echo $VIM_SERVERNAME\r")
448  endif
449  call term_wait(g:buf)
450  call Stop_shell_in_terminal(g:buf)
451  call WaitFor('getline(2) == v:servername')
452  call assert_equal(v:servername, getline(2))
453
454  exe g:buf . 'bwipe'
455  unlet g:buf
456endfunc
457
458func Test_terminal_env()
459  let g:buf = Run_shell_in_terminal({'env': {'TESTENV': 'correct'}})
460  " Wait for the shell to display a prompt
461  call WaitFor('term_getline(g:buf, 1) != ""')
462  if has('win32')
463    call term_sendkeys(g:buf, "echo %TESTENV%\r")
464  else
465    call term_sendkeys(g:buf, "echo $TESTENV\r")
466  endif
467  call term_wait(g:buf)
468  call Stop_shell_in_terminal(g:buf)
469  call WaitFor('getline(2) == "correct"')
470  call assert_equal('correct', getline(2))
471
472  exe g:buf . 'bwipe'
473  unlet g:buf
474endfunc
475
476" must be last, we can't go back from GUI to terminal
477func Test_zz_terminal_in_gui()
478  if !CanRunGui()
479    return
480  endif
481
482  " Ignore the "failed to create input context" error.
483  call test_ignore_error('E285:')
484
485  gui -f
486
487  call assert_equal(1, winnr('$'))
488  let buf = Run_shell_in_terminal({'term_finish': 'close'})
489  call Stop_shell_in_terminal(buf)
490  call term_wait(buf)
491
492  " closing window wipes out the terminal buffer a with finished job
493  call WaitFor("winnr('$') == 1")
494  call assert_equal(1, winnr('$'))
495  call assert_equal("", bufname(buf))
496
497  unlet g:job
498endfunc
499
500func Test_terminal_list_args()
501  let buf = term_start([&shell, &shellcmdflag, 'echo "123"'])
502  call assert_fails(buf . 'bwipe', 'E517')
503  exe buf . 'bwipe!'
504  call assert_equal("", bufname(buf))
505endfunction
506
507func Test_terminal_noblock()
508  let buf = term_start(&shell)
509  if has('mac')
510    " The shell or something else has a problem dealing with more than 1000
511    " characters at the same time.
512    let len = 1000
513  else
514    let len = 5000
515  endif
516
517  for c in ['a','b','c','d','e','f','g','h','i','j','k']
518    call term_sendkeys(buf, 'echo ' . repeat(c, len) . "\<cr>")
519  endfor
520  call term_sendkeys(buf, "echo done\<cr>")
521
522  " On MS-Windows there is an extra empty line below "done".  Find "done" in
523  " the last-but-one or the last-but-two line.
524  let lnum = term_getsize(buf)[0] - 1
525  call WaitFor({-> term_getline(buf, lnum) =~ "done" || term_getline(buf, lnum - 1) =~ "done"}, 3000)
526  let line = term_getline(buf, lnum)
527  if line !~ 'done'
528    let line = term_getline(buf, lnum - 1)
529  endif
530  call assert_match('done', line)
531
532  let g:job = term_getjob(buf)
533  call Stop_shell_in_terminal(buf)
534  call term_wait(buf)
535  unlet g:job
536  bwipe
537endfunc
538
539func Test_terminal_write_stdin()
540  if !executable('wc')
541    throw 'skipped: wc command not available'
542  endif
543  new
544  call setline(1, ['one', 'two', 'three'])
545  %term wc
546  call WaitFor('getline("$") =~ "3"')
547  let nrs = split(getline('$'))
548  call assert_equal(['3', '3', '14'], nrs)
549  bwipe
550
551  new
552  call setline(1, ['one', 'two', 'three', 'four'])
553  2,3term wc
554  call WaitFor('getline("$") =~ "2"')
555  let nrs = split(getline('$'))
556  call assert_equal(['2', '2', '10'], nrs)
557  bwipe
558
559  if executable('python')
560    new
561    call setline(1, ['print("hello")'])
562    1term ++eof=exit() python
563    " MS-Windows echoes the input, Unix doesn't.
564    call WaitFor('getline("$") =~ "exit" || getline(1) =~ "hello"')
565    if getline(1) =~ 'hello'
566      call assert_equal('hello', getline(1))
567    else
568      call assert_equal('hello', getline(line('$') - 1))
569    endif
570    bwipe
571
572    if has('win32')
573      new
574      call setline(1, ['print("hello")'])
575      1term ++eof=<C-Z> python
576      call WaitFor('getline("$") =~ "Z"')
577      call assert_equal('hello', getline(line('$') - 1))
578      bwipe
579    endif
580  endif
581
582  bwipe!
583endfunc
584
585func Test_terminal_no_cmd()
586  " Todo: make this work in the GUI
587  if !has('gui_running')
588    return
589  endif
590  let buf = term_start('NONE', {})
591  call assert_notequal(0, buf)
592
593  let pty = job_info(term_getjob(buf))['tty_out']
594  call assert_notequal('', pty)
595  if has('win32')
596    silent exe '!start cmd /c "echo look here > ' . pty . '"'
597  else
598    call system('echo "look here" > ' . pty)
599  endif
600  let g:buf = buf
601  call WaitFor('term_getline(g:buf, 1) =~ "look here"')
602
603  call assert_match('look here', term_getline(buf, 1))
604  bwipe!
605endfunc
606
607func Test_terminal_special_chars()
608  " this file name only works on Unix
609  if !has('unix')
610    return
611  endif
612  call mkdir('Xdir with spaces')
613  call writefile(['x'], 'Xdir with spaces/quoted"file')
614  term ls Xdir\ with\ spaces/quoted\"file
615  call WaitFor('term_getline("", 1) =~ "quoted"')
616  call assert_match('quoted"file', term_getline('', 1))
617  call term_wait('')
618
619  call delete('Xdir with spaces', 'rf')
620  bwipe
621endfunc
622
623func Test_terminal_wrong_options()
624  call assert_fails('call term_start(&shell, {
625	\ "in_io": "file",
626	\ "in_name": "xxx",
627	\ "out_io": "file",
628	\ "out_name": "xxx",
629	\ "err_io": "file",
630	\ "err_name": "xxx"
631	\ })', 'E474:')
632  call assert_fails('call term_start(&shell, {
633	\ "out_buf": bufnr("%")
634	\ })', 'E474:')
635  call assert_fails('call term_start(&shell, {
636	\ "err_buf": bufnr("%")
637	\ })', 'E474:')
638endfunc
639
640func Test_terminal_redir_file()
641  " TODO: this should work on MS-Window
642  if has('unix')
643    let cmd = Get_cat_123_cmd()
644    let buf = term_start(cmd, {'out_io': 'file', 'out_name': 'Xfile'})
645    call term_wait(buf)
646    call WaitFor('len(readfile("Xfile")) > 0')
647    call assert_match('123', readfile('Xfile')[0])
648    let g:job = term_getjob(buf)
649    call WaitFor('job_status(g:job) == "dead"')
650    call delete('Xfile')
651    bwipe
652  endif
653
654  if has('unix')
655    call writefile(['one line'], 'Xfile')
656    let buf = term_start('cat', {'in_io': 'file', 'in_name': 'Xfile'})
657    call term_wait(buf)
658    call WaitFor('term_getline(' . buf . ', 1) == "one line"')
659    call assert_equal('one line', term_getline(buf, 1))
660    let g:job = term_getjob(buf)
661    call WaitFor('job_status(g:job) == "dead"')
662    bwipe
663    call delete('Xfile')
664  endif
665endfunc
666
667func TerminalTmap(remap)
668  let buf = Run_shell_in_terminal({})
669  call assert_equal('t', mode())
670
671  if a:remap
672    tmap 123 456
673  else
674    tnoremap 123 456
675  endif
676  " don't use abcde, it's an existing command
677  tmap 456 abxde
678  call assert_equal('456', maparg('123', 't'))
679  call assert_equal('abxde', maparg('456', 't'))
680  call feedkeys("123", 'tx')
681  let g:buf = buf
682  call WaitFor("term_getline(g:buf,term_getcursor(g:buf)[0]) =~ 'abxde\\|456'")
683  let lnum = term_getcursor(buf)[0]
684  if a:remap
685    call assert_match('abxde', term_getline(buf, lnum))
686  else
687    call assert_match('456', term_getline(buf, lnum))
688  endif
689
690  call term_sendkeys(buf, "\r")
691  call Stop_shell_in_terminal(buf)
692  call term_wait(buf)
693
694  tunmap 123
695  tunmap 456
696  call assert_equal('', maparg('123', 't'))
697  close
698  unlet g:job
699endfunc
700
701func Test_terminal_tmap()
702  call TerminalTmap(1)
703  call TerminalTmap(0)
704endfunc
705
706func Test_terminal_wall()
707  let buf = Run_shell_in_terminal({})
708  wall
709  call Stop_shell_in_terminal(buf)
710  call term_wait(buf)
711  exe buf . 'bwipe'
712  unlet g:job
713endfunc
714
715func Test_terminal_composing_unicode()
716  let save_enc = &encoding
717  set encoding=utf-8
718
719  if has('win32')
720    let cmd = "cmd /K chcp 65001"
721    let lnum = [3, 6, 9]
722  else
723    let cmd = &shell
724    let lnum = [1, 3, 5]
725  endif
726
727  enew
728  let buf = term_start(cmd, {'curwin': bufnr('')})
729  let g:job = term_getjob(buf)
730  call term_wait(buf, 50)
731
732  " ascii + composing
733  let txt = "a\u0308bc"
734  call term_sendkeys(buf, "echo " . txt . "\r")
735  call term_wait(buf, 50)
736  call assert_match("echo " . txt, term_getline(buf, lnum[0]))
737  call assert_equal(txt, term_getline(buf, lnum[0] + 1))
738  let l = term_scrape(buf, lnum[0] + 1)
739  call assert_equal("a\u0308", l[0].chars)
740  call assert_equal("b", l[1].chars)
741  call assert_equal("c", l[2].chars)
742
743  " multibyte + composing
744  let txt = "\u304b\u3099\u304e\u304f\u3099\u3052\u3053\u3099"
745  call term_sendkeys(buf, "echo " . txt . "\r")
746  call term_wait(buf, 50)
747  call assert_match("echo " . txt, term_getline(buf, lnum[1]))
748  call assert_equal(txt, term_getline(buf, lnum[1] + 1))
749  let l = term_scrape(buf, lnum[1] + 1)
750  call assert_equal("\u304b\u3099", l[0].chars)
751  call assert_equal("\u304e", l[1].chars)
752  call assert_equal("\u304f\u3099", l[2].chars)
753  call assert_equal("\u3052", l[3].chars)
754  call assert_equal("\u3053\u3099", l[4].chars)
755
756  " \u00a0 + composing
757  let txt = "abc\u00a0\u0308"
758  call term_sendkeys(buf, "echo " . txt . "\r")
759  call term_wait(buf, 50)
760  call assert_match("echo " . txt, term_getline(buf, lnum[2]))
761  call assert_equal(txt, term_getline(buf, lnum[2] + 1))
762  let l = term_scrape(buf, lnum[2] + 1)
763  call assert_equal("\u00a0\u0308", l[3].chars)
764
765  call term_sendkeys(buf, "exit\r")
766  call WaitFor('job_status(g:job) == "dead"')
767  call assert_equal('dead', job_status(g:job))
768  bwipe!
769  unlet g:job
770  let &encoding = save_enc
771endfunc
772
773func Test_terminal_aucmd_on_close()
774  fun Nop()
775    let s:called = 1
776  endfun
777
778  aug repro
779      au!
780      au BufWinLeave * call Nop()
781  aug END
782
783  let [cmd, waittime] = s:get_sleep_cmd()
784
785  call assert_equal(1, winnr('$'))
786  new
787  call setline(1, ['one', 'two'])
788  exe 'term ++close ' . cmd
789  wincmd p
790  call WaitFor("winnr('$') == 2", waittime)
791  call assert_equal(1, s:called)
792  bwipe!
793
794  unlet s:called
795  au! repro
796  delfunc Nop
797endfunc
798