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