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