blob: ad05f3e044855e57fbeba5c65e621d12b3e6bfae [file] [log] [blame]
Bram Moolenaar2d295012022-07-02 16:29:34 +01001" Tests for editing the command line.
2
3source check.vim
Bram Moolenaar2d295012022-07-02 16:29:34 +01004source screendump.vim
5
6func Test_getcmdwintype()
7 call feedkeys("q/:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
8 call assert_equal('/', a)
9
10 call feedkeys("q?:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
11 call assert_equal('?', a)
12
13 call feedkeys("q::let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
14 call assert_equal(':', a)
15
16 call feedkeys(":\<C-F>:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
17 call assert_equal(':', a)
18
19 call assert_equal('', getcmdwintype())
20endfunc
21
22func Test_getcmdwin_autocmd()
23 let s:seq = []
24 augroup CmdWin
25 au WinEnter * call add(s:seq, 'WinEnter ' .. win_getid())
26 au WinLeave * call add(s:seq, 'WinLeave ' .. win_getid())
27 au BufEnter * call add(s:seq, 'BufEnter ' .. bufnr())
28 au BufLeave * call add(s:seq, 'BufLeave ' .. bufnr())
29 au CmdWinEnter * call add(s:seq, 'CmdWinEnter ' .. win_getid())
30 au CmdWinLeave * call add(s:seq, 'CmdWinLeave ' .. win_getid())
31
32 let org_winid = win_getid()
33 let org_bufnr = bufnr()
34 call feedkeys("q::let a = getcmdwintype()\<CR>:let s:cmd_winid = win_getid()\<CR>:let s:cmd_bufnr = bufnr()\<CR>:q\<CR>", 'x!')
35 call assert_equal(':', a)
36 call assert_equal([
37 \ 'WinLeave ' .. org_winid,
38 \ 'WinEnter ' .. s:cmd_winid,
39 \ 'BufLeave ' .. org_bufnr,
40 \ 'BufEnter ' .. s:cmd_bufnr,
41 \ 'CmdWinEnter ' .. s:cmd_winid,
42 \ 'CmdWinLeave ' .. s:cmd_winid,
43 \ 'BufLeave ' .. s:cmd_bufnr,
44 \ 'WinLeave ' .. s:cmd_winid,
45 \ 'WinEnter ' .. org_winid,
46 \ 'BufEnter ' .. org_bufnr,
47 \ ], s:seq)
48
49 au!
50 augroup END
51endfunc
52
53func Test_cmdwin_bug()
54 let winid = win_getid()
55 sp
56 try
57 call feedkeys("q::call win_gotoid(" .. winid .. ")\<CR>:q\<CR>", 'x!')
58 catch /^Vim\%((\a\+)\)\=:E11/
59 endtry
60 bw!
61endfunc
62
63func Test_cmdwin_restore()
64 CheckScreendump
65
66 let lines =<< trim [SCRIPT]
67 augroup vimHints | au! | augroup END
68 call setline(1, range(30))
69 2split
70 [SCRIPT]
Bram Moolenaar45bbaef2022-09-08 16:39:22 +010071 call writefile(lines, 'XTest_restore', 'D')
Bram Moolenaar2d295012022-07-02 16:29:34 +010072
73 let buf = RunVimInTerminal('-S XTest_restore', {'rows': 12})
Bram Moolenaar2d295012022-07-02 16:29:34 +010074 call term_sendkeys(buf, "q:")
75 call VerifyScreenDump(buf, 'Test_cmdwin_restore_1', {})
76
77 " normal restore
78 call term_sendkeys(buf, ":q\<CR>")
79 call VerifyScreenDump(buf, 'Test_cmdwin_restore_2', {})
80
81 " restore after setting 'lines' with one window
82 call term_sendkeys(buf, ":close\<CR>")
83 call term_sendkeys(buf, "q:")
84 call term_sendkeys(buf, ":set lines=18\<CR>")
85 call term_sendkeys(buf, ":q\<CR>")
86 call VerifyScreenDump(buf, 'Test_cmdwin_restore_3', {})
87
88 " clean up
89 call StopVimInTerminal(buf)
Bram Moolenaar2d295012022-07-02 16:29:34 +010090endfunc
91
92func Test_cmdwin_no_terminal()
Bram Moolenaarb2f0ca82022-09-18 15:08:19 +010093 CheckScreendump
Bram Moolenaar2d295012022-07-02 16:29:34 +010094
95 let buf = RunVimInTerminal('', {'rows': 12})
Bram Moolenaar2d295012022-07-02 16:29:34 +010096 call term_sendkeys(buf, ":set cmdheight=2\<CR>")
97 call term_sendkeys(buf, "q:")
98 call term_sendkeys(buf, ":let buf = term_start(['/bin/echo'], #{hidden: 1})\<CR>")
99 call VerifyScreenDump(buf, 'Test_cmdwin_no_terminal', {})
100 call term_sendkeys(buf, ":q\<CR>")
101 call StopVimInTerminal(buf)
102endfunc
103
Bram Moolenaarb2f0ca82022-09-18 15:08:19 +0100104func Test_cmdwin_wrong_command()
105 CheckScreendump
106
107 let buf = RunVimInTerminal('', {'rows': 12})
108 call term_sendkeys(buf, "q:")
109 call term_sendkeys(buf, "als\<Esc>")
110 call term_sendkeys(buf, "\<C-W>k")
111 call VerifyScreenDump(buf, 'Test_cmdwin_wrong_command_1', {})
112
113 call term_sendkeys(buf, "\<C-C>")
114 call VerifyScreenDump(buf, 'Test_cmdwin_wrong_command_2', {})
115
116 call term_sendkeys(buf, ":q\<CR>")
117 call StopVimInTerminal(buf)
118endfunc
119
Bram Moolenaar2d295012022-07-02 16:29:34 +0100120func Test_cmdwin_feedkeys()
121 " This should not generate E488
122 call feedkeys("q:\<CR>", 'x')
123 " Using feedkeys with q: only should automatically close the cmd window
124 call feedkeys('q:', 'xt')
125 call assert_equal(1, winnr('$'))
126 call assert_equal('', getcmdwintype())
127endfunc
128
129" Tests for the issues fixed in 7.4.441.
130" When 'cedit' is set to Ctrl-C, opening the command window hangs Vim
131func Test_cmdwin_cedit()
132 exe "set cedit=\<C-c>"
133 normal! :
134 call assert_equal(1, winnr('$'))
135
136 let g:cmd_wintype = ''
137 func CmdWinType()
138 let g:cmd_wintype = getcmdwintype()
139 let g:wintype = win_gettype()
140 return ''
141 endfunc
142
143 call feedkeys("\<C-c>a\<C-R>=CmdWinType()\<CR>\<CR>")
144 echo input('')
145 call assert_equal('@', g:cmd_wintype)
146 call assert_equal('command', g:wintype)
147
148 set cedit&vim
149 delfunc CmdWinType
150endfunc
151
152" Test for CmdwinEnter autocmd
153func Test_cmdwin_autocmd()
154 augroup CmdWin
155 au!
156 autocmd BufLeave * if &buftype == '' | update | endif
157 autocmd CmdwinEnter * startinsert
158 augroup END
159
160 call assert_fails('call feedkeys("q:xyz\<CR>", "xt")', 'E492:')
161 call assert_equal('xyz', @:)
162
163 augroup CmdWin
164 au!
165 augroup END
166 augroup! CmdWin
167endfunc
168
169func Test_cmdwin_jump_to_win()
170 call assert_fails('call feedkeys("q:\<C-W>\<C-W>\<CR>", "xt")', 'E11:')
171 new
172 set modified
173 call assert_fails('call feedkeys("q/:qall\<CR>", "xt")', ['E37:', 'E162:'])
174 close!
175 call feedkeys("q/:close\<CR>", "xt")
176 call assert_equal(1, winnr('$'))
177 call feedkeys("q/:exit\<CR>", "xt")
178 call assert_equal(1, winnr('$'))
179
180 " opening command window twice should fail
181 call assert_beeps('call feedkeys("q:q:\<CR>\<CR>", "xt")')
182 call assert_equal(1, winnr('$'))
183endfunc
184
185func Test_cmdwin_tabpage()
186 tabedit
187 call assert_fails("silent norm q/g :I\<Esc>", 'E11:')
188 tabclose!
189endfunc
190
191func Test_cmdwin_interrupted()
192 CheckScreendump
193
194 " aborting the :smile output caused the cmdline window to use the current
195 " buffer.
196 let lines =<< trim [SCRIPT]
197 au WinNew * smile
198 [SCRIPT]
Bram Moolenaar45bbaef2022-09-08 16:39:22 +0100199 call writefile(lines, 'XTest_cmdwin', 'D')
Bram Moolenaar2d295012022-07-02 16:29:34 +0100200
201 let buf = RunVimInTerminal('-S XTest_cmdwin', {'rows': 18})
202 " open cmdwin
203 call term_sendkeys(buf, "q:")
204 call WaitForAssert({-> assert_match('-- More --', term_getline(buf, 18))})
205 " quit more prompt for :smile command
206 call term_sendkeys(buf, "q")
207 call WaitForAssert({-> assert_match('^$', term_getline(buf, 18))})
208 " execute a simple command
209 call term_sendkeys(buf, "aecho 'done'\<CR>")
210 call VerifyScreenDump(buf, 'Test_cmdwin_interrupted', {})
211
212 " clean up
213 call StopVimInTerminal(buf)
Bram Moolenaar2d295012022-07-02 16:29:34 +0100214endfunc
215
216" Test for recursively getting multiple command line inputs
217func Test_cmdwin_multi_input()
218 call feedkeys(":\<C-R>=input('P: ')\<CR>\"cyan\<CR>\<CR>", 'xt')
219 call assert_equal('"cyan', @:)
220endfunc
221
222" Test for normal mode commands not supported in the cmd window
223func Test_cmdwin_blocked_commands()
224 call assert_fails('call feedkeys("q:\<C-T>\<CR>", "xt")', 'E11:')
225 call assert_fails('call feedkeys("q:\<C-]>\<CR>", "xt")', 'E11:')
226 call assert_fails('call feedkeys("q:\<C-^>\<CR>", "xt")', 'E11:')
227 call assert_fails('call feedkeys("q:Q\<CR>", "xt")', 'E11:')
228 call assert_fails('call feedkeys("q:Z\<CR>", "xt")', 'E11:')
229 call assert_fails('call feedkeys("q:\<F1>\<CR>", "xt")', 'E11:')
230 call assert_fails('call feedkeys("q:\<C-W>s\<CR>", "xt")', 'E11:')
231 call assert_fails('call feedkeys("q:\<C-W>v\<CR>", "xt")', 'E11:')
232 call assert_fails('call feedkeys("q:\<C-W>^\<CR>", "xt")', 'E11:')
233 call assert_fails('call feedkeys("q:\<C-W>n\<CR>", "xt")', 'E11:')
234 call assert_fails('call feedkeys("q:\<C-W>z\<CR>", "xt")', 'E11:')
235 call assert_fails('call feedkeys("q:\<C-W>o\<CR>", "xt")', 'E11:')
236 call assert_fails('call feedkeys("q:\<C-W>w\<CR>", "xt")', 'E11:')
237 call assert_fails('call feedkeys("q:\<C-W>j\<CR>", "xt")', 'E11:')
238 call assert_fails('call feedkeys("q:\<C-W>k\<CR>", "xt")', 'E11:')
239 call assert_fails('call feedkeys("q:\<C-W>h\<CR>", "xt")', 'E11:')
240 call assert_fails('call feedkeys("q:\<C-W>l\<CR>", "xt")', 'E11:')
241 call assert_fails('call feedkeys("q:\<C-W>T\<CR>", "xt")', 'E11:')
242 call assert_fails('call feedkeys("q:\<C-W>x\<CR>", "xt")', 'E11:')
243 call assert_fails('call feedkeys("q:\<C-W>r\<CR>", "xt")', 'E11:')
244 call assert_fails('call feedkeys("q:\<C-W>R\<CR>", "xt")', 'E11:')
245 call assert_fails('call feedkeys("q:\<C-W>K\<CR>", "xt")', 'E11:')
246 call assert_fails('call feedkeys("q:\<C-W>}\<CR>", "xt")', 'E11:')
247 call assert_fails('call feedkeys("q:\<C-W>]\<CR>", "xt")', 'E11:')
248 call assert_fails('call feedkeys("q:\<C-W>f\<CR>", "xt")', 'E11:')
249 call assert_fails('call feedkeys("q:\<C-W>d\<CR>", "xt")', 'E11:')
250 call assert_fails('call feedkeys("q:\<C-W>g\<CR>", "xt")', 'E11:')
251endfunc
252
253" Close the Cmd-line window in insert mode using CTRL-C
254func Test_cmdwin_insert_mode_close()
255 %bw!
256 let s = ''
257 exe "normal q:a\<C-C>let s='Hello'\<CR>"
258 call assert_equal('Hello', s)
259 call assert_equal(1, winnr('$'))
260endfunc
261
262func Test_cmdwin_ex_mode_with_modifier()
263 " this was accessing memory after allocated text in Ex mode
264 new
265 call setline(1, ['some', 'text', 'lines'])
266 silent! call feedkeys("gQnormal vq:atopleft\<C-V>\<CR>\<CR>", 'xt')
267 bwipe!
268endfunc
269
270func s:ComplInCmdwin_GlobalCompletion(a, l, p)
271 return 'global'
272endfunc
273
274func s:ComplInCmdwin_LocalCompletion(a, l, p)
275 return 'local'
276endfunc
277
278func Test_compl_in_cmdwin()
279 set wildmenu wildchar=<Tab>
280 com! -nargs=1 -complete=command GetInput let input = <q-args>
281 com! -buffer TestCommand echo 'TestCommand'
282 let w:test_winvar = 'winvar'
283 let b:test_bufvar = 'bufvar'
284
285 " User-defined commands
286 let input = ''
287 call feedkeys("q:iGetInput T\<C-x>\<C-v>\<CR>", 'tx!')
288 call assert_equal('TestCommand', input)
289
290 let input = ''
291 call feedkeys("q::GetInput T\<Tab>\<CR>:q\<CR>", 'tx!')
292 call assert_equal('T', input)
293
294
295 com! -nargs=1 -complete=var GetInput let input = <q-args>
296 " Window-local variables
297 let input = ''
298 call feedkeys("q:iGetInput w:test_\<C-x>\<C-v>\<CR>", 'tx!')
299 call assert_equal('w:test_winvar', input)
300
301 let input = ''
302 call feedkeys("q::GetInput w:test_\<Tab>\<CR>:q\<CR>", 'tx!')
303 call assert_equal('w:test_', input)
304
305 " Buffer-local variables
306 let input = ''
307 call feedkeys("q:iGetInput b:test_\<C-x>\<C-v>\<CR>", 'tx!')
308 call assert_equal('b:test_bufvar', input)
309
310 let input = ''
311 call feedkeys("q::GetInput b:test_\<Tab>\<CR>:q\<CR>", 'tx!')
312 call assert_equal('b:test_', input)
313
314
315 " Argument completion of buffer-local command
316 func s:ComplInCmdwin_GlobalCompletionList(a, l, p)
317 return ['global']
318 endfunc
319
320 func s:ComplInCmdwin_LocalCompletionList(a, l, p)
321 return ['local']
322 endfunc
323
324 func s:ComplInCmdwin_CheckCompletion(arg)
325 call assert_equal('local', a:arg)
326 endfunc
327
328 com! -nargs=1 -complete=custom,<SID>ComplInCmdwin_GlobalCompletion
329 \ TestCommand call s:ComplInCmdwin_CheckCompletion(<q-args>)
330 com! -buffer -nargs=1 -complete=custom,<SID>ComplInCmdwin_LocalCompletion
331 \ TestCommand call s:ComplInCmdwin_CheckCompletion(<q-args>)
332 call feedkeys("q:iTestCommand \<Tab>\<CR>", 'tx!')
333
334 com! -nargs=1 -complete=customlist,<SID>ComplInCmdwin_GlobalCompletionList
335 \ TestCommand call s:ComplInCmdwin_CheckCompletion(<q-args>)
336 com! -buffer -nargs=1 -complete=customlist,<SID>ComplInCmdwin_LocalCompletionList
337 \ TestCommand call s:ComplInCmdwin_CheckCompletion(<q-args>)
338
339 call feedkeys("q:iTestCommand \<Tab>\<CR>", 'tx!')
340
341 func! s:ComplInCmdwin_CheckCompletion(arg)
342 call assert_equal('global', a:arg)
343 endfunc
344 new
345 call feedkeys("q:iTestCommand \<Tab>\<CR>", 'tx!')
346 quit
347
348 delfunc s:ComplInCmdwin_GlobalCompletion
349 delfunc s:ComplInCmdwin_LocalCompletion
350 delfunc s:ComplInCmdwin_GlobalCompletionList
351 delfunc s:ComplInCmdwin_LocalCompletionList
352 delfunc s:ComplInCmdwin_CheckCompletion
353
354 delcom -buffer TestCommand
355 delcom TestCommand
356 delcom GetInput
357 unlet w:test_winvar
358 unlet b:test_bufvar
359 set wildmenu& wildchar&
360endfunc
361
362func Test_cmdwin_ctrl_bsl()
363 " Using CTRL-\ CTRL-N in cmd window should close the window
364 call feedkeys("q:\<C-\>\<C-N>", 'xt')
365 call assert_equal('', getcmdwintype())
366endfunc
367
Bram Moolenaarc963ec32022-07-24 20:08:01 +0100368func Test_cant_open_cmdwin_in_cmdwin()
369 try
370 call feedkeys("q:q::q\<CR>", "x!")
371 catch
372 let caught = v:exception
373 endtry
374 call assert_match('E1292:', caught)
375endfunc
376
Bram Moolenaare98c88c2022-08-16 14:51:53 +0100377func Test_cmdwin_virtual_edit()
378 enew!
379 set ve=all cpo+=$
380 silent normal q/s
381
382 set ve= cpo-=$
383endfunc
384
Bram Moolenaar3a7ad902022-08-23 19:54:27 +0100385" Check that a :normal command can be used to stop Visual mode without side
386" effects.
387func Test_normal_escape()
388 call feedkeys("q:i\" foo\<Esc>:normal! \<C-V>\<Esc>\<CR>:\" bar\<CR>", 'ntx')
389 call assert_equal('" bar', @:)
390endfunc
391
Bram Moolenaar1c3dd8d2022-09-17 19:43:23 +0100392" This was using a pointer to a freed buffer
393func Test_cmdwin_freed_buffer_ptr()
Bram Moolenaar312af652022-09-17 21:20:42 +0100394 " this does not work on MS-Windows because renaming an open file fails
395 CheckNotMSWindows
396
Bram Moolenaar1c3dd8d2022-09-17 19:43:23 +0100397 au BufEnter * next 0| file
398 edit 0
399 silent! norm q/
400
401 au! BufEnter
402 bwipe!
403endfunc
404
Bram Moolenaar8279af52022-09-26 23:08:22 +0100405" This was resulting in a window with negative width.
406" The test doesn't reproduce the illegal memory access though...
407func Test_cmdwin_split_often()
408 let lines = &lines
409 let columns = &columns
410 set t_WS=
411
412 try
413 set encoding=iso8859
414 set ruler
415 winsize 0 0
416 noremap 0 H
417 sil norm 0000000q:
418 catch /E36:/
419 endtry
420
421 bwipe!
422 set encoding=utf8
423 let &lines = lines
424 let &columns = columns
425endfunc
426
Bram Moolenaar2d295012022-07-02 16:29:34 +0100427
428" vim: shiftwidth=2 sts=2 expandtab