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