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