To: vim_dev@googlegroups.com Subject: Patch 8.2.2982 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.2982 Problem: Vim9: future commands are not reserved yet. Solution: Add commands to be implemented later. Make "this" a reserved name. Files: runtime/doc/vim9.txt, src/ex_cmds.h, src/ex_cmdidxs.h, src/vim9script.c, src/testdir/test_vim9_assign.vim *** ../vim-8.2.2981/runtime/doc/vim9.txt 2021-04-24 14:15:03.676264489 +0200 --- runtime/doc/vim9.txt 2021-06-12 14:36:51.266773606 +0200 *************** *** 101,107 **** def CallMe(count: number, message: string): bool - Call functions without `:call`: > writefile(['done'], 'file.txt') ! - You cannot use `:xit`, `:t`, `:k`, `:append`, `:change`, `:insert`, `:open` or curly-braces names. - A range before a command must be prefixed with a colon: > :%s/this/that --- 101,108 ---- def CallMe(count: number, message: string): bool - Call functions without `:call`: > writefile(['done'], 'file.txt') ! - You cannot use `:xit`, `:t`, `:k`, `:append`, `:change`, `:insert`, `:open`, ! and `:s` or `:d` with only flags. or curly-braces names. - A range before a command must be prefixed with a colon: > :%s/this/that *************** *** 157,168 **** --- 158,182 ---- *E1091* If compilation fails it is not tried again on the next call, instead this error is given: "E1091: Function is not compiled: {name}". + Compilation will fail when encountering a user command that has not been + created yet. In this case you can call `execute()` to invoke it at runtime. > + def MyFunc() + execute('DefinedLater') + enddef `:def` has no options like `:function` does: "range", "abort", "dict" or "closure". A `:def` function always aborts on an error (unless `:silent!` was used for the command or inside a `:try` block), does not get a range passed cannot be a "dict" function, and can always be a closure. + Later classes will be added, which replaces the "dict function" mechanism. + For now you will need to pass the dictionary explicitly: > + def DictFunc(d: dict, arg: string) + echo d[arg] + enddef + var d = {item: 'value', func: DictFunc} + d.func(d, 'item') + The argument types and return type need to be specified. The "any" type can be used, type checking will then be done at runtime, like with legacy functions. *************** *** 439,445 **** because of the use of argument types. To avoid these problems Vim9 script uses a different syntax for a lambda, ! which is similar to Javascript: > var Lambda = (arg) => expression No line break is allowed in the arguments of a lambda up to and including the --- 453,459 ---- because of the use of argument types. To avoid these problems Vim9 script uses a different syntax for a lambda, ! which is similar to JavaScript: > var Lambda = (arg) => expression No line break is allowed in the arguments of a lambda up to and including the *************** *** 516,522 **** one: 1, two: 2, } ! Function call: > var result = Func( arg1, arg2 --- 530,536 ---- one: 1, two: 2, } ! With a function call: > var result = Func( arg1, arg2 *************** *** 549,558 **** | echo 'match' | endif < *E1050* To make it possible for the operator at the start of the line to be ! recognized, it is required to put a colon before a range. This will add ! "start" and print: > var result = start + print Like this: > --- 563,593 ---- | echo 'match' | endif + Note that this means that in heredoc the first line cannot be a bar: > + var lines =<< trim END + | this doesn't work + END + Either use an empty line at the start or do not use heredoc. Or temporarily + add the "C" flag to 'cpoptions': > + set cpo+=C + var lines =<< trim END + | this doesn't work + END + set cpo-=C + If the heredoc is inside a function 'cpoptions' must be set before :def and + restored after the :enddef. + + In places where line continuation with a backslash is still needed, such as + splitting up a long Ex command, comments can start with #\ instead of "\: > + syn region Text + \ start='foo' + #\ comment + \ end='bar' + < *E1050* To make it possible for the operator at the start of the line to be ! recognized, it is required to put a colon before a range. This example will ! add "start" and print: > var result = start + print Like this: > *************** *** 604,609 **** --- 639,685 ---- < This does not work: > echo [1, 2] [3, 4] + - In some cases it is difficult for Vim to parse a command, especially when + commands are used as an argument to another command, such as `windo`. In + those cases the line continuation with a backslash has to be used. + + + White space ~ + + Vim9 script enforces proper use of white space. This is no longer allowed: > + var name=234 # Error! + var name= 234 # Error! + var name =234 # Error! + There must be white space before and after the "=": > + var name = 234 # OK + White space must also be put before the # that starts a comment after a + command: > + var name = 234# Error! + var name = 234 # OK + + White space is required around most operators. + + White space is required in a sublist (list slice) around the ":", except at + the start and end: > + otherlist = mylist[v : count] # v:count has a different meaning + otherlist = mylist[:] # make a copy of the List + otherlist = mylist[v :] + otherlist = mylist[: v] + + White space is not allowed: + - Between a function name and the "(": > + Func (arg) # Error! + Func + \ (arg) # Error! + Func + (arg) # Error! + Func(arg) # OK + Func( + arg) # OK + Func( + arg # OK + ) + No curly braces expansion ~ *************** *** 656,661 **** --- 732,748 ---- The 'ignorecase' option is not used for comparators that use strings. + Abort after error ~ + + In legacy script, when an error is encountered, Vim continues to execute + following lines. This can lead to a long sequence of errors and need to type + CTRL-C to stop it. In Vim9 script execution of commands stops at the first + error. Example: > + vim9script + var x = does-not-exist + echo 'not executed' + + For loop ~ Legacy Vim script has some tricks to make a for loop over a list handle *************** *** 679,721 **** first if needed. - White space ~ - - Vim9 script enforces proper use of white space. This is no longer allowed: > - var name=234 # Error! - var name= 234 # Error! - var name =234 # Error! - There must be white space before and after the "=": > - var name = 234 # OK - White space must also be put before the # that starts a comment after a - command: > - var name = 234# Error! - var name = 234 # OK - - White space is required around most operators. - - White space is required in a sublist (list slice) around the ":", except at - the start and end: > - otherlist = mylist[v : count] # v:count has a different meaning - otherlist = mylist[:] # make a copy of the List - otherlist = mylist[v :] - otherlist = mylist[: v] - - White space is not allowed: - - Between a function name and the "(": > - Func (arg) # Error! - Func - \ (arg) # Error! - Func - (arg) # Error! - Func(arg) # OK - Func( - arg) # OK - Func( - arg # OK - ) - - Conditions and expressions ~ Conditions and expressions are mostly working like they do in other languages. --- 766,771 ---- *************** *** 1222,1230 **** export const someValue = ... export def MyFunc() ... export class MyClass ... As this suggests, only constants, variables, `:def` functions and classes can ! be exported. {not implemented yet: export class} *E1042* `:export` can only be used in Vim9 script, at the script level. --- 1272,1281 ---- export const someValue = ... export def MyFunc() ... export class MyClass ... + export interface MyClass ... As this suggests, only constants, variables, `:def` functions and classes can ! be exported. {not implemented yet: class, interface} *E1042* `:export` can only be used in Vim9 script, at the script level. *************** *** 1324,1350 **** For now we'll just make sure classes can be added later. Thoughts: ! - `class` / `endclass`, everything in one file ! - Class names are always CamelCase ! - Single constructor - Single inheritance with `class ThisClass extends BaseClass` ! - `abstract class` ! - `interface` (Abstract class without any implementation) - `class SomeClass implements SomeInterface` - Generics for class: `class ` - Generics for function: `def GetLast(key: Tkey)` ! Again, much of this is from TypeScript. Some things that look like good additions: - Use a class as an interface (like Dart) - Extend a class with methods, using an import (like Dart) An important class that will be provided is "Promise". Since Vim is single threaded, connecting asynchronous operations is a natural way of allowing plugins to do their work without blocking the user. It's a uniform way to invoke callbacks and handle timeouts and errors. ============================================================================== 9. Rationale *vim9-rationale* --- 1375,1420 ---- For now we'll just make sure classes can be added later. Thoughts: ! - `class` / `endclass`, the whole class must be in one file ! - Class names are always CamelCase (to avoid a name clash with builtin types) ! - A single constructor called "constructor" - Single inheritance with `class ThisClass extends BaseClass` ! - `abstract class` (class with incomplete implementation) ! - `interface` / `endinterface` (abstract class without any implementation) - `class SomeClass implements SomeInterface` - Generics for class: `class ` - Generics for function: `def GetLast(key: Tkey)` ! Again, much of this is from TypeScript with a slightly different syntax. Some things that look like good additions: - Use a class as an interface (like Dart) - Extend a class with methods, using an import (like Dart) + - Mixins + - For testing: Mock mechanism An important class that will be provided is "Promise". Since Vim is single threaded, connecting asynchronous operations is a natural way of allowing plugins to do their work without blocking the user. It's a uniform way to invoke callbacks and handle timeouts and errors. + Some examples: > + + abstract class Person + static const prefix = 'xxx' + var name: string + + def constructor(name: string) + this.name = name; + enddef + + def display(): void + echo name + enddef + + abstract def find(string): Person + endclass + ============================================================================== 9. Rationale *vim9-rationale* *************** *** 1533,1539 **** If you have any type of value and want to use it as a boolean, use the `!!` operator: ! true: !`!'text'`, `!![99]`, `!!{'x': 1}`, `!!99` false: `!!''`, `!![]`, `!!{}` From a language like JavaScript we have this handy construct: > --- 1603,1609 ---- If you have any type of value and want to use it as a boolean, use the `!!` operator: ! true: `!!'text'`, `!![99]`, `!!{'x': 1}`, `!!99` false: `!!''`, `!![]`, `!!{}` From a language like JavaScript we have this handy construct: > *** ../vim-8.2.2981/src/ex_cmds.h 2021-06-06 22:02:12.590908512 +0200 --- src/ex_cmds.h 2021-06-12 14:29:15.995781876 +0200 *************** *** 122,127 **** --- 122,130 ---- EXCMD(CMD_aboveleft, "aboveleft", ex_wrongmodifier, EX_NEEDARG|EX_EXTRA|EX_NOTRLCOM, ADDR_NONE), + EXCMD(CMD_abstract, "abstract", ex_ni, + EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, + ADDR_NONE), EXCMD(CMD_all, "all", ex_all, EX_BANG|EX_RANGE|EX_COUNT|EX_TRLBAR, ADDR_OTHER), *************** *** 551,556 **** --- 554,562 ---- EXCMD(CMD_endif, "endif", ex_endif, EX_TRLBAR|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), + EXCMD(CMD_endinterface, "endinterface", ex_ni, + EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, + ADDR_NONE), EXCMD(CMD_endclass, "endclass", ex_ni, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), *************** *** 734,739 **** --- 740,748 ---- EXCMD(CMD_intro, "intro", ex_intro, EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), + EXCMD(CMD_interface, "interface", ex_ni, + EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, + ADDR_NONE), EXCMD(CMD_isearch, "isearch", ex_findpat, EX_BANG|EX_RANGE|EX_DFLALL|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK, ADDR_LINES), *************** *** 1463,1468 **** --- 1472,1480 ---- EXCMD(CMD_startreplace, "startreplace", ex_startinsert, EX_BANG|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), + EXCMD(CMD_static, "static", ex_ni, + EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, + ADDR_NONE), EXCMD(CMD_stopinsert, "stopinsert", ex_stopinsert, EX_BANG|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), *** ../vim-8.2.2981/src/ex_cmdidxs.h 2021-06-06 22:02:12.590908512 +0200 --- src/ex_cmdidxs.h 2021-06-12 14:40:18.222607128 +0200 *************** *** 6,36 **** static const unsigned short cmdidxs1[26] = { /* a */ 0, ! /* b */ 19, ! /* c */ 43, ! /* d */ 110, ! /* e */ 135, ! /* f */ 162, ! /* g */ 179, ! /* h */ 185, ! /* i */ 194, ! /* j */ 213, ! /* k */ 215, ! /* l */ 220, ! /* m */ 283, ! /* n */ 301, ! /* o */ 321, ! /* p */ 333, ! /* q */ 372, ! /* r */ 375, ! /* s */ 395, ! /* t */ 464, ! /* u */ 510, ! /* v */ 521, ! /* w */ 542, ! /* x */ 556, ! /* y */ 566, ! /* z */ 567 }; /* --- 6,36 ---- static const unsigned short cmdidxs1[26] = { /* a */ 0, ! /* b */ 20, ! /* c */ 44, ! /* d */ 111, ! /* e */ 136, ! /* f */ 164, ! /* g */ 181, ! /* h */ 187, ! /* i */ 196, ! /* j */ 216, ! /* k */ 218, ! /* l */ 223, ! /* m */ 286, ! /* n */ 304, ! /* o */ 324, ! /* p */ 336, ! /* q */ 375, ! /* r */ 378, ! /* s */ 398, ! /* t */ 468, ! /* u */ 514, ! /* v */ 525, ! /* w */ 546, ! /* x */ 560, ! /* y */ 570, ! /* z */ 571 }; /* *************** *** 41,55 **** */ static const unsigned char cmdidxs2[26][26] = { /* a b c d e f g h i j k l m n o p q r s t u v w x y z */ ! /* a */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 0, 0, 0, 7, 15, 0, 16, 0, 0, 0, 0, 0 }, /* b */ { 2, 0, 0, 5, 6, 8, 0, 0, 0, 0, 0, 9, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 23, 0, 0, 0 }, /* c */ { 3, 12, 16, 18, 20, 22, 25, 0, 0, 0, 0, 33, 38, 41, 47, 57, 59, 60, 61, 0, 63, 0, 66, 0, 0, 0 }, /* d */ { 0, 0, 0, 0, 0, 0, 0, 0, 8, 18, 0, 19, 0, 0, 20, 0, 0, 22, 23, 0, 0, 0, 0, 0, 0, 0 }, ! /* e */ { 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10, 11, 0, 0, 0, 0, 0, 0, 0, 21, 0, 22, 0, 0 }, /* f */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0 }, /* g */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 4, 5, 0, 0, 0, 0 }, /* h */ { 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, ! /* i */ { 1, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 5, 6, 0, 0, 0, 0, 0, 14, 0, 16, 0, 0, 0, 0, 0 }, /* j */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, /* k */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* l */ { 3, 11, 15, 19, 20, 25, 28, 33, 0, 0, 0, 35, 38, 41, 45, 51, 0, 53, 62, 54, 55, 59, 61, 0, 0, 0 }, --- 41,55 ---- */ static const unsigned char cmdidxs2[26][26] = { /* a b c d e f g h i j k l m n o p q r s t u v w x y z */ ! /* a */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 6, 7, 0, 0, 0, 8, 16, 0, 17, 0, 0, 0, 0, 0 }, /* b */ { 2, 0, 0, 5, 6, 8, 0, 0, 0, 0, 0, 9, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 23, 0, 0, 0 }, /* c */ { 3, 12, 16, 18, 20, 22, 25, 0, 0, 0, 0, 33, 38, 41, 47, 57, 59, 60, 61, 0, 63, 0, 66, 0, 0, 0 }, /* d */ { 0, 0, 0, 0, 0, 0, 0, 0, 8, 18, 0, 19, 0, 0, 20, 0, 0, 22, 23, 0, 0, 0, 0, 0, 0, 0 }, ! /* e */ { 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10, 11, 0, 0, 0, 0, 0, 0, 0, 22, 0, 23, 0, 0 }, /* f */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0 }, /* g */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 4, 5, 0, 0, 0, 0 }, /* h */ { 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, ! /* i */ { 1, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 5, 6, 0, 0, 0, 0, 0, 15, 0, 17, 0, 0, 0, 0, 0 }, /* j */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, /* k */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* l */ { 3, 11, 15, 19, 20, 25, 28, 33, 0, 0, 0, 35, 38, 41, 45, 51, 0, 53, 62, 54, 55, 59, 61, 0, 0, 0 }, *************** *** 59,65 **** /* p */ { 1, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 0, 0, 16, 17, 26, 0, 27, 0, 28, 0 }, /* q */ { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* r */ { 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 19, 0, 0, 0, 0 }, ! /* s */ { 2, 6, 15, 0, 19, 23, 0, 25, 26, 0, 0, 29, 31, 35, 39, 41, 0, 50, 0, 51, 0, 63, 64, 0, 65, 0 }, /* t */ { 2, 0, 19, 0, 24, 26, 0, 27, 0, 28, 0, 29, 33, 36, 38, 39, 0, 40, 42, 0, 43, 0, 0, 0, 45, 0 }, /* u */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* v */ { 1, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 12, 15, 0, 0, 0, 0, 18, 0, 19, 0, 0, 0, 0, 0 }, --- 59,65 ---- /* p */ { 1, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 0, 0, 16, 17, 26, 0, 27, 0, 28, 0 }, /* q */ { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* r */ { 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 19, 0, 0, 0, 0 }, ! /* s */ { 2, 6, 15, 0, 19, 23, 0, 25, 26, 0, 0, 29, 31, 35, 39, 41, 0, 50, 0, 51, 0, 64, 65, 0, 66, 0 }, /* t */ { 2, 0, 19, 0, 24, 26, 0, 27, 0, 28, 0, 29, 33, 36, 38, 39, 0, 40, 42, 0, 43, 0, 0, 0, 45, 0 }, /* u */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* v */ { 1, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 12, 15, 0, 0, 0, 0, 18, 0, 19, 0, 0, 0, 0, 0 }, *************** *** 69,72 **** /* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; ! static const int command_count = 584; --- 69,72 ---- /* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; ! static const int command_count = 588; *** ../vim-8.2.2981/src/vim9script.c 2021-05-28 21:06:04.624687355 +0200 --- src/vim9script.c 2021-06-12 14:41:50.606488546 +0200 *************** *** 979,984 **** --- 979,985 ---- "true", "false", "null", + "this", NULL }; *** ../vim-8.2.2981/src/testdir/test_vim9_assign.vim 2021-05-28 21:06:04.628687341 +0200 --- src/testdir/test_vim9_assign.vim 2021-06-12 14:42:56.026391538 +0200 *************** *** 982,987 **** --- 982,989 ---- CheckDefFailure(['var true = 1'], 'E1034:') CheckDefFailure(['var false = 1'], 'E1034:') + CheckDefFailure(['var null = 1'], 'E1034:') + CheckDefFailure(['var this = 1'], 'E1034:') CheckDefFailure(['[a; b; c] = g:list'], 'E452:') CheckDefExecFailure(['var a: number', *** ../vim-8.2.2981/src/version.c 2021-06-12 14:05:37.872370788 +0200 --- src/version.c 2021-06-12 14:39:54.318633906 +0200 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 2982, /**/ -- ARTHUR: What are you going to do. bleed on me? "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///