blob: cb880c18f5f9e310adbcf017213aa88257bee093 [file] [log] [blame]
Bram Moolenaar2cfb4a22020-05-07 18:56:00 +02001*vim9.txt* For Vim version 8.2. Last change: 2020 May 06
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
137call each other: >
138 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
148In Vim9 script the functions are compiled. If using the same functions as the
149above example it is not possible to compile function One without knowing that
150function Two exists. Or this would require a runtime check, which is slow and
151does not allow for compile time type checking.
152
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.
1562. Discovery: The script is read and encountered functions, imports and
157 variables are recognized. The type is parsed. Variable initializers that
158 are a constant are evaluated, this can give the type of the variable.
1593. Compilation: Functions are compiled. The script-local functions, imports
160 and variables from the discovery phase are recognized and types are
161 checked.
1624. Execution: the commands in the script are executed. Functions are skipped
163 over. Variable initializers are evaluated, unless they are a constant.
164
165The result is that items defined at the script level can be used anywhere in
166the script. This allows for putting the main function at the top: >
167 def Main()
168 SubOne()
169 SubTwo()
170 enddef
171 def SubOne()
172 ...
173 def SubTwo()
174 ...
175
176Note that script-local variables should either have a type defined or have a
177constant initializer. Otherwise an error is given for the type being unknown.
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200178
179
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100180Variable declarations with :let and :const ~
181
182Local variables need to be declared with `:let`. Local constants need to be
183declared with `:const`. We refer to both as "variables".
184
185Variables can be local to a script, function or code block: >
186 vim9script
187 let script_var = 123
188 def SomeFunc()
189 let func_var = script_var
190 if cond
191 let block_var = func_var
192 ...
193
194The variables are only visible in the block where they are defined and nested
195blocks. Once the block ends the variable is no longer accessible: >
196 if cond
197 let inner = 5
198 else
199 let inner = 0
200 endif
201 echo inner " Error!
202
203The declaration must be done earlier: >
204 let inner: number
205 if cond
206 inner = 5
207 else
208 inner = 0
209 endif
210 echo inner
211
212To intentionally use a variable that won't be available later, a block can be
213used: >
214 {
215 let temp = 'temp'
216 ...
217 }
218 echo temp " Error!
219
Bram Moolenaar560979e2020-02-04 22:53:05 +0100220An existing variable cannot be assigned to with `:let`, since that implies a
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100221declaration. An exception is global variables: these can be both used with
222and without `:let`, because there is no rule about where they are declared.
223
224Variables cannot shadow previously defined variables.
225Variables may shadow Ex commands, rename the variable if needed.
226
Bram Moolenaar7ceefb32020-05-01 16:07:38 +0200227Global variables and user defined functions must be prefixed with "g:", also
228at the script level. >
Bram Moolenaard1caa942020-04-10 22:10:56 +0200229 vim9script
230 let script_local = 'text'
231 let g:global = 'value'
Bram Moolenaar7ceefb32020-05-01 16:07:38 +0200232 let Funcref = g:ThatFunction
Bram Moolenaard1caa942020-04-10 22:10:56 +0200233
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100234Since "&opt = value" is now assigning a value to option "opt", ":&" cannot be
235used to repeat a `:substitute` command.
236
237
238Omitting :call and :eval ~
239
240Functions can be called without `:call`: >
241 writefile(lines, 'file')
Bram Moolenaar560979e2020-02-04 22:53:05 +0100242Using `:call` is still possible, but this is discouraged.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100243
244A method call without `eval` is possible, so long as the start is an
Bram Moolenaar0c6ceaf2020-02-22 18:36:32 +0100245identifier or can't be an Ex command. It does NOT work for string constants: >
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100246 myList->add(123) " works
247 g:myList->add(123) " works
248 [1, 2, 3]->Process() " works
249 #{a: 1, b: 2}->Process() " works
250 {'a': 1, 'b': 2}->Process() " works
251 "foobar"->Process() " does NOT work
Bram Moolenaar0c6ceaf2020-02-22 18:36:32 +0100252 ("foobar")->Process() " works
253 'foobar'->Process() " does NOT work
254 ('foobar')->Process() " works
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100255
Bram Moolenaar5b1c8fe2020-02-21 18:42:43 +0100256In case there is ambiguity between a function name and an Ex command, use ":"
257to make clear you want to use the Ex command. For example, there is both the
258`:substitute` command and the `substitute()` function. When the line starts
259with `substitute(` this will use the function, prepend a colon to use the
260command instead: >
Bram Moolenaar0c6ceaf2020-02-22 18:36:32 +0100261 :substitute(pattern (replacement (
Bram Moolenaar5b1c8fe2020-02-21 18:42:43 +0100262
Bram Moolenaarcc390ff2020-02-29 22:06:30 +0100263Note that while variables need to be defined before they can be used,
264functions can be called before being defined. This is required to be able
265have cyclic dependencies between functions. It is slightly less efficient,
266since the function has to be looked up by name. And a typo in the function
267name will only be found when the call is executed.
268
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100269
Bram Moolenaard1caa942020-04-10 22:10:56 +0200270Omitting function() ~
271
272A user defined function can be used as a function reference in an expression
273without `function()`. The argument types and return type will then be checked.
274The function must already have been defined. >
275
276 let Funcref = MyFunction
277
278When using `function()` the resulting type is "func", a function with any
279number of arguments and any return type. The function can be defined later.
280
281
Bram Moolenaar4fdae992020-04-12 16:38:57 +0200282Automatic line continuation ~
283
284In many cases it is obvious that an expression continues on the next line. In
285those cases there is no need to prefix the line with a backslash. For
286example, when a list spans multiple lines: >
287 let mylist = [
288 'one',
289 'two',
290 ]
Bram Moolenaare6085c52020-04-12 20:19:16 +0200291And when a dict spans multiple lines: >
292 let mydict = #{
293 one: 1,
294 two: 2,
295 }
296Function call: >
297 let result = Func(
298 arg1,
299 arg2
300 )
301
Bram Moolenaar9c7e6dd2020-04-12 20:55:20 +0200302For binary operators iin expressions not in [], {} or () a line break is
303possible AFTER the operators. For example: >
304 let text = lead ..
305 middle ..
306 end
307 let total = start +
308 end -
309 correction
310 let result = positive ?
311 PosFunc(arg) :
312 NegFunc(arg)
313
Bram Moolenaare6085c52020-04-12 20:19:16 +0200314Note that "enddef" cannot be used at the start of a continuation line, it ends
315the current function.
Bram Moolenaar4fdae992020-04-12 16:38:57 +0200316
Bram Moolenaar5e774c72020-04-12 21:53:00 +0200317It is also possible to split a function header over multiple lines, in between
318arguments: >
319 def MyFunc(
320 text: string,
321 separator = '-'
322 ): string
323
Bram Moolenaar4fdae992020-04-12 16:38:57 +0200324
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100325No curly braces expansion ~
326
327|curly-braces-names| cannot be used.
328
329
Bram Moolenaar560979e2020-02-04 22:53:05 +0100330No :append, :change or :insert ~
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100331
Bram Moolenaar560979e2020-02-04 22:53:05 +0100332These commands are too quickly confused with local variable names.
333
334
335Comparators ~
336
337The 'ignorecase' option is not used for comparators that use strings.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100338
339
340White space ~
341
342Vim9 script enforces proper use of white space. This is no longer allowed: >
343 let var=234 " Error!
344 let var= 234 " Error!
345 let var =234 " Error!
346There must be white space before and after the "=": >
347 let var = 234 " OK
Bram Moolenaar2c330432020-04-13 14:41:35 +0200348White space must also be put before the # that starts a comment: >
349 let var = 234# Error!
350 let var = 234 # OK
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100351
352White space is required around most operators.
353
354White space is not allowed:
355- Between a function name and the "(": >
356 call Func (arg) " Error!
357 call Func
358 \ (arg) " Error!
359 call Func(arg) " OK
360 call Func(
361 \ arg) " OK
Bram Moolenaar5b1c8fe2020-02-21 18:42:43 +0100362 call Func(
363 \ arg " OK
364 \ )
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100365
366
367Conditions and expressions ~
368
369Conditions and expression are mostly working like they do in JavaScript. A
370difference is made where JavaScript does not work like most people expect.
371Specifically, an empty list is falsey.
372
373Any type of variable can be used as a condition, there is no error, not even
374for using a list or job. This is very much like JavaScript, but there are a
375few exceptions.
376
377 type TRUE when ~
378 bool v:true
379 number non-zero
380 float non-zero
381 string non-empty
382 blob non-empty
383 list non-empty (different from JavaScript)
384 dictionary non-empty (different from JavaScript)
Bram Moolenaard1caa942020-04-10 22:10:56 +0200385 func when there is a function name
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100386 special v:true
387 job when not NULL
388 channel when not NULL
389 class when not NULL
390 object when not NULL (TODO: when isTrue() returns v:true)
391
392The boolean operators "||" and "&&" do not change the value: >
393 8 || 2 == 8
394 0 || 2 == 2
395 0 || '' == ''
396 8 && 2 == 2
397 0 && 2 == 0
398 [] && 2 == []
399
400When using `..` for string concatenation the arguments are always converted to
401string. >
402 'hello ' .. 123 == 'hello 123'
403 'hello ' .. v:true == 'hello true'
404
405In Vim9 script one can use "true" for v:true and "false" for v:false.
406
407
408==============================================================================
409
4103. New style functions *fast-functions*
411
412THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
413
414 *:def*
415:def[!] {name}([arguments])[: {return-type}
416 Define a new function by the name {name}. The body of
417 the function follows in the next lines, until the
418 matching `:enddef`.
419
Bram Moolenaard77a8522020-04-03 21:59:57 +0200420 When {return-type} is omitted or is "void" the
421 function is not expected to return anything.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100422
423 {arguments} is a sequence of zero or more argument
424 declarations. There are three forms:
425 {name}: {type}
426 {name} = {value}
427 {name}: {type} = {value}
428 The first form is a mandatory argument, the caller
429 must always provide them.
430 The second and third form are optional arguments.
431 When the caller omits an argument the {value} is used.
432
Bram Moolenaar560979e2020-02-04 22:53:05 +0100433 NOTE: It is possible to nest `:def` inside another
434 `:def`, but it is not possible to nest `:def` inside
435 `:function`, for backwards compatibility.
436
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100437 [!] is used as with `:function`.
438
439 *:enddef*
440:enddef End of a function defined with `:def`.
441
442
Bram Moolenaar5b1c8fe2020-02-21 18:42:43 +0100443If the script the function is defined in is Vim9 script, then script-local
444variables can be accessed without the "s:" prefix. They must be defined
445before the function. If the script the function is defined in is legacy
446script, then script-local variables must be accessed with the "s:" prefix.
447
448
Bram Moolenaarebdf3c92020-02-15 21:41:42 +0100449 *:disa* *:disassemble*
450:disa[ssemble] {func} Show the instructions generated for {func}.
451 This is for debugging and testing.
Bram Moolenaarcc390ff2020-02-29 22:06:30 +0100452 Note that for command line completion of {func} you
453 can prepend "s:" to find script-local functions.
Bram Moolenaarebdf3c92020-02-15 21:41:42 +0100454
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100455==============================================================================
456
4574. Types *vim9-types*
458
459THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
460
461The following builtin types are supported:
462 bool
463 number
464 float
465 string
466 blob
Bram Moolenaard77a8522020-04-03 21:59:57 +0200467 list<{type}>
468 dict<{type}>
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100469 job
470 channel
Bram Moolenaarb17893a2020-03-14 08:19:51 +0100471 func
Bram Moolenaard1caa942020-04-10 22:10:56 +0200472 func: {type}
Bram Moolenaard77a8522020-04-03 21:59:57 +0200473 func({type}, ...)
474 func({type}, ...): {type}
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100475
476Not supported yet:
Bram Moolenaard77a8522020-04-03 21:59:57 +0200477 tuple<a: {type}, b: {type}, ...>
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100478
Bram Moolenaard77a8522020-04-03 21:59:57 +0200479These types can be used in declarations, but no value will have this type:
480 {type}|{type}
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100481 void
482 any
483
Bram Moolenaard77a8522020-04-03 21:59:57 +0200484There is no array type, use list<{type}> instead. For a list constant an
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100485efficient implementation is used that avoids allocating lot of small pieces of
486memory.
487
Bram Moolenaard77a8522020-04-03 21:59:57 +0200488A partial and function can be declared in more or less specific ways:
489func any kind of function reference, no type
Bram Moolenaard1caa942020-04-10 22:10:56 +0200490 checking for arguments or return value
Bram Moolenaard77a8522020-04-03 21:59:57 +0200491func: {type} any number and type of arguments with specific
492 return type
Bram Moolenaard1caa942020-04-10 22:10:56 +0200493func({type}) function with argument type, does not return
Bram Moolenaard77a8522020-04-03 21:59:57 +0200494 a value
Bram Moolenaard1caa942020-04-10 22:10:56 +0200495func({type}): {type} function with argument type and return type
496func(?{type}) function with type of optional argument, does
497 not return a value
498func(...{type}) function with type of variable number of
499 arguments, does not return a value
500func({type}, ?{type}, ...{type}): {type}
501 function with:
502 - type of mandatory argument
503 - type of optional argument
504 - type of variable number of arguments
505 - return type
Bram Moolenaard77a8522020-04-03 21:59:57 +0200506
507If the return type is "void" the function does not return a value.
508
509The reference can also be a |Partial|, in which case it stores extra arguments
510and/or a dictionary, which are not visible to the caller. Since they are
511called in the same way the declaration is the same.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100512
513Custom types can be defined with `:type`: >
514 :type MyList list<string>
515{not implemented yet}
516
517And classes and interfaces can be used as types: >
518 :class MyClass
519 :let mine: MyClass
520
521 :interface MyInterface
522 :let mine: MyInterface
523
524 :class MyTemplate<Targ>
525 :let mine: MyTemplate<number>
526 :let mine: MyTemplate<string>
527
528 :class MyInterface<Targ>
529 :let mine: MyInterface<number>
530 :let mine: MyInterface<string>
531{not implemented yet}
532
533
534Type inference *type-inference*
535
536In general: Whenever the type is clear it can be omitted. For example, when
537declaring a variable and giving it a value: >
538 let var = 0 " infers number type
539 let var = 'hello' " infers string type
540
541
542==============================================================================
543
5445. Namespace, Import and Export
545 *vim9script* *vim9-export* *vim9-import*
546
547THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
548
549A Vim9 script can be written to be imported. This means that everything in
550the script is local, unless exported. Those exported items, and only those
551items, can then be imported in another script.
552
553
554Namespace ~
555 *:vim9script* *:vim9*
Bram Moolenaar560979e2020-02-04 22:53:05 +0100556To recognize a file that can be imported the `vim9script` statement must
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100557appear as the first statement in the file. It tells Vim to interpret the
558script in its own namespace, instead of the global namespace. If a file
559starts with: >
560 vim9script
561 let myvar = 'yes'
562Then "myvar" will only exist in this file. While without `vim9script` it would
563be available as `g:myvar` from any other script and function.
564
565The variables at the file level are very much like the script-local "s:"
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200566variables in legacy Vim script, but the "s:" is omitted. And they cannot be
567deleted.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100568
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200569In Vim9 script the global "g:" namespace can still be used as before. And the
570"w:", "b:" and "t:" namespaces. These have in common that variables are not
571declared and they can be deleted.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100572
573A side effect of `:vim9script` is that the 'cpoptions' option is set to the
574Vim default value, like with: >
575 :set cpo&vim
576One of the effects is that |line-continuation| is always enabled.
577The original value of 'cpoptions' is restored at the end of the script.
578
579
580Export ~
581 *:export* *:exp*
582Exporting one item can be written as: >
583 export const EXPORTED_CONST = 1234
584 export let someValue = ...
585 export def MyFunc() ...
586 export class MyClass ...
587
588As this suggests, only constants, variables, `:def` functions and classes can
589be exported.
590
591Alternatively, an export statement can be used to export several already
592defined (otherwise script-local) items: >
593 export {EXPORTED_CONST, someValue, MyFunc, MyClass}
594
595
596Import ~
597 *:import* *:imp*
598The exported items can be imported individually in another Vim9 script: >
599 import EXPORTED_CONST from "thatscript.vim"
600 import MyClass from "myclass.vim"
601
602To import multiple items at the same time: >
603 import {someValue, MyClass} from "thatscript.vim"
604
Bram Moolenaar560979e2020-02-04 22:53:05 +0100605In case the name is ambiguous, another name can be specified: >
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100606 import MyClass as ThatClass from "myclass.vim"
607 import {someValue, MyClass as ThatClass} from "myclass.vim"
608
609To import all exported items under a specific identifier: >
610 import * as That from 'thatscript.vim'
611
612Then you can use "That.EXPORTED_CONST", "That.someValue", etc. You are free
613to choose the name "That", but it is highly recommended to use the name of the
614script file to avoid confusion.
615
616The script name after `import` can be:
617- A relative path, starting "." or "..". This finds a file relative to the
618 location of the script file itself. This is useful to split up a large
619 plugin into several files.
620- An absolute path, starting with "/" on Unix or "D:/" on MS-Windows. This
621 will be rarely used.
622- A path not being relative or absolute. This will be found in the
623 "import" subdirectories of 'runtimepath' entries. The name will usually be
624 longer and unique, to avoid loading the wrong file.
625
626Once a vim9 script file has been imported, the result is cached and used the
627next time the same script is imported. It will not be read again.
628 *:import-cycle*
629The `import` commands are executed when encountered. If that script (directly
630or indirectly) imports the current script, then items defined after the
631`import` won't be processed yet. Therefore cyclic imports can exist, but may
632result in undefined items.
633
634
635Import in an autoload script ~
636
637For optimal startup speed, loading scripts should be postponed until they are
Bram Moolenaar560979e2020-02-04 22:53:05 +0100638actually needed. A recommended mechanism:
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100639
6401. In the plugin define user commands, functions and/or mappings that refer to
641 an autoload script. >
642 command -nargs=1 SearchForStuff call searchfor#Stuff(<f-args>)
643
644< This goes in .../plugin/anyname.vim. "anyname.vim" can be freely chosen.
645
6462. In the autocommand script do the actual work. You can import items from
647 other files to split up functionality in appropriate pieces. >
648 vim9script
649 import FilterFunc from "../import/someother.vim"
650 def searchfor#Stuff(arg: string)
651 let filtered = FilterFunc(arg)
652 ...
653< This goes in .../autoload/searchfor.vim. "searchfor" in the file name
654 must be exactly the same as the prefix for the function name, that is how
655 Vim finds the file.
656
6573. Other functionality, possibly shared between plugins, contains the exported
658 items and any private items. >
659 vim9script
660 let localVar = 'local'
661 export def FilterFunc(arg: string): string
662 ...
663< This goes in .../import/someother.vim.
664
665
666Import in legacy Vim script ~
667
668If an `import` statement is used in legacy Vim script, for identifier the
669script-local "s:" namespace will be used, even when "s:" is not specified.
670
671
672==============================================================================
673
6749. Rationale *vim9-rationale*
675
676The :def command ~
677
678Plugin writers have asked for a much faster Vim script. Investigation have
Bram Moolenaar560979e2020-02-04 22:53:05 +0100679shown that keeping the existing semantics of function calls make this close to
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100680impossible, because of the overhead involved with calling a function, setting
681up the local function scope and executing lines. There are many details that
682need to be handled, such as error messages and exceptions. The need to create
683a dictionary for a: and l: scopes, the a:000 list and several others add too
684much overhead that cannot be avoided.
685
686Therefore the `:def` method to define a new-style function had to be added,
687which allows for a function with different semantics. Most things still work
688as before, but some parts do not. A new way to define a function was
689considered the best way to separate the old-style code from Vim9 script code.
690
691Using "def" to define a function comes from Python. Other languages use
692"function" which clashes with legacy Vim script.
693
694
695Type checking ~
696
697When compiling lines of Vim commands into instructions as much as possible
698should be done at compile time. Postponing it to runtime makes the execution
699slower and means mistakes are found only later. For example, when
700encountering the "+" character and compiling this into a generic add
701instruction, at execution time the instruction would have to inspect the type
702of the arguments and decide what kind of addition to do. And when the
703type is dictionary throw an error. If the types are known to be numbers then
704an "add number" instruction can be used, which is faster. The error can be
705given at compile time, no error handling is needed at runtime.
706
707The syntax for types is similar to Java, since it is easy to understand and
708widely used. The type names are what was used in Vim before, with some
709additions such as "void" and "bool".
710
711
712JavaScript/TypeScript syntax and semantics ~
713
714Script writers have complained that the Vim script syntax is unexpectedly
715different from what they are used to. To reduce this complaint popular
716languages will be used as an example. At the same time, we do not want to
Bram Moolenaar560979e2020-02-04 22:53:05 +0100717abandon the well-known parts of legacy Vim script.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100718
719Since Vim already uses `:let` and `:const` and optional type checking is
720desirable, the JavaScript/TypeScript syntax fits best for variable
721declarations. >
722 const greeting = 'hello' " string type is inferred
723 let name: string
724 ...
725 name = 'John'
726
727Expression evaluation was already close to what JavaScript and other languages
728are doing. Some details are unexpected and can be fixed. For example how the
729|| and && operators work. Legacy Vim script: >
730 let result = 44
731 ...
732 return result || 0 " returns 1
733
734Vim9 script works like JavaScript, keep the value: >
735 let result = 44
736 ...
737 return result || 0 " returns 44
738
739On the other hand, overloading "+" to use both for addition and string
740concatenation goes against legacy Vim script and often leads to mistakes.
741For that reason we will keep using ".." for string concatenation. Lua also
742uses ".." this way.
743
744
745Import and Export ~
746
747A problem of legacy Vim script is that by default all functions and variables
748are global. It is possible to make them script-local, but then they are not
749available in other scripts.
750
751In Vim9 script a mechanism very similar to the Javascript import and export
752mechanism is supported. It is a variant to the existing `:source` command
753that works like one would expect:
754- Instead of making everything global by default, everything is script-local,
755 unless exported.
756- When importing a script the symbols that are imported are listed, avoiding
757 name conflicts and failures if later functionality is added.
758- The mechanism allows for writing a big, long script with a very clear API:
759 the exported function(s) and class(es).
760- By using relative paths loading can be much faster for an import inside of a
761 package, no need to search many directories.
762- Once an import has been used, it can be cached and loading it again can be
763 avoided.
764- The Vim-specific use of "s:" to make things script-local can be dropped.
765
766
767Classes ~
768
769Vim supports interfaces to Perl, Python, Lua, Tcl and a few others. But
770these have never become widespread. When Vim 9 was designed a decision was
771made to phase out these interfaces and concentrate on Vim script, while
772encouraging plugin authors to write code in any language and run it as an
773external tool, using jobs and channels.
774
775Still, using an external tool has disadvantages. An alternative is to convert
776the tool into Vim script. For that to be possible without too much
777translation, and keeping the code fast at the same time, the constructs of the
778tool need to be supported. Since most languages support classes the lack of
779class support in Vim is then a problem.
780
781Previously Vim supported a kind-of object oriented programming by adding
782methods to a dictionary. With some care this could be made to work, but it
783does not look like real classes. On top of that, it's very slow, because of
784the use of dictionaries.
785
786The support of classes in Vim9 script is a "minimal common functionality" of
787class support in most languages. It works mostly like Java, which is the most
788popular programming language.
789
790
791
792 vim:tw=78:ts=8:noet:ft=help:norl: