blob: d1d3194e2003a159f1dac86d119da4fd99af4c2b [file] [log] [blame]
Bram Moolenaar65c44152020-12-24 15:14:01 +01001*vim9.txt* For Vim version 8.2. Last change: 2020 Dec 24
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 Moolenaar4072ba52020-12-23 13:56:35 +01009Vim9 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
Bram Moolenaare7b1ea02020-08-07 19:54:59 +0200171. What is Vim9 script? |vim9-script|
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100182. Differences |vim9-differences|
193. New style functions |fast-functions|
204. Types |vim9-types|
215. Namespace, Import and Export |vim9script|
Bram Moolenaar1d59aa12020-09-19 18:50:13 +0200226. Future work: classes |vim9-classes|
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010023
249. Rationale |vim9-rationale|
25
26==============================================================================
27
Bram Moolenaar2b327002020-12-26 15:39:31 +0100281. What is Vim9 script? *Vim9-script*
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010029
30THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
31
Bram Moolenaar7ceefb32020-05-01 16:07:38 +020032Vim script has been growing over time, while preserving backwards
33compatibility. That means bad choices from the past often can't be changed
Bram Moolenaar73fef332020-06-21 22:12:03 +020034and compatibility with Vi restricts possible solutions. Execution is quite
Bram Moolenaar7ceefb32020-05-01 16:07:38 +020035slow, each line is parsed every time it is executed.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010036
Bram Moolenaar7ceefb32020-05-01 16:07:38 +020037The main goal of Vim9 script is to drastically improve performance. This is
38accomplished by compiling commands into instructions that can be efficiently
39executed. An increase in execution speed of 10 to 100 times can be expected.
40
41A secondary goal is to avoid Vim-specific constructs and get closer to
42commonly used programming languages, such as JavaScript, TypeScript and Java.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010043
44The performance improvements can only be achieved by not being 100% backwards
Bram Moolenaar388a5d42020-05-26 21:20:45 +020045compatible. For example, making function arguments available in the
46"a:" dictionary adds quite a lot of overhead. In a Vim9 function this
47dictionary is not available. Other differences are more subtle, such as how
48errors are handled.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010049
50The Vim9 script syntax and semantics are used in:
51- a function defined with the `:def` command
52- a script file where the first command is `vim9script`
Bram Moolenaar1d59aa12020-09-19 18:50:13 +020053- an autocommand defined in the context of the above
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010054
55When using `:function` in a Vim9 script file the legacy syntax is used.
Bram Moolenaar7ceefb32020-05-01 16:07:38 +020056However, this can be confusing and is therefore discouraged.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010057
Bram Moolenaar7ceefb32020-05-01 16:07:38 +020058Vim9 script and legacy Vim script can be mixed. There is no requirement to
Bram Moolenaar1d59aa12020-09-19 18:50:13 +020059rewrite old scripts, they keep working as before. You may want to use a few
60`:def` functions for code that needs to be fast.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010061
62==============================================================================
63
642. Differences from legacy Vim script *vim9-differences*
65
66THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
67
Bram Moolenaard58a3bf2020-09-28 21:48:16 +020068Overview ~
69
70Brief summary of the differences you will most often encounter when using Vim9
71script and `:def` functions; details are below:
72- Comments start with #, not ": >
73 echo "hello" # comment
74- Using a backslash for line continuation is hardly ever needed: >
75 echo "hello "
76 .. yourName
77 .. ", how are you?"
78- White space is required in many places.
79- Assign values without `:let`, declare variables with `:var`: >
80 var count = 0
81 count += 3
82- Constants can be declared with `:final` and `:const`: >
83 final matches = [] # add matches
84 const names = ['Betty', 'Peter'] # cannot be changed
85- `:final` cannot be used as an abbreviation of `:finally`.
86- Variables and functions are script-local by default.
87- Functions are declared with argument types and return type: >
88 def CallMe(count: number, message: string): bool
89- Call functions without `:call`: >
90 writefile(['done'], 'file.txt')
91- You cannot use `:xit`, `:t`, `:append`, `:change`, `:insert` or curly-braces
92 names.
93- A range before a command must be prefixed with a colon: >
94 :%s/this/that
95
96
Bram Moolenaar2c330432020-04-13 14:41:35 +020097Comments starting with # ~
98
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +020099In legacy Vim script comments start with double quote. In Vim9 script
100comments start with #. >
101 # declarations
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200102 var count = 0 # number of occurrences
Bram Moolenaar2c330432020-04-13 14:41:35 +0200103
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200104The reason is that a double quote can also be the start of a string. In many
Bram Moolenaar3d1cde82020-08-15 18:55:18 +0200105places, especially halfway through an expression with a line break, it's hard
106to tell what the meaning is, since both a string and a comment can be followed
107by arbitrary text. To avoid confusion only # comments are recognized. This
108is the same as in shell scripts and Python programs.
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200109
110In Vi # is a command to list text with numbers. In Vim9 script you can use
111`:number` for that. >
Bram Moolenaarae616492020-07-28 20:07:27 +0200112 101 number
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200113
114To improve readability there must be a space between a command and the #
Bram Moolenaar2b327002020-12-26 15:39:31 +0100115that starts a comment: >
116 var = value # comment
117 var = value# error!
118
119In legacy script # is also used for the alternate file name. In Vim9 script
120you need to use %% instead. Instead of ## use %%% (stands for all arguments).
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200121
Bram Moolenaar2c330432020-04-13 14:41:35 +0200122
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100123Vim9 functions ~
124
Bram Moolenaar7ceefb32020-05-01 16:07:38 +0200125A function defined with `:def` is compiled. Execution is many times faster,
126often 10x to 100x times.
127
Bram Moolenaar388a5d42020-05-26 21:20:45 +0200128Many errors are already found when compiling, before the function is executed.
Bram Moolenaar7ceefb32020-05-01 16:07:38 +0200129The syntax is strict, to enforce code that is easy to read and understand.
130
Bram Moolenaar1b884a02020-12-10 21:11:27 +0100131Compilation is done when either of these is encountered:
132- the first time the function is called
Bram Moolenaar207f0092020-08-30 17:20:20 +0200133- when the `:defcompile` command is encountered in the script where the
134 function was defined
135- `:disassemble` is used for the function.
136- a function that is compiled calls the function or uses it as a function
137 reference
Bram Moolenaar388a5d42020-05-26 21:20:45 +0200138
139`:def` has no options like `:function` does: "range", "abort", "dict" or
Bram Moolenaar1b884a02020-12-10 21:11:27 +0100140"closure". A `:def` function always aborts on an error (unless `:silent!` was
141used for the command or inside a `:try` block), does not get a range passed
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100142cannot be a "dict" function, and can always be a closure.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100143
Bram Moolenaar7ceefb32020-05-01 16:07:38 +0200144The argument types and return type need to be specified. The "any" type can
145be used, type checking will then be done at runtime, like with legacy
146functions.
147
Bram Moolenaar3d1cde82020-08-15 18:55:18 +0200148Arguments are accessed by name, without "a:", just like any other language.
149There is no "a:" dictionary or "a:000" list.
Bram Moolenaar7ceefb32020-05-01 16:07:38 +0200150
151Variable arguments are defined as the last argument, with a name and have a
Bram Moolenaar3d1cde82020-08-15 18:55:18 +0200152list type, similar to TypeScript. For example, a list of numbers: >
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200153 def MyFunc(...itemlist: list<number>)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100154 for item in itemlist
155 ...
156
157
Bram Moolenaar7ceefb32020-05-01 16:07:38 +0200158Functions and variables are script-local by default ~
Bram Moolenaar65e0d772020-06-14 17:29:55 +0200159 *vim9-scopes*
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200160When using `:function` or `:def` to specify a new function at the script level
161in a Vim9 script, the function is local to the script, as if "s:" was
Bram Moolenaar2bb26582020-10-03 22:52:39 +0200162prefixed. Using the "s:" prefix is optional. To define a global function or
163variable the "g:" prefix must be used. For functions in an autoload script
164the "name#" prefix is sufficient. >
Bram Moolenaarea2d8d22020-07-29 22:11:05 +0200165 def ThisFunction() # script-local
166 def s:ThisFunction() # script-local
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200167 def g:ThatFunction() # global
Bram Moolenaarea2d8d22020-07-29 22:11:05 +0200168 def scriptname#function() # autoload
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200169
Bram Moolenaar2bb26582020-10-03 22:52:39 +0200170When using `:function` or `:def` to specify a nested function inside a `:def`
171function, this nested function is local to the code block it is defined in.
Bram Moolenaar4f4d51a2020-10-11 13:57:40 +0200172In a `:def` function it is not possible to define a script-local function. It
Bram Moolenaar2bb26582020-10-03 22:52:39 +0200173is possible to define a global function by using the "g:" prefix.
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200174
175When referring to a function and no "s:" or "g:" prefix is used, Vim will
Bram Moolenaar13106602020-10-04 16:06:05 +0200176search for the function:
Bram Moolenaar4f4d51a2020-10-11 13:57:40 +0200177- in the function scope, in block scopes
Bram Moolenaar13106602020-10-04 16:06:05 +0200178- in the script scope, possibly imported
179- in the list of global functions
180However, it is recommended to always use "g:" to refer to a global function
181for clarity.
182
183In all cases the function must be defined before used. That is when it is
Bram Moolenaarcb80aa22020-10-26 21:12:46 +0100184called, when `:defcompile` causes it to be compiled, or when code that calls
185it is being compiled (to figure out the return type).
Bram Moolenaar7ceefb32020-05-01 16:07:38 +0200186
Bram Moolenaare7b1ea02020-08-07 19:54:59 +0200187The result is that functions and variables without a namespace can usually be
Bram Moolenaar7ceefb32020-05-01 16:07:38 +0200188found in the script, either defined there or imported. Global functions and
Bram Moolenaare7b1ea02020-08-07 19:54:59 +0200189variables could be defined anywhere (good luck finding out where!).
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200190
Bram Moolenaar3d1cde82020-08-15 18:55:18 +0200191Global functions can still be defined and deleted at nearly any time. In
Bram Moolenaar2cfb4a22020-05-07 18:56:00 +0200192Vim9 script script-local functions are defined once when the script is sourced
Bram Moolenaar388a5d42020-05-26 21:20:45 +0200193and cannot be deleted or replaced.
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200194
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100195When compiling a function and a function call is encountered for a function
196that is not (yet) defined, the |FuncUndefined| autocommand is not triggered.
197You can use an autoload function if needed, or call a legacy function and have
198|FuncUndefined| triggered there.
199
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200200
Bram Moolenaar2b327002020-12-26 15:39:31 +0100201Reloading a Vim9 script clears functions and variables by default ~
202 *vim9-reload*
203When loading a legacy Vim script a second time nothing is removed, the
204commands will replace existing variables and functions and create new ones.
205
206When loading a Vim9 script a second time all existing script-local functions
207and variables are deleted, thus you start with a clean slate. This is useful
208if you are developing a plugin and want to try a new version. If you renamed
209something you don't have to worry about the old name still hanging around.
210
211If you do want to keep items, use: >
212 vimscript noclear
213
214You want to use this in scripts that use a `finish` command to bail out at
215some point when loaded again. E.g. when a buffer local option is set: >
216 vimscript noclear
217 setlocal completefunc=SomeFunc
218 if exists('*SomeFunc') | finish | endif
219 def g:SomeFunc()
220 ....
221
Bram Moolenaar2b327002020-12-26 15:39:31 +0100222
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200223Variable declarations with :var, :final and :const ~
Bram Moolenaar2bb26582020-10-03 22:52:39 +0200224 *vim9-declaration* *:var*
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200225Local variables need to be declared with `:var`. Local constants need to be
226declared with `:final` or `:const`. We refer to both as "variables" in this
227section.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100228
229Variables can be local to a script, function or code block: >
230 vim9script
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200231 var script_var = 123
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100232 def SomeFunc()
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200233 var func_var = script_var
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100234 if cond
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200235 var block_var = func_var
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100236 ...
237
238The variables are only visible in the block where they are defined and nested
239blocks. Once the block ends the variable is no longer accessible: >
240 if cond
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200241 var inner = 5
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100242 else
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200243 var inner = 0
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100244 endif
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200245 echo inner # Error!
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100246
247The declaration must be done earlier: >
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200248 var inner: number
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100249 if cond
250 inner = 5
251 else
252 inner = 0
253 endif
254 echo inner
255
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200256To intentionally hide a variable from code that follows, a block can be
257used: >
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100258 {
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200259 var temp = 'temp'
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100260 ...
261 }
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200262 echo temp # Error!
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100263
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200264Declaring a variable with a type but without an initializer will initialize to
265zero, false or empty.
266
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200267In Vim9 script `:let` cannot be used. An existing variable is assigned to
268without any command. The same for global, window, tab, buffer and Vim
269variables, because they are not really declared. They can also be deleted
Bram Moolenaarf5a48012020-08-01 17:00:03 +0200270with `:unlet`.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100271
Bram Moolenaare7b1ea02020-08-07 19:54:59 +0200272Variables and functions cannot shadow previously defined or imported variables
273and functions.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100274Variables may shadow Ex commands, rename the variable if needed.
275
Bram Moolenaar7ceefb32020-05-01 16:07:38 +0200276Global variables and user defined functions must be prefixed with "g:", also
277at the script level. >
Bram Moolenaard1caa942020-04-10 22:10:56 +0200278 vim9script
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200279 var script_local = 'text'
Bram Moolenaar2547aa92020-07-26 17:00:44 +0200280 g:global = 'value'
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200281 var Funcref = g:ThatFunction
Bram Moolenaard1caa942020-04-10 22:10:56 +0200282
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200283Since `&opt = value` is now assigning a value to option "opt", ":&" cannot be
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100284used to repeat a `:substitute` command.
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200285
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200286
287Constants ~
288 *vim9-const* *vim9-final*
289How constants work varies between languages. Some consider a variable that
290can't be assigned another value a constant. JavaScript is an example. Others
291also make the value immutable, thus when a constant uses a list, the list
292cannot be changed. In Vim9 we can use both.
293
294`:const` is used for making both the variable and the value a constant. Use
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200295this for composite structures that you want to make sure will not be modified.
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200296Example: >
297 const myList = [1, 2]
298 myList = [3, 4] # Error!
299 myList[0] = 9 # Error!
300 muList->add(3) # Error!
Bram Moolenaar2bb26582020-10-03 22:52:39 +0200301< *:final*
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200302`:final` is used for making only the variable a constant, the value can be
303changed. This is well known from Java. Example: >
304 final myList = [1, 2]
305 myList = [3, 4] # Error!
306 myList[0] = 9 # OK
307 muList->add(3) # OK
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200308
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200309It is common to write constants as ALL_CAPS, but you don't have to.
310
311The constant only applies to the value itself, not what it refers to. >
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200312 final females = ["Mary"]
313 const NAMES = [["John", "Peter"], females]
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200314 NAMES[0] = ["Jack"] # Error!
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200315 NAMES[0][0] = "Jack" # Error!
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200316 NAMES[1] = ["Emma"] # Error!
317 Names[1][0] = "Emma" # OK, now females[0] == "Emma"
318
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200319< *E1092*
Bram Moolenaar2547aa92020-07-26 17:00:44 +0200320Declaring more than one variable at a time, using the unpack notation, is
321currently not supported: >
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200322 var [v1, v2] = GetValues() # Error!
Bram Moolenaar2547aa92020-07-26 17:00:44 +0200323That is because the type needs to be inferred from the list item type, which
324isn't that easy.
325
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100326
327Omitting :call and :eval ~
328
329Functions can be called without `:call`: >
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200330 writefile(lines, 'file')
Bram Moolenaar560979e2020-02-04 22:53:05 +0100331Using `:call` is still possible, but this is discouraged.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100332
333A method call without `eval` is possible, so long as the start is an
Bram Moolenaarae616492020-07-28 20:07:27 +0200334identifier or can't be an Ex command. Examples: >
335 myList->add(123)
336 g:myList->add(123)
337 [1, 2, 3]->Process()
Bram Moolenaar2bede172020-11-19 18:53:18 +0100338 {a: 1, b: 2}->Process()
Bram Moolenaarae616492020-07-28 20:07:27 +0200339 "foobar"->Process()
340 ("foobar")->Process()
341 'foobar'->Process()
342 ('foobar')->Process()
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100343
Bram Moolenaar3d1cde82020-08-15 18:55:18 +0200344In the rare case there is ambiguity between a function name and an Ex command,
Bram Moolenaare7b1ea02020-08-07 19:54:59 +0200345prepend ":" to make clear you want to use the Ex command. For example, there
346is both the `:substitute` command and the `substitute()` function. When the
347line starts with `substitute(` this will use the function. Prepend a colon to
348use the command instead: >
Bram Moolenaar0c6ceaf2020-02-22 18:36:32 +0100349 :substitute(pattern (replacement (
Bram Moolenaar5b1c8fe2020-02-21 18:42:43 +0100350
Bram Moolenaarcc390ff2020-02-29 22:06:30 +0100351Note that while variables need to be defined before they can be used,
Bram Moolenaar3d1cde82020-08-15 18:55:18 +0200352functions can be called before being defined. This is required to allow
353for cyclic dependencies between functions. It is slightly less efficient,
Bram Moolenaarcc390ff2020-02-29 22:06:30 +0100354since the function has to be looked up by name. And a typo in the function
Bram Moolenaarae616492020-07-28 20:07:27 +0200355name will only be found when the function is called.
Bram Moolenaarcc390ff2020-02-29 22:06:30 +0100356
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100357
Bram Moolenaard1caa942020-04-10 22:10:56 +0200358Omitting function() ~
359
360A user defined function can be used as a function reference in an expression
361without `function()`. The argument types and return type will then be checked.
362The function must already have been defined. >
363
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200364 var Funcref = MyFunction
Bram Moolenaard1caa942020-04-10 22:10:56 +0200365
366When using `function()` the resulting type is "func", a function with any
367number of arguments and any return type. The function can be defined later.
368
369
Bram Moolenaar2b327002020-12-26 15:39:31 +0100370Lambda using => instead of -> ~
Bram Moolenaar65c44152020-12-24 15:14:01 +0100371
372In legacy script there can be confusion between using "->" for a method call
373and for a lambda. Also, when a "{" is found the parser needs to figure out if
374it is the start of a lambda or a dictionary, which is now more complicated
375because of the use of argument types.
376
377To avoid these problems Vim9 script uses a different syntax for a lambda,
378which is similar to Javascript: >
379 var Lambda = (arg) => expression
380
Bram Moolenaar2b327002020-12-26 15:39:31 +0100381No line break is allowed in the arguments of a lambda up to and including the
Bram Moolenaar65c44152020-12-24 15:14:01 +0100382"=>". This is OK: >
383 filter(list, (k, v) =>
384 v > 0)
385This does not work: >
386 filter(list, (k, v)
387 => v > 0)
388This also does not work:
389 filter(list, (k,
390 v) => v > 0)
391
392Additionally, a lambda can contain statements in {}: >
393 var Lambda = (arg) => {
394 g:was_called = 'yes'
395 return expression
396 }
397NOT IMPLEMENTED YET
398
Bram Moolenaar2b327002020-12-26 15:39:31 +0100399To avoid the "{" of a dictionary literal to be recognized as a statement block
400wrap it in parenthesis: >
401 var Lambda = (arg) => ({key: 42})
Bram Moolenaar65c44152020-12-24 15:14:01 +0100402
403
Bram Moolenaar4fdae992020-04-12 16:38:57 +0200404Automatic line continuation ~
405
406In many cases it is obvious that an expression continues on the next line. In
Bram Moolenaare7b1ea02020-08-07 19:54:59 +0200407those cases there is no need to prefix the line with a backslash
408|line-continuation|. For example, when a list spans multiple lines: >
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200409 var mylist = [
Bram Moolenaar4fdae992020-04-12 16:38:57 +0200410 'one',
411 'two',
412 ]
Bram Moolenaare6085c52020-04-12 20:19:16 +0200413And when a dict spans multiple lines: >
Bram Moolenaar2bede172020-11-19 18:53:18 +0100414 var mydict = {
Bram Moolenaare6085c52020-04-12 20:19:16 +0200415 one: 1,
416 two: 2,
417 }
418Function call: >
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200419 var result = Func(
Bram Moolenaare6085c52020-04-12 20:19:16 +0200420 arg1,
421 arg2
422 )
423
Bram Moolenaardf069ee2020-06-22 23:02:51 +0200424For binary operators in expressions not in [], {} or () a line break is
425possible just before or after the operator. For example: >
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200426 var text = lead
Bram Moolenaardf069ee2020-06-22 23:02:51 +0200427 .. middle
428 .. end
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200429 var total = start +
Bram Moolenaar9c7e6dd2020-04-12 20:55:20 +0200430 end -
431 correction
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200432 var result = positive
Bram Moolenaardf069ee2020-06-22 23:02:51 +0200433 ? PosFunc(arg)
434 : NegFunc(arg)
Bram Moolenaar9c7e6dd2020-04-12 20:55:20 +0200435
Bram Moolenaar2547aa92020-07-26 17:00:44 +0200436For a method call using "->" and a member using a dot, a line break is allowed
437before it: >
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200438 var result = GetBuilder()
Bram Moolenaar73fef332020-06-21 22:12:03 +0200439 ->BuilderSetWidth(333)
440 ->BuilderSetHeight(777)
441 ->BuilderBuild()
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200442 var result = MyDict
Bram Moolenaar2547aa92020-07-26 17:00:44 +0200443 .member
Bram Moolenaar73fef332020-06-21 22:12:03 +0200444
Bram Moolenaardf069ee2020-06-22 23:02:51 +0200445< *E1050*
446To make it possible for the operator at the start of the line to be
Bram Moolenaar7ff78462020-07-10 22:00:53 +0200447recognized, it is required to put a colon before a range. This will add
Bram Moolenaardf069ee2020-06-22 23:02:51 +0200448"start" and print: >
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200449 var result = start
Bram Moolenaardf069ee2020-06-22 23:02:51 +0200450 + print
Bram Moolenaar7ff78462020-07-10 22:00:53 +0200451Like this: >
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200452 var result = start + print
Bram Moolenaar7ff78462020-07-10 22:00:53 +0200453
Bram Moolenaardf069ee2020-06-22 23:02:51 +0200454This will assign "start" and print a line: >
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200455 var result = start
Bram Moolenaardf069ee2020-06-22 23:02:51 +0200456 :+ print
Bram Moolenaar4fdae992020-04-12 16:38:57 +0200457
Bram Moolenaar23515b42020-11-29 14:36:24 +0100458Note that the colon is not required for the |+cmd| argument: >
459 edit +6 fname
460
Bram Moolenaar5e774c72020-04-12 21:53:00 +0200461It is also possible to split a function header over multiple lines, in between
462arguments: >
463 def MyFunc(
464 text: string,
465 separator = '-'
466 ): string
467
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100468Since a continuation line cannot be easily recognized the parsing of commands
Bram Moolenaar65c44152020-12-24 15:14:01 +0100469has been made stricter. E.g., because of the error in the first line, the
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100470second line is seen as a separate command: >
471 popup_create(some invalid expression, {
472 exit_cb: Func})
473Now "exit_cb: Func})" is actually a valid command: save any changes to the
474file "_cb: Func})" and exit. To avoid this kind of mistake in Vim9 script
475there must be white space between most command names and the argument.
476
477
Bram Moolenaar7ff78462020-07-10 22:00:53 +0200478Notes:
479- "enddef" cannot be used at the start of a continuation line, it ends the
480 current function.
481- No line break is allowed in the LHS of an assignment. Specifically when
482 unpacking a list |:let-unpack|. This is OK: >
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200483 [var1, var2] =
Bram Moolenaar7ff78462020-07-10 22:00:53 +0200484 Func()
485< This does not work: >
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200486 [var1,
Bram Moolenaar7ff78462020-07-10 22:00:53 +0200487 var2] =
488 Func()
489- No line break is allowed in between arguments of an `:echo`, `:execute` and
490 similar commands. This is OK: >
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200491 echo [1,
Bram Moolenaar7ff78462020-07-10 22:00:53 +0200492 2] [3,
493 4]
494< This does not work: >
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200495 echo [1, 2]
Bram Moolenaar7ff78462020-07-10 22:00:53 +0200496 [3, 4]
Bram Moolenaar4fdae992020-04-12 16:38:57 +0200497
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100498No curly braces expansion ~
499
500|curly-braces-names| cannot be used.
501
502
Bram Moolenaar2bede172020-11-19 18:53:18 +0100503Dictionary literals ~
504
505Traditionally Vim has supported dictionary literals with a {} syntax: >
506 let dict = {'key': value}
507
Bram Moolenaarc5e6a712020-12-04 19:12:14 +0100508Later it became clear that using a simple text key is very common, thus
509literal dictionaries were introduced in a backwards compatible way: >
Bram Moolenaar2bede172020-11-19 18:53:18 +0100510 let dict = #{key: value}
511
Bram Moolenaarc5e6a712020-12-04 19:12:14 +0100512However, this #{} syntax is unlike any existing language. As it turns out
513that using a literal key is much more common than using an expression, and
Bram Moolenaar2bede172020-11-19 18:53:18 +0100514considering that JavaScript uses this syntax, using the {} form for dictionary
Bram Moolenaarc5e6a712020-12-04 19:12:14 +0100515literals is considered a much more useful syntax. In Vim9 script the {} form
Bram Moolenaar2bede172020-11-19 18:53:18 +0100516uses literal keys: >
517 let dict = {key: value}
518
Bram Moolenaarc5e6a712020-12-04 19:12:14 +0100519This works for alphanumeric characters, underscore and dash. If you want to
520use another character, use a single or double quoted string: >
521 let dict = {'key with space': value}
522 let dict = {"key\twith\ttabs": value}
523 let dict = {'': value} # empty key
524
525In case the key needs to be an expression, square brackets can be used, just
526like in JavaScript: >
Bram Moolenaar2bede172020-11-19 18:53:18 +0100527 let dict = {["key" .. nr]: value}
528
529
Bram Moolenaarf5a48012020-08-01 17:00:03 +0200530No :xit, :t, :append, :change or :insert ~
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100531
Bram Moolenaarf5a48012020-08-01 17:00:03 +0200532These commands are too easily confused with local variable names.
533Instead of `:x` or `:xit` you can use `:exit`.
534Instead of `:t` you can use `:copy`.
Bram Moolenaar560979e2020-02-04 22:53:05 +0100535
536
537Comparators ~
538
539The 'ignorecase' option is not used for comparators that use strings.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100540
541
542White space ~
543
544Vim9 script enforces proper use of white space. This is no longer allowed: >
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200545 var name=234 # Error!
546 var name= 234 # Error!
547 var name =234 # Error!
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100548There must be white space before and after the "=": >
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200549 var name = 234 # OK
Bram Moolenaar7ff78462020-07-10 22:00:53 +0200550White space must also be put before the # that starts a comment after a
551command: >
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200552 var name = 234# Error!
553 var name = 234 # OK
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100554
555White space is required around most operators.
556
557White space is not allowed:
558- Between a function name and the "(": >
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200559 call Func (arg) # Error!
560 call Func
561 \ (arg) # Error!
562 call Func(arg) # OK
563 call Func(
564 \ arg) # OK
565 call Func(
566 \ arg # OK
Bram Moolenaar5b1c8fe2020-02-21 18:42:43 +0100567 \ )
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100568
569
570Conditions and expressions ~
571
Bram Moolenaar13106602020-10-04 16:06:05 +0200572Conditions and expressions are mostly working like they do in other languages.
573Some values are different from legacy Vim script:
574 value legacy Vim script Vim9 script ~
575 0 falsy falsy
576 1 truthy truthy
577 99 truthy Error!
578 "0" falsy Error!
579 "99" truthy Error!
580 "text" falsy Error!
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100581
Bram Moolenaar13106602020-10-04 16:06:05 +0200582For the "??" operator and when using "!" then there is no error, every value
583is either falsy or truthy. This is mostly like JavaScript, except that an
584empty list and dict is falsy:
585
586 type truthy when ~
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +0200587 bool v:true or 1
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100588 number non-zero
589 float non-zero
590 string non-empty
591 blob non-empty
592 list non-empty (different from JavaScript)
593 dictionary non-empty (different from JavaScript)
Bram Moolenaard1caa942020-04-10 22:10:56 +0200594 func when there is a function name
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100595 special v:true
596 job when not NULL
597 channel when not NULL
598 class when not NULL
599 object when not NULL (TODO: when isTrue() returns v:true)
600
Bram Moolenaar2bb26582020-10-03 22:52:39 +0200601The boolean operators "||" and "&&" expect the values to be boolean, zero or
602one: >
603 1 || false == true
604 0 || 1 == true
605 0 || false == false
606 1 && true == true
607 0 && 1 == false
608 8 || 0 Error!
609 'yes' && 0 Error!
610 [] || 99 Error!
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100611
Bram Moolenaar2bb26582020-10-03 22:52:39 +0200612When using "!" for inverting, there is no error for using any type and the
Bram Moolenaar13106602020-10-04 16:06:05 +0200613result is a boolean. "!!" can be used to turn any value into boolean: >
Bram Moolenaar2bb26582020-10-03 22:52:39 +0200614 !'yes' == false
Bram Moolenaar13106602020-10-04 16:06:05 +0200615 !![] == false
616 !![1, 2, 3] == true
Bram Moolenaar2bb26582020-10-03 22:52:39 +0200617
618When using "`.."` for string concatenation arguments of simple types are
Bram Moolenaar13106602020-10-04 16:06:05 +0200619always converted to string: >
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100620 'hello ' .. 123 == 'hello 123'
Bram Moolenaar3d1cde82020-08-15 18:55:18 +0200621 'hello ' .. v:true == 'hello v:true'
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100622
Bram Moolenaar418f1df2020-08-12 21:34:49 +0200623Simple types are string, float, special and bool. For other types |string()|
624can be used.
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200625 *false* *true*
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100626In Vim9 script one can use "true" for v:true and "false" for v:false.
627
Bram Moolenaar3d1cde82020-08-15 18:55:18 +0200628Indexing a string with [idx] or [idx, idx] uses character indexes instead of
629byte indexes. Example: >
630 echo 'bár'[1]
631In legacy script this results in the character 0xc3 (an illegal byte), in Vim9
632script this results in the string 'á'.
633
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100634
Bram Moolenaare46a4402020-06-30 20:38:27 +0200635What to watch out for ~
636 *vim9-gotchas*
637Vim9 was designed to be closer to often used programming languages, but at the
638same time tries to support the legacy Vim commands. Some compromises had to
639be made. Here is a summary of what might be unexpected.
640
641Ex command ranges need to be prefixed with a colon. >
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200642 -> # legacy Vim: shifts the previous line to the right
643 ->func() # Vim9: method call in continuation line
644 :-> # Vim9: shifts the previous line to the right
Bram Moolenaare46a4402020-06-30 20:38:27 +0200645
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200646 %s/a/b # legacy Vim: substitute on all lines
Bram Moolenaare46a4402020-06-30 20:38:27 +0200647 x = alongname
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200648 % another # Vim9: line continuation without a backslash
649 :%s/a/b # Vim9: substitute on all lines
650 'text'->func() # Vim9: method call
651 :'t # legacy Vim: jump to mark m
Bram Moolenaare46a4402020-06-30 20:38:27 +0200652
Bram Moolenaare7b1ea02020-08-07 19:54:59 +0200653Some Ex commands can be confused with assignments in Vim9 script: >
654 g:name = value # assignment
655 g:pattern:cmd # invalid command - ERROR
656 :g:pattern:cmd # :global command
657
Bram Moolenaare46a4402020-06-30 20:38:27 +0200658Functions defined with `:def` compile the whole function. Legacy functions
659can bail out, and the following lines are not parsed: >
660 func Maybe()
661 if !has('feature')
662 return
663 endif
664 use-feature
665 endfunc
666Vim9 functions are compiled as a whole: >
667 def Maybe()
668 if !has('feature')
669 return
670 endif
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200671 use-feature # May give compilation error
Bram Moolenaare46a4402020-06-30 20:38:27 +0200672 enddef
673For a workaround, split it in two functions: >
674 func Maybe()
675 if has('feature')
676 call MaybyInner()
677 endif
678 endfunc
679 if has('feature')
680 def MaybeInner()
681 use-feature
682 enddef
683 endif
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200684Or put the unsupported code inside an `if` with a constant expression that
Bram Moolenaar207f0092020-08-30 17:20:20 +0200685evaluates to false: >
686 def Maybe()
687 if has('feature')
688 use-feature
689 endif
690 enddef
691Note that for unrecognized commands there is no check for "|" and a following
692command. This will give an error for missing `endif`: >
693 def Maybe()
694 if has('feature') | use-feature | endif
695 enddef
Bram Moolenaare46a4402020-06-30 20:38:27 +0200696
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100697Other differences ~
698
699Patterns are used like 'magic' is set, unless explicitly overruled.
700The 'edcompatible' option value is not used.
701The 'gdefault' option value is not used.
702
703
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100704==============================================================================
705
7063. New style functions *fast-functions*
707
708THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
709
710 *:def*
Bram Moolenaar3d1cde82020-08-15 18:55:18 +0200711:def[!] {name}([arguments])[: {return-type}]
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100712 Define a new function by the name {name}. The body of
713 the function follows in the next lines, until the
714 matching `:enddef`.
715
Bram Moolenaard77a8522020-04-03 21:59:57 +0200716 When {return-type} is omitted or is "void" the
717 function is not expected to return anything.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100718
719 {arguments} is a sequence of zero or more argument
720 declarations. There are three forms:
721 {name}: {type}
722 {name} = {value}
723 {name}: {type} = {value}
724 The first form is a mandatory argument, the caller
725 must always provide them.
726 The second and third form are optional arguments.
727 When the caller omits an argument the {value} is used.
728
Bram Moolenaar65e0d772020-06-14 17:29:55 +0200729 The function will be compiled into instructions when
Bram Moolenaar2547aa92020-07-26 17:00:44 +0200730 called, or when `:disassemble` or `:defcompile` is
731 used. Syntax and type errors will be produced at that
732 time.
Bram Moolenaar65e0d772020-06-14 17:29:55 +0200733
Bram Moolenaar2547aa92020-07-26 17:00:44 +0200734 It is possible to nest `:def` inside another `:def` or
735 `:function` up to about 50 levels deep.
Bram Moolenaar560979e2020-02-04 22:53:05 +0100736
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200737 [!] is used as with `:function`. Note that
738 script-local functions cannot be deleted or redefined
739 later in Vim9 script. They can only be removed by
740 reloading the same script.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100741
742 *:enddef*
Bram Moolenaar2547aa92020-07-26 17:00:44 +0200743:enddef End of a function defined with `:def`. It should be on
744 a line by its own.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100745
746
Bram Moolenaar5b1c8fe2020-02-21 18:42:43 +0100747If the script the function is defined in is Vim9 script, then script-local
748variables can be accessed without the "s:" prefix. They must be defined
Bram Moolenaar65e0d772020-06-14 17:29:55 +0200749before the function is compiled. If the script the function is defined in is
750legacy script, then script-local variables must be accessed with the "s:"
Bram Moolenaar207f0092020-08-30 17:20:20 +0200751prefix and they do not need to exist (they can be deleted any time).
Bram Moolenaar5b1c8fe2020-02-21 18:42:43 +0100752
Bram Moolenaar388a5d42020-05-26 21:20:45 +0200753 *:defc* *:defcompile*
754:defc[ompile] Compile functions defined in the current script that
755 were not compiled yet.
756 This will report errors found during the compilation.
Bram Moolenaar5b1c8fe2020-02-21 18:42:43 +0100757
Bram Moolenaarebdf3c92020-02-15 21:41:42 +0100758 *:disa* *:disassemble*
759:disa[ssemble] {func} Show the instructions generated for {func}.
760 This is for debugging and testing.
Bram Moolenaarcc390ff2020-02-29 22:06:30 +0100761 Note that for command line completion of {func} you
762 can prepend "s:" to find script-local functions.
Bram Moolenaarebdf3c92020-02-15 21:41:42 +0100763
Bram Moolenaar7ff78462020-07-10 22:00:53 +0200764Limitations ~
765
766Local variables will not be visible to string evaluation. For example: >
Bram Moolenaar2b327002020-12-26 15:39:31 +0100767 def MapList(): list<string>
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200768 var list = ['aa', 'bb', 'cc', 'dd']
Bram Moolenaar7ff78462020-07-10 22:00:53 +0200769 return range(1, 2)->map('list[v:val]')
770 enddef
771
772The map argument is a string expression, which is evaluated without the
773function scope. Instead, use a lambda: >
Bram Moolenaar2b327002020-12-26 15:39:31 +0100774 def MapList(): list<string>
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200775 var list = ['aa', 'bb', 'cc', 'dd']
Bram Moolenaar2b327002020-12-26 15:39:31 +0100776 return range(1, 2)->map(( _, v) => list[v])
Bram Moolenaar7ff78462020-07-10 22:00:53 +0200777 enddef
778
Bram Moolenaar2b327002020-12-26 15:39:31 +0100779The same is true for commands that are not compiled, such as `:global`.
780For these the backtick expansion can be used. Example: >
781 def Replace()
782 var newText = 'blah'
783 g/pattern/s/^/`=newText`/
784 enddef
Bram Moolenaar7ff78462020-07-10 22:00:53 +0200785
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100786==============================================================================
787
7884. Types *vim9-types*
789
790THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
791
792The following builtin types are supported:
793 bool
794 number
795 float
796 string
797 blob
Bram Moolenaard77a8522020-04-03 21:59:57 +0200798 list<{type}>
799 dict<{type}>
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100800 job
801 channel
Bram Moolenaarb17893a2020-03-14 08:19:51 +0100802 func
Bram Moolenaard1caa942020-04-10 22:10:56 +0200803 func: {type}
Bram Moolenaard77a8522020-04-03 21:59:57 +0200804 func({type}, ...)
805 func({type}, ...): {type}
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100806
807Not supported yet:
Bram Moolenaard77a8522020-04-03 21:59:57 +0200808 tuple<a: {type}, b: {type}, ...>
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100809
Bram Moolenaard77a8522020-04-03 21:59:57 +0200810These types can be used in declarations, but no value will have this type:
Bram Moolenaar2547aa92020-07-26 17:00:44 +0200811 {type}|{type} {not implemented yet}
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100812 void
813 any
814
Bram Moolenaard77a8522020-04-03 21:59:57 +0200815There is no array type, use list<{type}> instead. For a list constant an
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100816efficient implementation is used that avoids allocating lot of small pieces of
817memory.
818
Bram Moolenaard77a8522020-04-03 21:59:57 +0200819A partial and function can be declared in more or less specific ways:
820func any kind of function reference, no type
Bram Moolenaard1caa942020-04-10 22:10:56 +0200821 checking for arguments or return value
Bram Moolenaard77a8522020-04-03 21:59:57 +0200822func: {type} any number and type of arguments with specific
823 return type
Bram Moolenaard1caa942020-04-10 22:10:56 +0200824func({type}) function with argument type, does not return
Bram Moolenaard77a8522020-04-03 21:59:57 +0200825 a value
Bram Moolenaard1caa942020-04-10 22:10:56 +0200826func({type}): {type} function with argument type and return type
827func(?{type}) function with type of optional argument, does
828 not return a value
829func(...{type}) function with type of variable number of
830 arguments, does not return a value
831func({type}, ?{type}, ...{type}): {type}
832 function with:
833 - type of mandatory argument
834 - type of optional argument
835 - type of variable number of arguments
836 - return type
Bram Moolenaard77a8522020-04-03 21:59:57 +0200837
838If the return type is "void" the function does not return a value.
839
840The reference can also be a |Partial|, in which case it stores extra arguments
841and/or a dictionary, which are not visible to the caller. Since they are
842called in the same way the declaration is the same.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100843
844Custom types can be defined with `:type`: >
845 :type MyList list<string>
Bram Moolenaar127542b2020-08-09 17:22:04 +0200846Custom types must start with a capital letter, to avoid name clashes with
847builtin types added later, similarly to user functions.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100848{not implemented yet}
849
850And classes and interfaces can be used as types: >
851 :class MyClass
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200852 :var mine: MyClass
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100853
854 :interface MyInterface
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200855 :var mine: MyInterface
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100856
857 :class MyTemplate<Targ>
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200858 :var mine: MyTemplate<number>
859 :var mine: MyTemplate<string>
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100860
861 :class MyInterface<Targ>
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200862 :var mine: MyInterface<number>
863 :var mine: MyInterface<string>
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100864{not implemented yet}
865
866
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200867Variable types and type casting ~
868 *variable-types*
Bram Moolenaar64d662d2020-08-09 19:02:50 +0200869Variables declared in Vim9 script or in a `:def` function have a type, either
870specified explicitly or inferred from the initialization.
871
872Global, buffer, window and tab page variables do not have a specific type, the
873value can be changed at any time, possibly changing the type. Therefore, in
874compiled code the "any" type is assumed.
875
876This can be a problem when the "any" type is undesired and the actual type is
877expected to always be the same. For example, when declaring a list: >
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200878 var l: list<number> = [1, g:two]
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100879At compile time Vim doesn't know the type of "g:two" and the expression type
880becomes list<any>. An instruction is generated to check the list type before
881doing the assignment, which is a bit inefficient.
882 *type-casting*
883To avoid this, use a type cast: >
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200884 var l: list<number> = [1, <number>g:two]
Bram Moolenaar4072ba52020-12-23 13:56:35 +0100885The compiled code will then only check that "g:two" is a number and give an
886error if it isn't. This is called type casting.
Bram Moolenaar64d662d2020-08-09 19:02:50 +0200887
888The syntax of a type cast is: "<" {type} ">". There cannot be white space
889after the "<" or before the ">" (to avoid them being confused with
890smaller-than and bigger-than operators).
891
892The semantics is that, if needed, a runtime type check is performed. The
893value is not actually changed. If you need to change the type, e.g. to change
894it to a string, use the |string()| function. Or use |str2nr()| to convert a
895string to a number.
896
897
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200898Type inference ~
899 *type-inference*
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100900In general: Whenever the type is clear it can be omitted. For example, when
901declaring a variable and giving it a value: >
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200902 var name = 0 # infers number type
903 var name = 'hello' # infers string type
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100904
Bram Moolenaar127542b2020-08-09 17:22:04 +0200905The type of a list and dictionary comes from the common type of the values.
906If the values all have the same type, that type is used for the list or
907dictionary. If there is a mix of types, the "any" type is used. >
908 [1, 2, 3] list<number>
909 ['a', 'b', 'c'] list<string>
910 [1, 'x', 3] list<any>
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100911
Bram Moolenaar207f0092020-08-30 17:20:20 +0200912
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200913Stricter type checking ~
914 *type-checking*
Bram Moolenaar207f0092020-08-30 17:20:20 +0200915In legacy Vim script, where a number was expected, a string would be
916automatically converted to a number. This was convenient for an actual number
917such as "123", but leads to unexpected problems (but no error message) if the
918string doesn't start with a number. Quite often this leads to hard-to-find
919bugs.
920
921In Vim9 script this has been made stricter. In most places it works just as
Bram Moolenaar1c6737b2020-09-07 22:18:52 +0200922before, if the value used matches the expected type. There will sometimes be
923an error, thus breaking backwards compatibility. For example:
Bram Moolenaar207f0092020-08-30 17:20:20 +0200924- Using a number other than 0 or 1 where a boolean is expected. *E1023*
925- Using a string value when setting a number options.
926- Using a number where a string is expected. *E1024*
927
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100928==============================================================================
929
Bram Moolenaar30fd8202020-09-26 15:09:30 +02009305. Namespace, Import and Export
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100931 *vim9script* *vim9-export* *vim9-import*
932
933THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
934
935A Vim9 script can be written to be imported. This means that everything in
936the script is local, unless exported. Those exported items, and only those
937items, can then be imported in another script.
938
Bram Moolenaar207f0092020-08-30 17:20:20 +0200939You can cheat by using the global namespace explicitly. We will assume here
940that you don't do that.
941
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100942
943Namespace ~
944 *:vim9script* *:vim9*
Bram Moolenaar560979e2020-02-04 22:53:05 +0100945To recognize a file that can be imported the `vim9script` statement must
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100946appear as the first statement in the file. It tells Vim to interpret the
947script in its own namespace, instead of the global namespace. If a file
948starts with: >
949 vim9script
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200950 var myvar = 'yes'
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100951Then "myvar" will only exist in this file. While without `vim9script` it would
952be available as `g:myvar` from any other script and function.
953
954The variables at the file level are very much like the script-local "s:"
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200955variables in legacy Vim script, but the "s:" is omitted. And they cannot be
956deleted.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100957
Bram Moolenaar2c7f8c52020-04-20 19:52:53 +0200958In Vim9 script the global "g:" namespace can still be used as before. And the
959"w:", "b:" and "t:" namespaces. These have in common that variables are not
960declared and they can be deleted.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100961
962A side effect of `:vim9script` is that the 'cpoptions' option is set to the
963Vim default value, like with: >
964 :set cpo&vim
965One of the effects is that |line-continuation| is always enabled.
966The original value of 'cpoptions' is restored at the end of the script.
967
968
969Export ~
970 *:export* *:exp*
Bram Moolenaar2547aa92020-07-26 17:00:44 +0200971Exporting an item can be written as: >
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100972 export const EXPORTED_CONST = 1234
Bram Moolenaar30fd8202020-09-26 15:09:30 +0200973 export var someValue = ...
974 export final someValue = ...
975 export const someValue = ...
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100976 export def MyFunc() ...
977 export class MyClass ...
978
979As this suggests, only constants, variables, `:def` functions and classes can
Bram Moolenaar2547aa92020-07-26 17:00:44 +0200980be exported. {classes are not implemented yet}
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100981
Bram Moolenaar65e0d772020-06-14 17:29:55 +0200982 *E1042*
983`:export` can only be used in Vim9 script, at the script level.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100984
985
986Import ~
Bram Moolenaar73fef332020-06-21 22:12:03 +0200987 *:import* *:imp* *E1094*
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100988The exported items can be imported individually in another Vim9 script: >
989 import EXPORTED_CONST from "thatscript.vim"
990 import MyClass from "myclass.vim"
991
992To import multiple items at the same time: >
993 import {someValue, MyClass} from "thatscript.vim"
994
Bram Moolenaar560979e2020-02-04 22:53:05 +0100995In case the name is ambiguous, another name can be specified: >
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100996 import MyClass as ThatClass from "myclass.vim"
997 import {someValue, MyClass as ThatClass} from "myclass.vim"
998
999To import all exported items under a specific identifier: >
1000 import * as That from 'thatscript.vim'
1001
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02001002{not implemented yet: using "This as That"}
1003
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001004Then you can use "That.EXPORTED_CONST", "That.someValue", etc. You are free
1005to choose the name "That", but it is highly recommended to use the name of the
1006script file to avoid confusion.
1007
Bram Moolenaar1c6737b2020-09-07 22:18:52 +02001008`:import` can also be used in legacy Vim script. The imported items still
1009become script-local, even when the "s:" prefix is not given.
1010
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001011The script name after `import` can be:
1012- A relative path, starting "." or "..". This finds a file relative to the
1013 location of the script file itself. This is useful to split up a large
1014 plugin into several files.
1015- An absolute path, starting with "/" on Unix or "D:/" on MS-Windows. This
Bram Moolenaarcb80aa22020-10-26 21:12:46 +01001016 will rarely be used.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001017- A path not being relative or absolute. This will be found in the
1018 "import" subdirectories of 'runtimepath' entries. The name will usually be
1019 longer and unique, to avoid loading the wrong file.
1020
1021Once a vim9 script file has been imported, the result is cached and used the
1022next time the same script is imported. It will not be read again.
1023 *:import-cycle*
1024The `import` commands are executed when encountered. If that script (directly
1025or indirectly) imports the current script, then items defined after the
1026`import` won't be processed yet. Therefore cyclic imports can exist, but may
1027result in undefined items.
1028
1029
1030Import in an autoload script ~
1031
1032For optimal startup speed, loading scripts should be postponed until they are
Bram Moolenaar560979e2020-02-04 22:53:05 +01001033actually needed. A recommended mechanism:
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001034
10351. In the plugin define user commands, functions and/or mappings that refer to
1036 an autoload script. >
1037 command -nargs=1 SearchForStuff call searchfor#Stuff(<f-args>)
1038
1039< This goes in .../plugin/anyname.vim. "anyname.vim" can be freely chosen.
1040
Bram Moolenaar3d1cde82020-08-15 18:55:18 +020010412. In the autoload script do the actual work. You can import items from
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001042 other files to split up functionality in appropriate pieces. >
1043 vim9script
1044 import FilterFunc from "../import/someother.vim"
1045 def searchfor#Stuff(arg: string)
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001046 var filtered = FilterFunc(arg)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001047 ...
1048< This goes in .../autoload/searchfor.vim. "searchfor" in the file name
1049 must be exactly the same as the prefix for the function name, that is how
1050 Vim finds the file.
1051
10523. Other functionality, possibly shared between plugins, contains the exported
1053 items and any private items. >
1054 vim9script
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001055 var localVar = 'local'
Bram Moolenaar1c6737b2020-09-07 22:18:52 +02001056 export def FilterFunc(arg: string): string
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001057 ...
1058< This goes in .../import/someother.vim.
1059
Bram Moolenaar418f1df2020-08-12 21:34:49 +02001060When compiling a `:def` function and a function in an autoload script is
1061encountered, the script is not loaded until the `:def` function is called.
1062
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001063
1064Import in legacy Vim script ~
1065
Bram Moolenaar65e0d772020-06-14 17:29:55 +02001066If an `import` statement is used in legacy Vim script, the script-local "s:"
1067namespace will be used for the imported item, even when "s:" is not specified.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001068
1069
1070==============================================================================
1071
Bram Moolenaar1d59aa12020-09-19 18:50:13 +020010726. Future work: classes *vim9-classes*
1073
1074Above "class" was mentioned a few times, but it has not been implemented yet.
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001075Most of Vim9 script can be created without this functionality, and since
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02001076implementing classes is going to be a lot of work, it is left for the future.
1077For now we'll just make sure classes can be added later.
1078
1079Thoughts:
1080- `class` / `endclass`, everything in one file
1081- Class names are always CamelCase
1082- Single constructor
1083- Single inheritance with `class ThisClass extends BaseClass`
1084- `abstract class`
1085- `interface` (Abstract class without any implementation)
1086- `class SomeClass implements SomeInterface`
1087- Generics for class: `class <Tkey, Tentry>`
1088- Generics for function: `def <Tkey> GetLast(key: Tkey)`
1089
1090Again, much of this is from TypeScript.
1091
1092Some things that look like good additions:
1093- Use a class as an interface (like Dart)
1094- Extend a class with methods, using an import (like Dart)
1095
1096An important class that will be provided is "Promise". Since Vim is single
1097threaded, connecting asynchronous operations is a natural way of allowing
1098plugins to do their work without blocking the user. It's a uniform way to
1099invoke callbacks and handle timeouts and errors.
1100
1101==============================================================================
1102
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010011039. Rationale *vim9-rationale*
1104
1105The :def command ~
1106
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001107Plugin writers have asked for much faster Vim script. Investigations have
Bram Moolenaar560979e2020-02-04 22:53:05 +01001108shown that keeping the existing semantics of function calls make this close to
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001109impossible, because of the overhead involved with calling a function, setting
1110up the local function scope and executing lines. There are many details that
1111need to be handled, such as error messages and exceptions. The need to create
1112a dictionary for a: and l: scopes, the a:000 list and several others add too
1113much overhead that cannot be avoided.
1114
1115Therefore the `:def` method to define a new-style function had to be added,
1116which allows for a function with different semantics. Most things still work
1117as before, but some parts do not. A new way to define a function was
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001118considered the best way to separate the legacy style code from Vim9 style code.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001119
1120Using "def" to define a function comes from Python. Other languages use
1121"function" which clashes with legacy Vim script.
1122
1123
1124Type checking ~
1125
1126When compiling lines of Vim commands into instructions as much as possible
1127should be done at compile time. Postponing it to runtime makes the execution
1128slower and means mistakes are found only later. For example, when
1129encountering the "+" character and compiling this into a generic add
1130instruction, at execution time the instruction would have to inspect the type
1131of the arguments and decide what kind of addition to do. And when the
1132type is dictionary throw an error. If the types are known to be numbers then
1133an "add number" instruction can be used, which is faster. The error can be
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001134given at compile time, no error handling is needed at runtime, since adding
1135two numbers cannot fail.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001136
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001137The syntax for types, using <type> for compound types, is similar to Java. It
1138is easy to understand and widely used. The type names are what were used in
1139Vim before, with some additions such as "void" and "bool".
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001140
1141
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02001142Removing clutter and weirdness ~
Bram Moolenaar65e0d772020-06-14 17:29:55 +02001143
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02001144Once decided that `:def` functions have different syntax than legacy functions,
1145we are free to add improvements to make the code more familiar for users who
1146know popular programming languages. In other words: remove weird things that
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001147only Vim does.
Bram Moolenaar65e0d772020-06-14 17:29:55 +02001148
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02001149We can also remove clutter, mainly things that were done to make Vim script
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001150backwards compatible with the good old Vi commands.
Bram Moolenaar65e0d772020-06-14 17:29:55 +02001151
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02001152Examples:
1153- Drop `:call` for calling a function and `:eval` for manipulating data.
1154- Drop using a leading backslash for line continuation, automatically figure
1155 out where an expression ends.
Bram Moolenaar65e0d772020-06-14 17:29:55 +02001156
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02001157However, this does require that some things need to change:
1158- Comments start with # instead of ", to avoid confusing them with strings.
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001159 This is good anyway, it is known from several popular languages.
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02001160- Ex command ranges need to be prefixed with a colon, to avoid confusion with
1161 expressions (single quote can be a string or a mark, "/" can be divide or a
1162 search command, etc.).
1163
1164Goal is to limit the differences. A good criteria is that when the old syntax
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001165is accidentally used you are very likely to get an error message.
Bram Moolenaar65e0d772020-06-14 17:29:55 +02001166
1167
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001168Syntax and semantics from popular languages ~
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001169
1170Script writers have complained that the Vim script syntax is unexpectedly
1171different from what they are used to. To reduce this complaint popular
Bram Moolenaar65e0d772020-06-14 17:29:55 +02001172languages are used as an example. At the same time, we do not want to abandon
1173the well-known parts of legacy Vim script.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001174
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001175For many things TypeScript is followed. It's a recent language that is
1176gaining popularity and has similarities with Vim script. It also has a
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02001177mix of static typing (a variable always has a known value type) and dynamic
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001178typing (a variable can have different types, this changes at runtime). Since
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02001179legacy Vim script is dynamically typed and a lot of existing functionality
1180(esp. builtin functions) depends on that, while static typing allows for much
1181faster execution, we need to have this mix in Vim9 script.
1182
Bram Moolenaar1c6737b2020-09-07 22:18:52 +02001183There is no intention to completely match TypeScript syntax and semantics. We
1184just want to take those parts that we can use for Vim and we expect Vim users
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02001185will be happy with. TypeScript is a complex language with its own history,
1186advantages and disadvantages. To get an idea of the disadvantages read the
1187book: "JavaScript: The Good Parts". Or find the article "TypeScript: the good
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +02001188parts" and read the "Things to avoid" section.
1189
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02001190People familiar with other languages (Java, Python, etc.) will also find
1191things in TypeScript that they do not like or do not understand. We'll try to
1192avoid those things.
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +02001193
1194Specific items from TypeScript we avoid:
1195- Overloading "+", using it both for addition and string concatenation. This
1196 goes against legacy Vim script and often leads to mistakes. For that reason
1197 we will keep using ".." for string concatenation. Lua also uses ".." this
1198 way. And it allows for conversion to string for more values.
1199- TypeScript can use an expression like "99 || 'yes'" in a condition, but
1200 cannot assign the value to a boolean. That is inconsistent and can be
1201 annoying. Vim recognizes an expression with && or || and allows using the
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001202 result as a bool. TODO: to be reconsidered
Bram Moolenaar0b4c66c2020-09-14 21:39:44 +02001203- TypeScript considers an empty string as Falsy, but an empty list or dict as
1204 Truthy. That is inconsistent. In Vim an empty list and dict are also
1205 Falsy.
1206- TypeScript has various "Readonly" types, which have limited usefulness,
1207 since a type cast can remove the immutable nature. Vim locks the value,
1208 which is more flexible, but is only checked at runtime.
Bram Moolenaar1c6737b2020-09-07 22:18:52 +02001209
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001210
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001211Declarations ~
1212
1213Legacy Vim script uses `:let` for every assignment, while in Vim9 declarations
1214are used. That is different, thus it's good to use a different command:
1215`:var`. This is used in many languages. The semantics might be slightly
1216different, but it's easily recognized as a declaration.
1217
Bram Moolenaar23515b42020-11-29 14:36:24 +01001218Using `:const` for constants is common, but the semantics varies. Some
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001219languages only make the variable immutable, others also make the value
1220immutable. Since "final" is well known from Java for only making the variable
1221immutable we decided to use that. And then `:const` can be used for making
1222both immutable. This was also used in legacy Vim script and the meaning is
1223almost the same.
1224
1225What we end up with is very similar to Dart: >
1226 :var name # mutable variable and value
1227 :final name # immutable variable, mutable value
1228 :const name # immutable variable and value
1229
1230Since legacy and Vim9 script will be mixed and global variables will be
1231shared, optional type checking is desirable. Also, type inference will avoid
1232the need for specifying the type in many cases. The TypeScript syntax fits
1233best for adding types to declarations: >
1234 var name: string # string type is specified
1235 ...
1236 name = 'John'
1237 const greeting = 'hello' # string type is inferred
1238
1239This is how we put types in a declaration: >
1240 var mylist: list<string>
1241 final mylist: list<string> = ['foo']
1242 def Func(arg1: number, arg2: string): bool
1243
1244Two alternatives were considered:
12451. Put the type before the name, like Dart: >
1246 var list<string> mylist
1247 final list<string> mylist = ['foo']
1248 def Func(number arg1, string arg2) bool
12492. Put the type after the variable name, but do not use a colon, like Go: >
1250 var mylist list<string>
1251 final mylist list<string> = ['foo']
1252 def Func(arg1 number, arg2 string) bool
1253
1254The first is more familiar for anyone used to C or Java. The second one
Bram Moolenaar4f4d51a2020-10-11 13:57:40 +02001255doesn't really have an advantage over the first, so let's discard the second.
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001256
1257Since we use type inference the type can be left out when it can be inferred
1258from the value. This means that after `var` we don't know if a type or a name
1259follows. That makes parsing harder, not only for Vim but also for humans.
1260Also, it will not be allowed to use a variable name that could be a type name,
1261using `var string string` is too confusing.
1262
1263The chosen syntax, using a colon to separate the name from the type, adds
1264punctuation, but it actually makes it easier to recognize the parts of a
1265declaration.
1266
1267
1268Expressions ~
1269
Bram Moolenaar4f4d51a2020-10-11 13:57:40 +02001270Expression evaluation was already close to what other languages are doing.
1271Some details are unexpected and can be improved. For example a boolean
1272condition would accept a string, convert it to a number and check if the
1273number is non-zero. This is unexpected and often leads to mistakes, since
1274text not starting with a number would be converted to zero, which is
Bram Moolenaarcb80aa22020-10-26 21:12:46 +01001275considered false. Thus using a string for a condition would often not give an
1276error and be considered false. That is confusing.
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001277
Bram Moolenaar23515b42020-11-29 14:36:24 +01001278In Vim9 type checking is stricter to avoid mistakes. Where a condition is
Bram Moolenaar4f4d51a2020-10-11 13:57:40 +02001279used, e.g. with the `:if` command and the `||` operator, only boolean-like
1280values are accepted:
1281 true: `true`, `v:true`, `1`, `0 < 9`
1282 false: `false`, `v:false`, `0`, `0 > 9`
1283Note that the number zero is false and the number one is true. This is more
Bram Moolenaarcb80aa22020-10-26 21:12:46 +01001284permissive than most other languages. It was done because many builtin
Bram Moolenaar4f4d51a2020-10-11 13:57:40 +02001285functions return these values.
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001286
Bram Moolenaar4f4d51a2020-10-11 13:57:40 +02001287If you have any type of value and want to use it as a boolean, use the `!!`
1288operator:
1289 true: !`!'text'`, `!![99]`, `!!{'x': 1}`, `!!99`
1290 false: `!!''`, `!![]`, `!!{}`
1291
1292From a language like JavaScript we have this handy construct: >
1293 GetName() || 'unknown'
1294However, this conflicts with only allowing a boolean for a condition.
1295Therefore the "??" operator was added: >
1296 GetName() ?? 'unknown'
1297Here you can explicitly express your intention to use the value as-is and not
1298result in a boolean. This is called the |falsy-operator|.
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001299
1300
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001301Import and Export ~
1302
1303A problem of legacy Vim script is that by default all functions and variables
1304are global. It is possible to make them script-local, but then they are not
Bram Moolenaar1c6737b2020-09-07 22:18:52 +02001305available in other scripts. This defies the concept of a package that only
1306exports selected items and keeps the rest local.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001307
Bram Moolenaar3d1cde82020-08-15 18:55:18 +02001308In Vim9 script a mechanism very similar to the JavaScript import and export
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001309mechanism is supported. It is a variant to the existing `:source` command
1310that works like one would expect:
1311- Instead of making everything global by default, everything is script-local,
1312 unless exported.
Bram Moolenaar1c6737b2020-09-07 22:18:52 +02001313- When importing a script the symbols that are imported are explicitly listed,
1314 avoiding name conflicts and failures if functionality is added later.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001315- The mechanism allows for writing a big, long script with a very clear API:
1316 the exported function(s) and class(es).
1317- By using relative paths loading can be much faster for an import inside of a
1318 package, no need to search many directories.
1319- Once an import has been used, it can be cached and loading it again can be
1320 avoided.
1321- The Vim-specific use of "s:" to make things script-local can be dropped.
1322
Bram Moolenaar65e0d772020-06-14 17:29:55 +02001323When sourcing a Vim9 script from a legacy script, only the items defined
1324globally can be used, not the exported items. Alternatives considered:
1325- All the exported items become available as script-local items. This makes
Bram Moolenaar1c6737b2020-09-07 22:18:52 +02001326 it uncontrollable what items get defined and likely soon leads to trouble.
Bram Moolenaar65e0d772020-06-14 17:29:55 +02001327- Use the exported items and make them global. Disadvantage is that it's then
1328 not possible to avoid name clashes in the global namespace.
1329- Completely disallow sourcing a Vim9 script, require using `:import`. That
1330 makes it difficult to use scripts for testing, or sourcing them from the
1331 command line to try them out.
Bram Moolenaar1c6737b2020-09-07 22:18:52 +02001332Note that you can also use `:import` in legacy Vim script, see above.
Bram Moolenaar65e0d772020-06-14 17:29:55 +02001333
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001334
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02001335Compiling functions early ~
1336
1337Functions are compiled when called or when `:defcompile` is used. Why not
1338compile them early, so that syntax and type errors are reported early?
1339
1340The functions can't be compiled right away when encountered, because there may
1341be forward references to functions defined later. Consider defining functions
1342A, B and C, where A calls B, B calls C, and C calls A again. It's impossible
1343to reorder the functions to avoid forward references.
1344
1345An alternative would be to first scan through the file to locate items and
1346figure out their type, so that forward references are found, and only then
1347execute the script and compile the functions. This means the script has to be
1348parsed twice, which is slower, and some conditions at the script level, such
1349as checking if a feature is supported, are hard to use. An attempt was made
1350to see if it works, but it turned out to be impossible to make work nicely.
1351
1352It would be possible to compile all the functions at the end of the script.
1353The drawback is that if a function never gets called, the overhead of
1354compiling it counts anyway. Since startup speed is very important, in most
1355cases it's better to do it later and accept that syntax and type errors are
1356only reported then. In case these errors should be found early, e.g. when
1357testing, the `:defcompile` command will help out.
1358
1359
Bram Moolenaar30fd8202020-09-26 15:09:30 +02001360Why not use an embedded language? ~
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001361
1362Vim supports interfaces to Perl, Python, Lua, Tcl and a few others. But
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02001363these interfaces have never become widely used, for various reasons. When
1364Vim9 was designed a decision was made to make these interfaces lower priority
1365and concentrate on Vim script.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001366
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02001367Still, plugin writers may find other languages more familiar, want to use
1368existing libraries or see a performance benefit. We encourage plugin authors
1369to write code in any language and run it as an external tool, using jobs and
1370channels. We can try to make this easier somehow.
1371
1372Using an external tool also has disadvantages. An alternative is to convert
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001373the tool into Vim script. For that to be possible without too much
1374translation, and keeping the code fast at the same time, the constructs of the
1375tool need to be supported. Since most languages support classes the lack of
Bram Moolenaar1c6737b2020-09-07 22:18:52 +02001376support for classes in Vim is then a problem.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001377
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02001378
1379Classes ~
1380
1381Vim supports a kind-of object oriented programming by adding methods to a
1382dictionary. With some care this can be made to work, but it does not look
1383like real classes. On top of that, it's quite slow, because of the use of
1384dictionaries.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001385
1386The support of classes in Vim9 script is a "minimal common functionality" of
Bram Moolenaar1c6737b2020-09-07 22:18:52 +02001387class support in most languages. It works much like Java, which is the most
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001388popular programming language.
1389
1390
1391
1392 vim:tw=78:ts=8:noet:ft=help:norl: