blob: fe849bcc16863de07b1481e65280be259569622e [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})
76 call TermWait(buf, 50)
77 call term_sendkeys(buf, "q:")
78 call VerifyScreenDump(buf, 'Test_cmdwin_restore_1', {})
79
80 " normal restore
81 call term_sendkeys(buf, ":q\<CR>")
82 call VerifyScreenDump(buf, 'Test_cmdwin_restore_2', {})
83
84 " restore after setting 'lines' with one window
85 call term_sendkeys(buf, ":close\<CR>")
86 call term_sendkeys(buf, "q:")
87 call term_sendkeys(buf, ":set lines=18\<CR>")
88 call term_sendkeys(buf, ":q\<CR>")
89 call VerifyScreenDump(buf, 'Test_cmdwin_restore_3', {})
90
91 " clean up
92 call StopVimInTerminal(buf)
Bram Moolenaar2d295012022-07-02 16:29:34 +010093endfunc
94
95func Test_cmdwin_no_terminal()
96 CheckFeature terminal
97 CheckNotMSWindows
98
99 let buf = RunVimInTerminal('', {'rows': 12})
100 call TermWait(buf, 50)
101 call term_sendkeys(buf, ":set cmdheight=2\<CR>")
102 call term_sendkeys(buf, "q:")
103 call term_sendkeys(buf, ":let buf = term_start(['/bin/echo'], #{hidden: 1})\<CR>")
104 call VerifyScreenDump(buf, 'Test_cmdwin_no_terminal', {})
105 call term_sendkeys(buf, ":q\<CR>")
106 call StopVimInTerminal(buf)
107endfunc
108
109func Test_cmdwin_feedkeys()
110 " This should not generate E488
111 call feedkeys("q:\<CR>", 'x')
112 " Using feedkeys with q: only should automatically close the cmd window
113 call feedkeys('q:', 'xt')
114 call assert_equal(1, winnr('$'))
115 call assert_equal('', getcmdwintype())
116endfunc
117
118" Tests for the issues fixed in 7.4.441.
119" When 'cedit' is set to Ctrl-C, opening the command window hangs Vim
120func Test_cmdwin_cedit()
121 exe "set cedit=\<C-c>"
122 normal! :
123 call assert_equal(1, winnr('$'))
124
125 let g:cmd_wintype = ''
126 func CmdWinType()
127 let g:cmd_wintype = getcmdwintype()
128 let g:wintype = win_gettype()
129 return ''
130 endfunc
131
132 call feedkeys("\<C-c>a\<C-R>=CmdWinType()\<CR>\<CR>")
133 echo input('')
134 call assert_equal('@', g:cmd_wintype)
135 call assert_equal('command', g:wintype)
136
137 set cedit&vim
138 delfunc CmdWinType
139endfunc
140
141" Test for CmdwinEnter autocmd
142func Test_cmdwin_autocmd()
143 augroup CmdWin
144 au!
145 autocmd BufLeave * if &buftype == '' | update | endif
146 autocmd CmdwinEnter * startinsert
147 augroup END
148
149 call assert_fails('call feedkeys("q:xyz\<CR>", "xt")', 'E492:')
150 call assert_equal('xyz', @:)
151
152 augroup CmdWin
153 au!
154 augroup END
155 augroup! CmdWin
156endfunc
157
158func Test_cmdwin_jump_to_win()
159 call assert_fails('call feedkeys("q:\<C-W>\<C-W>\<CR>", "xt")', 'E11:')
160 new
161 set modified
162 call assert_fails('call feedkeys("q/:qall\<CR>", "xt")', ['E37:', 'E162:'])
163 close!
164 call feedkeys("q/:close\<CR>", "xt")
165 call assert_equal(1, winnr('$'))
166 call feedkeys("q/:exit\<CR>", "xt")
167 call assert_equal(1, winnr('$'))
168
169 " opening command window twice should fail
170 call assert_beeps('call feedkeys("q:q:\<CR>\<CR>", "xt")')
171 call assert_equal(1, winnr('$'))
172endfunc
173
174func Test_cmdwin_tabpage()
175 tabedit
176 call assert_fails("silent norm q/g :I\<Esc>", 'E11:')
177 tabclose!
178endfunc
179
180func Test_cmdwin_interrupted()
181 CheckScreendump
182
183 " aborting the :smile output caused the cmdline window to use the current
184 " buffer.
185 let lines =<< trim [SCRIPT]
186 au WinNew * smile
187 [SCRIPT]
Bram Moolenaar45bbaef2022-09-08 16:39:22 +0100188 call writefile(lines, 'XTest_cmdwin', 'D')
Bram Moolenaar2d295012022-07-02 16:29:34 +0100189
190 let buf = RunVimInTerminal('-S XTest_cmdwin', {'rows': 18})
191 " open cmdwin
192 call term_sendkeys(buf, "q:")
193 call WaitForAssert({-> assert_match('-- More --', term_getline(buf, 18))})
194 " quit more prompt for :smile command
195 call term_sendkeys(buf, "q")
196 call WaitForAssert({-> assert_match('^$', term_getline(buf, 18))})
197 " execute a simple command
198 call term_sendkeys(buf, "aecho 'done'\<CR>")
199 call VerifyScreenDump(buf, 'Test_cmdwin_interrupted', {})
200
201 " clean up
202 call StopVimInTerminal(buf)
Bram Moolenaar2d295012022-07-02 16:29:34 +0100203endfunc
204
205" Test for recursively getting multiple command line inputs
206func Test_cmdwin_multi_input()
207 call feedkeys(":\<C-R>=input('P: ')\<CR>\"cyan\<CR>\<CR>", 'xt')
208 call assert_equal('"cyan', @:)
209endfunc
210
211" Test for normal mode commands not supported in the cmd window
212func Test_cmdwin_blocked_commands()
213 call assert_fails('call feedkeys("q:\<C-T>\<CR>", "xt")', 'E11:')
214 call assert_fails('call feedkeys("q:\<C-]>\<CR>", "xt")', 'E11:')
215 call assert_fails('call feedkeys("q:\<C-^>\<CR>", "xt")', 'E11:')
216 call assert_fails('call feedkeys("q:Q\<CR>", "xt")', 'E11:')
217 call assert_fails('call feedkeys("q:Z\<CR>", "xt")', 'E11:')
218 call assert_fails('call feedkeys("q:\<F1>\<CR>", "xt")', 'E11:')
219 call assert_fails('call feedkeys("q:\<C-W>s\<CR>", "xt")', 'E11:')
220 call assert_fails('call feedkeys("q:\<C-W>v\<CR>", "xt")', 'E11:')
221 call assert_fails('call feedkeys("q:\<C-W>^\<CR>", "xt")', 'E11:')
222 call assert_fails('call feedkeys("q:\<C-W>n\<CR>", "xt")', 'E11:')
223 call assert_fails('call feedkeys("q:\<C-W>z\<CR>", "xt")', 'E11:')
224 call assert_fails('call feedkeys("q:\<C-W>o\<CR>", "xt")', 'E11:')
225 call assert_fails('call feedkeys("q:\<C-W>w\<CR>", "xt")', 'E11:')
226 call assert_fails('call feedkeys("q:\<C-W>j\<CR>", "xt")', 'E11:')
227 call assert_fails('call feedkeys("q:\<C-W>k\<CR>", "xt")', 'E11:')
228 call assert_fails('call feedkeys("q:\<C-W>h\<CR>", "xt")', 'E11:')
229 call assert_fails('call feedkeys("q:\<C-W>l\<CR>", "xt")', 'E11:')
230 call assert_fails('call feedkeys("q:\<C-W>T\<CR>", "xt")', 'E11:')
231 call assert_fails('call feedkeys("q:\<C-W>x\<CR>", "xt")', 'E11:')
232 call assert_fails('call feedkeys("q:\<C-W>r\<CR>", "xt")', 'E11:')
233 call assert_fails('call feedkeys("q:\<C-W>R\<CR>", "xt")', 'E11:')
234 call assert_fails('call feedkeys("q:\<C-W>K\<CR>", "xt")', 'E11:')
235 call assert_fails('call feedkeys("q:\<C-W>}\<CR>", "xt")', 'E11:')
236 call assert_fails('call feedkeys("q:\<C-W>]\<CR>", "xt")', 'E11:')
237 call assert_fails('call feedkeys("q:\<C-W>f\<CR>", "xt")', 'E11:')
238 call assert_fails('call feedkeys("q:\<C-W>d\<CR>", "xt")', 'E11:')
239 call assert_fails('call feedkeys("q:\<C-W>g\<CR>", "xt")', 'E11:')
240endfunc
241
242" Close the Cmd-line window in insert mode using CTRL-C
243func Test_cmdwin_insert_mode_close()
244 %bw!
245 let s = ''
246 exe "normal q:a\<C-C>let s='Hello'\<CR>"
247 call assert_equal('Hello', s)
248 call assert_equal(1, winnr('$'))
249endfunc
250
251func Test_cmdwin_ex_mode_with_modifier()
252 " this was accessing memory after allocated text in Ex mode
253 new
254 call setline(1, ['some', 'text', 'lines'])
255 silent! call feedkeys("gQnormal vq:atopleft\<C-V>\<CR>\<CR>", 'xt')
256 bwipe!
257endfunc
258
259func s:ComplInCmdwin_GlobalCompletion(a, l, p)
260 return 'global'
261endfunc
262
263func s:ComplInCmdwin_LocalCompletion(a, l, p)
264 return 'local'
265endfunc
266
267func Test_compl_in_cmdwin()
268 set wildmenu wildchar=<Tab>
269 com! -nargs=1 -complete=command GetInput let input = <q-args>
270 com! -buffer TestCommand echo 'TestCommand'
271 let w:test_winvar = 'winvar'
272 let b:test_bufvar = 'bufvar'
273
274 " User-defined commands
275 let input = ''
276 call feedkeys("q:iGetInput T\<C-x>\<C-v>\<CR>", 'tx!')
277 call assert_equal('TestCommand', input)
278
279 let input = ''
280 call feedkeys("q::GetInput T\<Tab>\<CR>:q\<CR>", 'tx!')
281 call assert_equal('T', input)
282
283
284 com! -nargs=1 -complete=var GetInput let input = <q-args>
285 " Window-local variables
286 let input = ''
287 call feedkeys("q:iGetInput w:test_\<C-x>\<C-v>\<CR>", 'tx!')
288 call assert_equal('w:test_winvar', input)
289
290 let input = ''
291 call feedkeys("q::GetInput w:test_\<Tab>\<CR>:q\<CR>", 'tx!')
292 call assert_equal('w:test_', input)
293
294 " Buffer-local variables
295 let input = ''
296 call feedkeys("q:iGetInput b:test_\<C-x>\<C-v>\<CR>", 'tx!')
297 call assert_equal('b:test_bufvar', input)
298
299 let input = ''
300 call feedkeys("q::GetInput b:test_\<Tab>\<CR>:q\<CR>", 'tx!')
301 call assert_equal('b:test_', input)
302
303
304 " Argument completion of buffer-local command
305 func s:ComplInCmdwin_GlobalCompletionList(a, l, p)
306 return ['global']
307 endfunc
308
309 func s:ComplInCmdwin_LocalCompletionList(a, l, p)
310 return ['local']
311 endfunc
312
313 func s:ComplInCmdwin_CheckCompletion(arg)
314 call assert_equal('local', a:arg)
315 endfunc
316
317 com! -nargs=1 -complete=custom,<SID>ComplInCmdwin_GlobalCompletion
318 \ TestCommand call s:ComplInCmdwin_CheckCompletion(<q-args>)
319 com! -buffer -nargs=1 -complete=custom,<SID>ComplInCmdwin_LocalCompletion
320 \ TestCommand call s:ComplInCmdwin_CheckCompletion(<q-args>)
321 call feedkeys("q:iTestCommand \<Tab>\<CR>", 'tx!')
322
323 com! -nargs=1 -complete=customlist,<SID>ComplInCmdwin_GlobalCompletionList
324 \ TestCommand call s:ComplInCmdwin_CheckCompletion(<q-args>)
325 com! -buffer -nargs=1 -complete=customlist,<SID>ComplInCmdwin_LocalCompletionList
326 \ TestCommand call s:ComplInCmdwin_CheckCompletion(<q-args>)
327
328 call feedkeys("q:iTestCommand \<Tab>\<CR>", 'tx!')
329
330 func! s:ComplInCmdwin_CheckCompletion(arg)
331 call assert_equal('global', a:arg)
332 endfunc
333 new
334 call feedkeys("q:iTestCommand \<Tab>\<CR>", 'tx!')
335 quit
336
337 delfunc s:ComplInCmdwin_GlobalCompletion
338 delfunc s:ComplInCmdwin_LocalCompletion
339 delfunc s:ComplInCmdwin_GlobalCompletionList
340 delfunc s:ComplInCmdwin_LocalCompletionList
341 delfunc s:ComplInCmdwin_CheckCompletion
342
343 delcom -buffer TestCommand
344 delcom TestCommand
345 delcom GetInput
346 unlet w:test_winvar
347 unlet b:test_bufvar
348 set wildmenu& wildchar&
349endfunc
350
351func Test_cmdwin_ctrl_bsl()
352 " Using CTRL-\ CTRL-N in cmd window should close the window
353 call feedkeys("q:\<C-\>\<C-N>", 'xt')
354 call assert_equal('', getcmdwintype())
355endfunc
356
Bram Moolenaarc963ec32022-07-24 20:08:01 +0100357func Test_cant_open_cmdwin_in_cmdwin()
358 try
359 call feedkeys("q:q::q\<CR>", "x!")
360 catch
361 let caught = v:exception
362 endtry
363 call assert_match('E1292:', caught)
364endfunc
365
Bram Moolenaare98c88c2022-08-16 14:51:53 +0100366func Test_cmdwin_virtual_edit()
367 enew!
368 set ve=all cpo+=$
369 silent normal q/s
370
371 set ve= cpo-=$
372endfunc
373
Bram Moolenaar3a7ad902022-08-23 19:54:27 +0100374" Check that a :normal command can be used to stop Visual mode without side
375" effects.
376func Test_normal_escape()
377 call feedkeys("q:i\" foo\<Esc>:normal! \<C-V>\<Esc>\<CR>:\" bar\<CR>", 'ntx')
378 call assert_equal('" bar', @:)
379endfunc
380
Bram Moolenaar1c3dd8d2022-09-17 19:43:23 +0100381" This was using a pointer to a freed buffer
382func Test_cmdwin_freed_buffer_ptr()
383 au BufEnter * next 0| file
384 edit 0
385 silent! norm q/
386
387 au! BufEnter
388 bwipe!
389endfunc
390
Bram Moolenaar2d295012022-07-02 16:29:34 +0100391
392" vim: shiftwidth=2 sts=2 expandtab