1" Tests for the terminal window. 2 3if !has('terminal') 4 finish 5endif 6 7source shared.vim 8source screendump.vim 9 10let s:python = PythonProg() 11 12" Open a terminal with a shell, assign the job to g:job and return the buffer 13" number. 14func Run_shell_in_terminal(options) 15 if has('win32') 16 let buf = term_start([&shell,'/k'], a:options) 17 else 18 let buf = term_start(&shell, a:options) 19 endif 20 21 let termlist = term_list() 22 call assert_equal(1, len(termlist)) 23 call assert_equal(buf, termlist[0]) 24 25 let g:job = term_getjob(buf) 26 call assert_equal(v:t_job, type(g:job)) 27 28 let string = string({'job': term_getjob(buf)}) 29 call assert_match("{'job': 'process \\d\\+ run'}", string) 30 31 return buf 32endfunc 33 34func Test_terminal_basic() 35 au TerminalOpen * let b:done = 'yes' 36 let buf = Run_shell_in_terminal({}) 37 38 if has("unix") 39 call assert_match('^/dev/', job_info(g:job).tty_out) 40 call assert_match('^/dev/', term_gettty('')) 41 else 42 call assert_match('^\\\\.\\pipe\\', job_info(g:job).tty_out) 43 call assert_match('^\\\\.\\pipe\\', term_gettty('')) 44 endif 45 call assert_equal('t', mode()) 46 call assert_equal('yes', b:done) 47 call assert_match('%aR[^\n]*running]', execute('ls')) 48 call assert_match('%aR[^\n]*running]', execute('ls R')) 49 call assert_notmatch('%[^\n]*running]', execute('ls F')) 50 call assert_notmatch('%[^\n]*running]', execute('ls ?')) 51 52 call Stop_shell_in_terminal(buf) 53 call term_wait(buf) 54 call assert_equal('n', mode()) 55 call assert_match('%aF[^\n]*finished]', execute('ls')) 56 call assert_match('%aF[^\n]*finished]', execute('ls F')) 57 call assert_notmatch('%[^\n]*finished]', execute('ls R')) 58 call assert_notmatch('%[^\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! TerminalOpen 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 WaitForAssert({-> assert_equal('dead', job_status(g:job))}) 87 call assert_equal("", bufname(buf)) 88 89 unlet g:job 90endfunc 91 92func Test_terminal_split_quit() 93 let buf = Run_shell_in_terminal({}) 94 call term_wait(buf) 95 split 96 quit! 97 call term_wait(buf) 98 sleep 50m 99 call assert_equal('run', job_status(g:job)) 100 101 quit! 102 call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) 103 104 exe buf . 'bwipe' 105 unlet g:job 106endfunc 107 108func Test_terminal_hide_buffer() 109 let buf = Run_shell_in_terminal({}) 110 setlocal bufhidden=hide 111 quit 112 for nr in range(1, winnr('$')) 113 call assert_notequal(winbufnr(nr), buf) 114 endfor 115 call assert_true(bufloaded(buf)) 116 call assert_true(buflisted(buf)) 117 118 exe 'split ' . buf . 'buf' 119 call Stop_shell_in_terminal(buf) 120 exe buf . 'bwipe' 121 122 unlet g:job 123endfunc 124 125func s:Nasty_exit_cb(job, st) 126 exe g:buf . 'bwipe!' 127 let g:buf = 0 128endfunc 129 130func Get_cat_123_cmd() 131 if has('win32') 132 return 'cmd /c "cls && color 2 && echo 123"' 133 else 134 call writefile(["\<Esc>[32m123"], 'Xtext') 135 return "cat Xtext" 136 endif 137endfunc 138 139func Test_terminal_nasty_cb() 140 let cmd = Get_cat_123_cmd() 141 let g:buf = term_start(cmd, {'exit_cb': function('s:Nasty_exit_cb')}) 142 let g:job = term_getjob(g:buf) 143 144 call WaitForAssert({-> assert_equal("dead", job_status(g:job))}) 145 call WaitForAssert({-> assert_equal(0, g:buf)}) 146 unlet g:buf 147 unlet g:job 148 call delete('Xtext') 149endfunc 150 151func Check_123(buf) 152 let l = term_scrape(a:buf, 0) 153 call assert_true(len(l) == 0) 154 let l = term_scrape(a:buf, 999) 155 call assert_true(len(l) == 0) 156 let l = term_scrape(a:buf, 1) 157 call assert_true(len(l) > 0) 158 call assert_equal('1', l[0].chars) 159 call assert_equal('2', l[1].chars) 160 call assert_equal('3', l[2].chars) 161 call assert_equal('#00e000', l[0].fg) 162 if has('win32') 163 " On Windows 'background' always defaults to dark, even though the terminal 164 " may use a light background. Therefore accept both white and black. 165 call assert_match('#ffffff\|#000000', l[0].bg) 166 else 167 if &background == 'light' 168 call assert_equal('#ffffff', l[0].bg) 169 else 170 call assert_equal('#000000', l[0].bg) 171 endif 172 endif 173 174 let l = term_getline(a:buf, -1) 175 call assert_equal('', l) 176 let l = term_getline(a:buf, 0) 177 call assert_equal('', l) 178 let l = term_getline(a:buf, 999) 179 call assert_equal('', l) 180 let l = term_getline(a:buf, 1) 181 call assert_equal('123', l) 182endfunc 183 184func Test_terminal_scrape_123() 185 let cmd = Get_cat_123_cmd() 186 let buf = term_start(cmd) 187 188 let termlist = term_list() 189 call assert_equal(1, len(termlist)) 190 call assert_equal(buf, termlist[0]) 191 192 " Nothing happens with invalid buffer number 193 call term_wait(1234) 194 195 call term_wait(buf) 196 " On MS-Windows we first get a startup message of two lines, wait for the 197 " "cls" to happen, after that we have one line with three characters. 198 call WaitForAssert({-> assert_equal(3, len(term_scrape(buf, 1)))}) 199 call Check_123(buf) 200 201 " Must still work after the job ended. 202 let job = term_getjob(buf) 203 call WaitForAssert({-> assert_equal("dead", job_status(job))}) 204 call term_wait(buf) 205 call Check_123(buf) 206 207 exe buf . 'bwipe' 208 call delete('Xtext') 209endfunc 210 211func Test_terminal_scrape_multibyte() 212 if !has('multi_byte') 213 return 214 endif 215 call writefile(["léttまrs"], 'Xtext') 216 if has('win32') 217 " Run cmd with UTF-8 codepage to make the type command print the expected 218 " multibyte characters. 219 let buf = term_start("cmd /K chcp 65001") 220 call term_sendkeys(buf, "type Xtext\<CR>") 221 call term_sendkeys(buf, "exit\<CR>") 222 let line = 4 223 else 224 let buf = term_start("cat Xtext") 225 let line = 1 226 endif 227 228 call WaitFor({-> len(term_scrape(buf, line)) >= 7 && term_scrape(buf, line)[0].chars == "l"}) 229 let l = term_scrape(buf, line) 230 call assert_true(len(l) >= 7) 231 call assert_equal('l', l[0].chars) 232 call assert_equal('é', l[1].chars) 233 call assert_equal(1, l[1].width) 234 call assert_equal('t', l[2].chars) 235 call assert_equal('t', l[3].chars) 236 call assert_equal('ま', l[4].chars) 237 call assert_equal(2, l[4].width) 238 call assert_equal('r', l[5].chars) 239 call assert_equal('s', l[6].chars) 240 241 let job = term_getjob(buf) 242 call WaitForAssert({-> assert_equal("dead", job_status(job))}) 243 call term_wait(buf) 244 245 exe buf . 'bwipe' 246 call delete('Xtext') 247endfunc 248 249func Test_terminal_scroll() 250 call writefile(range(1, 200), 'Xtext') 251 if has('win32') 252 let cmd = 'cmd /c "type Xtext"' 253 else 254 let cmd = "cat Xtext" 255 endif 256 let buf = term_start(cmd) 257 258 let job = term_getjob(buf) 259 call WaitForAssert({-> assert_equal("dead", job_status(job))}) 260 call term_wait(buf) 261 if has('win32') 262 " TODO: this should not be needed 263 sleep 100m 264 endif 265 266 let scrolled = term_getscrolled(buf) 267 call assert_equal('1', getline(1)) 268 call assert_equal('1', term_getline(buf, 1 - scrolled)) 269 call assert_equal('49', getline(49)) 270 call assert_equal('49', term_getline(buf, 49 - scrolled)) 271 call assert_equal('200', getline(200)) 272 call assert_equal('200', term_getline(buf, 200 - scrolled)) 273 274 exe buf . 'bwipe' 275 call delete('Xtext') 276endfunc 277 278func Test_terminal_scrollback() 279 let buf = Run_shell_in_terminal({'term_rows': 15}) 280 set termwinscroll=100 281 call writefile(range(150), 'Xtext') 282 if has('win32') 283 call term_sendkeys(buf, "type Xtext\<CR>") 284 else 285 call term_sendkeys(buf, "cat Xtext\<CR>") 286 endif 287 let rows = term_getsize(buf)[0] 288 " On MS-Windows there is an empty line, check both last line and above it. 289 call WaitForAssert({-> assert_match( '149', term_getline(buf, rows - 1) . term_getline(buf, rows - 2))}) 290 let lines = line('$') 291 call assert_inrange(91, 100, lines) 292 293 call Stop_shell_in_terminal(buf) 294 call term_wait(buf) 295 exe buf . 'bwipe' 296 set termwinscroll& 297endfunc 298 299func Test_terminal_size() 300 let cmd = Get_cat_123_cmd() 301 302 exe 'terminal ++rows=5 ' . cmd 303 let size = term_getsize('') 304 bwipe! 305 call assert_equal(5, size[0]) 306 307 call term_start(cmd, {'term_rows': 6}) 308 let size = term_getsize('') 309 bwipe! 310 call assert_equal(6, size[0]) 311 312 vsplit 313 exe 'terminal ++rows=5 ++cols=33 ' . cmd 314 call assert_equal([5, 33], term_getsize('')) 315 316 call term_setsize('', 6, 0) 317 call assert_equal([6, 33], term_getsize('')) 318 319 call term_setsize('', 0, 35) 320 call assert_equal([6, 35], term_getsize('')) 321 322 call term_setsize('', 7, 30) 323 call assert_equal([7, 30], term_getsize('')) 324 325 bwipe! 326 call assert_fails("call term_setsize('', 7, 30)", "E955:") 327 328 call term_start(cmd, {'term_rows': 6, 'term_cols': 36}) 329 let size = term_getsize('') 330 bwipe! 331 call assert_equal([6, 36], size) 332 333 exe 'vertical terminal ++cols=20 ' . cmd 334 let size = term_getsize('') 335 bwipe! 336 call assert_equal(20, size[1]) 337 338 call term_start(cmd, {'vertical': 1, 'term_cols': 26}) 339 let size = term_getsize('') 340 bwipe! 341 call assert_equal(26, size[1]) 342 343 split 344 exe 'vertical terminal ++rows=6 ++cols=20 ' . cmd 345 let size = term_getsize('') 346 bwipe! 347 call assert_equal([6, 20], size) 348 349 call term_start(cmd, {'vertical': 1, 'term_rows': 7, 'term_cols': 27}) 350 let size = term_getsize('') 351 bwipe! 352 call assert_equal([7, 27], size) 353 354 call delete('Xtext') 355endfunc 356 357func Test_terminal_curwin() 358 let cmd = Get_cat_123_cmd() 359 call assert_equal(1, winnr('$')) 360 361 split dummy 362 exe 'terminal ++curwin ' . cmd 363 call assert_equal(2, winnr('$')) 364 bwipe! 365 366 split dummy 367 call term_start(cmd, {'curwin': 1}) 368 call assert_equal(2, winnr('$')) 369 bwipe! 370 371 split dummy 372 call setline(1, 'change') 373 call assert_fails('terminal ++curwin ' . cmd, 'E37:') 374 call assert_equal(2, winnr('$')) 375 exe 'terminal! ++curwin ' . cmd 376 call assert_equal(2, winnr('$')) 377 bwipe! 378 379 split dummy 380 call setline(1, 'change') 381 call assert_fails("call term_start(cmd, {'curwin': 1})", 'E37:') 382 call assert_equal(2, winnr('$')) 383 bwipe! 384 385 split dummy 386 bwipe! 387 call delete('Xtext') 388endfunc 389 390func s:get_sleep_cmd() 391 if s:python != '' 392 let cmd = s:python . " test_short_sleep.py" 393 " 500 was not enough for Travis 394 let waittime = 900 395 else 396 echo 'This will take five seconds...' 397 let waittime = 2000 398 if has('win32') 399 let cmd = $windir . '\system32\timeout.exe 1' 400 else 401 let cmd = 'sleep 1' 402 endif 403 endif 404 return [cmd, waittime] 405endfunc 406 407func Test_terminal_finish_open_close() 408 call assert_equal(1, winnr('$')) 409 410 let [cmd, waittime] = s:get_sleep_cmd() 411 412 " shell terminal closes automatically 413 terminal 414 let buf = bufnr('%') 415 call assert_equal(2, winnr('$')) 416 " Wait for the shell to display a prompt 417 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))}) 418 call Stop_shell_in_terminal(buf) 419 call WaitForAssert({-> assert_equal(1, winnr('$'))}, waittime) 420 421 " shell terminal that does not close automatically 422 terminal ++noclose 423 let buf = bufnr('%') 424 call assert_equal(2, winnr('$')) 425 " Wait for the shell to display a prompt 426 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))}) 427 call Stop_shell_in_terminal(buf) 428 call assert_equal(2, winnr('$')) 429 quit 430 call assert_equal(1, winnr('$')) 431 432 exe 'terminal ++close ' . cmd 433 call assert_equal(2, winnr('$')) 434 wincmd p 435 call WaitForAssert({-> assert_equal(1, winnr('$'))}, waittime) 436 437 call term_start(cmd, {'term_finish': 'close'}) 438 call assert_equal(2, winnr('$')) 439 wincmd p 440 call WaitForAssert({-> assert_equal(1, winnr('$'))}, waittime) 441 call assert_equal(1, winnr('$')) 442 443 exe 'terminal ++open ' . cmd 444 close! 445 call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime) 446 bwipe 447 448 call term_start(cmd, {'term_finish': 'open'}) 449 close! 450 call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime) 451 bwipe 452 453 exe 'terminal ++hidden ++open ' . cmd 454 call assert_equal(1, winnr('$')) 455 call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime) 456 bwipe 457 458 call term_start(cmd, {'term_finish': 'open', 'hidden': 1}) 459 call assert_equal(1, winnr('$')) 460 call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime) 461 bwipe 462 463 call assert_fails("call term_start(cmd, {'term_opencmd': 'open'})", 'E475:') 464 call assert_fails("call term_start(cmd, {'term_opencmd': 'split %x'})", 'E475:') 465 call assert_fails("call term_start(cmd, {'term_opencmd': 'split %d and %s'})", 'E475:') 466 call assert_fails("call term_start(cmd, {'term_opencmd': 'split % and %d'})", 'E475:') 467 468 call term_start(cmd, {'term_finish': 'open', 'term_opencmd': '4split | buffer %d'}) 469 close! 470 call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime) 471 call assert_equal(4, winheight(0)) 472 bwipe 473endfunc 474 475func Test_terminal_cwd() 476 if !executable('pwd') 477 return 478 endif 479 call mkdir('Xdir') 480 let buf = term_start('pwd', {'cwd': 'Xdir'}) 481 call WaitForAssert({-> assert_equal('Xdir', fnamemodify(getline(1), ":t"))}) 482 483 exe buf . 'bwipe' 484 call delete('Xdir', 'rf') 485endfunc 486 487func Test_terminal_cwd_failure() 488 " Case 1: Provided directory is not actually a directory. Attempt to make 489 " the file executable as well. 490 call writefile([], 'Xfile') 491 call setfperm('Xfile', 'rwx------') 492 call assert_fails("call term_start(&shell, {'cwd': 'Xfile'})", 'E475:') 493 call delete('Xfile') 494 495 " Case 2: Directory does not exist. 496 call assert_fails("call term_start(&shell, {'cwd': 'Xdir'})", 'E475:') 497 498 " Case 3: Directory exists but is not accessible. 499 " Skip this for root, it will be accessible anyway. 500 if $USER != 'root' 501 call mkdir('XdirNoAccess', '', '0600') 502 " return early if the directory permissions could not be set properly 503 if getfperm('XdirNoAccess')[2] == 'x' 504 call delete('XdirNoAccess', 'rf') 505 return 506 endif 507 call assert_fails("call term_start(&shell, {'cwd': 'XdirNoAccess'})", 'E475:') 508 call delete('XdirNoAccess', 'rf') 509 endif 510endfunc 511 512func Test_terminal_servername() 513 if !has('clientserver') 514 return 515 endif 516 call s:test_environment("VIM_SERVERNAME", v:servername) 517endfunc 518 519func Test_terminal_version() 520 call s:test_environment("VIM_TERMINAL", string(v:version)) 521endfunc 522 523func s:test_environment(name, value) 524 let buf = Run_shell_in_terminal({}) 525 " Wait for the shell to display a prompt 526 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))}) 527 if has('win32') 528 call term_sendkeys(buf, "echo %" . a:name . "%\r") 529 else 530 call term_sendkeys(buf, "echo $" . a:name . "\r") 531 endif 532 call term_wait(buf) 533 call Stop_shell_in_terminal(buf) 534 call WaitForAssert({-> assert_equal(a:value, getline(2))}) 535 536 exe buf . 'bwipe' 537 unlet buf 538endfunc 539 540func Test_terminal_env() 541 let buf = Run_shell_in_terminal({'env': {'TESTENV': 'correct'}}) 542 " Wait for the shell to display a prompt 543 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))}) 544 if has('win32') 545 call term_sendkeys(buf, "echo %TESTENV%\r") 546 else 547 call term_sendkeys(buf, "echo $TESTENV\r") 548 endif 549 call term_wait(buf) 550 call Stop_shell_in_terminal(buf) 551 call WaitForAssert({-> assert_equal('correct', getline(2))}) 552 553 exe buf . 'bwipe' 554endfunc 555 556func Test_terminal_list_args() 557 let buf = term_start([&shell, &shellcmdflag, 'echo "123"']) 558 call assert_fails(buf . 'bwipe', 'E517') 559 exe buf . 'bwipe!' 560 call assert_equal("", bufname(buf)) 561endfunction 562 563func Test_terminal_noblock() 564 let buf = term_start(&shell) 565 if has('mac') 566 " The shell or something else has a problem dealing with more than 1000 567 " characters at the same time. 568 let len = 1000 569 else 570 let len = 5000 571 endif 572 573 for c in ['a','b','c','d','e','f','g','h','i','j','k'] 574 call term_sendkeys(buf, 'echo ' . repeat(c, len) . "\<cr>") 575 endfor 576 call term_sendkeys(buf, "echo done\<cr>") 577 578 " On MS-Windows there is an extra empty line below "done". Find "done" in 579 " the last-but-one or the last-but-two line. 580 let lnum = term_getsize(buf)[0] - 1 581 call WaitFor({-> term_getline(buf, lnum) =~ "done" || term_getline(buf, lnum - 1) =~ "done"}, 10000) 582 let line = term_getline(buf, lnum) 583 if line !~ 'done' 584 let line = term_getline(buf, lnum - 1) 585 endif 586 call assert_match('done', line) 587 588 let g:job = term_getjob(buf) 589 call Stop_shell_in_terminal(buf) 590 call term_wait(buf) 591 unlet g:job 592 bwipe 593endfunc 594 595func Test_terminal_write_stdin() 596 if !executable('wc') 597 throw 'skipped: wc command not available' 598 endif 599 if has('win32') 600 " TODO: enable once writing to stdin works on MS-Windows 601 return 602 endif 603 new 604 call setline(1, ['one', 'two', 'three']) 605 %term wc 606 call WaitForAssert({-> assert_match('3', getline("$"))}) 607 let nrs = split(getline('$')) 608 call assert_equal(['3', '3', '14'], nrs) 609 bwipe 610 611 new 612 call setline(1, ['one', 'two', 'three', 'four']) 613 2,3term wc 614 call WaitForAssert({-> assert_match('2', getline("$"))}) 615 let nrs = split(getline('$')) 616 call assert_equal(['2', '2', '10'], nrs) 617 bwipe 618 619 if executable('python') 620 new 621 call setline(1, ['print("hello")']) 622 1term ++eof=exit() python 623 " MS-Windows echoes the input, Unix doesn't. 624 call WaitFor('getline("$") =~ "exit" || getline(1) =~ "hello"') 625 if getline(1) =~ 'hello' 626 call assert_equal('hello', getline(1)) 627 else 628 call assert_equal('hello', getline(line('$') - 1)) 629 endif 630 bwipe 631 632 if has('win32') 633 new 634 call setline(1, ['print("hello")']) 635 1term ++eof=<C-Z> python 636 call WaitForAssert({-> assert_match('Z', getline("$"))}) 637 call assert_equal('hello', getline(line('$') - 1)) 638 bwipe 639 endif 640 endif 641 642 bwipe! 643endfunc 644 645func Test_terminal_no_cmd() 646 " Todo: make this work in the GUI 647 if !has('gui_running') 648 return 649 endif 650 let buf = term_start('NONE', {}) 651 call assert_notequal(0, buf) 652 653 let pty = job_info(term_getjob(buf))['tty_out'] 654 call assert_notequal('', pty) 655 if has('win32') 656 silent exe '!start cmd /c "echo look here > ' . pty . '"' 657 else 658 call system('echo "look here" > ' . pty) 659 endif 660 call WaitForAssert({-> assert_match('look here', term_getline(buf, 1))}) 661 662 bwipe! 663endfunc 664 665func Test_terminal_special_chars() 666 " this file name only works on Unix 667 if !has('unix') 668 return 669 endif 670 call mkdir('Xdir with spaces') 671 call writefile(['x'], 'Xdir with spaces/quoted"file') 672 term ls Xdir\ with\ spaces/quoted\"file 673 call WaitForAssert({-> assert_match('quoted"file', term_getline('', 1))}) 674 call term_wait('') 675 676 call delete('Xdir with spaces', 'rf') 677 bwipe 678endfunc 679 680func Test_terminal_wrong_options() 681 call assert_fails('call term_start(&shell, { 682 \ "in_io": "file", 683 \ "in_name": "xxx", 684 \ "out_io": "file", 685 \ "out_name": "xxx", 686 \ "err_io": "file", 687 \ "err_name": "xxx" 688 \ })', 'E474:') 689 call assert_fails('call term_start(&shell, { 690 \ "out_buf": bufnr("%") 691 \ })', 'E474:') 692 call assert_fails('call term_start(&shell, { 693 \ "err_buf": bufnr("%") 694 \ })', 'E474:') 695endfunc 696 697func Test_terminal_redir_file() 698 let cmd = Get_cat_123_cmd() 699 let buf = term_start(cmd, {'out_io': 'file', 'out_name': 'Xfile'}) 700 call term_wait(buf) 701 call WaitForAssert({-> assert_notequal(0, len(readfile("Xfile")))}) 702 call assert_match('123', readfile('Xfile')[0]) 703 let g:job = term_getjob(buf) 704 call WaitForAssert({-> assert_equal("dead", job_status(g:job))}) 705 call delete('Xfile') 706 bwipe 707 708 if has('unix') 709 call writefile(['one line'], 'Xfile') 710 let buf = term_start('cat', {'in_io': 'file', 'in_name': 'Xfile'}) 711 call term_wait(buf) 712 call WaitForAssert({-> assert_equal('one line', term_getline(buf, 1))}) 713 let g:job = term_getjob(buf) 714 call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) 715 bwipe 716 call delete('Xfile') 717 endif 718endfunc 719 720func TerminalTmap(remap) 721 let buf = Run_shell_in_terminal({}) 722 call assert_equal('t', mode()) 723 724 if a:remap 725 tmap 123 456 726 else 727 tnoremap 123 456 728 endif 729 " don't use abcde, it's an existing command 730 tmap 456 abxde 731 call assert_equal('456', maparg('123', 't')) 732 call assert_equal('abxde', maparg('456', 't')) 733 call feedkeys("123", 'tx') 734 call WaitForAssert({-> assert_match('abxde\|456', term_getline(buf, term_getcursor(buf)[0]))}) 735 let lnum = term_getcursor(buf)[0] 736 if a:remap 737 call assert_match('abxde', term_getline(buf, lnum)) 738 else 739 call assert_match('456', term_getline(buf, lnum)) 740 endif 741 742 call term_sendkeys(buf, "\r") 743 call Stop_shell_in_terminal(buf) 744 call term_wait(buf) 745 746 tunmap 123 747 tunmap 456 748 call assert_equal('', maparg('123', 't')) 749 close 750 unlet g:job 751endfunc 752 753func Test_terminal_tmap() 754 call TerminalTmap(1) 755 call TerminalTmap(0) 756endfunc 757 758func Test_terminal_wall() 759 let buf = Run_shell_in_terminal({}) 760 wall 761 call Stop_shell_in_terminal(buf) 762 call term_wait(buf) 763 exe buf . 'bwipe' 764 unlet g:job 765endfunc 766 767func Test_terminal_wqall() 768 let buf = Run_shell_in_terminal({}) 769 call assert_fails('wqall', 'E948') 770 call Stop_shell_in_terminal(buf) 771 call term_wait(buf) 772 exe buf . 'bwipe' 773 unlet g:job 774endfunc 775 776func Test_terminal_composing_unicode() 777 let save_enc = &encoding 778 set encoding=utf-8 779 780 if has('win32') 781 let cmd = "cmd /K chcp 65001" 782 let lnum = [3, 6, 9] 783 else 784 let cmd = &shell 785 let lnum = [1, 3, 5] 786 endif 787 788 enew 789 let buf = term_start(cmd, {'curwin': bufnr('')}) 790 let g:job = term_getjob(buf) 791 call term_wait(buf, 50) 792 793 if has('win32') 794 call assert_equal('cmd', job_info(g:job).cmd[0]) 795 else 796 call assert_equal(&shell, job_info(g:job).cmd[0]) 797 endif 798 799 " ascii + composing 800 let txt = "a\u0308bc" 801 call term_sendkeys(buf, "echo " . txt . "\r") 802 call term_wait(buf, 50) 803 call assert_match("echo " . txt, term_getline(buf, lnum[0])) 804 call assert_equal(txt, term_getline(buf, lnum[0] + 1)) 805 let l = term_scrape(buf, lnum[0] + 1) 806 call assert_equal("a\u0308", l[0].chars) 807 call assert_equal("b", l[1].chars) 808 call assert_equal("c", l[2].chars) 809 810 " multibyte + composing 811 let txt = "\u304b\u3099\u304e\u304f\u3099\u3052\u3053\u3099" 812 call term_sendkeys(buf, "echo " . txt . "\r") 813 call term_wait(buf, 50) 814 call assert_match("echo " . txt, term_getline(buf, lnum[1])) 815 call assert_equal(txt, term_getline(buf, lnum[1] + 1)) 816 let l = term_scrape(buf, lnum[1] + 1) 817 call assert_equal("\u304b\u3099", l[0].chars) 818 call assert_equal("\u304e", l[1].chars) 819 call assert_equal("\u304f\u3099", l[2].chars) 820 call assert_equal("\u3052", l[3].chars) 821 call assert_equal("\u3053\u3099", l[4].chars) 822 823 " \u00a0 + composing 824 let txt = "abc\u00a0\u0308" 825 call term_sendkeys(buf, "echo " . txt . "\r") 826 call term_wait(buf, 50) 827 call assert_match("echo " . txt, term_getline(buf, lnum[2])) 828 call assert_equal(txt, term_getline(buf, lnum[2] + 1)) 829 let l = term_scrape(buf, lnum[2] + 1) 830 call assert_equal("\u00a0\u0308", l[3].chars) 831 832 call term_sendkeys(buf, "exit\r") 833 call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) 834 bwipe! 835 unlet g:job 836 let &encoding = save_enc 837endfunc 838 839func Test_terminal_aucmd_on_close() 840 fun Nop() 841 let s:called = 1 842 endfun 843 844 aug repro 845 au! 846 au BufWinLeave * call Nop() 847 aug END 848 849 let [cmd, waittime] = s:get_sleep_cmd() 850 851 call assert_equal(1, winnr('$')) 852 new 853 call setline(1, ['one', 'two']) 854 exe 'term ++close ' . cmd 855 wincmd p 856 call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime) 857 call assert_equal(1, s:called) 858 bwipe! 859 860 unlet s:called 861 au! repro 862 delfunc Nop 863endfunc 864 865func Test_terminal_term_start_empty_command() 866 let cmd = "call term_start('', {'curwin' : 1, 'term_finish' : 'close'})" 867 call assert_fails(cmd, 'E474') 868 let cmd = "call term_start('', {'curwin' : 1, 'term_finish' : 'close'})" 869 call assert_fails(cmd, 'E474') 870 let cmd = "call term_start({}, {'curwin' : 1, 'term_finish' : 'close'})" 871 call assert_fails(cmd, 'E474') 872 let cmd = "call term_start(0, {'curwin' : 1, 'term_finish' : 'close'})" 873 call assert_fails(cmd, 'E474') 874endfunc 875 876func Test_terminal_response_to_control_sequence() 877 if !has('unix') 878 return 879 endif 880 881 let buf = Run_shell_in_terminal({}) 882 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))}) 883 884 call term_sendkeys(buf, "cat\<CR>") 885 call WaitForAssert({-> assert_match('cat', term_getline(buf, 1))}) 886 887 " Request the cursor position. 888 call term_sendkeys(buf, "\x1b[6n\<CR>") 889 890 " Wait for output from tty to display, below an empty line. 891 call WaitForAssert({-> assert_match('3;1R', term_getline(buf, 4))}) 892 893 " End "cat" gently. 894 call term_sendkeys(buf, "\<CR>\<C-D>") 895 896 call Stop_shell_in_terminal(buf) 897 exe buf . 'bwipe' 898 unlet g:job 899endfunc 900 901" Run Vim, start a terminal in that Vim with the kill argument, 902" :qall works. 903func Run_terminal_qall_kill(line1, line2) 904 " 1. Open a terminal window and wait for the prompt to appear 905 " 2. set kill using term_setkill() 906 " 3. make Vim exit, it will kill the shell 907 let after = [ 908 \ a:line1, 909 \ 'let buf = bufnr("%")', 910 \ 'while term_getline(buf, 1) =~ "^\\s*$"', 911 \ ' sleep 10m', 912 \ 'endwhile', 913 \ a:line2, 914 \ 'au VimLeavePre * call writefile(["done"], "Xdone")', 915 \ 'qall', 916 \ ] 917 if !RunVim([], after, '') 918 return 919 endif 920 call assert_equal("done", readfile("Xdone")[0]) 921 call delete("Xdone") 922endfunc 923 924" Run Vim in a terminal, then start a terminal in that Vim with a kill 925" argument, check that :qall works. 926func Test_terminal_qall_kill_arg() 927 call Run_terminal_qall_kill('term ++kill=kill', '') 928endfunc 929 930" Run Vim, start a terminal in that Vim, set the kill argument with 931" term_setkill(), check that :qall works. 932func Test_terminal_qall_kill_func() 933 call Run_terminal_qall_kill('term', 'call term_setkill(buf, "kill")') 934endfunc 935 936" Run Vim, start a terminal in that Vim without the kill argument, 937" check that :qall does not exit, :qall! does. 938func Test_terminal_qall_exit() 939 let after = [ 940 \ 'term', 941 \ 'let buf = bufnr("%")', 942 \ 'while term_getline(buf, 1) =~ "^\\s*$"', 943 \ ' sleep 10m', 944 \ 'endwhile', 945 \ 'set nomore', 946 \ 'au VimLeavePre * call writefile(["too early"], "Xdone")', 947 \ 'qall', 948 \ 'au! VimLeavePre * exe buf . "bwipe!" | call writefile(["done"], "Xdone")', 949 \ 'cquit', 950 \ ] 951 if !RunVim([], after, '') 952 return 953 endif 954 call assert_equal("done", readfile("Xdone")[0]) 955 call delete("Xdone") 956endfunc 957 958" Run Vim in a terminal, then start a terminal in that Vim without a kill 959" argument, check that :confirm qall works. 960func Test_terminal_qall_prompt() 961 if !CanRunVimInTerminal() 962 return 963 endif 964 let buf = RunVimInTerminal('', {}) 965 966 " Open a terminal window and wait for the prompt to appear 967 call term_sendkeys(buf, ":term\<CR>") 968 call WaitForAssert({-> assert_match('\[running]', term_getline(buf, 10))}) 969 call WaitForAssert({-> assert_notmatch('^\s*$', term_getline(buf, 1))}) 970 971 " make Vim exit, it will prompt to kill the shell 972 call term_sendkeys(buf, "\<C-W>:confirm qall\<CR>") 973 call WaitForAssert({-> assert_match('ancel:', term_getline(buf, 20))}) 974 call term_sendkeys(buf, "y") 975 call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))}) 976 977 " close the terminal window where Vim was running 978 quit 979endfunc 980 981func Test_terminal_open_autocmd() 982 augroup repro 983 au! 984 au TerminalOpen * let s:called += 1 985 augroup END 986 987 let s:called = 0 988 989 " Open a terminal window with :terminal 990 terminal 991 call assert_equal(1, s:called) 992 bwipe! 993 994 " Open a terminal window with term_start() 995 call term_start(&shell) 996 call assert_equal(2, s:called) 997 bwipe! 998 999 " Open a hidden terminal buffer with :terminal 1000 terminal ++hidden 1001 call assert_equal(3, s:called) 1002 for buf in term_list() 1003 exe buf . "bwipe!" 1004 endfor 1005 1006 " Open a hidden terminal buffer with term_start() 1007 let buf = term_start(&shell, {'hidden': 1}) 1008 call assert_equal(4, s:called) 1009 exe buf . "bwipe!" 1010 1011 unlet s:called 1012 au! repro 1013endfunction 1014 1015func Check_dump01(off) 1016 call assert_equal('one two three four five', trim(getline(a:off + 1))) 1017 call assert_equal('~ Select Word', trim(getline(a:off + 7))) 1018 call assert_equal(':popup PopUp', trim(getline(a:off + 20))) 1019endfunc 1020 1021func Test_terminal_dumpwrite_composing() 1022 if !CanRunVimInTerminal() 1023 return 1024 endif 1025 let save_enc = &encoding 1026 set encoding=utf-8 1027 call assert_equal(1, winnr('$')) 1028 1029 let text = " a\u0300 e\u0302 o\u0308" 1030 call writefile([text], 'Xcomposing') 1031 let buf = RunVimInTerminal('--cmd "set encoding=utf-8" Xcomposing', {}) 1032 call WaitForAssert({-> assert_match(text, term_getline(buf, 1))}) 1033 call term_dumpwrite(buf, 'Xdump') 1034 let dumpline = readfile('Xdump')[0] 1035 call assert_match('|à| |ê| |ö', dumpline) 1036 1037 call StopVimInTerminal(buf) 1038 call delete('Xcomposing') 1039 call delete('Xdump') 1040 let &encoding = save_enc 1041endfunc 1042 1043" just testing basic functionality. 1044func Test_terminal_dumpload() 1045 call assert_equal(1, winnr('$')) 1046 call term_dumpload('dumps/Test_popup_command_01.dump') 1047 call assert_equal(2, winnr('$')) 1048 call assert_equal(20, line('$')) 1049 call Check_dump01(0) 1050 quit 1051endfunc 1052 1053func Test_terminal_dumpdiff() 1054 call assert_equal(1, winnr('$')) 1055 call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump') 1056 call assert_equal(2, winnr('$')) 1057 call assert_equal(62, line('$')) 1058 call Check_dump01(0) 1059 call Check_dump01(42) 1060 call assert_equal(' bbbbbbbbbbbbbbbbbb ', getline(26)[0:29]) 1061 quit 1062endfunc 1063 1064func Test_terminal_dumpdiff_options() 1065 set laststatus=0 1066 call assert_equal(1, winnr('$')) 1067 let height = winheight(0) 1068 call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump', {'vertical': 1, 'term_cols': 33}) 1069 call assert_equal(2, winnr('$')) 1070 call assert_equal(height, winheight(winnr())) 1071 call assert_equal(33, winwidth(winnr())) 1072 call assert_equal('dump diff dumps/Test_popup_command_01.dump', bufname('%')) 1073 quit 1074 1075 call assert_equal(1, winnr('$')) 1076 let width = winwidth(0) 1077 call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump', {'vertical': 0, 'term_rows': 13, 'term_name': 'something else'}) 1078 call assert_equal(2, winnr('$')) 1079 call assert_equal(width, winwidth(winnr())) 1080 call assert_equal(13, winheight(winnr())) 1081 call assert_equal('something else', bufname('%')) 1082 quit 1083 1084 call assert_equal(1, winnr('$')) 1085 call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump', {'curwin': 1}) 1086 call assert_equal(1, winnr('$')) 1087 bwipe 1088 1089 set laststatus& 1090endfunc 1091 1092func Api_drop_common(options) 1093 call assert_equal(1, winnr('$')) 1094 1095 " Use the title termcap entries to output the escape sequence. 1096 call writefile([ 1097 \ 'set title', 1098 \ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"', 1099 \ 'let &titlestring = ''["drop","Xtextfile"' . a:options . ']''', 1100 \ 'redraw', 1101 \ "set t_ts=", 1102 \ ], 'Xscript') 1103 let buf = RunVimInTerminal('-S Xscript', {}) 1104 call WaitFor({-> bufnr('Xtextfile') > 0}) 1105 call assert_equal('Xtextfile', expand('%:t')) 1106 call assert_true(winnr('$') >= 3) 1107 return buf 1108endfunc 1109 1110func Test_terminal_api_drop_newwin() 1111 if !CanRunVimInTerminal() 1112 return 1113 endif 1114 let buf = Api_drop_common('') 1115 call assert_equal(0, &bin) 1116 call assert_equal('', &fenc) 1117 1118 call StopVimInTerminal(buf) 1119 call delete('Xscript') 1120 bwipe Xtextfile 1121endfunc 1122 1123func Test_terminal_api_drop_newwin_bin() 1124 if !CanRunVimInTerminal() 1125 return 1126 endif 1127 let buf = Api_drop_common(',{"bin":1}') 1128 call assert_equal(1, &bin) 1129 1130 call StopVimInTerminal(buf) 1131 call delete('Xscript') 1132 bwipe Xtextfile 1133endfunc 1134 1135func Test_terminal_api_drop_newwin_binary() 1136 if !CanRunVimInTerminal() 1137 return 1138 endif 1139 let buf = Api_drop_common(',{"binary":1}') 1140 call assert_equal(1, &bin) 1141 1142 call StopVimInTerminal(buf) 1143 call delete('Xscript') 1144 bwipe Xtextfile 1145endfunc 1146 1147func Test_terminal_api_drop_newwin_nobin() 1148 if !CanRunVimInTerminal() 1149 return 1150 endif 1151 set binary 1152 let buf = Api_drop_common(',{"nobin":1}') 1153 call assert_equal(0, &bin) 1154 1155 call StopVimInTerminal(buf) 1156 call delete('Xscript') 1157 bwipe Xtextfile 1158 set nobinary 1159endfunc 1160 1161func Test_terminal_api_drop_newwin_nobinary() 1162 if !CanRunVimInTerminal() 1163 return 1164 endif 1165 set binary 1166 let buf = Api_drop_common(',{"nobinary":1}') 1167 call assert_equal(0, &bin) 1168 1169 call StopVimInTerminal(buf) 1170 call delete('Xscript') 1171 bwipe Xtextfile 1172 set nobinary 1173endfunc 1174 1175func Test_terminal_api_drop_newwin_ff() 1176 if !CanRunVimInTerminal() 1177 return 1178 endif 1179 let buf = Api_drop_common(',{"ff":"dos"}') 1180 call assert_equal("dos", &ff) 1181 1182 call StopVimInTerminal(buf) 1183 call delete('Xscript') 1184 bwipe Xtextfile 1185endfunc 1186 1187func Test_terminal_api_drop_newwin_fileformat() 1188 if !CanRunVimInTerminal() 1189 return 1190 endif 1191 let buf = Api_drop_common(',{"fileformat":"dos"}') 1192 call assert_equal("dos", &ff) 1193 1194 call StopVimInTerminal(buf) 1195 call delete('Xscript') 1196 bwipe Xtextfile 1197endfunc 1198 1199func Test_terminal_api_drop_newwin_enc() 1200 if !CanRunVimInTerminal() 1201 return 1202 endif 1203 let buf = Api_drop_common(',{"enc":"utf-16"}') 1204 call assert_equal("utf-16", &fenc) 1205 1206 call StopVimInTerminal(buf) 1207 call delete('Xscript') 1208 bwipe Xtextfile 1209endfunc 1210 1211func Test_terminal_api_drop_newwin_encoding() 1212 if !CanRunVimInTerminal() 1213 return 1214 endif 1215 let buf = Api_drop_common(',{"encoding":"utf-16"}') 1216 call assert_equal("utf-16", &fenc) 1217 1218 call StopVimInTerminal(buf) 1219 call delete('Xscript') 1220 bwipe Xtextfile 1221endfunc 1222 1223func Test_terminal_api_drop_oldwin() 1224 if !CanRunVimInTerminal() 1225 return 1226 endif 1227 let firstwinid = win_getid() 1228 split Xtextfile 1229 let textfile_winid = win_getid() 1230 call assert_equal(2, winnr('$')) 1231 call win_gotoid(firstwinid) 1232 1233 " Use the title termcap entries to output the escape sequence. 1234 call writefile([ 1235 \ 'set title', 1236 \ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"', 1237 \ 'let &titlestring = ''["drop","Xtextfile"]''', 1238 \ 'redraw', 1239 \ "set t_ts=", 1240 \ ], 'Xscript') 1241 let buf = RunVimInTerminal('-S Xscript', {'rows': 10}) 1242 call WaitForAssert({-> assert_equal('Xtextfile', expand('%:t'))}) 1243 call assert_equal(textfile_winid, win_getid()) 1244 1245 call StopVimInTerminal(buf) 1246 call delete('Xscript') 1247 bwipe Xtextfile 1248endfunc 1249 1250func Tapi_TryThis(bufnum, arg) 1251 let g:called_bufnum = a:bufnum 1252 let g:called_arg = a:arg 1253endfunc 1254 1255func WriteApiCall(funcname) 1256 " Use the title termcap entries to output the escape sequence. 1257 call writefile([ 1258 \ 'set title', 1259 \ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"', 1260 \ 'let &titlestring = ''["call","' . a:funcname . '",["hello",123]]''', 1261 \ 'redraw', 1262 \ "set t_ts=", 1263 \ ], 'Xscript') 1264endfunc 1265 1266func Test_terminal_api_call() 1267 if !CanRunVimInTerminal() 1268 return 1269 endif 1270 1271 call WriteApiCall('Tapi_TryThis') 1272 let buf = RunVimInTerminal('-S Xscript', {}) 1273 call WaitFor({-> exists('g:called_bufnum')}) 1274 call assert_equal(buf, g:called_bufnum) 1275 call assert_equal(['hello', 123], g:called_arg) 1276 1277 call StopVimInTerminal(buf) 1278 call delete('Xscript') 1279 unlet g:called_bufnum 1280 unlet g:called_arg 1281endfunc 1282 1283func Test_terminal_api_call_fails() 1284 if !CanRunVimInTerminal() 1285 return 1286 endif 1287 1288 call WriteApiCall('TryThis') 1289 call ch_logfile('Xlog', 'w') 1290 let buf = RunVimInTerminal('-S Xscript', {}) 1291 call WaitForAssert({-> assert_match('Invalid function name: TryThis', string(readfile('Xlog')))}) 1292 1293 call StopVimInTerminal(buf) 1294 call delete('Xscript') 1295 call ch_logfile('', '') 1296 call delete('Xlog') 1297endfunc 1298 1299let s:caught_e937 = 0 1300 1301func Tapi_Delete(bufnum, arg) 1302 try 1303 execute 'bdelete!' a:bufnum 1304 catch /E937:/ 1305 let s:caught_e937 = 1 1306 endtry 1307endfunc 1308 1309func Test_terminal_api_call_fail_delete() 1310 if !CanRunVimInTerminal() 1311 return 1312 endif 1313 1314 call WriteApiCall('Tapi_Delete') 1315 let buf = RunVimInTerminal('-S Xscript', {}) 1316 call WaitForAssert({-> assert_equal(1, s:caught_e937)}) 1317 1318 call StopVimInTerminal(buf) 1319 call delete('Xscript') 1320 call ch_logfile('', '') 1321endfunc 1322 1323func Test_terminal_ansicolors_default() 1324 let colors = [ 1325 \ '#000000', '#e00000', 1326 \ '#00e000', '#e0e000', 1327 \ '#0000e0', '#e000e0', 1328 \ '#00e0e0', '#e0e0e0', 1329 \ '#808080', '#ff4040', 1330 \ '#40ff40', '#ffff40', 1331 \ '#4040ff', '#ff40ff', 1332 \ '#40ffff', '#ffffff', 1333 \] 1334 1335 let buf = Run_shell_in_terminal({}) 1336 call assert_equal(colors, term_getansicolors(buf)) 1337 call Stop_shell_in_terminal(buf) 1338 call term_wait(buf) 1339 1340 exe buf . 'bwipe' 1341endfunc 1342 1343let s:test_colors = [ 1344 \ '#616e64', '#0d0a79', 1345 \ '#6d610d', '#0a7373', 1346 \ '#690d0a', '#6d696e', 1347 \ '#0d0a6f', '#616e0d', 1348 \ '#0a6479', '#6d0d0a', 1349 \ '#617373', '#0d0a69', 1350 \ '#6d690d', '#0a6e6f', 1351 \ '#610d0a', '#6e6479', 1352 \] 1353 1354func Test_terminal_ansicolors_global() 1355 let g:terminal_ansi_colors = reverse(copy(s:test_colors)) 1356 let buf = Run_shell_in_terminal({}) 1357 call assert_equal(g:terminal_ansi_colors, term_getansicolors(buf)) 1358 call Stop_shell_in_terminal(buf) 1359 call term_wait(buf) 1360 1361 exe buf . 'bwipe' 1362 unlet g:terminal_ansi_colors 1363endfunc 1364 1365func Test_terminal_ansicolors_func() 1366 let g:terminal_ansi_colors = reverse(copy(s:test_colors)) 1367 let buf = Run_shell_in_terminal({'ansi_colors': s:test_colors}) 1368 call assert_equal(s:test_colors, term_getansicolors(buf)) 1369 1370 call term_setansicolors(buf, g:terminal_ansi_colors) 1371 call assert_equal(g:terminal_ansi_colors, term_getansicolors(buf)) 1372 1373 let colors = [ 1374 \ 'ivory', 'AliceBlue', 1375 \ 'grey67', 'dark goldenrod', 1376 \ 'SteelBlue3', 'PaleVioletRed4', 1377 \ 'MediumPurple2', 'yellow2', 1378 \ 'RosyBrown3', 'OrangeRed2', 1379 \ 'white smoke', 'navy blue', 1380 \ 'grey47', 'gray97', 1381 \ 'MistyRose2', 'DodgerBlue4', 1382 \] 1383 call term_setansicolors(buf, colors) 1384 1385 let colors[4] = 'Invalid' 1386 call assert_fails('call term_setansicolors(buf, colors)', 'E474:') 1387 1388 call Stop_shell_in_terminal(buf) 1389 call term_wait(buf) 1390 exe buf . 'bwipe' 1391endfunc 1392 1393func Test_terminal_termwinsize_option_fixed() 1394 if !CanRunVimInTerminal() 1395 return 1396 endif 1397 set termwinsize=6x40 1398 let text = [] 1399 for n in range(10) 1400 call add(text, repeat(n, 50)) 1401 endfor 1402 call writefile(text, 'Xwinsize') 1403 let buf = RunVimInTerminal('Xwinsize', {}) 1404 let win = bufwinid(buf) 1405 call assert_equal([6, 40], term_getsize(buf)) 1406 call assert_equal(6, winheight(win)) 1407 call assert_equal(40, winwidth(win)) 1408 1409 " resizing the window doesn't resize the terminal. 1410 resize 10 1411 vertical resize 60 1412 call assert_equal([6, 40], term_getsize(buf)) 1413 call assert_equal(10, winheight(win)) 1414 call assert_equal(60, winwidth(win)) 1415 1416 call StopVimInTerminal(buf) 1417 call delete('Xwinsize') 1418 1419 call assert_fails('set termwinsize=40', 'E474') 1420 call assert_fails('set termwinsize=10+40', 'E474') 1421 call assert_fails('set termwinsize=abc', 'E474') 1422 1423 set termwinsize= 1424endfunc 1425 1426func Test_terminal_termwinsize_option_zero() 1427 set termwinsize=0x0 1428 let buf = Run_shell_in_terminal({}) 1429 let win = bufwinid(buf) 1430 call assert_equal([winheight(win), winwidth(win)], term_getsize(buf)) 1431 call Stop_shell_in_terminal(buf) 1432 call term_wait(buf) 1433 exe buf . 'bwipe' 1434 1435 set termwinsize=7x0 1436 let buf = Run_shell_in_terminal({}) 1437 let win = bufwinid(buf) 1438 call assert_equal([7, winwidth(win)], term_getsize(buf)) 1439 call Stop_shell_in_terminal(buf) 1440 call term_wait(buf) 1441 exe buf . 'bwipe' 1442 1443 set termwinsize=0x33 1444 let buf = Run_shell_in_terminal({}) 1445 let win = bufwinid(buf) 1446 call assert_equal([winheight(win), 33], term_getsize(buf)) 1447 call Stop_shell_in_terminal(buf) 1448 call term_wait(buf) 1449 exe buf . 'bwipe' 1450 1451 set termwinsize= 1452endfunc 1453 1454func Test_terminal_termwinsize_mininmum() 1455 set termwinsize=10*50 1456 vsplit 1457 let buf = Run_shell_in_terminal({}) 1458 let win = bufwinid(buf) 1459 call assert_inrange(10, 1000, winheight(win)) 1460 call assert_inrange(50, 1000, winwidth(win)) 1461 call assert_equal([winheight(win), winwidth(win)], term_getsize(buf)) 1462 1463 resize 15 1464 vertical resize 60 1465 redraw 1466 call assert_equal([15, 60], term_getsize(buf)) 1467 call assert_equal(15, winheight(win)) 1468 call assert_equal(60, winwidth(win)) 1469 1470 resize 7 1471 vertical resize 30 1472 redraw 1473 call assert_equal([10, 50], term_getsize(buf)) 1474 call assert_equal(7, winheight(win)) 1475 call assert_equal(30, winwidth(win)) 1476 1477 call Stop_shell_in_terminal(buf) 1478 call term_wait(buf) 1479 exe buf . 'bwipe' 1480 1481 set termwinsize=0*0 1482 let buf = Run_shell_in_terminal({}) 1483 let win = bufwinid(buf) 1484 call assert_equal([winheight(win), winwidth(win)], term_getsize(buf)) 1485 call Stop_shell_in_terminal(buf) 1486 call term_wait(buf) 1487 exe buf . 'bwipe' 1488 1489 set termwinsize= 1490endfunc 1491 1492func Test_terminal_termwinkey() 1493 call assert_equal(1, winnr('$')) 1494 let thiswin = win_getid() 1495 1496 let buf = Run_shell_in_terminal({}) 1497 let termwin = bufwinid(buf) 1498 set termwinkey=<C-L> 1499 call feedkeys("\<C-L>w", 'tx') 1500 call assert_equal(thiswin, win_getid()) 1501 call feedkeys("\<C-W>w", 'tx') 1502 1503 let job = term_getjob(buf) 1504 call feedkeys("\<C-L>\<C-C>", 'tx') 1505 call WaitForAssert({-> assert_equal("dead", job_status(job))}) 1506endfunc 1507 1508func Test_terminal_out_err() 1509 if !has('unix') 1510 return 1511 endif 1512 call writefile([ 1513 \ '#!/bin/sh', 1514 \ 'echo "this is standard error" >&2', 1515 \ 'echo "this is standard out" >&1', 1516 \ ], 'Xechoerrout.sh') 1517 call setfperm('Xechoerrout.sh', 'rwxrwx---') 1518 1519 let outfile = 'Xtermstdout' 1520 let buf = term_start(['./Xechoerrout.sh'], {'out_io': 'file', 'out_name': outfile}) 1521 1522 call WaitFor({-> !empty(readfile(outfile)) && !empty(term_getline(buf, 1))}) 1523 call assert_equal(['this is standard out'], readfile(outfile)) 1524 call assert_equal('this is standard error', term_getline(buf, 1)) 1525 1526 call WaitForAssert({-> assert_equal('dead', job_status(term_getjob(buf)))}) 1527 exe buf . 'bwipe' 1528 call delete('Xechoerrout.sh') 1529 call delete(outfile) 1530endfunc 1531 1532func Test_terminwinscroll() 1533 if !has('unix') 1534 return 1535 endif 1536 1537 " Let the terminal output more than 'termwinscroll' lines, some at the start 1538 " will be dropped. 1539 exe 'set termwinscroll=' . &lines 1540 let buf = term_start('/bin/sh') 1541 for i in range(1, &lines) 1542 call feedkeys("echo " . i . "\<CR>", 'xt') 1543 call WaitForAssert({-> assert_match(string(i), term_getline(buf, term_getcursor(buf)[0] - 1))}) 1544 endfor 1545 " Go to Terminal-Normal mode to update the buffer. 1546 call feedkeys("\<C-W>N", 'xt') 1547 call assert_inrange(&lines, &lines * 110 / 100 + winheight(0), line('$')) 1548 1549 " Every "echo nr" must only appear once 1550 let lines = getline(1, line('$')) 1551 for i in range(&lines - len(lines) / 2 + 2, &lines) 1552 let filtered = filter(copy(lines), {idx, val -> val =~ 'echo ' . i . '\>'}) 1553 call assert_equal(1, len(filtered), 'for "echo ' . i . '"') 1554 endfor 1555 1556 exe buf . 'bwipe!' 1557endfunc 1558 1559" Resizing the terminal window caused an ml_get error. 1560" TODO: This does not reproduce the original problem. 1561func Test_terminal_resize() 1562 set statusline=x 1563 terminal 1564 call assert_equal(2, winnr('$')) 1565 1566 " Fill the terminal with text. 1567 if has('win32') 1568 call feedkeys("dir\<CR>", 'xt') 1569 else 1570 call feedkeys("ls\<CR>", 'xt') 1571 endif 1572 " Go to Terminal-Normal mode for a moment. 1573 call feedkeys("\<C-W>N", 'xt') 1574 " Open a new window 1575 call feedkeys("i\<C-W>n", 'xt') 1576 call assert_equal(3, winnr('$')) 1577 redraw 1578 1579 close 1580 call assert_equal(2, winnr('$')) 1581 call feedkeys("exit\<CR>", 'xt') 1582 set statusline& 1583endfunc 1584 1585" must be nearly the last, we can't go back from GUI to terminal 1586func Test_zz1_terminal_in_gui() 1587 if !CanRunGui() 1588 return 1589 endif 1590 1591 " Ignore the "failed to create input context" error. 1592 call test_ignore_error('E285:') 1593 1594 gui -f 1595 1596 call assert_equal(1, winnr('$')) 1597 let buf = Run_shell_in_terminal({'term_finish': 'close'}) 1598 call Stop_shell_in_terminal(buf) 1599 call term_wait(buf) 1600 1601 " closing window wipes out the terminal buffer a with finished job 1602 call WaitForAssert({-> assert_equal(1, winnr('$'))}) 1603 call assert_equal("", bufname(buf)) 1604 1605 unlet g:job 1606endfunc 1607 1608func Test_zz2_terminal_guioptions_bang() 1609 if !has('gui_running') 1610 return 1611 endif 1612 set guioptions+=! 1613 1614 let filename = 'Xtestscript' 1615 if has('win32') 1616 let filename .= '.bat' 1617 let prefix = '' 1618 let contents = ['@echo off', 'exit %1'] 1619 else 1620 let filename .= '.sh' 1621 let prefix = './' 1622 let contents = ['#!/bin/sh', 'exit $1'] 1623 endif 1624 call writefile(contents, filename) 1625 call setfperm(filename, 'rwxrwx---') 1626 1627 " Check if v:shell_error is equal to the exit status. 1628 let exitval = 0 1629 execute printf(':!%s%s %d', prefix, filename, exitval) 1630 call assert_equal(exitval, v:shell_error) 1631 1632 let exitval = 9 1633 execute printf(':!%s%s %d', prefix, filename, exitval) 1634 call assert_equal(exitval, v:shell_error) 1635 1636 set guioptions& 1637 call delete(filename) 1638endfunc 1639 1640func Test_terminal_hidden() 1641 if !has('unix') 1642 return 1643 endif 1644 term ++hidden cat 1645 let bnr = bufnr('$') 1646 call assert_equal('terminal', getbufvar(bnr, '&buftype')) 1647 exe 'sbuf ' . bnr 1648 call assert_equal('terminal', &buftype) 1649 call term_sendkeys(bnr, "asdf\<CR>") 1650 call WaitForAssert({-> assert_match('asdf', term_getline(bnr, 2))}) 1651 call term_sendkeys(bnr, "\<C-D>") 1652 call WaitForAssert({-> assert_equal('finished', term_getstatus(bnr))}) 1653 bwipe! 1654endfunc 1655 1656func Test_terminal_hidden_and_close() 1657 if !has('unix') 1658 return 1659 endif 1660 call assert_equal(1, winnr('$')) 1661 term ++hidden ++close ls 1662 let bnr = bufnr('$') 1663 call assert_equal('terminal', getbufvar(bnr, '&buftype')) 1664 call WaitForAssert({-> assert_false(bufexists(bnr))}) 1665 call assert_equal(1, winnr('$')) 1666endfunc 1667 1668func Test_terminal_does_not_truncate_last_newlines() 1669 let contents = [ 1670 \ [ 'One', '', 'X' ], 1671 \ [ 'Two', '', '' ], 1672 \ [ 'Three' ] + repeat([''], 30) 1673 \ ] 1674 1675 for c in contents 1676 call writefile(c, 'Xfile') 1677 if has('win32') 1678 term cmd /c type Xfile 1679 else 1680 term cat Xfile 1681 endif 1682 let bnr = bufnr('$') 1683 call assert_equal('terminal', getbufvar(bnr, '&buftype')) 1684 call WaitForAssert({-> assert_equal('finished', term_getstatus(bnr))}) 1685 sleep 100m 1686 call assert_equal(c, getline(1, line('$'))) 1687 quit 1688 endfor 1689 1690 call delete('Xfile') 1691endfunc 1692 1693func Test_terminal_no_job() 1694 let term = term_start('false', {'term_finish': 'close'}) 1695 call WaitForAssert({-> assert_equal(v:null, term_getjob(term)) }) 1696endfunc 1697 1698func Test_term_gettitle() 1699 if !has('title') || empty(&t_ts) 1700 return 1701 endif 1702 " TODO: this fails on Travis 1703 return 1704 1705 " term_gettitle() returns an empty string for a non-terminal buffer 1706 " or for a non-existing buffer. 1707 call assert_equal('', term_gettitle(bufnr('%'))) 1708 call assert_equal('', term_gettitle(bufnr('$') + 1)) 1709 1710 let term = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile']) 1711 call WaitForAssert({-> assert_equal('[No Name] - VIM', term_gettitle(term)) }) 1712 1713 call term_sendkeys(term, ":e Xfoo\r") 1714 call WaitForAssert({-> assert_match('Xfoo (.*[/\\]testdir) - VIM', term_gettitle(term)) }) 1715 1716 call term_sendkeys(term, ":set titlestring=foo\r") 1717 call WaitForAssert({-> assert_equal('foo', term_gettitle(term)) }) 1718 1719 exe term . 'bwipe!' 1720endfunc 1721