blob: 82f808862db174e61bf034376238a9236f089617 [file] [log] [blame]
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001" Test various aspects of the Vim9 script language.
2
Bram Moolenaar673660a2020-01-26 16:50:05 +01003source check.vim
Bram Moolenaar101f4812020-06-16 23:18:51 +02004source term_util.vim
Bram Moolenaar62aec932022-01-29 21:45:34 +00005import './vim9.vim' as v9
Bram Moolenaar37294bd2021-03-10 13:40:08 +01006source screendump.vim
Bram Moolenaard8448622022-01-07 21:39:52 +00007source shared.vim
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01008
Bram Moolenaarb79ee0c2022-01-01 12:17:00 +00009def Test_vim9script_feature()
10 # example from the help, here the feature is always present
11 var lines =<< trim END
12 " old style comment
13 if !has('vim9script')
14 " legacy commands would go here
15 finish
16 endif
17 vim9script
18 # Vim9 script commands go here
19 g:didit = true
20 END
Bram Moolenaar62aec932022-01-29 21:45:34 +000021 v9.CheckScriptSuccess(lines)
Bram Moolenaarb79ee0c2022-01-01 12:17:00 +000022 assert_equal(true, g:didit)
23 unlet g:didit
24enddef
25
Bram Moolenaar5d72ce62020-08-20 23:04:06 +020026def Test_range_only()
27 new
28 setline(1, ['blah', 'Blah'])
29 :/Blah/
30 assert_equal(2, getcurpos()[1])
Bram Moolenaarc2af0af2020-08-23 21:06:02 +020031 bwipe!
32
33 # without range commands use current line
34 new
35 setline(1, ['one', 'two', 'three'])
36 :2
37 print
Bram Moolenaar62aec932022-01-29 21:45:34 +000038 assert_equal('two', g:Screenline(&lines))
Bram Moolenaarc2af0af2020-08-23 21:06:02 +020039 :3
40 list
Bram Moolenaar62aec932022-01-29 21:45:34 +000041 assert_equal('three$', g:Screenline(&lines))
Bram Moolenaarb8554302021-02-15 21:30:30 +010042
43 # missing command does not print the line
44 var lines =<< trim END
45 vim9script
46 :1|
Bram Moolenaar62aec932022-01-29 21:45:34 +000047 assert_equal('three$', g:Screenline(&lines))
Bram Moolenaarb8554302021-02-15 21:30:30 +010048 :|
Bram Moolenaar62aec932022-01-29 21:45:34 +000049 assert_equal('three$', g:Screenline(&lines))
Bram Moolenaarb8554302021-02-15 21:30:30 +010050 END
Bram Moolenaar62aec932022-01-29 21:45:34 +000051 v9.CheckScriptSuccess(lines)
Bram Moolenaarb8554302021-02-15 21:30:30 +010052
Bram Moolenaarc2af0af2020-08-23 21:06:02 +020053 bwipe!
Bram Moolenaar025cb1c2020-12-14 18:31:27 +010054
Bram Moolenaar0c7f2612022-02-17 19:44:07 +000055 lines =<< trim END
56 set cpo+=-
57 :1,999
58 END
59 v9.CheckDefExecAndScriptFailure(lines, 'E16:', 2)
60 set cpo&vim
61
62 v9.CheckDefExecAndScriptFailure([":'x"], 'E20:', 1)
63
Bram Moolenaar025cb1c2020-12-14 18:31:27 +010064 # won't generate anything
65 if false
66 :123
67 endif
Bram Moolenaar5d72ce62020-08-20 23:04:06 +020068enddef
69
Bram Moolenaar09d94212022-05-05 15:20:03 +010070def Test_invalid_range()
71 var lines =<< trim END
72 :123 eval 1 + 2
73 END
74 v9.CheckDefAndScriptFailure(lines, 'E481:', 1)
75
76 lines =<< trim END
77 :123 if true
78 endif
79 END
80 v9.CheckDefAndScriptFailure(lines, 'E481:', 1)
81
82 lines =<< trim END
83 :123 echo 'yes'
84 END
85 v9.CheckDefAndScriptFailure(lines, 'E481:', 1)
86
87 lines =<< trim END
88 :123 cd there
89 END
90 v9.CheckDefAndScriptFailure(lines, 'E481:', 1)
91enddef
92
Bram Moolenaara6e67e42020-05-15 23:36:40 +020093let g:alist = [7]
94let g:astring = 'text'
Bram Moolenaarf0b9f432020-07-17 23:03:17 +020095let g:anumber = 123
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010096
Bram Moolenaar4c17ad92020-04-27 22:47:51 +020097def Test_delfunction()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +020098 # Check function is defined in script namespace
Bram Moolenaar62aec932022-01-29 21:45:34 +000099 v9.CheckScriptSuccess([
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200100 'vim9script',
101 'func CheckMe()',
102 ' return 123',
103 'endfunc',
Bram Moolenaara749a422022-02-12 19:52:25 +0000104 'func DoTest()',
105 ' call assert_equal(123, s:CheckMe())',
106 'endfunc',
107 'DoTest()',
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200108 ])
109
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200110 # Check function in script namespace cannot be deleted
Bram Moolenaar62aec932022-01-29 21:45:34 +0000111 v9.CheckScriptFailure([
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200112 'vim9script',
113 'func DeleteMe1()',
114 'endfunc',
115 'delfunction DeleteMe1',
116 ], 'E1084:')
Bram Moolenaar62aec932022-01-29 21:45:34 +0000117 v9.CheckScriptFailure([
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200118 'vim9script',
119 'func DeleteMe2()',
120 'endfunc',
121 'def DoThat()',
122 ' delfunction DeleteMe2',
123 'enddef',
124 'DoThat()',
125 ], 'E1084:')
Bram Moolenaar62aec932022-01-29 21:45:34 +0000126 v9.CheckScriptFailure([
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200127 'vim9script',
128 'def DeleteMe3()',
129 'enddef',
130 'delfunction DeleteMe3',
131 ], 'E1084:')
Bram Moolenaar62aec932022-01-29 21:45:34 +0000132 v9.CheckScriptFailure([
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200133 'vim9script',
134 'def DeleteMe4()',
135 'enddef',
136 'def DoThat()',
137 ' delfunction DeleteMe4',
138 'enddef',
139 'DoThat()',
140 ], 'E1084:')
Bram Moolenaar925e9fd2020-07-25 15:41:11 +0200141
142 # Check that global :def function can be replaced and deleted
Bram Moolenaarcfcd0112020-09-27 15:19:27 +0200143 var lines =<< trim END
Bram Moolenaar925e9fd2020-07-25 15:41:11 +0200144 vim9script
145 def g:Global(): string
146 return "yes"
147 enddef
148 assert_equal("yes", g:Global())
149 def! g:Global(): string
150 return "no"
151 enddef
152 assert_equal("no", g:Global())
153 delfunc g:Global
154 assert_false(exists('*g:Global'))
155 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000156 v9.CheckScriptSuccess(lines)
Bram Moolenaar925e9fd2020-07-25 15:41:11 +0200157
158 # Check that global function can be replaced by a :def function and deleted
159 lines =<< trim END
160 vim9script
161 func g:Global()
162 return "yes"
163 endfunc
164 assert_equal("yes", g:Global())
165 def! g:Global(): string
166 return "no"
167 enddef
168 assert_equal("no", g:Global())
169 delfunc g:Global
170 assert_false(exists('*g:Global'))
171 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000172 v9.CheckScriptSuccess(lines)
Bram Moolenaar925e9fd2020-07-25 15:41:11 +0200173
174 # Check that global :def function can be replaced by a function and deleted
175 lines =<< trim END
176 vim9script
177 def g:Global(): string
178 return "yes"
179 enddef
180 assert_equal("yes", g:Global())
181 func! g:Global()
182 return "no"
183 endfunc
184 assert_equal("no", g:Global())
185 delfunc g:Global
186 assert_false(exists('*g:Global'))
187 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000188 v9.CheckScriptSuccess(lines)
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200189enddef
190
Bram Moolenaar08052222020-09-14 17:04:31 +0200191def Test_wrong_type()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000192 v9.CheckDefFailure(['var name: list<nothing>'], 'E1010:')
193 v9.CheckDefFailure(['var name: list<list<nothing>>'], 'E1010:')
194 v9.CheckDefFailure(['var name: dict<nothing>'], 'E1010:')
195 v9.CheckDefFailure(['var name: dict<dict<nothing>>'], 'E1010:')
Bram Moolenaar599c89c2020-03-28 14:53:20 +0100196
Bram Moolenaar62aec932022-01-29 21:45:34 +0000197 v9.CheckDefFailure(['var name: dict<number'], 'E1009:')
198 v9.CheckDefFailure(['var name: dict<list<number>'], 'E1009:')
Bram Moolenaar42a480b2020-02-29 23:23:47 +0100199
Bram Moolenaar62aec932022-01-29 21:45:34 +0000200 v9.CheckDefFailure(['var name: ally'], 'E1010:')
201 v9.CheckDefFailure(['var name: bram'], 'E1010:')
202 v9.CheckDefFailure(['var name: cathy'], 'E1010:')
203 v9.CheckDefFailure(['var name: dom'], 'E1010:')
204 v9.CheckDefFailure(['var name: freddy'], 'E1010:')
205 v9.CheckDefFailure(['var name: john'], 'E1010:')
206 v9.CheckDefFailure(['var name: larry'], 'E1010:')
207 v9.CheckDefFailure(['var name: ned'], 'E1010:')
208 v9.CheckDefFailure(['var name: pam'], 'E1010:')
209 v9.CheckDefFailure(['var name: sam'], 'E1010:')
210 v9.CheckDefFailure(['var name: vim'], 'E1010:')
Bram Moolenaara0a9f432020-04-28 21:29:34 +0200211
Bram Moolenaar62aec932022-01-29 21:45:34 +0000212 v9.CheckDefFailure(['var Ref: number', 'Ref()'], 'E1085:')
213 v9.CheckDefFailure(['var Ref: string', 'var res = Ref()'], 'E1085:')
Bram Moolenaar08052222020-09-14 17:04:31 +0200214enddef
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100215
Bram Moolenaara749a422022-02-12 19:52:25 +0000216def Test_script_namespace()
217 # defining a function or variable with s: is not allowed
218 var lines =<< trim END
219 vim9script
220 def s:Function()
221 enddef
222 END
223 v9.CheckScriptFailure(lines, 'E1268:')
224
225 for decl in ['var', 'const', 'final']
226 lines =<< trim END
227 vim9script
228 var s:var = 'var'
229 END
230 v9.CheckScriptFailure([
231 'vim9script',
232 decl .. ' s:var = "var"',
233 ], 'E1268:')
234 endfor
235
236 # Calling a function or using a variable with s: is not allowed at script
237 # level
238 lines =<< trim END
239 vim9script
240 def Function()
241 enddef
242 s:Function()
243 END
244 v9.CheckScriptFailure(lines, 'E1268:')
245 lines =<< trim END
246 vim9script
247 def Function()
248 enddef
249 call s:Function()
250 END
251 v9.CheckScriptFailure(lines, 'E1268:')
252 lines =<< trim END
253 vim9script
254 var var = 'var'
255 echo s:var
256 END
257 v9.CheckScriptFailure(lines, 'E1268:')
258enddef
259
Bram Moolenaar10c65862020-10-08 21:16:42 +0200260def Test_script_wrong_type()
261 var lines =<< trim END
262 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +0000263 var dict: dict<string>
264 dict['a'] = ['x']
Bram Moolenaar10c65862020-10-08 21:16:42 +0200265 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000266 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got list<string>', 3)
Bram Moolenaar10c65862020-10-08 21:16:42 +0200267enddef
268
Bram Moolenaar08052222020-09-14 17:04:31 +0200269def Test_const()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000270 v9.CheckDefFailure(['final name = 234', 'name = 99'], 'E1018:')
271 v9.CheckDefFailure(['final one = 234', 'var one = 99'], 'E1017:')
272 v9.CheckDefFailure(['final list = [1, 2]', 'var list = [3, 4]'], 'E1017:')
273 v9.CheckDefFailure(['final two'], 'E1125:')
274 v9.CheckDefFailure(['final &option'], 'E996:')
Bram Moolenaardbeecb22020-09-14 18:15:09 +0200275
Bram Moolenaarcfcd0112020-09-27 15:19:27 +0200276 var lines =<< trim END
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200277 final list = [1, 2, 3]
Bram Moolenaardbeecb22020-09-14 18:15:09 +0200278 list[0] = 4
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200279 list->assert_equal([4, 2, 3])
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200280 const other = [5, 6, 7]
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200281 other->assert_equal([5, 6, 7])
Bram Moolenaar71abe482020-09-14 22:28:30 +0200282
Bram Moolenaarcfcd0112020-09-27 15:19:27 +0200283 var varlist = [7, 8]
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200284 const constlist = [1, varlist, 3]
Bram Moolenaar71abe482020-09-14 22:28:30 +0200285 varlist[0] = 77
Bram Moolenaar23e2e112021-08-03 21:16:18 +0200286 constlist[1][1] = 88
Bram Moolenaarcfcd0112020-09-27 15:19:27 +0200287 var cl = constlist[1]
Bram Moolenaar71abe482020-09-14 22:28:30 +0200288 cl[1] = 88
289 constlist->assert_equal([1, [77, 88], 3])
290
Bram Moolenaare0de1712020-12-02 17:36:54 +0100291 var vardict = {five: 5, six: 6}
292 const constdict = {one: 1, two: vardict, three: 3}
Bram Moolenaar71abe482020-09-14 22:28:30 +0200293 vardict['five'] = 55
Bram Moolenaar23e2e112021-08-03 21:16:18 +0200294 constdict['two']['six'] = 66
Bram Moolenaarcfcd0112020-09-27 15:19:27 +0200295 var cd = constdict['two']
Bram Moolenaar71abe482020-09-14 22:28:30 +0200296 cd['six'] = 66
Bram Moolenaare0de1712020-12-02 17:36:54 +0100297 constdict->assert_equal({one: 1, two: {five: 55, six: 66}, three: 3})
Bram Moolenaardbeecb22020-09-14 18:15:09 +0200298 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000299 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar0089ce22022-10-08 14:39:36 +0100300
301 # "any" type with const flag is recognized as "any"
302 lines =<< trim END
303 const dict: dict<any> = {foo: {bar: 42}}
304 const foo = dict.foo
305 assert_equal(v:t_number, type(foo.bar))
306 END
307 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar330d64d2022-10-09 12:55:33 +0100308
309 # also when used as a builtin function argument
310 lines =<< trim END
311 vim9script
312
313 def SorterFunc(lhs: dict<string>, rhs: dict<string>): number
314 return lhs.name <# rhs.name ? -1 : 1
315 enddef
316
317 def Run(): void
318 var list = [{name: "3"}, {name: "2"}]
319 const Sorter = get({}, "unknown", SorterFunc)
320 sort(list, Sorter)
321 assert_equal([{name: "2"}, {name: "3"}], list)
322 enddef
323
324 Run()
325 END
326 v9.CheckScriptSuccess(lines)
Bram Moolenaar08052222020-09-14 17:04:31 +0200327enddef
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100328
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200329def Test_const_bang()
Bram Moolenaarcfcd0112020-09-27 15:19:27 +0200330 var lines =<< trim END
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200331 const var = 234
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200332 var = 99
333 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000334 v9.CheckDefExecFailure(lines, 'E1018:', 2)
335 v9.CheckScriptFailure(['vim9script'] + lines, 'E46:', 3)
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200336
337 lines =<< trim END
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200338 const ll = [2, 3, 4]
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200339 ll[0] = 99
340 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000341 v9.CheckDefExecFailure(lines, 'E1119:', 2)
342 v9.CheckScriptFailure(['vim9script'] + lines, 'E741:', 3)
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200343
344 lines =<< trim END
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200345 const ll = [2, 3, 4]
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200346 ll[3] = 99
347 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000348 v9.CheckDefExecFailure(lines, 'E1118:', 2)
349 v9.CheckScriptFailure(['vim9script'] + lines, 'E684:', 3)
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200350
351 lines =<< trim END
Bram Moolenaare0de1712020-12-02 17:36:54 +0100352 const dd = {one: 1, two: 2}
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200353 dd["one"] = 99
354 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000355 v9.CheckDefExecFailure(lines, 'E1121:', 2)
356 v9.CheckScriptFailure(['vim9script'] + lines, 'E741:', 3)
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200357
358 lines =<< trim END
Bram Moolenaare0de1712020-12-02 17:36:54 +0100359 const dd = {one: 1, two: 2}
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200360 dd["three"] = 99
361 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000362 v9.CheckDefExecFailure(lines, 'E1120:')
363 v9.CheckScriptFailure(['vim9script'] + lines, 'E741:', 3)
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200364enddef
365
Bram Moolenaardf069ee2020-06-22 23:02:51 +0200366def Test_range_no_colon()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000367 v9.CheckDefFailure(['%s/a/b/'], 'E1050:')
368 v9.CheckDefFailure(['+ s/a/b/'], 'E1050:')
369 v9.CheckDefFailure(['- s/a/b/'], 'E1050:')
370 v9.CheckDefFailure(['. s/a/b/'], 'E1050:')
Bram Moolenaardf069ee2020-06-22 23:02:51 +0200371enddef
372
373
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100374def Test_block()
Bram Moolenaarcfcd0112020-09-27 15:19:27 +0200375 var outer = 1
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100376 {
Bram Moolenaarcfcd0112020-09-27 15:19:27 +0200377 var inner = 2
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100378 assert_equal(1, outer)
379 assert_equal(2, inner)
380 }
381 assert_equal(1, outer)
Bram Moolenaar3f1e9f02021-02-27 22:36:43 +0100382
383 {|echo 'yes'|}
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100384enddef
385
Bram Moolenaar08052222020-09-14 17:04:31 +0200386def Test_block_failure()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000387 v9.CheckDefFailure(['{', 'var inner = 1', '}', 'echo inner'], 'E1001:')
388 v9.CheckDefFailure(['}'], 'E1025:')
389 v9.CheckDefFailure(['{', 'echo 1'], 'E1026:')
Bram Moolenaar08052222020-09-14 17:04:31 +0200390enddef
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100391
Bram Moolenaarfbbcd002020-10-15 12:46:44 +0200392def Test_block_local_vars()
393 var lines =<< trim END
394 vim9script
Bram Moolenaared234f22020-10-15 20:42:20 +0200395 v:testing = 1
Bram Moolenaarfbbcd002020-10-15 12:46:44 +0200396 if true
Bram Moolenaared234f22020-10-15 20:42:20 +0200397 var text = ['hello']
398 def SayHello(): list<string>
Bram Moolenaarfbbcd002020-10-15 12:46:44 +0200399 return text
400 enddef
401 def SetText(v: string)
Bram Moolenaared234f22020-10-15 20:42:20 +0200402 text = [v]
Bram Moolenaarfbbcd002020-10-15 12:46:44 +0200403 enddef
404 endif
405
406 if true
Bram Moolenaared234f22020-10-15 20:42:20 +0200407 var text = ['again']
408 def SayAgain(): list<string>
Bram Moolenaarfbbcd002020-10-15 12:46:44 +0200409 return text
410 enddef
411 endif
Bram Moolenaared234f22020-10-15 20:42:20 +0200412
413 # test that the "text" variables are not cleaned up
414 test_garbagecollect_now()
415
Bram Moolenaarfbbcd002020-10-15 12:46:44 +0200416 defcompile
417
Bram Moolenaared234f22020-10-15 20:42:20 +0200418 assert_equal(['hello'], SayHello())
419 assert_equal(['again'], SayAgain())
Bram Moolenaarfbbcd002020-10-15 12:46:44 +0200420
421 SetText('foobar')
Bram Moolenaared234f22020-10-15 20:42:20 +0200422 assert_equal(['foobar'], SayHello())
423
424 call writefile(['ok'], 'Xdidit')
425 qall!
Bram Moolenaarfbbcd002020-10-15 12:46:44 +0200426 END
Bram Moolenaared234f22020-10-15 20:42:20 +0200427
428 # need to execute this with a separate Vim instance to avoid the current
429 # context gets garbage collected.
Bram Moolenaardd674772022-09-15 22:26:18 +0100430 writefile(lines, 'Xscript', 'D')
Bram Moolenaar62aec932022-01-29 21:45:34 +0000431 g:RunVim([], [], '-S Xscript')
Bram Moolenaared234f22020-10-15 20:42:20 +0200432 assert_equal(['ok'], readfile('Xdidit'))
433
Bram Moolenaared234f22020-10-15 20:42:20 +0200434 delete('Xdidit')
Bram Moolenaarfbbcd002020-10-15 12:46:44 +0200435enddef
436
Bram Moolenaar39ca4122020-10-20 14:25:07 +0200437def Test_block_local_vars_with_func()
438 var lines =<< trim END
439 vim9script
440 if true
441 var foo = 'foo'
442 if true
443 var bar = 'bar'
444 def Func(): list<string>
445 return [foo, bar]
446 enddef
447 endif
448 endif
449 # function is compiled here, after blocks have finished, can still access
450 # "foo" and "bar"
451 assert_equal(['foo', 'bar'], Func())
452 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000453 v9.CheckScriptSuccess(lines)
Bram Moolenaar39ca4122020-10-20 14:25:07 +0200454enddef
455
Bram Moolenaare4db17f2021-08-01 21:19:43 +0200456" legacy func for command that's defined later
Bram Moolenaar62aec932022-01-29 21:45:34 +0000457func s:InvokeSomeCommand()
Bram Moolenaare4db17f2021-08-01 21:19:43 +0200458 SomeCommand
459endfunc
460
Yegappan Lakshmanane74cad32024-04-12 18:48:35 +0200461def Test_command_block()
Bram Moolenaare4db17f2021-08-01 21:19:43 +0200462 com SomeCommand {
463 g:someVar = 'some'
464 }
465 InvokeSomeCommand()
466 assert_equal('some', g:someVar)
467
468 delcommand SomeCommand
469 unlet g:someVar
470enddef
471
Yegappan Lakshmanane74cad32024-04-12 18:48:35 +0200472" Test for using heredoc in a :command command block
473def Test_command_block_heredoc()
474 var lines =<< trim CODE
475 vim9script
476 com SomeCommand {
477 g:someVar =<< trim END
478 aaa
479 bbb
480 END
481 }
482 SomeCommand
483 assert_equal(['aaa', 'bbb'], g:someVar)
484 def Foo()
485 g:someVar = []
486 SomeCommand
487 assert_equal(['aaa', 'bbb'], g:someVar)
488 enddef
489 Foo()
490 delcommand SomeCommand
491 unlet g:someVar
492 CODE
493 v9.CheckSourceSuccess( lines)
494
495 # Execute a command with heredoc in a block
496 lines =<< trim CODE
497 vim9script
498 com SomeCommand {
499 g:someVar =<< trim END
500 aaa
501 bbb
502 END
503 }
504 execute('SomeCommand')
505 assert_equal(['aaa', 'bbb'], g:someVar)
506 delcommand SomeCommand
507 unlet g:someVar
508 CODE
509 v9.CheckSourceSuccess(lines)
510
zeertzjq1f5175d2024-04-13 17:52:26 +0200511 # Heredoc with comment
512 lines =<< trim CODE
513 vim9script
514 com SomeCommand {
515 g:someVar =<< trim END # comment
516 aaa
517 bbb
518 END
519 }
520 execute('SomeCommand')
521 assert_equal(['aaa', 'bbb'], g:someVar)
522 delcommand SomeCommand
523 unlet g:someVar
524 CODE
525 v9.CheckSourceSuccess(lines)
526
Yegappan Lakshmanane74cad32024-04-12 18:48:35 +0200527 # heredoc evaluation
528 lines =<< trim CODE
529 vim9script
530 com SomeCommand {
531 var suffix = '---'
532 g:someVar =<< trim eval END
533 ccc{suffix}
534 ddd
535 END
536 }
537 SomeCommand
538 assert_equal(['ccc---', 'ddd'], g:someVar)
539 def Foo()
540 g:someVar = []
541 SomeCommand
542 assert_equal(['ccc---', 'ddd'], g:someVar)
543 enddef
544 Foo()
545 delcommand SomeCommand
546 unlet g:someVar
547 CODE
548 v9.CheckSourceSuccess(lines)
549
550 # command following heredoc
551 lines =<< trim CODE
552 vim9script
553 com SomeCommand {
554 var l =<< trim END
555 eee
556 fff
557 END
558 g:someVar = l
559 }
560 SomeCommand
561 assert_equal(['eee', 'fff'], g:someVar)
562 delcommand SomeCommand
563 unlet g:someVar
564 CODE
565 v9.CheckSourceSuccess(lines)
566
567 # Error in heredoc
568 lines =<< trim CODE
569 vim9script
570 com SomeCommand {
571 g:someVar =<< trim END
572 eee
573 fff
574 }
575 try
576 SomeCommand
577 catch
578 assert_match("E990: Missing end marker 'END'", v:exception)
579 endtry
580 delcommand SomeCommand
581 unlet g:someVar
582 CODE
583 v9.CheckSourceSuccess(lines)
584enddef
585
586def Test_autocommand_block()
Bram Moolenaare4db17f2021-08-01 21:19:43 +0200587 au BufNew *.xml {
588 g:otherVar = 'other'
589 }
590 split other.xml
591 assert_equal('other', g:otherVar)
592
593 bwipe!
594 au! BufNew *.xml
595 unlet g:otherVar
596enddef
597
Bram Moolenaard032f342020-07-18 18:13:02 +0200598func g:NoSuchFunc()
599 echo 'none'
600endfunc
601
Bram Moolenaar9e1d9e32021-01-11 20:17:34 +0100602def Test_try_catch_throw()
Bram Moolenaarcfcd0112020-09-27 15:19:27 +0200603 var l = []
Bram Moolenaar7a092242020-04-16 22:10:49 +0200604 try # comment
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100605 add(l, '1')
606 throw 'wrong'
Bram Moolenaar9d383f32023-05-14 21:38:12 +0100607 add(l, '2') # "unreachable code"
Bram Moolenaar7a092242020-04-16 22:10:49 +0200608 catch # comment
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100609 add(l, v:exception)
Bram Moolenaar7a092242020-04-16 22:10:49 +0200610 finally # comment
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100611 add(l, '3')
Bram Moolenaar7a092242020-04-16 22:10:49 +0200612 endtry # comment
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100613 assert_equal(['1', 'wrong', '3'], l)
Bram Moolenaar68d130c2020-07-17 22:06:44 +0200614
Bram Moolenaare8593122020-07-18 15:17:02 +0200615 l = []
616 try
617 try
618 add(l, '1')
619 throw 'wrong'
Bram Moolenaar9d383f32023-05-14 21:38:12 +0100620 add(l, '2') # "unreachable code"
Bram Moolenaare8593122020-07-18 15:17:02 +0200621 catch /right/
622 add(l, v:exception)
623 endtry
624 catch /wrong/
625 add(l, 'caught')
Bram Moolenaar204852a2022-03-05 12:56:44 +0000626 finally
Bram Moolenaare8593122020-07-18 15:17:02 +0200627 add(l, 'finally')
628 endtry
629 assert_equal(['1', 'caught', 'finally'], l)
630
Bram Moolenaarcfcd0112020-09-27 15:19:27 +0200631 var n: number
Bram Moolenaar68d130c2020-07-17 22:06:44 +0200632 try
633 n = l[3]
634 catch /E684:/
635 n = 99
636 endtry
637 assert_equal(99, n)
638
Bram Moolenaar69f70502021-01-01 16:10:46 +0100639 var done = 'no'
640 if 0
641 try | catch | endtry
642 else
643 done = 'yes'
644 endif
645 assert_equal('yes', done)
646
647 done = 'no'
648 if 1
649 done = 'yes'
650 else
651 try | catch | endtry
652 done = 'never'
653 endif
654 assert_equal('yes', done)
655
656 if 1
657 else
658 try | catch /pat/ | endtry
Bram Moolenaar755bf2b2023-01-28 19:38:49 +0000659 try | catch /pat/
Bram Moolenaar69f70502021-01-01 16:10:46 +0100660 endtry
Bram Moolenaar755bf2b2023-01-28 19:38:49 +0000661 try
Bram Moolenaar69f70502021-01-01 16:10:46 +0100662 catch /pat/ | endtry
Bram Moolenaar755bf2b2023-01-28 19:38:49 +0000663 try
664 catch /pat/
Bram Moolenaar69f70502021-01-01 16:10:46 +0100665 endtry
666 endif
667
Bram Moolenaar68d130c2020-07-17 22:06:44 +0200668 try
Bram Moolenaarcc673e72020-08-16 17:33:35 +0200669 # string slice returns a string, not a number
Bram Moolenaar68d130c2020-07-17 22:06:44 +0200670 n = g:astring[3]
Bram Moolenaar5e654232020-09-16 15:22:00 +0200671 catch /E1012:/
Bram Moolenaar68d130c2020-07-17 22:06:44 +0200672 n = 77
673 endtry
674 assert_equal(77, n)
675
676 try
677 n = l[g:astring]
Bram Moolenaar5e654232020-09-16 15:22:00 +0200678 catch /E1012:/
Bram Moolenaar56acb092020-08-16 14:48:19 +0200679 n = 88
Bram Moolenaar68d130c2020-07-17 22:06:44 +0200680 endtry
Bram Moolenaar56acb092020-08-16 14:48:19 +0200681 assert_equal(88, n)
Bram Moolenaar68d130c2020-07-17 22:06:44 +0200682
683 try
684 n = s:does_not_exist
685 catch /E121:/
Bram Moolenaarf0b9f432020-07-17 23:03:17 +0200686 n = 111
687 endtry
688 assert_equal(111, n)
689
690 try
691 n = g:does_not_exist
692 catch /E121:/
Bram Moolenaar68d130c2020-07-17 22:06:44 +0200693 n = 121
694 endtry
695 assert_equal(121, n)
696
Bram Moolenaare0de1712020-12-02 17:36:54 +0100697 var d = {one: 1}
Bram Moolenaar68d130c2020-07-17 22:06:44 +0200698 try
699 n = d[g:astring]
700 catch /E716:/
701 n = 222
702 endtry
703 assert_equal(222, n)
Bram Moolenaarf0b9f432020-07-17 23:03:17 +0200704
705 try
706 n = -g:astring
Bram Moolenaarcd6b4f32021-08-15 20:36:28 +0200707 catch /E1012:/
Bram Moolenaarf0b9f432020-07-17 23:03:17 +0200708 n = 233
709 endtry
710 assert_equal(233, n)
711
712 try
713 n = +g:astring
Bram Moolenaarcd6b4f32021-08-15 20:36:28 +0200714 catch /E1012:/
Bram Moolenaarf0b9f432020-07-17 23:03:17 +0200715 n = 244
716 endtry
717 assert_equal(244, n)
718
719 try
720 n = +g:alist
Bram Moolenaarcd6b4f32021-08-15 20:36:28 +0200721 catch /E1012:/
Bram Moolenaarf0b9f432020-07-17 23:03:17 +0200722 n = 255
723 endtry
724 assert_equal(255, n)
725
Bram Moolenaarcfcd0112020-09-27 15:19:27 +0200726 var nd: dict<any>
Bram Moolenaarf0b9f432020-07-17 23:03:17 +0200727 try
Bram Moolenaar2e5910b2021-02-03 17:41:24 +0100728 nd = {[g:alist]: 1}
729 catch /E1105:/
Bram Moolenaarf0b9f432020-07-17 23:03:17 +0200730 n = 266
731 endtry
732 assert_equal(266, n)
733
Bram Moolenaar755bf2b2023-01-28 19:38:49 +0000734 l = [1, 2, 3]
Bram Moolenaarf0b9f432020-07-17 23:03:17 +0200735 try
Bram Moolenaardb9ff9a2021-12-01 17:38:01 +0000736 [n] = l
Bram Moolenaarf0b9f432020-07-17 23:03:17 +0200737 catch /E1093:/
738 n = 277
739 endtry
740 assert_equal(277, n)
741
Bram Moolenaare8593122020-07-18 15:17:02 +0200742 try
743 &ts = g:astring
Bram Moolenaar5e654232020-09-16 15:22:00 +0200744 catch /E1012:/
Bram Moolenaare8593122020-07-18 15:17:02 +0200745 n = 288
746 endtry
747 assert_equal(288, n)
748
749 try
750 &backspace = 'asdf'
751 catch /E474:/
752 n = 299
753 endtry
754 assert_equal(299, n)
755
756 l = [1]
757 try
758 l[3] = 3
759 catch /E684:/
760 n = 300
761 endtry
762 assert_equal(300, n)
763
764 try
Bram Moolenaare8593122020-07-18 15:17:02 +0200765 unlet g:does_not_exist
766 catch /E108:/
767 n = 322
768 endtry
769 assert_equal(322, n)
770
771 try
Bram Moolenaar2bede172020-11-19 18:53:18 +0100772 d = {text: 1, [g:astring]: 2}
Bram Moolenaare8593122020-07-18 15:17:02 +0200773 catch /E721:/
774 n = 333
775 endtry
776 assert_equal(333, n)
777
778 try
Bram Moolenaar62aec932022-01-29 21:45:34 +0000779 l = g:DeletedFunc()
Bram Moolenaare8593122020-07-18 15:17:02 +0200780 catch /E933:/
781 n = 344
782 endtry
783 assert_equal(344, n)
Bram Moolenaard032f342020-07-18 18:13:02 +0200784
785 try
Yegappan Lakshmanana764e732021-07-25 15:57:32 +0200786 echo range(1, 2, 0)
787 catch /E726:/
Bram Moolenaard032f342020-07-18 18:13:02 +0200788 n = 355
789 endtry
790 assert_equal(355, n)
791
Bram Moolenaarcfcd0112020-09-27 15:19:27 +0200792 var P = function('g:NoSuchFunc')
Bram Moolenaard032f342020-07-18 18:13:02 +0200793 delfunc g:NoSuchFunc
794 try
795 echo P()
796 catch /E117:/
797 n = 366
798 endtry
799 assert_equal(366, n)
800
801 try
802 echo g:NoSuchFunc()
803 catch /E117:/
804 n = 377
805 endtry
806 assert_equal(377, n)
807
808 try
809 echo g:alist + 4
810 catch /E745:/
811 n = 388
812 endtry
813 assert_equal(388, n)
814
815 try
816 echo 4 + g:alist
817 catch /E745:/
818 n = 399
819 endtry
820 assert_equal(399, n)
821
822 try
823 echo g:alist.member
824 catch /E715:/
825 n = 400
826 endtry
827 assert_equal(400, n)
828
829 try
830 echo d.member
831 catch /E716:/
832 n = 411
833 endtry
834 assert_equal(411, n)
Bram Moolenaard9d77892021-02-12 21:32:47 +0100835
836 var counter = 0
837 for i in range(4)
838 try
839 eval [][0]
840 catch
841 endtry
842 counter += 1
843 endfor
844 assert_equal(4, counter)
Bram Moolenaar7e82c5f2021-02-21 21:32:45 +0100845
Bram Moolenaar9fa5dab2021-07-20 19:18:44 +0200846 # no requirement for spaces before |
847 try|echo 0|catch|endtry
848
Bram Moolenaar003312b2021-12-20 10:55:35 +0000849 # return in try with finally
850 def ReturnInTry(): number
851 var ret = 4
852 try
853 return ret
854 catch /this/
855 return -1
856 catch /that/
857 return -1
858 finally
859 # changing ret has no effect
860 ret = 7
861 endtry
862 return -2
863 enddef
864 assert_equal(4, ReturnInTry())
865
866 # return in catch with finally
867 def ReturnInCatch(): number
868 var ret = 5
869 try
870 throw 'getout'
Bram Moolenaar9d383f32023-05-14 21:38:12 +0100871 return -1 # "unreachable code"
Bram Moolenaar003312b2021-12-20 10:55:35 +0000872 catch /getout/
873 # ret is evaluated here
874 return ret
875 finally
876 # changing ret later has no effect
877 ret = -3
878 endtry
879 return -2
880 enddef
881 assert_equal(5, ReturnInCatch())
882
Bram Moolenaar7e82c5f2021-02-21 21:32:45 +0100883 # return in finally after empty catch
884 def ReturnInFinally(): number
885 try
886 finally
Bram Moolenaar003312b2021-12-20 10:55:35 +0000887 return 6
Bram Moolenaar7e82c5f2021-02-21 21:32:45 +0100888 endtry
Bram Moolenaar7e82c5f2021-02-21 21:32:45 +0100889 enddef
Bram Moolenaar003312b2021-12-20 10:55:35 +0000890 assert_equal(6, ReturnInFinally())
Bram Moolenaar8ac681a2021-06-15 20:06:34 +0200891
892 var lines =<< trim END
893 vim9script
894 try
895 acos('0.5')
896 ->setline(1)
897 catch
898 g:caught = v:exception
899 endtry
900 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000901 v9.CheckScriptSuccess(lines)
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +0200902 assert_match('E1219: Float or Number required for argument 1', g:caught)
Bram Moolenaar8ac681a2021-06-15 20:06:34 +0200903 unlet g:caught
Bram Moolenaar41978282021-07-04 14:47:30 +0200904
905 # missing catch and/or finally
906 lines =<< trim END
907 vim9script
908 try
909 echo 'something'
910 endtry
911 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000912 v9.CheckScriptFailure(lines, 'E1032:')
rbtnn84934992021-08-07 13:26:53 +0200913
914 # skipping try-finally-endtry when try-finally-endtry is used in another block
915 lines =<< trim END
916 if v:true
917 try
918 finally
919 endtry
920 else
921 try
922 finally
923 endtry
924 endif
925 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000926 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100927enddef
928
Bram Moolenaara2c00282023-05-14 22:05:15 +0100929def Test_unreachable_after()
930 var lines =<< trim END
931 try
932 throw 'Error'
933 echo 'not reached'
934 catch /Error/
935 endtry
936 END
937 v9.CheckDefFailure(lines, 'E1095: Unreachable code after :throw')
938
939 lines =<< trim END
940 def SomeFunc(): number
941 try
942 return 3
943 echo 'not reached'
944 catch /Error/
945 endtry
946 return 4
947 enddef
948 defcompile
949 END
950 v9.CheckScriptFailure(lines, 'E1095: Unreachable code after :return')
951enddef
952
Bram Moolenaar3ef2e412023-04-30 18:50:48 +0100953def Test_throw_in_nested_try()
954 var lines =<< trim END
955 vim9script
956
957 def Try(F: func(): void)
958 try
959 F()
960 catch
961 endtry
962 enddef
963
964 class X
965 def F()
966 try
967 throw 'Foobar'
968 catch
969 throw v:exception
970 endtry
971 enddef
972 endclass
973
974 def Test_TryMethod()
975 var x = X.new()
976 Try(() => x.F())
977 enddef
978
979
980 try
981 Test_TryMethod()
982 catch
983 endtry
984 END
985 v9.CheckScriptSuccess(lines)
986enddef
987
Bram Moolenaar28bf6492022-03-03 15:11:20 +0000988def Test_try_var_decl()
989 var lines =<< trim END
990 vim9script
991 try
992 var in_try = 1
993 assert_equal(1, get(s:, 'in_try', -1))
994 throw "getout"
995 catch
996 var in_catch = 2
997 assert_equal(-1, get(s:, 'in_try', -1))
998 assert_equal(2, get(s:, 'in_catch', -1))
999 finally
1000 var in_finally = 3
1001 assert_equal(-1, get(s:, 'in_try', -1))
1002 assert_equal(-1, get(s:, 'in_catch', -1))
1003 assert_equal(3, get(s:, 'in_finally', -1))
1004 endtry
1005 assert_equal(-1, get(s:, 'in_try', -1))
1006 assert_equal(-1, get(s:, 'in_catch', -1))
1007 assert_equal(-1, get(s:, 'in_finally', -1))
1008 END
1009 v9.CheckScriptSuccess(lines)
1010enddef
1011
Bram Moolenaar53c29612022-01-12 16:18:18 +00001012def Test_try_ends_in_return()
1013 var lines =<< trim END
1014 vim9script
1015 def Foo(): string
1016 try
1017 return 'foo'
1018 catch
1019 return 'caught'
1020 endtry
1021 enddef
1022 assert_equal('foo', Foo())
1023 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001024 v9.CheckScriptSuccess(lines)
Bram Moolenaar53c29612022-01-12 16:18:18 +00001025
1026 lines =<< trim END
1027 vim9script
1028 def Foo(): string
1029 try
1030 return 'foo'
1031 catch
1032 return 'caught'
1033 endtry
1034 echo 'notreached'
1035 enddef
1036 assert_equal('foo', Foo())
1037 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001038 v9.CheckScriptFailure(lines, 'E1095:')
Bram Moolenaar53c29612022-01-12 16:18:18 +00001039
1040 lines =<< trim END
1041 vim9script
1042 def Foo(): string
1043 try
1044 return 'foo'
1045 catch /x/
1046 return 'caught'
1047 endtry
1048 enddef
1049 assert_equal('foo', Foo())
1050 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001051 v9.CheckScriptFailure(lines, 'E1027:')
Bram Moolenaar53c29612022-01-12 16:18:18 +00001052
1053 lines =<< trim END
1054 vim9script
1055 def Foo(): string
1056 try
1057 echo 'foo'
1058 catch
1059 echo 'caught'
1060 finally
1061 return 'done'
1062 endtry
1063 enddef
1064 assert_equal('done', Foo())
1065 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001066 v9.CheckScriptSuccess(lines)
Bram Moolenaar53c29612022-01-12 16:18:18 +00001067
1068enddef
1069
Bram Moolenaar3f987b52021-06-30 12:02:24 +02001070def Test_try_in_catch()
1071 var lines =<< trim END
1072 vim9script
1073 var seq = []
1074 def DoIt()
1075 try
1076 seq->add('throw 1')
1077 eval [][0]
1078 seq->add('notreached')
1079 catch
1080 seq->add('catch')
1081 try
1082 seq->add('throw 2')
1083 eval [][0]
1084 seq->add('notreached')
1085 catch /nothing/
1086 seq->add('notreached')
1087 endtry
1088 seq->add('done')
1089 endtry
1090 enddef
1091 DoIt()
1092 assert_equal(['throw 1', 'catch', 'throw 2', 'done'], seq)
1093 END
1094enddef
1095
Bram Moolenaard3d8fee2021-06-30 19:54:43 +02001096def Test_error_in_catch()
1097 var lines =<< trim END
1098 try
1099 eval [][0]
1100 catch /E684:/
1101 eval [][0]
1102 endtry
1103 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001104 v9.CheckDefExecFailure(lines, 'E684:', 4)
Bram Moolenaard3d8fee2021-06-30 19:54:43 +02001105enddef
1106
Bram Moolenaar2e34c342021-03-14 12:13:33 +01001107" :while at the very start of a function that :continue jumps to
Bram Moolenaar62aec932022-01-29 21:45:34 +00001108def s:TryContinueFunc()
Bram Moolenaar2e34c342021-03-14 12:13:33 +01001109 while g:Count < 2
1110 g:sequence ..= 't'
1111 try
1112 echoerr 'Test'
1113 catch
1114 g:Count += 1
1115 g:sequence ..= 'c'
1116 continue
1117 endtry
1118 g:sequence ..= 'e'
1119 g:Count += 1
1120 endwhile
1121enddef
1122
1123def Test_continue_in_try_in_while()
1124 g:Count = 0
1125 g:sequence = ''
1126 TryContinueFunc()
1127 assert_equal('tctc', g:sequence)
1128 unlet g:Count
1129 unlet g:sequence
1130enddef
1131
Bram Moolenaar873f8242022-03-10 21:53:44 +00001132def Test_break_in_try_in_for()
1133 var lines =<< trim END
1134 vim9script
1135 def Ls(): list<string>
1136 var ls: list<string>
1137 for s in ['abc', 'def']
1138 for _ in [123, 456]
1139 try
1140 eval [][0]
1141 catch
1142 break
1143 endtry
1144 endfor
1145 ls += [s]
1146 endfor
1147 return ls
1148 enddef
1149 assert_equal(['abc', 'def'], Ls())
1150 END
1151 v9.CheckScriptSuccess(lines)
1152enddef
1153
Bram Moolenaar9cb577a2021-02-22 22:45:10 +01001154def Test_nocatch_return_in_try()
1155 # return in try block returns normally
1156 def ReturnInTry(): string
1157 try
1158 return '"some message"'
1159 catch
1160 endtry
1161 return 'not reached'
1162 enddef
1163 exe 'echoerr ' .. ReturnInTry()
1164enddef
1165
Bram Moolenaar1430cee2021-01-17 19:20:32 +01001166def Test_cnext_works_in_catch()
1167 var lines =<< trim END
1168 vim9script
Bram Moolenaarc3235272021-07-10 19:42:03 +02001169 au BufEnter * eval 1 + 2
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001170 writefile(['text'], 'Xcncfile1')
1171 writefile(['text'], 'Xcncfile2')
Bram Moolenaar1430cee2021-01-17 19:20:32 +01001172 var items = [
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001173 {lnum: 1, filename: 'Xcncfile1', valid: true},
1174 {lnum: 1, filename: 'Xcncfile2', valid: true}
Bram Moolenaar1430cee2021-01-17 19:20:32 +01001175 ]
1176 setqflist([], ' ', {items: items})
1177 cwindow
1178
1179 def CnextOrCfirst()
1180 # if cnext fails, cfirst is used
1181 try
1182 cnext
1183 catch
1184 cfirst
1185 endtry
1186 enddef
1187
1188 CnextOrCfirst()
1189 CnextOrCfirst()
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001190 writefile([getqflist({idx: 0}).idx], 'Xcncresult')
Bram Moolenaar1430cee2021-01-17 19:20:32 +01001191 qall
1192 END
Bram Moolenaardd674772022-09-15 22:26:18 +01001193 writefile(lines, 'XCatchCnext', 'D')
Bram Moolenaar62aec932022-01-29 21:45:34 +00001194 g:RunVim([], [], '--clean -S XCatchCnext')
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001195 assert_equal(['1'], readfile('Xcncresult'))
Bram Moolenaar1430cee2021-01-17 19:20:32 +01001196
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001197 delete('Xcncfile1')
1198 delete('Xcncfile2')
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001199 delete('Xcncresult')
Bram Moolenaar1430cee2021-01-17 19:20:32 +01001200enddef
1201
Bram Moolenaar9e1d9e32021-01-11 20:17:34 +01001202def Test_throw_skipped()
1203 if 0
1204 throw dontgethere
1205 endif
1206enddef
1207
Bram Moolenaar8f81b222021-01-14 21:47:06 +01001208def Test_nocatch_throw_silenced()
1209 var lines =<< trim END
1210 vim9script
1211 def Func()
1212 throw 'error'
1213 enddef
1214 silent! Func()
1215 END
Bram Moolenaardd674772022-09-15 22:26:18 +01001216 writefile(lines, 'XthrowSilenced', 'D')
Bram Moolenaar8f81b222021-01-14 21:47:06 +01001217 source XthrowSilenced
Bram Moolenaar8f81b222021-01-14 21:47:06 +01001218enddef
1219
Bram Moolenaara2c00282023-05-14 22:05:15 +01001220" g:DeletedFunc() is found when compiling Test_try_catch_throw() and then
1221" deleted, this should give a runtime error.
Bram Moolenaare8593122020-07-18 15:17:02 +02001222def DeletedFunc(): list<any>
1223 return ['delete me']
1224enddef
Bram Moolenaar9d383f32023-05-14 21:38:12 +01001225defcompile DeletedFunc
1226
1227call test_override('unreachable', 1)
1228defcompile Test_try_catch_throw
1229call test_override('unreachable', 0)
1230
Bram Moolenaare8593122020-07-18 15:17:02 +02001231delfunc DeletedFunc
1232
Bram Moolenaar62aec932022-01-29 21:45:34 +00001233def s:ThrowFromDef()
Bram Moolenaara72cfb82020-04-23 17:07:30 +02001234 throw "getout" # comment
Bram Moolenaar257cc5e2020-02-19 17:06:11 +01001235enddef
1236
Bram Moolenaar62aec932022-01-29 21:45:34 +00001237func s:CatchInFunc()
Bram Moolenaar257cc5e2020-02-19 17:06:11 +01001238 try
Bram Moolenaar62aec932022-01-29 21:45:34 +00001239 call s:ThrowFromDef()
Bram Moolenaar257cc5e2020-02-19 17:06:11 +01001240 catch
1241 let g:thrown_func = v:exception
1242 endtry
1243endfunc
1244
Bram Moolenaar62aec932022-01-29 21:45:34 +00001245def s:CatchInDef()
Bram Moolenaar257cc5e2020-02-19 17:06:11 +01001246 try
1247 ThrowFromDef()
1248 catch
1249 g:thrown_def = v:exception
1250 endtry
1251enddef
1252
Bram Moolenaar62aec932022-01-29 21:45:34 +00001253def s:ReturnFinally(): string
Bram Moolenaarf575adf2020-02-20 20:41:06 +01001254 try
1255 return 'intry'
Bram Moolenaar204852a2022-03-05 12:56:44 +00001256 finally
Bram Moolenaarf575adf2020-02-20 20:41:06 +01001257 g:in_finally = 'finally'
1258 endtry
1259 return 'end'
1260enddef
1261
Bram Moolenaar257cc5e2020-02-19 17:06:11 +01001262def Test_try_catch_nested()
1263 CatchInFunc()
1264 assert_equal('getout', g:thrown_func)
1265
1266 CatchInDef()
1267 assert_equal('getout', g:thrown_def)
Bram Moolenaarf575adf2020-02-20 20:41:06 +01001268
1269 assert_equal('intry', ReturnFinally())
1270 assert_equal('finally', g:in_finally)
Bram Moolenaard3d8fee2021-06-30 19:54:43 +02001271
1272 var l = []
1273 try
1274 l->add('1')
1275 throw 'bad'
Bram Moolenaar9d383f32023-05-14 21:38:12 +01001276 l->add('x') # "unreachable code"
Bram Moolenaard3d8fee2021-06-30 19:54:43 +02001277 catch /bad/
1278 l->add('2')
1279 try
1280 l->add('3')
1281 throw 'one'
1282 l->add('x')
1283 catch /one/
1284 l->add('4')
1285 try
1286 l->add('5')
1287 throw 'more'
1288 l->add('x')
1289 catch /more/
1290 l->add('6')
1291 endtry
1292 endtry
1293 endtry
1294 assert_equal(['1', '2', '3', '4', '5', '6'], l)
Bram Moolenaar834193a2021-06-30 20:39:15 +02001295
1296 l = []
1297 try
1298 try
1299 l->add('1')
1300 throw 'foo'
1301 l->add('x')
1302 catch
1303 l->add('2')
1304 throw 'bar'
1305 l->add('x')
1306 finally
1307 l->add('3')
1308 endtry
1309 l->add('x')
1310 catch /bar/
1311 l->add('4')
1312 endtry
1313 assert_equal(['1', '2', '3', '4'], l)
Bram Moolenaarf575adf2020-02-20 20:41:06 +01001314enddef
1315
Bram Moolenaar9d383f32023-05-14 21:38:12 +01001316call test_override('unreachable', 1)
1317defcompile Test_try_catch_nested
1318call test_override('unreachable', 0)
1319
Bram Moolenaar62aec932022-01-29 21:45:34 +00001320def s:TryOne(): number
Bram Moolenaar9939f572020-09-16 22:29:52 +02001321 try
1322 return 0
1323 catch
1324 endtry
1325 return 0
1326enddef
1327
Bram Moolenaar62aec932022-01-29 21:45:34 +00001328def s:TryTwo(n: number): string
Bram Moolenaar9939f572020-09-16 22:29:52 +02001329 try
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001330 var x = {}
Bram Moolenaar9939f572020-09-16 22:29:52 +02001331 catch
1332 endtry
1333 return 'text'
1334enddef
1335
1336def Test_try_catch_twice()
1337 assert_equal('text', TryOne()->TryTwo())
1338enddef
1339
Bram Moolenaarf575adf2020-02-20 20:41:06 +01001340def Test_try_catch_match()
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001341 var seq = 'a'
Bram Moolenaarf575adf2020-02-20 20:41:06 +01001342 try
1343 throw 'something'
1344 catch /nothing/
1345 seq ..= 'x'
1346 catch /some/
1347 seq ..= 'b'
1348 catch /asdf/
1349 seq ..= 'x'
Bram Moolenaare8c4abb2020-04-02 21:13:25 +02001350 catch ?a\?sdf?
1351 seq ..= 'y'
Bram Moolenaarf575adf2020-02-20 20:41:06 +01001352 finally
1353 seq ..= 'c'
1354 endtry
1355 assert_equal('abc', seq)
Bram Moolenaar257cc5e2020-02-19 17:06:11 +01001356enddef
1357
Bram Moolenaare8c4abb2020-04-02 21:13:25 +02001358def Test_try_catch_fails()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001359 v9.CheckDefFailure(['catch'], 'E603:')
1360 v9.CheckDefFailure(['try', 'echo 0', 'catch', 'catch'], 'E1033:')
1361 v9.CheckDefFailure(['try', 'echo 0', 'catch /pat'], 'E1067:')
1362 v9.CheckDefFailure(['finally'], 'E606:')
1363 v9.CheckDefFailure(['try', 'echo 0', 'finally', 'echo 1', 'finally'], 'E607:')
1364 v9.CheckDefFailure(['endtry'], 'E602:')
1365 v9.CheckDefFailure(['while 1', 'endtry'], 'E170:')
1366 v9.CheckDefFailure(['for i in range(5)', 'endtry'], 'E170:')
1367 v9.CheckDefFailure(['if 1', 'endtry'], 'E171:')
1368 v9.CheckDefFailure(['try', 'echo 1', 'endtry'], 'E1032:')
Bram Moolenaar585fea72020-04-02 22:33:21 +02001369
Bram Moolenaar62aec932022-01-29 21:45:34 +00001370 v9.CheckDefFailure(['throw'], 'E1143:')
1371 v9.CheckDefFailure(['throw xxx'], 'E1001:')
Bram Moolenaare8c4abb2020-04-02 21:13:25 +02001372enddef
1373
Bram Moolenaar7c5b3c0362021-02-14 22:40:57 +01001374def Try_catch_skipped()
1375 var l = []
1376 try
1377 finally
1378 endtry
1379
1380 if 1
1381 else
1382 try
1383 endtry
1384 endif
1385enddef
1386
1387" The skipped try/endtry was updating the wrong instruction.
1388def Test_try_catch_skipped()
1389 var instr = execute('disassemble Try_catch_skipped')
1390 assert_match("NEWLIST size 0\n", instr)
1391enddef
1392
Bram Moolenaar90a57162022-02-12 14:23:17 +00001393def Test_throw_line_number()
1394 def Func()
1395 eval 1 + 1
1396 eval 2 + 2
1397 throw 'exception'
1398 enddef
1399 try
1400 Func()
1401 catch /exception/
1402 assert_match('line 3', v:throwpoint)
1403 endtry
1404enddef
Bram Moolenaar7c5b3c0362021-02-14 22:40:57 +01001405
1406
Bram Moolenaar006ad482020-06-30 20:55:15 +02001407def Test_throw_vimscript()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001408 # only checks line continuation
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001409 var lines =<< trim END
Bram Moolenaar006ad482020-06-30 20:55:15 +02001410 vim9script
1411 try
1412 throw 'one'
1413 .. 'two'
1414 catch
1415 assert_equal('onetwo', v:exception)
1416 endtry
1417 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001418 v9.CheckScriptSuccess(lines)
Bram Moolenaar1e021e62020-10-16 20:25:23 +02001419
1420 lines =<< trim END
1421 vim9script
Bram Moolenaar352134b2020-10-17 22:04:08 +02001422 @r = ''
Bram Moolenaar1e021e62020-10-16 20:25:23 +02001423 def Func()
1424 throw @r
1425 enddef
1426 var result = ''
1427 try
1428 Func()
1429 catch /E1129:/
1430 result = 'caught'
1431 endtry
1432 assert_equal('caught', result)
1433 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001434 v9.CheckScriptSuccess(lines)
Bram Moolenaar006ad482020-06-30 20:55:15 +02001435enddef
1436
Bram Moolenaared677f52020-08-12 16:38:10 +02001437def Test_error_in_nested_function()
Bram Moolenaar03dfde22021-02-14 13:17:22 +01001438 # an error in a nested :function aborts executing in the calling :def function
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001439 var lines =<< trim END
Bram Moolenaared677f52020-08-12 16:38:10 +02001440 vim9script
1441 def Func()
1442 Error()
1443 g:test_var = 1
1444 enddef
1445 func Error() abort
1446 eval [][0]
1447 endfunc
1448 Func()
1449 END
1450 g:test_var = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00001451 v9.CheckScriptFailure(lines, 'E684:')
Bram Moolenaared677f52020-08-12 16:38:10 +02001452 assert_equal(0, g:test_var)
1453enddef
1454
Bram Moolenaar227c58a2021-04-28 20:40:44 +02001455def Test_abort_after_error()
1456 var lines =<< trim END
1457 vim9script
1458 while true
1459 echo notfound
1460 endwhile
1461 g:gotthere = true
1462 END
1463 g:gotthere = false
Bram Moolenaar62aec932022-01-29 21:45:34 +00001464 v9.CheckScriptFailure(lines, 'E121:')
Bram Moolenaar227c58a2021-04-28 20:40:44 +02001465 assert_false(g:gotthere)
1466 unlet g:gotthere
1467enddef
1468
Bram Moolenaar37c83712020-06-30 21:18:36 +02001469def Test_cexpr_vimscript()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001470 # only checks line continuation
Bram Moolenaar37c83712020-06-30 21:18:36 +02001471 set errorformat=File\ %f\ line\ %l
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001472 var lines =<< trim END
Bram Moolenaar37c83712020-06-30 21:18:36 +02001473 vim9script
1474 cexpr 'File'
1475 .. ' someFile' ..
1476 ' line 19'
1477 assert_equal(19, getqflist()[0].lnum)
1478 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001479 v9.CheckScriptSuccess(lines)
Bram Moolenaar397a87a2022-03-20 21:14:15 +00001480
1481 lines =<< trim END
1482 vim9script
1483 def CexprFail()
1484 au QuickfixCmdPre * echo g:doesnotexist
1485 cexpr 'File otherFile line 99'
1486 g:didContinue = 'yes'
1487 enddef
1488 CexprFail()
1489 g:didContinue = 'also'
1490 END
1491 g:didContinue = 'no'
1492 v9.CheckScriptFailure(lines, 'E121: Undefined variable: g:doesnotexist')
1493 assert_equal('no', g:didContinue)
1494 au! QuickfixCmdPre
1495
1496 lines =<< trim END
1497 vim9script
1498 def CexprFail()
1499 cexpr g:aNumber
1500 g:didContinue = 'yes'
1501 enddef
1502 CexprFail()
1503 g:didContinue = 'also'
1504 END
1505 g:aNumber = 123
1506 g:didContinue = 'no'
1507 v9.CheckScriptFailure(lines, 'E777: String or List expected')
1508 assert_equal('no', g:didContinue)
1509 unlet g:didContinue
1510
Bram Moolenaar37c83712020-06-30 21:18:36 +02001511 set errorformat&
1512enddef
1513
Bram Moolenaarc9edd6b2020-08-12 22:18:23 +02001514def Test_statusline_syntax()
1515 # legacy syntax is used for 'statusline'
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001516 var lines =<< trim END
Bram Moolenaarc9edd6b2020-08-12 22:18:23 +02001517 vim9script
1518 func g:Status()
1519 return '%{"x" is# "x"}'
1520 endfunc
1521 set laststatus=2 statusline=%!Status()
1522 redrawstatus
Bram Moolenaar755bf2b2023-01-28 19:38:49 +00001523 set laststatus statusline=
Bram Moolenaarc9edd6b2020-08-12 22:18:23 +02001524 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001525 v9.CheckScriptSuccess(lines)
Bram Moolenaarc9edd6b2020-08-12 22:18:23 +02001526enddef
1527
Bram Moolenaarb2097502020-07-19 17:17:02 +02001528def Test_list_vimscript()
1529 # checks line continuation and comments
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001530 var lines =<< trim END
Bram Moolenaarb2097502020-07-19 17:17:02 +02001531 vim9script
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001532 var mylist = [
Bram Moolenaarb2097502020-07-19 17:17:02 +02001533 'one',
1534 # comment
1535 'two', # empty line follows
1536
1537 'three',
1538 ]
1539 assert_equal(['one', 'two', 'three'], mylist)
1540 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001541 v9.CheckScriptSuccess(lines)
Bram Moolenaar66250c92020-08-20 15:02:42 +02001542
1543 # check all lines from heredoc are kept
1544 lines =<< trim END
1545 # comment 1
1546 two
1547 # comment 3
1548
1549 five
1550 # comment 6
1551 END
1552 assert_equal(['# comment 1', 'two', '# comment 3', '', 'five', '# comment 6'], lines)
Bram Moolenaar4bce26b2021-01-22 22:06:56 +01001553
1554 lines =<< trim END
1555 [{
1556 a: 0}]->string()->assert_equal("[{'a': 0}]")
1557 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001558 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarb2097502020-07-19 17:17:02 +02001559enddef
1560
Bram Moolenaar2a1381c2020-05-05 23:32:58 +02001561if has('channel')
1562 let someJob = test_null_job()
Bram Moolenaar40ee4662020-05-05 22:08:26 +02001563
Bram Moolenaar2a1381c2020-05-05 23:32:58 +02001564 def FuncWithError()
1565 echomsg g:someJob
1566 enddef
Bram Moolenaar40ee4662020-05-05 22:08:26 +02001567
Bram Moolenaar2a1381c2020-05-05 23:32:58 +02001568 func Test_convert_emsg_to_exception()
1569 try
1570 call FuncWithError()
1571 catch
1572 call assert_match('Vim:E908:', v:exception)
1573 endtry
1574 endfunc
1575endif
Bram Moolenaar40ee4662020-05-05 22:08:26 +02001576
Bram Moolenaard3f8a9e2021-02-17 21:57:03 +01001577def Test_vim9script_mix()
1578 var lines =<< trim END
1579 if has(g:feature)
1580 " legacy script
1581 let g:legacy = 1
1582 finish
1583 endif
1584 vim9script
1585 g:legacy = 0
1586 END
1587 g:feature = 'eval'
1588 g:legacy = -1
Bram Moolenaar62aec932022-01-29 21:45:34 +00001589 v9.CheckScriptSuccess(lines)
Bram Moolenaard3f8a9e2021-02-17 21:57:03 +01001590 assert_equal(1, g:legacy)
1591
1592 g:feature = 'noteval'
1593 g:legacy = -1
Bram Moolenaar62aec932022-01-29 21:45:34 +00001594 v9.CheckScriptSuccess(lines)
Bram Moolenaard3f8a9e2021-02-17 21:57:03 +01001595 assert_equal(0, g:legacy)
1596enddef
1597
Bram Moolenaar750802b2020-02-23 18:08:33 +01001598def Test_vim9script_fails()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001599 v9.CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
1600 v9.CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
Bram Moolenaar750802b2020-02-23 18:08:33 +01001601
Bram Moolenaar62aec932022-01-29 21:45:34 +00001602 v9.CheckScriptFailure(['vim9script', 'var str: string', 'str = 1234'], 'E1012:')
1603 v9.CheckScriptFailure(['vim9script', 'const str = "asdf"', 'str = "xxx"'], 'E46:')
Bram Moolenaarc785b9a2020-06-19 18:34:15 +02001604
Bram Moolenaare2e40752020-09-04 21:18:46 +02001605 assert_fails('vim9script', 'E1038:')
Bram Moolenaar107f7322022-02-06 17:30:41 +00001606 v9.CheckDefFailure(['vim9script'], 'E1038:')
Bram Moolenaar8cbf2492022-02-06 20:28:13 +00001607
1608 # no error when skipping
1609 if has('nothing')
1610 vim9script
1611 endif
Bram Moolenaarc970e422021-03-17 15:03:04 +01001612enddef
1613
Bram Moolenaar6c3843c2021-03-04 12:38:21 +01001614def Test_script_var_shadows_function()
1615 var lines =<< trim END
1616 vim9script
1617 def Func(): number
1618 return 123
1619 enddef
1620 var Func = 1
1621 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001622 v9.CheckScriptFailure(lines, 'E1041:', 5)
Bram Moolenaar6c3843c2021-03-04 12:38:21 +01001623enddef
1624
Bram Moolenaar052ff292021-12-11 13:54:46 +00001625def Test_function_shadows_script_var()
1626 var lines =<< trim END
1627 vim9script
1628 var Func = 1
1629 def Func(): number
1630 return 123
1631 enddef
1632 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001633 v9.CheckScriptFailure(lines, 'E1041:', 3)
Bram Moolenaar052ff292021-12-11 13:54:46 +00001634enddef
1635
Bram Moolenaarc3235272021-07-10 19:42:03 +02001636def Test_script_var_shadows_command()
1637 var lines =<< trim END
1638 var undo = 1
1639 undo = 2
1640 assert_equal(2, undo)
1641 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001642 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarc3235272021-07-10 19:42:03 +02001643
1644 lines =<< trim END
1645 var undo = 1
1646 undo
1647 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001648 v9.CheckDefAndScriptFailure(lines, 'E1207:', 2)
Bram Moolenaarc3235272021-07-10 19:42:03 +02001649enddef
1650
Bram Moolenaar2ef91562021-12-11 16:14:07 +00001651def Test_vim9script_call_wrong_type()
1652 var lines =<< trim END
1653 vim9script
1654 var Time = 'localtime'
1655 Time()
1656 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001657 v9.CheckScriptFailure(lines, 'E1085:')
Bram Moolenaar2ef91562021-12-11 16:14:07 +00001658enddef
1659
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02001660def Test_vim9script_reload_delfunc()
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001661 var first_lines =<< trim END
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02001662 vim9script
1663 def FuncYes(): string
1664 return 'yes'
1665 enddef
1666 END
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001667 var withno_lines =<< trim END
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02001668 def FuncNo(): string
1669 return 'no'
1670 enddef
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02001671 def g:DoCheck(no_exists: bool)
1672 assert_equal('yes', FuncYes())
Bram Moolenaar03afdcf2020-04-27 23:39:30 +02001673 assert_equal('no', FuncNo())
1674 enddef
1675 END
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001676 var nono_lines =<< trim END
Bram Moolenaar03afdcf2020-04-27 23:39:30 +02001677 def g:DoCheck(no_exists: bool)
1678 assert_equal('yes', FuncYes())
Bram Moolenaar44d66522020-09-06 22:26:57 +02001679 assert_fails('FuncNo()', 'E117:', '', 2, 'DoCheck')
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02001680 enddef
1681 END
1682
1683 # FuncNo() is defined
Bram Moolenaardd674772022-09-15 22:26:18 +01001684 writefile(first_lines + withno_lines, 'Xreloaded.vim', 'D')
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02001685 source Xreloaded.vim
1686 g:DoCheck(true)
1687
1688 # FuncNo() is not redefined
Bram Moolenaar03afdcf2020-04-27 23:39:30 +02001689 writefile(first_lines + nono_lines, 'Xreloaded.vim')
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02001690 source Xreloaded.vim
Bram Moolenaar50824712020-12-20 21:10:17 +01001691 g:DoCheck(false)
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02001692
1693 # FuncNo() is back
Bram Moolenaar03afdcf2020-04-27 23:39:30 +02001694 writefile(first_lines + withno_lines, 'Xreloaded.vim')
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02001695 source Xreloaded.vim
Bram Moolenaar50824712020-12-20 21:10:17 +01001696 g:DoCheck(false)
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02001697enddef
1698
Bram Moolenaar89483d42020-05-10 15:24:44 +02001699def Test_vim9script_reload_delvar()
1700 # write the script with a script-local variable
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001701 var lines =<< trim END
Bram Moolenaar89483d42020-05-10 15:24:44 +02001702 vim9script
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001703 var name = 'string'
Bram Moolenaar89483d42020-05-10 15:24:44 +02001704 END
Bram Moolenaardd674772022-09-15 22:26:18 +01001705 writefile(lines, 'XreloadVar.vim', 'D')
Bram Moolenaar89483d42020-05-10 15:24:44 +02001706 source XreloadVar.vim
1707
1708 # now write the script using the same variable locally - works
1709 lines =<< trim END
1710 vim9script
1711 def Func()
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001712 var name = 'string'
Bram Moolenaar89483d42020-05-10 15:24:44 +02001713 enddef
1714 END
1715 writefile(lines, 'XreloadVar.vim')
1716 source XreloadVar.vim
Bram Moolenaar89483d42020-05-10 15:24:44 +02001717enddef
1718
Bram Moolenaarc4ce36d2020-08-14 17:08:15 +02001719def Test_func_redefine_error()
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001720 var lines = [
Bram Moolenaarc4ce36d2020-08-14 17:08:15 +02001721 'vim9script',
1722 'def Func()',
1723 ' eval [][0]',
1724 'enddef',
1725 'Func()',
1726 ]
Bram Moolenaardd674772022-09-15 22:26:18 +01001727 writefile(lines, 'Xtestscript.vim', 'D')
Bram Moolenaarc4ce36d2020-08-14 17:08:15 +02001728
1729 for count in range(3)
1730 try
1731 source Xtestscript.vim
1732 catch /E684/
1733 # function name should contain <SNR> every time
Bram Moolenaarec892232022-05-06 17:53:06 +01001734 assert_match('E684: List index out of range', v:exception)
Bram Moolenaarc4ce36d2020-08-14 17:08:15 +02001735 assert_match('function <SNR>\d\+_Func, line 1', v:throwpoint)
1736 endtry
1737 endfor
Bram Moolenaarc4ce36d2020-08-14 17:08:15 +02001738enddef
1739
Bram Moolenaarb9a2cac2020-08-01 22:23:20 +02001740def Test_func_redefine_fails()
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001741 var lines =<< trim END
Bram Moolenaarb9a2cac2020-08-01 22:23:20 +02001742 vim9script
1743 def Func()
1744 echo 'one'
1745 enddef
1746 def Func()
1747 echo 'two'
1748 enddef
1749 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001750 v9.CheckScriptFailure(lines, 'E1073:')
Bram Moolenaarfa211f32020-08-07 22:00:26 +02001751
1752 lines =<< trim END
1753 vim9script
1754 def Foo(): string
1755 return 'foo'
Bram Moolenaar052ff292021-12-11 13:54:46 +00001756 enddef
Bram Moolenaarfa211f32020-08-07 22:00:26 +02001757 def Func()
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001758 var Foo = {-> 'lambda'}
Bram Moolenaarfa211f32020-08-07 22:00:26 +02001759 enddef
1760 defcompile
1761 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001762 v9.CheckScriptFailure(lines, 'E1073:')
Bram Moolenaarb9a2cac2020-08-01 22:23:20 +02001763enddef
1764
Bram Moolenaar91c7cbf2022-08-18 13:28:31 +01001765def Test_lambda_split()
1766 # this was using freed memory, because of the split expression
1767 var lines =<< trim END
1768 vim9script
1769 try
1770 0
1771 0->(0
1772 ->a.0(
1773 ->u
1774 END
1775 v9.CheckScriptFailure(lines, 'E1050:')
1776enddef
1777
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001778def Test_fixed_size_list()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001779 # will be allocated as one piece of memory, check that changes work
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001780 var l = [1, 2, 3, 4]
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001781 l->remove(0)
1782 l->add(5)
1783 l->insert(99, 1)
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +01001784 assert_equal([2, 99, 3, 4, 5], l)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001785enddef
1786
Bram Moolenaarae616492020-07-28 20:07:27 +02001787def Test_no_insert_xit()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001788 v9.CheckDefExecFailure(['a = 1'], 'E1100:')
1789 v9.CheckDefExecFailure(['c = 1'], 'E1100:')
1790 v9.CheckDefExecFailure(['i = 1'], 'E1100:')
1791 v9.CheckDefExecFailure(['t = 1'], 'E1100:')
1792 v9.CheckDefExecFailure(['x = 1'], 'E1100:')
Bram Moolenaarae616492020-07-28 20:07:27 +02001793
Bram Moolenaar62aec932022-01-29 21:45:34 +00001794 v9.CheckScriptFailure(['vim9script', 'a = 1'], 'E488:')
1795 v9.CheckScriptFailure(['vim9script', 'a'], 'E1100:')
1796 v9.CheckScriptFailure(['vim9script', 'c = 1'], 'E488:')
1797 v9.CheckScriptFailure(['vim9script', 'c'], 'E1100:')
1798 v9.CheckScriptFailure(['vim9script', 'i = 1'], 'E488:')
1799 v9.CheckScriptFailure(['vim9script', 'i'], 'E1100:')
1800 v9.CheckScriptFailure(['vim9script', 'o = 1'], 'E1100:')
1801 v9.CheckScriptFailure(['vim9script', 'o'], 'E1100:')
1802 v9.CheckScriptFailure(['vim9script', 't'], 'E1100:')
1803 v9.CheckScriptFailure(['vim9script', 't = 1'], 'E1100:')
1804 v9.CheckScriptFailure(['vim9script', 'x = 1'], 'E1100:')
Bram Moolenaarae616492020-07-28 20:07:27 +02001805enddef
1806
Bram Moolenaar62aec932022-01-29 21:45:34 +00001807def s:IfElse(what: number): string
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001808 var res = ''
Bram Moolenaar158906c2020-02-06 20:39:45 +01001809 if what == 1
1810 res = "one"
1811 elseif what == 2
1812 res = "two"
Bram Moolenaara259d8d2020-01-31 20:10:50 +01001813 else
Bram Moolenaar158906c2020-02-06 20:39:45 +01001814 res = "three"
Bram Moolenaara259d8d2020-01-31 20:10:50 +01001815 endif
Bram Moolenaar158906c2020-02-06 20:39:45 +01001816 return res
Bram Moolenaara259d8d2020-01-31 20:10:50 +01001817enddef
1818
Bram Moolenaar158906c2020-02-06 20:39:45 +01001819def Test_if_elseif_else()
1820 assert_equal('one', IfElse(1))
1821 assert_equal('two', IfElse(2))
1822 assert_equal('three', IfElse(3))
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +01001823enddef
1824
Bram Moolenaare8c4abb2020-04-02 21:13:25 +02001825def Test_if_elseif_else_fails()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001826 v9.CheckDefFailure(['elseif true'], 'E582:')
1827 v9.CheckDefFailure(['else'], 'E581:')
1828 v9.CheckDefFailure(['endif'], 'E580:')
1829 v9.CheckDefFailure(['if g:abool', 'elseif xxx'], 'E1001:')
1830 v9.CheckDefFailure(['if true', 'echo 1'], 'E171:')
Bram Moolenaar6628b7e2021-02-07 16:33:35 +01001831
1832 var lines =<< trim END
1833 var s = ''
1834 if s = ''
1835 endif
1836 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001837 v9.CheckDefFailure(lines, 'E488:')
Bram Moolenaar6628b7e2021-02-07 16:33:35 +01001838
1839 lines =<< trim END
1840 var s = ''
1841 if s == ''
1842 elseif s = ''
1843 endif
1844 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001845 v9.CheckDefFailure(lines, 'E488:')
Bram Moolenaarfa010cd2022-04-03 16:13:07 +01001846
1847 lines =<< trim END
1848 var cond = true
1849 if cond
1850 echo 'true'
1851 elseif
1852 echo 'false'
1853 endif
1854 END
1855 v9.CheckDefAndScriptFailure(lines, ['E1143:', 'E15:'], 4)
Bram Moolenaare8c4abb2020-04-02 21:13:25 +02001856enddef
1857
Bram Moolenaar505ed0c2022-05-05 17:02:46 +01001858def Test_if_else_func_using_var()
1859 var lines =<< trim END
1860 vim9script
1861
1862 const debug = true
1863 if debug
1864 var mode_chars = 'something'
1865 def Bits2Ascii()
1866 var x = mode_chars
1867 g:where = 'in true'
1868 enddef
1869 else
1870 def Bits2Ascii()
1871 g:where = 'in false'
1872 enddef
1873 endif
1874
1875 Bits2Ascii()
1876 END
1877 v9.CheckScriptSuccess(lines)
1878 assert_equal('in true', g:where)
1879 unlet g:where
1880
1881 lines =<< trim END
1882 vim9script
1883
1884 const debug = false
1885 if debug
1886 var mode_chars = 'something'
1887 def Bits2Ascii()
1888 g:where = 'in true'
1889 enddef
1890 else
1891 def Bits2Ascii()
1892 var x = mode_chars
1893 g:where = 'in false'
1894 enddef
1895 endif
1896
1897 Bits2Ascii()
1898 END
1899 v9.CheckScriptFailure(lines, 'E1001: Variable not found: mode_chars')
1900enddef
1901
Bram Moolenaar6d69bf62020-03-03 19:02:12 +01001902let g:bool_true = v:true
1903let g:bool_false = v:false
1904
1905def Test_if_const_expr()
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02001906 var res = false
Bram Moolenaar6d69bf62020-03-03 19:02:12 +01001907 if true ? true : false
1908 res = true
1909 endif
1910 assert_equal(true, res)
1911
Bram Moolenaar585fea72020-04-02 22:33:21 +02001912 g:glob = 2
1913 if false
Bram Moolenaar67979662020-06-20 22:50:47 +02001914 execute('g:glob = 3')
Bram Moolenaar585fea72020-04-02 22:33:21 +02001915 endif
1916 assert_equal(2, g:glob)
1917 if true
Bram Moolenaar67979662020-06-20 22:50:47 +02001918 execute('g:glob = 3')
Bram Moolenaar585fea72020-04-02 22:33:21 +02001919 endif
1920 assert_equal(3, g:glob)
1921
Bram Moolenaar6d69bf62020-03-03 19:02:12 +01001922 res = false
1923 if g:bool_true ? true : false
1924 res = true
1925 endif
1926 assert_equal(true, res)
1927
1928 res = false
1929 if true ? g:bool_true : false
1930 res = true
1931 endif
1932 assert_equal(true, res)
1933
1934 res = false
1935 if true ? true : g:bool_false
1936 res = true
1937 endif
1938 assert_equal(true, res)
1939
1940 res = false
1941 if true ? false : true
1942 res = true
1943 endif
1944 assert_equal(false, res)
1945
1946 res = false
1947 if false ? false : true
1948 res = true
1949 endif
1950 assert_equal(true, res)
1951
1952 res = false
1953 if false ? true : false
1954 res = true
1955 endif
1956 assert_equal(false, res)
1957
1958 res = false
Bram Moolenaare8c4abb2020-04-02 21:13:25 +02001959 if has('xyz') ? true : false
1960 res = true
1961 endif
1962 assert_equal(false, res)
1963
1964 res = false
Bram Moolenaar6d69bf62020-03-03 19:02:12 +01001965 if true && true
1966 res = true
1967 endif
1968 assert_equal(true, res)
1969
1970 res = false
1971 if true && false
1972 res = true
1973 endif
1974 assert_equal(false, res)
1975
1976 res = false
1977 if g:bool_true && false
1978 res = true
1979 endif
1980 assert_equal(false, res)
1981
1982 res = false
1983 if true && g:bool_false
1984 res = true
1985 endif
1986 assert_equal(false, res)
1987
1988 res = false
1989 if false && false
1990 res = true
1991 endif
1992 assert_equal(false, res)
1993
1994 res = false
1995 if true || false
1996 res = true
1997 endif
1998 assert_equal(true, res)
1999
2000 res = false
2001 if g:bool_true || false
2002 res = true
2003 endif
2004 assert_equal(true, res)
2005
2006 res = false
2007 if true || g:bool_false
2008 res = true
2009 endif
2010 assert_equal(true, res)
2011
2012 res = false
2013 if false || false
2014 res = true
2015 endif
2016 assert_equal(false, res)
Bram Moolenaar3988f642020-08-27 22:43:03 +02002017
2018 # with constant "false" expression may be invalid so long as the syntax is OK
Bram Moolenaarc3235272021-07-10 19:42:03 +02002019 if false | eval 1 + 2 | endif
Bram Moolenaar3988f642020-08-27 22:43:03 +02002020 if false | eval burp + 234 | endif
2021 if false | echo burp 234 'asd' | endif
2022 if false
2023 burp
2024 endif
Bram Moolenaare525bdd2021-08-07 18:12:40 +02002025
Bram Moolenaar21ebb082022-02-04 21:58:58 +00002026 if 0
2027 if 1
2028 echo nothing
2029 elseif 1
2030 echo still nothing
2031 endif
2032 endif
2033
Bram Moolenaare525bdd2021-08-07 18:12:40 +02002034 # expression with line breaks skipped
2035 if false
2036 ('aaa'
2037 .. 'bbb'
2038 .. 'ccc'
2039 )->setline(1)
2040 endif
Yegappan Lakshmanane2038412024-12-14 19:59:24 +01002041
2042 if 1
2043 # do nothing
2044 else
2045 var [a] = [10]
2046 endif
Bram Moolenaar80c34ca2020-04-01 23:05:18 +02002047enddef
Bram Moolenaar6d69bf62020-03-03 19:02:12 +01002048
Bram Moolenaar80c34ca2020-04-01 23:05:18 +02002049def Test_if_const_expr_fails()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002050 v9.CheckDefFailure(['if "aaa" == "bbb'], 'E114:')
2051 v9.CheckDefFailure(["if 'aaa' == 'bbb"], 'E115:')
2052 v9.CheckDefFailure(["if has('aaa'"], 'E110:')
2053 v9.CheckDefFailure(["if has('aaa') ? true false"], 'E109:')
Bram Moolenaar6d69bf62020-03-03 19:02:12 +01002054enddef
2055
Bram Moolenaar62aec932022-01-29 21:45:34 +00002056def s:RunNested(i: number): number
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02002057 var x: number = 0
Bram Moolenaar72abcf42020-06-18 18:26:24 +02002058 if i % 2
2059 if 1
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002060 # comment
Bram Moolenaar72abcf42020-06-18 18:26:24 +02002061 else
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002062 # comment
Bram Moolenaar72abcf42020-06-18 18:26:24 +02002063 endif
2064 x += 1
2065 else
2066 x += 1000
2067 endif
2068 return x
2069enddef
2070
2071def Test_nested_if()
2072 assert_equal(1, RunNested(1))
2073 assert_equal(1000, RunNested(2))
2074enddef
2075
Bram Moolenaarad39c092020-02-26 18:23:43 +01002076def Test_execute_cmd()
Bram Moolenaare4984292020-12-13 14:19:25 +01002077 # missing argument is ignored
2078 execute
2079 execute # comment
2080
Bram Moolenaarad39c092020-02-26 18:23:43 +01002081 new
2082 setline(1, 'default')
Bram Moolenaard2c61702020-09-06 15:58:36 +02002083 execute 'setline(1, "execute-string")'
Bram Moolenaarad39c092020-02-26 18:23:43 +01002084 assert_equal('execute-string', getline(1))
Bram Moolenaara72cfb82020-04-23 17:07:30 +02002085
Bram Moolenaard2c61702020-09-06 15:58:36 +02002086 execute "setline(1, 'execute-string')"
Bram Moolenaara72cfb82020-04-23 17:07:30 +02002087 assert_equal('execute-string', getline(1))
2088
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02002089 var cmd1 = 'setline(1,'
2090 var cmd2 = '"execute-var")'
Bram Moolenaara72cfb82020-04-23 17:07:30 +02002091 execute cmd1 cmd2 # comment
Bram Moolenaarad39c092020-02-26 18:23:43 +01002092 assert_equal('execute-var', getline(1))
Bram Moolenaara72cfb82020-04-23 17:07:30 +02002093
Bram Moolenaard2c61702020-09-06 15:58:36 +02002094 execute cmd1 cmd2 '|setline(1, "execute-var-string")'
Bram Moolenaarad39c092020-02-26 18:23:43 +01002095 assert_equal('execute-var-string', getline(1))
Bram Moolenaara72cfb82020-04-23 17:07:30 +02002096
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02002097 var cmd_first = 'call '
2098 var cmd_last = 'setline(1, "execute-var-var")'
Bram Moolenaarad39c092020-02-26 18:23:43 +01002099 execute cmd_first .. cmd_last
2100 assert_equal('execute-var-var', getline(1))
2101 bwipe!
Bram Moolenaar585fea72020-04-02 22:33:21 +02002102
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02002103 var n = true
Bram Moolenaar2d6b20d2020-07-25 19:30:59 +02002104 execute 'echomsg' (n ? '"true"' : '"no"')
Bram Moolenaar62aec932022-01-29 21:45:34 +00002105 assert_match('^true$', g:Screenline(&lines))
Bram Moolenaar2d6b20d2020-07-25 19:30:59 +02002106
Bram Moolenaare0de1712020-12-02 17:36:54 +01002107 echomsg [1, 2, 3] {a: 1, b: 2}
Bram Moolenaar62aec932022-01-29 21:45:34 +00002108 assert_match('^\[1, 2, 3\] {''a'': 1, ''b'': 2}$', g:Screenline(&lines))
Bram Moolenaare5abf7a2020-08-16 18:29:35 +02002109
Bram Moolenaar62aec932022-01-29 21:45:34 +00002110 v9.CheckDefFailure(['execute xxx'], 'E1001:', 1)
2111 v9.CheckDefExecFailure(['execute "tabnext " .. 8'], 'E475:', 1)
2112 v9.CheckDefFailure(['execute "cmd"# comment'], 'E488:', 1)
Bram Moolenaar0c7f2612022-02-17 19:44:07 +00002113 if has('channel')
2114 v9.CheckDefExecFailure(['execute test_null_channel()'], 'E908:', 1)
2115 endif
Bram Moolenaarad39c092020-02-26 18:23:43 +01002116enddef
2117
Bram Moolenaar47e880d2020-06-30 22:02:02 +02002118def Test_execute_cmd_vimscript()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002119 # only checks line continuation
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02002120 var lines =<< trim END
Bram Moolenaar47e880d2020-06-30 22:02:02 +02002121 vim9script
2122 execute 'g:someVar'
2123 .. ' = ' ..
2124 '28'
2125 assert_equal(28, g:someVar)
2126 unlet g:someVar
2127 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002128 v9.CheckScriptSuccess(lines)
Bram Moolenaar47e880d2020-06-30 22:02:02 +02002129enddef
2130
Bram Moolenaar43216612022-03-25 11:16:28 +00002131def Test_execute_finish()
2132 # the empty lines are relevant here
2133 var lines =<< trim END
2134 vim9script
2135
2136 var vname = "g:hello"
2137
2138 if exists(vname) | finish | endif | execute vname '= "world"'
2139
2140 assert_equal('world', g:hello)
2141
2142 if exists(vname) | finish | endif | execute vname '= "world"'
2143
2144 assert_report('should not be reached')
2145 END
2146 v9.CheckScriptSuccess(lines)
2147enddef
2148
Bram Moolenaarad39c092020-02-26 18:23:43 +01002149def Test_echo_cmd()
Bram Moolenaara72cfb82020-04-23 17:07:30 +02002150 echo 'some' # comment
Bram Moolenaar585fea72020-04-02 22:33:21 +02002151 echon 'thing'
Bram Moolenaar62aec932022-01-29 21:45:34 +00002152 assert_match('^something$', g:Screenline(&lines))
Bram Moolenaarad39c092020-02-26 18:23:43 +01002153
Bram Moolenaara72cfb82020-04-23 17:07:30 +02002154 echo "some" # comment
2155 echon "thing"
Bram Moolenaar62aec932022-01-29 21:45:34 +00002156 assert_match('^something$', g:Screenline(&lines))
Bram Moolenaara72cfb82020-04-23 17:07:30 +02002157
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02002158 var str1 = 'some'
2159 var str2 = 'more'
Bram Moolenaarad39c092020-02-26 18:23:43 +01002160 echo str1 str2
Bram Moolenaar62aec932022-01-29 21:45:34 +00002161 assert_match('^some more$', g:Screenline(&lines))
Bram Moolenaara72cfb82020-04-23 17:07:30 +02002162
Bram Moolenaar397a87a2022-03-20 21:14:15 +00002163 echo "one\ntwo"
2164 assert_match('^one$', g:Screenline(&lines - 1))
2165 assert_match('^two$', g:Screenline(&lines))
2166
Bram Moolenaar62aec932022-01-29 21:45:34 +00002167 v9.CheckDefFailure(['echo "xxx"# comment'], 'E488:')
Yegappan Lakshmanan22029ed2024-05-20 13:57:11 +02002168
2169 # Test for echoing a script local function name
2170 var lines =<< trim END
2171 vim9script
2172 def ScriptLocalEcho()
2173 enddef
2174 echo ScriptLocalEcho
2175 END
2176 new
2177 setline(1, lines)
2178 assert_match('<SNR>\d\+_ScriptLocalEcho', execute('source')->split("\n")[0])
2179 bw!
Bram Moolenaarad39c092020-02-26 18:23:43 +01002180enddef
2181
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002182def Test_echomsg_cmd()
2183 echomsg 'some' 'more' # comment
Bram Moolenaar62aec932022-01-29 21:45:34 +00002184 assert_match('^some more$', g:Screenline(&lines))
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002185 echo 'clear'
Bram Moolenaardf069ee2020-06-22 23:02:51 +02002186 :1messages
Bram Moolenaar62aec932022-01-29 21:45:34 +00002187 assert_match('^some more$', g:Screenline(&lines))
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002188
Bram Moolenaar62aec932022-01-29 21:45:34 +00002189 v9.CheckDefFailure(['echomsg "xxx"# comment'], 'E488:')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002190enddef
2191
Bram Moolenaar47e880d2020-06-30 22:02:02 +02002192def Test_echomsg_cmd_vimscript()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002193 # only checks line continuation
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02002194 var lines =<< trim END
Bram Moolenaar47e880d2020-06-30 22:02:02 +02002195 vim9script
2196 echomsg 'here'
2197 .. ' is ' ..
2198 'a message'
Bram Moolenaar62aec932022-01-29 21:45:34 +00002199 assert_match('^here is a message$', g:Screenline(&lines))
Bram Moolenaar47e880d2020-06-30 22:02:02 +02002200 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002201 v9.CheckScriptSuccess(lines)
Bram Moolenaar47e880d2020-06-30 22:02:02 +02002202enddef
2203
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002204def Test_echoerr_cmd()
Bram Moolenaar7de62622021-08-07 15:05:47 +02002205 var local = 'local'
Bram Moolenaar40ee4662020-05-05 22:08:26 +02002206 try
Bram Moolenaar7de62622021-08-07 15:05:47 +02002207 echoerr 'something' local 'wrong' # comment
Bram Moolenaar40ee4662020-05-05 22:08:26 +02002208 catch
Bram Moolenaar7de62622021-08-07 15:05:47 +02002209 assert_match('something local wrong', v:exception)
Bram Moolenaar40ee4662020-05-05 22:08:26 +02002210 endtry
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002211enddef
2212
Bram Moolenaar47e880d2020-06-30 22:02:02 +02002213def Test_echoerr_cmd_vimscript()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002214 # only checks line continuation
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02002215 var lines =<< trim END
Bram Moolenaar47e880d2020-06-30 22:02:02 +02002216 vim9script
2217 try
2218 echoerr 'this'
2219 .. ' is ' ..
2220 'wrong'
2221 catch
2222 assert_match('this is wrong', v:exception)
2223 endtry
2224 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002225 v9.CheckScriptSuccess(lines)
Bram Moolenaar47e880d2020-06-30 22:02:02 +02002226enddef
2227
Bram Moolenaar7de62622021-08-07 15:05:47 +02002228def Test_echoconsole_cmd()
2229 var local = 'local'
2230 echoconsole 'something' local # comment
2231 # output goes anywhere
2232enddef
2233
Bram Moolenaar7d7ad7b2022-09-01 16:00:53 +01002234def Test_echowindow_cmd()
2235 var local = 'local'
2236 echowindow 'something' local # comment
Bram Moolenaar2435adf2022-10-21 12:05:46 +01002237
2238 # with modifier
2239 unsilent echowin 'loud'
2240
Bram Moolenaar7d7ad7b2022-09-01 16:00:53 +01002241 # output goes in message window
2242 popup_clear()
Yegappan Lakshmanane2038412024-12-14 19:59:24 +01002243
2244 # Invalid range
2245 var lines =<< trim END
2246 def Foo()
2247 :$echowindow "foo"
2248 enddef
2249 defcompile
2250 END
2251 v9.CheckDefAndScriptFailure(lines, 'E16: Invalid range')
Bram Moolenaar7d7ad7b2022-09-01 16:00:53 +01002252enddef
2253
Bram Moolenaar41fe0612020-03-01 16:22:40 +01002254def Test_for_outside_of_function()
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02002255 var lines =<< trim END
Bram Moolenaar41fe0612020-03-01 16:22:40 +01002256 vim9script
2257 new
2258 for var in range(0, 3)
2259 append(line('$'), var)
2260 endfor
2261 assert_equal(['', '0', '1', '2', '3'], getline(1, '$'))
2262 bwipe!
Bram Moolenaar522eefd2021-03-26 18:49:22 +01002263
2264 var result = ''
2265 for i in [1, 2, 3]
2266 var loop = ' loop ' .. i
2267 result ..= loop
2268 endfor
2269 assert_equal(' loop 1 loop 2 loop 3', result)
Bram Moolenaar41fe0612020-03-01 16:22:40 +01002270 END
Bram Moolenaardd674772022-09-15 22:26:18 +01002271 writefile(lines, 'Xvim9for.vim', 'D')
Bram Moolenaar41fe0612020-03-01 16:22:40 +01002272 source Xvim9for.vim
Bram Moolenaar41fe0612020-03-01 16:22:40 +01002273enddef
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002274
rbtnnbebf0692021-08-21 17:26:50 +02002275def Test_for_skipped_block()
2276 # test skipped blocks at outside of function
2277 var lines =<< trim END
2278 var result = []
2279 if true
2280 for n in [1, 2]
2281 result += [n]
2282 endfor
2283 else
2284 for n in [3, 4]
2285 result += [n]
2286 endfor
2287 endif
2288 assert_equal([1, 2], result)
2289
2290 result = []
2291 if false
2292 for n in [1, 2]
2293 result += [n]
2294 endfor
2295 else
2296 for n in [3, 4]
2297 result += [n]
2298 endfor
2299 endif
2300 assert_equal([3, 4], result)
2301 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002302 v9.CheckDefAndScriptSuccess(lines)
rbtnnbebf0692021-08-21 17:26:50 +02002303
2304 # test skipped blocks at inside of function
2305 lines =<< trim END
2306 def DefTrue()
2307 var result = []
2308 if true
2309 for n in [1, 2]
2310 result += [n]
2311 endfor
2312 else
2313 for n in [3, 4]
2314 result += [n]
2315 endfor
2316 endif
2317 assert_equal([1, 2], result)
2318 enddef
2319 DefTrue()
2320
2321 def DefFalse()
2322 var result = []
2323 if false
2324 for n in [1, 2]
2325 result += [n]
2326 endfor
2327 else
2328 for n in [3, 4]
2329 result += [n]
2330 endfor
2331 endif
2332 assert_equal([3, 4], result)
2333 enddef
2334 DefFalse()
Bram Moolenaar97f8c102022-04-02 19:43:57 +01002335
2336 def BuildDiagrams()
2337 var diagrams: list<any>
2338 if false
2339 var max = 0
2340 for v in diagrams
2341 var l = 3
2342 if max < l | max = l | endif
2343 v->add(l)
2344 endfor
2345 endif
2346 enddef
2347 BuildDiagrams()
rbtnnbebf0692021-08-21 17:26:50 +02002348 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002349 v9.CheckDefAndScriptSuccess(lines)
rbtnnbebf0692021-08-21 17:26:50 +02002350enddef
2351
Bram Moolenaar4875d6a2022-08-17 15:55:51 +01002352def Test_skipped_redir()
2353 var lines =<< trim END
Bram Moolenaar3558afe2022-10-13 16:12:57 +01002354 def Tredir()
Bram Moolenaar4875d6a2022-08-17 15:55:51 +01002355 if 0
Bram Moolenaar3558afe2022-10-13 16:12:57 +01002356 redir => l[0]
Bram Moolenaar4875d6a2022-08-17 15:55:51 +01002357 redir END
2358 endif
2359 enddef
2360 defcompile
2361 END
2362 v9.CheckScriptSuccess(lines)
Bram Moolenaar3558afe2022-10-13 16:12:57 +01002363 delfunc g:Tredir
2364
2365 lines =<< trim END
2366 def Tredir()
2367 if 0
2368 redir => l[0]
2369 endif
2370 echo 'executed'
2371 if 0
2372 redir END
2373 endif
2374 enddef
2375 defcompile
2376 END
2377 v9.CheckScriptSuccess(lines)
2378 delfunc g:Tredir
2379
2380 lines =<< trim END
2381 def Tredir()
2382 var l = ['']
2383 if 1
2384 redir => l[0]
2385 endif
2386 echo 'executed'
2387 if 0
2388 redir END
2389 else
2390 redir END
2391 endif
2392 enddef
2393 defcompile
2394 END
2395 v9.CheckScriptSuccess(lines)
2396 delfunc g:Tredir
2397
2398 lines =<< trim END
2399 let doit = 1
2400 def Tredir()
2401 var l = ['']
2402 if g:doit
2403 redir => l[0]
2404 endif
2405 echo 'executed'
2406 if g:doit
2407 redir END
2408 endif
2409 enddef
2410 defcompile
2411 END
2412 v9.CheckScriptSuccess(lines)
2413 delfunc g:Tredir
Bram Moolenaar4875d6a2022-08-17 15:55:51 +01002414enddef
2415
Bram Moolenaare8c4abb2020-04-02 21:13:25 +02002416def Test_for_loop()
Bram Moolenaarf2253962021-04-13 20:53:13 +02002417 var lines =<< trim END
2418 var result = ''
2419 for cnt in range(7)
2420 if cnt == 4
2421 break
2422 endif
2423 if cnt == 2
2424 continue
2425 endif
2426 result ..= cnt .. '_'
2427 endfor
2428 assert_equal('0_1_3_', result)
Bram Moolenaar0ad3e892020-07-05 21:38:11 +02002429
Bram Moolenaarf2253962021-04-13 20:53:13 +02002430 var concat = ''
2431 for str in eval('["one", "two"]')
2432 concat ..= str
2433 endfor
2434 assert_equal('onetwo', concat)
Bram Moolenaar38bd8de2020-12-02 13:23:36 +01002435
Bram Moolenaarf2253962021-04-13 20:53:13 +02002436 var total = 0
2437 for nr in
2438 [1, 2, 3]
2439 total += nr
2440 endfor
2441 assert_equal(6, total)
Bram Moolenaar38bd8de2020-12-02 13:23:36 +01002442
Bram Moolenaarf2253962021-04-13 20:53:13 +02002443 total = 0
2444 for nr
2445 in [1, 2, 3]
2446 total += nr
2447 endfor
2448 assert_equal(6, total)
Bram Moolenaar38bd8de2020-12-02 13:23:36 +01002449
Bram Moolenaarf2253962021-04-13 20:53:13 +02002450 total = 0
2451 for nr
2452 in
2453 [1, 2, 3]
2454 total += nr
2455 endfor
2456 assert_equal(6, total)
Bram Moolenaar036d0712021-01-17 20:23:38 +01002457
Bram Moolenaara3589a02021-04-14 13:30:46 +02002458 # with type
2459 total = 0
2460 for n: number in [1, 2, 3]
2461 total += n
2462 endfor
2463 assert_equal(6, total)
2464
Bram Moolenaarefd73ae2022-03-20 18:51:00 +00002465 total = 0
2466 for b in 0z010203
2467 total += b
2468 endfor
2469 assert_equal(6, total)
2470
Bram Moolenaarfe090eb2021-04-15 21:48:32 +02002471 var chars = ''
2472 for s: string in 'foobar'
2473 chars ..= s
2474 endfor
2475 assert_equal('foobar', chars)
2476
Bram Moolenaar5ede5b22021-07-07 21:55:25 +02002477 chars = ''
2478 for x: string in {a: 'a', b: 'b'}->values()
2479 chars ..= x
2480 endfor
2481 assert_equal('ab', chars)
2482
Bram Moolenaara3589a02021-04-14 13:30:46 +02002483 # unpack with type
Bram Moolenaarf2253962021-04-13 20:53:13 +02002484 var res = ''
Bram Moolenaara3589a02021-04-14 13:30:46 +02002485 for [n: number, s: string] in [[1, 'a'], [2, 'b']]
2486 res ..= n .. s
2487 endfor
2488 assert_equal('1a2b', res)
2489
Bram Moolenaar444d8782021-06-26 12:40:56 +02002490 # unpack with one var
2491 var reslist = []
2492 for [x] in [['aaa'], ['bbb']]
2493 reslist->add(x)
2494 endfor
2495 assert_equal(['aaa', 'bbb'], reslist)
2496
Bram Moolenaara3589a02021-04-14 13:30:46 +02002497 # loop over string
2498 res = ''
Bram Moolenaarf2253962021-04-13 20:53:13 +02002499 for c in 'aéc̀d'
2500 res ..= c .. '-'
2501 endfor
2502 assert_equal('a-é-c̀-d-', res)
2503
2504 res = ''
2505 for c in ''
2506 res ..= c .. '-'
2507 endfor
2508 assert_equal('', res)
2509
2510 res = ''
2511 for c in test_null_string()
2512 res ..= c .. '-'
2513 endfor
2514 assert_equal('', res)
2515
Bram Moolenaar10611952022-04-03 21:11:34 +01002516 total = 0
2517 for c in null_list
2518 total += 1
2519 endfor
2520 assert_equal(0, total)
2521
2522 for c in null_blob
2523 total += 1
2524 endfor
2525 assert_equal(0, total)
2526
Bram Moolenaarf2253962021-04-13 20:53:13 +02002527 var foo: list<dict<any>> = [
2528 {a: 'Cat'}
2529 ]
2530 for dd in foo
2531 dd.counter = 12
2532 endfor
2533 assert_equal([{a: 'Cat', counter: 12}], foo)
Bram Moolenaarad2d4962021-07-18 17:08:50 +02002534
2535 reslist = []
2536 for _ in range(3)
2537 reslist->add('x')
2538 endfor
2539 assert_equal(['x', 'x', 'x'], reslist)
Yegappan Lakshmanan4776e642024-05-19 09:06:50 +02002540
2541 # Test for trying to use the loop variable "_" inside the loop
2542 for _ in "a"
2543 assert_fails('echo _', 'E1181: Cannot use an underscore here')
2544 endfor
Bram Moolenaarf2253962021-04-13 20:53:13 +02002545 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002546 v9.CheckDefAndScriptSuccess(lines)
Yegappan Lakshmananfe424d12024-05-17 18:20:43 +02002547
2548 lines =<< trim END
2549 for i : number : [1, 2]
2550 echo i
2551 endfor
2552 END
2553 v9.CheckSourceDefAndScriptFailure(lines, 'E1059: No white space allowed before colon: : [1, 2]', 1)
Bram Moolenaare8c4abb2020-04-02 21:13:25 +02002554enddef
2555
Bram Moolenaar159b2d52022-10-11 21:41:25 +01002556def Test_for_loop_list_of_lists()
2557 # loop variable is final, not const
2558 var lines =<< trim END
2559 # Filter out all odd numbers in each sublist
2560 var list: list<list<number>> = [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4]]
2561 for i in list
2562 filter(i, (_, n: number): bool => n % 2 == 0)
2563 endfor
2564
2565 assert_equal([[], [2], [2], [2, 4]], list)
2566 END
2567 v9.CheckDefAndScriptSuccess(lines)
2568enddef
2569
Bram Moolenaar2eb6fc32021-07-25 14:13:53 +02002570def Test_for_loop_with_closure()
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01002571 # using the loop variable in a closure results in the last used value
Bram Moolenaar2eb6fc32021-07-25 14:13:53 +02002572 var lines =<< trim END
2573 var flist: list<func>
2574 for i in range(5)
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01002575 flist[i] = () => i
2576 endfor
2577 for i in range(5)
2578 assert_equal(4, flist[i]())
2579 endfor
2580 END
2581 v9.CheckDefAndScriptSuccess(lines)
2582
Bram Moolenaardd674772022-09-15 22:26:18 +01002583 # also works when the loop variable is used only once halfway the loops
2584 lines =<< trim END
2585 var Clo: func
2586 for i in range(5)
2587 if i == 3
2588 Clo = () => i
2589 endif
2590 endfor
2591 assert_equal(4, Clo())
2592 END
2593 v9.CheckDefAndScriptSuccess(lines)
2594
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01002595 # using a local variable set to the loop variable in a closure results in the
2596 # value at that moment
2597 lines =<< trim END
2598 var flist: list<func>
2599 for i in range(5)
Bram Moolenaar2eb6fc32021-07-25 14:13:53 +02002600 var inloop = i
2601 flist[i] = () => inloop
2602 endfor
2603 for i in range(5)
Bram Moolenaar353b68a2022-09-13 21:10:45 +01002604 assert_equal(i, flist[i]())
Bram Moolenaar2eb6fc32021-07-25 14:13:53 +02002605 endfor
2606 END
Bram Moolenaar0cdfb7c2022-09-17 15:44:52 +01002607 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar2eb6fc32021-07-25 14:13:53 +02002608
Bram Moolenaara275f2c2022-10-11 20:04:09 +01002609 # also with an extra block level
2610 lines =<< trim END
2611 var flist: list<func>
2612 for i in range(5)
2613 {
2614 var inloop = i
2615 flist[i] = () => inloop
2616 }
2617 endfor
2618 for i in range(5)
2619 assert_equal(i, flist[i]())
2620 endfor
2621 END
2622 v9.CheckDefAndScriptSuccess(lines)
2623
2624 # and declaration in higher block
2625 lines =<< trim END
2626 var flist: list<func>
2627 for i in range(5)
2628 var inloop = i
2629 {
2630 flist[i] = () => inloop
2631 }
2632 endfor
2633 for i in range(5)
2634 assert_equal(i, flist[i]())
2635 endfor
2636 END
2637 v9.CheckDefAndScriptSuccess(lines)
2638
Bram Moolenaar2eb6fc32021-07-25 14:13:53 +02002639 lines =<< trim END
2640 var flist: list<func>
2641 for i in range(5)
2642 var inloop = i
2643 flist[i] = () => {
2644 return inloop
2645 }
2646 endfor
2647 for i in range(5)
Bram Moolenaar353b68a2022-09-13 21:10:45 +01002648 assert_equal(i, flist[i]())
Bram Moolenaar2eb6fc32021-07-25 14:13:53 +02002649 endfor
2650 END
Bram Moolenaar0cdfb7c2022-09-17 15:44:52 +01002651 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaardbbb02b2022-09-18 12:00:21 +01002652
2653 # Also works for a nested loop
2654 lines =<< trim END
2655 var flist: list<func>
2656 var n = 0
2657 for i in range(3)
2658 var ii = i
2659 for a in ['a', 'b', 'c']
2660 var aa = a
2661 flist[n] = () => ii .. aa
2662 ++n
2663 endfor
2664 endfor
2665
2666 n = 0
2667 for i in range(3)
2668 for a in ['a', 'b', 'c']
2669 assert_equal(i .. a, flist[n]())
2670 ++n
2671 endfor
2672 endfor
2673 END
Bram Moolenaarcc341812022-09-19 15:54:34 +01002674 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaare8e369a2022-09-21 18:59:14 +01002675
2676 # using two loop variables
2677 lines =<< trim END
2678 var lv_list: list<func>
2679 var copy_list: list<func>
2680 for [idx, c] in items('word')
2681 var lidx = idx
2682 var lc = c
2683 lv_list[idx] = () => {
2684 return idx .. c
2685 }
2686 copy_list[idx] = () => {
2687 return lidx .. lc
2688 }
2689 endfor
2690 for [i, c] in items('word')
2691 assert_equal(3 .. 'd', lv_list[i]())
2692 assert_equal(i .. c, copy_list[i]())
2693 endfor
2694 END
2695 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarcc341812022-09-19 15:54:34 +01002696enddef
2697
2698def Test_define_global_closure_in_loops()
2699 var lines =<< trim END
2700 vim9script
2701
2702 def Func()
2703 for i in range(3)
2704 var ii = i
2705 for a in ['a', 'b', 'c']
2706 var aa = a
2707 if ii == 0 && aa == 'a'
2708 def g:Global_0a(): string
2709 return ii .. aa
2710 enddef
2711 endif
2712 if ii == 1 && aa == 'b'
2713 def g:Global_1b(): string
2714 return ii .. aa
2715 enddef
2716 endif
2717 if ii == 2 && aa == 'c'
2718 def g:Global_2c(): string
2719 return ii .. aa
2720 enddef
2721 endif
2722 endfor
2723 endfor
2724 enddef
2725 Func()
2726 END
2727 v9.CheckScriptSuccess(lines)
2728 assert_equal("0a", g:Global_0a())
2729 assert_equal("1b", g:Global_1b())
2730 assert_equal("2c", g:Global_2c())
2731
2732 delfunc g:Global_0a
2733 delfunc g:Global_1b
2734 delfunc g:Global_2c
Bram Moolenaar2eb6fc32021-07-25 14:13:53 +02002735enddef
2736
Bram Moolenaare8c4abb2020-04-02 21:13:25 +02002737def Test_for_loop_fails()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002738 v9.CheckDefAndScriptFailure(['for '], ['E1097:', 'E690:'])
2739 v9.CheckDefAndScriptFailure(['for x'], ['E1097:', 'E690:'])
2740 v9.CheckDefAndScriptFailure(['for x in'], ['E1097:', 'E15:'])
2741 v9.CheckDefAndScriptFailure(['for # in range(5)'], 'E690:')
2742 v9.CheckDefAndScriptFailure(['for i In range(5)'], 'E690:')
2743 v9.CheckDefAndScriptFailure(['var x = 5', 'for x in range(5)', 'endfor'], ['E1017:', 'E1041:'])
2744 v9.CheckScriptFailure(['vim9script', 'var x = 5', 'for x in range(5)', '# comment', 'endfor'], 'E1041:', 3)
2745 v9.CheckScriptFailure(['def Func(arg: any)', 'for arg in range(5)', 'enddef', 'defcompile'], 'E1006:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002746 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002747 v9.CheckDefFailure(['for i in xxx'], 'E1001:')
2748 v9.CheckDefFailure(['endfor'], 'E588:')
2749 v9.CheckDefFailure(['for i in range(3)', 'echo 3'], 'E170:')
Bram Moolenaar74e54fc2021-03-26 20:41:29 +01002750
2751 # wrong type detected at compile time
Bram Moolenaar62aec932022-01-29 21:45:34 +00002752 v9.CheckDefFailure(['for i in {a: 1}', 'echo 3', 'endfor'], 'E1177: For loop on dict not supported')
Bram Moolenaar74e54fc2021-03-26 20:41:29 +01002753
2754 # wrong type detected at runtime
2755 g:adict = {a: 1}
Bram Moolenaar62aec932022-01-29 21:45:34 +00002756 v9.CheckDefExecFailure(['for i in g:adict', 'echo 3', 'endfor'], 'E1177: For loop on dict not supported')
Bram Moolenaar74e54fc2021-03-26 20:41:29 +01002757 unlet g:adict
Bram Moolenaarf6a8d422021-04-13 21:48:03 +02002758
2759 var lines =<< trim END
2760 var d: list<dict<any>> = [{a: 0}]
2761 for e in d
2762 e = {a: 0, b: ''}
2763 endfor
2764 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002765 v9.CheckDefAndScriptFailure(lines, ['E1018:', 'E46:'], 3)
Bram Moolenaarfe090eb2021-04-15 21:48:32 +02002766
2767 lines =<< trim END
2768 for nr: number in ['foo']
2769 endfor
2770 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002771 v9.CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
Bram Moolenaar404557e2021-07-05 21:41:48 +02002772
2773 lines =<< trim END
2774 for n : number in [1, 2]
2775 echo n
2776 endfor
2777 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002778 v9.CheckDefAndScriptFailure(lines, 'E1059:', 1)
Bram Moolenaarefc5db52021-07-07 21:21:30 +02002779
2780 lines =<< trim END
2781 var d: dict<number> = {a: 1, b: 2}
2782 for [k: job, v: job] in d->items()
2783 echo k v
2784 endfor
2785 END
Bram Moolenaarbd3a9d22022-05-17 16:12:39 +01002786 v9.CheckDefExecAndScriptFailure(lines, ['E1163: Variable 1: type mismatch, expected job but got string', 'E1012: Type mismatch; expected job but got string'], 2)
Bram Moolenaar3b3755f2021-11-22 20:10:18 +00002787
2788 lines =<< trim END
2789 var i = 0
2790 for i in [1, 2, 3]
2791 echo i
2792 endfor
2793 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002794 v9.CheckDefExecAndScriptFailure(lines, ['E1017:', 'E1041:'])
Bram Moolenaar3b3755f2021-11-22 20:10:18 +00002795
2796 lines =<< trim END
2797 var l = [0]
2798 for l[0] in [1, 2, 3]
2799 echo l[0]
2800 endfor
2801 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002802 v9.CheckDefExecAndScriptFailure(lines, ['E461:', 'E1017:'])
Bram Moolenaar3b3755f2021-11-22 20:10:18 +00002803
2804 lines =<< trim END
2805 var d = {x: 0}
2806 for d.x in [1, 2, 3]
2807 echo d.x
2808 endfor
2809 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002810 v9.CheckDefExecAndScriptFailure(lines, ['E461:', 'E1017:'])
Bram Moolenaara1c51952022-02-02 16:20:26 +00002811
2812 lines =<< trim END
2813 var l: list<dict<any>> = [{a: 1, b: 'x'}]
2814 for item: dict<number> in l
2815 echo item
2816 endfor
2817 END
2818 v9.CheckDefExecAndScriptFailure(lines, 'E1012: Type mismatch; expected dict<number> but got dict<any>')
2819
2820 lines =<< trim END
2821 var l: list<dict<any>> = [{n: 1}]
2822 for item: dict<number> in l
Bram Moolenaarfa103972022-09-29 19:14:42 +01002823 var d = {s: ''}
2824 d->extend(item)
Bram Moolenaara1c51952022-02-02 16:20:26 +00002825 endfor
2826 END
Bram Moolenaarfa103972022-09-29 19:14:42 +01002827 v9.CheckDefExecAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected dict<string> but got dict<number>')
Bram Moolenaarcc341812022-09-19 15:54:34 +01002828
2829 lines =<< trim END
2830 for a in range(3)
2831 while a > 3
2832 for b in range(2)
2833 while b < 0
2834 for c in range(5)
2835 while c > 6
2836 while c < 0
2837 for d in range(1)
2838 for e in range(3)
2839 while e > 3
2840 endwhile
2841 endfor
2842 endfor
2843 endwhile
2844 endwhile
2845 endfor
2846 endwhile
2847 endfor
2848 endwhile
2849 endfor
2850 END
2851 v9.CheckDefSuccess(lines)
2852
2853 v9.CheckDefFailure(['for x in range(3)'] + lines + ['endfor'], 'E1306:')
Yegappan Lakshmanan062bb6b2023-12-16 14:46:40 +01002854
2855 # Test for too many for loops
2856 lines =<< trim END
2857 vim9script
2858 def Foo()
2859 for a in range(1)
2860 for b in range(1)
2861 for c in range(1)
2862 for d in range(1)
2863 for e in range(1)
2864 for f in range(1)
2865 for g in range(1)
2866 for h in range(1)
2867 for i in range(1)
2868 for j in range(1)
2869 for k in range(1)
2870 endfor
2871 endfor
2872 endfor
2873 endfor
2874 endfor
2875 endfor
2876 endfor
2877 endfor
2878 endfor
2879 endfor
2880 endfor
2881 enddef
2882 defcompile
2883 END
2884 v9.CheckSourceFailure(lines, 'E1306: Loop nesting too deep', 11)
Bram Moolenaare8c4abb2020-04-02 21:13:25 +02002885enddef
2886
Bram Moolenaarea870692020-12-02 14:24:30 +01002887def Test_for_loop_script_var()
2888 # cannot use s:var in a :def function
Bram Moolenaar62aec932022-01-29 21:45:34 +00002889 v9.CheckDefFailure(['for s:var in range(3)', 'echo 3'], 'E1254:')
Bram Moolenaarea870692020-12-02 14:24:30 +01002890
2891 # can use s:var in Vim9 script, with or without s:
2892 var lines =<< trim END
2893 vim9script
2894 var total = 0
2895 for s:var in [1, 2, 3]
2896 total += s:var
2897 endfor
2898 assert_equal(6, total)
2899
2900 total = 0
2901 for var in [1, 2, 3]
2902 total += var
2903 endfor
2904 assert_equal(6, total)
2905 END
2906enddef
2907
Bram Moolenaar792f7862020-11-23 08:31:18 +01002908def Test_for_loop_unpack()
Bram Moolenaar792f7862020-11-23 08:31:18 +01002909 var lines =<< trim END
Bram Moolenaar4b8a0652020-12-01 16:30:44 +01002910 var result = []
2911 for [v1, v2] in [[1, 2], [3, 4]]
2912 result->add(v1)
2913 result->add(v2)
2914 endfor
2915 assert_equal([1, 2, 3, 4], result)
2916
2917 result = []
2918 for [v1, v2; v3] in [[1, 2], [3, 4, 5, 6]]
2919 result->add(v1)
2920 result->add(v2)
2921 result->add(v3)
2922 endfor
2923 assert_equal([1, 2, [], 3, 4, [5, 6]], result)
2924
2925 result = []
2926 for [&ts, &sw] in [[1, 2], [3, 4]]
2927 result->add(&ts)
2928 result->add(&sw)
2929 endfor
2930 assert_equal([1, 2, 3, 4], result)
2931
2932 var slist: list<string>
2933 for [$LOOPVAR, @r, v:errmsg] in [['a', 'b', 'c'], ['d', 'e', 'f']]
2934 slist->add($LOOPVAR)
2935 slist->add(@r)
2936 slist->add(v:errmsg)
2937 endfor
2938 assert_equal(['a', 'b', 'c', 'd', 'e', 'f'], slist)
2939
2940 slist = []
2941 for [g:globalvar, b:bufvar, w:winvar, t:tabvar] in [['global', 'buf', 'win', 'tab'], ['1', '2', '3', '4']]
2942 slist->add(g:globalvar)
2943 slist->add(b:bufvar)
2944 slist->add(w:winvar)
2945 slist->add(t:tabvar)
2946 endfor
2947 assert_equal(['global', 'buf', 'win', 'tab', '1', '2', '3', '4'], slist)
Bram Moolenaarf6c177a2020-12-04 17:38:00 +01002948 unlet! g:globalvar b:bufvar w:winvar t:tabvar
Bram Moolenaarb777da92021-05-22 21:40:39 +02002949
2950 var res = []
2951 for [_, n, _] in [[1, 2, 3], [4, 5, 6]]
2952 res->add(n)
2953 endfor
2954 assert_equal([2, 5], res)
Bram Moolenaar61efa162022-03-18 13:10:48 +00002955
2956 var text: list<string> = ["hello there", "goodbye now"]
2957 var splitted = ''
2958 for [first; next] in mapnew(text, (i, v) => split(v))
2959 splitted ..= string(first) .. string(next) .. '/'
2960 endfor
2961 assert_equal("'hello'['there']/'goodbye'['now']/", splitted)
Bram Moolenaar4b8a0652020-12-01 16:30:44 +01002962 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002963 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar4b8a0652020-12-01 16:30:44 +01002964
2965 lines =<< trim END
Bram Moolenaar792f7862020-11-23 08:31:18 +01002966 for [v1, v2] in [[1, 2, 3], [3, 4]]
2967 echo v1 v2
2968 endfor
2969 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002970 v9.CheckDefExecFailure(lines, 'E710:', 1)
Bram Moolenaar792f7862020-11-23 08:31:18 +01002971
2972 lines =<< trim END
2973 for [v1, v2] in [[1], [3, 4]]
2974 echo v1 v2
2975 endfor
2976 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002977 v9.CheckDefExecFailure(lines, 'E711:', 1)
Bram Moolenaar792f7862020-11-23 08:31:18 +01002978
2979 lines =<< trim END
2980 for [v1, v1] in [[1, 2], [3, 4]]
2981 echo v1
2982 endfor
2983 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002984 v9.CheckDefExecFailure(lines, 'E1017:', 1)
Bram Moolenaar95e4dd82022-04-27 22:15:40 +01002985
2986 lines =<< trim END
2987 for [a, b] in g:listlist
2988 echo a
2989 endfor
2990 END
2991 g:listlist = [1, 2, 3]
2992 v9.CheckDefExecFailure(lines, 'E1140:', 1)
Bram Moolenaar792f7862020-11-23 08:31:18 +01002993enddef
2994
Bram Moolenaarc150c092021-02-13 15:02:46 +01002995def Test_for_loop_with_try_continue()
Bram Moolenaarf2253962021-04-13 20:53:13 +02002996 var lines =<< trim END
2997 var looped = 0
2998 var cleanup = 0
2999 for i in range(3)
3000 looped += 1
3001 try
3002 eval [][0]
3003 catch
3004 continue
3005 finally
3006 cleanup += 1
3007 endtry
3008 endfor
3009 assert_equal(3, looped)
3010 assert_equal(3, cleanup)
3011 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003012 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarc150c092021-02-13 15:02:46 +01003013enddef
3014
rbtnnd895b1d2021-08-20 20:54:25 +02003015def Test_while_skipped_block()
3016 # test skipped blocks at outside of function
3017 var lines =<< trim END
3018 var result = []
3019 var n = 0
3020 if true
3021 n = 1
3022 while n < 3
3023 result += [n]
3024 n += 1
3025 endwhile
3026 else
3027 n = 3
3028 while n < 5
3029 result += [n]
3030 n += 1
3031 endwhile
3032 endif
3033 assert_equal([1, 2], result)
3034
3035 result = []
3036 if false
3037 n = 1
3038 while n < 3
3039 result += [n]
3040 n += 1
3041 endwhile
3042 else
3043 n = 3
3044 while n < 5
3045 result += [n]
3046 n += 1
3047 endwhile
3048 endif
3049 assert_equal([3, 4], result)
3050 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003051 v9.CheckDefAndScriptSuccess(lines)
rbtnnd895b1d2021-08-20 20:54:25 +02003052
3053 # test skipped blocks at inside of function
3054 lines =<< trim END
3055 def DefTrue()
3056 var result = []
3057 var n = 0
3058 if true
3059 n = 1
3060 while n < 3
3061 result += [n]
3062 n += 1
3063 endwhile
3064 else
3065 n = 3
3066 while n < 5
3067 result += [n]
3068 n += 1
3069 endwhile
3070 endif
3071 assert_equal([1, 2], result)
3072 enddef
3073 DefTrue()
3074
3075 def DefFalse()
3076 var result = []
3077 var n = 0
3078 if false
3079 n = 1
3080 while n < 3
3081 result += [n]
3082 n += 1
3083 endwhile
3084 else
3085 n = 3
3086 while n < 5
3087 result += [n]
3088 n += 1
3089 endwhile
3090 endif
3091 assert_equal([3, 4], result)
3092 enddef
3093 DefFalse()
3094 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003095 v9.CheckDefAndScriptSuccess(lines)
rbtnnd895b1d2021-08-20 20:54:25 +02003096enddef
3097
Bram Moolenaard0df1aa2020-03-04 21:50:46 +01003098def Test_while_loop()
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02003099 var result = ''
3100 var cnt = 0
Bram Moolenaard0df1aa2020-03-04 21:50:46 +01003101 while cnt < 555
3102 if cnt == 3
3103 break
3104 endif
3105 cnt += 1
3106 if cnt == 2
3107 continue
3108 endif
3109 result ..= cnt .. '_'
3110 endwhile
3111 assert_equal('1_3_', result)
Bram Moolenaardee37dc2021-02-07 16:40:05 +01003112
3113 var s = ''
Bram Moolenaar4b3e1962021-03-18 21:37:55 +01003114 while s == 'x' # {comment}
Bram Moolenaardee37dc2021-02-07 16:40:05 +01003115 endwhile
Bram Moolenaard0df1aa2020-03-04 21:50:46 +01003116enddef
3117
Bram Moolenaar7a53f292021-11-22 18:31:02 +00003118def Test_while_loop_in_script()
3119 var lines =<< trim END
3120 vim9script
3121 var result = ''
3122 var cnt = 0
3123 while cnt < 3
3124 var s = 'v' .. cnt
3125 result ..= s
3126 cnt += 1
3127 endwhile
3128 assert_equal('v0v1v2', result)
3129 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003130 v9.CheckScriptSuccess(lines)
Bram Moolenaar7a53f292021-11-22 18:31:02 +00003131enddef
3132
Bram Moolenaare8c4abb2020-04-02 21:13:25 +02003133def Test_while_loop_fails()
Bram Moolenaar62aec932022-01-29 21:45:34 +00003134 v9.CheckDefFailure(['while xxx'], 'E1001:')
3135 v9.CheckDefFailure(['endwhile'], 'E588:')
3136 v9.CheckDefFailure(['continue'], 'E586:')
3137 v9.CheckDefFailure(['if true', 'continue'], 'E586:')
3138 v9.CheckDefFailure(['break'], 'E587:')
3139 v9.CheckDefFailure(['if true', 'break'], 'E587:')
3140 v9.CheckDefFailure(['while 1', 'echo 3'], 'E170:')
Bram Moolenaar6628b7e2021-02-07 16:33:35 +01003141
3142 var lines =<< trim END
3143 var s = ''
3144 while s = ''
3145 endwhile
3146 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003147 v9.CheckDefFailure(lines, 'E488:')
Bram Moolenaarbd5da372020-03-31 23:13:10 +02003148enddef
3149
Bram Moolenaar9645e2d2020-03-20 20:48:49 +01003150def Test_interrupt_loop()
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02003151 var caught = false
3152 var x = 0
Bram Moolenaar97acfc72020-03-22 13:44:28 +01003153 try
3154 while 1
3155 x += 1
3156 if x == 100
3157 feedkeys("\<C-C>", 'Lt')
3158 endif
3159 endwhile
3160 catch
3161 caught = true
3162 assert_equal(100, x)
3163 endtry
3164 assert_true(caught, 'should have caught an exception')
Bram Moolenaar25859dd2020-08-30 12:54:53 +02003165 # consume the CTRL-C
3166 getchar(0)
Bram Moolenaar9645e2d2020-03-20 20:48:49 +01003167enddef
Bram Moolenaar20431c92020-03-20 18:39:46 +01003168
Bram Moolenaar4fdae992020-04-12 16:38:57 +02003169def Test_automatic_line_continuation()
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02003170 var mylist = [
Bram Moolenaar4fdae992020-04-12 16:38:57 +02003171 'one',
3172 'two',
3173 'three',
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02003174 ] # comment
Bram Moolenaar4fdae992020-04-12 16:38:57 +02003175 assert_equal(['one', 'two', 'three'], mylist)
3176
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02003177 var mydict = {
Bram Moolenaare0de1712020-12-02 17:36:54 +01003178 ['one']: 1,
3179 ['two']: 2,
3180 ['three']:
Bram Moolenaar4fdae992020-04-12 16:38:57 +02003181 3,
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02003182 } # comment
Bram Moolenaare0de1712020-12-02 17:36:54 +01003183 assert_equal({one: 1, two: 2, three: 3}, mydict)
3184 mydict = {
Bram Moolenaar2c330432020-04-13 14:41:35 +02003185 one: 1, # comment
3186 two: # comment
3187 2, # comment
3188 three: 3 # comment
3189 }
Bram Moolenaare0de1712020-12-02 17:36:54 +01003190 assert_equal({one: 1, two: 2, three: 3}, mydict)
3191 mydict = {
Bram Moolenaar2c330432020-04-13 14:41:35 +02003192 one: 1,
3193 two:
3194 2,
3195 three: 3
Bram Moolenaar4fdae992020-04-12 16:38:57 +02003196 }
Bram Moolenaare0de1712020-12-02 17:36:54 +01003197 assert_equal({one: 1, two: 2, three: 3}, mydict)
Bram Moolenaare6085c52020-04-12 20:19:16 +02003198
3199 assert_equal(
3200 ['one', 'two', 'three'],
3201 split('one two three')
3202 )
Bram Moolenaar4fdae992020-04-12 16:38:57 +02003203enddef
3204
Bram Moolenaar7a092242020-04-16 22:10:49 +02003205def Test_vim9_comment()
Bram Moolenaar62aec932022-01-29 21:45:34 +00003206 v9.CheckScriptSuccess([
Bram Moolenaar7a092242020-04-16 22:10:49 +02003207 'vim9script',
3208 '# something',
Bram Moolenaar93f82cb2020-12-12 21:25:56 +01003209 '#something',
Bram Moolenaar3f74c0a2022-08-06 18:12:06 +01003210 '#{{something',
Bram Moolenaar7a092242020-04-16 22:10:49 +02003211 ])
Bram Moolenaar3f74c0a2022-08-06 18:12:06 +01003212 v9.CheckScriptFailure([
3213 'vim9script',
3214 '#{something',
3215 ], 'E1170:')
Bram Moolenaar93f82cb2020-12-12 21:25:56 +01003216
Bram Moolenaarb18b4962022-09-02 21:55:50 +01003217 split Xv9cfile
Bram Moolenaar62aec932022-01-29 21:45:34 +00003218 v9.CheckScriptSuccess([
Bram Moolenaar93f82cb2020-12-12 21:25:56 +01003219 'vim9script',
3220 'edit #something',
3221 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003222 v9.CheckScriptSuccess([
Bram Moolenaar93f82cb2020-12-12 21:25:56 +01003223 'vim9script',
3224 'edit #{something',
3225 ])
3226 close
3227
Bram Moolenaar62aec932022-01-29 21:45:34 +00003228 v9.CheckScriptFailure([
Bram Moolenaar7a092242020-04-16 22:10:49 +02003229 'vim9script',
3230 ':# something',
3231 ], 'E488:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003232 v9.CheckScriptFailure([
Bram Moolenaar7a092242020-04-16 22:10:49 +02003233 '# something',
3234 ], 'E488:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003235 v9.CheckScriptFailure([
Bram Moolenaar7a092242020-04-16 22:10:49 +02003236 ':# something',
3237 ], 'E488:')
3238
Bram Moolenaar4a8d9f22020-04-16 22:54:32 +02003239 { # block start
3240 } # block end
Bram Moolenaar62aec932022-01-29 21:45:34 +00003241 v9.CheckDefFailure([
Bram Moolenaar4a8d9f22020-04-16 22:54:32 +02003242 '{# comment',
3243 ], 'E488:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003244 v9.CheckDefFailure([
Bram Moolenaar4a8d9f22020-04-16 22:54:32 +02003245 '{',
3246 '}# comment',
3247 ], 'E488:')
3248
3249 echo "yes" # comment
Bram Moolenaar62aec932022-01-29 21:45:34 +00003250 v9.CheckDefFailure([
Bram Moolenaar4a8d9f22020-04-16 22:54:32 +02003251 'echo "yes"# comment',
3252 ], 'E488:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003253 v9.CheckScriptSuccess([
Bram Moolenaar7a092242020-04-16 22:10:49 +02003254 'vim9script',
3255 'echo "yes" # something',
3256 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003257 v9.CheckScriptFailure([
Bram Moolenaar7a092242020-04-16 22:10:49 +02003258 'vim9script',
3259 'echo "yes"# something',
3260 ], 'E121:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003261 v9.CheckScriptFailure([
Bram Moolenaar7a092242020-04-16 22:10:49 +02003262 'vim9script',
3263 'echo# something',
Bram Moolenaarf8103f22020-12-25 17:36:27 +01003264 ], 'E1144:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003265 v9.CheckScriptFailure([
Bram Moolenaar7a092242020-04-16 22:10:49 +02003266 'echo "yes" # something',
3267 ], 'E121:')
3268
Bram Moolenaar4a8d9f22020-04-16 22:54:32 +02003269 exe "echo" # comment
Bram Moolenaar62aec932022-01-29 21:45:34 +00003270 v9.CheckDefFailure([
Bram Moolenaar4a8d9f22020-04-16 22:54:32 +02003271 'exe "echo"# comment',
3272 ], 'E488:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003273 v9.CheckScriptSuccess([
Bram Moolenaar4a8d9f22020-04-16 22:54:32 +02003274 'vim9script',
3275 'exe "echo" # something',
3276 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003277 v9.CheckScriptFailure([
Bram Moolenaar4a8d9f22020-04-16 22:54:32 +02003278 'vim9script',
3279 'exe "echo"# something',
3280 ], 'E121:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003281 v9.CheckScriptFailure([
Bram Moolenaar4a8d9f22020-04-16 22:54:32 +02003282 'vim9script',
3283 'exe# something',
Bram Moolenaarf8103f22020-12-25 17:36:27 +01003284 ], 'E1144:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003285 v9.CheckScriptFailure([
Bram Moolenaar4a8d9f22020-04-16 22:54:32 +02003286 'exe "echo" # something',
3287 ], 'E121:')
3288
Bram Moolenaar62aec932022-01-29 21:45:34 +00003289 v9.CheckDefFailure([
Bram Moolenaar7a092242020-04-16 22:10:49 +02003290 'try# comment',
Bram Moolenaar2c5ed4e2020-04-20 19:42:10 +02003291 ' echo "yes"',
Bram Moolenaar7a092242020-04-16 22:10:49 +02003292 'catch',
3293 'endtry',
Bram Moolenaarf8103f22020-12-25 17:36:27 +01003294 ], 'E1144:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003295 v9.CheckScriptFailure([
Bram Moolenaar2c5ed4e2020-04-20 19:42:10 +02003296 'vim9script',
3297 'try# comment',
3298 'echo "yes"',
Bram Moolenaarf8103f22020-12-25 17:36:27 +01003299 ], 'E1144:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003300 v9.CheckDefFailure([
Bram Moolenaar7a092242020-04-16 22:10:49 +02003301 'try',
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003302 ' throw#comment',
3303 'catch',
3304 'endtry',
Bram Moolenaarf8103f22020-12-25 17:36:27 +01003305 ], 'E1144:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003306 v9.CheckDefFailure([
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003307 'try',
3308 ' throw "yes"#comment',
3309 'catch',
3310 'endtry',
3311 ], 'E488:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003312 v9.CheckDefFailure([
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003313 'try',
Bram Moolenaar2c5ed4e2020-04-20 19:42:10 +02003314 ' echo "yes"',
Bram Moolenaar7a092242020-04-16 22:10:49 +02003315 'catch# comment',
3316 'endtry',
Bram Moolenaarf8103f22020-12-25 17:36:27 +01003317 ], 'E1144:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003318 v9.CheckScriptFailure([
Bram Moolenaar2c5ed4e2020-04-20 19:42:10 +02003319 'vim9script',
3320 'try',
3321 ' echo "yes"',
3322 'catch# comment',
3323 'endtry',
Bram Moolenaarf8103f22020-12-25 17:36:27 +01003324 ], 'E1144:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003325 v9.CheckDefFailure([
Bram Moolenaar2c5ed4e2020-04-20 19:42:10 +02003326 'try',
3327 ' echo "yes"',
3328 'catch /pat/# comment',
3329 'endtry',
3330 ], 'E488:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003331 v9.CheckDefFailure([
Bram Moolenaar7a092242020-04-16 22:10:49 +02003332 'try',
3333 'echo "yes"',
3334 'catch',
3335 'endtry# comment',
Bram Moolenaarf8103f22020-12-25 17:36:27 +01003336 ], 'E1144:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003337 v9.CheckScriptFailure([
Bram Moolenaar2c5ed4e2020-04-20 19:42:10 +02003338 'vim9script',
3339 'try',
3340 ' echo "yes"',
3341 'catch',
3342 'endtry# comment',
Bram Moolenaarf8103f22020-12-25 17:36:27 +01003343 ], 'E1144:')
Bram Moolenaar2c5ed4e2020-04-20 19:42:10 +02003344
Bram Moolenaar62aec932022-01-29 21:45:34 +00003345 v9.CheckScriptSuccess([
Bram Moolenaar2c5ed4e2020-04-20 19:42:10 +02003346 'vim9script',
3347 'hi # comment',
3348 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003349 v9.CheckScriptFailure([
Bram Moolenaar2c5ed4e2020-04-20 19:42:10 +02003350 'vim9script',
3351 'hi# comment',
Bram Moolenaarf8103f22020-12-25 17:36:27 +01003352 ], 'E1144:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003353 v9.CheckScriptSuccess([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003354 'vim9script',
3355 'hi Search # comment',
3356 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003357 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003358 'vim9script',
3359 'hi Search# comment',
3360 ], 'E416:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003361 v9.CheckScriptSuccess([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003362 'vim9script',
3363 'hi link This Search # comment',
3364 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003365 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003366 'vim9script',
3367 'hi link This That# comment',
3368 ], 'E413:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003369 v9.CheckScriptSuccess([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003370 'vim9script',
3371 'hi clear This # comment',
3372 'hi clear # comment',
3373 ])
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02003374 # not tested, because it doesn't give an error but a warning:
3375 # hi clear This# comment',
Bram Moolenaar62aec932022-01-29 21:45:34 +00003376 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003377 'vim9script',
3378 'hi clear# comment',
3379 ], 'E416:')
3380
Bram Moolenaar62aec932022-01-29 21:45:34 +00003381 v9.CheckScriptSuccess([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003382 'vim9script',
3383 'hi Group term=bold',
3384 'match Group /todo/ # comment',
3385 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003386 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003387 'vim9script',
3388 'hi Group term=bold',
3389 'match Group /todo/# comment',
3390 ], 'E488:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003391 v9.CheckScriptSuccess([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003392 'vim9script',
3393 'match # comment',
3394 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003395 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003396 'vim9script',
3397 'match# comment',
Bram Moolenaarf8103f22020-12-25 17:36:27 +01003398 ], 'E1144:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003399 v9.CheckScriptSuccess([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003400 'vim9script',
3401 'match none # comment',
3402 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003403 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003404 'vim9script',
3405 'match none# comment',
3406 ], 'E475:')
3407
Bram Moolenaar62aec932022-01-29 21:45:34 +00003408 v9.CheckScriptSuccess([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003409 'vim9script',
3410 'menutrans clear # comment',
3411 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003412 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003413 'vim9script',
3414 'menutrans clear# comment text',
3415 ], 'E474:')
3416
Bram Moolenaar62aec932022-01-29 21:45:34 +00003417 v9.CheckScriptSuccess([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003418 'vim9script',
3419 'syntax clear # comment',
3420 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003421 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003422 'vim9script',
3423 'syntax clear# comment text',
3424 ], 'E28:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003425 v9.CheckScriptSuccess([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003426 'vim9script',
3427 'syntax keyword Word some',
3428 'syntax clear Word # comment',
3429 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003430 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003431 'vim9script',
3432 'syntax keyword Word some',
3433 'syntax clear Word# comment text',
3434 ], 'E28:')
3435
Bram Moolenaar62aec932022-01-29 21:45:34 +00003436 v9.CheckScriptSuccess([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003437 'vim9script',
3438 'syntax list # comment',
3439 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003440 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003441 'vim9script',
3442 'syntax list# comment text',
3443 ], 'E28:')
3444
Bram Moolenaar62aec932022-01-29 21:45:34 +00003445 v9.CheckScriptSuccess([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003446 'vim9script',
3447 'syntax match Word /pat/ oneline # comment',
3448 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003449 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003450 'vim9script',
3451 'syntax match Word /pat/ oneline# comment',
3452 ], 'E475:')
3453
Bram Moolenaar62aec932022-01-29 21:45:34 +00003454 v9.CheckScriptSuccess([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003455 'vim9script',
3456 'syntax keyword Word word # comm[ent',
3457 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003458 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003459 'vim9script',
3460 'syntax keyword Word word# comm[ent',
3461 ], 'E789:')
3462
Bram Moolenaar62aec932022-01-29 21:45:34 +00003463 v9.CheckScriptSuccess([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003464 'vim9script',
3465 'syntax match Word /pat/ # comment',
3466 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003467 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003468 'vim9script',
3469 'syntax match Word /pat/# comment',
3470 ], 'E402:')
3471
Bram Moolenaar62aec932022-01-29 21:45:34 +00003472 v9.CheckScriptSuccess([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003473 'vim9script',
3474 'syntax match Word /pat/ contains=Something # comment',
3475 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003476 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003477 'vim9script',
3478 'syntax match Word /pat/ contains=Something# comment',
3479 ], 'E475:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003480 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003481 'vim9script',
3482 'syntax match Word /pat/ contains= # comment',
3483 ], 'E406:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003484 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003485 'vim9script',
3486 'syntax match Word /pat/ contains=# comment',
3487 ], 'E475:')
3488
Bram Moolenaar62aec932022-01-29 21:45:34 +00003489 v9.CheckScriptSuccess([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003490 'vim9script',
3491 'syntax region Word start=/pat/ end=/pat/ # comment',
3492 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003493 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003494 'vim9script',
3495 'syntax region Word start=/pat/ end=/pat/# comment',
Bram Moolenaard032f342020-07-18 18:13:02 +02003496 ], 'E402:')
Bram Moolenaar1966c242020-04-20 22:42:32 +02003497
Bram Moolenaar62aec932022-01-29 21:45:34 +00003498 v9.CheckScriptSuccess([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003499 'vim9script',
3500 'syntax sync # comment',
3501 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003502 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003503 'vim9script',
3504 'syntax sync# comment',
3505 ], 'E404:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003506 v9.CheckScriptSuccess([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003507 'vim9script',
3508 'syntax sync ccomment # comment',
3509 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003510 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003511 'vim9script',
3512 'syntax sync ccomment# comment',
3513 ], 'E404:')
3514
Bram Moolenaar62aec932022-01-29 21:45:34 +00003515 v9.CheckScriptSuccess([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003516 'vim9script',
3517 'syntax cluster Some contains=Word # comment',
3518 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003519 v9.CheckScriptFailure([
Bram Moolenaar1966c242020-04-20 22:42:32 +02003520 'vim9script',
3521 'syntax cluster Some contains=Word# comment',
3522 ], 'E475:')
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003523
Bram Moolenaar62aec932022-01-29 21:45:34 +00003524 v9.CheckScriptSuccess([
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003525 'vim9script',
3526 'command Echo echo # comment',
3527 'command Echo # comment',
Bram Moolenaar2d870f82020-12-05 13:41:01 +01003528 'delcommand Echo',
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003529 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003530 v9.CheckScriptFailure([
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003531 'vim9script',
3532 'command Echo echo# comment',
3533 'Echo',
Bram Moolenaarf8103f22020-12-25 17:36:27 +01003534 ], 'E1144:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01003535 delcommand Echo
Bram Moolenaar70249ee2020-12-10 21:01:30 +01003536
3537 var curdir = getcwd()
Bram Moolenaar62aec932022-01-29 21:45:34 +00003538 v9.CheckScriptSuccess([
Bram Moolenaar70249ee2020-12-10 21:01:30 +01003539 'command Echo cd " comment',
3540 'Echo',
3541 'delcommand Echo',
3542 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003543 v9.CheckScriptSuccess([
Bram Moolenaar090728a2020-12-20 15:43:31 +01003544 'vim9script',
Bram Moolenaar70249ee2020-12-10 21:01:30 +01003545 'command Echo cd # comment',
3546 'Echo',
3547 'delcommand Echo',
3548 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003549 v9.CheckScriptFailure([
Bram Moolenaar70249ee2020-12-10 21:01:30 +01003550 'vim9script',
3551 'command Echo cd " comment',
3552 'Echo',
3553 ], 'E344:')
3554 delcommand Echo
3555 chdir(curdir)
3556
Bram Moolenaar62aec932022-01-29 21:45:34 +00003557 v9.CheckScriptFailure([
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003558 'vim9script',
3559 'command Echo# comment',
3560 ], 'E182:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003561 v9.CheckScriptFailure([
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003562 'vim9script',
3563 'command Echo echo',
3564 'command Echo# comment',
3565 ], 'E182:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01003566 delcommand Echo
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003567
Bram Moolenaar62aec932022-01-29 21:45:34 +00003568 v9.CheckScriptSuccess([
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003569 'vim9script',
3570 'function # comment',
3571 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003572 v9.CheckScriptFailure([
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003573 'vim9script',
Bram Moolenaar98981072020-07-29 14:40:25 +02003574 'function " comment',
3575 ], 'E129:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003576 v9.CheckScriptFailure([
Bram Moolenaar98981072020-07-29 14:40:25 +02003577 'vim9script',
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003578 'function# comment',
Bram Moolenaarf8103f22020-12-25 17:36:27 +01003579 ], 'E1144:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003580 v9.CheckScriptSuccess([
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003581 'vim9script',
Bram Moolenaar62aec932022-01-29 21:45:34 +00003582 'import "./vim9.vim" as v9',
3583 'function v9.CheckScriptSuccess # comment',
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003584 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003585 v9.CheckScriptFailure([
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003586 'vim9script',
Bram Moolenaar62aec932022-01-29 21:45:34 +00003587 'import "./vim9.vim" as v9',
3588 'function v9.CheckScriptSuccess# comment',
3589 ], 'E1048: Item not found in script: CheckScriptSuccess#')
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003590
Bram Moolenaar62aec932022-01-29 21:45:34 +00003591 v9.CheckScriptSuccess([
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003592 'vim9script',
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02003593 'func g:DeleteMeA()',
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003594 'endfunc',
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02003595 'delfunction g:DeleteMeA # comment',
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003596 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003597 v9.CheckScriptFailure([
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003598 'vim9script',
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02003599 'func g:DeleteMeB()',
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003600 'endfunc',
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02003601 'delfunction g:DeleteMeB# comment',
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003602 ], 'E488:')
3603
Bram Moolenaar62aec932022-01-29 21:45:34 +00003604 v9.CheckScriptSuccess([
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003605 'vim9script',
3606 'call execute("ls") # comment',
3607 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003608 v9.CheckScriptFailure([
Bram Moolenaara72cfb82020-04-23 17:07:30 +02003609 'vim9script',
3610 'call execute("ls")# comment',
3611 ], 'E488:')
Bram Moolenaare7e48382020-07-22 18:17:08 +02003612
Bram Moolenaar62aec932022-01-29 21:45:34 +00003613 v9.CheckScriptFailure([
Bram Moolenaare7e48382020-07-22 18:17:08 +02003614 'def Test() " comment',
3615 'enddef',
3616 ], 'E488:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003617 v9.CheckScriptFailure([
Bram Moolenaare7e48382020-07-22 18:17:08 +02003618 'vim9script',
3619 'def Test() " comment',
3620 'enddef',
3621 ], 'E488:')
3622
Bram Moolenaar62aec932022-01-29 21:45:34 +00003623 v9.CheckScriptSuccess([
Bram Moolenaare7e48382020-07-22 18:17:08 +02003624 'func Test() " comment',
3625 'endfunc',
Bram Moolenaar2d870f82020-12-05 13:41:01 +01003626 'delfunc Test',
Bram Moolenaare7e48382020-07-22 18:17:08 +02003627 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003628 v9.CheckScriptSuccess([
Bram Moolenaare7e48382020-07-22 18:17:08 +02003629 'vim9script',
3630 'func Test() " comment',
3631 'endfunc',
Bram Moolenaar98981072020-07-29 14:40:25 +02003632 ])
Bram Moolenaare7e48382020-07-22 18:17:08 +02003633
Bram Moolenaar62aec932022-01-29 21:45:34 +00003634 v9.CheckScriptSuccess([
Bram Moolenaare7e48382020-07-22 18:17:08 +02003635 'def Test() # comment',
3636 'enddef',
3637 ])
Bram Moolenaar62aec932022-01-29 21:45:34 +00003638 v9.CheckScriptFailure([
Bram Moolenaare7e48382020-07-22 18:17:08 +02003639 'func Test() # comment',
3640 'endfunc',
3641 ], 'E488:')
Bram Moolenaar0f37e352021-06-02 15:28:15 +02003642
3643 var lines =<< trim END
3644 vim9script
3645 syn region Text
3646 \ start='foo'
3647 #\ comment
3648 \ end='bar'
Bram Moolenaar5072b472021-06-03 21:56:10 +02003649 syn region Text start='foo'
3650 #\ comment
3651 \ end='bar'
Bram Moolenaar0f37e352021-06-02 15:28:15 +02003652 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003653 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f37e352021-06-02 15:28:15 +02003654
3655 lines =<< trim END
3656 vim9script
3657 syn region Text
3658 \ start='foo'
3659 "\ comment
3660 \ end='bar'
3661 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003662 v9.CheckScriptFailure(lines, 'E399:')
Bram Moolenaar2c5ed4e2020-04-20 19:42:10 +02003663enddef
3664
3665def Test_vim9_comment_gui()
3666 CheckCanRunGui
3667
Bram Moolenaar62aec932022-01-29 21:45:34 +00003668 v9.CheckScriptFailure([
Bram Moolenaar2c5ed4e2020-04-20 19:42:10 +02003669 'vim9script',
3670 'gui#comment'
Bram Moolenaarf8103f22020-12-25 17:36:27 +01003671 ], 'E1144:')
Bram Moolenaar62aec932022-01-29 21:45:34 +00003672 v9.CheckScriptFailure([
Bram Moolenaar2c5ed4e2020-04-20 19:42:10 +02003673 'vim9script',
3674 'gui -f#comment'
Bram Moolenaarb8bd2e62021-08-21 17:13:14 +02003675 ], 'E194:')
Bram Moolenaar7a092242020-04-16 22:10:49 +02003676enddef
3677
Bram Moolenaara26b9702020-04-18 19:53:28 +02003678def Test_vim9_comment_not_compiled()
Bram Moolenaar67979662020-06-20 22:50:47 +02003679 au TabEnter *.vim g:entered = 1
3680 au TabEnter *.x g:entered = 2
Bram Moolenaara26b9702020-04-18 19:53:28 +02003681
3682 edit test.vim
3683 doautocmd TabEnter #comment
3684 assert_equal(1, g:entered)
3685
3686 doautocmd TabEnter f.x
3687 assert_equal(2, g:entered)
3688
3689 g:entered = 0
3690 doautocmd TabEnter f.x #comment
3691 assert_equal(2, g:entered)
3692
3693 assert_fails('doautocmd Syntax#comment', 'E216:')
3694
3695 au! TabEnter
3696 unlet g:entered
Bram Moolenaard72c1bf2020-04-19 16:28:59 +02003697
Bram Moolenaar62aec932022-01-29 21:45:34 +00003698 v9.CheckScriptSuccess([
Bram Moolenaard72c1bf2020-04-19 16:28:59 +02003699 'vim9script',
Bram Moolenaar67979662020-06-20 22:50:47 +02003700 'g:var = 123',
Bram Moolenaare55b1c02020-06-21 15:52:59 +02003701 'b:var = 456',
3702 'w:var = 777',
3703 't:var = 888',
Bram Moolenaard72c1bf2020-04-19 16:28:59 +02003704 'unlet g:var w:var # something',
3705 ])
3706
Bram Moolenaar62aec932022-01-29 21:45:34 +00003707 v9.CheckScriptFailure([
Bram Moolenaard72c1bf2020-04-19 16:28:59 +02003708 'vim9script',
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02003709 'let var = 123',
3710 ], 'E1126: Cannot use :let in Vim9 script')
3711
Bram Moolenaar62aec932022-01-29 21:45:34 +00003712 v9.CheckScriptFailure([
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02003713 'vim9script',
3714 'var g:var = 123',
Bram Moolenaare55b1c02020-06-21 15:52:59 +02003715 ], 'E1016: Cannot declare a global variable:')
3716
Bram Moolenaar62aec932022-01-29 21:45:34 +00003717 v9.CheckScriptFailure([
Bram Moolenaare55b1c02020-06-21 15:52:59 +02003718 'vim9script',
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02003719 'var b:var = 123',
Bram Moolenaare55b1c02020-06-21 15:52:59 +02003720 ], 'E1016: Cannot declare a buffer variable:')
3721
Bram Moolenaar62aec932022-01-29 21:45:34 +00003722 v9.CheckScriptFailure([
Bram Moolenaare55b1c02020-06-21 15:52:59 +02003723 'vim9script',
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02003724 'var w:var = 123',
Bram Moolenaare55b1c02020-06-21 15:52:59 +02003725 ], 'E1016: Cannot declare a window variable:')
3726
Bram Moolenaar62aec932022-01-29 21:45:34 +00003727 v9.CheckScriptFailure([
Bram Moolenaare55b1c02020-06-21 15:52:59 +02003728 'vim9script',
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02003729 'var t:var = 123',
Bram Moolenaare55b1c02020-06-21 15:52:59 +02003730 ], 'E1016: Cannot declare a tab variable:')
3731
Bram Moolenaar62aec932022-01-29 21:45:34 +00003732 v9.CheckScriptFailure([
Bram Moolenaare55b1c02020-06-21 15:52:59 +02003733 'vim9script',
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02003734 'var v:version = 123',
Bram Moolenaare55b1c02020-06-21 15:52:59 +02003735 ], 'E1016: Cannot declare a v: variable:')
3736
Bram Moolenaar62aec932022-01-29 21:45:34 +00003737 v9.CheckScriptFailure([
Bram Moolenaare55b1c02020-06-21 15:52:59 +02003738 'vim9script',
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02003739 'var $VARIABLE = "text"',
Bram Moolenaare55b1c02020-06-21 15:52:59 +02003740 ], 'E1016: Cannot declare an environment variable:')
Bram Moolenaar67979662020-06-20 22:50:47 +02003741
Bram Moolenaar62aec932022-01-29 21:45:34 +00003742 v9.CheckScriptFailure([
Bram Moolenaar67979662020-06-20 22:50:47 +02003743 'vim9script',
3744 'g:var = 123',
Bram Moolenaar32e35112020-05-14 22:41:15 +02003745 'unlet g:var# comment1',
Bram Moolenaard72c1bf2020-04-19 16:28:59 +02003746 ], 'E108:')
3747
Bram Moolenaar62aec932022-01-29 21:45:34 +00003748 v9.CheckScriptFailure([
Bram Moolenaard72c1bf2020-04-19 16:28:59 +02003749 'let g:var = 123',
3750 'unlet g:var # something',
3751 ], 'E488:')
Bram Moolenaarfaac4102020-04-20 17:46:14 +02003752
Bram Moolenaar62aec932022-01-29 21:45:34 +00003753 v9.CheckScriptSuccess([
Bram Moolenaarfaac4102020-04-20 17:46:14 +02003754 'vim9script',
Bram Moolenaar32e35112020-05-14 22:41:15 +02003755 'if 1 # comment2',
Bram Moolenaarfaac4102020-04-20 17:46:14 +02003756 ' echo "yes"',
3757 'elseif 2 #comment',
3758 ' echo "no"',
3759 'endif',
3760 ])
3761
Bram Moolenaar62aec932022-01-29 21:45:34 +00003762 v9.CheckScriptFailure([
Bram Moolenaarfaac4102020-04-20 17:46:14 +02003763 'vim9script',
Bram Moolenaar32e35112020-05-14 22:41:15 +02003764 'if 1# comment3',
Bram Moolenaarfaac4102020-04-20 17:46:14 +02003765 ' echo "yes"',
3766 'endif',
Bram Moolenaarfae55a92021-06-17 22:08:30 +02003767 ], 'E488:')
Bram Moolenaarfaac4102020-04-20 17:46:14 +02003768
Bram Moolenaar62aec932022-01-29 21:45:34 +00003769 v9.CheckScriptFailure([
Bram Moolenaarfaac4102020-04-20 17:46:14 +02003770 'vim9script',
Bram Moolenaar32e35112020-05-14 22:41:15 +02003771 'if 0 # comment4',
Bram Moolenaarfaac4102020-04-20 17:46:14 +02003772 ' echo "yes"',
3773 'elseif 2#comment',
3774 ' echo "no"',
3775 'endif',
Bram Moolenaarfae55a92021-06-17 22:08:30 +02003776 ], 'E488:')
Bram Moolenaarfaac4102020-04-20 17:46:14 +02003777
Bram Moolenaar62aec932022-01-29 21:45:34 +00003778 v9.CheckScriptSuccess([
Bram Moolenaarfaac4102020-04-20 17:46:14 +02003779 'vim9script',
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02003780 'var v = 1 # comment5',
Bram Moolenaarfaac4102020-04-20 17:46:14 +02003781 ])
3782
Bram Moolenaar62aec932022-01-29 21:45:34 +00003783 v9.CheckScriptFailure([
Bram Moolenaarfaac4102020-04-20 17:46:14 +02003784 'vim9script',
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02003785 'var v = 1# comment6',
Bram Moolenaarfae55a92021-06-17 22:08:30 +02003786 ], 'E488:')
Bram Moolenaarfaac4102020-04-20 17:46:14 +02003787
Bram Moolenaar62aec932022-01-29 21:45:34 +00003788 v9.CheckScriptSuccess([
Bram Moolenaarfaac4102020-04-20 17:46:14 +02003789 'vim9script',
Bram Moolenaar2984ed32022-08-20 14:51:17 +01003790 'new',
Bram Moolenaard2c61702020-09-06 15:58:36 +02003791 'setline(1, ["# define pat", "last"])',
Bram Moolenaardf069ee2020-06-22 23:02:51 +02003792 ':$',
Bram Moolenaarfaac4102020-04-20 17:46:14 +02003793 'dsearch /pat/ #comment',
3794 'bwipe!',
3795 ])
3796
Bram Moolenaar62aec932022-01-29 21:45:34 +00003797 v9.CheckScriptFailure([
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02003798 'vim9script',
Bram Moolenaar2984ed32022-08-20 14:51:17 +01003799 'new',
Bram Moolenaard2c61702020-09-06 15:58:36 +02003800 'setline(1, ["# define pat", "last"])',
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02003801 ':$',
3802 'dsearch /pat/#comment',
3803 'bwipe!',
3804 ], 'E488:')
3805
Bram Moolenaar62aec932022-01-29 21:45:34 +00003806 v9.CheckScriptFailure([
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02003807 'vim9script',
3808 'func! SomeFunc()',
3809 ], 'E477:')
Bram Moolenaara26b9702020-04-18 19:53:28 +02003810enddef
3811
Bram Moolenaar7e5bd912020-05-10 21:20:29 +02003812def Test_finish()
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02003813 var lines =<< trim END
Bram Moolenaar7e5bd912020-05-10 21:20:29 +02003814 vim9script
Bram Moolenaar67979662020-06-20 22:50:47 +02003815 g:res = 'one'
Bram Moolenaar7e5bd912020-05-10 21:20:29 +02003816 if v:false | finish | endif
Bram Moolenaar67979662020-06-20 22:50:47 +02003817 g:res = 'two'
Bram Moolenaar7e5bd912020-05-10 21:20:29 +02003818 finish
Bram Moolenaar67979662020-06-20 22:50:47 +02003819 g:res = 'three'
Bram Moolenaar7e5bd912020-05-10 21:20:29 +02003820 END
Bram Moolenaardd674772022-09-15 22:26:18 +01003821 writefile(lines, 'Xfinished', 'D')
Bram Moolenaar7e5bd912020-05-10 21:20:29 +02003822 source Xfinished
3823 assert_equal('two', g:res)
3824
3825 unlet g:res
Bram Moolenaar7e5bd912020-05-10 21:20:29 +02003826enddef
3827
Bram Moolenaara5d00772020-05-14 23:20:55 +02003828def Test_forward_declaration()
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02003829 var lines =<< trim END
Bram Moolenaara5d00772020-05-14 23:20:55 +02003830 vim9script
Bram Moolenaara5d00772020-05-14 23:20:55 +02003831 def GetValue(): string
3832 return theVal
3833 enddef
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02003834 var theVal = 'something'
Bram Moolenaar822ba242020-05-24 23:00:18 +02003835 g:initVal = GetValue()
Bram Moolenaara5d00772020-05-14 23:20:55 +02003836 theVal = 'else'
3837 g:laterVal = GetValue()
3838 END
Bram Moolenaardd674772022-09-15 22:26:18 +01003839 writefile(lines, 'Xforward', 'D')
Bram Moolenaara5d00772020-05-14 23:20:55 +02003840 source Xforward
3841 assert_equal('something', g:initVal)
3842 assert_equal('else', g:laterVal)
3843
3844 unlet g:initVal
3845 unlet g:laterVal
Bram Moolenaara5d00772020-05-14 23:20:55 +02003846enddef
3847
Bram Moolenaar75e27d72022-02-13 13:56:29 +00003848def Test_declare_script_var_in_func()
Bram Moolenaare535db82021-03-31 21:07:24 +02003849 var lines =<< trim END
3850 vim9script
3851 func Declare()
3852 let s:local = 123
3853 endfunc
3854 Declare()
Bram Moolenaar75e27d72022-02-13 13:56:29 +00003855 END
3856 v9.CheckScriptFailure(lines, 'E1269:')
3857enddef
Bram Moolenaar755bf2b2023-01-28 19:38:49 +00003858
Bram Moolenaar75e27d72022-02-13 13:56:29 +00003859def Test_lock_script_var()
3860 var lines =<< trim END
3861 vim9script
3862 var local = 123
Bram Moolenaare535db82021-03-31 21:07:24 +02003863 assert_equal(123, local)
3864
3865 var error: string
3866 try
3867 local = 'asdf'
3868 catch
3869 error = v:exception
3870 endtry
3871 assert_match('E1012: Type mismatch; expected number but got string', error)
3872
3873 lockvar local
3874 try
3875 local = 999
3876 catch
3877 error = v:exception
3878 endtry
3879 assert_match('E741: Value is locked: local', error)
3880 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003881 v9.CheckScriptSuccess(lines)
Bram Moolenaare535db82021-03-31 21:07:24 +02003882enddef
Bram Moolenaar755bf2b2023-01-28 19:38:49 +00003883
Bram Moolenaare535db82021-03-31 21:07:24 +02003884
Bram Moolenaar7d699702020-08-14 20:52:28 +02003885func Test_vim9script_not_global()
3886 " check that items defined in Vim9 script are script-local, not global
3887 let vim9lines =<< trim END
3888 vim9script
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02003889 var name = 'local'
Bram Moolenaar7d699702020-08-14 20:52:28 +02003890 func TheFunc()
3891 echo 'local'
3892 endfunc
3893 def DefFunc()
3894 echo 'local'
3895 enddef
3896 END
Bram Moolenaardd674772022-09-15 22:26:18 +01003897 call writefile(vim9lines, 'Xvim9script.vim', 'D')
Bram Moolenaar7d699702020-08-14 20:52:28 +02003898 source Xvim9script.vim
3899 try
3900 echo g:var
3901 assert_report('did not fail')
3902 catch /E121:/
3903 " caught
3904 endtry
3905 try
3906 call TheFunc()
3907 assert_report('did not fail')
3908 catch /E117:/
3909 " caught
3910 endtry
3911 try
3912 call DefFunc()
3913 assert_report('did not fail')
3914 catch /E117:/
3915 " caught
3916 endtry
Bram Moolenaar7d699702020-08-14 20:52:28 +02003917endfunc
3918
Bram Moolenaareeb27bf2020-07-04 17:39:10 +02003919def Test_vim9_copen()
3920 # this was giving an error for setting w:quickfix_title
3921 copen
3922 quit
3923enddef
3924
Bram Moolenaar81e17fb2020-08-21 21:55:43 +02003925def Test_script_var_in_autocmd()
3926 # using a script variable from an autocommand, defined in a :def function in a
3927 # legacy Vim script, cannot check the variable type.
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02003928 var lines =<< trim END
Bram Moolenaar81e17fb2020-08-21 21:55:43 +02003929 let s:counter = 1
3930 def s:Func()
3931 au! CursorHold
3932 au CursorHold * s:counter += 1
3933 enddef
3934 call s:Func()
3935 doau CursorHold
3936 call assert_equal(2, s:counter)
3937 au! CursorHold
3938 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003939 v9.CheckScriptSuccess(lines)
Bram Moolenaar81e17fb2020-08-21 21:55:43 +02003940enddef
3941
Bram Moolenaarb5841b92021-07-15 18:09:53 +02003942def Test_error_in_autoload_script()
3943 var save_rtp = &rtp
3944 var dir = getcwd() .. '/Xruntime'
3945 &rtp = dir
Bram Moolenaardd674772022-09-15 22:26:18 +01003946 mkdir(dir .. '/autoload', 'pR')
Bram Moolenaarb5841b92021-07-15 18:09:53 +02003947
3948 var lines =<< trim END
3949 vim9script noclear
Bram Moolenaard8fe6d32022-01-30 18:40:44 +00003950 export def Autoloaded()
Bram Moolenaarb5841b92021-07-15 18:09:53 +02003951 enddef
3952 def Broken()
3953 var x: any = ''
3954 eval x != 0
3955 enddef
3956 Broken()
3957 END
3958 writefile(lines, dir .. '/autoload/script.vim')
3959
3960 lines =<< trim END
3961 vim9script
3962 def CallAutoloaded()
Bram Moolenaard8fe6d32022-01-30 18:40:44 +00003963 script#Autoloaded()
Bram Moolenaarb5841b92021-07-15 18:09:53 +02003964 enddef
3965
3966 function Legacy()
3967 try
3968 call s:CallAutoloaded()
3969 catch
3970 call assert_match('E1030: Using a String as a Number', v:exception)
3971 endtry
3972 endfunction
3973
3974 Legacy()
3975 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003976 v9.CheckScriptSuccess(lines)
Bram Moolenaarb5841b92021-07-15 18:09:53 +02003977
3978 &rtp = save_rtp
Bram Moolenaarb5841b92021-07-15 18:09:53 +02003979enddef
3980
Bram Moolenaar6809ff92022-07-26 15:10:56 +01003981def Test_error_in_autoload_script_foldexpr()
3982 var save_rtp = &rtp
Bram Moolenaardd674772022-09-15 22:26:18 +01003983 mkdir('Xvim/autoload', 'pR')
Bram Moolenaar6809ff92022-07-26 15:10:56 +01003984 &runtimepath = 'Xvim'
3985
3986 var lines =<< trim END
3987 vim9script
3988 eval [][0]
3989 echomsg 'no error'
3990 END
3991 lines->writefile('Xvim/autoload/script.vim')
3992
3993 lines =<< trim END
3994 vim9script
3995 import autoload 'script.vim'
3996 &foldmethod = 'expr'
3997 &foldexpr = 'script.Func()'
3998 redraw
3999 END
4000 v9.CheckScriptFailure(lines, 'E684: List index out of range: 0')
Bram Moolenaar6809ff92022-07-26 15:10:56 +01004001enddef
4002
Bram Moolenaare3d46852020-08-29 13:39:17 +02004003def Test_invalid_sid()
4004 assert_fails('func <SNR>1234_func', 'E123:')
Bram Moolenaar25859dd2020-08-30 12:54:53 +02004005
Bram Moolenaar62aec932022-01-29 21:45:34 +00004006 if g:RunVim([], ['wq! Xdidit'], '+"func <SNR>1_func"')
Bram Moolenaard2c61702020-09-06 15:58:36 +02004007 assert_equal([], readfile('Xdidit'))
Bram Moolenaare3d46852020-08-29 13:39:17 +02004008 endif
4009 delete('Xdidit')
4010enddef
4011
Bram Moolenaar9ec70262020-12-09 17:16:59 +01004012def Test_restoring_cpo()
Bram Moolenaardd674772022-09-15 22:26:18 +01004013 writefile(['vim9script', 'set nocp'], 'Xsourced', 'D')
4014 writefile(['call writefile(["done"], "Xdone")', 'quit!'], 'Xclose', 'D')
Bram Moolenaar62aec932022-01-29 21:45:34 +00004015 if g:RunVim([], [], '-u NONE +"set cpo+=a" -S Xsourced -S Xclose')
Bram Moolenaar9ec70262020-12-09 17:16:59 +01004016 assert_equal(['done'], readfile('Xdone'))
4017 endif
Bram Moolenaar090728a2020-12-20 15:43:31 +01004018 delete('Xdone')
Bram Moolenaar0123cc12021-02-07 17:17:58 +01004019
Bram Moolenaardd674772022-09-15 22:26:18 +01004020 writefile(['vim9script', 'g:cpoval = &cpo'], 'XanotherScript', 'D')
Bram Moolenaar0123cc12021-02-07 17:17:58 +01004021 set cpo=aABceFsMny>
4022 edit XanotherScript
4023 so %
4024 assert_equal('aABceFsMny>', &cpo)
Christian Brabandt22105fd2024-07-15 20:51:11 +02004025 assert_equal('aABceFsz', g:cpoval)
Bram Moolenaar0123cc12021-02-07 17:17:58 +01004026 :1del
Bram Moolenaar71eb3ad2021-12-26 12:07:30 +00004027 setline(1, 'let g:cpoval = &cpo')
Bram Moolenaar0123cc12021-02-07 17:17:58 +01004028 w
4029 so %
4030 assert_equal('aABceFsMny>', &cpo)
Bram Moolenaar71eb3ad2021-12-26 12:07:30 +00004031 assert_equal('aABceFsMny>', g:cpoval)
Bram Moolenaar0123cc12021-02-07 17:17:58 +01004032
Bram Moolenaar0123cc12021-02-07 17:17:58 +01004033 set cpo&vim
Bram Moolenaar71eb3ad2021-12-26 12:07:30 +00004034 unlet g:cpoval
4035
4036 if has('unix')
4037 # 'cpo' is not restored in main vimrc
4038 var save_HOME = $HOME
4039 $HOME = getcwd() .. '/Xhome'
Bram Moolenaardd674772022-09-15 22:26:18 +01004040 mkdir('Xhome', 'R')
Bram Moolenaar71eb3ad2021-12-26 12:07:30 +00004041 var lines =<< trim END
4042 vim9script
Bram Moolenaarb18b4962022-09-02 21:55:50 +01004043 writefile(['before: ' .. &cpo], 'Xrporesult')
Bram Moolenaar71eb3ad2021-12-26 12:07:30 +00004044 set cpo+=M
Bram Moolenaarb18b4962022-09-02 21:55:50 +01004045 writefile(['after: ' .. &cpo], 'Xrporesult', 'a')
Bram Moolenaar71eb3ad2021-12-26 12:07:30 +00004046 END
4047 writefile(lines, 'Xhome/.vimrc')
4048
4049 lines =<< trim END
Bram Moolenaarb18b4962022-09-02 21:55:50 +01004050 call writefile(['later: ' .. &cpo], 'Xrporesult', 'a')
Bram Moolenaar71eb3ad2021-12-26 12:07:30 +00004051 END
Bram Moolenaardd674772022-09-15 22:26:18 +01004052 writefile(lines, 'Xlegacy', 'D')
Bram Moolenaar71eb3ad2021-12-26 12:07:30 +00004053
4054 lines =<< trim END
4055 vim9script
Bram Moolenaarb18b4962022-09-02 21:55:50 +01004056 call writefile(['vim9: ' .. &cpo], 'Xrporesult', 'a')
Bram Moolenaar71eb3ad2021-12-26 12:07:30 +00004057 qa
4058 END
Bram Moolenaardd674772022-09-15 22:26:18 +01004059 writefile(lines, 'Xvim9', 'D')
Bram Moolenaar71eb3ad2021-12-26 12:07:30 +00004060
Bram Moolenaar62aec932022-01-29 21:45:34 +00004061 var cmd = g:GetVimCommand() .. " -S Xlegacy -S Xvim9"
Bram Moolenaar71eb3ad2021-12-26 12:07:30 +00004062 cmd = substitute(cmd, '-u NONE', '', '')
4063 exe "silent !" .. cmd
4064
4065 assert_equal([
Christian Brabandt22105fd2024-07-15 20:51:11 +02004066 'before: aABceFsz',
4067 'after: aABceFszM',
4068 'later: aABceFszM',
4069 'vim9: aABceFsz'], readfile('Xrporesult'))
Bram Moolenaar71eb3ad2021-12-26 12:07:30 +00004070
4071 $HOME = save_HOME
Bram Moolenaarb18b4962022-09-02 21:55:50 +01004072 delete('Xrporesult')
Bram Moolenaar71eb3ad2021-12-26 12:07:30 +00004073 endif
Bram Moolenaar9ec70262020-12-09 17:16:59 +01004074enddef
4075
Bram Moolenaarffb7dcd2021-03-10 14:00:18 +01004076" Use :function so we can use Check commands
4077func Test_no_redraw_when_restoring_cpo()
Bram Moolenaar37294bd2021-03-10 13:40:08 +01004078 CheckScreendump
Bram Moolenaarffb7dcd2021-03-10 14:00:18 +01004079 CheckFeature timers
Bram Moolenaar0e1574c2022-03-03 17:05:35 +00004080 call Run_test_no_redraw_when_restoring_cpo()
4081endfunc
Bram Moolenaar37294bd2021-03-10 13:40:08 +01004082
Bram Moolenaar0e1574c2022-03-03 17:05:35 +00004083def Run_test_no_redraw_when_restoring_cpo()
4084 var lines =<< trim END
Bram Moolenaar37294bd2021-03-10 13:40:08 +01004085 vim9script
Bram Moolenaard8fe6d32022-01-30 18:40:44 +00004086 export def Func()
Bram Moolenaar37294bd2021-03-10 13:40:08 +01004087 enddef
4088 END
Bram Moolenaardd674772022-09-15 22:26:18 +01004089 mkdir('Xnordir/autoload', 'pR')
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01004090 writefile(lines, 'Xnordir/autoload/script.vim')
Bram Moolenaar37294bd2021-03-10 13:40:08 +01004091
Bram Moolenaar0e1574c2022-03-03 17:05:35 +00004092 lines =<< trim END
Bram Moolenaar37294bd2021-03-10 13:40:08 +01004093 vim9script
4094 set cpo+=M
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +01004095 exe 'set rtp^=' .. getcwd() .. '/Xnordir'
Bram Moolenaard8fe6d32022-01-30 18:40:44 +00004096 au CmdlineEnter : ++once timer_start(0, (_) => script#Func())
Bram Moolenaar37294bd2021-03-10 13:40:08 +01004097 setline(1, 'some text')
4098 END
Bram Moolenaardd674772022-09-15 22:26:18 +01004099 writefile(lines, 'XTest_redraw_cpo', 'D')
Bram Moolenaar0e1574c2022-03-03 17:05:35 +00004100 var buf = g:RunVimInTerminal('-S XTest_redraw_cpo', {'rows': 6})
4101 term_sendkeys(buf, "V:")
4102 g:VerifyScreenDump(buf, 'Test_vim9_no_redraw', {})
Bram Moolenaar37294bd2021-03-10 13:40:08 +01004103
Bram Moolenaar0e1574c2022-03-03 17:05:35 +00004104 # clean up
4105 term_sendkeys(buf, "\<Esc>u")
4106 g:StopVimInTerminal(buf)
Bram Moolenaar0e1574c2022-03-03 17:05:35 +00004107enddef
4108
4109func Test_reject_declaration()
4110 CheckScreendump
4111 call Run_test_reject_declaration()
Bram Moolenaarffb7dcd2021-03-10 14:00:18 +01004112endfunc
Bram Moolenaar37294bd2021-03-10 13:40:08 +01004113
Bram Moolenaar0e1574c2022-03-03 17:05:35 +00004114def Run_test_reject_declaration()
4115 var buf = g:RunVimInTerminal('', {'rows': 6})
4116 term_sendkeys(buf, ":vim9cmd var x: number\<CR>")
Bram Moolenaar330a3882022-03-05 11:05:57 +00004117 g:VerifyScreenDump(buf, 'Test_vim9_reject_declaration_1', {})
4118 term_sendkeys(buf, ":\<CR>")
4119 term_sendkeys(buf, ":vim9cmd g:foo = 123 | echo g:foo\<CR>")
4120 g:VerifyScreenDump(buf, 'Test_vim9_reject_declaration_2', {})
Bram Moolenaar0e1574c2022-03-03 17:05:35 +00004121
4122 # clean up
4123 g:StopVimInTerminal(buf)
4124enddef
Bram Moolenaar9ec70262020-12-09 17:16:59 +01004125
Bram Moolenaar204852a2022-03-05 12:56:44 +00004126def Test_minimal_command_name_length()
4127 var names = [
4128 'cons',
4129 'brea',
4130 'cat',
4131 'catc',
4132 'con',
Bram Moolenaarb2175222022-03-05 20:24:41 +00004133 'cont',
4134 'conti',
4135 'contin',
4136 'continu',
Bram Moolenaar204852a2022-03-05 12:56:44 +00004137 'el',
4138 'els',
4139 'elsei',
4140 'endfo',
4141 'en',
4142 'end',
4143 'endi',
4144 'endw',
4145 'endt',
4146 'endtr',
Bram Moolenaarb2175222022-03-05 20:24:41 +00004147 'exp',
4148 'expo',
4149 'expor',
Bram Moolenaar204852a2022-03-05 12:56:44 +00004150 'fina',
4151 'finall',
Bram Moolenaard523c7b2022-03-06 14:51:22 +00004152 'fini',
4153 'finis',
Bram Moolenaarb2175222022-03-05 20:24:41 +00004154 'imp',
4155 'impo',
4156 'impor',
4157 'retu',
4158 'retur',
Bram Moolenaar204852a2022-03-05 12:56:44 +00004159 'th',
4160 'thr',
4161 'thro',
4162 'wh',
4163 'whi',
4164 'whil',
4165 ]
4166 for name in names
4167 v9.CheckDefAndScriptFailure([name .. ' '], 'E1065:')
4168 endfor
Bram Moolenaarb2175222022-03-05 20:24:41 +00004169
4170 var lines =<< trim END
4171 vim9script
4172 def SomeFunc()
4173 endd
4174 END
4175 v9.CheckScriptFailure(lines, 'E1065:')
4176 lines =<< trim END
4177 vim9script
4178 def SomeFunc()
4179 endde
4180 END
4181 v9.CheckScriptFailure(lines, 'E1065:')
Bram Moolenaar204852a2022-03-05 12:56:44 +00004182enddef
4183
Bram Moolenaarf0afd9e2020-09-13 18:57:47 +02004184def Test_unset_any_variable()
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02004185 var lines =<< trim END
4186 var name: any
4187 assert_equal(0, name)
Bram Moolenaarf0afd9e2020-09-13 18:57:47 +02004188 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004189 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarf0afd9e2020-09-13 18:57:47 +02004190enddef
4191
Bram Moolenaar7e9210e2020-09-25 23:12:51 +02004192func Test_define_func_at_command_line()
Bram Moolenaar58dbef32020-09-25 22:13:05 +02004193 CheckRunVimInTerminal
4194
Bram Moolenaar7e9210e2020-09-25 23:12:51 +02004195 " call indirectly to avoid compilation error for missing functions
4196 call Run_Test_define_func_at_command_line()
4197endfunc
4198
4199def Run_Test_define_func_at_command_line()
Bram Moolenaar9c4f5522020-09-25 21:47:28 +02004200 # run in a separate Vim instance to avoid the script context
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02004201 var lines =<< trim END
Bram Moolenaar9c4f5522020-09-25 21:47:28 +02004202 func CheckAndQuit()
4203 call assert_fails('call Afunc()', 'E117: Unknown function: Bfunc')
4204 call writefile(['errors: ' .. string(v:errors)], 'Xdidcmd')
4205 endfunc
4206 END
Bram Moolenaardd674772022-09-15 22:26:18 +01004207 writefile([''], 'Xdidcmd', 'D')
4208 writefile(lines, 'XcallFunc', 'D')
Bram Moolenaar62aec932022-01-29 21:45:34 +00004209 var buf = g:RunVimInTerminal('-S XcallFunc', {rows: 6})
Bram Moolenaar9c4f5522020-09-25 21:47:28 +02004210 # define Afunc() on the command line
4211 term_sendkeys(buf, ":def Afunc()\<CR>Bfunc()\<CR>enddef\<CR>")
4212 term_sendkeys(buf, ":call CheckAndQuit()\<CR>")
Bram Moolenaar62aec932022-01-29 21:45:34 +00004213 g:WaitForAssert(() => assert_equal(['errors: []'], readfile('Xdidcmd')))
Bram Moolenaar9c4f5522020-09-25 21:47:28 +02004214
Bram Moolenaar62aec932022-01-29 21:45:34 +00004215 call g:StopVimInTerminal(buf)
Bram Moolenaar9c4f5522020-09-25 21:47:28 +02004216enddef
4217
Bram Moolenaarfcdc5d82020-10-10 19:07:09 +02004218def Test_script_var_scope()
4219 var lines =<< trim END
4220 vim9script
4221 if true
4222 if true
4223 var one = 'one'
4224 echo one
4225 endif
4226 echo one
4227 endif
4228 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004229 v9.CheckScriptFailure(lines, 'E121:', 7)
Bram Moolenaarfcdc5d82020-10-10 19:07:09 +02004230
4231 lines =<< trim END
4232 vim9script
4233 if true
4234 if false
4235 var one = 'one'
4236 echo one
4237 else
4238 var one = 'one'
4239 echo one
4240 endif
4241 echo one
4242 endif
4243 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004244 v9.CheckScriptFailure(lines, 'E121:', 10)
Bram Moolenaarfcdc5d82020-10-10 19:07:09 +02004245
4246 lines =<< trim END
4247 vim9script
4248 while true
4249 var one = 'one'
4250 echo one
4251 break
4252 endwhile
4253 echo one
4254 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004255 v9.CheckScriptFailure(lines, 'E121:', 7)
Bram Moolenaarfcdc5d82020-10-10 19:07:09 +02004256
4257 lines =<< trim END
4258 vim9script
4259 for i in range(1)
4260 var one = 'one'
4261 echo one
4262 endfor
4263 echo one
4264 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004265 v9.CheckScriptFailure(lines, 'E121:', 6)
Bram Moolenaar9becdf22020-10-10 21:33:48 +02004266
4267 lines =<< trim END
4268 vim9script
4269 {
4270 var one = 'one'
4271 assert_equal('one', one)
4272 }
4273 assert_false(exists('one'))
4274 assert_false(exists('s:one'))
4275 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004276 v9.CheckScriptSuccess(lines)
Bram Moolenaar9becdf22020-10-10 21:33:48 +02004277
4278 lines =<< trim END
4279 vim9script
4280 {
4281 var one = 'one'
4282 echo one
4283 }
4284 echo one
4285 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004286 v9.CheckScriptFailure(lines, 'E121:', 6)
Bram Moolenaarfcdc5d82020-10-10 19:07:09 +02004287enddef
4288
Bram Moolenaar352134b2020-10-17 22:04:08 +02004289def Test_catch_exception_in_callback()
4290 var lines =<< trim END
4291 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02004292 def Callback(...l: list<any>)
Bram Moolenaar352134b2020-10-17 22:04:08 +02004293 try
4294 var x: string
4295 var y: string
4296 # this error should be caught with CHECKLEN
Bram Moolenaardb9ff9a2021-12-01 17:38:01 +00004297 var sl = ['']
4298 [x, y] = sl
Bram Moolenaar352134b2020-10-17 22:04:08 +02004299 catch
4300 g:caught = 'yes'
4301 endtry
4302 enddef
Bram Moolenaare0de1712020-12-02 17:36:54 +01004303 popup_menu('popup', {callback: Callback})
Bram Moolenaar352134b2020-10-17 22:04:08 +02004304 feedkeys("\r", 'xt')
4305 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004306 v9.CheckScriptSuccess(lines)
Bram Moolenaar352134b2020-10-17 22:04:08 +02004307
4308 unlet g:caught
4309enddef
4310
Bram Moolenaar631e8f92020-11-04 15:07:16 +01004311def Test_no_unknown_error_after_error()
4312 if !has('unix') || !has('job')
4313 throw 'Skipped: not unix of missing +job feature'
4314 endif
Bram Moolenaarb16ff292021-09-26 20:14:39 +01004315 # FIXME: this check should not be needed
4316 if has('win32')
4317 throw 'Skipped: does not work on MS-Windows'
4318 endif
Bram Moolenaar631e8f92020-11-04 15:07:16 +01004319 var lines =<< trim END
4320 vim9script
4321 var source: list<number>
Bram Moolenaar2a389082021-04-09 20:24:31 +02004322 def Out_cb(...l: list<any>)
Bram Moolenaar631e8f92020-11-04 15:07:16 +01004323 eval [][0]
4324 enddef
Bram Moolenaar2a389082021-04-09 20:24:31 +02004325 def Exit_cb(...l: list<any>)
Bram Moolenaar631e8f92020-11-04 15:07:16 +01004326 sleep 1m
Bram Moolenaar23d44492022-05-04 16:24:57 +01004327 g:did_call_exit_cb = true
Bram Moolenaar631e8f92020-11-04 15:07:16 +01004328 source += l
4329 enddef
Bram Moolenaare0de1712020-12-02 17:36:54 +01004330 var myjob = job_start('echo burp', {out_cb: Out_cb, exit_cb: Exit_cb, mode: 'raw'})
Bram Moolenaar6f17a3f2020-12-21 18:11:24 +01004331 while job_status(myjob) == 'run'
4332 sleep 10m
4333 endwhile
Bram Moolenaar206c2a62021-01-31 14:04:44 +01004334 # wait for Exit_cb() to be called
Bram Moolenaar23d44492022-05-04 16:24:57 +01004335 for x in range(100)
4336 if exists('g:did_call_exit_cb')
4337 unlet g:did_call_exit_cb
4338 break
4339 endif
4340 sleep 10m
4341 endfor
Bram Moolenaar631e8f92020-11-04 15:07:16 +01004342 END
Bram Moolenaardd674772022-09-15 22:26:18 +01004343 writefile(lines, 'Xdef', 'D')
Yee Cheng Chin69a8bb82022-11-06 12:25:47 +00004344 # Either the exit or out callback is called first, accept them in any order
4345 assert_fails('so Xdef', ['E684:\|E1012:', 'E1012:\|E684:'])
Bram Moolenaar631e8f92020-11-04 15:07:16 +01004346enddef
4347
Bram Moolenaar4324d872020-12-01 20:12:24 +01004348def InvokeNormal()
4349 exe "norm! :m+1\r"
4350enddef
4351
4352def Test_invoke_normal_in_visual_mode()
4353 xnoremap <F3> <Cmd>call <SID>InvokeNormal()<CR>
4354 new
4355 setline(1, ['aaa', 'bbb'])
4356 feedkeys("V\<F3>", 'xt')
4357 assert_equal(['bbb', 'aaa'], getline(1, 2))
4358 xunmap <F3>
4359enddef
4360
Bram Moolenaarb5b94802020-12-13 17:50:20 +01004361def Test_white_space_after_command()
4362 var lines =<< trim END
4363 exit_cb: Func})
4364 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004365 v9.CheckDefAndScriptFailure(lines, 'E1144:', 1)
Bram Moolenaarf8103f22020-12-25 17:36:27 +01004366
4367 lines =<< trim END
4368 e#
4369 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004370 v9.CheckDefAndScriptFailure(lines, 'E1144:', 1)
Bram Moolenaarb5b94802020-12-13 17:50:20 +01004371enddef
4372
Bram Moolenaar4aab88d2020-12-24 21:56:41 +01004373def Test_script_var_gone_when_sourced_twice()
4374 var lines =<< trim END
4375 vim9script
4376 if exists('g:guard')
4377 finish
4378 endif
4379 g:guard = 1
4380 var name = 'thename'
4381 def g:GetName(): string
4382 return name
4383 enddef
4384 def g:SetName(arg: string)
4385 name = arg
4386 enddef
4387 END
Bram Moolenaardd674772022-09-15 22:26:18 +01004388 writefile(lines, 'XscriptTwice.vim', 'D')
Bram Moolenaar4aab88d2020-12-24 21:56:41 +01004389 so XscriptTwice.vim
4390 assert_equal('thename', g:GetName())
4391 g:SetName('newname')
4392 assert_equal('newname', g:GetName())
4393 so XscriptTwice.vim
4394 assert_fails('call g:GetName()', 'E1149:')
4395 assert_fails('call g:SetName("x")', 'E1149:')
4396
4397 delfunc g:GetName
4398 delfunc g:SetName
Bram Moolenaar4aab88d2020-12-24 21:56:41 +01004399 unlet g:guard
4400enddef
4401
Bram Moolenaar10b94212021-02-19 21:42:57 +01004402def Test_unsupported_commands()
4403 var lines =<< trim END
4404 ka
4405 END
Bram Moolenaar6aca4d32022-03-04 17:10:19 +00004406 v9.CheckDefAndScriptFailure(lines, ['E476:', 'E492:'])
Bram Moolenaar10b94212021-02-19 21:42:57 +01004407
4408 lines =<< trim END
Bram Moolenaarada1d872021-02-20 08:16:51 +01004409 :1ka
4410 END
Bram Moolenaar6aca4d32022-03-04 17:10:19 +00004411 v9.CheckDefAndScriptFailure(lines, ['E476:', 'E492:'])
Bram Moolenaarada1d872021-02-20 08:16:51 +01004412
4413 lines =<< trim END
Yegappan Lakshmanan885de442022-04-23 10:51:14 +01004414 :k a
4415 END
4416 v9.CheckDefAndScriptFailure(lines, 'E1100:')
4417
4418 lines =<< trim END
4419 :1k a
4420 END
4421 v9.CheckDefAndScriptFailure(lines, 'E481:')
4422
4423 lines =<< trim END
Bram Moolenaar10b94212021-02-19 21:42:57 +01004424 t
4425 END
Bram Moolenaar6aca4d32022-03-04 17:10:19 +00004426 v9.CheckDefAndScriptFailure(lines, 'E1100:')
Bram Moolenaar10b94212021-02-19 21:42:57 +01004427
4428 lines =<< trim END
4429 x
4430 END
Bram Moolenaar6aca4d32022-03-04 17:10:19 +00004431 v9.CheckDefAndScriptFailure(lines, 'E1100:')
Bram Moolenaar10b94212021-02-19 21:42:57 +01004432
4433 lines =<< trim END
4434 xit
4435 END
Bram Moolenaar6aca4d32022-03-04 17:10:19 +00004436 v9.CheckDefAndScriptFailure(lines, 'E1100:')
4437
4438 lines =<< trim END
4439 Print
4440 END
4441 v9.CheckDefAndScriptFailure(lines, ['E476: Invalid command: Print', 'E492: Not an editor command: Print'])
4442
4443 lines =<< trim END
4444 mode 4
4445 END
4446 v9.CheckDefAndScriptFailure(lines, ['E476: Invalid command: mode 4', 'E492: Not an editor command: mode 4'])
Bram Moolenaar10b94212021-02-19 21:42:57 +01004447enddef
4448
Bram Moolenaarc70fe462021-04-17 17:59:19 +02004449def Test_mapping_line_number()
4450 var lines =<< trim END
4451 vim9script
4452 def g:FuncA()
4453 # Some comment
4454 FuncB(0)
4455 enddef
4456 # Some comment
4457 def FuncB(
4458 # Some comment
4459 n: number
4460 )
4461 exe 'nno '
4462 # Some comment
4463 .. '<F3> a'
4464 .. 'b'
4465 .. 'c'
4466 enddef
4467 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004468 v9.CheckScriptSuccess(lines)
Bram Moolenaarc70fe462021-04-17 17:59:19 +02004469 var res = execute('verbose nmap <F3>')
4470 assert_match('No mapping found', res)
4471
4472 g:FuncA()
4473 res = execute('verbose nmap <F3>')
4474 assert_match(' <F3> .* abc.*Last set from .*XScriptSuccess\d\+ line 11', res)
4475
4476 nunmap <F3>
4477 delfunc g:FuncA
4478enddef
4479
Bram Moolenaardeb108b2021-07-08 17:35:36 +02004480def Test_option_set()
4481 # legacy script allows for white space
4482 var lines =<< trim END
4483 set foldlevel =11
4484 call assert_equal(11, &foldlevel)
4485 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004486 v9.CheckScriptSuccess(lines)
Bram Moolenaardeb108b2021-07-08 17:35:36 +02004487
4488 set foldlevel
4489 set foldlevel=12
4490 assert_equal(12, &foldlevel)
4491 set foldlevel+=2
4492 assert_equal(14, &foldlevel)
4493 set foldlevel-=3
4494 assert_equal(11, &foldlevel)
4495
4496 lines =<< trim END
4497 set foldlevel =1
4498 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004499 v9.CheckDefExecAndScriptFailure(lines, 'E1205: No white space allowed between option and: =1')
Bram Moolenaardeb108b2021-07-08 17:35:36 +02004500
4501 lines =<< trim END
4502 set foldlevel +=1
4503 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004504 v9.CheckDefExecAndScriptFailure(lines, 'E1205: No white space allowed between option and: +=1')
Bram Moolenaardeb108b2021-07-08 17:35:36 +02004505
4506 lines =<< trim END
4507 set foldlevel ^=1
4508 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004509 v9.CheckDefExecAndScriptFailure(lines, 'E1205: No white space allowed between option and: ^=1')
Bram Moolenaardeb108b2021-07-08 17:35:36 +02004510
4511 lines =<< trim END
4512 set foldlevel -=1
4513 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004514 v9.CheckDefExecAndScriptFailure(lines, 'E1205: No white space allowed between option and: -=1')
Bram Moolenaardeb108b2021-07-08 17:35:36 +02004515
4516 set foldlevel&
4517enddef
4518
LemonBoy32f34612023-09-02 21:52:05 +02004519def Test_option_set_line_number()
4520 var lines =<< trim END
4521 vim9script
4522 # line2
4523 # line3
4524 def F()
4525 # line5
4526 &foldlevel = -128
4527 enddef
4528 F()
4529 END
4530 v9.CheckScriptSuccess(lines)
4531
4532 var res = execute('verbose set foldlevel')
4533 assert_match(' foldlevel.*Last set from .*XScriptSuccess\d\+ line 6', res)
4534enddef
4535
Bram Moolenaar208f0b42021-06-20 12:40:08 +02004536def Test_option_modifier()
Bram Moolenaar1594f312021-07-08 16:40:13 +02004537 # legacy script allows for white space
Bram Moolenaar208f0b42021-06-20 12:40:08 +02004538 var lines =<< trim END
4539 set hlsearch & hlsearch !
4540 call assert_equal(1, &hlsearch)
4541 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004542 v9.CheckScriptSuccess(lines)
Bram Moolenaar208f0b42021-06-20 12:40:08 +02004543
Bram Moolenaar1594f312021-07-08 16:40:13 +02004544 set hlsearch
4545 set hlsearch!
4546 assert_equal(false, &hlsearch)
4547
4548 set hlsearch
4549 set hlsearch&
4550 assert_equal(false, &hlsearch)
Bram Moolenaar208f0b42021-06-20 12:40:08 +02004551
4552 lines =<< trim END
Bram Moolenaar1594f312021-07-08 16:40:13 +02004553 set hlsearch &
Bram Moolenaar208f0b42021-06-20 12:40:08 +02004554 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004555 v9.CheckDefExecAndScriptFailure(lines, 'E1205: No white space allowed between option and: &')
Bram Moolenaar1594f312021-07-08 16:40:13 +02004556
4557 lines =<< trim END
4558 set hlsearch !
4559 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004560 v9.CheckDefExecAndScriptFailure(lines, 'E1205: No white space allowed between option and: !')
Bram Moolenaar1594f312021-07-08 16:40:13 +02004561
4562 set hlsearch&
Bram Moolenaar208f0b42021-06-20 12:40:08 +02004563enddef
4564
Bram Moolenaarc03fe662021-07-11 16:52:45 +02004565" This must be called last, it may cause following :def functions to fail
4566def Test_xxx_echoerr_line_number()
4567 var lines =<< trim END
4568 echoerr 'some'
4569 .. ' error'
4570 .. ' continued'
4571 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004572 v9.CheckDefExecAndScriptFailure(lines, 'some error continued', 1)
Bram Moolenaarc03fe662021-07-11 16:52:45 +02004573enddef
4574
Bram Moolenaar9537e372021-12-10 21:05:53 +00004575func Test_debug_with_lambda()
Bram Moolenaar9fffef92021-12-10 16:55:58 +00004576 CheckRunVimInTerminal
4577
Bram Moolenaar9537e372021-12-10 21:05:53 +00004578 " call indirectly to avoid compilation error for missing functions
4579 call Run_Test_debug_with_lambda()
4580endfunc
4581
4582def Run_Test_debug_with_lambda()
Bram Moolenaar9fffef92021-12-10 16:55:58 +00004583 var lines =<< trim END
4584 vim9script
4585 def Func()
4586 var n = 0
4587 echo [0]->filter((_, v) => v == n)
4588 enddef
4589 breakadd func Func
4590 Func()
4591 END
Bram Moolenaardd674772022-09-15 22:26:18 +01004592 writefile(lines, 'XdebugFunc', 'D')
Christian Brabandt7edde3f2024-05-04 09:38:59 +02004593 var buf = g:RunVimInTerminal('-S XdebugFunc', {rows: 10, wait_for_ruler: 0})
4594 g:WaitForAssert(() => assert_match('^>', term_getline(buf, 10)))
Bram Moolenaar9fffef92021-12-10 16:55:58 +00004595
4596 term_sendkeys(buf, "cont\<CR>")
Christian Brabandt7edde3f2024-05-04 09:38:59 +02004597 g:WaitForAssert(() => assert_match('\[0\]', term_getline(buf, 9)))
Bram Moolenaar9fffef92021-12-10 16:55:58 +00004598
Bram Moolenaar62aec932022-01-29 21:45:34 +00004599 g:StopVimInTerminal(buf)
Bram Moolenaar9fffef92021-12-10 16:55:58 +00004600enddef
4601
Bram Moolenaar310091d2021-12-23 21:14:37 +00004602func Test_debug_running_out_of_lines()
4603 CheckRunVimInTerminal
4604
4605 " call indirectly to avoid compilation error for missing functions
4606 call Run_Test_debug_running_out_of_lines()
4607endfunc
4608
4609def Run_Test_debug_running_out_of_lines()
4610 var lines =<< trim END
4611 vim9script
4612 def Crash()
4613 #
4614 #
4615 #
4616 #
4617 #
4618 #
4619 #
4620 if true
4621 #
4622 endif
4623 enddef
4624 breakadd func Crash
4625 Crash()
4626 END
Bram Moolenaardd674772022-09-15 22:26:18 +01004627 writefile(lines, 'XdebugFunc', 'D')
Christian Brabandt7edde3f2024-05-04 09:38:59 +02004628 var buf = g:RunVimInTerminal('-S XdebugFunc', {rows: 10, wait_for_ruler: 0})
4629 g:WaitForAssert(() => assert_match('^>', term_getline(buf, 10)))
Bram Moolenaar310091d2021-12-23 21:14:37 +00004630
4631 term_sendkeys(buf, "next\<CR>")
Bram Moolenaar62aec932022-01-29 21:45:34 +00004632 g:TermWait(buf)
Christian Brabandt7edde3f2024-05-04 09:38:59 +02004633 g:WaitForAssert(() => assert_match('^>', term_getline(buf, 10)))
Bram Moolenaar310091d2021-12-23 21:14:37 +00004634
4635 term_sendkeys(buf, "cont\<CR>")
Bram Moolenaar62aec932022-01-29 21:45:34 +00004636 g:TermWait(buf)
Bram Moolenaar310091d2021-12-23 21:14:37 +00004637
Bram Moolenaar62aec932022-01-29 21:45:34 +00004638 g:StopVimInTerminal(buf)
Bram Moolenaar310091d2021-12-23 21:14:37 +00004639enddef
4640
dundargocc57b5bc2022-11-02 13:30:51 +00004641def Test_ambiguous_command_error()
Bram Moolenaarbed34f02022-01-19 20:48:37 +00004642 var lines =<< trim END
4643 vim9script
4644 command CmdA echomsg 'CmdA'
4645 command CmdB echomsg 'CmdB'
4646 Cmd
4647 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004648 v9.CheckScriptFailure(lines, 'E464: Ambiguous use of user-defined command: Cmd', 4)
Bram Moolenaarbed34f02022-01-19 20:48:37 +00004649
4650 lines =<< trim END
4651 vim9script
4652 def Func()
4653 Cmd
4654 enddef
4655 Func()
4656 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004657 v9.CheckScriptFailure(lines, 'E464: Ambiguous use of user-defined command: Cmd', 1)
Bram Moolenaarbed34f02022-01-19 20:48:37 +00004658
4659 lines =<< trim END
4660 vim9script
4661 nnoremap <F3> <ScriptCmd>Cmd<CR>
4662 feedkeys("\<F3>", 'xt')
4663 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004664 v9.CheckScriptFailure(lines, 'E464: Ambiguous use of user-defined command: Cmd', 3)
Bram Moolenaarbed34f02022-01-19 20:48:37 +00004665
4666 delcommand CmdA
4667 delcommand CmdB
4668 nunmap <F3>
4669enddef
4670
Dominique Pelle923dce22021-11-21 11:36:04 +00004671" Execute this near the end, profiling doesn't stop until Vim exits.
Bram Moolenaard9162552021-07-11 15:26:13 +02004672" This only tests that it works, not the profiling output.
Bram Moolenaar129e33e2022-03-14 10:50:23 +00004673def Test_profile_with_lambda()
Bram Moolenaar4ece1522021-07-11 16:31:51 +02004674 CheckFeature profile
4675
Bram Moolenaar129e33e2022-03-14 10:50:23 +00004676 var lines =<< trim END
4677 vim9script
Bram Moolenaarffcfddc2021-07-11 20:22:30 +02004678
Bram Moolenaar129e33e2022-03-14 10:50:23 +00004679 def ProfiledWithLambda()
4680 var n = 3
4681 echo [[1, 2], [3, 4]]->filter((_, l) => l[0] == n)
4682 enddef
Bram Moolenaarffcfddc2021-07-11 20:22:30 +02004683
Bram Moolenaar129e33e2022-03-14 10:50:23 +00004684 def ProfiledNested()
4685 var x = 0
4686 def Nested(): any
4687 return x
4688 enddef
4689 Nested()
4690 enddef
Bram Moolenaarffcfddc2021-07-11 20:22:30 +02004691
Bram Moolenaar129e33e2022-03-14 10:50:23 +00004692 def g:ProfiledNestedProfiled()
4693 var x = 0
4694 def Nested(): any
4695 return x
4696 enddef
4697 Nested()
4698 enddef
4699
4700 def Profile()
Bram Moolenaar48f69cd2022-03-15 16:16:47 +00004701 ProfiledWithLambda()
Bram Moolenaar129e33e2022-03-14 10:50:23 +00004702 ProfiledNested()
4703
Bram Moolenaar48f69cd2022-03-15 16:16:47 +00004704 # Also profile the nested function. Use a different function, although
4705 # the contents is the same, to make sure it was not already compiled.
Bram Moolenaar129e33e2022-03-14 10:50:23 +00004706 profile func *
4707 g:ProfiledNestedProfiled()
4708
4709 profdel func *
4710 profile pause
4711 enddef
Bram Moolenaar4c8b5462022-03-16 20:01:39 +00004712
4713 var result = 'done'
4714 try
4715 # mark functions for profiling now to avoid E1271
4716 profile start Xprofile.log
4717 profile func ProfiledWithLambda
4718 profile func ProfiledNested
4719
4720 Profile()
4721 catch
4722 result = 'failed: ' .. v:exception
4723 finally
4724 writefile([result], 'Xdidprofile')
4725 endtry
Bram Moolenaar129e33e2022-03-14 10:50:23 +00004726 END
Bram Moolenaardd674772022-09-15 22:26:18 +01004727 writefile(lines, 'Xprofile.vim', 'D')
Bram Moolenaar129e33e2022-03-14 10:50:23 +00004728 call system(g:GetVimCommand()
4729 .. ' --clean'
4730 .. ' -c "so Xprofile.vim"'
4731 .. ' -c "qall!"')
4732 call assert_equal(0, v:shell_error)
4733
4734 assert_equal(['done'], readfile('Xdidprofile'))
4735 assert_true(filereadable('Xprofile.log'))
4736 delete('Xdidprofile')
4737 delete('Xprofile.log')
Bram Moolenaard9162552021-07-11 15:26:13 +02004738enddef
4739
Bram Moolenaar4f6e7722022-03-16 20:26:02 +00004740func Test_misplaced_type()
4741 CheckRunVimInTerminal
4742 call Run_Test_misplaced_type()
4743endfunc
4744
4745def Run_Test_misplaced_type()
Bram Moolenaar9510d222022-09-11 15:14:05 +01004746 writefile(['let g:somevar = "asdf"'], 'XTest_misplaced_type', 'D')
Bram Moolenaar4c8b5462022-03-16 20:01:39 +00004747 var buf = g:RunVimInTerminal('-S XTest_misplaced_type', {'rows': 6})
Bram Moolenaar9510d222022-09-11 15:14:05 +01004748 term_sendkeys(buf, ":vim9cmd echo islocked('somevar: string')\<CR>")
Bram Moolenaar4c8b5462022-03-16 20:01:39 +00004749 g:VerifyScreenDump(buf, 'Test_misplaced_type', {})
4750
4751 g:StopVimInTerminal(buf)
Bram Moolenaar4c8b5462022-03-16 20:01:39 +00004752enddef
4753
LemonBoya5d35902022-04-29 21:15:02 +01004754" Ensure echo doesn't crash when stringifying empty variables.
4755def Test_echo_uninit_variables()
4756 var res: string
4757
4758 var var_bool: bool
4759 var var_num: number
4760 var var_float: float
4761 var Var_func: func
4762 var var_string: string
4763 var var_blob: blob
LemonBoya5d35902022-04-29 21:15:02 +01004764 var var_list: list<any>
4765 var var_dict: dict<any>
4766
4767 redir => res
4768 echo var_bool
4769 echo var_num
4770 echo var_float
4771 echo Var_func
4772 echo var_string
4773 echo var_blob
LemonBoya5d35902022-04-29 21:15:02 +01004774 echo var_list
4775 echo var_dict
4776 redir END
4777
Bram Moolenaarf1d63b92022-05-06 13:37:42 +01004778 assert_equal(['false', '0', '0.0', 'function()', '', '0z', '[]', '{}'], res->split('\n'))
4779
4780 if has('job')
4781 var var_job: job
4782 var var_channel: channel
4783
4784 redir => res
4785 echo var_job
4786 echo var_channel
4787 redir END
4788
4789 assert_equal(['no process', 'channel fail'], res->split('\n'))
4790 endif
LemonBoya5d35902022-04-29 21:15:02 +01004791enddef
4792
Bram Moolenaar6342e2c2022-12-12 18:56:32 +00004793def Test_free_type_before_use()
4794 # this rather complicated script was freeing a type before using it
4795 var lines =<< trim END
4796 vim9script
4797
4798 def Scan(rel: list<dict<any>>): func(func(dict<any>))
4799 return (Emit: func(dict<any>)) => {
4800 for t in rel
4801 Emit(t)
4802 endfor
4803 }
4804 enddef
4805
4806 def Build(Cont: func(func(dict<any>))): list<dict<any>>
4807 var rel: list<dict<any>> = []
4808 Cont((t) => {
4809 add(rel, t)
4810 })
4811 return rel
4812 enddef
4813
4814 var R = [{A: 0}]
4815 var result = Scan(R)->Build()
4816 result = Scan(R)->Build()
4817
4818 assert_equal(R, result)
4819 END
4820 v9.CheckScriptSuccess(lines)
4821enddef
4822
Yegappan Lakshmanana76fbe62023-09-27 18:51:43 +02004823" The following complicated script used to cause an internal error (E340)
4824" because the funcref instruction memory was referenced after the instruction
4825" memory was reallocated (Github issue #13178)
4826def Test_refer_funcref_instr_after_realloc()
4827 var lines =<< trim END
4828 vim9script
4829 def A(d: bool)
4830 var e = abs(0)
4831 var f = &emoji
4832 &emoji = true
4833 if ['', '', '']->index('xxx') == 0
4834 eval 0 + 0
4835 endif
4836 if &filetype == 'xxx'
4837 var g = abs(0)
4838 while g > 0
4839 if getline(g) == ''
4840 break
4841 endif
4842 --g
4843 endwhile
4844 if g == 0
4845 return
4846 endif
4847 if d
4848 feedkeys($'{g}G')
4849 g = abs(0)
4850 endif
4851 var h = abs(0)
4852 var i = abs(0)
4853 var j = abs(0)
4854 while j < 0
4855 if abs(0) < h && getline(j) != ''
4856 break
4857 endif
4858 ++j
4859 endwhile
4860 feedkeys($'{g}G{j}G')
4861 return
4862 endif
4863 def B()
4864 enddef
4865 def C()
4866 enddef
4867 enddef
4868 A(false)
4869 END
4870 v9.CheckScriptSuccess(lines)
4871enddef
4872
Yegappan Lakshmanan06725952023-10-18 11:47:37 +02004873" Test for calling a deferred function after an exception
4874def Test_defer_after_exception()
4875 var lines =<< trim END
4876 vim9script
4877
Yegappan Lakshmananc59c1e02023-10-19 10:52:34 +02004878 var callTrace: list<number> = []
4879 def Bar()
4880 callTrace += [1]
4881 throw 'InnerException'
4882 enddef
4883
Yegappan Lakshmanan06725952023-10-18 11:47:37 +02004884 def Defer()
Yegappan Lakshmananc59c1e02023-10-19 10:52:34 +02004885 callTrace += [2]
4886 callTrace += [3]
4887 try
4888 Bar()
4889 catch /InnerException/
4890 callTrace += [4]
4891 endtry
4892 callTrace += [5]
4893 callTrace += [6]
Yegappan Lakshmanan06725952023-10-18 11:47:37 +02004894 enddef
4895
4896 def Foo()
4897 defer Defer()
4898 throw "TestException"
4899 enddef
4900
4901 try
4902 Foo()
4903 catch /TestException/
Yegappan Lakshmananc59c1e02023-10-19 10:52:34 +02004904 callTrace += [7]
Yegappan Lakshmanan06725952023-10-18 11:47:37 +02004905 endtry
4906
Yegappan Lakshmananc59c1e02023-10-19 10:52:34 +02004907 assert_equal([2, 3, 1, 4, 5, 6, 7], callTrace)
Yegappan Lakshmanan06725952023-10-18 11:47:37 +02004908 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +02004909 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan06725952023-10-18 11:47:37 +02004910enddef
4911
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02004912" Test for multiple deferred function which throw exceptions.
4913" Exceptions thrown by deferred functions should result in error messages but
4914" not propagated into the calling functions.
4915def Test_multidefer_with_exception()
4916 var lines =<< trim END
4917 vim9script
4918
4919 var callTrace: list<number> = []
4920 def Except()
4921 callTrace += [1]
4922 throw 'InnerException'
4923 callTrace += [2]
4924 enddef
4925
4926 def FirstDefer()
4927 callTrace += [3]
4928 callTrace += [4]
4929 enddef
4930
4931 def SecondDeferWithExcept()
4932 callTrace += [5]
4933 Except()
4934 callTrace += [6]
4935 enddef
4936
4937 def ThirdDefer()
4938 callTrace += [7]
4939 callTrace += [8]
4940 enddef
4941
4942 def Foo()
4943 callTrace += [9]
4944 defer FirstDefer()
4945 defer SecondDeferWithExcept()
4946 defer ThirdDefer()
4947 callTrace += [10]
4948 enddef
4949
4950 v:errmsg = ''
4951 try
4952 callTrace += [11]
4953 Foo()
4954 callTrace += [12]
4955 catch /TestException/
4956 callTrace += [13]
4957 catch
4958 callTrace += [14]
4959 finally
4960 callTrace += [15]
4961 endtry
4962 callTrace += [16]
4963
4964 assert_equal('E605: Exception not caught: InnerException', v:errmsg)
4965 assert_equal([11, 9, 10, 7, 8, 5, 1, 3, 4, 12, 15, 16], callTrace)
4966 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +02004967 v9.CheckSourceSuccess(lines)
4968enddef
4969
Yegappan Lakshmanana185a312023-12-16 14:36:08 +01004970" Test for using ":defer" inside an if statement with a false condition
4971def Test_defer_skipped()
4972 var lines =<< trim END
4973 def Foo()
4974 if false
4975 defer execute('echow "hello"', "")
4976 endif
4977 enddef
4978 defcompile
4979 END
4980 v9.CheckSourceSuccess(lines)
4981enddef
4982
Yegappan Lakshmanan062bb6b2023-12-16 14:46:40 +01004983" Test for using defer without parenthesis for the function name
4984def Test_defer_func_without_paren()
4985 var lines =<< trim END
4986 vim9script
4987 def Foo()
4988 defer Bar
4989 enddef
4990 defcompile
4991 END
4992 v9.CheckScriptFailure(lines, 'E107: Missing parentheses: Bar', 1)
4993enddef
4994
4995" Test for using defer without parenthesis for the function name
4996def Test_defer_non_existing_func()
4997 var lines =<< trim END
4998 vim9script
4999 def Foo()
5000 defer Bar()
5001 enddef
5002 defcompile
5003 END
5004 v9.CheckScriptFailure(lines, 'E1001: Variable not found: Bar', 1)
5005enddef
5006
5007" Test for using defer with an invalid function name
5008def Test_defer_invalid_func()
5009 var lines =<< trim END
5010 vim9script
5011 def Foo()
5012 var Abc = 10
5013 defer Abc()
5014 enddef
5015 defcompile
5016 END
5017 v9.CheckScriptFailure(lines, 'E129: Function name required', 2)
5018enddef
5019
5020" Test for using defer with an invalid argument to a function
5021def Test_defer_invalid_func_arg()
5022 var lines =<< trim END
5023 vim9script
5024 def Bar(x: number)
5025 enddef
5026 def Foo()
5027 defer Bar(a)
5028 enddef
5029 defcompile
5030 END
5031 v9.CheckScriptFailure(lines, 'E1001: Variable not found: a', 1)
5032enddef
5033
5034" Test for using an non-existing type in a "for" statement.
5035def Test_invalid_type_in_for()
5036 var lines =<< trim END
5037 vim9script
5038 def Foo()
5039 for b: x in range(10)
5040 endfor
5041 enddef
5042 defcompile
5043 END
Yegappan Lakshmanan1b531722024-05-09 09:12:31 +02005044 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: x', 1)
Yegappan Lakshmanan062bb6b2023-12-16 14:46:40 +01005045enddef
5046
5047" Test for using a line break between the variable name and the type in a for
5048" statement.
5049def Test_for_stmt_space_before_type()
5050 var lines =<< trim END
5051 vim9script
5052 def Foo()
5053 for a
5054 :number in range(10)
5055 endfor
5056 enddef
5057 defcompile
5058 END
5059 v9.CheckSourceFailure(lines, 'E1059: No white space allowed before colon: :number in range(10)', 2)
5060enddef
5061
zeertzjqc029c132024-03-28 11:37:26 +01005062" This test used to cause a use-after-free memory access
Yegappan Lakshmanan28d71b52024-01-12 17:21:55 +01005063def Test_for_empty_line_after_lambda()
5064 var lines =<< trim END
5065 vim9script
5066 echomsg range(0, 2)->map((_, v) => {
5067 return 1
5068 })
5069
5070 assert_equal('[1, 1, 1]', v:statusmsg)
5071 END
5072 v9.CheckSourceSuccess(lines)
5073
5074 lines =<< trim END
5075 vim9script
5076 echomsg range(0, 1)->map((_, v) => {
5077 return 1
5078 }) range(0, 1)->map((_, v) => {
5079 return 2
5080 }) # comment
5081
5082 assert_equal('[1, 1] [2, 2]', v:statusmsg)
5083 END
5084 v9.CheckSourceSuccess(lines)
5085enddef
5086
Yegappan Lakshmanan3fa8f772024-04-04 21:42:07 +02005087" Test for evaluating a lambda block from a string
5088def Test_eval_lambda_block()
5089 var lines =<< trim END
5090 vim9script
5091 var Fn = eval("(x: number): number => {\nreturn x * 2\n}")
5092 assert_equal(6, Fn(3))
5093 END
5094 v9.CheckSourceSuccess(lines)
5095enddef
5096
Yegappan Lakshmananda9d3452024-05-02 13:02:36 +02005097" Test for using various null values
5098def Test_null_values()
5099 var lines =<< trim END
5100 var nullValues = [
5101 [null, 1, 'null', 7, 'special'],
5102 [null_blob, 1, '0z', 10, 'blob'],
Yegappan Lakshmananda9d3452024-05-02 13:02:36 +02005103 [null_dict, 1, '{}', 4, 'dict<any>'],
5104 [null_function, 1, "function('')", 2, 'func(...): unknown'],
Yegappan Lakshmananda9d3452024-05-02 13:02:36 +02005105 [null_list, 1, '[]', 3, 'list<any>'],
5106 [null_object, 1, 'object of [unknown]', 13, 'object<Unknown>'],
5107 [null_partial, 1, "function('')", 2, 'func(...): unknown'],
5108 [null_string, 1, "''", 1, 'string']
5109 ]
Dominique Pellé52123872024-07-07 20:37:12 +02005110 if has('channel')
5111 nullValues->add([null_channel, 1, 'channel fail', 9, 'channel'])
5112 endif
5113 if has('job')
5114 nullValues->add([null_job, 1, 'no process', 8, 'job'])
5115 endif
Yegappan Lakshmananda9d3452024-05-02 13:02:36 +02005116
5117 for [Val, emptyExp, stringExp, typeExp, typenameExp] in nullValues
5118 assert_equal(emptyExp, empty(Val))
5119 assert_equal(stringExp, string(Val))
5120 assert_equal(typeExp, type(Val))
5121 assert_equal(typenameExp, typename(Val))
5122 assert_equal(Val, copy(Val))
5123 assert_equal(-1, test_refcount(Val))
5124 endfor
5125 END
5126 v9.CheckSourceDefAndScriptSuccess(lines)
5127enddef
5128
Yegappan Lakshmanan1b531722024-05-09 09:12:31 +02005129" Test for using an unknown type in a typecast
5130def Test_unknown_type_in_typecast()
5131 var lines =<< trim END
5132 vim9script
5133 var a = <MyType>b
5134 END
5135 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: MyType', 2)
5136
5137 lines =<< trim END
5138 vim9script
5139 var Fn = <funcx(number, number): number>b
5140 END
5141 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: funcx(number, number): number', 2)
Yegappan Lakshmananfe424d12024-05-17 18:20:43 +02005142
5143 # Wrong type in a type cast
5144 lines =<< trim END
5145 vim9script
5146 var i: number = <number>true
5147 END
5148 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got bool', 2)
Yegappan Lakshmanan1b531722024-05-09 09:12:31 +02005149enddef
5150
Yegappan Lakshmanane2038412024-12-14 19:59:24 +01005151" Test for calling a function as a method with a list argument
5152" This exercises some conditions in the assignment statement parsing code.
5153def Test_method_call_with_list_arg()
5154 var lines =<< trim END
5155 vim9script
5156
5157 def Foo(l: list<number>)
5158 g:save_list = l
5159 enddef
5160
5161 def Bar()
5162 var a = 10
5163 var b = 20
5164 [a, b]->Foo()
5165 enddef
5166
5167 g:save_list = []
5168 Bar()
5169 assert_equal([10, 20], g:save_list)
5170 END
5171 v9.CheckSourceSuccess(lines)
5172enddef
5173
Bram Moolenaar585fea72020-04-02 22:33:21 +02005174" Keep this last, it messes up highlighting.
5175def Test_substitute_cmd()
5176 new
5177 setline(1, 'something')
5178 :substitute(some(other(
5179 assert_equal('otherthing', getline(1))
5180 bwipe!
5181
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02005182 # also when the context is Vim9 script
Bram Moolenaarcfcd0112020-09-27 15:19:27 +02005183 var lines =<< trim END
Bram Moolenaar585fea72020-04-02 22:33:21 +02005184 vim9script
5185 new
5186 setline(1, 'something')
5187 :substitute(some(other(
5188 assert_equal('otherthing', getline(1))
5189 bwipe!
5190 END
Bram Moolenaardd674772022-09-15 22:26:18 +01005191 writefile(lines, 'Xvim9lines', 'D')
Bram Moolenaar585fea72020-04-02 22:33:21 +02005192 source Xvim9lines
Bram Moolenaar585fea72020-04-02 22:33:21 +02005193enddef
5194
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005195" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker