blob: 3eec28036446a1009e4498ceb6939f679c8593dd [file] [log] [blame]
Bram Moolenaar47e13952020-05-12 22:49:12 +02001*vim9.txt* For Vim version 8.2. Last change: 2020 May 09
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002
3
4 VIM REFERENCE MANUAL by Bram Moolenaar
5
6
7THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
8
Bram Moolenaar7ceefb32020-05-01 16:07:38 +02009Vim9 script commands and expressions. *vim9*
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010010
11Most expression help is in |eval.txt|. This file is about the new syntax and
12features in Vim9 script.
13
14THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
15
16
171 What is Vim9 script? |vim9-script|
182. Differences |vim9-differences|
193. New style functions |fast-functions|
204. Types |vim9-types|
215. Namespace, Import and Export |vim9script|
22
239. Rationale |vim9-rationale|
24
25==============================================================================
26
271. What is Vim9 script? *vim9-script*
28
29THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
30
Bram Moolenaar7ceefb32020-05-01 16:07:38 +020031Vim script has been growing over time, while preserving backwards
32compatibility. That means bad choices from the past often can't be changed
33and compability with Vi restricts possible solutions. Execution is quite
34slow, each line is parsed every time it is executed.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010035
Bram Moolenaar7ceefb32020-05-01 16:07:38 +020036The main goal of Vim9 script is to drastically improve performance. This is
37accomplished by compiling commands into instructions that can be efficiently
38executed. An increase in execution speed of 10 to 100 times can be expected.
39
40A secondary goal is to avoid Vim-specific constructs and get closer to
41commonly used programming languages, such as JavaScript, TypeScript and Java.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010042
43The performance improvements can only be achieved by not being 100% backwards
44compatible. For example, in a function the arguments are not available in the
Bram Moolenaar7ceefb32020-05-01 16:07:38 +020045"a:" dictionary, because creating that dictionary adds quite a lot of
46overhead. Other differences are more subtle, such as how errors are handled.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010047
48The Vim9 script syntax and semantics are used in:
49- a function defined with the `:def` command
50- a script file where the first command is `vim9script`
51
52When using `:function` in a Vim9 script file the legacy syntax is used.
Bram Moolenaar7ceefb32020-05-01 16:07:38 +020053However, this can be confusing and is therefore discouraged.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010054
Bram Moolenaar7ceefb32020-05-01 16:07:38 +020055Vim9 script and legacy Vim script can be mixed. There is no requirement to
56rewrite old scripts, they keep working as before.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010057
58==============================================================================
59
602. Differences from legacy Vim script *vim9-differences*
61
62THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
63
Bram Moolenaar2c330432020-04-13 14:41:35 +020064Comments starting with # ~
65
66In Vim script comments normally start with double quote. That can also be the
67start of a string, thus in many places it cannot be used. In Vim9 script a
Bram Moolenaar7ceefb32020-05-01 16:07:38 +020068comment can also start with #. In Vi this is a command to list text with
Bram Moolenaar2c330432020-04-13 14:41:35 +020069numbers, but you can also use `:number` for that. >
Bram Moolenaar7ceefb32020-05-01 16:07:38 +020070 let count = 0 # number of occurences
Bram Moolenaar2c330432020-04-13 14:41:35 +020071
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +020072To improve readability there must be a space between the command and the #
73that starts a comment. Note that #{ is the start of a dictionary, therefore
74it cannot start a comment.
75
Bram Moolenaar2c330432020-04-13 14:41:35 +020076
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010077Vim9 functions ~
78
Bram Moolenaar7ceefb32020-05-01 16:07:38 +020079A function defined with `:def` is compiled. Execution is many times faster,
80often 10x to 100x times.
81
82Many errors are already found when compiling, before the function is called.
83The syntax is strict, to enforce code that is easy to read and understand.
84
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010085`:def` has no extra arguments like `:function` does: "range", "abort", "dict"
86or "closure". A `:def` function always aborts on an error, does not get a
87range passed and cannot be a "dict" function.
88
Bram Moolenaar7ceefb32020-05-01 16:07:38 +020089The argument types and return type need to be specified. The "any" type can
90be used, type checking will then be done at runtime, like with legacy
91functions.
92
93Arguments are accessed by name, without "a:". There is no "a:" dictionary or
94"a:000" list.
95
96Variable arguments are defined as the last argument, with a name and have a
97list type, similar to Typescript. For example, a list of numbers: >
98 def MyFunc(...itemlist: list<number>)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010099 for item in itemlist
100 ...
101
102
Bram Moolenaar7ceefb32020-05-01 16:07:38 +0200103Functions and variables are script-local by default ~
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200104
105When using `:function` or `:def` to specify a new function at the script level
106in a Vim9 script, the function is local to the script, as if "s:" was
Bram Moolenaar7ceefb32020-05-01 16:07:38 +0200107prefixed. Using the "s:" prefix is optional.
108
109To define or use a global function or variable the "g:" prefix must be used.
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200110
111When using `:function` or `:def` to specify a new function inside a function,
112the function is local to the function. It is not possible to define a
Bram Moolenaar7ceefb32020-05-01 16:07:38 +0200113script-local function inside a function. It is possible to define a global
114function, using the "g:" prefix.
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200115
116When referring to a function and no "s:" or "g:" prefix is used, Vim will
117search for the function in this order:
Bram Moolenaar7ceefb32020-05-01 16:07:38 +0200118- Local to the current scope and outer scopes up to the function scope.
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200119- Local to the current script file.
120- Imported functions, see `:import`.
Bram Moolenaar7ceefb32020-05-01 16:07:38 +0200121In all cases the function must be defined before used. To make a call cycle a
122global function needs to be used. (TODO: can we fix this?)
123
124The result is that functions and variables without a namespace can always be
125found in the script, either defined there or imported. Global functions and
126variables could be defined anywhere (good luck finding where!).
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200127
Bram Moolenaar2cfb4a22020-05-07 18:56:00 +0200128Global functions can be still be defined and deleted at nearly any time. In
129Vim9 script script-local functions are defined once when the script is sourced
130and cannot be deleted.
131
132
133Four phases when loading a Vim9 script ~
134
135In legacy script the functions are created when encountered, but parsed only
136when used. This allows for defining functions in any order and having them
Bram Moolenaar47e13952020-05-12 22:49:12 +0200137call each other, so long as the function is defined when it is called: >
Bram Moolenaar2cfb4a22020-05-07 18:56:00 +0200138 func One()
139 call Two()
140 endfunc
141 func Two()
142 if cond
143 call One() " recursive call
144 endif
145 endfunc
146 call One()
147
Bram Moolenaar47e13952020-05-12 22:49:12 +0200148In Vim9 script the functions are compiled. When using the same functions as
149the above example it is not possible to compile function One without knowing
150that function Two exists. Or this would require a runtime check, which is slow
151and does not allow for compile time type checking.
Bram Moolenaar2cfb4a22020-05-07 18:56:00 +0200152
153When sourcing a Vim9 script this happens in four phases:
1541. Cleanup: If the script was sourced before all script-local variables,
155 imports and functions are deleted.
Bram Moolenaar47e13952020-05-12 22:49:12 +02001562. Discovery: The script is read and declarations of functions, imports and
157 variables are recognized and the type is parsed. Variable initializers
158 that are a constant are evaluated, this can also give the type of the
159 variable.
Bram Moolenaar2cfb4a22020-05-07 18:56:00 +02001603. Compilation: Functions are compiled. The script-local functions, imports
Bram Moolenaar47e13952020-05-12 22:49:12 +0200161 and variables from the discovery phase are found and types are checked.
1624. Execution: the commands in the script are executed, top to bottom.
163 Functions are skipped over, they do do not need to be processed again.
164 Variable initializers are evaluated when encountered. Note that if a
165 function called earlier has set the value this will be over-written. It is
166 best to declare variables before where they are used to avoid confusion.
Bram Moolenaar2cfb4a22020-05-07 18:56:00 +0200167
168The result is that items defined at the script level can be used anywhere in
169the script. This allows for putting the main function at the top: >
170 def Main()
171 SubOne()
172 SubTwo()
173 enddef
174 def SubOne()
175 ...
176 def SubTwo()
177 ...
178
179Note that script-local variables should either have a type defined or have a
180constant initializer. Otherwise an error is given for the type being unknown.
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200181
182
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100183Variable declarations with :let and :const ~
184
185Local variables need to be declared with `:let`. Local constants need to be
186declared with `:const`. We refer to both as "variables".
187
188Variables can be local to a script, function or code block: >
189 vim9script
190 let script_var = 123
191 def SomeFunc()
192 let func_var = script_var
193 if cond
194 let block_var = func_var
195 ...
196
197The variables are only visible in the block where they are defined and nested
198blocks. Once the block ends the variable is no longer accessible: >
199 if cond
200 let inner = 5
201 else
202 let inner = 0
203 endif
204 echo inner " Error!
205
206The declaration must be done earlier: >
207 let inner: number
208 if cond
209 inner = 5
210 else
211 inner = 0
212 endif
213 echo inner
214
215To intentionally use a variable that won't be available later, a block can be
216used: >
217 {
218 let temp = 'temp'
219 ...
220 }
221 echo temp " Error!
222
Bram Moolenaar560979e2020-02-04 22:53:05 +0100223An existing variable cannot be assigned to with `:let`, since that implies a
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100224declaration. An exception is global variables: these can be both used with
225and without `:let`, because there is no rule about where they are declared.
226
227Variables cannot shadow previously defined variables.
228Variables may shadow Ex commands, rename the variable if needed.
229
Bram Moolenaar7ceefb32020-05-01 16:07:38 +0200230Global variables and user defined functions must be prefixed with "g:", also
231at the script level. >
Bram Moolenaard1caa942020-04-10 22:10:56 +0200232 vim9script
233 let script_local = 'text'
234 let g:global = 'value'
Bram Moolenaar7ceefb32020-05-01 16:07:38 +0200235 let Funcref = g:ThatFunction
Bram Moolenaard1caa942020-04-10 22:10:56 +0200236
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100237Since "&opt = value" is now assigning a value to option "opt", ":&" cannot be
238used to repeat a `:substitute` command.
239
240
241Omitting :call and :eval ~
242
243Functions can be called without `:call`: >
244 writefile(lines, 'file')
Bram Moolenaar560979e2020-02-04 22:53:05 +0100245Using `:call` is still possible, but this is discouraged.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100246
247A method call without `eval` is possible, so long as the start is an
Bram Moolenaar0c6ceaf2020-02-22 18:36:32 +0100248identifier or can't be an Ex command. It does NOT work for string constants: >
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100249 myList->add(123) " works
250 g:myList->add(123) " works
251 [1, 2, 3]->Process() " works
252 #{a: 1, b: 2}->Process() " works
253 {'a': 1, 'b': 2}->Process() " works
254 "foobar"->Process() " does NOT work
Bram Moolenaar0c6ceaf2020-02-22 18:36:32 +0100255 ("foobar")->Process() " works
256 'foobar'->Process() " does NOT work
257 ('foobar')->Process() " works
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100258
Bram Moolenaar5b1c8fe2020-02-21 18:42:43 +0100259In case there is ambiguity between a function name and an Ex command, use ":"
260to make clear you want to use the Ex command. For example, there is both the
261`:substitute` command and the `substitute()` function. When the line starts
262with `substitute(` this will use the function, prepend a colon to use the
263command instead: >
Bram Moolenaar0c6ceaf2020-02-22 18:36:32 +0100264 :substitute(pattern (replacement (
Bram Moolenaar5b1c8fe2020-02-21 18:42:43 +0100265
Bram Moolenaarcc390ff2020-02-29 22:06:30 +0100266Note that while variables need to be defined before they can be used,
267functions can be called before being defined. This is required to be able
268have cyclic dependencies between functions. It is slightly less efficient,
269since the function has to be looked up by name. And a typo in the function
270name will only be found when the call is executed.
271
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100272
Bram Moolenaard1caa942020-04-10 22:10:56 +0200273Omitting function() ~
274
275A user defined function can be used as a function reference in an expression
276without `function()`. The argument types and return type will then be checked.
277The function must already have been defined. >
278
279 let Funcref = MyFunction
280
281When using `function()` the resulting type is "func", a function with any
282number of arguments and any return type. The function can be defined later.
283
284
Bram Moolenaar4fdae992020-04-12 16:38:57 +0200285Automatic line continuation ~
286
287In many cases it is obvious that an expression continues on the next line. In
288those cases there is no need to prefix the line with a backslash. For
289example, when a list spans multiple lines: >
290 let mylist = [
291 'one',
292 'two',
293 ]
Bram Moolenaare6085c52020-04-12 20:19:16 +0200294And when a dict spans multiple lines: >
295 let mydict = #{
296 one: 1,
297 two: 2,
298 }
299Function call: >
300 let result = Func(
301 arg1,
302 arg2
303 )
304
Bram Moolenaar9c7e6dd2020-04-12 20:55:20 +0200305For binary operators iin expressions not in [], {} or () a line break is
306possible AFTER the operators. For example: >
307 let text = lead ..
308 middle ..
309 end
310 let total = start +
311 end -
312 correction
313 let result = positive ?
314 PosFunc(arg) :
315 NegFunc(arg)
316
Bram Moolenaare6085c52020-04-12 20:19:16 +0200317Note that "enddef" cannot be used at the start of a continuation line, it ends
318the current function.
Bram Moolenaar4fdae992020-04-12 16:38:57 +0200319
Bram Moolenaar5e774c72020-04-12 21:53:00 +0200320It is also possible to split a function header over multiple lines, in between
321arguments: >
322 def MyFunc(
323 text: string,
324 separator = '-'
325 ): string
326
Bram Moolenaar4fdae992020-04-12 16:38:57 +0200327
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100328No curly braces expansion ~
329
330|curly-braces-names| cannot be used.
331
332
Bram Moolenaar560979e2020-02-04 22:53:05 +0100333No :append, :change or :insert ~
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100334
Bram Moolenaar560979e2020-02-04 22:53:05 +0100335These commands are too quickly confused with local variable names.
336
337
338Comparators ~
339
340The 'ignorecase' option is not used for comparators that use strings.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100341
342
343White space ~
344
345Vim9 script enforces proper use of white space. This is no longer allowed: >
346 let var=234 " Error!
347 let var= 234 " Error!
348 let var =234 " Error!
349There must be white space before and after the "=": >
350 let var = 234 " OK
Bram Moolenaar2c330432020-04-13 14:41:35 +0200351White space must also be put before the # that starts a comment: >
352 let var = 234# Error!
353 let var = 234 # OK
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100354
355White space is required around most operators.
356
357White space is not allowed:
358- Between a function name and the "(": >
359 call Func (arg) " Error!
360 call Func
361 \ (arg) " Error!
362 call Func(arg) " OK
363 call Func(
364 \ arg) " OK
Bram Moolenaar5b1c8fe2020-02-21 18:42:43 +0100365 call Func(
366 \ arg " OK
367 \ )
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100368
369
370Conditions and expressions ~
371
372Conditions and expression are mostly working like they do in JavaScript. A
373difference is made where JavaScript does not work like most people expect.
374Specifically, an empty list is falsey.
375
376Any type of variable can be used as a condition, there is no error, not even
377for using a list or job. This is very much like JavaScript, but there are a
378few exceptions.
379
380 type TRUE when ~
381 bool v:true
382 number non-zero
383 float non-zero
384 string non-empty
385 blob non-empty
386 list non-empty (different from JavaScript)
387 dictionary non-empty (different from JavaScript)
Bram Moolenaard1caa942020-04-10 22:10:56 +0200388 func when there is a function name
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100389 special v:true
390 job when not NULL
391 channel when not NULL
392 class when not NULL
393 object when not NULL (TODO: when isTrue() returns v:true)
394
395The boolean operators "||" and "&&" do not change the value: >
396 8 || 2 == 8
397 0 || 2 == 2
398 0 || '' == ''
399 8 && 2 == 2
400 0 && 2 == 0
401 [] && 2 == []
402
403When using `..` for string concatenation the arguments are always converted to
404string. >
405 'hello ' .. 123 == 'hello 123'
406 'hello ' .. v:true == 'hello true'
407
408In Vim9 script one can use "true" for v:true and "false" for v:false.
409
410
411==============================================================================
412
4133. New style functions *fast-functions*
414
415THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
416
417 *:def*
418:def[!] {name}([arguments])[: {return-type}
419 Define a new function by the name {name}. The body of
420 the function follows in the next lines, until the
421 matching `:enddef`.
422
Bram Moolenaard77a8522020-04-03 21:59:57 +0200423 When {return-type} is omitted or is "void" the
424 function is not expected to return anything.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100425
426 {arguments} is a sequence of zero or more argument
427 declarations. There are three forms:
428 {name}: {type}
429 {name} = {value}
430 {name}: {type} = {value}
431 The first form is a mandatory argument, the caller
432 must always provide them.
433 The second and third form are optional arguments.
434 When the caller omits an argument the {value} is used.
435
Bram Moolenaar560979e2020-02-04 22:53:05 +0100436 NOTE: It is possible to nest `:def` inside another
437 `:def`, but it is not possible to nest `:def` inside
438 `:function`, for backwards compatibility.
439
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100440 [!] is used as with `:function`.
441
442 *:enddef*
443:enddef End of a function defined with `:def`.
444
445
Bram Moolenaar5b1c8fe2020-02-21 18:42:43 +0100446If the script the function is defined in is Vim9 script, then script-local
447variables can be accessed without the "s:" prefix. They must be defined
448before the function. If the script the function is defined in is legacy
449script, then script-local variables must be accessed with the "s:" prefix.
450
451
Bram Moolenaarebdf3c92020-02-15 21:41:42 +0100452 *:disa* *:disassemble*
453:disa[ssemble] {func} Show the instructions generated for {func}.
454 This is for debugging and testing.
Bram Moolenaarcc390ff2020-02-29 22:06:30 +0100455 Note that for command line completion of {func} you
456 can prepend "s:" to find script-local functions.
Bram Moolenaarebdf3c92020-02-15 21:41:42 +0100457
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100458==============================================================================
459
4604. Types *vim9-types*
461
462THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
463
464The following builtin types are supported:
465 bool
466 number
467 float
468 string
469 blob
Bram Moolenaard77a8522020-04-03 21:59:57 +0200470 list<{type}>
471 dict<{type}>
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100472 job
473 channel
Bram Moolenaarb17893a2020-03-14 08:19:51 +0100474 func
Bram Moolenaard1caa942020-04-10 22:10:56 +0200475 func: {type}
Bram Moolenaard77a8522020-04-03 21:59:57 +0200476 func({type}, ...)
477 func({type}, ...): {type}
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100478
479Not supported yet:
Bram Moolenaard77a8522020-04-03 21:59:57 +0200480 tuple<a: {type}, b: {type}, ...>
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100481
Bram Moolenaard77a8522020-04-03 21:59:57 +0200482These types can be used in declarations, but no value will have this type:
483 {type}|{type}
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100484 void
485 any
486
Bram Moolenaard77a8522020-04-03 21:59:57 +0200487There is no array type, use list<{type}> instead. For a list constant an
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100488efficient implementation is used that avoids allocating lot of small pieces of
489memory.
490
Bram Moolenaard77a8522020-04-03 21:59:57 +0200491A partial and function can be declared in more or less specific ways:
492func any kind of function reference, no type
Bram Moolenaard1caa942020-04-10 22:10:56 +0200493 checking for arguments or return value
Bram Moolenaard77a8522020-04-03 21:59:57 +0200494func: {type} any number and type of arguments with specific
495 return type
Bram Moolenaard1caa942020-04-10 22:10:56 +0200496func({type}) function with argument type, does not return
Bram Moolenaard77a8522020-04-03 21:59:57 +0200497 a value
Bram Moolenaard1caa942020-04-10 22:10:56 +0200498func({type}): {type} function with argument type and return type
499func(?{type}) function with type of optional argument, does
500 not return a value
501func(...{type}) function with type of variable number of
502 arguments, does not return a value
503func({type}, ?{type}, ...{type}): {type}
504 function with:
505 - type of mandatory argument
506 - type of optional argument
507 - type of variable number of arguments
508 - return type
Bram Moolenaard77a8522020-04-03 21:59:57 +0200509
510If the return type is "void" the function does not return a value.
511
512The reference can also be a |Partial|, in which case it stores extra arguments
513and/or a dictionary, which are not visible to the caller. Since they are
514called in the same way the declaration is the same.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100515
516Custom types can be defined with `:type`: >
517 :type MyList list<string>
518{not implemented yet}
519
520And classes and interfaces can be used as types: >
521 :class MyClass
522 :let mine: MyClass
523
524 :interface MyInterface
525 :let mine: MyInterface
526
527 :class MyTemplate<Targ>
528 :let mine: MyTemplate<number>
529 :let mine: MyTemplate<string>
530
531 :class MyInterface<Targ>
532 :let mine: MyInterface<number>
533 :let mine: MyInterface<string>
534{not implemented yet}
535
536
537Type inference *type-inference*
538
539In general: Whenever the type is clear it can be omitted. For example, when
540declaring a variable and giving it a value: >
541 let var = 0 " infers number type
542 let var = 'hello' " infers string type
543
544
545==============================================================================
546
5475. Namespace, Import and Export
548 *vim9script* *vim9-export* *vim9-import*
549
550THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
551
552A Vim9 script can be written to be imported. This means that everything in
553the script is local, unless exported. Those exported items, and only those
554items, can then be imported in another script.
555
556
557Namespace ~
558 *:vim9script* *:vim9*
Bram Moolenaar560979e2020-02-04 22:53:05 +0100559To recognize a file that can be imported the `vim9script` statement must
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100560appear as the first statement in the file. It tells Vim to interpret the
561script in its own namespace, instead of the global namespace. If a file
562starts with: >
563 vim9script
564 let myvar = 'yes'
565Then "myvar" will only exist in this file. While without `vim9script` it would
566be available as `g:myvar` from any other script and function.
567
568The variables at the file level are very much like the script-local "s:"
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200569variables in legacy Vim script, but the "s:" is omitted. And they cannot be
570deleted.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100571
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200572In Vim9 script the global "g:" namespace can still be used as before. And the
573"w:", "b:" and "t:" namespaces. These have in common that variables are not
574declared and they can be deleted.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100575
576A side effect of `:vim9script` is that the 'cpoptions' option is set to the
577Vim default value, like with: >
578 :set cpo&vim
579One of the effects is that |line-continuation| is always enabled.
580The original value of 'cpoptions' is restored at the end of the script.
581
582
583Export ~
584 *:export* *:exp*
585Exporting one item can be written as: >
586 export const EXPORTED_CONST = 1234
587 export let someValue = ...
588 export def MyFunc() ...
589 export class MyClass ...
590
591As this suggests, only constants, variables, `:def` functions and classes can
592be exported.
593
594Alternatively, an export statement can be used to export several already
595defined (otherwise script-local) items: >
596 export {EXPORTED_CONST, someValue, MyFunc, MyClass}
597
598
599Import ~
600 *:import* *:imp*
601The exported items can be imported individually in another Vim9 script: >
602 import EXPORTED_CONST from "thatscript.vim"
603 import MyClass from "myclass.vim"
604
605To import multiple items at the same time: >
606 import {someValue, MyClass} from "thatscript.vim"
607
Bram Moolenaar560979e2020-02-04 22:53:05 +0100608In case the name is ambiguous, another name can be specified: >
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100609 import MyClass as ThatClass from "myclass.vim"
610 import {someValue, MyClass as ThatClass} from "myclass.vim"
611
612To import all exported items under a specific identifier: >
613 import * as That from 'thatscript.vim'
614
615Then you can use "That.EXPORTED_CONST", "That.someValue", etc. You are free
616to choose the name "That", but it is highly recommended to use the name of the
617script file to avoid confusion.
618
619The script name after `import` can be:
620- A relative path, starting "." or "..". This finds a file relative to the
621 location of the script file itself. This is useful to split up a large
622 plugin into several files.
623- An absolute path, starting with "/" on Unix or "D:/" on MS-Windows. This
624 will be rarely used.
625- A path not being relative or absolute. This will be found in the
626 "import" subdirectories of 'runtimepath' entries. The name will usually be
627 longer and unique, to avoid loading the wrong file.
628
629Once a vim9 script file has been imported, the result is cached and used the
630next time the same script is imported. It will not be read again.
631 *:import-cycle*
632The `import` commands are executed when encountered. If that script (directly
633or indirectly) imports the current script, then items defined after the
634`import` won't be processed yet. Therefore cyclic imports can exist, but may
635result in undefined items.
636
637
638Import in an autoload script ~
639
640For optimal startup speed, loading scripts should be postponed until they are
Bram Moolenaar560979e2020-02-04 22:53:05 +0100641actually needed. A recommended mechanism:
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100642
6431. In the plugin define user commands, functions and/or mappings that refer to
644 an autoload script. >
645 command -nargs=1 SearchForStuff call searchfor#Stuff(<f-args>)
646
647< This goes in .../plugin/anyname.vim. "anyname.vim" can be freely chosen.
648
6492. In the autocommand script do the actual work. You can import items from
650 other files to split up functionality in appropriate pieces. >
651 vim9script
652 import FilterFunc from "../import/someother.vim"
653 def searchfor#Stuff(arg: string)
654 let filtered = FilterFunc(arg)
655 ...
656< This goes in .../autoload/searchfor.vim. "searchfor" in the file name
657 must be exactly the same as the prefix for the function name, that is how
658 Vim finds the file.
659
6603. Other functionality, possibly shared between plugins, contains the exported
661 items and any private items. >
662 vim9script
663 let localVar = 'local'
664 export def FilterFunc(arg: string): string
665 ...
666< This goes in .../import/someother.vim.
667
668
669Import in legacy Vim script ~
670
671If an `import` statement is used in legacy Vim script, for identifier the
672script-local "s:" namespace will be used, even when "s:" is not specified.
673
674
675==============================================================================
676
6779. Rationale *vim9-rationale*
678
679The :def command ~
680
681Plugin writers have asked for a much faster Vim script. Investigation have
Bram Moolenaar560979e2020-02-04 22:53:05 +0100682shown that keeping the existing semantics of function calls make this close to
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100683impossible, because of the overhead involved with calling a function, setting
684up the local function scope and executing lines. There are many details that
685need to be handled, such as error messages and exceptions. The need to create
686a dictionary for a: and l: scopes, the a:000 list and several others add too
687much overhead that cannot be avoided.
688
689Therefore the `:def` method to define a new-style function had to be added,
690which allows for a function with different semantics. Most things still work
691as before, but some parts do not. A new way to define a function was
692considered the best way to separate the old-style code from Vim9 script code.
693
694Using "def" to define a function comes from Python. Other languages use
695"function" which clashes with legacy Vim script.
696
697
698Type checking ~
699
700When compiling lines of Vim commands into instructions as much as possible
701should be done at compile time. Postponing it to runtime makes the execution
702slower and means mistakes are found only later. For example, when
703encountering the "+" character and compiling this into a generic add
704instruction, at execution time the instruction would have to inspect the type
705of the arguments and decide what kind of addition to do. And when the
706type is dictionary throw an error. If the types are known to be numbers then
707an "add number" instruction can be used, which is faster. The error can be
708given at compile time, no error handling is needed at runtime.
709
710The syntax for types is similar to Java, since it is easy to understand and
711widely used. The type names are what was used in Vim before, with some
712additions such as "void" and "bool".
713
714
715JavaScript/TypeScript syntax and semantics ~
716
717Script writers have complained that the Vim script syntax is unexpectedly
718different from what they are used to. To reduce this complaint popular
719languages will be used as an example. At the same time, we do not want to
Bram Moolenaar560979e2020-02-04 22:53:05 +0100720abandon the well-known parts of legacy Vim script.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100721
722Since Vim already uses `:let` and `:const` and optional type checking is
723desirable, the JavaScript/TypeScript syntax fits best for variable
724declarations. >
725 const greeting = 'hello' " string type is inferred
726 let name: string
727 ...
728 name = 'John'
729
730Expression evaluation was already close to what JavaScript and other languages
731are doing. Some details are unexpected and can be fixed. For example how the
732|| and && operators work. Legacy Vim script: >
733 let result = 44
734 ...
735 return result || 0 " returns 1
736
737Vim9 script works like JavaScript, keep the value: >
738 let result = 44
739 ...
740 return result || 0 " returns 44
741
742On the other hand, overloading "+" to use both for addition and string
743concatenation goes against legacy Vim script and often leads to mistakes.
744For that reason we will keep using ".." for string concatenation. Lua also
745uses ".." this way.
746
747
748Import and Export ~
749
750A problem of legacy Vim script is that by default all functions and variables
751are global. It is possible to make them script-local, but then they are not
752available in other scripts.
753
754In Vim9 script a mechanism very similar to the Javascript import and export
755mechanism is supported. It is a variant to the existing `:source` command
756that works like one would expect:
757- Instead of making everything global by default, everything is script-local,
758 unless exported.
759- When importing a script the symbols that are imported are listed, avoiding
760 name conflicts and failures if later functionality is added.
761- The mechanism allows for writing a big, long script with a very clear API:
762 the exported function(s) and class(es).
763- By using relative paths loading can be much faster for an import inside of a
764 package, no need to search many directories.
765- Once an import has been used, it can be cached and loading it again can be
766 avoided.
767- The Vim-specific use of "s:" to make things script-local can be dropped.
768
769
770Classes ~
771
772Vim supports interfaces to Perl, Python, Lua, Tcl and a few others. But
773these have never become widespread. When Vim 9 was designed a decision was
774made to phase out these interfaces and concentrate on Vim script, while
775encouraging plugin authors to write code in any language and run it as an
776external tool, using jobs and channels.
777
778Still, using an external tool has disadvantages. An alternative is to convert
779the tool into Vim script. For that to be possible without too much
780translation, and keeping the code fast at the same time, the constructs of the
781tool need to be supported. Since most languages support classes the lack of
782class support in Vim is then a problem.
783
784Previously Vim supported a kind-of object oriented programming by adding
785methods to a dictionary. With some care this could be made to work, but it
786does not look like real classes. On top of that, it's very slow, because of
787the use of dictionaries.
788
789The support of classes in Vim9 script is a "minimal common functionality" of
790class support in most languages. It works mostly like Java, which is the most
791popular programming language.
792
793
794
795 vim:tw=78:ts=8:noet:ft=help:norl: