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 let g:test_is_flaky = 1 21 22 let termlist = term_list() 23 call assert_equal(1, len(termlist)) 24 call assert_equal(buf, termlist[0]) 25 26 let g:job = term_getjob(buf) 27 call assert_equal(v:t_job, type(g:job)) 28 29 let string = string({'job': buf->term_getjob()}) 30 call assert_match("{'job': 'process \\d\\+ run'}", string) 31 32 return buf 33endfunc 34 35func Test_terminal_basic() 36 au TerminalOpen * let b:done = 'yes' 37 let buf = Run_shell_in_terminal({}) 38 39 call assert_equal('t', mode()) 40 call assert_equal('yes', b:done) 41 call assert_match('%aR[^\n]*running]', execute('ls')) 42 call assert_match('%aR[^\n]*running]', execute('ls R')) 43 call assert_notmatch('%[^\n]*running]', execute('ls F')) 44 call assert_notmatch('%[^\n]*running]', execute('ls ?')) 45 call assert_fails('set modifiable', 'E946:') 46 47 call StopShellInTerminal(buf) 48 call TermWait(buf) 49 call assert_equal('n', mode()) 50 call assert_match('%aF[^\n]*finished]', execute('ls')) 51 call assert_match('%aF[^\n]*finished]', execute('ls F')) 52 call assert_notmatch('%[^\n]*finished]', execute('ls R')) 53 call assert_notmatch('%[^\n]*finished]', execute('ls ?')) 54 55 " closing window wipes out the terminal buffer a with finished job 56 close 57 call assert_equal("", bufname(buf)) 58 59 au! TerminalOpen 60 unlet g:job 61endfunc 62 63func Test_terminal_TerminalWinOpen() 64 au TerminalWinOpen * let b:done = 'yes' 65 let buf = Run_shell_in_terminal({}) 66 call assert_equal('yes', b:done) 67 call StopShellInTerminal(buf) 68 " closing window wipes out the terminal buffer with the finished job 69 close 70 71 if has("unix") 72 terminal ++hidden ++open sleep 1 73 sleep 1 74 call assert_fails("echo b:done", 'E121:') 75 endif 76 77 au! TerminalWinOpen 78endfunc 79 80func Test_terminal_make_change() 81 let buf = Run_shell_in_terminal({}) 82 call StopShellInTerminal(buf) 83 call TermWait(buf) 84 85 setlocal modifiable 86 exe "normal Axxx\<Esc>" 87 call assert_fails(buf . 'bwipe', 'E517') 88 undo 89 90 exe buf . 'bwipe' 91 unlet g:job 92endfunc 93 94func Test_terminal_paste_register() 95 let @" = "text to paste" 96 97 let buf = Run_shell_in_terminal({}) 98 " Wait for the shell to display a prompt 99 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))}) 100 101 call feedkeys("echo \<C-W>\"\" \<C-W>\"=37 + 5\<CR>\<CR>", 'xt') 102 call WaitForAssert({-> assert_match("echo text to paste 42$", getline(1))}) 103 call WaitForAssert({-> assert_equal('text to paste 42', 2->getline())}) 104 105 exe buf . 'bwipe!' 106 unlet g:job 107endfunc 108 109func Test_terminal_wipe_buffer() 110 let buf = Run_shell_in_terminal({}) 111 call assert_fails(buf . 'bwipe', 'E517') 112 exe buf . 'bwipe!' 113 call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) 114 call assert_equal("", bufname(buf)) 115 116 unlet g:job 117endfunc 118 119func Test_terminal_split_quit() 120 let buf = Run_shell_in_terminal({}) 121 call TermWait(buf) 122 split 123 quit! 124 call TermWait(buf) 125 sleep 50m 126 call assert_equal('run', job_status(g:job)) 127 128 quit! 129 call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) 130 131 exe buf . 'bwipe' 132 unlet g:job 133endfunc 134 135func Test_terminal_hide_buffer() 136 let buf = Run_shell_in_terminal({}) 137 setlocal bufhidden=hide 138 quit 139 for nr in range(1, winnr('$')) 140 call assert_notequal(winbufnr(nr), buf) 141 endfor 142 call assert_true(bufloaded(buf)) 143 call assert_true(buflisted(buf)) 144 145 exe 'split ' . buf . 'buf' 146 call StopShellInTerminal(buf) 147 exe buf . 'bwipe' 148 149 unlet g:job 150endfunc 151 152func s:Nasty_exit_cb(job, st) 153 exe g:buf . 'bwipe!' 154 let g:buf = 0 155endfunc 156 157func Get_cat_123_cmd() 158 if has('win32') 159 if !has('conpty') 160 return 'cmd /c "cls && color 2 && echo 123"' 161 else 162 " When clearing twice, extra sequence is not output. 163 return 'cmd /c "cls && cls && color 2 && echo 123"' 164 endif 165 else 166 call writefile(["\<Esc>[32m123"], 'Xtext') 167 return "cat Xtext" 168 endif 169endfunc 170 171func Test_terminal_nasty_cb() 172 let cmd = Get_cat_123_cmd() 173 let g:buf = term_start(cmd, {'exit_cb': function('s:Nasty_exit_cb')}) 174 let g:job = term_getjob(g:buf) 175 176 call WaitForAssert({-> assert_equal("dead", job_status(g:job))}) 177 call WaitForAssert({-> assert_equal(0, g:buf)}) 178 unlet g:job 179 unlet g:buf 180 call delete('Xtext') 181endfunc 182 183func Check_123(buf) 184 let l = term_scrape(a:buf, 0) 185 call assert_true(len(l) == 0) 186 let l = term_scrape(a:buf, 999) 187 call assert_true(len(l) == 0) 188 let l = a:buf->term_scrape(1) 189 call assert_true(len(l) > 0) 190 call assert_equal('1', l[0].chars) 191 call assert_equal('2', l[1].chars) 192 call assert_equal('3', l[2].chars) 193 call assert_equal('#00e000', l[0].fg) 194 call assert_equal(0, term_getattr(l[0].attr, 'bold')) 195 call assert_equal(0, l[0].attr->term_getattr('italic')) 196 if has('win32') 197 " On Windows 'background' always defaults to dark, even though the terminal 198 " may use a light background. Therefore accept both white and black. 199 call assert_match('#ffffff\|#000000', l[0].bg) 200 else 201 if &background == 'light' 202 call assert_equal('#ffffff', l[0].bg) 203 else 204 call assert_equal('#000000', l[0].bg) 205 endif 206 endif 207 208 let l = term_getline(a:buf, -1) 209 call assert_equal('', l) 210 let l = term_getline(a:buf, 0) 211 call assert_equal('', l) 212 let l = term_getline(a:buf, 999) 213 call assert_equal('', l) 214 let l = term_getline(a:buf, 1) 215 call assert_equal('123', l) 216endfunc 217 218func Test_terminal_scrape_123() 219 let cmd = Get_cat_123_cmd() 220 let buf = term_start(cmd) 221 222 let termlist = term_list() 223 call assert_equal(1, len(termlist)) 224 call assert_equal(buf, termlist[0]) 225 226 " Nothing happens with invalid buffer number 227 call term_wait(1234) 228 229 call TermWait(buf) 230 " On MS-Windows we first get a startup message of two lines, wait for the 231 " "cls" to happen, after that we have one line with three characters. 232 call WaitForAssert({-> assert_equal(3, len(term_scrape(buf, 1)))}) 233 call Check_123(buf) 234 235 " Must still work after the job ended. 236 let job = term_getjob(buf) 237 call WaitForAssert({-> assert_equal("dead", job_status(job))}) 238 call TermWait(buf) 239 call Check_123(buf) 240 241 exe buf . 'bwipe' 242 call delete('Xtext') 243endfunc 244 245func Test_terminal_scrape_multibyte() 246 call writefile(["léttまrs"], 'Xtext') 247 if has('win32') 248 " Run cmd with UTF-8 codepage to make the type command print the expected 249 " multibyte characters. 250 let buf = term_start("cmd /K chcp 65001") 251 call term_sendkeys(buf, "type Xtext\<CR>") 252 eval buf->term_sendkeys("exit\<CR>") 253 let line = 4 254 else 255 let buf = term_start("cat Xtext") 256 let line = 1 257 endif 258 259 call WaitFor({-> len(term_scrape(buf, line)) >= 7 && term_scrape(buf, line)[0].chars == "l"}) 260 let l = term_scrape(buf, line) 261 call assert_true(len(l) >= 7) 262 call assert_equal('l', l[0].chars) 263 call assert_equal('é', l[1].chars) 264 call assert_equal(1, l[1].width) 265 call assert_equal('t', l[2].chars) 266 call assert_equal('t', l[3].chars) 267 call assert_equal('ま', l[4].chars) 268 call assert_equal(2, l[4].width) 269 call assert_equal('r', l[5].chars) 270 call assert_equal('s', l[6].chars) 271 272 let job = term_getjob(buf) 273 call WaitForAssert({-> assert_equal("dead", job_status(job))}) 274 call TermWait(buf) 275 276 exe buf . 'bwipe' 277 call delete('Xtext') 278endfunc 279 280func Test_terminal_scroll() 281 call writefile(range(1, 200), 'Xtext') 282 if has('win32') 283 let cmd = 'cmd /c "type Xtext"' 284 else 285 let cmd = "cat Xtext" 286 endif 287 let buf = term_start(cmd) 288 289 let job = term_getjob(buf) 290 call WaitForAssert({-> assert_equal("dead", job_status(job))}) 291 call TermWait(buf) 292 293 " wait until the scrolling stops 294 while 1 295 let scrolled = buf->term_getscrolled() 296 sleep 20m 297 if scrolled == buf->term_getscrolled() 298 break 299 endif 300 endwhile 301 302 call assert_equal('1', getline(1)) 303 call assert_equal('1', term_getline(buf, 1 - scrolled)) 304 call assert_equal('49', getline(49)) 305 call assert_equal('49', term_getline(buf, 49 - scrolled)) 306 call assert_equal('200', getline(200)) 307 call assert_equal('200', term_getline(buf, 200 - scrolled)) 308 309 exe buf . 'bwipe' 310 call delete('Xtext') 311endfunc 312 313func Test_terminal_scrollback() 314 let buf = Run_shell_in_terminal({'term_rows': 15}) 315 set termwinscroll=100 316 call writefile(range(150), 'Xtext') 317 if has('win32') 318 call term_sendkeys(buf, "type Xtext\<CR>") 319 else 320 call term_sendkeys(buf, "cat Xtext\<CR>") 321 endif 322 let rows = term_getsize(buf)[0] 323 " On MS-Windows there is an empty line, check both last line and above it. 324 call WaitForAssert({-> assert_match( '149', term_getline(buf, rows - 1) . term_getline(buf, rows - 2))}) 325 let lines = line('$') 326 call assert_inrange(91, 100, lines) 327 328 call StopShellInTerminal(buf) 329 call TermWait(buf) 330 exe buf . 'bwipe' 331 set termwinscroll& 332 call delete('Xtext') 333endfunc 334 335func Test_terminal_postponed_scrollback() 336 " tail -f only works on Unix 337 CheckUnix 338 339 call writefile(range(50), 'Xtext') 340 call writefile([ 341 \ 'set shell=/bin/sh noruler', 342 \ 'terminal', 343 \ 'sleep 200m', 344 \ 'call feedkeys("tail -n 100 -f Xtext\<CR>", "xt")', 345 \ 'sleep 100m', 346 \ 'call feedkeys("\<C-W>N", "xt")', 347 \ ], 'XTest_postponed') 348 let buf = RunVimInTerminal('-S XTest_postponed', {}) 349 " Check that the Xtext lines are displayed and in Terminal-Normal mode 350 call VerifyScreenDump(buf, 'Test_terminal_scrollback_1', {}) 351 352 silent !echo 'one more line' >>Xtext 353 " Screen will not change, move cursor to get a different dump 354 call term_sendkeys(buf, "k") 355 call VerifyScreenDump(buf, 'Test_terminal_scrollback_2', {}) 356 357 " Back to Terminal-Job mode, text will scroll and show the extra line. 358 call term_sendkeys(buf, "a") 359 call VerifyScreenDump(buf, 'Test_terminal_scrollback_3', {}) 360 361 " stop "tail -f" 362 call term_sendkeys(buf, "\<C-C>") 363 call TermWait(buf, 25) 364 " stop shell 365 call term_sendkeys(buf, "exit\<CR>") 366 call TermWait(buf, 50) 367 " close terminal window 368 let tsk_ret = term_sendkeys(buf, ":q\<CR>") 369 370 " check type of term_sendkeys() return value 371 echo type(tsk_ret) 372 373 call StopVimInTerminal(buf) 374 call delete('XTest_postponed') 375 call delete('Xtext') 376endfunc 377 378" Run diff on two dumps with different size. 379func Test_terminal_dumpdiff_size() 380 call assert_equal(1, winnr('$')) 381 call term_dumpdiff('dumps/Test_incsearch_search_01.dump', 'dumps/Test_popup_command_01.dump') 382 call assert_equal(2, winnr('$')) 383 call assert_match('Test_incsearch_search_01.dump', getline(10)) 384 call assert_match(' +++++$', getline(11)) 385 call assert_match('Test_popup_command_01.dump', getline(31)) 386 call assert_equal(repeat('+', 75), getline(30)) 387 quit 388endfunc 389 390func Test_terminal_size() 391 let cmd = Get_cat_123_cmd() 392 393 exe 'terminal ++rows=5 ' . cmd 394 let size = term_getsize('') 395 bwipe! 396 call assert_equal(5, size[0]) 397 398 call term_start(cmd, {'term_rows': 6}) 399 let size = term_getsize('') 400 bwipe! 401 call assert_equal(6, size[0]) 402 403 vsplit 404 exe 'terminal ++rows=5 ++cols=33 ' . cmd 405 call assert_equal([5, 33], ''->term_getsize()) 406 407 call term_setsize('', 6, 0) 408 call assert_equal([6, 33], term_getsize('')) 409 410 eval ''->term_setsize(0, 35) 411 call assert_equal([6, 35], term_getsize('')) 412 413 call term_setsize('', 7, 30) 414 call assert_equal([7, 30], term_getsize('')) 415 416 bwipe! 417 call assert_fails("call term_setsize('', 7, 30)", "E955:") 418 419 call term_start(cmd, {'term_rows': 6, 'term_cols': 36}) 420 let size = term_getsize('') 421 bwipe! 422 call assert_equal([6, 36], size) 423 424 exe 'vertical terminal ++cols=20 ' . cmd 425 let size = term_getsize('') 426 bwipe! 427 call assert_equal(20, size[1]) 428 429 eval cmd->term_start({'vertical': 1, 'term_cols': 26}) 430 let size = term_getsize('') 431 bwipe! 432 call assert_equal(26, size[1]) 433 434 split 435 exe 'vertical terminal ++rows=6 ++cols=20 ' . cmd 436 let size = term_getsize('') 437 bwipe! 438 call assert_equal([6, 20], size) 439 440 call term_start(cmd, {'vertical': 1, 'term_rows': 7, 'term_cols': 27}) 441 let size = term_getsize('') 442 bwipe! 443 call assert_equal([7, 27], size) 444 445 call delete('Xtext') 446endfunc 447 448func Test_terminal_curwin() 449 let cmd = Get_cat_123_cmd() 450 call assert_equal(1, winnr('$')) 451 452 split dummy 453 exe 'terminal ++curwin ' . cmd 454 call assert_equal(2, winnr('$')) 455 bwipe! 456 457 split dummy 458 call term_start(cmd, {'curwin': 1}) 459 call assert_equal(2, winnr('$')) 460 bwipe! 461 462 split dummy 463 call setline(1, 'change') 464 call assert_fails('terminal ++curwin ' . cmd, 'E37:') 465 call assert_equal(2, winnr('$')) 466 exe 'terminal! ++curwin ' . cmd 467 call assert_equal(2, winnr('$')) 468 bwipe! 469 470 split dummy 471 call setline(1, 'change') 472 call assert_fails("call term_start(cmd, {'curwin': 1})", 'E37:') 473 call assert_equal(2, winnr('$')) 474 bwipe! 475 476 split dummy 477 bwipe! 478 call delete('Xtext') 479endfunc 480 481func s:get_sleep_cmd() 482 if s:python != '' 483 let cmd = s:python . " test_short_sleep.py" 484 " 500 was not enough for Travis 485 let waittime = 900 486 else 487 echo 'This will take five seconds...' 488 let waittime = 2000 489 if has('win32') 490 let cmd = $windir . '\system32\timeout.exe 1' 491 else 492 let cmd = 'sleep 1' 493 endif 494 endif 495 return [cmd, waittime] 496endfunc 497 498func Test_terminal_finish_open_close() 499 call assert_equal(1, winnr('$')) 500 501 let [cmd, waittime] = s:get_sleep_cmd() 502 503 " shell terminal closes automatically 504 terminal 505 let buf = bufnr('%') 506 call assert_equal(2, winnr('$')) 507 " Wait for the shell to display a prompt 508 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))}) 509 call StopShellInTerminal(buf) 510 call WaitForAssert({-> assert_equal(1, winnr('$'))}, waittime) 511 512 " shell terminal that does not close automatically 513 terminal ++noclose 514 let buf = bufnr('%') 515 call assert_equal(2, winnr('$')) 516 " Wait for the shell to display a prompt 517 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))}) 518 call StopShellInTerminal(buf) 519 call assert_equal(2, winnr('$')) 520 quit 521 call assert_equal(1, winnr('$')) 522 523 exe 'terminal ++close ' . cmd 524 call assert_equal(2, winnr('$')) 525 wincmd p 526 call WaitForAssert({-> assert_equal(1, winnr('$'))}, waittime) 527 528 call term_start(cmd, {'term_finish': 'close'}) 529 call assert_equal(2, winnr('$')) 530 wincmd p 531 call WaitForAssert({-> assert_equal(1, winnr('$'))}, waittime) 532 call assert_equal(1, winnr('$')) 533 534 exe 'terminal ++open ' . cmd 535 close! 536 call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime) 537 bwipe 538 539 call term_start(cmd, {'term_finish': 'open'}) 540 close! 541 call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime) 542 bwipe 543 544 exe 'terminal ++hidden ++open ' . cmd 545 call assert_equal(1, winnr('$')) 546 call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime) 547 bwipe 548 549 call term_start(cmd, {'term_finish': 'open', 'hidden': 1}) 550 call assert_equal(1, winnr('$')) 551 call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime) 552 bwipe 553 554 call assert_fails("call term_start(cmd, {'term_opencmd': 'open'})", 'E475:') 555 call assert_fails("call term_start(cmd, {'term_opencmd': 'split %x'})", 'E475:') 556 call assert_fails("call term_start(cmd, {'term_opencmd': 'split %d and %s'})", 'E475:') 557 call assert_fails("call term_start(cmd, {'term_opencmd': 'split % and %d'})", 'E475:') 558 559 call term_start(cmd, {'term_finish': 'open', 'term_opencmd': '4split | buffer %d'}) 560 close! 561 call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime) 562 call assert_equal(4, winheight(0)) 563 bwipe 564endfunc 565 566func Test_terminal_cwd() 567 if has('win32') 568 let cmd = 'cmd /c cd' 569 else 570 CheckExecutable pwd 571 let cmd = 'pwd' 572 endif 573 call mkdir('Xdir') 574 let buf = term_start(cmd, {'cwd': 'Xdir'}) 575 call WaitForAssert({-> assert_equal('Xdir', fnamemodify(getline(1), ":t"))}) 576 577 exe buf . 'bwipe' 578 call delete('Xdir', 'rf') 579endfunc 580 581func Test_terminal_cwd_failure() 582 " Case 1: Provided directory is not actually a directory. Attempt to make 583 " the file executable as well. 584 call writefile([], 'Xfile') 585 call setfperm('Xfile', 'rwx------') 586 call assert_fails("call term_start(&shell, {'cwd': 'Xfile'})", 'E475:') 587 call delete('Xfile') 588 589 " Case 2: Directory does not exist. 590 call assert_fails("call term_start(&shell, {'cwd': 'Xdir'})", 'E475:') 591 592 " Case 3: Directory exists but is not accessible. 593 " Skip this for root, it will be accessible anyway. 594 if !IsRoot() 595 call mkdir('XdirNoAccess', '', '0600') 596 " return early if the directory permissions could not be set properly 597 if getfperm('XdirNoAccess')[2] == 'x' 598 call delete('XdirNoAccess', 'rf') 599 return 600 endif 601 call assert_fails("call term_start(&shell, {'cwd': 'XdirNoAccess'})", 'E475:') 602 call delete('XdirNoAccess', 'rf') 603 endif 604endfunc 605 606func Test_terminal_servername() 607 if !has('clientserver') 608 return 609 endif 610 call s:test_environment("VIM_SERVERNAME", v:servername) 611endfunc 612 613func Test_terminal_version() 614 call s:test_environment("VIM_TERMINAL", string(v:version)) 615endfunc 616 617func s:test_environment(name, value) 618 let buf = Run_shell_in_terminal({}) 619 " Wait for the shell to display a prompt 620 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))}) 621 if has('win32') 622 call term_sendkeys(buf, "echo %" . a:name . "%\r") 623 else 624 call term_sendkeys(buf, "echo $" . a:name . "\r") 625 endif 626 call TermWait(buf) 627 call StopShellInTerminal(buf) 628 call WaitForAssert({-> assert_equal(a:value, getline(2))}) 629 630 exe buf . 'bwipe' 631 unlet buf 632endfunc 633 634func Test_terminal_env() 635 let buf = Run_shell_in_terminal({'env': {'TESTENV': 'correct'}}) 636 " Wait for the shell to display a prompt 637 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))}) 638 if has('win32') 639 call term_sendkeys(buf, "echo %TESTENV%\r") 640 else 641 call term_sendkeys(buf, "echo $TESTENV\r") 642 endif 643 eval buf->TermWait() 644 call StopShellInTerminal(buf) 645 call WaitForAssert({-> assert_equal('correct', getline(2))}) 646 647 exe buf . 'bwipe' 648endfunc 649 650func Test_terminal_list_args() 651 let buf = term_start([&shell, &shellcmdflag, 'echo "123"']) 652 call assert_fails(buf . 'bwipe', 'E517') 653 exe buf . 'bwipe!' 654 call assert_equal("", bufname(buf)) 655endfunction 656 657func Test_terminal_noblock() 658 let buf = term_start(&shell) 659 let wait_time = 5000 660 let letters = 'abcdefghijklmnopqrstuvwxyz' 661 if has('bsd') || has('mac') || has('sun') 662 " The shell or something else has a problem dealing with more than 1000 663 " characters at the same time. It's very slow too. 664 let len = 1000 665 let wait_time = 15000 666 let letters = 'abcdefghijklm' 667 " NPFS is used in Windows, nonblocking mode does not work properly. 668 elseif has('win32') 669 let len = 1 670 else 671 let len = 5000 672 endif 673 674 " Send a lot of text lines, should be buffered properly. 675 for c in split(letters, '\zs') 676 call term_sendkeys(buf, 'echo ' . repeat(c, len) . "\<cr>") 677 endfor 678 call term_sendkeys(buf, "echo done\<cr>") 679 680 " On MS-Windows there is an extra empty line below "done". Find "done" in 681 " the last-but-one or the last-but-two line. 682 let lnum = term_getsize(buf)[0] - 1 683 call WaitForAssert({-> assert_match('done', term_getline(buf, lnum - 1) .. '//' .. term_getline(buf, lnum))}, wait_time) 684 let line = term_getline(buf, lnum) 685 if line !~ 'done' 686 let line = term_getline(buf, lnum - 1) 687 endif 688 call assert_match('done', line) 689 690 let g:job = term_getjob(buf) 691 call StopShellInTerminal(buf) 692 call TermWait(buf) 693 unlet g:job 694 bwipe 695endfunc 696 697func Test_terminal_write_stdin() 698 " TODO: enable once writing to stdin works on MS-Windows 699 CheckNotMSWindows 700 CheckExecutable wc 701 702 call setline(1, ['one', 'two', 'three']) 703 %term wc 704 call WaitForAssert({-> assert_match('3', getline("$"))}) 705 let nrs = split(getline('$')) 706 call assert_equal(['3', '3', '14'], nrs) 707 %bwipe! 708 709 call setline(1, ['one', 'two', 'three', 'four']) 710 2,3term wc 711 call WaitForAssert({-> assert_match('2', getline("$"))}) 712 let nrs = split(getline('$')) 713 call assert_equal(['2', '2', '10'], nrs) 714 %bwipe! 715endfunc 716 717func Test_terminal_eof_arg() 718 call CheckPython(s:python) 719 720 call setline(1, ['print("hello")']) 721 exe '1term ++eof=exit(123) ' .. s:python 722 " MS-Windows echoes the input, Unix doesn't. 723 if has('win32') 724 call WaitFor({-> getline('$') =~ 'exit(123)'}) 725 call assert_equal('hello', getline(line('$') - 1)) 726 else 727 call WaitFor({-> getline('$') =~ 'hello'}) 728 call assert_equal('hello', getline('$')) 729 endif 730 call assert_equal(123, bufnr()->term_getjob()->job_info().exitval) 731 %bwipe! 732endfunc 733 734func Test_terminal_eof_arg_win32_ctrl_z() 735 CheckMSWindows 736 call CheckPython(s:python) 737 738 call setline(1, ['print("hello")']) 739 exe '1term ++eof=<C-Z> ' .. s:python 740 call WaitForAssert({-> assert_match('\^Z', getline(line('$') - 1))}) 741 call assert_match('\^Z', getline(line('$') - 1)) 742 %bwipe! 743endfunc 744 745func Test_terminal_duplicate_eof_arg() 746 call CheckPython(s:python) 747 748 " Check the last specified ++eof arg is used and should not memory leak. 749 new 750 call setline(1, ['print("hello")']) 751 exe '1term ++eof=<C-Z> ++eof=exit(123) ' .. s:python 752 " MS-Windows echoes the input, Unix doesn't. 753 if has('win32') 754 call WaitFor({-> getline('$') =~ 'exit(123)'}) 755 call assert_equal('hello', getline(line('$') - 1)) 756 else 757 call WaitFor({-> getline('$') =~ 'hello'}) 758 call assert_equal('hello', getline('$')) 759 endif 760 call assert_equal(123, bufnr()->term_getjob()->job_info().exitval) 761 %bwipe! 762endfunc 763 764func Test_terminal_no_cmd() 765 let buf = term_start('NONE', {}) 766 call assert_notequal(0, buf) 767 768 let pty = job_info(term_getjob(buf))['tty_out'] 769 call assert_notequal('', pty) 770 if has('gui_running') && !has('win32') 771 " In the GUI job_start() doesn't work, it does not read from the pty. 772 call system('echo "look here" > ' . pty) 773 else 774 " Otherwise using a job works on all systems. 775 call job_start([&shell, &shellcmdflag, 'echo "look here" > ' . pty]) 776 endif 777 call WaitForAssert({-> assert_match('look here', term_getline(buf, 1))}) 778 779 bwipe! 780endfunc 781 782func Test_terminal_special_chars() 783 " this file name only works on Unix 784 CheckUnix 785 786 call mkdir('Xdir with spaces') 787 call writefile(['x'], 'Xdir with spaces/quoted"file') 788 term ls Xdir\ with\ spaces/quoted\"file 789 call WaitForAssert({-> assert_match('quoted"file', term_getline('', 1))}) 790 " make sure the job has finished 791 call WaitForAssert({-> assert_match('finish', term_getstatus(bufnr()))}) 792 793 call delete('Xdir with spaces', 'rf') 794 bwipe 795endfunc 796 797func Test_terminal_wrong_options() 798 call assert_fails('call term_start(&shell, { 799 \ "in_io": "file", 800 \ "in_name": "xxx", 801 \ "out_io": "file", 802 \ "out_name": "xxx", 803 \ "err_io": "file", 804 \ "err_name": "xxx" 805 \ })', 'E474:') 806 call assert_fails('call term_start(&shell, { 807 \ "out_buf": bufnr("%") 808 \ })', 'E474:') 809 call assert_fails('call term_start(&shell, { 810 \ "err_buf": bufnr("%") 811 \ })', 'E474:') 812endfunc 813 814func Test_terminal_redir_file() 815 let cmd = Get_cat_123_cmd() 816 let buf = term_start(cmd, {'out_io': 'file', 'out_name': 'Xfile'}) 817 call TermWait(buf) 818 " ConPTY may precede escape sequence. There are things that are not so. 819 if !has('conpty') 820 call WaitForAssert({-> assert_notequal(0, len(readfile("Xfile")))}) 821 call assert_match('123', readfile('Xfile')[0]) 822 endif 823 let g:job = term_getjob(buf) 824 call WaitForAssert({-> assert_equal("dead", job_status(g:job))}) 825 call delete('Xfile') 826 bwipe 827 828 if has('unix') 829 call writefile(['one line'], 'Xfile') 830 let buf = term_start('cat', {'in_io': 'file', 'in_name': 'Xfile'}) 831 call TermWait(buf) 832 call WaitForAssert({-> assert_equal('one line', term_getline(buf, 1))}) 833 let g:job = term_getjob(buf) 834 call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) 835 bwipe 836 call delete('Xfile') 837 endif 838endfunc 839 840func TerminalTmap(remap) 841 let buf = Run_shell_in_terminal({}) 842 call assert_equal('t', mode()) 843 844 if a:remap 845 tmap 123 456 846 else 847 tnoremap 123 456 848 endif 849 " don't use abcde, it's an existing command 850 tmap 456 abxde 851 call assert_equal('456', maparg('123', 't')) 852 call assert_equal('abxde', maparg('456', 't')) 853 call feedkeys("123", 'tx') 854 call WaitForAssert({-> assert_match('abxde\|456', term_getline(buf, term_getcursor(buf)[0]))}) 855 let lnum = term_getcursor(buf)[0] 856 if a:remap 857 call assert_match('abxde', term_getline(buf, lnum)) 858 else 859 call assert_match('456', term_getline(buf, lnum)) 860 endif 861 862 call term_sendkeys(buf, "\r") 863 call StopShellInTerminal(buf) 864 call TermWait(buf) 865 866 tunmap 123 867 tunmap 456 868 call assert_equal('', maparg('123', 't')) 869 close 870 unlet g:job 871endfunc 872 873func Test_terminal_tmap() 874 call TerminalTmap(1) 875 call TerminalTmap(0) 876endfunc 877 878func Test_terminal_wall() 879 let buf = Run_shell_in_terminal({}) 880 wall 881 call StopShellInTerminal(buf) 882 call TermWait(buf) 883 exe buf . 'bwipe' 884 unlet g:job 885endfunc 886 887func Test_terminal_wqall() 888 let buf = Run_shell_in_terminal({}) 889 call assert_fails('wqall', 'E948') 890 call StopShellInTerminal(buf) 891 call TermWait(buf) 892 exe buf . 'bwipe' 893 unlet g:job 894endfunc 895 896func Test_terminal_composing_unicode() 897 let save_enc = &encoding 898 set encoding=utf-8 899 900 if has('win32') 901 let cmd = "cmd /K chcp 65001" 902 let lnum = [3, 6, 9] 903 else 904 let cmd = &shell 905 let lnum = [1, 3, 5] 906 endif 907 908 enew 909 let buf = term_start(cmd, {'curwin': bufnr('')}) 910 let g:job = term_getjob(buf) 911 call WaitFor({-> term_getline(buf, 1) !=# ''}, 1000) 912 913 if has('win32') 914 call assert_equal('cmd', job_info(g:job).cmd[0]) 915 else 916 call assert_equal(&shell, job_info(g:job).cmd[0]) 917 endif 918 919 " ascii + composing 920 let txt = "a\u0308bc" 921 call term_sendkeys(buf, "echo " . txt) 922 call TermWait(buf, 25) 923 call assert_match("echo " . txt, term_getline(buf, lnum[0])) 924 call term_sendkeys(buf, "\<cr>") 925 call WaitForAssert({-> assert_equal(txt, term_getline(buf, lnum[0] + 1))}, 1000) 926 let l = term_scrape(buf, lnum[0] + 1) 927 call assert_equal("a\u0308", l[0].chars) 928 call assert_equal("b", l[1].chars) 929 call assert_equal("c", l[2].chars) 930 931 " multibyte + composing 932 let txt = "\u304b\u3099\u304e\u304f\u3099\u3052\u3053\u3099" 933 call term_sendkeys(buf, "echo " . txt) 934 call TermWait(buf, 25) 935 call assert_match("echo " . txt, term_getline(buf, lnum[1])) 936 call term_sendkeys(buf, "\<cr>") 937 call WaitForAssert({-> assert_equal(txt, term_getline(buf, lnum[1] + 1))}, 1000) 938 let l = term_scrape(buf, lnum[1] + 1) 939 call assert_equal("\u304b\u3099", l[0].chars) 940 call assert_equal("\u304e", l[1].chars) 941 call assert_equal("\u304f\u3099", l[2].chars) 942 call assert_equal("\u3052", l[3].chars) 943 call assert_equal("\u3053\u3099", l[4].chars) 944 945 " \u00a0 + composing 946 let txt = "abc\u00a0\u0308" 947 call term_sendkeys(buf, "echo " . txt) 948 call TermWait(buf, 25) 949 call assert_match("echo " . txt, term_getline(buf, lnum[2])) 950 call term_sendkeys(buf, "\<cr>") 951 call WaitForAssert({-> assert_equal(txt, term_getline(buf, lnum[2] + 1))}, 1000) 952 let l = term_scrape(buf, lnum[2] + 1) 953 call assert_equal("\u00a0\u0308", l[3].chars) 954 955 call term_sendkeys(buf, "exit\r") 956 call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) 957 bwipe! 958 unlet g:job 959 let &encoding = save_enc 960endfunc 961 962func Test_terminal_aucmd_on_close() 963 fun Nop() 964 let s:called = 1 965 endfun 966 967 aug repro 968 au! 969 au BufWinLeave * call Nop() 970 aug END 971 972 let [cmd, waittime] = s:get_sleep_cmd() 973 974 call assert_equal(1, winnr('$')) 975 new 976 call setline(1, ['one', 'two']) 977 exe 'term ++close ' . cmd 978 wincmd p 979 call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime) 980 call assert_equal(1, s:called) 981 bwipe! 982 983 unlet s:called 984 au! repro 985 delfunc Nop 986endfunc 987 988func Test_terminal_term_start_empty_command() 989 let cmd = "call term_start('', {'curwin' : 1, 'term_finish' : 'close'})" 990 call assert_fails(cmd, 'E474') 991 let cmd = "call term_start('', {'curwin' : 1, 'term_finish' : 'close'})" 992 call assert_fails(cmd, 'E474') 993 let cmd = "call term_start({}, {'curwin' : 1, 'term_finish' : 'close'})" 994 call assert_fails(cmd, 'E474') 995 let cmd = "call term_start(0, {'curwin' : 1, 'term_finish' : 'close'})" 996 call assert_fails(cmd, 'E474') 997 let cmd = "call term_start('', {'term_name' : []})" 998 call assert_fails(cmd, 'E475') 999 let cmd = "call term_start('', {'term_finish' : 'axby'})" 1000 call assert_fails(cmd, 'E475') 1001 let cmd = "call term_start('', {'eof_chars' : []})" 1002 call assert_fails(cmd, 'E475:') 1003 let cmd = "call term_start('', {'term_kill' : []})" 1004 call assert_fails(cmd, 'E475:') 1005 let cmd = "call term_start('', {'tty_type' : []})" 1006 call assert_fails(cmd, 'E475:') 1007 let cmd = "call term_start('', {'tty_type' : 'abc'})" 1008 call assert_fails(cmd, 'E475:') 1009 let cmd = "call term_start('', {'term_highlight' : []})" 1010 call assert_fails(cmd, 'E475:') 1011 if has('gui') 1012 let cmd = "call term_start('', {'ansi_colors' : 'abc'})" 1013 call assert_fails(cmd, 'E475:') 1014 let cmd = "call term_start('', {'ansi_colors' : [[]]})" 1015 call assert_fails(cmd, 'E730:') 1016 let cmd = "call term_start('', {'ansi_colors' : repeat(['blue'], 18)})" 1017 call assert_fails(cmd, 'E475:') 1018 endif 1019endfunc 1020 1021func Test_terminal_response_to_control_sequence() 1022 CheckUnix 1023 1024 let buf = Run_shell_in_terminal({}) 1025 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))}) 1026 1027 call term_sendkeys(buf, "cat\<CR>") 1028 call WaitForAssert({-> assert_match('cat', term_getline(buf, 1))}) 1029 1030 " Request the cursor position. 1031 call term_sendkeys(buf, "\x1b[6n\<CR>") 1032 1033 " Wait for output from tty to display, below an empty line. 1034 call WaitForAssert({-> assert_match('3;1R', term_getline(buf, 4))}) 1035 1036 " End "cat" gently. 1037 call term_sendkeys(buf, "\<CR>\<C-D>") 1038 1039 call StopShellInTerminal(buf) 1040 exe buf . 'bwipe' 1041 unlet g:job 1042endfunc 1043 1044" Run Vim, start a terminal in that Vim with the kill argument, 1045" :qall works. 1046func Run_terminal_qall_kill(line1, line2) 1047 " 1. Open a terminal window and wait for the prompt to appear 1048 " 2. set kill using term_setkill() 1049 " 3. make Vim exit, it will kill the shell 1050 let after = [ 1051 \ a:line1, 1052 \ 'let buf = bufnr("%")', 1053 \ 'while term_getline(buf, 1) =~ "^\\s*$"', 1054 \ ' sleep 10m', 1055 \ 'endwhile', 1056 \ a:line2, 1057 \ 'au VimLeavePre * call writefile(["done"], "Xdone")', 1058 \ 'qall', 1059 \ ] 1060 if !RunVim([], after, '') 1061 return 1062 endif 1063 call assert_equal("done", readfile("Xdone")[0]) 1064 call delete("Xdone") 1065endfunc 1066 1067" Run Vim in a terminal, then start a terminal in that Vim with a kill 1068" argument, check that :qall works. 1069func Test_terminal_qall_kill_arg() 1070 call Run_terminal_qall_kill('term ++kill=kill', '') 1071endfunc 1072 1073" Run Vim, start a terminal in that Vim, set the kill argument with 1074" term_setkill(), check that :qall works. 1075func Test_terminal_qall_kill_func() 1076 call Run_terminal_qall_kill('term', 'eval buf->term_setkill("kill")') 1077endfunc 1078 1079" Run Vim, start a terminal in that Vim without the kill argument, 1080" check that :qall does not exit, :qall! does. 1081func Test_terminal_qall_exit() 1082 let after =<< trim [CODE] 1083 term 1084 let buf = bufnr("%") 1085 while term_getline(buf, 1) =~ "^\\s*$" 1086 sleep 10m 1087 endwhile 1088 set nomore 1089 au VimLeavePre * call writefile(["too early"], "Xdone") 1090 qall 1091 au! VimLeavePre * exe buf . "bwipe!" | call writefile(["done"], "Xdone") 1092 cquit 1093 [CODE] 1094 1095 if !RunVim([], after, '') 1096 return 1097 endif 1098 call assert_equal("done", readfile("Xdone")[0]) 1099 call delete("Xdone") 1100endfunc 1101 1102" Run Vim in a terminal, then start a terminal in that Vim without a kill 1103" argument, check that :confirm qall works. 1104func Test_terminal_qall_prompt() 1105 CheckRunVimInTerminal 1106 let buf = RunVimInTerminal('', {}) 1107 1108 " Open a terminal window and wait for the prompt to appear 1109 call term_sendkeys(buf, ":term\<CR>") 1110 call WaitForAssert({-> assert_match('\[running]', term_getline(buf, 10))}) 1111 call WaitForAssert({-> assert_notmatch('^\s*$', term_getline(buf, 1))}) 1112 1113 " make Vim exit, it will prompt to kill the shell 1114 call term_sendkeys(buf, "\<C-W>:confirm qall\<CR>") 1115 call WaitForAssert({-> assert_match('ancel:', term_getline(buf, 20))}) 1116 call term_sendkeys(buf, "y") 1117 call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))}) 1118 1119 " close the terminal window where Vim was running 1120 quit 1121endfunc 1122 1123" Run Vim in a terminal, then start a terminal window with a shell and check 1124" that Vim exits if it is closed. 1125func Test_terminal_exit() 1126 CheckRunVimInTerminal 1127 1128 let lines =<< trim END 1129 let winid = win_getid() 1130 help 1131 term 1132 let termid = win_getid() 1133 call win_gotoid(winid) 1134 close 1135 call win_gotoid(termid) 1136 END 1137 call writefile(lines, 'XtermExit') 1138 let buf = RunVimInTerminal('-S XtermExit', #{rows: 10}) 1139 let job = term_getjob(buf) 1140 call WaitForAssert({-> assert_equal("run", job_status(job))}) 1141 1142 " quit the shell, it will make Vim exit 1143 call term_sendkeys(buf, "exit\<CR>") 1144 call WaitForAssert({-> assert_equal("dead", job_status(job))}) 1145 1146 call delete('XtermExit') 1147endfunc 1148 1149func Test_terminal_open_autocmd() 1150 augroup repro 1151 au! 1152 au TerminalOpen * let s:called += 1 1153 augroup END 1154 1155 let s:called = 0 1156 1157 " Open a terminal window with :terminal 1158 terminal 1159 call assert_equal(1, s:called) 1160 bwipe! 1161 1162 " Open a terminal window with term_start() 1163 call term_start(&shell) 1164 call assert_equal(2, s:called) 1165 bwipe! 1166 1167 " Open a hidden terminal buffer with :terminal 1168 terminal ++hidden 1169 call assert_equal(3, s:called) 1170 for buf in term_list() 1171 exe buf . "bwipe!" 1172 endfor 1173 1174 " Open a hidden terminal buffer with term_start() 1175 let buf = term_start(&shell, {'hidden': 1}) 1176 call assert_equal(4, s:called) 1177 exe buf . "bwipe!" 1178 1179 unlet s:called 1180 au! repro 1181endfunction 1182 1183func Check_dump01(off) 1184 call assert_equal('one two three four five', trim(getline(a:off + 1))) 1185 call assert_equal('~ Select Word', trim(getline(a:off + 7))) 1186 call assert_equal(':popup PopUp', trim(getline(a:off + 20))) 1187endfunc 1188 1189func Test_terminal_dumpwrite_composing() 1190 CheckRunVimInTerminal 1191 let save_enc = &encoding 1192 set encoding=utf-8 1193 call assert_equal(1, winnr('$')) 1194 1195 let text = " a\u0300 e\u0302 o\u0308" 1196 call writefile([text], 'Xcomposing') 1197 let buf = RunVimInTerminal('--cmd "set encoding=utf-8" Xcomposing', {}) 1198 call WaitForAssert({-> assert_match(text, term_getline(buf, 1))}) 1199 eval 'Xdump'->term_dumpwrite(buf) 1200 let dumpline = readfile('Xdump')[0] 1201 call assert_match('|à| |ê| |ö', dumpline) 1202 1203 call StopVimInTerminal(buf) 1204 call delete('Xcomposing') 1205 call delete('Xdump') 1206 let &encoding = save_enc 1207endfunc 1208 1209" just testing basic functionality. 1210func Test_terminal_dumpload() 1211 let curbuf = winbufnr('') 1212 call assert_equal(1, winnr('$')) 1213 let buf = term_dumpload('dumps/Test_popup_command_01.dump') 1214 call assert_equal(2, winnr('$')) 1215 call assert_equal(20, line('$')) 1216 call Check_dump01(0) 1217 1218 " Load another dump in the same window 1219 let buf2 = 'dumps/Test_diff_01.dump'->term_dumpload({'bufnr': buf}) 1220 call assert_equal(buf, buf2) 1221 call assert_notequal('one two three four five', trim(getline(1))) 1222 1223 " Load the first dump again in the same window 1224 let buf2 = term_dumpload('dumps/Test_popup_command_01.dump', {'bufnr': buf}) 1225 call assert_equal(buf, buf2) 1226 call Check_dump01(0) 1227 1228 call assert_fails("call term_dumpload('dumps/Test_popup_command_01.dump', {'bufnr': curbuf})", 'E475:') 1229 call assert_fails("call term_dumpload('dumps/Test_popup_command_01.dump', {'bufnr': 9999})", 'E86:') 1230 new 1231 let closedbuf = winbufnr('') 1232 quit 1233 call assert_fails("call term_dumpload('dumps/Test_popup_command_01.dump', {'bufnr': closedbuf})", 'E475:') 1234 1235 quit 1236endfunc 1237 1238func Test_terminal_dumpload_dump() 1239 CheckRunVimInTerminal 1240 1241 let lines =<< trim END 1242 call term_dumpload('dumps/Test_popupwin_22.dump', #{term_rows: 12}) 1243 END 1244 call writefile(lines, 'XtermDumpload') 1245 let buf = RunVimInTerminal('-S XtermDumpload', #{rows: 15}) 1246 call VerifyScreenDump(buf, 'Test_terminal_dumpload', {}) 1247 1248 call StopVimInTerminal(buf) 1249 call delete('XtermDumpload') 1250endfunc 1251 1252func Test_terminal_dumpdiff() 1253 call assert_equal(1, winnr('$')) 1254 eval 'dumps/Test_popup_command_01.dump'->term_dumpdiff('dumps/Test_popup_command_02.dump') 1255 call assert_equal(2, winnr('$')) 1256 call assert_equal(62, line('$')) 1257 call Check_dump01(0) 1258 call Check_dump01(42) 1259 call assert_equal(' bbbbbbbbbbbbbbbbbb ', getline(26)[0:29]) 1260 quit 1261endfunc 1262 1263func Test_terminal_dumpdiff_swap() 1264 call assert_equal(1, winnr('$')) 1265 call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_03.dump') 1266 call assert_equal(2, winnr('$')) 1267 call assert_equal(62, line('$')) 1268 call assert_match('Test_popup_command_01.dump', getline(21)) 1269 call assert_match('Test_popup_command_03.dump', getline(42)) 1270 call assert_match('Undo', getline(3)) 1271 call assert_match('three four five', getline(45)) 1272 1273 normal s 1274 call assert_match('Test_popup_command_03.dump', getline(21)) 1275 call assert_match('Test_popup_command_01.dump', getline(42)) 1276 call assert_match('three four five', getline(3)) 1277 call assert_match('Undo', getline(45)) 1278 quit 1279endfunc 1280 1281func Test_terminal_dumpdiff_options() 1282 set laststatus=0 1283 call assert_equal(1, winnr('$')) 1284 let height = winheight(0) 1285 call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump', {'vertical': 1, 'term_cols': 33}) 1286 call assert_equal(2, winnr('$')) 1287 call assert_equal(height, winheight(winnr())) 1288 call assert_equal(33, winwidth(winnr())) 1289 call assert_equal('dump diff dumps/Test_popup_command_01.dump', bufname('%')) 1290 quit 1291 1292 call assert_equal(1, winnr('$')) 1293 call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump', {'vertical': 0, 'term_rows': 13, 'term_name': 'something else'}) 1294 call assert_equal(2, winnr('$')) 1295 call assert_equal(&columns, winwidth(0)) 1296 call assert_equal(13, winheight(0)) 1297 call assert_equal('something else', bufname('%')) 1298 quit 1299 1300 call assert_equal(1, winnr('$')) 1301 call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump', {'curwin': 1}) 1302 call assert_equal(1, winnr('$')) 1303 call assert_fails("call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump', {'bufnr': -1})", 'E475:') 1304 bwipe 1305 1306 set laststatus& 1307endfunc 1308 1309func Api_drop_common(options) 1310 call assert_equal(1, winnr('$')) 1311 1312 " Use the title termcap entries to output the escape sequence. 1313 call writefile([ 1314 \ 'set title', 1315 \ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"', 1316 \ 'let &titlestring = ''["drop","Xtextfile"' . a:options . ']''', 1317 \ 'redraw', 1318 \ "set t_ts=", 1319 \ ], 'Xscript') 1320 let buf = RunVimInTerminal('-S Xscript', {}) 1321 call WaitFor({-> bufnr('Xtextfile') > 0}) 1322 call assert_equal('Xtextfile', expand('%:t')) 1323 call assert_true(winnr('$') >= 3) 1324 return buf 1325endfunc 1326 1327func Test_terminal_api_drop_newwin() 1328 CheckRunVimInTerminal 1329 let buf = Api_drop_common('') 1330 call assert_equal(0, &bin) 1331 call assert_equal('', &fenc) 1332 1333 call StopVimInTerminal(buf) 1334 call delete('Xscript') 1335 bwipe Xtextfile 1336endfunc 1337 1338func Test_terminal_api_drop_newwin_bin() 1339 CheckRunVimInTerminal 1340 let buf = Api_drop_common(',{"bin":1}') 1341 call assert_equal(1, &bin) 1342 1343 call StopVimInTerminal(buf) 1344 call delete('Xscript') 1345 bwipe Xtextfile 1346endfunc 1347 1348func Test_terminal_api_drop_newwin_binary() 1349 CheckRunVimInTerminal 1350 let buf = Api_drop_common(',{"binary":1}') 1351 call assert_equal(1, &bin) 1352 1353 call StopVimInTerminal(buf) 1354 call delete('Xscript') 1355 bwipe Xtextfile 1356endfunc 1357 1358func Test_terminal_api_drop_newwin_nobin() 1359 CheckRunVimInTerminal 1360 set binary 1361 let buf = Api_drop_common(',{"nobin":1}') 1362 call assert_equal(0, &bin) 1363 1364 call StopVimInTerminal(buf) 1365 call delete('Xscript') 1366 bwipe Xtextfile 1367 set nobinary 1368endfunc 1369 1370func Test_terminal_api_drop_newwin_nobinary() 1371 CheckRunVimInTerminal 1372 set binary 1373 let buf = Api_drop_common(',{"nobinary":1}') 1374 call assert_equal(0, &bin) 1375 1376 call StopVimInTerminal(buf) 1377 call delete('Xscript') 1378 bwipe Xtextfile 1379 set nobinary 1380endfunc 1381 1382func Test_terminal_api_drop_newwin_ff() 1383 CheckRunVimInTerminal 1384 let buf = Api_drop_common(',{"ff":"dos"}') 1385 call assert_equal("dos", &ff) 1386 1387 call StopVimInTerminal(buf) 1388 call delete('Xscript') 1389 bwipe Xtextfile 1390endfunc 1391 1392func Test_terminal_api_drop_newwin_fileformat() 1393 CheckRunVimInTerminal 1394 let buf = Api_drop_common(',{"fileformat":"dos"}') 1395 call assert_equal("dos", &ff) 1396 1397 call StopVimInTerminal(buf) 1398 call delete('Xscript') 1399 bwipe Xtextfile 1400endfunc 1401 1402func Test_terminal_api_drop_newwin_enc() 1403 CheckRunVimInTerminal 1404 let buf = Api_drop_common(',{"enc":"utf-16"}') 1405 call assert_equal("utf-16", &fenc) 1406 1407 call StopVimInTerminal(buf) 1408 call delete('Xscript') 1409 bwipe Xtextfile 1410endfunc 1411 1412func Test_terminal_api_drop_newwin_encoding() 1413 CheckRunVimInTerminal 1414 let buf = Api_drop_common(',{"encoding":"utf-16"}') 1415 call assert_equal("utf-16", &fenc) 1416 1417 call StopVimInTerminal(buf) 1418 call delete('Xscript') 1419 bwipe Xtextfile 1420endfunc 1421 1422func Test_terminal_api_drop_oldwin() 1423 CheckRunVimInTerminal 1424 let firstwinid = win_getid() 1425 split Xtextfile 1426 let textfile_winid = win_getid() 1427 call assert_equal(2, winnr('$')) 1428 call win_gotoid(firstwinid) 1429 1430 " Use the title termcap entries to output the escape sequence. 1431 call writefile([ 1432 \ 'set title', 1433 \ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"', 1434 \ 'let &titlestring = ''["drop","Xtextfile"]''', 1435 \ 'redraw', 1436 \ "set t_ts=", 1437 \ ], 'Xscript') 1438 let buf = RunVimInTerminal('-S Xscript', {'rows': 10}) 1439 call WaitForAssert({-> assert_equal('Xtextfile', expand('%:t'))}) 1440 call assert_equal(textfile_winid, win_getid()) 1441 1442 call StopVimInTerminal(buf) 1443 call delete('Xscript') 1444 bwipe Xtextfile 1445endfunc 1446 1447func Tapi_TryThis(bufnum, arg) 1448 let g:called_bufnum = a:bufnum 1449 let g:called_arg = a:arg 1450endfunc 1451 1452func WriteApiCall(funcname) 1453 " Use the title termcap entries to output the escape sequence. 1454 call writefile([ 1455 \ 'set title', 1456 \ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"', 1457 \ 'let &titlestring = ''["call","' . a:funcname . '",["hello",123]]''', 1458 \ 'redraw', 1459 \ "set t_ts=", 1460 \ ], 'Xscript') 1461endfunc 1462 1463func Test_terminal_api_call() 1464 CheckRunVimInTerminal 1465 1466 unlet! g:called_bufnum 1467 unlet! g:called_arg 1468 1469 call WriteApiCall('Tapi_TryThis') 1470 1471 " Default 1472 let buf = RunVimInTerminal('-S Xscript', {}) 1473 call WaitFor({-> exists('g:called_bufnum')}) 1474 call assert_equal(buf, g:called_bufnum) 1475 call assert_equal(['hello', 123], g:called_arg) 1476 call StopVimInTerminal(buf) 1477 1478 unlet! g:called_bufnum 1479 unlet! g:called_arg 1480 1481 " Enable explicitly 1482 let buf = RunVimInTerminal('-S Xscript', {'term_api': 'Tapi_Try'}) 1483 call WaitFor({-> exists('g:called_bufnum')}) 1484 call assert_equal(buf, g:called_bufnum) 1485 call assert_equal(['hello', 123], g:called_arg) 1486 call StopVimInTerminal(buf) 1487 1488 unlet! g:called_bufnum 1489 unlet! g:called_arg 1490 1491 func! ApiCall_TryThis(bufnum, arg) 1492 let g:called_bufnum2 = a:bufnum 1493 let g:called_arg2 = a:arg 1494 endfunc 1495 1496 call WriteApiCall('ApiCall_TryThis') 1497 1498 " Use prefix match 1499 let buf = RunVimInTerminal('-S Xscript', {'term_api': 'ApiCall_'}) 1500 call WaitFor({-> exists('g:called_bufnum2')}) 1501 call assert_equal(buf, g:called_bufnum2) 1502 call assert_equal(['hello', 123], g:called_arg2) 1503 call StopVimInTerminal(buf) 1504 1505 call assert_fails("call term_start('ls', {'term_api' : []})", 'E475:') 1506 1507 unlet! g:called_bufnum2 1508 unlet! g:called_arg2 1509 1510 call delete('Xscript') 1511 delfunction! ApiCall_TryThis 1512 unlet! g:called_bufnum2 1513 unlet! g:called_arg2 1514endfunc 1515 1516func Test_terminal_api_call_fails() 1517 CheckRunVimInTerminal 1518 1519 func! TryThis(bufnum, arg) 1520 let g:called_bufnum3 = a:bufnum 1521 let g:called_arg3 = a:arg 1522 endfunc 1523 1524 call WriteApiCall('TryThis') 1525 1526 unlet! g:called_bufnum3 1527 unlet! g:called_arg3 1528 1529 " Not permitted 1530 call ch_logfile('Xlog', 'w') 1531 let buf = RunVimInTerminal('-S Xscript', {'term_api': ''}) 1532 call WaitForAssert({-> assert_match('Unpermitted function: TryThis', string(readfile('Xlog')))}) 1533 call assert_false(exists('g:called_bufnum3')) 1534 call assert_false(exists('g:called_arg3')) 1535 call StopVimInTerminal(buf) 1536 1537 " No match 1538 call ch_logfile('Xlog', 'w') 1539 let buf = RunVimInTerminal('-S Xscript', {'term_api': 'TryThat'}) 1540 call WaitFor({-> string(readfile('Xlog')) =~ 'Unpermitted function: TryThis'}) 1541 call assert_false(exists('g:called_bufnum3')) 1542 call assert_false(exists('g:called_arg3')) 1543 call StopVimInTerminal(buf) 1544 1545 call delete('Xscript') 1546 call ch_logfile('') 1547 call delete('Xlog') 1548 delfunction! TryThis 1549 unlet! g:called_bufnum3 1550 unlet! g:called_arg3 1551endfunc 1552 1553let s:caught_e937 = 0 1554 1555func Tapi_Delete(bufnum, arg) 1556 try 1557 execute 'bdelete!' a:bufnum 1558 catch /E937:/ 1559 let s:caught_e937 = 1 1560 endtry 1561endfunc 1562 1563func Test_terminal_api_call_fail_delete() 1564 CheckRunVimInTerminal 1565 1566 call WriteApiCall('Tapi_Delete') 1567 let buf = RunVimInTerminal('-S Xscript', {}) 1568 call WaitForAssert({-> assert_equal(1, s:caught_e937)}) 1569 1570 call StopVimInTerminal(buf) 1571 call delete('Xscript') 1572 call ch_logfile('', '') 1573endfunc 1574 1575func Test_terminal_ansicolors_default() 1576 CheckFunction term_getansicolors 1577 1578 let colors = [ 1579 \ '#000000', '#e00000', 1580 \ '#00e000', '#e0e000', 1581 \ '#0000e0', '#e000e0', 1582 \ '#00e0e0', '#e0e0e0', 1583 \ '#808080', '#ff4040', 1584 \ '#40ff40', '#ffff40', 1585 \ '#4040ff', '#ff40ff', 1586 \ '#40ffff', '#ffffff', 1587 \] 1588 1589 let buf = Run_shell_in_terminal({}) 1590 call assert_equal(colors, term_getansicolors(buf)) 1591 call StopShellInTerminal(buf) 1592 call TermWait(buf) 1593 1594 exe buf . 'bwipe' 1595endfunc 1596 1597let s:test_colors = [ 1598 \ '#616e64', '#0d0a79', 1599 \ '#6d610d', '#0a7373', 1600 \ '#690d0a', '#6d696e', 1601 \ '#0d0a6f', '#616e0d', 1602 \ '#0a6479', '#6d0d0a', 1603 \ '#617373', '#0d0a69', 1604 \ '#6d690d', '#0a6e6f', 1605 \ '#610d0a', '#6e6479', 1606 \] 1607 1608func Test_terminal_ansicolors_global() 1609 CheckFeature termguicolors 1610 CheckFunction term_getansicolors 1611 1612 let g:terminal_ansi_colors = reverse(copy(s:test_colors)) 1613 let buf = Run_shell_in_terminal({}) 1614 call assert_equal(g:terminal_ansi_colors, term_getansicolors(buf)) 1615 call StopShellInTerminal(buf) 1616 call TermWait(buf) 1617 1618 exe buf . 'bwipe' 1619 unlet g:terminal_ansi_colors 1620endfunc 1621 1622func Test_terminal_ansicolors_func() 1623 CheckFeature termguicolors 1624 CheckFunction term_getansicolors 1625 1626 let g:terminal_ansi_colors = reverse(copy(s:test_colors)) 1627 let buf = Run_shell_in_terminal({'ansi_colors': s:test_colors}) 1628 call assert_equal(s:test_colors, term_getansicolors(buf)) 1629 1630 call term_setansicolors(buf, g:terminal_ansi_colors) 1631 call assert_equal(g:terminal_ansi_colors, buf->term_getansicolors()) 1632 1633 let colors = [ 1634 \ 'ivory', 'AliceBlue', 1635 \ 'grey67', 'dark goldenrod', 1636 \ 'SteelBlue3', 'PaleVioletRed4', 1637 \ 'MediumPurple2', 'yellow2', 1638 \ 'RosyBrown3', 'OrangeRed2', 1639 \ 'white smoke', 'navy blue', 1640 \ 'grey47', 'gray97', 1641 \ 'MistyRose2', 'DodgerBlue4', 1642 \] 1643 eval buf->term_setansicolors(colors) 1644 1645 let colors[4] = 'Invalid' 1646 call assert_fails('call term_setansicolors(buf, colors)', 'E474:') 1647 1648 call StopShellInTerminal(buf) 1649 call TermWait(buf) 1650 exe buf . 'bwipe' 1651endfunc 1652 1653func Test_terminal_all_ansi_colors() 1654 CheckRunVimInTerminal 1655 1656 " Use all the ANSI colors. 1657 call writefile([ 1658 \ 'call setline(1, "AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPP XXYYZZ")', 1659 \ 'hi Tblack ctermfg=0 ctermbg=8', 1660 \ 'hi Tdarkred ctermfg=1 ctermbg=9', 1661 \ 'hi Tdarkgreen ctermfg=2 ctermbg=10', 1662 \ 'hi Tbrown ctermfg=3 ctermbg=11', 1663 \ 'hi Tdarkblue ctermfg=4 ctermbg=12', 1664 \ 'hi Tdarkmagenta ctermfg=5 ctermbg=13', 1665 \ 'hi Tdarkcyan ctermfg=6 ctermbg=14', 1666 \ 'hi Tlightgrey ctermfg=7 ctermbg=15', 1667 \ 'hi Tdarkgrey ctermfg=8 ctermbg=0', 1668 \ 'hi Tred ctermfg=9 ctermbg=1', 1669 \ 'hi Tgreen ctermfg=10 ctermbg=2', 1670 \ 'hi Tyellow ctermfg=11 ctermbg=3', 1671 \ 'hi Tblue ctermfg=12 ctermbg=4', 1672 \ 'hi Tmagenta ctermfg=13 ctermbg=5', 1673 \ 'hi Tcyan ctermfg=14 ctermbg=6', 1674 \ 'hi Twhite ctermfg=15 ctermbg=7', 1675 \ 'hi TdarkredBold ctermfg=1 cterm=bold', 1676 \ 'hi TgreenBold ctermfg=10 cterm=bold', 1677 \ 'hi TmagentaBold ctermfg=13 cterm=bold ctermbg=5', 1678 \ '', 1679 \ 'call matchadd("Tblack", "A")', 1680 \ 'call matchadd("Tdarkred", "B")', 1681 \ 'call matchadd("Tdarkgreen", "C")', 1682 \ 'call matchadd("Tbrown", "D")', 1683 \ 'call matchadd("Tdarkblue", "E")', 1684 \ 'call matchadd("Tdarkmagenta", "F")', 1685 \ 'call matchadd("Tdarkcyan", "G")', 1686 \ 'call matchadd("Tlightgrey", "H")', 1687 \ 'call matchadd("Tdarkgrey", "I")', 1688 \ 'call matchadd("Tred", "J")', 1689 \ 'call matchadd("Tgreen", "K")', 1690 \ 'call matchadd("Tyellow", "L")', 1691 \ 'call matchadd("Tblue", "M")', 1692 \ 'call matchadd("Tmagenta", "N")', 1693 \ 'call matchadd("Tcyan", "O")', 1694 \ 'call matchadd("Twhite", "P")', 1695 \ 'call matchadd("TdarkredBold", "X")', 1696 \ 'call matchadd("TgreenBold", "Y")', 1697 \ 'call matchadd("TmagentaBold", "Z")', 1698 \ 'redraw', 1699 \ ], 'Xcolorscript') 1700 let buf = RunVimInTerminal('-S Xcolorscript', {'rows': 10}) 1701 call VerifyScreenDump(buf, 'Test_terminal_all_ansi_colors', {}) 1702 1703 call term_sendkeys(buf, ":q\<CR>") 1704 call StopVimInTerminal(buf) 1705 call delete('Xcolorscript') 1706endfunc 1707 1708func Test_terminal_termwinsize_option_fixed() 1709 CheckRunVimInTerminal 1710 set termwinsize=6x40 1711 let text = [] 1712 for n in range(10) 1713 call add(text, repeat(n, 50)) 1714 endfor 1715 call writefile(text, 'Xwinsize') 1716 let buf = RunVimInTerminal('Xwinsize', {}) 1717 let win = bufwinid(buf) 1718 call assert_equal([6, 40], term_getsize(buf)) 1719 call assert_equal(6, winheight(win)) 1720 call assert_equal(40, winwidth(win)) 1721 1722 " resizing the window doesn't resize the terminal. 1723 resize 10 1724 vertical resize 60 1725 call assert_equal([6, 40], term_getsize(buf)) 1726 call assert_equal(10, winheight(win)) 1727 call assert_equal(60, winwidth(win)) 1728 1729 call StopVimInTerminal(buf) 1730 call delete('Xwinsize') 1731 1732 call assert_fails('set termwinsize=40', 'E474') 1733 call assert_fails('set termwinsize=10+40', 'E474') 1734 call assert_fails('set termwinsize=abc', 'E474') 1735 1736 set termwinsize= 1737endfunc 1738 1739func Test_terminal_termwinsize_option_zero() 1740 set termwinsize=0x0 1741 let buf = Run_shell_in_terminal({}) 1742 let win = bufwinid(buf) 1743 call assert_equal([winheight(win), winwidth(win)], term_getsize(buf)) 1744 call StopShellInTerminal(buf) 1745 call TermWait(buf) 1746 exe buf . 'bwipe' 1747 1748 set termwinsize=7x0 1749 let buf = Run_shell_in_terminal({}) 1750 let win = bufwinid(buf) 1751 call assert_equal([7, winwidth(win)], term_getsize(buf)) 1752 call StopShellInTerminal(buf) 1753 call TermWait(buf) 1754 exe buf . 'bwipe' 1755 1756 set termwinsize=0x33 1757 let buf = Run_shell_in_terminal({}) 1758 let win = bufwinid(buf) 1759 call assert_equal([winheight(win), 33], term_getsize(buf)) 1760 call StopShellInTerminal(buf) 1761 call TermWait(buf) 1762 exe buf . 'bwipe' 1763 1764 set termwinsize= 1765endfunc 1766 1767func Test_terminal_termwinsize_minimum() 1768 set termwinsize=10*50 1769 vsplit 1770 let buf = Run_shell_in_terminal({}) 1771 let win = bufwinid(buf) 1772 call assert_inrange(10, 1000, winheight(win)) 1773 call assert_inrange(50, 1000, winwidth(win)) 1774 call assert_equal([winheight(win), winwidth(win)], term_getsize(buf)) 1775 1776 resize 15 1777 vertical resize 60 1778 redraw 1779 call assert_equal([15, 60], term_getsize(buf)) 1780 call assert_equal(15, winheight(win)) 1781 call assert_equal(60, winwidth(win)) 1782 1783 resize 7 1784 vertical resize 30 1785 redraw 1786 call assert_equal([10, 50], term_getsize(buf)) 1787 call assert_equal(7, winheight(win)) 1788 call assert_equal(30, winwidth(win)) 1789 1790 call StopShellInTerminal(buf) 1791 call TermWait(buf) 1792 exe buf . 'bwipe' 1793 1794 set termwinsize=0*0 1795 let buf = Run_shell_in_terminal({}) 1796 let win = bufwinid(buf) 1797 call assert_equal([winheight(win), winwidth(win)], term_getsize(buf)) 1798 call StopShellInTerminal(buf) 1799 call TermWait(buf) 1800 exe buf . 'bwipe' 1801 1802 set termwinsize= 1803endfunc 1804 1805func Test_terminal_termwinkey() 1806 " make three tabpages, terminal in the middle 1807 0tabnew 1808 tabnext 1809 tabnew 1810 tabprev 1811 call assert_equal(1, winnr('$')) 1812 call assert_equal(2, tabpagenr()) 1813 let thiswin = win_getid() 1814 1815 let buf = Run_shell_in_terminal({}) 1816 let termwin = bufwinid(buf) 1817 set termwinkey=<C-L> 1818 call feedkeys("\<C-L>w", 'tx') 1819 call assert_equal(thiswin, win_getid()) 1820 call feedkeys("\<C-W>w", 'tx') 1821 call assert_equal(termwin, win_getid()) 1822 1823 if has('langmap') 1824 set langmap=xjyk 1825 call feedkeys("\<C-L>x", 'tx') 1826 call assert_equal(thiswin, win_getid()) 1827 call feedkeys("\<C-W>y", 'tx') 1828 call assert_equal(termwin, win_getid()) 1829 set langmap= 1830 endif 1831 1832 call feedkeys("\<C-L>gt", "xt") 1833 call assert_equal(3, tabpagenr()) 1834 tabprev 1835 call assert_equal(2, tabpagenr()) 1836 call assert_equal(termwin, win_getid()) 1837 1838 call feedkeys("\<C-L>gT", "xt") 1839 call assert_equal(1, tabpagenr()) 1840 tabnext 1841 call assert_equal(2, tabpagenr()) 1842 call assert_equal(termwin, win_getid()) 1843 1844 let job = term_getjob(buf) 1845 call feedkeys("\<C-L>\<C-C>", 'tx') 1846 call WaitForAssert({-> assert_equal("dead", job_status(job))}) 1847 1848 set termwinkey& 1849 tabnext 1850 tabclose 1851 tabprev 1852 tabclose 1853endfunc 1854 1855func Test_terminal_out_err() 1856 CheckUnix 1857 1858 call writefile([ 1859 \ '#!/bin/sh', 1860 \ 'echo "this is standard error" >&2', 1861 \ 'echo "this is standard out" >&1', 1862 \ ], 'Xechoerrout.sh') 1863 call setfperm('Xechoerrout.sh', 'rwxrwx---') 1864 1865 let outfile = 'Xtermstdout' 1866 let buf = term_start(['./Xechoerrout.sh'], {'out_io': 'file', 'out_name': outfile}) 1867 1868 call WaitFor({-> !empty(readfile(outfile)) && !empty(term_getline(buf, 1))}) 1869 call assert_equal(['this is standard out'], readfile(outfile)) 1870 call assert_equal('this is standard error', term_getline(buf, 1)) 1871 1872 call WaitForAssert({-> assert_equal('dead', job_status(term_getjob(buf)))}) 1873 exe buf . 'bwipe' 1874 call delete('Xechoerrout.sh') 1875 call delete(outfile) 1876endfunc 1877 1878func Test_termwinscroll() 1879 CheckUnix 1880 1881 " Let the terminal output more than 'termwinscroll' lines, some at the start 1882 " will be dropped. 1883 exe 'set termwinscroll=' . &lines 1884 let buf = term_start('/bin/sh') 1885 for i in range(1, &lines) 1886 call feedkeys("echo " . i . "\<CR>", 'xt') 1887 call WaitForAssert({-> assert_match(string(i), term_getline(buf, term_getcursor(buf)[0] - 1))}) 1888 endfor 1889 " Go to Terminal-Normal mode to update the buffer. 1890 call feedkeys("\<C-W>N", 'xt') 1891 call assert_inrange(&lines, &lines * 110 / 100 + winheight(0), line('$')) 1892 1893 " Every "echo nr" must only appear once 1894 let lines = getline(1, line('$')) 1895 for i in range(&lines - len(lines) / 2 + 2, &lines) 1896 let filtered = filter(copy(lines), {idx, val -> val =~ 'echo ' . i . '\>'}) 1897 call assert_equal(1, len(filtered), 'for "echo ' . i . '"') 1898 endfor 1899 1900 exe buf . 'bwipe!' 1901endfunc 1902 1903" Resizing the terminal window caused an ml_get error. 1904" TODO: This does not reproduce the original problem. 1905func Test_terminal_resize() 1906 set statusline=x 1907 terminal 1908 call assert_equal(2, winnr('$')) 1909 1910 " Fill the terminal with text. 1911 if has('win32') 1912 call feedkeys("dir\<CR>", 'xt') 1913 else 1914 call feedkeys("ls\<CR>", 'xt') 1915 endif 1916 " Go to Terminal-Normal mode for a moment. 1917 call feedkeys("\<C-W>N", 'xt') 1918 " Open a new window 1919 call feedkeys("i\<C-W>n", 'xt') 1920 call assert_equal(3, winnr('$')) 1921 redraw 1922 1923 close 1924 call assert_equal(2, winnr('$')) 1925 call feedkeys("exit\<CR>", 'xt') 1926 set statusline& 1927endfunc 1928 1929" must be nearly the last, we can't go back from GUI to terminal 1930func Test_zz1_terminal_in_gui() 1931 CheckCanRunGui 1932 1933 " Ignore the "failed to create input context" error. 1934 call test_ignore_error('E285:') 1935 1936 gui -f 1937 1938 call assert_equal(1, winnr('$')) 1939 let buf = Run_shell_in_terminal({'term_finish': 'close'}) 1940 call StopShellInTerminal(buf) 1941 call TermWait(buf) 1942 1943 " closing window wipes out the terminal buffer a with finished job 1944 call WaitForAssert({-> assert_equal(1, winnr('$'))}) 1945 call assert_equal("", bufname(buf)) 1946 1947 unlet g:job 1948endfunc 1949 1950func Test_zz2_terminal_guioptions_bang() 1951 CheckGui 1952 set guioptions+=! 1953 1954 let filename = 'Xtestscript' 1955 if has('win32') 1956 let filename .= '.bat' 1957 let prefix = '' 1958 let contents = ['@echo off', 'exit %1'] 1959 else 1960 let filename .= '.sh' 1961 let prefix = './' 1962 let contents = ['#!/bin/sh', 'exit $1'] 1963 endif 1964 call writefile(contents, filename) 1965 call setfperm(filename, 'rwxrwx---') 1966 1967 " Check if v:shell_error is equal to the exit status. 1968 let exitval = 0 1969 execute printf(':!%s%s %d', prefix, filename, exitval) 1970 call assert_equal(exitval, v:shell_error) 1971 1972 let exitval = 9 1973 execute printf(':!%s%s %d', prefix, filename, exitval) 1974 call assert_equal(exitval, v:shell_error) 1975 1976 set guioptions& 1977 call delete(filename) 1978endfunc 1979 1980func Test_terminal_hidden() 1981 CheckUnix 1982 1983 term ++hidden cat 1984 let bnr = bufnr('$') 1985 call assert_equal('terminal', getbufvar(bnr, '&buftype')) 1986 exe 'sbuf ' . bnr 1987 call assert_equal('terminal', &buftype) 1988 call term_sendkeys(bnr, "asdf\<CR>") 1989 call WaitForAssert({-> assert_match('asdf', term_getline(bnr, 2))}) 1990 call term_sendkeys(bnr, "\<C-D>") 1991 call WaitForAssert({-> assert_equal('finished', bnr->term_getstatus())}) 1992 bwipe! 1993endfunc 1994 1995func Test_terminal_switch_mode() 1996 term 1997 let bnr = bufnr('$') 1998 call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))}) 1999 call feedkeys("\<C-W>N", 'xt') 2000 call WaitForAssert({-> assert_equal('running,normal', term_getstatus(bnr))}) 2001 call feedkeys("A", 'xt') 2002 call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))}) 2003 call feedkeys("\<C-W>N", 'xt') 2004 call WaitForAssert({-> assert_equal('running,normal', term_getstatus(bnr))}) 2005 call feedkeys("I", 'xt') 2006 call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))}) 2007 call feedkeys("\<C-W>Nv", 'xt') 2008 call WaitForAssert({-> assert_equal('running,normal', term_getstatus(bnr))}) 2009 call feedkeys("I", 'xt') 2010 call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))}) 2011 call feedkeys("\<C-W>Nv", 'xt') 2012 call WaitForAssert({-> assert_equal('running,normal', term_getstatus(bnr))}) 2013 call feedkeys("A", 'xt') 2014 call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))}) 2015 bwipe! 2016endfunc 2017 2018func Test_terminal_normal_mode() 2019 CheckRunVimInTerminal 2020 2021 " Run Vim in a terminal and open a terminal window to run Vim in. 2022 let lines =<< trim END 2023 call setline(1, range(11111, 11122)) 2024 3 2025 END 2026 call writefile(lines, 'XtermNormal') 2027 let buf = RunVimInTerminal('-S XtermNormal', {'rows': 8}) 2028 call TermWait(buf) 2029 2030 call term_sendkeys(buf, "\<C-W>N") 2031 call term_sendkeys(buf, ":set number cursorline culopt=both\r") 2032 call VerifyScreenDump(buf, 'Test_terminal_normal_1', {}) 2033 2034 call term_sendkeys(buf, ":set culopt=number\r") 2035 call VerifyScreenDump(buf, 'Test_terminal_normal_2', {}) 2036 2037 call term_sendkeys(buf, ":set culopt=line\r") 2038 call VerifyScreenDump(buf, 'Test_terminal_normal_3', {}) 2039 2040 call term_sendkeys(buf, "a:q!\<CR>:q\<CR>:q\<CR>") 2041 call StopVimInTerminal(buf) 2042 call delete('XtermNormal') 2043endfunc 2044 2045func Test_terminal_hidden_and_close() 2046 CheckUnix 2047 2048 call assert_equal(1, winnr('$')) 2049 term ++hidden ++close ls 2050 let bnr = bufnr('$') 2051 call assert_equal('terminal', getbufvar(bnr, '&buftype')) 2052 call WaitForAssert({-> assert_false(bufexists(bnr))}) 2053 call assert_equal(1, winnr('$')) 2054endfunc 2055 2056func Test_terminal_does_not_truncate_last_newlines() 2057 " This test does not pass through ConPTY. 2058 if has('conpty') 2059 return 2060 endif 2061 let contents = [ 2062 \ [ 'One', '', 'X' ], 2063 \ [ 'Two', '', '' ], 2064 \ [ 'Three' ] + repeat([''], 30) 2065 \ ] 2066 2067 for c in contents 2068 call writefile(c, 'Xfile') 2069 if has('win32') 2070 term cmd /c type Xfile 2071 else 2072 term cat Xfile 2073 endif 2074 let bnr = bufnr('$') 2075 call assert_equal('terminal', getbufvar(bnr, '&buftype')) 2076 call WaitForAssert({-> assert_equal('finished', term_getstatus(bnr))}) 2077 sleep 100m 2078 call assert_equal(c, getline(1, line('$'))) 2079 quit 2080 endfor 2081 2082 call delete('Xfile') 2083endfunc 2084 2085func Test_terminal_no_job() 2086 if has('win32') 2087 let cmd = 'cmd /c ""' 2088 else 2089 CheckExecutable false 2090 let cmd = 'false' 2091 endif 2092 let term = term_start(cmd, {'term_finish': 'close'}) 2093 call WaitForAssert({-> assert_equal(v:null, term_getjob(term)) }) 2094endfunc 2095 2096func Test_term_getcursor() 2097 CheckUnix 2098 2099 let buf = Run_shell_in_terminal({}) 2100 2101 " Wait for the shell to display a prompt. 2102 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))}) 2103 2104 " Hide the cursor. 2105 call term_sendkeys(buf, "echo -e '\\033[?25l'\r") 2106 call WaitForAssert({-> assert_equal(0, term_getcursor(buf)[2].visible)}) 2107 2108 " Show the cursor. 2109 call term_sendkeys(buf, "echo -e '\\033[?25h'\r") 2110 call WaitForAssert({-> assert_equal(1, buf->term_getcursor()[2].visible)}) 2111 2112 " Change color of cursor. 2113 call WaitForAssert({-> assert_equal('', term_getcursor(buf)[2].color)}) 2114 call term_sendkeys(buf, "echo -e '\\033]12;blue\\007'\r") 2115 call WaitForAssert({-> assert_equal('blue', term_getcursor(buf)[2].color)}) 2116 call term_sendkeys(buf, "echo -e '\\033]12;green\\007'\r") 2117 call WaitForAssert({-> assert_equal('green', term_getcursor(buf)[2].color)}) 2118 2119 " Make cursor a blinking block. 2120 call term_sendkeys(buf, "echo -e '\\033[1 q'\r") 2121 call WaitForAssert({-> assert_equal([1, 1], 2122 \ [term_getcursor(buf)[2].blink, term_getcursor(buf)[2].shape])}) 2123 2124 " Make cursor a steady block. 2125 call term_sendkeys(buf, "echo -e '\\033[2 q'\r") 2126 call WaitForAssert({-> assert_equal([0, 1], 2127 \ [term_getcursor(buf)[2].blink, term_getcursor(buf)[2].shape])}) 2128 2129 " Make cursor a blinking underline. 2130 call term_sendkeys(buf, "echo -e '\\033[3 q'\r") 2131 call WaitForAssert({-> assert_equal([1, 2], 2132 \ [term_getcursor(buf)[2].blink, term_getcursor(buf)[2].shape])}) 2133 2134 " Make cursor a steady underline. 2135 call term_sendkeys(buf, "echo -e '\\033[4 q'\r") 2136 call WaitForAssert({-> assert_equal([0, 2], 2137 \ [term_getcursor(buf)[2].blink, term_getcursor(buf)[2].shape])}) 2138 2139 " Make cursor a blinking vertical bar. 2140 call term_sendkeys(buf, "echo -e '\\033[5 q'\r") 2141 call WaitForAssert({-> assert_equal([1, 3], 2142 \ [term_getcursor(buf)[2].blink, term_getcursor(buf)[2].shape])}) 2143 2144 " Make cursor a steady vertical bar. 2145 call term_sendkeys(buf, "echo -e '\\033[6 q'\r") 2146 call WaitForAssert({-> assert_equal([0, 3], 2147 \ [term_getcursor(buf)[2].blink, term_getcursor(buf)[2].shape])}) 2148 2149 call StopShellInTerminal(buf) 2150endfunc 2151 2152func Test_term_gettitle() 2153 " term_gettitle() returns an empty string for a non-terminal buffer 2154 " and for a non-existing buffer. 2155 call assert_equal('', bufnr('%')->term_gettitle()) 2156 call assert_equal('', term_gettitle(bufnr('$') + 1)) 2157 2158 if !has('title') || &title == 0 || empty(&t_ts) 2159 throw "Skipped: can't get/set title" 2160 endif 2161 2162 let term = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile']) 2163 if has('autoservername') 2164 call WaitForAssert({-> assert_match('^\[No Name\] - VIM\d\+$', term_gettitle(term)) }) 2165 call term_sendkeys(term, ":e Xfoo\r") 2166 call WaitForAssert({-> assert_match('^Xfoo (.*[/\\]testdir) - VIM\d\+$', term_gettitle(term)) }) 2167 else 2168 call WaitForAssert({-> assert_equal('[No Name] - VIM', term_gettitle(term)) }) 2169 call term_sendkeys(term, ":e Xfoo\r") 2170 call WaitForAssert({-> assert_match('^Xfoo (.*[/\\]testdir) - VIM$', term_gettitle(term)) }) 2171 endif 2172 2173 call term_sendkeys(term, ":set titlestring=foo\r") 2174 call WaitForAssert({-> assert_equal('foo', term_gettitle(term)) }) 2175 2176 exe term . 'bwipe!' 2177endfunc 2178 2179func Test_term_gettty() 2180 let buf = Run_shell_in_terminal({}) 2181 let gettty = term_gettty(buf) 2182 2183 if has('unix') && executable('tty') 2184 " Find tty using the tty shell command. 2185 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))}) 2186 call term_sendkeys(buf, "tty\r") 2187 call WaitForAssert({-> assert_notequal('', term_getline(buf, 3))}) 2188 let tty = term_getline(buf, 2) 2189 call assert_equal(tty, gettty) 2190 endif 2191 2192 let gettty0 = term_gettty(buf, 0) 2193 let gettty1 = term_gettty(buf, 1) 2194 2195 call assert_equal(gettty, gettty0) 2196 call assert_equal(job_info(g:job).tty_out, gettty0) 2197 call assert_equal(job_info(g:job).tty_in, gettty1) 2198 2199 if has('unix') 2200 " For unix, term_gettty(..., 0) and term_gettty(..., 1) 2201 " are identical according to :help term_gettty() 2202 call assert_equal(gettty0, gettty1) 2203 call assert_match('^/dev/', gettty) 2204 else 2205 " ConPTY works on anonymous pipe. 2206 if !has('conpty') 2207 call assert_match('^\\\\.\\pipe\\', gettty0) 2208 call assert_match('^\\\\.\\pipe\\', gettty1) 2209 endif 2210 endif 2211 2212 call assert_fails('call term_gettty(buf, 2)', 'E475:') 2213 call assert_fails('call term_gettty(buf, -1)', 'E475:') 2214 2215 call assert_equal('', term_gettty(buf + 1)) 2216 2217 call StopShellInTerminal(buf) 2218 call TermWait(buf) 2219 exe buf . 'bwipe' 2220endfunc 2221 2222" When drawing the statusline the cursor position may not have been updated 2223" yet. 2224" 1. create a terminal, make it show 2 lines 2225" 2. 0.5 sec later: leave terminal window, execute "i" 2226" 3. 0.5 sec later: clear terminal window, now it's 1 line 2227" 4. 0.5 sec later: redraw, including statusline (used to trigger bug) 2228" 4. 0.5 sec later: should be done, clean up 2229func Test_terminal_statusline() 2230 CheckUnix 2231 2232 set statusline=x 2233 terminal 2234 let tbuf = bufnr('') 2235 call term_sendkeys(tbuf, "clear; echo a; echo b; sleep 1; clear\n") 2236 call timer_start(500, { tid -> feedkeys("\<C-w>j", 'tx') }) 2237 call timer_start(1500, { tid -> feedkeys("\<C-l>", 'tx') }) 2238 au BufLeave * if &buftype == 'terminal' | silent! normal i | endif 2239 2240 sleep 2 2241 exe tbuf . 'bwipe!' 2242 au! BufLeave 2243 set statusline= 2244endfunc 2245 2246func Test_terminal_getwinpos() 2247 CheckRunVimInTerminal 2248 2249 " split, go to the bottom-right window 2250 split 2251 wincmd j 2252 set splitright 2253 2254 call writefile([ 2255 \ 'echo getwinpos()', 2256 \ ], 'XTest_getwinpos') 2257 let buf = RunVimInTerminal('-S XTest_getwinpos', {'cols': 60}) 2258 call TermWait(buf) 2259 2260 " Find the output of getwinpos() in the bottom line. 2261 let rows = term_getsize(buf)[0] 2262 call WaitForAssert({-> assert_match('\[\d\+, \d\+\]', term_getline(buf, rows))}) 2263 let line = term_getline(buf, rows) 2264 let xpos = str2nr(substitute(line, '\[\(\d\+\), \d\+\]', '\1', '')) 2265 let ypos = str2nr(substitute(line, '\[\d\+, \(\d\+\)\]', '\1', '')) 2266 2267 " Position must be bigger than the getwinpos() result of Vim itself. 2268 " The calculation in the console assumes a 10 x 7 character cell. 2269 " In the GUI it can be more, let's assume a 20 x 14 cell. 2270 " And then add 100 / 200 tolerance. 2271 let [xroot, yroot] = getwinpos() 2272 let winpos = 50->getwinpos() 2273 call assert_equal(xroot, winpos[0]) 2274 call assert_equal(yroot, winpos[1]) 2275 let [winrow, wincol] = win_screenpos('.') 2276 let xoff = wincol * (has('gui_running') ? 14 : 7) + 100 2277 let yoff = winrow * (has('gui_running') ? 20 : 10) + 200 2278 call assert_inrange(xroot + 2, xroot + xoff, xpos) 2279 call assert_inrange(yroot + 2, yroot + yoff, ypos) 2280 2281 call TermWait(buf) 2282 call term_sendkeys(buf, ":q\<CR>") 2283 call StopVimInTerminal(buf) 2284 call delete('XTest_getwinpos') 2285 exe buf . 'bwipe!' 2286 set splitright& 2287 only! 2288endfunc 2289 2290func Test_terminal_altscreen() 2291 " somehow doesn't work on MS-Windows 2292 CheckUnix 2293 let cmd = "cat Xtext\<CR>" 2294 2295 let buf = term_start(&shell, {}) 2296 call writefile(["\<Esc>[?1047h"], 'Xtext') 2297 call term_sendkeys(buf, cmd) 2298 call WaitForAssert({-> assert_equal(1, term_getaltscreen(buf))}) 2299 2300 call writefile(["\<Esc>[?1047l"], 'Xtext') 2301 call term_sendkeys(buf, cmd) 2302 call WaitForAssert({-> assert_equal(0, term_getaltscreen(buf))}) 2303 2304 call term_sendkeys(buf, "exit\r") 2305 exe buf . "bwipe!" 2306 call delete('Xtext') 2307endfunc 2308 2309func Test_terminal_shell_option() 2310 if has('unix') 2311 " exec is a shell builtin command, should fail without a shell. 2312 term exec ls runtest.vim 2313 call WaitForAssert({-> assert_match('job failed', term_getline(bufnr(), 1))}) 2314 bwipe! 2315 2316 term ++shell exec ls runtest.vim 2317 call WaitForAssert({-> assert_match('runtest.vim', term_getline(bufnr(), 1))}) 2318 bwipe! 2319 elseif has('win32') 2320 " dir is a shell builtin command, should fail without a shell. 2321 try 2322 term dir /b runtest.vim 2323 call WaitForAssert({-> assert_match('job failed\|cannot access .*: No such file or directory', term_getline(bufnr(), 1))}) 2324 catch /CreateProcess/ 2325 " ignore 2326 endtry 2327 bwipe! 2328 2329 term ++shell dir /b runtest.vim 2330 call WaitForAssert({-> assert_match('runtest.vim', term_getline(bufnr(), 1))}) 2331 bwipe! 2332 endif 2333endfunc 2334 2335func Test_terminal_setapi_and_call() 2336 CheckRunVimInTerminal 2337 2338 call WriteApiCall('Tapi_TryThis') 2339 call ch_logfile('Xlog', 'w') 2340 2341 unlet! g:called_bufnum 2342 unlet! g:called_arg 2343 2344 let buf = RunVimInTerminal('-S Xscript', {'term_api': ''}) 2345 call WaitForAssert({-> assert_match('Unpermitted function: Tapi_TryThis', string(readfile('Xlog')))}) 2346 call assert_false(exists('g:called_bufnum')) 2347 call assert_false(exists('g:called_arg')) 2348 2349 eval buf->term_setapi('Tapi_') 2350 call term_sendkeys(buf, ":set notitle\<CR>") 2351 call term_sendkeys(buf, ":source Xscript\<CR>") 2352 call WaitFor({-> exists('g:called_bufnum')}) 2353 call assert_equal(buf, g:called_bufnum) 2354 call assert_equal(['hello', 123], g:called_arg) 2355 2356 call StopVimInTerminal(buf) 2357 2358 call delete('Xscript') 2359 call ch_logfile('') 2360 call delete('Xlog') 2361 unlet! g:called_bufnum 2362 unlet! g:called_arg 2363endfunc 2364 2365func Test_terminal_api_arg() 2366 CheckRunVimInTerminal 2367 2368 call WriteApiCall('Tapi_TryThis') 2369 call ch_logfile('Xlog', 'w') 2370 2371 unlet! g:called_bufnum 2372 unlet! g:called_arg 2373 2374 execute 'term ++api= ' .. GetVimCommandCleanTerm() .. '-S Xscript' 2375 let buf = bufnr('%') 2376 call WaitForAssert({-> assert_match('Unpermitted function: Tapi_TryThis', string(readfile('Xlog')))}) 2377 call assert_false(exists('g:called_bufnum')) 2378 call assert_false(exists('g:called_arg')) 2379 2380 call StopVimInTerminal(buf) 2381 2382 call ch_logfile('Xlog', 'w') 2383 2384 execute 'term ++api=Tapi_ ' .. GetVimCommandCleanTerm() .. '-S Xscript' 2385 let buf = bufnr('%') 2386 call WaitFor({-> exists('g:called_bufnum')}) 2387 call assert_equal(buf, g:called_bufnum) 2388 call assert_equal(['hello', 123], g:called_arg) 2389 2390 call StopVimInTerminal(buf) 2391 2392 call delete('Xscript') 2393 call ch_logfile('') 2394 call delete('Xlog') 2395 unlet! g:called_bufnum 2396 unlet! g:called_arg 2397endfunc 2398 2399func Test_terminal_invalid_arg() 2400 call assert_fails('terminal ++xyz', 'E181:') 2401endfunc 2402 2403func Test_terminal_in_popup() 2404 CheckRunVimInTerminal 2405 2406 let text =<< trim END 2407 some text 2408 to edit 2409 in a popup window 2410 END 2411 call writefile(text, 'Xtext') 2412 let cmd = GetVimCommandCleanTerm() 2413 let lines = [ 2414 \ 'set t_u7=', 2415 \ 'call setline(1, range(20))', 2416 \ 'hi PopTerm ctermbg=grey', 2417 \ 'func OpenTerm(setColor)', 2418 \ " set noruler", 2419 \ " let s:buf = term_start('" .. cmd .. " Xtext', #{hidden: 1, term_finish: 'close'})", 2420 \ ' let g:winid = popup_create(s:buf, #{minwidth: 45, minheight: 7, border: [], drag: 1, resize: 1})', 2421 \ ' if a:setColor', 2422 \ ' call win_execute(g:winid, "set wincolor=PopTerm")', 2423 \ ' endif', 2424 \ 'endfunc', 2425 \ 'func HidePopup()', 2426 \ ' call popup_hide(g:winid)', 2427 \ 'endfunc', 2428 \ 'func ClosePopup()', 2429 \ ' call popup_close(g:winid)', 2430 \ 'endfunc', 2431 \ 'func ReopenPopup()', 2432 \ ' call popup_create(s:buf, #{minwidth: 40, minheight: 6, border: []})', 2433 \ 'endfunc', 2434 \ ] 2435 call writefile(lines, 'XtermPopup') 2436 let buf = RunVimInTerminal('-S XtermPopup', #{rows: 15}) 2437 call TermWait(buf, 100) 2438 call term_sendkeys(buf, ":call OpenTerm(0)\<CR>") 2439 call TermWait(buf, 100) 2440 call term_sendkeys(buf, ":\<CR>") 2441 call TermWait(buf, 100) 2442 call term_sendkeys(buf, "\<C-W>:echo getwinvar(g:winid, \"&buftype\") win_gettype(g:winid)\<CR>") 2443 call VerifyScreenDump(buf, 'Test_terminal_popup_1', {}) 2444 2445 call term_sendkeys(buf, ":q\<CR>") 2446 call VerifyScreenDump(buf, 'Test_terminal_popup_2', {}) 2447 2448 call term_sendkeys(buf, ":call OpenTerm(1)\<CR>") 2449 call TermWait(buf, 150) 2450 call term_sendkeys(buf, ":set hlsearch\<CR>") 2451 call term_sendkeys(buf, "/edit\<CR>") 2452 call VerifyScreenDump(buf, 'Test_terminal_popup_3', {}) 2453 2454 call term_sendkeys(buf, "\<C-W>:call HidePopup()\<CR>") 2455 call VerifyScreenDump(buf, 'Test_terminal_popup_4', {}) 2456 call term_sendkeys(buf, "\<CR>") 2457 call TermWait(buf, 50) 2458 2459 call term_sendkeys(buf, "\<C-W>:call ClosePopup()\<CR>") 2460 call VerifyScreenDump(buf, 'Test_terminal_popup_5', {}) 2461 2462 call term_sendkeys(buf, "\<C-W>:call ReopenPopup()\<CR>") 2463 call VerifyScreenDump(buf, 'Test_terminal_popup_6', {}) 2464 2465 " Go to terminal-Normal mode and visually select text. 2466 call term_sendkeys(buf, "\<C-W>Ngg/in\<CR>vww") 2467 call VerifyScreenDump(buf, 'Test_terminal_popup_7', {}) 2468 2469 " Back to job mode, redraws 2470 call term_sendkeys(buf, "A") 2471 call VerifyScreenDump(buf, 'Test_terminal_popup_8', {}) 2472 2473 call TermWait(buf, 50) 2474 call term_sendkeys(buf, ":q\<CR>") 2475 call TermWait(buf, 100) " wait for terminal to vanish 2476 2477 call StopVimInTerminal(buf) 2478 call delete('Xtext') 2479 call delete('XtermPopup') 2480endfunc 2481 2482" Check a terminal in popup window uses the default mininum size. 2483func Test_terminal_in_popup_min_size() 2484 CheckRunVimInTerminal 2485 2486 let text =<< trim END 2487 another text 2488 to show 2489 in a popup window 2490 END 2491 call writefile(text, 'Xtext') 2492 let lines = [ 2493 \ 'set t_u7=', 2494 \ 'call setline(1, range(20))', 2495 \ 'func OpenTerm()', 2496 \ " let s:buf = term_start('cat Xtext', #{hidden: 1})", 2497 \ ' let g:winid = popup_create(s:buf, #{ border: []})', 2498 \ 'endfunc', 2499 \ ] 2500 call writefile(lines, 'XtermPopup') 2501 let buf = RunVimInTerminal('-S XtermPopup', #{rows: 15}) 2502 call TermWait(buf, 100) 2503 call term_sendkeys(buf, ":set noruler\<CR>") 2504 call term_sendkeys(buf, ":call OpenTerm()\<CR>") 2505 call TermWait(buf, 50) 2506 call term_sendkeys(buf, ":\<CR>") 2507 call VerifyScreenDump(buf, 'Test_terminal_popup_m1', {}) 2508 2509 call TermWait(buf, 50) 2510 call term_sendkeys(buf, ":q\<CR>") 2511 call TermWait(buf, 50) " wait for terminal to vanish 2512 call StopVimInTerminal(buf) 2513 call delete('Xtext') 2514 call delete('XtermPopup') 2515endfunc 2516 2517" Check a terminal in popup window with different colors 2518func Terminal_in_popup_colored(group_name, highlight_cmd, highlight_opt) 2519 CheckRunVimInTerminal 2520 CheckUnix 2521 2522 let lines = [ 2523 \ 'set t_u7=', 2524 \ 'call setline(1, range(20))', 2525 \ 'func OpenTerm()', 2526 \ " let s:buf = term_start('cat', #{hidden: 1, " 2527 \ .. a:highlight_opt .. "})", 2528 \ ' let g:winid = popup_create(s:buf, #{ border: []})', 2529 \ 'endfunc', 2530 \ a:highlight_cmd, 2531 \ ] 2532 call writefile(lines, 'XtermPopup') 2533 let buf = RunVimInTerminal('-S XtermPopup', #{rows: 15}) 2534 call TermWait(buf, 100) 2535 call term_sendkeys(buf, ":set noruler\<CR>") 2536 call term_sendkeys(buf, ":call OpenTerm()\<CR>") 2537 call TermWait(buf, 50) 2538 call term_sendkeys(buf, "hello\<CR>") 2539 call VerifyScreenDump(buf, 'Test_terminal_popup_' .. a:group_name, {}) 2540 2541 call term_sendkeys(buf, "\<C-D>") 2542 call TermWait(buf, 50) 2543 call term_sendkeys(buf, ":q\<CR>") 2544 call TermWait(buf, 50) " wait for terminal to vanish 2545 call StopVimInTerminal(buf) 2546 call delete('XtermPopup') 2547endfunc 2548 2549func Test_terminal_in_popup_colored_Terminal() 2550 call Terminal_in_popup_colored("Terminal", "highlight Terminal ctermfg=blue ctermbg=yellow", "") 2551endfunc 2552 2553func Test_terminal_in_popup_colored_group() 2554 call Terminal_in_popup_colored("MyTermCol", "highlight MyTermCol ctermfg=darkgreen ctermbg=lightblue", "term_highlight: 'MyTermCol',") 2555endfunc 2556 2557func Test_double_popup_terminal() 2558 let buf1 = term_start(&shell, #{hidden: 1}) 2559 let win1 = popup_create(buf1, {}) 2560 let buf2 = term_start(&shell, #{hidden: 1}) 2561 let win2 = popup_create(buf2, {}) 2562 call popup_close(win1) 2563 call popup_close(win2) 2564 exe buf1 .. 'bwipe!' 2565 exe buf2 .. 'bwipe!' 2566endfunc 2567 2568func Test_issue_5607() 2569 let wincount = winnr('$') 2570 exe 'terminal' &shell &shellcmdflag 'exit' 2571 let job = term_getjob(bufnr()) 2572 call WaitForAssert({-> assert_equal("dead", job_status(job))}) 2573 2574 let old_wincolor = &wincolor 2575 try 2576 set wincolor= 2577 finally 2578 let &wincolor = old_wincolor 2579 bw! 2580 endtry 2581endfunc 2582 2583func Test_hidden_terminal() 2584 let buf = term_start(&shell, #{hidden: 1}) 2585 call assert_equal('', bufname('^$')) 2586 call StopShellInTerminal(buf) 2587endfunc 2588 2589func Test_term_nasty_callback() 2590 CheckExecutable sh 2591 func OpenTerms() 2592 set hidden 2593 let g:buf0 = term_start('sh', #{hidden: 1}) 2594 call popup_create(g:buf0, {}) 2595 let g:buf1 = term_start('sh', #{hidden: 1, term_finish: 'close'}) 2596 call popup_create(g:buf1, {}) 2597 let g:buf2 = term_start(['sh', '-c'], #{curwin: 1, exit_cb: function('TermExit')}) 2598 call TermWait(g:buf2, 50) 2599 call popup_close(win_getid()) 2600 endfunc 2601 func TermExit(...) 2602 let altbuf = bufnr('#') 2603 call term_sendkeys(altbuf, "exit\<CR>") 2604 call TermWait(altbuf) 2605 call popup_close(win_getid()) 2606 endfunc 2607 call OpenTerms() 2608 2609 call term_sendkeys(g:buf0, "exit\<CR>") 2610 call TermWait(g:buf0, 50) 2611 exe g:buf0 .. 'bwipe!' 2612 set hidden& 2613endfunc 2614 2615func Test_term_and_startinsert() 2616 CheckRunVimInTerminal 2617 CheckUnix 2618 2619 let lines =<< trim EOL 2620 put='some text' 2621 term 2622 startinsert 2623 EOL 2624 call writefile(lines, 'XTest_startinsert') 2625 let buf = RunVimInTerminal('-S XTest_startinsert', {}) 2626 2627 call term_sendkeys(buf, "exit\r") 2628 call WaitForAssert({-> assert_equal("some text", term_getline(buf, 1))}) 2629 call term_sendkeys(buf, "0l") 2630 call term_sendkeys(buf, "A<\<Esc>") 2631 call WaitForAssert({-> assert_equal("some text<", term_getline(buf, 1))}) 2632 2633 call StopVimInTerminal(buf) 2634 call delete('XTest_startinsert') 2635endfunc 2636 2637" Test for passing invalid arguments to terminal functions 2638func Test_term_func_invalid_arg() 2639 call assert_fails('let b = term_getaltscreen([])', 'E745:') 2640 call assert_fails('let p = term_getansicolors([])', 'E745:') 2641 call assert_fails('let a = term_getattr(1, [])', 'E730:') 2642 call assert_fails('let c = term_getcursor([])', 'E745:') 2643 call assert_fails('let l = term_getline([], 1)', 'E745:') 2644 call assert_fails('let l = term_getscrolled([])', 'E745:') 2645 call assert_fails('let s = term_getsize([])', 'E745:') 2646 call assert_fails('let s = term_getstatus([])', 'E745:') 2647 call assert_fails('let s = term_scrape([], 1)', 'E745:') 2648 call assert_fails('call term_sendkeys([], "a")', 'E745:') 2649 call assert_fails('call term_setansicolors([], [])', 'E745:') 2650 call assert_fails('call term_setapi([], "")', 'E745:') 2651 call assert_fails('call term_setrestore([], "")', 'E745:') 2652 call assert_fails('call term_setkill([], "")', 'E745:') 2653endfunc 2654 2655" vim: shiftwidth=2 sts=2 expandtab 2656