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 CheckExecutable python 719 720 call setline(1, ['print("hello")']) 721 1term ++eof=exit(123) 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 CheckExecutable python 737 738 call setline(1, ['print("hello")']) 739 1term ++eof=<C-Z> 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 CheckExecutable 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 1term ++eof=<C-Z> ++eof=exit(123) 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 CheckNotBSD 898 let save_enc = &encoding 899 set encoding=utf-8 900 901 if has('win32') 902 let cmd = "cmd /K chcp 65001" 903 let lnum = [3, 6, 9] 904 else 905 let cmd = &shell 906 let lnum = [1, 3, 5] 907 endif 908 909 enew 910 let buf = term_start(cmd, {'curwin': bufnr('')}) 911 let g:job = term_getjob(buf) 912 call TermWait(buf, 25) 913 914 if has('win32') 915 call assert_equal('cmd', job_info(g:job).cmd[0]) 916 else 917 call assert_equal(&shell, job_info(g:job).cmd[0]) 918 endif 919 920 " ascii + composing 921 let txt = "a\u0308bc" 922 call term_sendkeys(buf, "echo " . txt . "\r") 923 call TermWait(buf, 25) 924 call assert_match("echo " . txt, term_getline(buf, lnum[0])) 925 call assert_equal(txt, term_getline(buf, lnum[0] + 1)) 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 . "\r") 934 call TermWait(buf, 25) 935 call assert_match("echo " . txt, term_getline(buf, lnum[1])) 936 call assert_equal(txt, term_getline(buf, lnum[1] + 1)) 937 let l = term_scrape(buf, lnum[1] + 1) 938 call assert_equal("\u304b\u3099", l[0].chars) 939 call assert_equal("\u304e", l[1].chars) 940 call assert_equal("\u304f\u3099", l[2].chars) 941 call assert_equal("\u3052", l[3].chars) 942 call assert_equal("\u3053\u3099", l[4].chars) 943 944 " \u00a0 + composing 945 let txt = "abc\u00a0\u0308" 946 call term_sendkeys(buf, "echo " . txt . "\r") 947 call TermWait(buf, 25) 948 call assert_match("echo " . txt, term_getline(buf, lnum[2])) 949 call assert_equal(txt, term_getline(buf, lnum[2] + 1)) 950 let l = term_scrape(buf, lnum[2] + 1) 951 call assert_equal("\u00a0\u0308", l[3].chars) 952 953 call term_sendkeys(buf, "exit\r") 954 call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) 955 bwipe! 956 unlet g:job 957 let &encoding = save_enc 958endfunc 959 960func Test_terminal_aucmd_on_close() 961 fun Nop() 962 let s:called = 1 963 endfun 964 965 aug repro 966 au! 967 au BufWinLeave * call Nop() 968 aug END 969 970 let [cmd, waittime] = s:get_sleep_cmd() 971 972 call assert_equal(1, winnr('$')) 973 new 974 call setline(1, ['one', 'two']) 975 exe 'term ++close ' . cmd 976 wincmd p 977 call WaitForAssert({-> assert_equal(2, winnr('$'))}, waittime) 978 call assert_equal(1, s:called) 979 bwipe! 980 981 unlet s:called 982 au! repro 983 delfunc Nop 984endfunc 985 986func Test_terminal_term_start_empty_command() 987 let cmd = "call term_start('', {'curwin' : 1, 'term_finish' : 'close'})" 988 call assert_fails(cmd, 'E474') 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(0, {'curwin' : 1, 'term_finish' : 'close'})" 994 call assert_fails(cmd, 'E474') 995 let cmd = "call term_start('', {'term_name' : []})" 996 call assert_fails(cmd, 'E475') 997 let cmd = "call term_start('', {'term_finish' : 'axby'})" 998 call assert_fails(cmd, 'E475') 999 let cmd = "call term_start('', {'eof_chars' : []})" 1000 call assert_fails(cmd, 'E475:') 1001 let cmd = "call term_start('', {'term_kill' : []})" 1002 call assert_fails(cmd, 'E475:') 1003 let cmd = "call term_start('', {'tty_type' : []})" 1004 call assert_fails(cmd, 'E475:') 1005 let cmd = "call term_start('', {'tty_type' : 'abc'})" 1006 call assert_fails(cmd, 'E475:') 1007 let cmd = "call term_start('', {'term_highlight' : []})" 1008 call assert_fails(cmd, 'E475:') 1009 if has('gui') 1010 let cmd = "call term_start('', {'ansi_colors' : 'abc'})" 1011 call assert_fails(cmd, 'E475:') 1012 let cmd = "call term_start('', {'ansi_colors' : [[]]})" 1013 call assert_fails(cmd, 'E730:') 1014 let cmd = "call term_start('', {'ansi_colors' : repeat(['blue'], 18)})" 1015 call assert_fails(cmd, 'E475:') 1016 endif 1017endfunc 1018 1019func Test_terminal_response_to_control_sequence() 1020 CheckUnix 1021 1022 let buf = Run_shell_in_terminal({}) 1023 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))}) 1024 1025 call term_sendkeys(buf, "cat\<CR>") 1026 call WaitForAssert({-> assert_match('cat', term_getline(buf, 1))}) 1027 1028 " Request the cursor position. 1029 call term_sendkeys(buf, "\x1b[6n\<CR>") 1030 1031 " Wait for output from tty to display, below an empty line. 1032 call WaitForAssert({-> assert_match('3;1R', term_getline(buf, 4))}) 1033 1034 " End "cat" gently. 1035 call term_sendkeys(buf, "\<CR>\<C-D>") 1036 1037 call StopShellInTerminal(buf) 1038 exe buf . 'bwipe' 1039 unlet g:job 1040endfunc 1041 1042" Run Vim, start a terminal in that Vim with the kill argument, 1043" :qall works. 1044func Run_terminal_qall_kill(line1, line2) 1045 " 1. Open a terminal window and wait for the prompt to appear 1046 " 2. set kill using term_setkill() 1047 " 3. make Vim exit, it will kill the shell 1048 let after = [ 1049 \ a:line1, 1050 \ 'let buf = bufnr("%")', 1051 \ 'while term_getline(buf, 1) =~ "^\\s*$"', 1052 \ ' sleep 10m', 1053 \ 'endwhile', 1054 \ a:line2, 1055 \ 'au VimLeavePre * call writefile(["done"], "Xdone")', 1056 \ 'qall', 1057 \ ] 1058 if !RunVim([], after, '') 1059 return 1060 endif 1061 call assert_equal("done", readfile("Xdone")[0]) 1062 call delete("Xdone") 1063endfunc 1064 1065" Run Vim in a terminal, then start a terminal in that Vim with a kill 1066" argument, check that :qall works. 1067func Test_terminal_qall_kill_arg() 1068 call Run_terminal_qall_kill('term ++kill=kill', '') 1069endfunc 1070 1071" Run Vim, start a terminal in that Vim, set the kill argument with 1072" term_setkill(), check that :qall works. 1073func Test_terminal_qall_kill_func() 1074 call Run_terminal_qall_kill('term', 'eval buf->term_setkill("kill")') 1075endfunc 1076 1077" Run Vim, start a terminal in that Vim without the kill argument, 1078" check that :qall does not exit, :qall! does. 1079func Test_terminal_qall_exit() 1080 let after =<< trim [CODE] 1081 term 1082 let buf = bufnr("%") 1083 while term_getline(buf, 1) =~ "^\\s*$" 1084 sleep 10m 1085 endwhile 1086 set nomore 1087 au VimLeavePre * call writefile(["too early"], "Xdone") 1088 qall 1089 au! VimLeavePre * exe buf . "bwipe!" | call writefile(["done"], "Xdone") 1090 cquit 1091 [CODE] 1092 1093 if !RunVim([], after, '') 1094 return 1095 endif 1096 call assert_equal("done", readfile("Xdone")[0]) 1097 call delete("Xdone") 1098endfunc 1099 1100" Run Vim in a terminal, then start a terminal in that Vim without a kill 1101" argument, check that :confirm qall works. 1102func Test_terminal_qall_prompt() 1103 CheckRunVimInTerminal 1104 let buf = RunVimInTerminal('', {}) 1105 1106 " Open a terminal window and wait for the prompt to appear 1107 call term_sendkeys(buf, ":term\<CR>") 1108 call WaitForAssert({-> assert_match('\[running]', term_getline(buf, 10))}) 1109 call WaitForAssert({-> assert_notmatch('^\s*$', term_getline(buf, 1))}) 1110 1111 " make Vim exit, it will prompt to kill the shell 1112 call term_sendkeys(buf, "\<C-W>:confirm qall\<CR>") 1113 call WaitForAssert({-> assert_match('ancel:', term_getline(buf, 20))}) 1114 call term_sendkeys(buf, "y") 1115 call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))}) 1116 1117 " close the terminal window where Vim was running 1118 quit 1119endfunc 1120 1121" Run Vim in a terminal, then start a terminal window with a shell and check 1122" that Vim exits if it is closed. 1123func Test_terminal_exit() 1124 CheckRunVimInTerminal 1125 1126 let lines =<< trim END 1127 let winid = win_getid() 1128 help 1129 term 1130 let termid = win_getid() 1131 call win_gotoid(winid) 1132 close 1133 call win_gotoid(termid) 1134 END 1135 call writefile(lines, 'XtermExit') 1136 let buf = RunVimInTerminal('-S XtermExit', #{rows: 10}) 1137 let job = term_getjob(buf) 1138 call WaitForAssert({-> assert_equal("run", job_status(job))}) 1139 1140 " quit the shell, it will make Vim exit 1141 call term_sendkeys(buf, "exit\<CR>") 1142 call WaitForAssert({-> assert_equal("dead", job_status(job))}) 1143 1144 call delete('XtermExit') 1145endfunc 1146 1147func Test_terminal_open_autocmd() 1148 augroup repro 1149 au! 1150 au TerminalOpen * let s:called += 1 1151 augroup END 1152 1153 let s:called = 0 1154 1155 " Open a terminal window with :terminal 1156 terminal 1157 call assert_equal(1, s:called) 1158 bwipe! 1159 1160 " Open a terminal window with term_start() 1161 call term_start(&shell) 1162 call assert_equal(2, s:called) 1163 bwipe! 1164 1165 " Open a hidden terminal buffer with :terminal 1166 terminal ++hidden 1167 call assert_equal(3, s:called) 1168 for buf in term_list() 1169 exe buf . "bwipe!" 1170 endfor 1171 1172 " Open a hidden terminal buffer with term_start() 1173 let buf = term_start(&shell, {'hidden': 1}) 1174 call assert_equal(4, s:called) 1175 exe buf . "bwipe!" 1176 1177 unlet s:called 1178 au! repro 1179endfunction 1180 1181func Check_dump01(off) 1182 call assert_equal('one two three four five', trim(getline(a:off + 1))) 1183 call assert_equal('~ Select Word', trim(getline(a:off + 7))) 1184 call assert_equal(':popup PopUp', trim(getline(a:off + 20))) 1185endfunc 1186 1187func Test_terminal_dumpwrite_composing() 1188 CheckRunVimInTerminal 1189 let save_enc = &encoding 1190 set encoding=utf-8 1191 call assert_equal(1, winnr('$')) 1192 1193 let text = " a\u0300 e\u0302 o\u0308" 1194 call writefile([text], 'Xcomposing') 1195 let buf = RunVimInTerminal('--cmd "set encoding=utf-8" Xcomposing', {}) 1196 call WaitForAssert({-> assert_match(text, term_getline(buf, 1))}) 1197 eval 'Xdump'->term_dumpwrite(buf) 1198 let dumpline = readfile('Xdump')[0] 1199 call assert_match('|à| |ê| |ö', dumpline) 1200 1201 call StopVimInTerminal(buf) 1202 call delete('Xcomposing') 1203 call delete('Xdump') 1204 let &encoding = save_enc 1205endfunc 1206 1207" just testing basic functionality. 1208func Test_terminal_dumpload() 1209 let curbuf = winbufnr('') 1210 call assert_equal(1, winnr('$')) 1211 let buf = term_dumpload('dumps/Test_popup_command_01.dump') 1212 call assert_equal(2, winnr('$')) 1213 call assert_equal(20, line('$')) 1214 call Check_dump01(0) 1215 1216 " Load another dump in the same window 1217 let buf2 = 'dumps/Test_diff_01.dump'->term_dumpload({'bufnr': buf}) 1218 call assert_equal(buf, buf2) 1219 call assert_notequal('one two three four five', trim(getline(1))) 1220 1221 " Load the first dump again in the same window 1222 let buf2 = term_dumpload('dumps/Test_popup_command_01.dump', {'bufnr': buf}) 1223 call assert_equal(buf, buf2) 1224 call Check_dump01(0) 1225 1226 call assert_fails("call term_dumpload('dumps/Test_popup_command_01.dump', {'bufnr': curbuf})", 'E475:') 1227 call assert_fails("call term_dumpload('dumps/Test_popup_command_01.dump', {'bufnr': 9999})", 'E86:') 1228 new 1229 let closedbuf = winbufnr('') 1230 quit 1231 call assert_fails("call term_dumpload('dumps/Test_popup_command_01.dump', {'bufnr': closedbuf})", 'E475:') 1232 1233 quit 1234endfunc 1235 1236func Test_terminal_dumpload_dump() 1237 CheckRunVimInTerminal 1238 1239 let lines =<< trim END 1240 call term_dumpload('dumps/Test_popupwin_22.dump', #{term_rows: 12}) 1241 END 1242 call writefile(lines, 'XtermDumpload') 1243 let buf = RunVimInTerminal('-S XtermDumpload', #{rows: 15}) 1244 call VerifyScreenDump(buf, 'Test_terminal_dumpload', {}) 1245 1246 call StopVimInTerminal(buf) 1247 call delete('XtermDumpload') 1248endfunc 1249 1250func Test_terminal_dumpdiff() 1251 call assert_equal(1, winnr('$')) 1252 eval 'dumps/Test_popup_command_01.dump'->term_dumpdiff('dumps/Test_popup_command_02.dump') 1253 call assert_equal(2, winnr('$')) 1254 call assert_equal(62, line('$')) 1255 call Check_dump01(0) 1256 call Check_dump01(42) 1257 call assert_equal(' bbbbbbbbbbbbbbbbbb ', getline(26)[0:29]) 1258 quit 1259endfunc 1260 1261func Test_terminal_dumpdiff_swap() 1262 call assert_equal(1, winnr('$')) 1263 call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_03.dump') 1264 call assert_equal(2, winnr('$')) 1265 call assert_equal(62, line('$')) 1266 call assert_match('Test_popup_command_01.dump', getline(21)) 1267 call assert_match('Test_popup_command_03.dump', getline(42)) 1268 call assert_match('Undo', getline(3)) 1269 call assert_match('three four five', getline(45)) 1270 1271 normal s 1272 call assert_match('Test_popup_command_03.dump', getline(21)) 1273 call assert_match('Test_popup_command_01.dump', getline(42)) 1274 call assert_match('three four five', getline(3)) 1275 call assert_match('Undo', getline(45)) 1276 quit 1277endfunc 1278 1279func Test_terminal_dumpdiff_options() 1280 set laststatus=0 1281 call assert_equal(1, winnr('$')) 1282 let height = winheight(0) 1283 call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump', {'vertical': 1, 'term_cols': 33}) 1284 call assert_equal(2, winnr('$')) 1285 call assert_equal(height, winheight(winnr())) 1286 call assert_equal(33, winwidth(winnr())) 1287 call assert_equal('dump diff dumps/Test_popup_command_01.dump', bufname('%')) 1288 quit 1289 1290 call assert_equal(1, winnr('$')) 1291 call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump', {'vertical': 0, 'term_rows': 13, 'term_name': 'something else'}) 1292 call assert_equal(2, winnr('$')) 1293 call assert_equal(&columns, winwidth(0)) 1294 call assert_equal(13, winheight(0)) 1295 call assert_equal('something else', bufname('%')) 1296 quit 1297 1298 call assert_equal(1, winnr('$')) 1299 call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump', {'curwin': 1}) 1300 call assert_equal(1, winnr('$')) 1301 call assert_fails("call term_dumpdiff('dumps/Test_popup_command_01.dump', 'dumps/Test_popup_command_02.dump', {'bufnr': -1})", 'E475:') 1302 bwipe 1303 1304 set laststatus& 1305endfunc 1306 1307func Api_drop_common(options) 1308 call assert_equal(1, winnr('$')) 1309 1310 " Use the title termcap entries to output the escape sequence. 1311 call writefile([ 1312 \ 'set title', 1313 \ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"', 1314 \ 'let &titlestring = ''["drop","Xtextfile"' . a:options . ']''', 1315 \ 'redraw', 1316 \ "set t_ts=", 1317 \ ], 'Xscript') 1318 let buf = RunVimInTerminal('-S Xscript', {}) 1319 call WaitFor({-> bufnr('Xtextfile') > 0}) 1320 call assert_equal('Xtextfile', expand('%:t')) 1321 call assert_true(winnr('$') >= 3) 1322 return buf 1323endfunc 1324 1325func Test_terminal_api_drop_newwin() 1326 CheckRunVimInTerminal 1327 let buf = Api_drop_common('') 1328 call assert_equal(0, &bin) 1329 call assert_equal('', &fenc) 1330 1331 call StopVimInTerminal(buf) 1332 call delete('Xscript') 1333 bwipe Xtextfile 1334endfunc 1335 1336func Test_terminal_api_drop_newwin_bin() 1337 CheckRunVimInTerminal 1338 let buf = Api_drop_common(',{"bin":1}') 1339 call assert_equal(1, &bin) 1340 1341 call StopVimInTerminal(buf) 1342 call delete('Xscript') 1343 bwipe Xtextfile 1344endfunc 1345 1346func Test_terminal_api_drop_newwin_binary() 1347 CheckRunVimInTerminal 1348 let buf = Api_drop_common(',{"binary":1}') 1349 call assert_equal(1, &bin) 1350 1351 call StopVimInTerminal(buf) 1352 call delete('Xscript') 1353 bwipe Xtextfile 1354endfunc 1355 1356func Test_terminal_api_drop_newwin_nobin() 1357 CheckRunVimInTerminal 1358 set binary 1359 let buf = Api_drop_common(',{"nobin":1}') 1360 call assert_equal(0, &bin) 1361 1362 call StopVimInTerminal(buf) 1363 call delete('Xscript') 1364 bwipe Xtextfile 1365 set nobinary 1366endfunc 1367 1368func Test_terminal_api_drop_newwin_nobinary() 1369 CheckRunVimInTerminal 1370 set binary 1371 let buf = Api_drop_common(',{"nobinary":1}') 1372 call assert_equal(0, &bin) 1373 1374 call StopVimInTerminal(buf) 1375 call delete('Xscript') 1376 bwipe Xtextfile 1377 set nobinary 1378endfunc 1379 1380func Test_terminal_api_drop_newwin_ff() 1381 CheckRunVimInTerminal 1382 let buf = Api_drop_common(',{"ff":"dos"}') 1383 call assert_equal("dos", &ff) 1384 1385 call StopVimInTerminal(buf) 1386 call delete('Xscript') 1387 bwipe Xtextfile 1388endfunc 1389 1390func Test_terminal_api_drop_newwin_fileformat() 1391 CheckRunVimInTerminal 1392 let buf = Api_drop_common(',{"fileformat":"dos"}') 1393 call assert_equal("dos", &ff) 1394 1395 call StopVimInTerminal(buf) 1396 call delete('Xscript') 1397 bwipe Xtextfile 1398endfunc 1399 1400func Test_terminal_api_drop_newwin_enc() 1401 CheckRunVimInTerminal 1402 let buf = Api_drop_common(',{"enc":"utf-16"}') 1403 call assert_equal("utf-16", &fenc) 1404 1405 call StopVimInTerminal(buf) 1406 call delete('Xscript') 1407 bwipe Xtextfile 1408endfunc 1409 1410func Test_terminal_api_drop_newwin_encoding() 1411 CheckRunVimInTerminal 1412 let buf = Api_drop_common(',{"encoding":"utf-16"}') 1413 call assert_equal("utf-16", &fenc) 1414 1415 call StopVimInTerminal(buf) 1416 call delete('Xscript') 1417 bwipe Xtextfile 1418endfunc 1419 1420func Test_terminal_api_drop_oldwin() 1421 CheckRunVimInTerminal 1422 let firstwinid = win_getid() 1423 split Xtextfile 1424 let textfile_winid = win_getid() 1425 call assert_equal(2, winnr('$')) 1426 call win_gotoid(firstwinid) 1427 1428 " Use the title termcap entries to output the escape sequence. 1429 call writefile([ 1430 \ 'set title', 1431 \ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"', 1432 \ 'let &titlestring = ''["drop","Xtextfile"]''', 1433 \ 'redraw', 1434 \ "set t_ts=", 1435 \ ], 'Xscript') 1436 let buf = RunVimInTerminal('-S Xscript', {'rows': 10}) 1437 call WaitForAssert({-> assert_equal('Xtextfile', expand('%:t'))}) 1438 call assert_equal(textfile_winid, win_getid()) 1439 1440 call StopVimInTerminal(buf) 1441 call delete('Xscript') 1442 bwipe Xtextfile 1443endfunc 1444 1445func Tapi_TryThis(bufnum, arg) 1446 let g:called_bufnum = a:bufnum 1447 let g:called_arg = a:arg 1448endfunc 1449 1450func WriteApiCall(funcname) 1451 " Use the title termcap entries to output the escape sequence. 1452 call writefile([ 1453 \ 'set title', 1454 \ 'exe "set t_ts=\<Esc>]51; t_fs=\x07"', 1455 \ 'let &titlestring = ''["call","' . a:funcname . '",["hello",123]]''', 1456 \ 'redraw', 1457 \ "set t_ts=", 1458 \ ], 'Xscript') 1459endfunc 1460 1461func Test_terminal_api_call() 1462 CheckRunVimInTerminal 1463 1464 unlet! g:called_bufnum 1465 unlet! g:called_arg 1466 1467 call WriteApiCall('Tapi_TryThis') 1468 1469 " Default 1470 let buf = RunVimInTerminal('-S Xscript', {}) 1471 call WaitFor({-> exists('g:called_bufnum')}) 1472 call assert_equal(buf, g:called_bufnum) 1473 call assert_equal(['hello', 123], g:called_arg) 1474 call StopVimInTerminal(buf) 1475 1476 unlet! g:called_bufnum 1477 unlet! g:called_arg 1478 1479 " Enable explicitly 1480 let buf = RunVimInTerminal('-S Xscript', {'term_api': 'Tapi_Try'}) 1481 call WaitFor({-> exists('g:called_bufnum')}) 1482 call assert_equal(buf, g:called_bufnum) 1483 call assert_equal(['hello', 123], g:called_arg) 1484 call StopVimInTerminal(buf) 1485 1486 unlet! g:called_bufnum 1487 unlet! g:called_arg 1488 1489 func! ApiCall_TryThis(bufnum, arg) 1490 let g:called_bufnum2 = a:bufnum 1491 let g:called_arg2 = a:arg 1492 endfunc 1493 1494 call WriteApiCall('ApiCall_TryThis') 1495 1496 " Use prefix match 1497 let buf = RunVimInTerminal('-S Xscript', {'term_api': 'ApiCall_'}) 1498 call WaitFor({-> exists('g:called_bufnum2')}) 1499 call assert_equal(buf, g:called_bufnum2) 1500 call assert_equal(['hello', 123], g:called_arg2) 1501 call StopVimInTerminal(buf) 1502 1503 call assert_fails("call term_start('ls', {'term_api' : []})", 'E475:') 1504 1505 unlet! g:called_bufnum2 1506 unlet! g:called_arg2 1507 1508 call delete('Xscript') 1509 delfunction! ApiCall_TryThis 1510 unlet! g:called_bufnum2 1511 unlet! g:called_arg2 1512endfunc 1513 1514func Test_terminal_api_call_fails() 1515 CheckRunVimInTerminal 1516 1517 func! TryThis(bufnum, arg) 1518 let g:called_bufnum3 = a:bufnum 1519 let g:called_arg3 = a:arg 1520 endfunc 1521 1522 call WriteApiCall('TryThis') 1523 1524 unlet! g:called_bufnum3 1525 unlet! g:called_arg3 1526 1527 " Not permitted 1528 call ch_logfile('Xlog', 'w') 1529 let buf = RunVimInTerminal('-S Xscript', {'term_api': ''}) 1530 call WaitForAssert({-> assert_match('Unpermitted function: TryThis', string(readfile('Xlog')))}) 1531 call assert_false(exists('g:called_bufnum3')) 1532 call assert_false(exists('g:called_arg3')) 1533 call StopVimInTerminal(buf) 1534 1535 " No match 1536 call ch_logfile('Xlog', 'w') 1537 let buf = RunVimInTerminal('-S Xscript', {'term_api': 'TryThat'}) 1538 call WaitFor({-> string(readfile('Xlog')) =~ 'Unpermitted function: TryThis'}) 1539 call assert_false(exists('g:called_bufnum3')) 1540 call assert_false(exists('g:called_arg3')) 1541 call StopVimInTerminal(buf) 1542 1543 call delete('Xscript') 1544 call ch_logfile('') 1545 call delete('Xlog') 1546 delfunction! TryThis 1547 unlet! g:called_bufnum3 1548 unlet! g:called_arg3 1549endfunc 1550 1551let s:caught_e937 = 0 1552 1553func Tapi_Delete(bufnum, arg) 1554 try 1555 execute 'bdelete!' a:bufnum 1556 catch /E937:/ 1557 let s:caught_e937 = 1 1558 endtry 1559endfunc 1560 1561func Test_terminal_api_call_fail_delete() 1562 CheckRunVimInTerminal 1563 1564 call WriteApiCall('Tapi_Delete') 1565 let buf = RunVimInTerminal('-S Xscript', {}) 1566 call WaitForAssert({-> assert_equal(1, s:caught_e937)}) 1567 1568 call StopVimInTerminal(buf) 1569 call delete('Xscript') 1570 call ch_logfile('', '') 1571endfunc 1572 1573func Test_terminal_ansicolors_default() 1574 if !exists('*term_getansicolors') 1575 throw 'Skipped: term_getansicolors() not supported' 1576 endif 1577 let colors = [ 1578 \ '#000000', '#e00000', 1579 \ '#00e000', '#e0e000', 1580 \ '#0000e0', '#e000e0', 1581 \ '#00e0e0', '#e0e0e0', 1582 \ '#808080', '#ff4040', 1583 \ '#40ff40', '#ffff40', 1584 \ '#4040ff', '#ff40ff', 1585 \ '#40ffff', '#ffffff', 1586 \] 1587 1588 let buf = Run_shell_in_terminal({}) 1589 call assert_equal(colors, term_getansicolors(buf)) 1590 call StopShellInTerminal(buf) 1591 call TermWait(buf) 1592 1593 exe buf . 'bwipe' 1594endfunc 1595 1596let s:test_colors = [ 1597 \ '#616e64', '#0d0a79', 1598 \ '#6d610d', '#0a7373', 1599 \ '#690d0a', '#6d696e', 1600 \ '#0d0a6f', '#616e0d', 1601 \ '#0a6479', '#6d0d0a', 1602 \ '#617373', '#0d0a69', 1603 \ '#6d690d', '#0a6e6f', 1604 \ '#610d0a', '#6e6479', 1605 \] 1606 1607func Test_terminal_ansicolors_global() 1608 CheckFeature termguicolors 1609 if !exists('*term_getansicolors') 1610 throw 'Skipped: term_getansicolors() not supported' 1611 endif 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 if !exists('*term_getansicolors') 1625 throw 'Skipped: term_getansicolors() not supported' 1626 endif 1627 let g:terminal_ansi_colors = reverse(copy(s:test_colors)) 1628 let buf = Run_shell_in_terminal({'ansi_colors': s:test_colors}) 1629 call assert_equal(s:test_colors, term_getansicolors(buf)) 1630 1631 call term_setansicolors(buf, g:terminal_ansi_colors) 1632 call assert_equal(g:terminal_ansi_colors, buf->term_getansicolors()) 1633 1634 let colors = [ 1635 \ 'ivory', 'AliceBlue', 1636 \ 'grey67', 'dark goldenrod', 1637 \ 'SteelBlue3', 'PaleVioletRed4', 1638 \ 'MediumPurple2', 'yellow2', 1639 \ 'RosyBrown3', 'OrangeRed2', 1640 \ 'white smoke', 'navy blue', 1641 \ 'grey47', 'gray97', 1642 \ 'MistyRose2', 'DodgerBlue4', 1643 \] 1644 eval buf->term_setansicolors(colors) 1645 1646 let colors[4] = 'Invalid' 1647 call assert_fails('call term_setansicolors(buf, colors)', 'E474:') 1648 1649 call StopShellInTerminal(buf) 1650 call TermWait(buf) 1651 exe buf . 'bwipe' 1652endfunc 1653 1654func Test_terminal_all_ansi_colors() 1655 CheckRunVimInTerminal 1656 1657 " Use all the ANSI colors. 1658 call writefile([ 1659 \ 'call setline(1, "AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPP XXYYZZ")', 1660 \ 'hi Tblack ctermfg=0 ctermbg=8', 1661 \ 'hi Tdarkred ctermfg=1 ctermbg=9', 1662 \ 'hi Tdarkgreen ctermfg=2 ctermbg=10', 1663 \ 'hi Tbrown ctermfg=3 ctermbg=11', 1664 \ 'hi Tdarkblue ctermfg=4 ctermbg=12', 1665 \ 'hi Tdarkmagenta ctermfg=5 ctermbg=13', 1666 \ 'hi Tdarkcyan ctermfg=6 ctermbg=14', 1667 \ 'hi Tlightgrey ctermfg=7 ctermbg=15', 1668 \ 'hi Tdarkgrey ctermfg=8 ctermbg=0', 1669 \ 'hi Tred ctermfg=9 ctermbg=1', 1670 \ 'hi Tgreen ctermfg=10 ctermbg=2', 1671 \ 'hi Tyellow ctermfg=11 ctermbg=3', 1672 \ 'hi Tblue ctermfg=12 ctermbg=4', 1673 \ 'hi Tmagenta ctermfg=13 ctermbg=5', 1674 \ 'hi Tcyan ctermfg=14 ctermbg=6', 1675 \ 'hi Twhite ctermfg=15 ctermbg=7', 1676 \ 'hi TdarkredBold ctermfg=1 cterm=bold', 1677 \ 'hi TgreenBold ctermfg=10 cterm=bold', 1678 \ 'hi TmagentaBold ctermfg=13 cterm=bold ctermbg=5', 1679 \ '', 1680 \ 'call matchadd("Tblack", "A")', 1681 \ 'call matchadd("Tdarkred", "B")', 1682 \ 'call matchadd("Tdarkgreen", "C")', 1683 \ 'call matchadd("Tbrown", "D")', 1684 \ 'call matchadd("Tdarkblue", "E")', 1685 \ 'call matchadd("Tdarkmagenta", "F")', 1686 \ 'call matchadd("Tdarkcyan", "G")', 1687 \ 'call matchadd("Tlightgrey", "H")', 1688 \ 'call matchadd("Tdarkgrey", "I")', 1689 \ 'call matchadd("Tred", "J")', 1690 \ 'call matchadd("Tgreen", "K")', 1691 \ 'call matchadd("Tyellow", "L")', 1692 \ 'call matchadd("Tblue", "M")', 1693 \ 'call matchadd("Tmagenta", "N")', 1694 \ 'call matchadd("Tcyan", "O")', 1695 \ 'call matchadd("Twhite", "P")', 1696 \ 'call matchadd("TdarkredBold", "X")', 1697 \ 'call matchadd("TgreenBold", "Y")', 1698 \ 'call matchadd("TmagentaBold", "Z")', 1699 \ 'redraw', 1700 \ ], 'Xcolorscript') 1701 let buf = RunVimInTerminal('-S Xcolorscript', {'rows': 10}) 1702 call VerifyScreenDump(buf, 'Test_terminal_all_ansi_colors', {}) 1703 1704 call term_sendkeys(buf, ":q\<CR>") 1705 call StopVimInTerminal(buf) 1706 call delete('Xcolorscript') 1707endfunc 1708 1709func Test_terminal_termwinsize_option_fixed() 1710 CheckRunVimInTerminal 1711 set termwinsize=6x40 1712 let text = [] 1713 for n in range(10) 1714 call add(text, repeat(n, 50)) 1715 endfor 1716 call writefile(text, 'Xwinsize') 1717 let buf = RunVimInTerminal('Xwinsize', {}) 1718 let win = bufwinid(buf) 1719 call assert_equal([6, 40], term_getsize(buf)) 1720 call assert_equal(6, winheight(win)) 1721 call assert_equal(40, winwidth(win)) 1722 1723 " resizing the window doesn't resize the terminal. 1724 resize 10 1725 vertical resize 60 1726 call assert_equal([6, 40], term_getsize(buf)) 1727 call assert_equal(10, winheight(win)) 1728 call assert_equal(60, winwidth(win)) 1729 1730 call StopVimInTerminal(buf) 1731 call delete('Xwinsize') 1732 1733 call assert_fails('set termwinsize=40', 'E474') 1734 call assert_fails('set termwinsize=10+40', 'E474') 1735 call assert_fails('set termwinsize=abc', 'E474') 1736 1737 set termwinsize= 1738endfunc 1739 1740func Test_terminal_termwinsize_option_zero() 1741 set termwinsize=0x0 1742 let buf = Run_shell_in_terminal({}) 1743 let win = bufwinid(buf) 1744 call assert_equal([winheight(win), winwidth(win)], term_getsize(buf)) 1745 call StopShellInTerminal(buf) 1746 call TermWait(buf) 1747 exe buf . 'bwipe' 1748 1749 set termwinsize=7x0 1750 let buf = Run_shell_in_terminal({}) 1751 let win = bufwinid(buf) 1752 call assert_equal([7, winwidth(win)], term_getsize(buf)) 1753 call StopShellInTerminal(buf) 1754 call TermWait(buf) 1755 exe buf . 'bwipe' 1756 1757 set termwinsize=0x33 1758 let buf = Run_shell_in_terminal({}) 1759 let win = bufwinid(buf) 1760 call assert_equal([winheight(win), 33], term_getsize(buf)) 1761 call StopShellInTerminal(buf) 1762 call TermWait(buf) 1763 exe buf . 'bwipe' 1764 1765 set termwinsize= 1766endfunc 1767 1768func Test_terminal_termwinsize_minimum() 1769 set termwinsize=10*50 1770 vsplit 1771 let buf = Run_shell_in_terminal({}) 1772 let win = bufwinid(buf) 1773 call assert_inrange(10, 1000, winheight(win)) 1774 call assert_inrange(50, 1000, winwidth(win)) 1775 call assert_equal([winheight(win), winwidth(win)], term_getsize(buf)) 1776 1777 resize 15 1778 vertical resize 60 1779 redraw 1780 call assert_equal([15, 60], term_getsize(buf)) 1781 call assert_equal(15, winheight(win)) 1782 call assert_equal(60, winwidth(win)) 1783 1784 resize 7 1785 vertical resize 30 1786 redraw 1787 call assert_equal([10, 50], term_getsize(buf)) 1788 call assert_equal(7, winheight(win)) 1789 call assert_equal(30, winwidth(win)) 1790 1791 call StopShellInTerminal(buf) 1792 call TermWait(buf) 1793 exe buf . 'bwipe' 1794 1795 set termwinsize=0*0 1796 let buf = Run_shell_in_terminal({}) 1797 let win = bufwinid(buf) 1798 call assert_equal([winheight(win), winwidth(win)], term_getsize(buf)) 1799 call StopShellInTerminal(buf) 1800 call TermWait(buf) 1801 exe buf . 'bwipe' 1802 1803 set termwinsize= 1804endfunc 1805 1806func Test_terminal_termwinkey() 1807 " make three tabpages, terminal in the middle 1808 0tabnew 1809 tabnext 1810 tabnew 1811 tabprev 1812 call assert_equal(1, winnr('$')) 1813 call assert_equal(2, tabpagenr()) 1814 let thiswin = win_getid() 1815 1816 let buf = Run_shell_in_terminal({}) 1817 let termwin = bufwinid(buf) 1818 set termwinkey=<C-L> 1819 call feedkeys("\<C-L>w", 'tx') 1820 call assert_equal(thiswin, win_getid()) 1821 call feedkeys("\<C-W>w", 'tx') 1822 call assert_equal(termwin, win_getid()) 1823 1824 if has('langmap') 1825 set langmap=xjyk 1826 call feedkeys("\<C-L>x", 'tx') 1827 call assert_equal(thiswin, win_getid()) 1828 call feedkeys("\<C-W>y", 'tx') 1829 call assert_equal(termwin, win_getid()) 1830 set langmap= 1831 endif 1832 1833 call feedkeys("\<C-L>gt", "xt") 1834 call assert_equal(3, tabpagenr()) 1835 tabprev 1836 call assert_equal(2, tabpagenr()) 1837 call assert_equal(termwin, win_getid()) 1838 1839 call feedkeys("\<C-L>gT", "xt") 1840 call assert_equal(1, tabpagenr()) 1841 tabnext 1842 call assert_equal(2, tabpagenr()) 1843 call assert_equal(termwin, win_getid()) 1844 1845 let job = term_getjob(buf) 1846 call feedkeys("\<C-L>\<C-C>", 'tx') 1847 call WaitForAssert({-> assert_equal("dead", job_status(job))}) 1848 1849 set termwinkey& 1850 tabnext 1851 tabclose 1852 tabprev 1853 tabclose 1854endfunc 1855 1856func Test_terminal_out_err() 1857 CheckUnix 1858 1859 call writefile([ 1860 \ '#!/bin/sh', 1861 \ 'echo "this is standard error" >&2', 1862 \ 'echo "this is standard out" >&1', 1863 \ ], 'Xechoerrout.sh') 1864 call setfperm('Xechoerrout.sh', 'rwxrwx---') 1865 1866 let outfile = 'Xtermstdout' 1867 let buf = term_start(['./Xechoerrout.sh'], {'out_io': 'file', 'out_name': outfile}) 1868 1869 call WaitFor({-> !empty(readfile(outfile)) && !empty(term_getline(buf, 1))}) 1870 call assert_equal(['this is standard out'], readfile(outfile)) 1871 call assert_equal('this is standard error', term_getline(buf, 1)) 1872 1873 call WaitForAssert({-> assert_equal('dead', job_status(term_getjob(buf)))}) 1874 exe buf . 'bwipe' 1875 call delete('Xechoerrout.sh') 1876 call delete(outfile) 1877endfunc 1878 1879func Test_termwinscroll() 1880 CheckUnix 1881 1882 " Let the terminal output more than 'termwinscroll' lines, some at the start 1883 " will be dropped. 1884 exe 'set termwinscroll=' . &lines 1885 let buf = term_start('/bin/sh') 1886 for i in range(1, &lines) 1887 call feedkeys("echo " . i . "\<CR>", 'xt') 1888 call WaitForAssert({-> assert_match(string(i), term_getline(buf, term_getcursor(buf)[0] - 1))}) 1889 endfor 1890 " Go to Terminal-Normal mode to update the buffer. 1891 call feedkeys("\<C-W>N", 'xt') 1892 call assert_inrange(&lines, &lines * 110 / 100 + winheight(0), line('$')) 1893 1894 " Every "echo nr" must only appear once 1895 let lines = getline(1, line('$')) 1896 for i in range(&lines - len(lines) / 2 + 2, &lines) 1897 let filtered = filter(copy(lines), {idx, val -> val =~ 'echo ' . i . '\>'}) 1898 call assert_equal(1, len(filtered), 'for "echo ' . i . '"') 1899 endfor 1900 1901 exe buf . 'bwipe!' 1902endfunc 1903 1904" Resizing the terminal window caused an ml_get error. 1905" TODO: This does not reproduce the original problem. 1906func Test_terminal_resize() 1907 set statusline=x 1908 terminal 1909 call assert_equal(2, winnr('$')) 1910 1911 " Fill the terminal with text. 1912 if has('win32') 1913 call feedkeys("dir\<CR>", 'xt') 1914 else 1915 call feedkeys("ls\<CR>", 'xt') 1916 endif 1917 " Go to Terminal-Normal mode for a moment. 1918 call feedkeys("\<C-W>N", 'xt') 1919 " Open a new window 1920 call feedkeys("i\<C-W>n", 'xt') 1921 call assert_equal(3, winnr('$')) 1922 redraw 1923 1924 close 1925 call assert_equal(2, winnr('$')) 1926 call feedkeys("exit\<CR>", 'xt') 1927 set statusline& 1928endfunc 1929 1930" must be nearly the last, we can't go back from GUI to terminal 1931func Test_zz1_terminal_in_gui() 1932 CheckCanRunGui 1933 1934 " Ignore the "failed to create input context" error. 1935 call test_ignore_error('E285:') 1936 1937 gui -f 1938 1939 call assert_equal(1, winnr('$')) 1940 let buf = Run_shell_in_terminal({'term_finish': 'close'}) 1941 call StopShellInTerminal(buf) 1942 call TermWait(buf) 1943 1944 " closing window wipes out the terminal buffer a with finished job 1945 call WaitForAssert({-> assert_equal(1, winnr('$'))}) 1946 call assert_equal("", bufname(buf)) 1947 1948 unlet g:job 1949endfunc 1950 1951func Test_zz2_terminal_guioptions_bang() 1952 CheckGui 1953 set guioptions+=! 1954 1955 let filename = 'Xtestscript' 1956 if has('win32') 1957 let filename .= '.bat' 1958 let prefix = '' 1959 let contents = ['@echo off', 'exit %1'] 1960 else 1961 let filename .= '.sh' 1962 let prefix = './' 1963 let contents = ['#!/bin/sh', 'exit $1'] 1964 endif 1965 call writefile(contents, filename) 1966 call setfperm(filename, 'rwxrwx---') 1967 1968 " Check if v:shell_error is equal to the exit status. 1969 let exitval = 0 1970 execute printf(':!%s%s %d', prefix, filename, exitval) 1971 call assert_equal(exitval, v:shell_error) 1972 1973 let exitval = 9 1974 execute printf(':!%s%s %d', prefix, filename, exitval) 1975 call assert_equal(exitval, v:shell_error) 1976 1977 set guioptions& 1978 call delete(filename) 1979endfunc 1980 1981func Test_terminal_hidden() 1982 CheckUnix 1983 1984 term ++hidden cat 1985 let bnr = bufnr('$') 1986 call assert_equal('terminal', getbufvar(bnr, '&buftype')) 1987 exe 'sbuf ' . bnr 1988 call assert_equal('terminal', &buftype) 1989 call term_sendkeys(bnr, "asdf\<CR>") 1990 call WaitForAssert({-> assert_match('asdf', term_getline(bnr, 2))}) 1991 call term_sendkeys(bnr, "\<C-D>") 1992 call WaitForAssert({-> assert_equal('finished', bnr->term_getstatus())}) 1993 bwipe! 1994endfunc 1995 1996func Test_terminal_switch_mode() 1997 term 1998 let bnr = bufnr('$') 1999 call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))}) 2000 call feedkeys("\<C-W>N", 'xt') 2001 call WaitForAssert({-> assert_equal('running,normal', term_getstatus(bnr))}) 2002 call feedkeys("A", 'xt') 2003 call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))}) 2004 call feedkeys("\<C-W>N", 'xt') 2005 call WaitForAssert({-> assert_equal('running,normal', term_getstatus(bnr))}) 2006 call feedkeys("I", 'xt') 2007 call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))}) 2008 call feedkeys("\<C-W>Nv", 'xt') 2009 call WaitForAssert({-> assert_equal('running,normal', term_getstatus(bnr))}) 2010 call feedkeys("I", 'xt') 2011 call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))}) 2012 call feedkeys("\<C-W>Nv", 'xt') 2013 call WaitForAssert({-> assert_equal('running,normal', term_getstatus(bnr))}) 2014 call feedkeys("A", 'xt') 2015 call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))}) 2016 bwipe! 2017endfunc 2018 2019func Test_terminal_normal_mode() 2020 CheckRunVimInTerminal 2021 2022 " Run Vim in a terminal and open a terminal window to run Vim in. 2023 let lines =<< trim END 2024 call setline(1, range(11111, 11122)) 2025 3 2026 END 2027 call writefile(lines, 'XtermNormal') 2028 let buf = RunVimInTerminal('-S XtermNormal', {'rows': 8}) 2029 call TermWait(buf) 2030 2031 call term_sendkeys(buf, "\<C-W>N") 2032 call term_sendkeys(buf, ":set number cursorline culopt=both\r") 2033 call VerifyScreenDump(buf, 'Test_terminal_normal_1', {}) 2034 2035 call term_sendkeys(buf, ":set culopt=number\r") 2036 call VerifyScreenDump(buf, 'Test_terminal_normal_2', {}) 2037 2038 call term_sendkeys(buf, ":set culopt=line\r") 2039 call VerifyScreenDump(buf, 'Test_terminal_normal_3', {}) 2040 2041 call term_sendkeys(buf, "a:q!\<CR>:q\<CR>:q\<CR>") 2042 call StopVimInTerminal(buf) 2043 call delete('XtermNormal') 2044endfunc 2045 2046func Test_terminal_hidden_and_close() 2047 CheckUnix 2048 2049 call assert_equal(1, winnr('$')) 2050 term ++hidden ++close ls 2051 let bnr = bufnr('$') 2052 call assert_equal('terminal', getbufvar(bnr, '&buftype')) 2053 call WaitForAssert({-> assert_false(bufexists(bnr))}) 2054 call assert_equal(1, winnr('$')) 2055endfunc 2056 2057func Test_terminal_does_not_truncate_last_newlines() 2058 " This test does not pass through ConPTY. 2059 if has('conpty') 2060 return 2061 endif 2062 let contents = [ 2063 \ [ 'One', '', 'X' ], 2064 \ [ 'Two', '', '' ], 2065 \ [ 'Three' ] + repeat([''], 30) 2066 \ ] 2067 2068 for c in contents 2069 call writefile(c, 'Xfile') 2070 if has('win32') 2071 term cmd /c type Xfile 2072 else 2073 term cat Xfile 2074 endif 2075 let bnr = bufnr('$') 2076 call assert_equal('terminal', getbufvar(bnr, '&buftype')) 2077 call WaitForAssert({-> assert_equal('finished', term_getstatus(bnr))}) 2078 sleep 100m 2079 call assert_equal(c, getline(1, line('$'))) 2080 quit 2081 endfor 2082 2083 call delete('Xfile') 2084endfunc 2085 2086func Test_terminal_no_job() 2087 if has('win32') 2088 let cmd = 'cmd /c ""' 2089 else 2090 CheckExecutable false 2091 let cmd = 'false' 2092 endif 2093 let term = term_start(cmd, {'term_finish': 'close'}) 2094 call WaitForAssert({-> assert_equal(v:null, term_getjob(term)) }) 2095endfunc 2096 2097func Test_term_getcursor() 2098 CheckUnix 2099 2100 let buf = Run_shell_in_terminal({}) 2101 2102 " Wait for the shell to display a prompt. 2103 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))}) 2104 2105 " Hide the cursor. 2106 call term_sendkeys(buf, "echo -e '\\033[?25l'\r") 2107 call WaitForAssert({-> assert_equal(0, term_getcursor(buf)[2].visible)}) 2108 2109 " Show the cursor. 2110 call term_sendkeys(buf, "echo -e '\\033[?25h'\r") 2111 call WaitForAssert({-> assert_equal(1, buf->term_getcursor()[2].visible)}) 2112 2113 " Change color of cursor. 2114 call WaitForAssert({-> assert_equal('', term_getcursor(buf)[2].color)}) 2115 call term_sendkeys(buf, "echo -e '\\033]12;blue\\007'\r") 2116 call WaitForAssert({-> assert_equal('blue', term_getcursor(buf)[2].color)}) 2117 call term_sendkeys(buf, "echo -e '\\033]12;green\\007'\r") 2118 call WaitForAssert({-> assert_equal('green', term_getcursor(buf)[2].color)}) 2119 2120 " Make cursor a blinking block. 2121 call term_sendkeys(buf, "echo -e '\\033[1 q'\r") 2122 call WaitForAssert({-> assert_equal([1, 1], 2123 \ [term_getcursor(buf)[2].blink, term_getcursor(buf)[2].shape])}) 2124 2125 " Make cursor a steady block. 2126 call term_sendkeys(buf, "echo -e '\\033[2 q'\r") 2127 call WaitForAssert({-> assert_equal([0, 1], 2128 \ [term_getcursor(buf)[2].blink, term_getcursor(buf)[2].shape])}) 2129 2130 " Make cursor a blinking underline. 2131 call term_sendkeys(buf, "echo -e '\\033[3 q'\r") 2132 call WaitForAssert({-> assert_equal([1, 2], 2133 \ [term_getcursor(buf)[2].blink, term_getcursor(buf)[2].shape])}) 2134 2135 " Make cursor a steady underline. 2136 call term_sendkeys(buf, "echo -e '\\033[4 q'\r") 2137 call WaitForAssert({-> assert_equal([0, 2], 2138 \ [term_getcursor(buf)[2].blink, term_getcursor(buf)[2].shape])}) 2139 2140 " Make cursor a blinking vertical bar. 2141 call term_sendkeys(buf, "echo -e '\\033[5 q'\r") 2142 call WaitForAssert({-> assert_equal([1, 3], 2143 \ [term_getcursor(buf)[2].blink, term_getcursor(buf)[2].shape])}) 2144 2145 " Make cursor a steady vertical bar. 2146 call term_sendkeys(buf, "echo -e '\\033[6 q'\r") 2147 call WaitForAssert({-> assert_equal([0, 3], 2148 \ [term_getcursor(buf)[2].blink, term_getcursor(buf)[2].shape])}) 2149 2150 call StopShellInTerminal(buf) 2151endfunc 2152 2153func Test_term_gettitle() 2154 " term_gettitle() returns an empty string for a non-terminal buffer 2155 " and for a non-existing buffer. 2156 call assert_equal('', bufnr('%')->term_gettitle()) 2157 call assert_equal('', term_gettitle(bufnr('$') + 1)) 2158 2159 if !has('title') || &title == 0 || empty(&t_ts) 2160 throw "Skipped: can't get/set title" 2161 endif 2162 2163 let term = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile']) 2164 if has('autoservername') 2165 call WaitForAssert({-> assert_match('^\[No Name\] - VIM\d\+$', term_gettitle(term)) }) 2166 call term_sendkeys(term, ":e Xfoo\r") 2167 call WaitForAssert({-> assert_match('^Xfoo (.*[/\\]testdir) - VIM\d\+$', term_gettitle(term)) }) 2168 else 2169 call WaitForAssert({-> assert_equal('[No Name] - VIM', term_gettitle(term)) }) 2170 call term_sendkeys(term, ":e Xfoo\r") 2171 call WaitForAssert({-> assert_match('^Xfoo (.*[/\\]testdir) - VIM$', term_gettitle(term)) }) 2172 endif 2173 2174 call term_sendkeys(term, ":set titlestring=foo\r") 2175 call WaitForAssert({-> assert_equal('foo', term_gettitle(term)) }) 2176 2177 exe term . 'bwipe!' 2178endfunc 2179 2180func Test_term_gettty() 2181 let buf = Run_shell_in_terminal({}) 2182 let gettty = term_gettty(buf) 2183 2184 if has('unix') && executable('tty') 2185 " Find tty using the tty shell command. 2186 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))}) 2187 call term_sendkeys(buf, "tty\r") 2188 call WaitForAssert({-> assert_notequal('', term_getline(buf, 3))}) 2189 let tty = term_getline(buf, 2) 2190 call assert_equal(tty, gettty) 2191 endif 2192 2193 let gettty0 = term_gettty(buf, 0) 2194 let gettty1 = term_gettty(buf, 1) 2195 2196 call assert_equal(gettty, gettty0) 2197 call assert_equal(job_info(g:job).tty_out, gettty0) 2198 call assert_equal(job_info(g:job).tty_in, gettty1) 2199 2200 if has('unix') 2201 " For unix, term_gettty(..., 0) and term_gettty(..., 1) 2202 " are identical according to :help term_gettty() 2203 call assert_equal(gettty0, gettty1) 2204 call assert_match('^/dev/', gettty) 2205 else 2206 " ConPTY works on anonymous pipe. 2207 if !has('conpty') 2208 call assert_match('^\\\\.\\pipe\\', gettty0) 2209 call assert_match('^\\\\.\\pipe\\', gettty1) 2210 endif 2211 endif 2212 2213 call assert_fails('call term_gettty(buf, 2)', 'E475:') 2214 call assert_fails('call term_gettty(buf, -1)', 'E475:') 2215 2216 call assert_equal('', term_gettty(buf + 1)) 2217 2218 call StopShellInTerminal(buf) 2219 call TermWait(buf) 2220 exe buf . 'bwipe' 2221endfunc 2222 2223" When drawing the statusline the cursor position may not have been updated 2224" yet. 2225" 1. create a terminal, make it show 2 lines 2226" 2. 0.5 sec later: leave terminal window, execute "i" 2227" 3. 0.5 sec later: clear terminal window, now it's 1 line 2228" 4. 0.5 sec later: redraw, including statusline (used to trigger bug) 2229" 4. 0.5 sec later: should be done, clean up 2230func Test_terminal_statusline() 2231 CheckUnix 2232 2233 set statusline=x 2234 terminal 2235 let tbuf = bufnr('') 2236 call term_sendkeys(tbuf, "clear; echo a; echo b; sleep 1; clear\n") 2237 call timer_start(500, { tid -> feedkeys("\<C-w>j", 'tx') }) 2238 call timer_start(1500, { tid -> feedkeys("\<C-l>", 'tx') }) 2239 au BufLeave * if &buftype == 'terminal' | silent! normal i | endif 2240 2241 sleep 2 2242 exe tbuf . 'bwipe!' 2243 au! BufLeave 2244 set statusline= 2245endfunc 2246 2247func Test_terminal_getwinpos() 2248 CheckRunVimInTerminal 2249 2250 " split, go to the bottom-right window 2251 split 2252 wincmd j 2253 set splitright 2254 2255 call writefile([ 2256 \ 'echo getwinpos()', 2257 \ ], 'XTest_getwinpos') 2258 let buf = RunVimInTerminal('-S XTest_getwinpos', {'cols': 60}) 2259 call TermWait(buf) 2260 2261 " Find the output of getwinpos() in the bottom line. 2262 let rows = term_getsize(buf)[0] 2263 call WaitForAssert({-> assert_match('\[\d\+, \d\+\]', term_getline(buf, rows))}) 2264 let line = term_getline(buf, rows) 2265 let xpos = str2nr(substitute(line, '\[\(\d\+\), \d\+\]', '\1', '')) 2266 let ypos = str2nr(substitute(line, '\[\d\+, \(\d\+\)\]', '\1', '')) 2267 2268 " Position must be bigger than the getwinpos() result of Vim itself. 2269 " The calculation in the console assumes a 10 x 7 character cell. 2270 " In the GUI it can be more, let's assume a 20 x 14 cell. 2271 " And then add 100 / 200 tolerance. 2272 let [xroot, yroot] = getwinpos() 2273 let winpos = 50->getwinpos() 2274 call assert_equal(xroot, winpos[0]) 2275 call assert_equal(yroot, winpos[1]) 2276 let [winrow, wincol] = win_screenpos('.') 2277 let xoff = wincol * (has('gui_running') ? 14 : 7) + 100 2278 let yoff = winrow * (has('gui_running') ? 20 : 10) + 200 2279 call assert_inrange(xroot + 2, xroot + xoff, xpos) 2280 call assert_inrange(yroot + 2, yroot + yoff, ypos) 2281 2282 call TermWait(buf) 2283 call term_sendkeys(buf, ":q\<CR>") 2284 call StopVimInTerminal(buf) 2285 call delete('XTest_getwinpos') 2286 exe buf . 'bwipe!' 2287 set splitright& 2288 only! 2289endfunc 2290 2291func Test_terminal_altscreen() 2292 " somehow doesn't work on MS-Windows 2293 CheckUnix 2294 let cmd = "cat Xtext\<CR>" 2295 2296 let buf = term_start(&shell, {}) 2297 call writefile(["\<Esc>[?1047h"], 'Xtext') 2298 call term_sendkeys(buf, cmd) 2299 call WaitForAssert({-> assert_equal(1, term_getaltscreen(buf))}) 2300 2301 call writefile(["\<Esc>[?1047l"], 'Xtext') 2302 call term_sendkeys(buf, cmd) 2303 call WaitForAssert({-> assert_equal(0, term_getaltscreen(buf))}) 2304 2305 call term_sendkeys(buf, "exit\r") 2306 exe buf . "bwipe!" 2307 call delete('Xtext') 2308endfunc 2309 2310func Test_terminal_shell_option() 2311 if has('unix') 2312 " exec is a shell builtin command, should fail without a shell. 2313 term exec ls runtest.vim 2314 call WaitForAssert({-> assert_match('job failed', term_getline(bufnr(), 1))}) 2315 bwipe! 2316 2317 term ++shell exec ls runtest.vim 2318 call WaitForAssert({-> assert_match('runtest.vim', term_getline(bufnr(), 1))}) 2319 bwipe! 2320 elseif has('win32') 2321 " dir is a shell builtin command, should fail without a shell. 2322 try 2323 term dir /b runtest.vim 2324 call WaitForAssert({-> assert_match('job failed\|cannot access .*: No such file or directory', term_getline(bufnr(), 1))}) 2325 catch /CreateProcess/ 2326 " ignore 2327 endtry 2328 bwipe! 2329 2330 term ++shell dir /b runtest.vim 2331 call WaitForAssert({-> assert_match('runtest.vim', term_getline(bufnr(), 1))}) 2332 bwipe! 2333 endif 2334endfunc 2335 2336func Test_terminal_setapi_and_call() 2337 CheckRunVimInTerminal 2338 2339 call WriteApiCall('Tapi_TryThis') 2340 call ch_logfile('Xlog', 'w') 2341 2342 unlet! g:called_bufnum 2343 unlet! g:called_arg 2344 2345 let buf = RunVimInTerminal('-S Xscript', {'term_api': ''}) 2346 call WaitForAssert({-> assert_match('Unpermitted function: Tapi_TryThis', string(readfile('Xlog')))}) 2347 call assert_false(exists('g:called_bufnum')) 2348 call assert_false(exists('g:called_arg')) 2349 2350 eval buf->term_setapi('Tapi_') 2351 call term_sendkeys(buf, ":set notitle\<CR>") 2352 call term_sendkeys(buf, ":source Xscript\<CR>") 2353 call WaitFor({-> exists('g:called_bufnum')}) 2354 call assert_equal(buf, g:called_bufnum) 2355 call assert_equal(['hello', 123], g:called_arg) 2356 2357 call StopVimInTerminal(buf) 2358 2359 call delete('Xscript') 2360 call ch_logfile('') 2361 call delete('Xlog') 2362 unlet! g:called_bufnum 2363 unlet! g:called_arg 2364endfunc 2365 2366func Test_terminal_api_arg() 2367 CheckRunVimInTerminal 2368 2369 call WriteApiCall('Tapi_TryThis') 2370 call ch_logfile('Xlog', 'w') 2371 2372 unlet! g:called_bufnum 2373 unlet! g:called_arg 2374 2375 execute 'term ++api= ' .. GetVimCommandCleanTerm() .. '-S Xscript' 2376 let buf = bufnr('%') 2377 call WaitForAssert({-> assert_match('Unpermitted function: Tapi_TryThis', string(readfile('Xlog')))}) 2378 call assert_false(exists('g:called_bufnum')) 2379 call assert_false(exists('g:called_arg')) 2380 2381 call StopVimInTerminal(buf) 2382 2383 call ch_logfile('Xlog', 'w') 2384 2385 execute 'term ++api=Tapi_ ' .. GetVimCommandCleanTerm() .. '-S Xscript' 2386 let buf = bufnr('%') 2387 call WaitFor({-> exists('g:called_bufnum')}) 2388 call assert_equal(buf, g:called_bufnum) 2389 call assert_equal(['hello', 123], g:called_arg) 2390 2391 call StopVimInTerminal(buf) 2392 2393 call delete('Xscript') 2394 call ch_logfile('') 2395 call delete('Xlog') 2396 unlet! g:called_bufnum 2397 unlet! g:called_arg 2398endfunc 2399 2400func Test_terminal_invalid_arg() 2401 call assert_fails('terminal ++xyz', 'E181:') 2402endfunc 2403 2404func Test_terminal_in_popup() 2405 CheckRunVimInTerminal 2406 2407 let text =<< trim END 2408 some text 2409 to edit 2410 in a popup window 2411 END 2412 call writefile(text, 'Xtext') 2413 let cmd = GetVimCommandCleanTerm() 2414 let lines = [ 2415 \ 'set t_u7=', 2416 \ 'call setline(1, range(20))', 2417 \ 'hi PopTerm ctermbg=grey', 2418 \ 'func OpenTerm(setColor)', 2419 \ " set noruler", 2420 \ " let s:buf = term_start('" .. cmd .. " Xtext', #{hidden: 1, term_finish: 'close'})", 2421 \ ' let g:winid = popup_create(s:buf, #{minwidth: 45, minheight: 7, border: [], drag: 1, resize: 1})', 2422 \ ' if a:setColor', 2423 \ ' call win_execute(g:winid, "set wincolor=PopTerm")', 2424 \ ' endif', 2425 \ 'endfunc', 2426 \ 'func HidePopup()', 2427 \ ' call popup_hide(g:winid)', 2428 \ 'endfunc', 2429 \ 'func ClosePopup()', 2430 \ ' call popup_close(g:winid)', 2431 \ 'endfunc', 2432 \ 'func ReopenPopup()', 2433 \ ' call popup_create(s:buf, #{minwidth: 40, minheight: 6, border: []})', 2434 \ 'endfunc', 2435 \ ] 2436 call writefile(lines, 'XtermPopup') 2437 let buf = RunVimInTerminal('-S XtermPopup', #{rows: 15}) 2438 call TermWait(buf, 100) 2439 call term_sendkeys(buf, ":call OpenTerm(0)\<CR>") 2440 call TermWait(buf, 100) 2441 call term_sendkeys(buf, ":\<CR>") 2442 call TermWait(buf, 100) 2443 call term_sendkeys(buf, "\<C-W>:echo getwinvar(g:winid, \"&buftype\") win_gettype(g:winid)\<CR>") 2444 call VerifyScreenDump(buf, 'Test_terminal_popup_1', {}) 2445 2446 call term_sendkeys(buf, ":q\<CR>") 2447 call VerifyScreenDump(buf, 'Test_terminal_popup_2', {}) 2448 2449 call term_sendkeys(buf, ":call OpenTerm(1)\<CR>") 2450 call TermWait(buf, 150) 2451 call term_sendkeys(buf, ":set hlsearch\<CR>") 2452 call term_sendkeys(buf, "/edit\<CR>") 2453 call VerifyScreenDump(buf, 'Test_terminal_popup_3', {}) 2454 2455 call term_sendkeys(buf, "\<C-W>:call HidePopup()\<CR>") 2456 call VerifyScreenDump(buf, 'Test_terminal_popup_4', {}) 2457 call term_sendkeys(buf, "\<CR>") 2458 call TermWait(buf, 50) 2459 2460 call term_sendkeys(buf, "\<C-W>:call ClosePopup()\<CR>") 2461 call VerifyScreenDump(buf, 'Test_terminal_popup_5', {}) 2462 2463 call term_sendkeys(buf, "\<C-W>:call ReopenPopup()\<CR>") 2464 call VerifyScreenDump(buf, 'Test_terminal_popup_6', {}) 2465 2466 " Go to terminal-Normal mode and visually select text. 2467 call term_sendkeys(buf, "\<C-W>Ngg/in\<CR>vww") 2468 call VerifyScreenDump(buf, 'Test_terminal_popup_7', {}) 2469 2470 " Back to job mode, redraws 2471 call term_sendkeys(buf, "A") 2472 call VerifyScreenDump(buf, 'Test_terminal_popup_8', {}) 2473 2474 call TermWait(buf, 50) 2475 call term_sendkeys(buf, ":q\<CR>") 2476 call TermWait(buf, 100) " wait for terminal to vanish 2477 2478 call StopVimInTerminal(buf) 2479 call delete('Xtext') 2480 call delete('XtermPopup') 2481endfunc 2482 2483" Check a terminal in popup window uses the default mininum size. 2484func Test_terminal_in_popup_min_size() 2485 CheckRunVimInTerminal 2486 2487 let text =<< trim END 2488 another text 2489 to show 2490 in a popup window 2491 END 2492 call writefile(text, 'Xtext') 2493 let lines = [ 2494 \ 'set t_u7=', 2495 \ 'call setline(1, range(20))', 2496 \ 'func OpenTerm()', 2497 \ " let s:buf = term_start('cat Xtext', #{hidden: 1})", 2498 \ ' let g:winid = popup_create(s:buf, #{ border: []})', 2499 \ 'endfunc', 2500 \ ] 2501 call writefile(lines, 'XtermPopup') 2502 let buf = RunVimInTerminal('-S XtermPopup', #{rows: 15}) 2503 call TermWait(buf, 100) 2504 call term_sendkeys(buf, ":set noruler\<CR>") 2505 call term_sendkeys(buf, ":call OpenTerm()\<CR>") 2506 call TermWait(buf, 50) 2507 call term_sendkeys(buf, ":\<CR>") 2508 call VerifyScreenDump(buf, 'Test_terminal_popup_m1', {}) 2509 2510 call TermWait(buf, 50) 2511 call term_sendkeys(buf, ":q\<CR>") 2512 call TermWait(buf, 50) " wait for terminal to vanish 2513 call StopVimInTerminal(buf) 2514 call delete('Xtext') 2515 call delete('XtermPopup') 2516endfunc 2517 2518" Check a terminal in popup window with different colors 2519func Terminal_in_popup_colored(group_name, highlight_cmd, highlight_opt) 2520 CheckRunVimInTerminal 2521 CheckUnix 2522 2523 let lines = [ 2524 \ 'set t_u7=', 2525 \ 'call setline(1, range(20))', 2526 \ 'func OpenTerm()', 2527 \ " let s:buf = term_start('cat', #{hidden: 1, " 2528 \ .. a:highlight_opt .. "})", 2529 \ ' let g:winid = popup_create(s:buf, #{ border: []})', 2530 \ 'endfunc', 2531 \ a:highlight_cmd, 2532 \ ] 2533 call writefile(lines, 'XtermPopup') 2534 let buf = RunVimInTerminal('-S XtermPopup', #{rows: 15}) 2535 call TermWait(buf, 100) 2536 call term_sendkeys(buf, ":set noruler\<CR>") 2537 call term_sendkeys(buf, ":call OpenTerm()\<CR>") 2538 call TermWait(buf, 50) 2539 call term_sendkeys(buf, "hello\<CR>") 2540 call VerifyScreenDump(buf, 'Test_terminal_popup_' .. a:group_name, {}) 2541 2542 call term_sendkeys(buf, "\<C-D>") 2543 call TermWait(buf, 50) 2544 call term_sendkeys(buf, ":q\<CR>") 2545 call TermWait(buf, 50) " wait for terminal to vanish 2546 call StopVimInTerminal(buf) 2547 call delete('XtermPopup') 2548endfunc 2549 2550func Test_terminal_in_popup_colored_Terminal() 2551 call Terminal_in_popup_colored("Terminal", "highlight Terminal ctermfg=blue ctermbg=yellow", "") 2552endfunc 2553 2554func Test_terminal_in_popup_colored_group() 2555 call Terminal_in_popup_colored("MyTermCol", "highlight MyTermCol ctermfg=darkgreen ctermbg=lightblue", "term_highlight: 'MyTermCol',") 2556endfunc 2557 2558func Test_double_popup_terminal() 2559 let buf1 = term_start(&shell, #{hidden: 1}) 2560 let win1 = popup_create(buf1, {}) 2561 let buf2 = term_start(&shell, #{hidden: 1}) 2562 let win2 = popup_create(buf2, {}) 2563 call popup_close(win1) 2564 call popup_close(win2) 2565 exe buf1 .. 'bwipe!' 2566 exe buf2 .. 'bwipe!' 2567endfunc 2568 2569func Test_issue_5607() 2570 let wincount = winnr('$') 2571 exe 'terminal' &shell &shellcmdflag 'exit' 2572 let job = term_getjob(bufnr()) 2573 call WaitForAssert({-> assert_equal("dead", job_status(job))}) 2574 2575 let old_wincolor = &wincolor 2576 try 2577 set wincolor= 2578 finally 2579 let &wincolor = old_wincolor 2580 bw! 2581 endtry 2582endfunc 2583 2584func Test_hidden_terminal() 2585 let buf = term_start(&shell, #{hidden: 1}) 2586 call assert_equal('', bufname('^$')) 2587 call StopShellInTerminal(buf) 2588endfunc 2589 2590func Test_term_nasty_callback() 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 2615" vim: shiftwidth=2 sts=2 expandtab 2616