blob: 961aeb2df7825ba8ec8c0cd9e8dc747ae74b83bf [file] [log] [blame]
Bram Moolenaar63a60de2016-06-04 22:08:55 +02001" Tests for user defined commands
2
Bram Moolenaar62aec932022-01-29 21:45:34 +00003import './vim9.vim' as v9
Bram Moolenaarcc7eb2a2021-07-11 19:12:04 +02004
Bram Moolenaar63a60de2016-06-04 22:08:55 +02005" Test for <mods> in user defined commands
6function Test_cmdmods()
7 let g:mods = ''
8
Bram Moolenaar7a1637f2020-04-13 21:16:21 +02009 command! -nargs=* MyCmd let g:mods = '<mods>'
Bram Moolenaar63a60de2016-06-04 22:08:55 +020010
11 MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020012 call assert_equal('', g:mods)
Bram Moolenaar63a60de2016-06-04 22:08:55 +020013 aboveleft MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020014 call assert_equal('aboveleft', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020015 abo MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020016 call assert_equal('aboveleft', g:mods)
Bram Moolenaar63a60de2016-06-04 22:08:55 +020017 belowright MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020018 call assert_equal('belowright', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020019 bel MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020020 call assert_equal('belowright', g:mods)
Bram Moolenaar63a60de2016-06-04 22:08:55 +020021 botright MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020022 call assert_equal('botright', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020023 bo MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020024 call assert_equal('botright', g:mods)
Bram Moolenaar63a60de2016-06-04 22:08:55 +020025 browse MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020026 call assert_equal('browse', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020027 bro MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020028 call assert_equal('browse', g:mods)
Bram Moolenaar63a60de2016-06-04 22:08:55 +020029 confirm MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020030 call assert_equal('confirm', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020031 conf MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020032 call assert_equal('confirm', g:mods)
Bram Moolenaar63a60de2016-06-04 22:08:55 +020033 hide MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020034 call assert_equal('hide', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020035 hid MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020036 call assert_equal('hide', g:mods)
Bram Moolenaar63a60de2016-06-04 22:08:55 +020037 keepalt MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020038 call assert_equal('keepalt', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020039 keepa MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020040 call assert_equal('keepalt', g:mods)
Bram Moolenaar63a60de2016-06-04 22:08:55 +020041 keepjumps MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020042 call assert_equal('keepjumps', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020043 keepj MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020044 call assert_equal('keepjumps', g:mods)
Bram Moolenaar63a60de2016-06-04 22:08:55 +020045 keepmarks MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020046 call assert_equal('keepmarks', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020047 kee MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020048 call assert_equal('keepmarks', g:mods)
Bram Moolenaar63a60de2016-06-04 22:08:55 +020049 keeppatterns MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020050 call assert_equal('keeppatterns', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020051 keepp MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020052 call assert_equal('keeppatterns', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020053 leftabove MyCmd " results in :aboveleft
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020054 call assert_equal('aboveleft', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020055 lefta MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020056 call assert_equal('aboveleft', g:mods)
Bram Moolenaar63a60de2016-06-04 22:08:55 +020057 lockmarks MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020058 call assert_equal('lockmarks', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020059 loc MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020060 call assert_equal('lockmarks', g:mods)
zeertzjq9359e8a2022-07-03 13:16:09 +010061 noautocmd MyCmd
62 call assert_equal('noautocmd', g:mods)
63 noa MyCmd
64 call assert_equal('noautocmd', g:mods)
Bram Moolenaar63a60de2016-06-04 22:08:55 +020065 noswapfile MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020066 call assert_equal('noswapfile', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020067 nos MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020068 call assert_equal('noswapfile', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020069 rightbelow MyCmd " results in :belowright
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020070 call assert_equal('belowright', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020071 rightb MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020072 call assert_equal('belowright', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020073 " sandbox MyCmd
Bram Moolenaar63a60de2016-06-04 22:08:55 +020074 silent MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020075 call assert_equal('silent', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020076 sil MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020077 call assert_equal('silent', g:mods)
zeertzjq9359e8a2022-07-03 13:16:09 +010078 silent! MyCmd
79 call assert_equal('silent!', g:mods)
80 sil! MyCmd
81 call assert_equal('silent!', g:mods)
Bram Moolenaar63a60de2016-06-04 22:08:55 +020082 tab MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020083 call assert_equal('tab', g:mods)
Bram Moolenaar63a60de2016-06-04 22:08:55 +020084 topleft MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020085 call assert_equal('topleft', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020086 to MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020087 call assert_equal('topleft', g:mods)
zeertzjq9359e8a2022-07-03 13:16:09 +010088 unsilent MyCmd
89 call assert_equal('unsilent', g:mods)
90 uns MyCmd
91 call assert_equal('unsilent', g:mods)
Bram Moolenaar63a60de2016-06-04 22:08:55 +020092 verbose MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020093 call assert_equal('verbose', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +020094 verb MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +020095 call assert_equal('verbose', g:mods)
zeertzjq9359e8a2022-07-03 13:16:09 +010096 0verbose MyCmd
97 call assert_equal('0verbose', g:mods)
98 3verbose MyCmd
99 call assert_equal('3verbose', g:mods)
100 999verbose MyCmd
101 call assert_equal('999verbose', g:mods)
Bram Moolenaar63a60de2016-06-04 22:08:55 +0200102 vertical MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +0200103 call assert_equal('vertical', g:mods)
Bram Moolenaar3bcfca32016-07-30 19:39:29 +0200104 vert MyCmd
Bram Moolenaar7a1637f2020-04-13 21:16:21 +0200105 call assert_equal('vertical', g:mods)
zeertzjqd3de1782022-09-01 12:58:52 +0100106 horizontal MyCmd
107 call assert_equal('horizontal', g:mods)
108 hor MyCmd
109 call assert_equal('horizontal', g:mods)
Bram Moolenaar63a60de2016-06-04 22:08:55 +0200110
111 aboveleft belowright botright browse confirm hide keepalt keepjumps
zeertzjq9359e8a2022-07-03 13:16:09 +0100112 \ keepmarks keeppatterns lockmarks noautocmd noswapfile silent
113 \ tab topleft unsilent verbose vertical MyCmd
Bram Moolenaar63a60de2016-06-04 22:08:55 +0200114
Bram Moolenaar7a1637f2020-04-13 21:16:21 +0200115 call assert_equal('browse confirm hide keepalt keepjumps ' .
zeertzjq9359e8a2022-07-03 13:16:09 +0100116 \ 'keepmarks keeppatterns lockmarks noswapfile unsilent noautocmd ' .
117 \ 'silent verbose aboveleft belowright botright tab topleft vertical',
118 \ g:mods)
Bram Moolenaar63a60de2016-06-04 22:08:55 +0200119
120 let g:mods = ''
121 command! -nargs=* MyQCmd let g:mods .= '<q-mods> '
122
123 vertical MyQCmd
124 call assert_equal('"vertical" ', g:mods)
125
126 delcommand MyCmd
127 delcommand MyQCmd
128 unlet g:mods
129endfunction
Bram Moolenaareac784e2016-07-28 22:08:24 +0200130
Bram Moolenaare61e5482019-04-27 15:05:12 +0200131func SaveCmdArgs(...)
132 let g:args = a:000
133endfunc
134
135func Test_f_args()
136 command -nargs=* TestFArgs call SaveCmdArgs(<f-args>)
137
138 TestFArgs
139 call assert_equal([], g:args)
140
141 TestFArgs one two three
142 call assert_equal(['one', 'two', 'three'], g:args)
143
144 TestFArgs one\\two three
145 call assert_equal(['one\two', 'three'], g:args)
146
147 TestFArgs one\ two three
148 call assert_equal(['one two', 'three'], g:args)
149
150 TestFArgs one\"two three
151 call assert_equal(['one\"two', 'three'], g:args)
152
153 delcommand TestFArgs
154endfunc
155
156func Test_q_args()
157 command -nargs=* TestQArgs call SaveCmdArgs(<q-args>)
158
159 TestQArgs
160 call assert_equal([''], g:args)
161
162 TestQArgs one two three
163 call assert_equal(['one two three'], g:args)
164
165 TestQArgs one\\two three
166 call assert_equal(['one\\two three'], g:args)
167
168 TestQArgs one\ two three
169 call assert_equal(['one\ two three'], g:args)
170
171 TestQArgs one\"two three
172 call assert_equal(['one\"two three'], g:args)
173
174 delcommand TestQArgs
175endfunc
176
177func Test_reg_arg()
178 command -nargs=* -reg TestRegArg call SaveCmdArgs("<reg>", "<register>")
179
180 TestRegArg
181 call assert_equal(['', ''], g:args)
182
183 TestRegArg x
184 call assert_equal(['x', 'x'], g:args)
185
186 delcommand TestRegArg
187endfunc
188
189func Test_no_arg()
190 command -nargs=* TestNoArg call SaveCmdArgs("<args>", "<>", "<x>", "<lt>")
191
192 TestNoArg
193 call assert_equal(['', '<>', '<x>', '<'], g:args)
194
195 TestNoArg one
196 call assert_equal(['one', '<>', '<x>', '<'], g:args)
197
198 delcommand TestNoArg
199endfunc
200
201func Test_range_arg()
202 command -range TestRangeArg call SaveCmdArgs(<range>, <line1>, <line2>)
203 new
204 call setline(1, range(100))
205 let lnum = line('.')
206
207 TestRangeArg
208 call assert_equal([0, lnum, lnum], g:args)
209
210 99TestRangeArg
211 call assert_equal([1, 99, 99], g:args)
212
213 88,99TestRangeArg
214 call assert_equal([2, 88, 99], g:args)
215
216 call assert_fails('102TestRangeArg', 'E16:')
217
218 bwipe!
219 delcommand TestRangeArg
220endfunc
221
Bram Moolenaareac784e2016-07-28 22:08:24 +0200222func Test_Ambiguous()
223 command Doit let g:didit = 'yes'
224 command Dothat let g:didthat = 'also'
225 call assert_fails('Do', 'E464:')
226 Doit
227 call assert_equal('yes', g:didit)
228 Dothat
229 call assert_equal('also', g:didthat)
230 unlet g:didit
231 unlet g:didthat
232
233 delcommand Doit
234 Do
235 call assert_equal('also', g:didthat)
236 delcommand Dothat
Bram Moolenaare61e5482019-04-27 15:05:12 +0200237
238 call assert_fails("\x4ei\041", ' you demand a ')
Bram Moolenaareac784e2016-07-28 22:08:24 +0200239endfunc
240
Bram Moolenaar55d46912018-12-08 16:03:28 +0100241func Test_redefine_on_reload()
Bram Moolenaar5b148ef2022-10-15 21:35:56 +0100242 call writefile(['command ExistingCommand echo "yes"'], 'Xcommandexists', 'D')
Bram Moolenaar55d46912018-12-08 16:03:28 +0100243 call assert_equal(0, exists(':ExistingCommand'))
244 source Xcommandexists
245 call assert_equal(2, exists(':ExistingCommand'))
246 " Redefining a command when reloading a script is OK.
247 source Xcommandexists
248 call assert_equal(2, exists(':ExistingCommand'))
249
250 " But redefining in another script is not OK.
Bram Moolenaar5b148ef2022-10-15 21:35:56 +0100251 call writefile(['command ExistingCommand echo "yes"'], 'Xcommandexists2', 'D')
Bram Moolenaar55d46912018-12-08 16:03:28 +0100252 call assert_fails('source Xcommandexists2', 'E174:')
Bram Moolenaar55d46912018-12-08 16:03:28 +0100253
254 " And defining twice in one script is not OK.
255 delcommand ExistingCommand
256 call assert_equal(0, exists(':ExistingCommand'))
257 call writefile([
258 \ 'command ExistingCommand echo "yes"',
259 \ 'command ExistingCommand echo "no"',
260 \ ], 'Xcommandexists')
261 call assert_fails('source Xcommandexists', 'E174:')
262 call assert_equal(2, exists(':ExistingCommand'))
263
Bram Moolenaar55d46912018-12-08 16:03:28 +0100264 delcommand ExistingCommand
265endfunc
266
Bram Moolenaareac784e2016-07-28 22:08:24 +0200267func Test_CmdUndefined()
268 call assert_fails('Doit', 'E492:')
269 au CmdUndefined Doit :command Doit let g:didit = 'yes'
270 Doit
271 call assert_equal('yes', g:didit)
272 delcommand Doit
273
274 call assert_fails('Dothat', 'E492:')
275 au CmdUndefined * let g:didnot = 'yes'
276 call assert_fails('Dothat', 'E492:')
277 call assert_equal('yes', g:didnot)
278endfunc
Bram Moolenaar65c836e2017-01-26 22:07:33 +0100279
280func Test_CmdErrors()
281 call assert_fails('com! docmd :', 'E183:')
282 call assert_fails('com! \<Tab> :', 'E182:')
283 call assert_fails('com! _ :', 'E182:')
284 call assert_fails('com! X :', 'E841:')
285 call assert_fails('com! - DoCmd :', 'E175:')
286 call assert_fails('com! -xxx DoCmd :', 'E181:')
287 call assert_fails('com! -addr DoCmd :', 'E179:')
Bram Moolenaare61e5482019-04-27 15:05:12 +0200288 call assert_fails('com! -addr=asdf DoCmd :', 'E180:')
Bram Moolenaar65c836e2017-01-26 22:07:33 +0100289 call assert_fails('com! -complete DoCmd :', 'E179:')
290 call assert_fails('com! -complete=xxx DoCmd :', 'E180:')
291 call assert_fails('com! -complete=custom DoCmd :', 'E467:')
292 call assert_fails('com! -complete=customlist DoCmd :', 'E467:')
293 call assert_fails('com! -complete=behave,CustomComplete DoCmd :', 'E468:')
294 call assert_fails('com! -nargs=x DoCmd :', 'E176:')
295 call assert_fails('com! -count=1 -count=2 DoCmd :', 'E177:')
296 call assert_fails('com! -count=x DoCmd :', 'E178:')
297 call assert_fails('com! -range=x DoCmd :', 'E178:')
298
Bram Moolenaarcc7eb2a2021-07-11 19:12:04 +0200299 com! -complete=file DoCmd :
300 call assert_match('E1208:', v:warningmsg)
301 let v:warningmsg = ''
302 com! -nargs=0 -complete=file DoCmd :
303 call assert_match('E1208:', v:warningmsg)
304
305 let lines =<< trim END
306 vim9script
307 com! -complete=file DoCmd :
308 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000309 call v9.CheckScriptFailure(lines, 'E1208', 2)
Bram Moolenaarcc7eb2a2021-07-11 19:12:04 +0200310
311 let lines =<< trim END
312 vim9script
313 com! -nargs=0 -complete=file DoCmd :
314 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000315 call v9.CheckScriptFailure(lines, 'E1208', 2)
Bram Moolenaarcc7eb2a2021-07-11 19:12:04 +0200316
Bram Moolenaar65c836e2017-01-26 22:07:33 +0100317 com! -nargs=0 DoCmd :
318 call assert_fails('DoCmd x', 'E488:')
319
320 com! -nargs=1 DoCmd :
321 call assert_fails('DoCmd', 'E471:')
322
323 com! -nargs=+ DoCmd :
324 call assert_fails('DoCmd', 'E471:')
325
326 call assert_fails('com DoCmd :', 'E174:')
327 comclear
328 call assert_fails('delcom DoCmd', 'E184:')
329endfunc
330
331func CustomComplete(A, L, P)
332 return "January\nFebruary\nMars\n"
333endfunc
334
335func CustomCompleteList(A, L, P)
Yegappan Lakshmanan9773db62022-02-14 11:10:59 +0000336 return [ "Monday", "Tuesday", "Wednesday", {}, test_null_string()]
Bram Moolenaar65c836e2017-01-26 22:07:33 +0100337endfunc
338
339func Test_CmdCompletion()
340 call feedkeys(":com -\<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaar326e7da2021-11-12 16:06:03 +0000341 call assert_equal('"com -addr bang bar buffer complete count keepscript nargs range register', @:)
Bram Moolenaar65c836e2017-01-26 22:07:33 +0100342
343 call feedkeys(":com -nargs=0 -\<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaar326e7da2021-11-12 16:06:03 +0000344 call assert_equal('"com -nargs=0 -addr bang bar buffer complete count keepscript nargs range register', @:)
Bram Moolenaar65c836e2017-01-26 22:07:33 +0100345
346 call feedkeys(":com -nargs=\<C-A>\<C-B>\"\<CR>", 'tx')
347 call assert_equal('"com -nargs=* + 0 1 ?', @:)
348
349 call feedkeys(":com -addr=\<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaar51a74542018-12-02 18:21:49 +0100350 call assert_equal('"com -addr=arguments buffers lines loaded_buffers other quickfix tabs windows', @:)
Bram Moolenaar65c836e2017-01-26 22:07:33 +0100351
352 call feedkeys(":com -complete=co\<C-A>\<C-B>\"\<CR>", 'tx')
353 call assert_equal('"com -complete=color command compiler', @:)
354
Yegappan Lakshmanan24384302022-02-17 11:26:42 +0000355 " try completion for unsupported argument values
356 call feedkeys(":com -newarg=\<Tab>\<C-B>\"\<CR>", 'tx')
357 call assert_equal("\"com -newarg=\t", @:)
358
359 " command completion after the name in a user defined command
360 call feedkeys(":com MyCmd chist\<Tab>\<C-B>\"\<CR>", 'tx')
361 call assert_equal("\"com MyCmd chistory", @:)
362
Bram Moolenaar65c836e2017-01-26 22:07:33 +0100363 command! DoCmd1 :
364 command! DoCmd2 :
365 call feedkeys(":com \<C-A>\<C-B>\"\<CR>", 'tx')
366 call assert_equal('"com DoCmd1 DoCmd2', @:)
367
368 call feedkeys(":DoC\<C-A>\<C-B>\"\<CR>", 'tx')
369 call assert_equal('"DoCmd1 DoCmd2', @:)
370
371 call feedkeys(":delcom DoC\<C-A>\<C-B>\"\<CR>", 'tx')
372 call assert_equal('"delcom DoCmd1 DoCmd2', @:)
373
Yegappan Lakshmanan24384302022-02-17 11:26:42 +0000374 " try argument completion for a command without completion
375 call feedkeys(":DoCmd1 \<Tab>\<C-B>\"\<CR>", 'tx')
376 call assert_equal("\"DoCmd1 \t", @:)
377
Bram Moolenaar65c836e2017-01-26 22:07:33 +0100378 delcom DoCmd1
379 call feedkeys(":delcom DoC\<C-A>\<C-B>\"\<CR>", 'tx')
380 call assert_equal('"delcom DoCmd2', @:)
381
382 call feedkeys(":com DoC\<C-A>\<C-B>\"\<CR>", 'tx')
383 call assert_equal('"com DoCmd2', @:)
384
385 delcom DoCmd2
386 call feedkeys(":delcom DoC\<C-A>\<C-B>\"\<CR>", 'tx')
387 call assert_equal('"delcom DoC', @:)
388
389 call feedkeys(":com DoC\<C-A>\<C-B>\"\<CR>", 'tx')
390 call assert_equal('"com DoC', @:)
391
Martin Tournoijde69a732021-07-11 14:28:25 +0200392 com! -nargs=1 -complete=behave DoCmd :
Bram Moolenaar65c836e2017-01-26 22:07:33 +0100393 call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx')
394 call assert_equal('"DoCmd mswin xterm', @:)
395
Yegappan Lakshmanan24384302022-02-17 11:26:42 +0000396 " Test for file name completion
397 com! -nargs=1 -complete=file DoCmd :
398 call feedkeys(":DoCmd READM\<Tab>\<C-B>\"\<CR>", 'tx')
399 call assert_equal('"DoCmd README.txt', @:)
400
401 " Test for buffer name completion
402 com! -nargs=1 -complete=buffer DoCmd :
403 let bnum = bufadd('BufForUserCmd')
404 call setbufvar(bnum, '&buflisted', 1)
405 call feedkeys(":DoCmd BufFor\<Tab>\<C-B>\"\<CR>", 'tx')
406 call assert_equal('"DoCmd BufForUserCmd', @:)
407 bwipe BufForUserCmd
408 call feedkeys(":DoCmd BufFor\<Tab>\<C-B>\"\<CR>", 'tx')
409 call assert_equal('"DoCmd BufFor', @:)
410
Martin Tournoijde69a732021-07-11 14:28:25 +0200411 com! -nargs=* -complete=custom,CustomComplete DoCmd :
Bram Moolenaar65c836e2017-01-26 22:07:33 +0100412 call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx')
413 call assert_equal('"DoCmd January February Mars', @:)
414
Martin Tournoijde69a732021-07-11 14:28:25 +0200415 com! -nargs=? -complete=customlist,CustomCompleteList DoCmd :
Bram Moolenaar65c836e2017-01-26 22:07:33 +0100416 call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx')
417 call assert_equal('"DoCmd Monday Tuesday Wednesday', @:)
418
Martin Tournoijde69a732021-07-11 14:28:25 +0200419 com! -nargs=+ -complete=custom,CustomCompleteList DoCmd :
Bram Moolenaar65c836e2017-01-26 22:07:33 +0100420 call assert_fails("call feedkeys(':DoCmd \<C-D>', 'tx')", 'E730:')
421
Martin Tournoijde69a732021-07-11 14:28:25 +0200422 com! -nargs=+ -complete=customlist,CustomComp DoCmd :
Bram Moolenaar65c836e2017-01-26 22:07:33 +0100423 call assert_fails("call feedkeys(':DoCmd \<C-D>', 'tx')", 'E117:')
Bram Moolenaar24ebd832020-03-16 21:25:24 +0100424
425 " custom completion without a function
Martin Tournoijde69a732021-07-11 14:28:25 +0200426 com! -nargs=? -complete=custom, DoCmd
Bram Moolenaar24ebd832020-03-16 21:25:24 +0100427 call assert_beeps("call feedkeys(':DoCmd \t', 'tx')")
428
Bram Moolenaar9d8d0b52020-04-24 22:47:31 +0200429 " custom completion failure with the wrong function
Martin Tournoijde69a732021-07-11 14:28:25 +0200430 com! -nargs=? -complete=custom,min DoCmd
Bram Moolenaar9d8d0b52020-04-24 22:47:31 +0200431 call assert_fails("call feedkeys(':DoCmd \t', 'tx')", 'E118:')
432
Yegappan Lakshmanan4d03d872022-02-13 11:45:09 +0000433 " custom completion for a pattern with a backslash
434 let g:ArgLead = ''
435 func! CustCompl(A, L, P)
436 let g:ArgLead = a:A
437 return ['one', 'two', 'three']
438 endfunc
439 com! -nargs=? -complete=customlist,CustCompl DoCmd
440 call feedkeys(":DoCmd a\\\t", 'xt')
441 call assert_equal('a\', g:ArgLead)
442 delfunc CustCompl
443
Bram Moolenaar24ebd832020-03-16 21:25:24 +0100444 delcom DoCmd
Bram Moolenaar65c836e2017-01-26 22:07:33 +0100445endfunc
Bram Moolenaar20951482017-12-25 13:44:43 +0100446
447func CallExecute(A, L, P)
448 " Drop first '\n'
449 return execute('echo "hi"')[1:]
450endfunc
451
452func Test_use_execute_in_completion()
453 command! -nargs=* -complete=custom,CallExecute DoExec :
454 call feedkeys(":DoExec \<C-A>\<C-B>\"\<CR>", 'tx')
455 call assert_equal('"DoExec hi', @:)
456 delcommand DoExec
457endfunc
Bram Moolenaar51a74542018-12-02 18:21:49 +0100458
459func Test_addr_all()
460 command! -addr=lines DoSomething let g:a1 = <line1> | let g:a2 = <line2>
461 %DoSomething
462 call assert_equal(1, g:a1)
463 call assert_equal(line('$'), g:a2)
464
465 command! -addr=arguments DoSomething let g:a1 = <line1> | let g:a2 = <line2>
466 args one two three
467 %DoSomething
468 call assert_equal(1, g:a1)
469 call assert_equal(3, g:a2)
470
471 command! -addr=buffers DoSomething let g:a1 = <line1> | let g:a2 = <line2>
472 %DoSomething
473 for low in range(1, bufnr('$'))
474 if buflisted(low)
475 break
476 endif
477 endfor
478 call assert_equal(low, g:a1)
479 call assert_equal(bufnr('$'), g:a2)
480
481 command! -addr=loaded_buffers DoSomething let g:a1 = <line1> | let g:a2 = <line2>
482 %DoSomething
483 for low in range(1, bufnr('$'))
484 if bufloaded(low)
485 break
486 endif
487 endfor
488 call assert_equal(low, g:a1)
489 for up in range(bufnr('$'), 1, -1)
490 if bufloaded(up)
491 break
492 endif
493 endfor
494 call assert_equal(up, g:a2)
495
496 command! -addr=windows DoSomething let g:a1 = <line1> | let g:a2 = <line2>
497 new
498 %DoSomething
499 call assert_equal(1, g:a1)
500 call assert_equal(winnr('$'), g:a2)
501 bwipe
502
503 command! -addr=tabs DoSomething let g:a1 = <line1> | let g:a2 = <line2>
504 tabnew
505 %DoSomething
506 call assert_equal(1, g:a1)
507 call assert_equal(len(gettabinfo()), g:a2)
508 bwipe
509
Bram Moolenaarb7316892019-05-01 18:08:42 +0200510 command! -addr=other DoSomething let g:a1 = <line1> | let g:a2 = <line2>
Bram Moolenaar51a74542018-12-02 18:21:49 +0100511 DoSomething
Bram Moolenaarb7316892019-05-01 18:08:42 +0200512 call assert_equal(line('.'), g:a1)
513 call assert_equal(line('.'), g:a2)
514 %DoSomething
515 call assert_equal(1, g:a1)
516 call assert_equal(line('$'), g:a2)
Bram Moolenaar51a74542018-12-02 18:21:49 +0100517
518 delcommand DoSomething
519endfunc
Bram Moolenaard1f90bb2019-04-25 22:42:07 +0200520
521func Test_command_list()
522 command! DoCmd :
523 call assert_equal("\n Name Args Address Complete Definition"
524 \ .. "\n DoCmd 0 :",
525 \ execute('command DoCmd'))
526
527 " Test with various -range= and -count= argument values.
528 command! -range DoCmd :
529 call assert_equal("\n Name Args Address Complete Definition"
530 \ .. "\n DoCmd 0 . :",
531 \ execute('command DoCmd'))
532 command! -range=% DoCmd :
533 call assert_equal("\n Name Args Address Complete Definition"
534 \ .. "\n DoCmd 0 % :",
535 \ execute('command! DoCmd'))
536 command! -range=2 DoCmd :
537 call assert_equal("\n Name Args Address Complete Definition"
538 \ .. "\n DoCmd 0 2 :",
539 \ execute('command DoCmd'))
540 command! -count=2 DoCmd :
541 call assert_equal("\n Name Args Address Complete Definition"
Bram Moolenaarb7316892019-05-01 18:08:42 +0200542 \ .. "\n DoCmd 0 2c ? :",
Bram Moolenaard1f90bb2019-04-25 22:42:07 +0200543 \ execute('command DoCmd'))
544
545 " Test with various -addr= argument values.
546 command! -addr=lines DoCmd :
547 call assert_equal("\n Name Args Address Complete Definition"
548 \ .. "\n DoCmd 0 . :",
549 \ execute('command DoCmd'))
550 command! -addr=arguments DoCmd :
551 call assert_equal("\n Name Args Address Complete Definition"
552 \ .. "\n DoCmd 0 . arg :",
553 \ execute('command DoCmd'))
554 command! -addr=buffers DoCmd :
555 call assert_equal("\n Name Args Address Complete Definition"
556 \ .. "\n DoCmd 0 . buf :",
557 \ execute('command DoCmd'))
558 command! -addr=loaded_buffers DoCmd :
559 call assert_equal("\n Name Args Address Complete Definition"
560 \ .. "\n DoCmd 0 . load :",
561 \ execute('command DoCmd'))
562 command! -addr=windows DoCmd :
563 call assert_equal("\n Name Args Address Complete Definition"
564 \ .. "\n DoCmd 0 . win :",
565 \ execute('command DoCmd'))
566 command! -addr=tabs DoCmd :
567 call assert_equal("\n Name Args Address Complete Definition"
568 \ .. "\n DoCmd 0 . tab :",
569 \ execute('command DoCmd'))
570 command! -addr=other DoCmd :
571 call assert_equal("\n Name Args Address Complete Definition"
572 \ .. "\n DoCmd 0 . ? :",
573 \ execute('command DoCmd'))
574
575 " Test with various -complete= argument values (non-exhaustive list)
Martin Tournoijde69a732021-07-11 14:28:25 +0200576 command! -nargs=1 -complete=arglist DoCmd :
Bram Moolenaard1f90bb2019-04-25 22:42:07 +0200577 call assert_equal("\n Name Args Address Complete Definition"
Martin Tournoijde69a732021-07-11 14:28:25 +0200578 \ .. "\n DoCmd 1 arglist :",
Bram Moolenaard1f90bb2019-04-25 22:42:07 +0200579 \ execute('command DoCmd'))
Martin Tournoijde69a732021-07-11 14:28:25 +0200580 command! -nargs=* -complete=augroup DoCmd :
Bram Moolenaard1f90bb2019-04-25 22:42:07 +0200581 call assert_equal("\n Name Args Address Complete Definition"
Martin Tournoijde69a732021-07-11 14:28:25 +0200582 \ .. "\n DoCmd * augroup :",
Bram Moolenaard1f90bb2019-04-25 22:42:07 +0200583 \ execute('command DoCmd'))
Martin Tournoijde69a732021-07-11 14:28:25 +0200584 command! -nargs=? -complete=custom,CustomComplete DoCmd :
Bram Moolenaard1f90bb2019-04-25 22:42:07 +0200585 call assert_equal("\n Name Args Address Complete Definition"
Martin Tournoijde69a732021-07-11 14:28:25 +0200586 \ .. "\n DoCmd ? custom :",
Bram Moolenaard1f90bb2019-04-25 22:42:07 +0200587 \ execute('command DoCmd'))
Martin Tournoijde69a732021-07-11 14:28:25 +0200588 command! -nargs=+ -complete=customlist,CustomComplete DoCmd :
Bram Moolenaard1f90bb2019-04-25 22:42:07 +0200589 call assert_equal("\n Name Args Address Complete Definition"
Martin Tournoijde69a732021-07-11 14:28:25 +0200590 \ .. "\n DoCmd + customlist :",
Bram Moolenaard1f90bb2019-04-25 22:42:07 +0200591 \ execute('command DoCmd'))
592
593 " Test with various -narg= argument values.
594 command! -nargs=0 DoCmd :
595 call assert_equal("\n Name Args Address Complete Definition"
596 \ .. "\n DoCmd 0 :",
597 \ execute('command DoCmd'))
598 command! -nargs=1 DoCmd :
599 call assert_equal("\n Name Args Address Complete Definition"
600 \ .. "\n DoCmd 1 :",
601 \ execute('command DoCmd'))
602 command! -nargs=* DoCmd :
603 call assert_equal("\n Name Args Address Complete Definition"
604 \ .. "\n DoCmd * :",
605 \ execute('command DoCmd'))
606 command! -nargs=? DoCmd :
607 call assert_equal("\n Name Args Address Complete Definition"
608 \ .. "\n DoCmd ? :",
609 \ execute('command DoCmd'))
610 command! -nargs=+ DoCmd :
611 call assert_equal("\n Name Args Address Complete Definition"
612 \ .. "\n DoCmd + :",
613 \ execute('command DoCmd'))
614
615 " Test with other arguments.
616 command! -bang DoCmd :
617 call assert_equal("\n Name Args Address Complete Definition"
618 \ .. "\n! DoCmd 0 :",
619 \ execute('command DoCmd'))
620 command! -bar DoCmd :
621 call assert_equal("\n Name Args Address Complete Definition"
622 \ .. "\n| DoCmd 0 :",
623 \ execute('command DoCmd'))
624 command! -register DoCmd :
625 call assert_equal("\n Name Args Address Complete Definition"
626 \ .. "\n\" DoCmd 0 :",
627 \ execute('command DoCmd'))
628 command! -buffer DoCmd :
629 call assert_equal("\n Name Args Address Complete Definition"
630 \ .. "\nb DoCmd 0 :"
631 \ .. "\n\" DoCmd 0 :",
632 \ execute('command DoCmd'))
633 comclear
634
635 " Test with many args.
636 command! -bang -bar -register -buffer -nargs=+ -complete=environment -addr=windows -count=3 DoCmd :
637 call assert_equal("\n Name Args Address Complete Definition"
638 \ .. "\n!\"b|DoCmd + 3c win environment :",
639 \ execute('command DoCmd'))
640 comclear
641
642 " Test with special characters in command definition.
643 command! DoCmd :<cr><tab><c-d>
644 call assert_equal("\n Name Args Address Complete Definition"
645 \ .. "\n DoCmd 0 :<CR><Tab><C-D>",
646 \ execute('command DoCmd'))
647
648 " Test output in verbose mode.
Bram Moolenaar3f3597b2022-01-17 19:06:56 +0000649 command! -nargs=+ -complete=customlist,SomeFunc DoCmd :ls
Bram Moolenaard1f90bb2019-04-25 22:42:07 +0200650 call assert_match("^\n"
651 \ .. " Name Args Address Complete Definition\n"
Bram Moolenaar3f3597b2022-01-17 19:06:56 +0000652 \ .. " DoCmd + customlist,SomeFunc :ls\n"
Bram Moolenaard1f90bb2019-04-25 22:42:07 +0200653 \ .. "\tLast set from .*/test_usercommands.vim line \\d\\+$",
654 \ execute('verbose command DoCmd'))
655
656 comclear
657 call assert_equal("\nNo user-defined commands found", execute(':command Xxx'))
658 call assert_equal("\nNo user-defined commands found", execute('command'))
659endfunc
Bram Moolenaar24ebd832020-03-16 21:25:24 +0100660
Bram Moolenaar8b633132020-03-20 18:20:51 +0100661" Test for a custom user completion returning the wrong value type
662func Test_usercmd_custom()
663 func T1(a, c, p)
664 return "a\nb\n"
665 endfunc
666 command -nargs=* -complete=customlist,T1 TCmd1
Bram Moolenaar55e93662022-09-10 13:52:26 +0100667 call assert_fails('call feedkeys(":TCmd1 \<C-A>\<C-B>\"\<CR>", "xt")', 'E1303: Custom list completion function does not return a List but a string')
Bram Moolenaarea04a6e2020-04-23 13:38:02 +0200668 call assert_equal('"TCmd1 ', @:)
Bram Moolenaar8b633132020-03-20 18:20:51 +0100669 delcommand TCmd1
670 delfunc T1
671
672 func T2(a, c, p)
Bram Moolenaarea04a6e2020-04-23 13:38:02 +0200673 return {}
Bram Moolenaar8b633132020-03-20 18:20:51 +0100674 endfunc
675 command -nargs=* -complete=customlist,T2 TCmd2
Bram Moolenaar55e93662022-09-10 13:52:26 +0100676 call assert_fails('call feedkeys(":TCmd2 \<C-A>\<C-B>\"\<CR>", "xt")', 'E1303: Custom list completion function does not return a List but a dict')
Bram Moolenaarea04a6e2020-04-23 13:38:02 +0200677 call assert_equal('"TCmd2 ', @:)
Bram Moolenaar8b633132020-03-20 18:20:51 +0100678 delcommand TCmd2
679 delfunc T2
680endfunc
681
Bram Moolenaar5d7c2df2021-07-27 21:17:32 +0200682func Test_usercmd_with_block()
683 command DoSomething {
Bram Moolenaarec1b0962021-09-06 17:10:59 +0200684 g:didit = 'yes' # comment
685 # comment line
Bram Moolenaar5d7c2df2021-07-27 21:17:32 +0200686 g:didmore = 'more'
687 }
688 DoSomething
689 call assert_equal('yes', g:didit)
690 call assert_equal('more', g:didmore)
691 unlet g:didit
692 unlet g:didmore
Bram Moolenaar68686342021-07-28 15:54:54 +0200693 delcommand DoSomething
694
695 command DoMap {
696 echo [1, 2, 3]->map((_, v) => v + 1)
697 }
698 DoMap
699 delcommand DoMap
Bram Moolenaar5d7c2df2021-07-27 21:17:32 +0200700
701 let lines =<< trim END
702 command DoesNotEnd {
703 echo 'hello'
704 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000705 call v9.CheckScriptFailure(lines, 'E1026:')
Bram Moolenaar63b91732021-08-05 20:40:03 +0200706
707 let lines =<< trim END
Bram Moolenaarf87dac02021-12-15 17:53:40 +0000708 command HelloThere {
Bram Moolenaar63b91732021-08-05 20:40:03 +0200709 echo 'hello' | echo 'there'
710 }
Bram Moolenaarf87dac02021-12-15 17:53:40 +0000711 HelloThere
Bram Moolenaar63b91732021-08-05 20:40:03 +0200712 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000713 call v9.CheckScriptSuccess(lines)
Bram Moolenaarf87dac02021-12-15 17:53:40 +0000714 delcommand HelloThere
715
716 let lines =<< trim END
Bram Moolenaare442d592022-05-05 12:20:28 +0100717 command EchoCond {
718 const test: string = true
719 ? 'true'
720 : 'false'
721 g:result = test
722 }
723 EchoCond
724 END
725 call v9.CheckScriptSuccess(lines)
726 call assert_equal('true', g:result)
Bram Moolenaara13e7ac2022-05-06 21:24:31 +0100727 unlet g:result
728
729 call feedkeys(":EchoCond\<CR>", 'xt')
730 call assert_equal('true', g:result)
731
Bram Moolenaare442d592022-05-05 12:20:28 +0100732 delcommand EchoCond
733 unlet g:result
734
735 let lines =<< trim END
Bram Moolenaarf87dac02021-12-15 17:53:40 +0000736 command BadCommand {
737 echo {
738 'key': 'value',
739 }
740 }
741 BadCommand
742 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000743 call v9.CheckScriptFailure(lines, 'E1128:')
Bram Moolenaar5d7c2df2021-07-27 21:17:32 +0200744endfunc
745
Bram Moolenaarbdcba242021-09-12 20:58:02 +0200746func Test_delcommand_buffer()
747 command Global echo 'global'
748 command -buffer OneBuffer echo 'one'
749 new
750 command -buffer TwoBuffer echo 'two'
751 call assert_equal(0, exists(':OneBuffer'))
752 call assert_equal(2, exists(':Global'))
753 call assert_equal(2, exists(':TwoBuffer'))
754 delcommand -buffer TwoBuffer
755 call assert_equal(0, exists(':TwoBuffer'))
756 call assert_fails('delcommand -buffer Global', 'E1237:')
757 call assert_fails('delcommand -buffer OneBuffer', 'E1237:')
758 bwipe!
759 call assert_equal(2, exists(':OneBuffer'))
760 delcommand -buffer OneBuffer
761 call assert_equal(0, exists(':OneBuffer'))
762 call assert_fails('delcommand -buffer Global', 'E1237:')
763 delcommand Global
764 call assert_equal(0, exists(':Global'))
765endfunc
766
Bram Moolenaaraf377e32021-11-29 12:12:43 +0000767def Test_count_with_quotes()
768 command -count GetCount g:nr = <count>
769 execute("GetCount 1'2")
770 assert_equal(12, g:nr)
771 execute("GetCount 1'234'567")
772 assert_equal(1'234'567, g:nr)
773
774 execute("GetCount 1'234'567'890'123'456'789'012")
775 assert_equal(v:sizeoflong == 8 ? 9223372036854775807 : 2147483647, g:nr)
776
777 # TODO: test with negative number once this is supported
778
779 assert_fails("GetCount '12", "E488:")
780 assert_fails("GetCount 12'", "E488:")
781 assert_fails("GetCount 1''2", "E488:")
782
783 assert_fails(":1'2GetCount", 'E492:')
784 new
785 setline(1, 'text')
786 normal ma
787 execute(":1, 'aprint")
788 bwipe!
789
790 unlet g:nr
791 delcommand GetCount
792enddef
793
Bram Moolenaar205f29c2021-12-10 21:46:09 +0000794func DefCmd(name)
795 if len(a:name) > 30
796 return
797 endif
798 exe 'command ' .. a:name .. ' call DefCmd("' .. a:name .. 'x")'
799 echo a:name
800 exe a:name
801endfunc
802
803func Test_recursive_define()
804 call DefCmd('Command')
805
806 let name = 'Command'
807 while len(name) < 30
808 exe 'delcommand ' .. name
809 let name ..= 'x'
810 endwhile
811endfunc
812
Yegappan Lakshmanan24384302022-02-17 11:26:42 +0000813" Test for using buffer-local ambiguous user-defined commands
814func Test_buflocal_ambiguous_usercmd()
815 new
816 command -buffer -nargs=1 -complete=sign TestCmd1 echo "Hello"
817 command -buffer -nargs=1 -complete=sign TestCmd2 echo "World"
818
819 call assert_fails("call feedkeys(':TestCmd\<CR>', 'xt')", 'E464:')
820 call feedkeys(":TestCmd \<Tab>\<C-B>\"\<CR>", 'xt')
821 call assert_equal('"TestCmd ', @:)
822
823 delcommand TestCmd1
824 delcommand TestCmd2
825 bw!
826endfunc
827
828" Test for using a multibyte character in a user command
829func Test_multibyte_in_usercmd()
830 command SubJapanesePeriodToDot exe "%s/\u3002/./g"
831 new
832 call setline(1, "Hello\u3002")
833 SubJapanesePeriodToDot
834 call assert_equal('Hello.', getline(1))
835 bw!
836 delcommand SubJapanesePeriodToDot
837endfunc
Bram Moolenaaraf377e32021-11-29 12:12:43 +0000838
Bram Moolenaar98b7fe72022-03-23 21:36:27 +0000839" Declaring a variable in a {} uses Vim9 script rules, even when defined in a
840" legacy script.
841func Test_block_declaration_legacy_script()
842 let lines =<< trim END
843 command -range Rename {
844 var save = @a
845 @a = 'something'
846 g:someExpr = @a
847 @a = save
848 }
849 END
Bram Moolenaar5b148ef2022-10-15 21:35:56 +0100850 call writefile(lines, 'Xlegacy', 'D')
Bram Moolenaar98b7fe72022-03-23 21:36:27 +0000851 source Xlegacy
852
853 let lines =<< trim END
854 let @a = 'saved'
855 Rename
856 call assert_equal('something', g:someExpr)
857 call assert_equal('saved', @a)
858
859 let g:someExpr = 'xxx'
860 let @a = 'also'
861 Rename
862 call assert_equal('something', g:someExpr)
863 call assert_equal('also', @a)
864 END
Bram Moolenaar5b148ef2022-10-15 21:35:56 +0100865 call writefile(lines, 'Xother', 'D')
Bram Moolenaar98b7fe72022-03-23 21:36:27 +0000866 source Xother
867
868 unlet g:someExpr
Bram Moolenaar98b7fe72022-03-23 21:36:27 +0000869 delcommand Rename
870endfunc
871
872
Bram Moolenaar24ebd832020-03-16 21:25:24 +0100873" vim: shiftwidth=2 sts=2 expandtab