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 Test_finish_open_close()
356  call assert_equal(1, winnr('$'))
357
358  if s:python != ''
359    let cmd = s:python . " test_short_sleep.py"
360    let waittime = 500
361  else
362    echo 'This will take five seconds...'
363    let waittime = 2000
364    if has('win32')
365      let cmd = $windir . '\system32\timeout.exe 1'
366    else
367      let cmd = 'sleep 1'
368    endif
369  endif
370
371  exe 'terminal ++close ' . cmd
372  call assert_equal(2, winnr('$'))
373  wincmd p
374  call WaitFor("winnr('$') == 1", waittime)
375  call assert_equal(1, winnr('$'))
376
377  call term_start(cmd, {'term_finish': 'close'})
378  call assert_equal(2, winnr('$'))
379  wincmd p
380  call WaitFor("winnr('$') == 1", waittime)
381  call assert_equal(1, winnr('$'))
382
383  exe 'terminal ++open ' . cmd
384  close!
385  call WaitFor("winnr('$') == 2", waittime)
386  call assert_equal(2, winnr('$'))
387  bwipe
388
389  call term_start(cmd, {'term_finish': 'open'})
390  close!
391  call WaitFor("winnr('$') == 2", waittime)
392  call assert_equal(2, winnr('$'))
393  bwipe
394
395  exe 'terminal ++hidden ++open ' . cmd
396  call assert_equal(1, winnr('$'))
397  call WaitFor("winnr('$') == 2", waittime)
398  call assert_equal(2, winnr('$'))
399  bwipe
400
401  call term_start(cmd, {'term_finish': 'open', 'hidden': 1})
402  call assert_equal(1, winnr('$'))
403  call WaitFor("winnr('$') == 2", waittime)
404  call assert_equal(2, winnr('$'))
405  bwipe
406
407  call assert_fails("call term_start(cmd, {'term_opencmd': 'open'})", 'E475:')
408  call assert_fails("call term_start(cmd, {'term_opencmd': 'split %x'})", 'E475:')
409  call assert_fails("call term_start(cmd, {'term_opencmd': 'split %d and %s'})", 'E475:')
410  call assert_fails("call term_start(cmd, {'term_opencmd': 'split % and %d'})", 'E475:')
411
412  call term_start(cmd, {'term_finish': 'open', 'term_opencmd': '4split | buffer %d'})
413  close!
414  call WaitFor("winnr('$') == 2", waittime)
415  call assert_equal(2, winnr('$'))
416  call assert_equal(4, winheight(0))
417  bwipe
418endfunc
419
420func Test_terminal_cwd()
421  if !executable('pwd')
422    return
423  endif
424  call mkdir('Xdir')
425  let buf = term_start('pwd', {'cwd': 'Xdir'})
426  call WaitFor('"Xdir" == fnamemodify(getline(1), ":t")')
427  call assert_equal('Xdir', fnamemodify(getline(1), ":t"))
428
429  exe buf . 'bwipe'
430  call delete('Xdir', 'rf')
431endfunc
432
433func Test_terminal_env()
434  let g:buf = Run_shell_in_terminal({'env': {'TESTENV': 'correct'}})
435  " Wait for the shell to display a prompt
436  call WaitFor('term_getline(g:buf, 1) != ""')
437  if has('win32')
438    call term_sendkeys(g:buf, "echo %TESTENV%\r")
439  else
440    call term_sendkeys(g:buf, "echo $TESTENV\r")
441  endif
442  call term_wait(g:buf)
443  call Stop_shell_in_terminal(g:buf)
444  call WaitFor('getline(2) == "correct"')
445  call assert_equal('correct', getline(2))
446
447  exe g:buf . 'bwipe'
448  unlet g:buf
449endfunc
450
451" must be last, we can't go back from GUI to terminal
452func Test_zz_terminal_in_gui()
453  if !CanRunGui()
454    return
455  endif
456
457  " Ignore the "failed to create input context" error.
458  call test_ignore_error('E285:')
459
460  gui -f
461
462  call assert_equal(1, winnr('$'))
463  let buf = Run_shell_in_terminal({'term_finish': 'close'})
464  call Stop_shell_in_terminal(buf)
465  call term_wait(buf)
466
467  " closing window wipes out the terminal buffer a with finished job
468  call WaitFor("winnr('$') == 1")
469  call assert_equal(1, winnr('$'))
470  call assert_equal("", bufname(buf))
471
472  unlet g:job
473endfunc
474
475func Test_terminal_list_args()
476  let buf = term_start([&shell, &shellcmdflag, 'echo "123"'])
477  call assert_fails(buf . 'bwipe', 'E517')
478  exe buf . 'bwipe!'
479  call assert_equal("", bufname(buf))
480endfunction
481
482func Test_terminal_noblock()
483  let buf = term_start(&shell)
484  if has('mac')
485    " The shell or something else has a problem dealing with more than 1000
486    " characters at the same time.
487    let len = 1000
488  else
489    let len = 5000
490  endif
491
492  for c in ['a','b','c','d','e','f','g','h','i','j','k']
493    call term_sendkeys(buf, 'echo ' . repeat(c, len) . "\<cr>")
494  endfor
495  call term_sendkeys(buf, "echo done\<cr>")
496
497  " On MS-Windows there is an extra empty line below "done".  Find "done" in
498  " the last-but-one or the last-but-two line.
499  let lnum = term_getsize(buf)[0] - 1
500  call WaitFor({-> term_getline(buf, lnum) =~ "done" || term_getline(buf, lnum - 1) =~ "done"}, 3000)
501  let line = term_getline(buf, lnum)
502  if line !~ 'done'
503    let line = term_getline(buf, lnum - 1)
504  endif
505  call assert_match('done', line)
506
507  let g:job = term_getjob(buf)
508  call Stop_shell_in_terminal(buf)
509  call term_wait(buf)
510  unlet g:job
511  bwipe
512endfunc
513
514func Test_terminal_write_stdin()
515  if !executable('wc')
516    throw 'skipped: wc command not available'
517  endif
518  new
519  call setline(1, ['one', 'two', 'three'])
520  %term wc
521  call WaitFor('getline("$") =~ "3"')
522  let nrs = split(getline('$'))
523  call assert_equal(['3', '3', '14'], nrs)
524  bwipe
525
526  new
527  call setline(1, ['one', 'two', 'three', 'four'])
528  2,3term wc
529  call WaitFor('getline("$") =~ "2"')
530  let nrs = split(getline('$'))
531  call assert_equal(['2', '2', '10'], nrs)
532  bwipe
533
534  if executable('python')
535    new
536    call setline(1, ['print("hello")'])
537    1term ++eof=exit() python
538    " MS-Windows echoes the input, Unix doesn't.
539    call WaitFor('getline("$") =~ "exit" || getline(1) =~ "hello"')
540    if getline(1) =~ 'hello'
541      call assert_equal('hello', getline(1))
542    else
543      call assert_equal('hello', getline(line('$') - 1))
544    endif
545    bwipe
546
547    if has('win32')
548      new
549      call setline(1, ['print("hello")'])
550      1term ++eof=<C-Z> python
551      call WaitFor('getline("$") =~ "Z"')
552      call assert_equal('hello', getline(line('$') - 1))
553      bwipe
554    endif
555  endif
556
557  bwipe!
558endfunc
559
560func Test_terminal_no_cmd()
561  " Todo: make this work in the GUI
562  if !has('gui_running')
563    return
564  endif
565  let buf = term_start('NONE', {})
566  call assert_notequal(0, buf)
567
568  let pty = job_info(term_getjob(buf))['tty_out']
569  call assert_notequal('', pty)
570  if has('win32')
571    silent exe '!start cmd /c "echo look here > ' . pty . '"'
572  else
573    call system('echo "look here" > ' . pty)
574  endif
575  let g:buf = buf
576  call WaitFor('term_getline(g:buf, 1) =~ "look here"')
577
578  call assert_match('look here', term_getline(buf, 1))
579  bwipe!
580endfunc
581
582func Test_terminal_special_chars()
583  " this file name only works on Unix
584  if !has('unix')
585    return
586  endif
587  call mkdir('Xdir with spaces')
588  call writefile(['x'], 'Xdir with spaces/quoted"file')
589  term ls Xdir\ with\ spaces/quoted\"file
590  call WaitFor('term_getline("", 1) =~ "quoted"')
591  call assert_match('quoted"file', term_getline('', 1))
592  call term_wait('')
593
594  call delete('Xdir with spaces', 'rf')
595  bwipe
596endfunc
597
598func Test_terminal_wrong_options()
599  call assert_fails('call term_start(&shell, {
600	\ "in_io": "file",
601	\ "in_name": "xxx",
602	\ "out_io": "file",
603	\ "out_name": "xxx",
604	\ "err_io": "file",
605	\ "err_name": "xxx"
606	\ })', 'E474:')
607  call assert_fails('call term_start(&shell, {
608	\ "out_buf": bufnr("%")
609	\ })', 'E474:')
610  call assert_fails('call term_start(&shell, {
611	\ "err_buf": bufnr("%")
612	\ })', 'E474:')
613endfunc
614
615func Test_terminal_redir_file()
616  " TODO: this should work on MS-Window
617  if has('unix')
618    let cmd = Get_cat_123_cmd()
619    let buf = term_start(cmd, {'out_io': 'file', 'out_name': 'Xfile'})
620    call term_wait(buf)
621    call WaitFor('len(readfile("Xfile")) > 0')
622    call assert_match('123', readfile('Xfile')[0])
623    let g:job = term_getjob(buf)
624    call WaitFor('job_status(g:job) == "dead"')
625    call delete('Xfile')
626    bwipe
627  endif
628
629  if has('unix')
630    call writefile(['one line'], 'Xfile')
631    let buf = term_start('cat', {'in_io': 'file', 'in_name': 'Xfile'})
632    call term_wait(buf)
633    call WaitFor('term_getline(' . buf . ', 1) == "one line"')
634    call assert_equal('one line', term_getline(buf, 1))
635    let g:job = term_getjob(buf)
636    call WaitFor('job_status(g:job) == "dead"')
637    bwipe
638    call delete('Xfile')
639  endif
640endfunc
641
642func TerminalTmap(remap)
643  let buf = Run_shell_in_terminal({})
644  call assert_equal('t', mode())
645
646  if a:remap
647    tmap 123 456
648  else
649    tnoremap 123 456
650  endif
651  tmap 456 abcde
652  call assert_equal('456', maparg('123', 't'))
653  call assert_equal('abcde', maparg('456', 't'))
654  call feedkeys("123", 'tx')
655  let g:buf = buf
656  call WaitFor("term_getline(g:buf,term_getcursor(g:buf)[0]) =~ 'abcde\\|456'")
657  let lnum = term_getcursor(buf)[0]
658  if a:remap
659    call assert_match('abcde', term_getline(buf, lnum))
660  else
661    call assert_match('456', term_getline(buf, lnum))
662  endif
663
664  call term_sendkeys(buf, "\r")
665  call Stop_shell_in_terminal(buf)
666  call term_wait(buf)
667
668  tunmap 123
669  tunmap 456
670  call assert_equal('', maparg('123', 't'))
671  close
672  unlet g:job
673endfunc
674
675func Test_terminal_tmap()
676  call TerminalTmap(1)
677  call TerminalTmap(0)
678endfunc
679
680func Test_terminal_wall()
681  let buf = Run_shell_in_terminal({})
682  wall
683  call Stop_shell_in_terminal(buf)
684  call term_wait(buf)
685  exe buf . 'bwipe'
686  unlet g:job
687endfunc
688
689func Test_terminal_composing_unicode()
690  let save_enc = &encoding
691  set encoding=utf-8
692
693  if has('win32')
694    let cmd = "cmd /K chcp 65001"
695    let lnum = [3, 6, 9]
696  else
697    let cmd = &shell
698    let lnum = [1, 3, 5]
699  endif
700
701  enew
702  let buf = term_start(cmd, {'curwin': bufnr('')})
703  let g:job = term_getjob(buf)
704  call term_wait(buf, 50)
705
706  " ascii + composing
707  let txt = "a\u0308bc"
708  call term_sendkeys(buf, "echo " . txt . "\r")
709  call term_wait(buf, 50)
710  call assert_match("echo " . txt, term_getline(buf, lnum[0]))
711  call assert_equal(txt, term_getline(buf, lnum[0] + 1))
712  let l = term_scrape(buf, lnum[0] + 1)
713  call assert_equal("a\u0308", l[0].chars)
714  call assert_equal("b", l[1].chars)
715  call assert_equal("c", l[2].chars)
716
717  " multibyte + composing
718  let txt = "\u304b\u3099\u304e\u304f\u3099\u3052\u3053\u3099"
719  call term_sendkeys(buf, "echo " . txt . "\r")
720  call term_wait(buf, 50)
721  call assert_match("echo " . txt, term_getline(buf, lnum[1]))
722  call assert_equal(txt, term_getline(buf, lnum[1] + 1))
723  let l = term_scrape(buf, lnum[1] + 1)
724  call assert_equal("\u304b\u3099", l[0].chars)
725  call assert_equal("\u304e", l[1].chars)
726  call assert_equal("\u304f\u3099", l[2].chars)
727  call assert_equal("\u3052", l[3].chars)
728  call assert_equal("\u3053\u3099", l[4].chars)
729
730  " \u00a0 + composing
731  let txt = "abc\u00a0\u0308"
732  call term_sendkeys(buf, "echo " . txt . "\r")
733  call term_wait(buf, 50)
734  call assert_match("echo " . txt, term_getline(buf, lnum[2]))
735  call assert_equal(txt, term_getline(buf, lnum[2] + 1))
736  let l = term_scrape(buf, lnum[2] + 1)
737  call assert_equal("\u00a0\u0308", l[3].chars)
738
739  call term_sendkeys(buf, "exit\r")
740  call WaitFor('job_status(g:job) == "dead"')
741  call assert_equal('dead', job_status(g:job))
742  bwipe!
743  unlet g:job
744  let &encoding = save_enc
745endfunc
746