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