blob: d2fc4fc398ee66b4644bd8a28454bb319b414b77 [file] [log] [blame]
Bram Moolenaar1112c0f2020-07-01 21:53:50 +02001" Tests for the terminal window.
2" This is split in two, because it can take a lot of time.
Bram Moolenaar18aa13d2020-07-11 13:09:36 +02003" See test_terminal.vim and test_terminal3.vim for further tests.
Bram Moolenaar1112c0f2020-07-01 21:53:50 +02004
Bram Moolenaar1112c0f2020-07-01 21:53:50 +02005CheckFeature terminal
6
Christian Brabandteb380b92025-07-07 20:53:55 +02007source util/screendump.vim
8source util/mouse.vim
Bram Moolenaar1112c0f2020-07-01 21:53:50 +02009
Bram Moolenaar1112c0f2020-07-01 21:53:50 +020010let $PROMPT_COMMAND=''
11
Bram Moolenaar1112c0f2020-07-01 21:53:50 +020012func Test_terminal_termwinsize_option_fixed()
13 CheckRunVimInTerminal
14 set termwinsize=6x40
15 let text = []
16 for n in range(10)
17 call add(text, repeat(n, 50))
18 endfor
Bram Moolenaarc4860bd2022-10-15 20:52:26 +010019 call writefile(text, 'Xwinsize', 'D')
Bram Moolenaar1112c0f2020-07-01 21:53:50 +020020 let buf = RunVimInTerminal('Xwinsize', {})
21 let win = bufwinid(buf)
22 call assert_equal([6, 40], term_getsize(buf))
23 call assert_equal(6, winheight(win))
24 call assert_equal(40, winwidth(win))
25
26 " resizing the window doesn't resize the terminal.
27 resize 10
28 vertical resize 60
29 call assert_equal([6, 40], term_getsize(buf))
30 call assert_equal(10, winheight(win))
31 call assert_equal(60, winwidth(win))
32
33 call StopVimInTerminal(buf)
Bram Moolenaar1112c0f2020-07-01 21:53:50 +020034
Bram Moolenaare2e40752020-09-04 21:18:46 +020035 call assert_fails('set termwinsize=40', 'E474:')
36 call assert_fails('set termwinsize=10+40', 'E474:')
37 call assert_fails('set termwinsize=abc', 'E474:')
Bram Moolenaar1112c0f2020-07-01 21:53:50 +020038
39 set termwinsize=
40endfunc
41
42func Test_terminal_termwinsize_option_zero()
43 set termwinsize=0x0
44 let buf = Run_shell_in_terminal({})
45 let win = bufwinid(buf)
46 call assert_equal([winheight(win), winwidth(win)], term_getsize(buf))
47 call StopShellInTerminal(buf)
Bram Moolenaar1112c0f2020-07-01 21:53:50 +020048 exe buf . 'bwipe'
49
50 set termwinsize=7x0
51 let buf = Run_shell_in_terminal({})
52 let win = bufwinid(buf)
53 call assert_equal([7, winwidth(win)], term_getsize(buf))
54 call StopShellInTerminal(buf)
Bram Moolenaar1112c0f2020-07-01 21:53:50 +020055 exe buf . 'bwipe'
56
57 set termwinsize=0x33
58 let buf = Run_shell_in_terminal({})
59 let win = bufwinid(buf)
60 call assert_equal([winheight(win), 33], term_getsize(buf))
61 call StopShellInTerminal(buf)
Bram Moolenaar1112c0f2020-07-01 21:53:50 +020062 exe buf . 'bwipe'
63
Christian Brabandtaa64ba12023-09-19 21:05:20 +020064 " This used to crash Vim
65 set termwinsize=10000*10000
66 let buf = Run_shell_in_terminal({})
67 let win = bufwinid(buf)
68 call assert_equal([1000, 1000], term_getsize(buf))
69 call StopShellInTerminal(buf)
70 exe buf . 'bwipe'
71
Bram Moolenaar1112c0f2020-07-01 21:53:50 +020072 set termwinsize=
73endfunc
74
75func Test_terminal_termwinsize_minimum()
76 set termwinsize=10*50
77 vsplit
78 let buf = Run_shell_in_terminal({})
79 let win = bufwinid(buf)
80 call assert_inrange(10, 1000, winheight(win))
81 call assert_inrange(50, 1000, winwidth(win))
82 call assert_equal([winheight(win), winwidth(win)], term_getsize(buf))
83
84 resize 15
85 vertical resize 60
86 redraw
87 call assert_equal([15, 60], term_getsize(buf))
88 call assert_equal(15, winheight(win))
89 call assert_equal(60, winwidth(win))
90
91 resize 7
92 vertical resize 30
93 redraw
94 call assert_equal([10, 50], term_getsize(buf))
95 call assert_equal(7, winheight(win))
96 call assert_equal(30, winwidth(win))
97
98 call StopShellInTerminal(buf)
Bram Moolenaar1112c0f2020-07-01 21:53:50 +020099 exe buf . 'bwipe'
100
101 set termwinsize=0*0
102 let buf = Run_shell_in_terminal({})
103 let win = bufwinid(buf)
104 call assert_equal([winheight(win), winwidth(win)], term_getsize(buf))
105 call StopShellInTerminal(buf)
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200106 exe buf . 'bwipe'
107
108 set termwinsize=
109endfunc
110
Bram Moolenaarb936b792020-09-04 18:34:09 +0200111func Test_terminal_termwinsize_overruled()
112 let cmd = GetDummyCmd()
113 set termwinsize=5x43
114 let buf = term_start(cmd, #{term_rows: 7, term_cols: 50})
115 call TermWait(buf)
116 call assert_equal([7, 50], term_getsize(buf))
117 exe "bwipe! " .. buf
118
119 let buf = term_start(cmd, #{term_cols: 50})
120 call TermWait(buf)
121 call assert_equal([5, 50], term_getsize(buf))
122 exe "bwipe! " .. buf
123
124 let buf = term_start(cmd, #{term_rows: 7})
125 call TermWait(buf)
126 call assert_equal([7, 43], term_getsize(buf))
127 exe "bwipe! " .. buf
128
129 set termwinsize=
130endfunc
131
Bram Moolenaar2ce14582020-09-05 16:08:49 +0200132" hidden terminal must not change current window size
133func Test_terminal_hidden_winsize()
134 let cmd = GetDummyCmd()
135 let rows = winheight(0)
136 let buf = term_start(cmd, #{hidden: 1, term_rows: 10})
Yegappan Lakshmanane446a012023-01-19 17:49:58 +0000137 call TermWait(buf)
Bram Moolenaar2ce14582020-09-05 16:08:49 +0200138 call assert_equal(rows, winheight(0))
139 call assert_equal([10, &columns], term_getsize(buf))
140 exe "bwipe! " .. buf
141endfunc
142
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200143func Test_terminal_termwinkey()
144 " make three tabpages, terminal in the middle
145 0tabnew
146 tabnext
147 tabnew
148 tabprev
149 call assert_equal(1, winnr('$'))
150 call assert_equal(2, tabpagenr())
151 let thiswin = win_getid()
152
153 let buf = Run_shell_in_terminal({})
154 let termwin = bufwinid(buf)
155 set termwinkey=<C-L>
156 call feedkeys("\<C-L>w", 'tx')
157 call assert_equal(thiswin, win_getid())
158 call feedkeys("\<C-W>w", 'tx')
159 call assert_equal(termwin, win_getid())
160
161 if has('langmap')
162 set langmap=xjyk
163 call feedkeys("\<C-L>x", 'tx')
164 call assert_equal(thiswin, win_getid())
165 call feedkeys("\<C-W>y", 'tx')
166 call assert_equal(termwin, win_getid())
167 set langmap=
168 endif
169
170 call feedkeys("\<C-L>gt", "xt")
171 call assert_equal(3, tabpagenr())
172 tabprev
173 call assert_equal(2, tabpagenr())
174 call assert_equal(termwin, win_getid())
175
176 call feedkeys("\<C-L>gT", "xt")
177 call assert_equal(1, tabpagenr())
178 tabnext
179 call assert_equal(2, tabpagenr())
180 call assert_equal(termwin, win_getid())
181
182 let job = term_getjob(buf)
183 call feedkeys("\<C-L>\<C-C>", 'tx')
184 call WaitForAssert({-> assert_equal("dead", job_status(job))})
185
186 set termwinkey&
187 tabnext
188 tabclose
189 tabprev
190 tabclose
191endfunc
192
193func Test_terminal_out_err()
194 CheckUnix
195
196 call writefile([
197 \ '#!/bin/sh',
198 \ 'echo "this is standard error" >&2',
199 \ 'echo "this is standard out" >&1',
Bram Moolenaarc4860bd2022-10-15 20:52:26 +0100200 \ ], 'Xechoerrout.sh', 'D')
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200201 call setfperm('Xechoerrout.sh', 'rwxrwx---')
202
203 let outfile = 'Xtermstdout'
204 let buf = term_start(['./Xechoerrout.sh'], {'out_io': 'file', 'out_name': outfile})
Yegappan Lakshmanane446a012023-01-19 17:49:58 +0000205 call TermWait(buf)
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200206
207 call WaitFor({-> !empty(readfile(outfile)) && !empty(term_getline(buf, 1))})
208 call assert_equal(['this is standard out'], readfile(outfile))
209 call assert_equal('this is standard error', term_getline(buf, 1))
210
211 call WaitForAssert({-> assert_equal('dead', job_status(term_getjob(buf)))})
212 exe buf . 'bwipe'
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200213 call delete(outfile)
214endfunc
215
216func Test_termwinscroll()
217 CheckUnix
Bram Moolenaarf65927f2020-07-11 14:04:28 +0200218 " TODO: Somehow this test sometimes hangs in the GUI
219 CheckNotGui
Bram Moolenaarf08b0eb2021-10-16 13:00:14 +0100220 let g:test_is_flaky = 1
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200221
222 " Let the terminal output more than 'termwinscroll' lines, some at the start
223 " will be dropped.
224 exe 'set termwinscroll=' . &lines
225 let buf = term_start('/bin/sh')
Yegappan Lakshmanane446a012023-01-19 17:49:58 +0000226 call TermWait(buf)
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200227 for i in range(1, &lines)
228 call feedkeys("echo " . i . "\<CR>", 'xt')
229 call WaitForAssert({-> assert_match(string(i), term_getline(buf, term_getcursor(buf)[0] - 1))})
230 endfor
231 " Go to Terminal-Normal mode to update the buffer.
232 call feedkeys("\<C-W>N", 'xt')
233 call assert_inrange(&lines, &lines * 110 / 100 + winheight(0), line('$'))
234
235 " Every "echo nr" must only appear once
236 let lines = getline(1, line('$'))
237 for i in range(&lines - len(lines) / 2 + 2, &lines)
238 let filtered = filter(copy(lines), {idx, val -> val =~ 'echo ' . i . '\>'})
239 call assert_equal(1, len(filtered), 'for "echo ' . i . '"')
240 endfor
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200241 exe buf . 'bwipe!'
242endfunc
243
h-east3a3a2c92024-12-15 19:36:11 +0100244func Test_termwinscroll_topline()
Christian Brabandta74d5502025-04-29 18:21:31 +0200245 " TODO: why does this fail on Appveyor and Github?
246 CheckNotMSWindows
Hirohito Higashifa9753a2025-04-27 15:36:43 +0200247
h-east3a3a2c92024-12-15 19:36:11 +0100248 set termwinscroll=1000 mouse=a
249 terminal
250 call assert_equal(2, winnr('$'))
251 let buf = bufnr()
252 call WaitFor({-> !empty(term_getline(buf, 1))})
253
254 let num1 = &termwinscroll / 100 * 99
255 call writefile(range(num1), 'Xtext', 'D')
256 if has('win32')
257 call term_sendkeys(buf, "type Xtext\<CR>")
258 else
259 call term_sendkeys(buf, "cat Xtext\<CR>")
260 endif
261 let rows = term_getsize(buf)[0]
262 " On MS-Windows there is an empty line, check both last line and above it.
263 call WaitForAssert({-> assert_match(string(num1 - 1), term_getline(buf, rows - 1) .. term_getline(buf, rows - 2))})
264 call feedkeys("\<C-W>N", 'xt')
265 call feedkeys("i", 'xt')
266
267 let num2 = &termwinscroll / 100 * 10
268 call writefile(range(num2), 'Xtext', 'D')
269 if has('win32')
270 call term_sendkeys(buf, "timeout /t 1 && type Xtext\<CR>")
271 else
272 call term_sendkeys(buf, "sleep 1; cat Xtext\<CR>")
273 endif
274 " Change the normal window to the current window with keystrokes.
275 call feedkeys("\<C-W>w", 'xt')
276 call WaitForAssert({-> assert_notequal(buf, bufnr())})
277 let rows = term_getsize(buf)[0]
278 " On MS-Windows there is an empty line, check both last line and above it.
279 call WaitForAssert({-> assert_match(string(num2 - 1), term_getline(buf, rows - 1) .. term_getline(buf, rows - 2))})
280 " Change the terminal window to the current window using mouse operation.
281 call test_setmouse(1, 1)
282 call feedkeys("\<LeftMouse>", "xt")
283 call WaitForAssert({-> assert_equal(buf, bufnr())})
284 " Before the fix, E340 and E315 would occur multiple times at this point.
285 let wm = winheight(0) * 2
286 let num3 = num1 + num2 - (num1 / 10) - wm
287 call assert_inrange(num3 - wm, num3 + wm, getwininfo(bufwinid(buf))[0].topline)
288 exe buf . 'bwipe!'
289 set termwinscroll& mouse&
290endfunc
291
Hirohito Higashi3219da52025-02-01 14:48:35 +0100292func Test_termwinscroll_topline2()
Christian Brabandtaae1bfb2025-02-09 17:10:30 +0100293 " calling the terminal API doesn't work on Windows
294 CheckNotMSWindows
Christian Brabandtaae1bfb2025-02-09 17:10:30 +0100295
Christian Brabandt44a21352025-02-02 09:03:00 +0100296 set termwinscroll=50000 mouse=a
Christian Brabandtaae1bfb2025-02-09 17:10:30 +0100297 set shell=sh
Hirohito Higashi3219da52025-02-01 14:48:35 +0100298 let norm_winid = win_getid()
299 terminal
300 call assert_equal(2, winnr('$'))
301 let buf = bufnr()
302 let win = winnr()
303 call WaitFor({-> !empty(term_getline(buf, 1))})
304
305 let num1 = &termwinscroll / 1000 * 999
306 call writefile(range(num1), 'Xtext', 'D')
Christian Brabandtaae1bfb2025-02-09 17:10:30 +0100307 call term_sendkeys(buf, "cat Xtext\<CR>")
Yee Cheng Chine70587d2025-02-13 20:55:45 +0100308 call term_sendkeys(buf, "printf '" .. TermNotifyParentCmd(v:false) .. "'\<cr>")
Hirohito Higashi3219da52025-02-01 14:48:35 +0100309 let rows = term_getsize(buf)[0]
Christian Brabandtaae1bfb2025-02-09 17:10:30 +0100310 let cnt = 0
Yee Cheng Chine70587d2025-02-13 20:55:45 +0100311 while !g:child_notification && cnt <= 50000
312 " Spin wait to process the terminal print as quickly as possible. This is
313 " more efficient than calling WaitForChildNotification() as we don't want
314 " to sleep here as the print is I/O-bound.
Christian Brabandtaae1bfb2025-02-09 17:10:30 +0100315 let cnt += 1
Yee Cheng Chine70587d2025-02-13 20:55:45 +0100316 call term_wait(buf, 0)
Christian Brabandtaae1bfb2025-02-09 17:10:30 +0100317 endwhile
Hirohito Higashi3219da52025-02-01 14:48:35 +0100318 call WaitForAssert({-> assert_match(string(num1 - 1), term_getline(buf, rows - 1) .. '\|' .. term_getline(buf, rows - 2))})
319 call feedkeys("\<C-W>N", 'xt')
320 call feedkeys("i", 'xt')
321
322 let num2 = &termwinscroll / 1000 * 8
323 call writefile(range(num2), 'Xtext', 'D')
Christian Brabandtaae1bfb2025-02-09 17:10:30 +0100324 call term_sendkeys(buf, "sleep 2; cat Xtext\<CR>")
Hirohito Higashi3219da52025-02-01 14:48:35 +0100325 let winrow = get(get(filter(getwininfo(), 'v:val.winid == norm_winid'), 0, {}), 'winrow', -1)
326
327 call test_setmouse(winrow, 1)
328 call feedkeys("\<LeftMouse>", "xt")
329 call WaitForAssert({-> assert_notequal(buf, bufnr())})
330
331 " Change the terminal window row size
332 call win_move_statusline(win,1)
333 " Before the fix, E340 and E315 would occur multiple times at this point.
334 let winrow2 = get(get(filter(getwininfo(), 'v:val.winid == norm_winid'), 0, {}), 'winrow', -1)
335 call assert_equal(winrow + 1, winrow2)
336
337 call test_setmouse(1, 1)
338 call feedkeys("\<LeftMouse>", "xt")
339 call WaitForAssert({-> assert_equal(buf, bufnr())})
340
341 exe buf . 'bwipe!'
342 set termwinscroll& mouse& sh&
343endfunc
344
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200345" Resizing the terminal window caused an ml_get error.
346" TODO: This does not reproduce the original problem.
Christian Brabandt926c3f42023-12-01 16:59:32 +0000347" TODO: This test starts timing out in Github CI Gui test, why????
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200348func Test_terminal_resize()
Christian Brabandt926c3f42023-12-01 16:59:32 +0000349 if has('gui_running') && expand('$GITHUB_ACTIONS') ==# 'true'
350 throw 'Skipped: FIXME: this test times-out in Github Actions CI with GUI. Why?'
351 endif
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200352 set statusline=x
353 terminal
354 call assert_equal(2, winnr('$'))
Bram Moolenaarc54f3472021-03-23 19:22:12 +0100355 let buf = bufnr()
356
357 " Wait for the shell to display a prompt
358 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))})
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200359
360 " Fill the terminal with text.
361 if has('win32')
362 call feedkeys("dir\<CR>", 'xt')
363 else
364 call feedkeys("ls\<CR>", 'xt')
365 endif
Bram Moolenaarc54f3472021-03-23 19:22:12 +0100366 " Wait for some output
367 call WaitForAssert({-> assert_notequal('', term_getline(buf, 3))})
368
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200369 " Go to Terminal-Normal mode for a moment.
370 call feedkeys("\<C-W>N", 'xt')
371 " Open a new window
372 call feedkeys("i\<C-W>n", 'xt')
373 call assert_equal(3, winnr('$'))
374 redraw
375
376 close
377 call assert_equal(2, winnr('$'))
378 call feedkeys("exit\<CR>", 'xt')
Bram Moolenaarc54f3472021-03-23 19:22:12 +0100379 call TermWait(buf)
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200380 set statusline&
381endfunc
382
Christian Brabandtc089c382023-12-03 16:48:29 +0000383" TODO: This test starts timing out in Github CI Gui test, why????
Christian Brabandtaa64ba12023-09-19 21:05:20 +0200384func Test_terminal_resize2()
385 CheckNotMSWindows
Christian Brabandtc089c382023-12-03 16:48:29 +0000386 if has('gui_running') && expand('$GITHUB_ACTIONS') ==# 'true'
387 throw 'Skipped: FIXME: this test times-out in Github Actions CI with GUI. Why?'
388 endif
Christian Brabandtaa64ba12023-09-19 21:05:20 +0200389 set statusline=x
390 terminal
391 call assert_equal(2, winnr('$'))
392 let buf = bufnr()
393
394 " Wait for the shell to display a prompt
395 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))})
396
397 " This used to crash Vim
398 call feedkeys("printf '\033[8;99999;99999t'\<CR>", 'xt')
399 redraw
400
401 call feedkeys("exit\<CR>", 'xt')
402 call TermWait(buf)
403 set statusline&
404endfunc
405
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200406" must be nearly the last, we can't go back from GUI to terminal
407func Test_zz1_terminal_in_gui()
408 CheckCanRunGui
409
410 " Ignore the "failed to create input context" error.
411 call test_ignore_error('E285:')
412
413 gui -f
414
415 call assert_equal(1, winnr('$'))
416 let buf = Run_shell_in_terminal({'term_finish': 'close'})
417 call StopShellInTerminal(buf)
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200418
419 " closing window wipes out the terminal buffer a with finished job
420 call WaitForAssert({-> assert_equal(1, winnr('$'))})
421 call assert_equal("", bufname(buf))
422
423 unlet g:job
424endfunc
425
Bram Moolenaarc4860bd2022-10-15 20:52:26 +0100426func Test_zz2_terminal_guioptions_bang()
427 CheckGui
428 set guioptions+=!
429
430 let filename = 'Xtestscript'
431 if has('win32')
432 let filename .= '.bat'
433 let prefix = ''
434 let contents = ['@echo off', 'exit %1']
435 else
436 let filename .= '.sh'
437 let prefix = './'
438 let contents = ['#!/bin/sh', 'exit $1']
439 endif
440 call writefile(contents, filename, 'D')
441 call setfperm(filename, 'rwxrwx---')
442
443 " Check if v:shell_error is equal to the exit status.
444 let exitval = 0
445 execute printf(':!%s%s %d', prefix, filename, exitval)
446 call assert_equal(exitval, v:shell_error)
447
448 let exitval = 9
449 execute printf(':!%s%s %d', prefix, filename, exitval)
450 call assert_equal(exitval, v:shell_error)
451
452 set guioptions&
453endfunc
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200454
455func Test_terminal_hidden()
456 CheckUnix
457
458 term ++hidden cat
459 let bnr = bufnr('$')
460 call assert_equal('terminal', getbufvar(bnr, '&buftype'))
461 exe 'sbuf ' . bnr
462 call assert_equal('terminal', &buftype)
463 call term_sendkeys(bnr, "asdf\<CR>")
464 call WaitForAssert({-> assert_match('asdf', term_getline(bnr, 2))})
465 call term_sendkeys(bnr, "\<C-D>")
466 call WaitForAssert({-> assert_equal('finished', bnr->term_getstatus())})
467 bwipe!
468endfunc
469
470func Test_terminal_switch_mode()
471 term
472 let bnr = bufnr('$')
473 call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))})
Bram Moolenaarc85156b2020-07-12 14:09:23 +0200474 " In the GUI the first switch sometimes doesn't work. Switch twice to avoid
Bram Moolenaar8e7d6222020-12-18 19:49:56 +0100475 " flakiness.
Bram Moolenaarc85156b2020-07-12 14:09:23 +0200476 call feedkeys("\<C-W>N", 'xt')
477 call feedkeys("A", 'xt')
478 call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))})
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200479 call feedkeys("\<C-W>N", 'xt')
480 call WaitForAssert({-> assert_equal('running,normal', term_getstatus(bnr))})
481 call feedkeys("A", 'xt')
482 call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))})
483 call feedkeys("\<C-\>\<C-N>", 'xt')
484 call WaitForAssert({-> assert_equal('running,normal', term_getstatus(bnr))})
485 call feedkeys("I", 'xt')
486 call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))})
487 call feedkeys("\<C-W>Nv", 'xt')
488 call WaitForAssert({-> assert_equal('running,normal', term_getstatus(bnr))})
489 call feedkeys("I", 'xt')
490 call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))})
491 call feedkeys("\<C-W>Nv", 'xt')
492 call WaitForAssert({-> assert_equal('running,normal', term_getstatus(bnr))})
493 call feedkeys("A", 'xt')
494 call WaitForAssert({-> assert_equal('running', term_getstatus(bnr))})
495 bwipe!
496endfunc
497
498func Test_terminal_normal_mode()
Drew Vogelea67ba72025-05-07 22:05:17 +0200499 CheckScreendump
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200500 CheckRunVimInTerminal
501
502 " Run Vim in a terminal and open a terminal window to run Vim in.
503 let lines =<< trim END
504 call setline(1, range(11111, 11122))
505 3
506 END
Bram Moolenaarc4860bd2022-10-15 20:52:26 +0100507 call writefile(lines, 'XtermNormal', 'D')
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200508 let buf = RunVimInTerminal('-S XtermNormal', {'rows': 8})
509 call TermWait(buf)
510
511 call term_sendkeys(buf, "\<C-W>N")
512 call term_sendkeys(buf, ":set number cursorline culopt=both\r")
513 call VerifyScreenDump(buf, 'Test_terminal_normal_1', {})
514
515 call term_sendkeys(buf, ":set culopt=number\r")
516 call VerifyScreenDump(buf, 'Test_terminal_normal_2', {})
517
518 call term_sendkeys(buf, ":set culopt=line\r")
519 call VerifyScreenDump(buf, 'Test_terminal_normal_3', {})
520
521 call assert_fails('call term_sendkeys(buf, [])', 'E730:')
522 call term_sendkeys(buf, "a:q!\<CR>:q\<CR>:q\<CR>")
523 call StopVimInTerminal(buf)
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200524endfunc
525
526func Test_terminal_hidden_and_close()
527 CheckUnix
528
529 call assert_equal(1, winnr('$'))
530 term ++hidden ++close ls
531 let bnr = bufnr('$')
532 call assert_equal('terminal', getbufvar(bnr, '&buftype'))
533 call WaitForAssert({-> assert_false(bufexists(bnr))})
534 call assert_equal(1, winnr('$'))
535endfunc
536
537func Test_terminal_does_not_truncate_last_newlines()
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200538 if has('conpty')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200539 throw 'Skipped: fail on ConPTY'
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200540 endif
Bram Moolenaarf08b0eb2021-10-16 13:00:14 +0100541 let g:test_is_flaky = 1
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200542 let contents = [
543 \ [ 'One', '', 'X' ],
544 \ [ 'Two', '', '' ],
545 \ [ 'Three' ] + repeat([''], 30)
546 \ ]
547
548 for c in contents
Bram Moolenaarc4860bd2022-10-15 20:52:26 +0100549 call writefile(c, 'Xdntfile', 'D')
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200550 if has('win32')
Milly4f5681d2024-10-20 11:06:00 +0200551 term cmd /D /c type Xdntfile
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200552 else
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100553 term cat Xdntfile
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200554 endif
555 let bnr = bufnr('$')
556 call assert_equal('terminal', getbufvar(bnr, '&buftype'))
557 call WaitForAssert({-> assert_equal('finished', term_getstatus(bnr))})
558 sleep 100m
559 call assert_equal(c, getline(1, line('$')))
560 quit
561 endfor
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200562endfunc
563
Bram Moolenaarb936b792020-09-04 18:34:09 +0200564func GetDummyCmd()
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200565 if has('win32')
Milly4f5681d2024-10-20 11:06:00 +0200566 return 'cmd /D /c ""'
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200567 else
568 CheckExecutable false
Bram Moolenaarb936b792020-09-04 18:34:09 +0200569 return 'false'
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200570 endif
Bram Moolenaarb936b792020-09-04 18:34:09 +0200571endfunc
572
573func Test_terminal_no_job()
574 let cmd = GetDummyCmd()
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200575 let term = term_start(cmd, {'term_finish': 'close'})
576 call WaitForAssert({-> assert_equal(v:null, term_getjob(term)) })
577endfunc
578
579func Test_term_getcursor()
580 CheckUnix
581
582 let buf = Run_shell_in_terminal({})
583
584 " Wait for the shell to display a prompt.
585 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))})
586
587 " Hide the cursor.
588 call term_sendkeys(buf, "echo -e '\\033[?25l'\r")
589 call WaitForAssert({-> assert_equal(0, term_getcursor(buf)[2].visible)})
590
591 " Show the cursor.
592 call term_sendkeys(buf, "echo -e '\\033[?25h'\r")
593 call WaitForAssert({-> assert_equal(1, buf->term_getcursor()[2].visible)})
594
595 " Change color of cursor.
596 call WaitForAssert({-> assert_equal('', term_getcursor(buf)[2].color)})
597 call term_sendkeys(buf, "echo -e '\\033]12;blue\\007'\r")
598 call WaitForAssert({-> assert_equal('blue', term_getcursor(buf)[2].color)})
599 call term_sendkeys(buf, "echo -e '\\033]12;green\\007'\r")
600 call WaitForAssert({-> assert_equal('green', term_getcursor(buf)[2].color)})
601
602 " Make cursor a blinking block.
603 call term_sendkeys(buf, "echo -e '\\033[1 q'\r")
604 call WaitForAssert({-> assert_equal([1, 1],
605 \ [term_getcursor(buf)[2].blink, term_getcursor(buf)[2].shape])})
606
607 " Make cursor a steady block.
608 call term_sendkeys(buf, "echo -e '\\033[2 q'\r")
609 call WaitForAssert({-> assert_equal([0, 1],
610 \ [term_getcursor(buf)[2].blink, term_getcursor(buf)[2].shape])})
611
612 " Make cursor a blinking underline.
613 call term_sendkeys(buf, "echo -e '\\033[3 q'\r")
614 call WaitForAssert({-> assert_equal([1, 2],
615 \ [term_getcursor(buf)[2].blink, term_getcursor(buf)[2].shape])})
616
617 " Make cursor a steady underline.
618 call term_sendkeys(buf, "echo -e '\\033[4 q'\r")
619 call WaitForAssert({-> assert_equal([0, 2],
620 \ [term_getcursor(buf)[2].blink, term_getcursor(buf)[2].shape])})
621
622 " Make cursor a blinking vertical bar.
623 call term_sendkeys(buf, "echo -e '\\033[5 q'\r")
624 call WaitForAssert({-> assert_equal([1, 3],
625 \ [term_getcursor(buf)[2].blink, term_getcursor(buf)[2].shape])})
626
627 " Make cursor a steady vertical bar.
628 call term_sendkeys(buf, "echo -e '\\033[6 q'\r")
629 call WaitForAssert({-> assert_equal([0, 3],
630 \ [term_getcursor(buf)[2].blink, term_getcursor(buf)[2].shape])})
631
632 call StopShellInTerminal(buf)
633endfunc
634
635" Test for term_gettitle()
Christian Brabandt6a46c192024-02-24 15:56:34 +0100636" Known to be flaky on Mac-OS X and the GH runners
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200637func Test_term_gettitle()
638 " term_gettitle() returns an empty string for a non-terminal buffer
639 " and for a non-existing buffer.
640 call assert_equal('', bufnr('%')->term_gettitle())
641 call assert_equal('', term_gettitle(bufnr('$') + 1))
642
643 if !has('title') || empty(&t_ts)
644 throw "Skipped: can't get/set title"
645 endif
Christian Brabandt6a46c192024-02-24 15:56:34 +0100646 if has('osx') && !empty($CI) && system('uname -m') =~# 'arm64'
647 " This test often fails with the following error message on Github runners
648 " MacOS-14
649 " '^\\[No Name\\] - VIM\\d*$' does not match 'e] - VIM'
650 " Why? Is the terminal that runs Vim too small?
651 throw 'Skipped: FIXME: Running this test on M1 Mac fails on GitHub Actions'
652 endif
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200653
654 let term = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', '-c', 'set title'])
Yegappan Lakshmanane446a012023-01-19 17:49:58 +0000655 call TermWait(term)
Bram Moolenaar3bb79dc2021-12-12 18:50:19 +0000656 " When Vim is running as a server then the title ends in VIM{number}, thus
657 " optionally match a number after "VIM".
658 call WaitForAssert({-> assert_match('^\[No Name\] - VIM\d*$', term_gettitle(term)) })
659 call term_sendkeys(term, ":e Xfoo\r")
660 call WaitForAssert({-> assert_match('^Xfoo (.*[/\\]testdir) - VIM\d*$', term_gettitle(term)) })
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200661
662 call term_sendkeys(term, ":set titlestring=foo\r")
663 call WaitForAssert({-> assert_equal('foo', term_gettitle(term)) })
664
665 exe term . 'bwipe!'
666endfunc
667
668func Test_term_gettty()
669 let buf = Run_shell_in_terminal({})
670 let gettty = term_gettty(buf)
671
672 if has('unix') && executable('tty')
673 " Find tty using the tty shell command.
674 call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))})
675 call term_sendkeys(buf, "tty\r")
676 call WaitForAssert({-> assert_notequal('', term_getline(buf, 3))})
677 let tty = term_getline(buf, 2)
678 call assert_equal(tty, gettty)
679 endif
680
681 let gettty0 = term_gettty(buf, 0)
682 let gettty1 = term_gettty(buf, 1)
683
684 call assert_equal(gettty, gettty0)
685 call assert_equal(job_info(g:job).tty_out, gettty0)
686 call assert_equal(job_info(g:job).tty_in, gettty1)
687
688 if has('unix')
689 " For unix, term_gettty(..., 0) and term_gettty(..., 1)
690 " are identical according to :help term_gettty()
691 call assert_equal(gettty0, gettty1)
692 call assert_match('^/dev/', gettty)
693 else
694 " ConPTY works on anonymous pipe.
695 if !has('conpty')
696 call assert_match('^\\\\.\\pipe\\', gettty0)
697 call assert_match('^\\\\.\\pipe\\', gettty1)
698 endif
699 endif
700
Bram Moolenaarbade44e2020-09-26 22:39:24 +0200701 call assert_fails('call term_gettty(buf, 2)', 'E475:')
702 call assert_fails('call term_gettty(buf, -1)', 'E475:')
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200703
704 call assert_equal('', term_gettty(buf + 1))
705
706 call StopShellInTerminal(buf)
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200707 exe buf . 'bwipe'
708endfunc
709
Bram Moolenaar1112c0f2020-07-01 21:53:50 +0200710
711" vim: shiftwidth=2 sts=2 expandtab