To: vim_dev@googlegroups.com Subject: Patch 8.2.1227 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1227 Problem: Vim9: allowing both quoted and # comments is confusing. Solution: Only support # comments in Vim9 script. Files: runtime/doc/vim9.txt, src/ex_docmd.c, src/proto/ex_docmd.pro, src/vim9compile.c, src/testdir/test_vim9_disassemble.vim, src/testdir/test_vim9_expr.vim, src/testdir/test_vim9_func.vim, src/testdir/test_vim9_script.vim *** ../vim-8.2.1226/runtime/doc/vim9.txt 2020-06-22 23:02:14.769942569 +0200 --- runtime/doc/vim9.txt 2020-07-17 20:32:55.445926999 +0200 *************** *** 30,36 **** Vim script has been growing over time, while preserving backwards compatibility. That means bad choices from the past often can't be changed ! and compability with Vi restricts possible solutions. Execution is quite slow, each line is parsed every time it is executed. The main goal of Vim9 script is to drastically improve performance. This is --- 30,36 ---- Vim script has been growing over time, while preserving backwards compatibility. That means bad choices from the past often can't be changed ! and compatibility with Vi restricts possible solutions. Execution is quite slow, each line is parsed every time it is executed. The main goal of Vim9 script is to drastically improve performance. This is *************** *** 41,49 **** commonly used programming languages, such as JavaScript, TypeScript and Java. The performance improvements can only be achieved by not being 100% backwards ! compatible. For example, in a function the arguments are not available in the ! "a:" dictionary, because creating that dictionary adds quite a lot of ! overhead. Other differences are more subtle, such as how errors are handled. The Vim9 script syntax and semantics are used in: - a function defined with the `:def` command --- 41,50 ---- commonly used programming languages, such as JavaScript, TypeScript and Java. The performance improvements can only be achieved by not being 100% backwards ! compatible. For example, making function arguments available in the ! "a:" dictionary adds quite a lot of overhead. In a Vim9 function this ! dictionary is not available. Other differences are more subtle, such as how ! errors are handled. The Vim9 script syntax and semantics are used in: - a function defined with the `:def` command *************** *** 63,75 **** Comments starting with # ~ ! In Vim script comments normally start with double quote. That can also be the ! start of a string, thus in many places it cannot be used. In Vim9 script a ! comment can also start with #. In Vi this is a command to list text with ! numbers, but you can also use `:number` for that. > ! let count = 0 # number of occurences ! To improve readability there must be a space between the command and the # that starts a comment. Note that #{ is the start of a dictionary, therefore it cannot start a comment. --- 64,84 ---- Comments starting with # ~ ! In legacy Vim script comments start with double quote. In Vim9 script ! comments start with #. > ! # declarations ! let count = 0 # number of occurrences ! ! The reason is that a double quote can also be the start of a string. In many ! places, especially halfway an expression with a line break, it's hard to tell ! what the meaning is. To avoid confusion only # comments are recognized. ! This is the same as in shell scripts and Python programs. ! ! In Vi # is a command to list text with numbers. In Vim9 script you can use ! `:number` for that. > ! 101number ! To improve readability there must be a space between a command and the # that starts a comment. Note that #{ is the start of a dictionary, therefore it cannot start a comment. *************** *** 82,93 **** Many errors are already found when compiling, before the function is executed. The syntax is strict, to enforce code that is easy to read and understand. ! Compilation is done when the function is first called, or when the `:compile` ! command is encountered in the script where the function was defined. ! ! `:def` has no extra arguments like `:function` does: "range", "abort", "dict" ! or "closure". A `:def` function always aborts on an error, does not get a ! range passed and cannot be a "dict" function. 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 --- 91,103 ---- Many errors are already found when compiling, before the function is executed. The syntax is strict, to enforce code that is easy to read and understand. ! Compilation is done when the function is first called, or when the ! `:defcompile` command is encountered in the script where the function was ! defined. ! ! `:def` has no options like `:function` does: "range", "abort", "dict" or ! "closure". A `:def` function always aborts on an error, does not get a range ! passed and cannot be a "dict" function. 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 *************** *** 104,110 **** Functions and variables are script-local by default ~ ! When using `:function` or `:def` to specify a new function at the script level in a Vim9 script, the function is local to the script, as if "s:" was prefixed. Using the "s:" prefix is optional. --- 114,120 ---- Functions and variables are script-local by default ~ ! *vim9-scopes* When using `:function` or `:def` to specify a new function at the script level in a Vim9 script, the function is local to the script, as if "s:" was prefixed. Using the "s:" prefix is optional. *************** *** 121,128 **** - Local to the current scope and outer scopes up to the function scope. - Local to the current script file. - Imported functions, see `:import`. ! In all cases the function must be defined before used. To make a call cycle a ! global function needs to be used. (TODO: can we fix this?) The result is that functions and variables without a namespace can always be found in the script, either defined there or imported. Global functions and --- 131,138 ---- - Local to the current scope and outer scopes up to the function scope. - Local to the current script file. - Imported functions, see `:import`. ! In all cases the function must be defined before used. That is when it is ! first called or when `:defcompile` causes the call to be compiled. The result is that functions and variables without a namespace can always be found in the script, either defined there or imported. Global functions and *************** *** 130,140 **** Global functions can be still be defined and deleted at nearly any time. In Vim9 script script-local functions are defined once when the script is sourced ! and cannot be deleted. Variable declarations with :let and :const ~ ! Local variables need to be declared with `:let`. Local constants need to be declared with `:const`. We refer to both as "variables". --- 140,150 ---- Global functions can be still be defined and deleted at nearly any time. In Vim9 script script-local functions are defined once when the script is sourced ! and cannot be deleted or replaced. Variable declarations with :let and :const ~ ! *vim9-declaration* Local variables need to be declared with `:let`. Local constants need to be declared with `:const`. We refer to both as "variables". *************** *** 165,172 **** endif echo inner ! To intentionally use a variable that won't be available later, a block can be ! used: > { let temp = 'temp' ... --- 175,182 ---- endif echo inner ! To intentionally avoid a variable being available later, a block can be used: ! > { let temp = 'temp' ... *************** *** 274,283 **** < *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 adde "start" and print: > let result = start + print This will assign "start" and print a line: > let result = start :+ print --- 284,296 ---- < *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: > let result = start + print + Like this: > + let result = start + print + This will assign "start" and print a line: > let result = start :+ print *************** *** 289,296 **** separator = '-' ): string ! Note that "enddef" cannot be used at the start of a continuation line, it ends ! the current function. No curly braces expansion ~ --- 302,333 ---- separator = '-' ): string ! Notes: ! - "enddef" cannot be used at the start of a continuation line, it ends the ! current function. ! - No line break is allowed in the LHS of an assignment. Specifically when ! unpacking a list |:let-unpack|. This is OK: > ! [var1, var2] = ! Func() ! < This does not work: > ! [var1, ! var2] = ! Func() ! - No line break is allowed in between arguments of an `:echo`, `:execute` and ! similar commands. This is OK: > ! echo [1, ! 2] [3, ! 4] ! < This does not work: > ! echo [1, 2] ! [3, 4] ! - No line break is allowed in the arguments of a lambda, between the "{" and ! "->". This is OK: > ! filter(list, {k, v -> ! v > 0}) ! < This does not work: > ! filter(list, {k, ! v -> v > 0}) No curly braces expansion ~ *************** *** 316,322 **** let var =234 " Error! There must be white space before and after the "=": > let var = 234 " OK ! White space must also be put before the # that starts a comment: > let var = 234# Error! let var = 234 # OK --- 353,360 ---- let var =234 " Error! There must be white space before and after the "=": > let var = 234 " OK ! White space must also be put before the # that starts a comment after a ! command: > let var = 234# Error! let var = 234 # OK *************** *** 366,371 **** --- 404,410 ---- 0 || '' == '' 8 && 2 == 2 0 && 2 == 0 + 2 && 0 == 0 [] && 2 == [] When using `..` for string concatenation the arguments are always converted to *************** *** 376,381 **** --- 415,465 ---- In Vim9 script one can use "true" for v:true and "false" for v:false. + What to watch out for ~ + *vim9-gotchas* + Vim9 was designed to be closer to often used programming languages, but at the + same time tries to support the legacy Vim commands. Some compromises had to + be made. Here is a summary of what might be unexpected. + + Ex command ranges need to be prefixed with a colon. > + -> " legacy Vim: shifts the previous line to the right + ->func() " Vim9: method call in continuation line + :-> " Vim9: shifts the previous line to the right + + %s/a/b " legacy Vim: substitute on all lines + x = alongname + % another " Vim9: line continuation without a backslash + :%s/a/b " Vim9: substitute on all lines + 'text'->func() " Vim9: method call + :'t " legacy Vim: jump to mark m + + Functions defined with `:def` compile the whole function. Legacy functions + can bail out, and the following lines are not parsed: > + func Maybe() + if !has('feature') + return + endif + use-feature + endfunc + Vim9 functions are compiled as a whole: > + def Maybe() + if !has('feature') + return + endif + use-feature " May give compilation error + enddef + For a workaround, split it in two functions: > + func Maybe() + if has('feature') + call MaybyInner() + endif + endfunc + if has('feature') + def MaybeInner() + use-feature + enddef + endif + ============================================================================== 3. New style functions *fast-functions* *************** *** 401,413 **** The second and third form are optional arguments. When the caller omits an argument the {value} is used. NOTE: It is possible to nest `:def` inside another `:def`, but it is not possible to nest `:def` inside `:function`, for backwards compatibility. [!] is used as with `:function`. Note that in Vim9 script script-local functions cannot be deleted or ! redefined. *:enddef* :enddef End of a function defined with `:def`. --- 485,501 ---- The second and third form are optional arguments. When the caller omits an argument the {value} is used. + The function will be compiled into instructions when + called, or when `:defcompile` is used. Syntax and + type errors will be produced at that time. + NOTE: It is possible to nest `:def` inside another `:def`, but it is not possible to nest `:def` inside `:function`, for backwards compatibility. [!] is used as with `:function`. Note that in Vim9 script script-local functions cannot be deleted or ! redefined later in the same script. *:enddef* :enddef End of a function defined with `:def`. *************** *** 415,422 **** If the script the function is defined in is Vim9 script, then script-local variables can be accessed without the "s:" prefix. They must be defined ! before the function. If the script the function is defined in is legacy ! script, then script-local variables must be accessed with the "s:" prefix. *:defc* *:defcompile* :defc[ompile] Compile functions defined in the current script that --- 503,511 ---- If the script the function is defined in is Vim9 script, then script-local variables can be accessed without the "s:" prefix. They must be defined ! before the function is compiled. If the script the function is defined in is ! legacy script, then script-local variables must be accessed with the "s:" ! prefix. *:defc* *:defcompile* :defc[ompile] Compile functions defined in the current script that *************** *** 429,434 **** --- 518,539 ---- Note that for command line completion of {func} you can prepend "s:" to find script-local functions. + Limitations ~ + + Local variables will not be visible to string evaluation. For example: > + def EvalString(): list + let list = ['aa', 'bb', 'cc', 'dd'] + return range(1, 2)->map('list[v:val]') + enddef + + The map argument is a string expression, which is evaluated without the + function scope. Instead, use a lambda: > + def EvalString(): list + let list = ['aa', 'bb', 'cc', 'dd'] + return range(1, 2)->map({ _, v -> list[v] }) + enddef + + ============================================================================== 4. Types *vim9-types* *************** *** 568,577 **** Alternatively, an export statement can be used to export several already defined (otherwise script-local) items: > export {EXPORTED_CONST, someValue, MyFunc, MyClass} Import ~ ! *:import* *:imp* The exported items can be imported individually in another Vim9 script: > import EXPORTED_CONST from "thatscript.vim" import MyClass from "myclass.vim" --- 673,685 ---- Alternatively, an export statement can be used to export several already defined (otherwise script-local) items: > export {EXPORTED_CONST, someValue, MyFunc, MyClass} + < + *E1042* + `:export` can only be used in Vim9 script, at the script level. Import ~ ! *:import* *:imp* *E1094* The exported items can be imported individually in another Vim9 script: > import EXPORTED_CONST from "thatscript.vim" import MyClass from "myclass.vim" *************** *** 642,649 **** Import in legacy Vim script ~ ! If an `import` statement is used in legacy Vim script, for identifier the ! script-local "s:" namespace will be used, even when "s:" is not specified. ============================================================================== --- 750,757 ---- Import in legacy Vim script ~ ! If an `import` statement is used in legacy Vim script, the script-local "s:" ! namespace will be used for the imported item, even when "s:" is not specified. ============================================================================== *************** *** 686,697 **** additions such as "void" and "bool". ! JavaScript/TypeScript syntax and semantics ~ Script writers have complained that the Vim script syntax is unexpectedly different from what they are used to. To reduce this complaint popular ! languages will be used as an example. At the same time, we do not want to ! abandon the well-known parts of legacy Vim script. Since Vim already uses `:let` and `:const` and optional type checking is desirable, the JavaScript/TypeScript syntax fits best for variable --- 794,830 ---- additions such as "void" and "bool". ! Compiling functions early ~ ! ! Functions are compiled when called or when `:defcompile` is used. Why not ! compile them early, so that syntax and type errors are reported early? ! ! The functions can't be compiled right away when encountered, because there may ! be forward references to functions defined later. Consider defining functions ! A, B and C, where A calls B, B calls C, and C calls A again. It's impossible ! to reorder the functions to avoid forward references. ! ! An alternative would be to first scan through the file to locate items and ! figure out their type, so that forward references are found, and only then ! execute the script and compile the functions. This means the script has to be ! parsed twice, which is slower, and some conditions at the script level, such ! as checking if a feature is supported, are hard to use. An attempt was made ! to see if it works, but it turned out to be impossible to make work nicely. ! ! It would be possible to compile all the functions at the end of the script. ! The drawback is that if a function never gets called, the overhead of ! compiling it counts anyway. Since startup speed is very important, in most ! cases it's better to do it later and accept that syntax and type errors are ! only reported then. In case these errors should be found early, e.g. when ! testing, the `:defcompile` command will help out. ! ! ! TypeScript syntax and semantics ~ Script writers have complained that the Vim script syntax is unexpectedly different from what they are used to. To reduce this complaint popular ! languages are used as an example. At the same time, we do not want to abandon ! the well-known parts of legacy Vim script. Since Vim already uses `:let` and `:const` and optional type checking is desirable, the JavaScript/TypeScript syntax fits best for variable *************** *** 708,714 **** ... return result || 0 " returns 1 ! Vim9 script works like JavaScript, keep the value: > let result = 44 ... return result || 0 " returns 44 --- 841,847 ---- ... return result || 0 " returns 1 ! Vim9 script works like JavaScript/Typescript, keep the value: > let result = 44 ... return result || 0 " returns 44 *************** *** 740,745 **** --- 873,888 ---- avoided. - The Vim-specific use of "s:" to make things script-local can be dropped. + When sourcing a Vim9 script from a legacy script, only the items defined + globally can be used, not the exported items. Alternatives considered: + - All the exported items become available as script-local items. This makes + it uncontrollable what items get defined. + - Use the exported items and make them global. Disadvantage is that it's then + not possible to avoid name clashes in the global namespace. + - Completely disallow sourcing a Vim9 script, require using `:import`. That + makes it difficult to use scripts for testing, or sourcing them from the + command line to try them out. + Classes ~ *** ../vim-8.2.1226/src/ex_docmd.c 2020-07-15 14:15:47.418627519 +0200 --- src/ex_docmd.c 2020-07-17 18:42:56.628857468 +0200 *************** *** 1649,1654 **** --- 1649,1664 ---- return nr; } + int + comment_start(char_u *p, int starts_with_colon UNUSED) + { + #ifdef FEAT_EVAL + if (in_vim9script()) + return p[0] == '#' && p[1] != '{' && !starts_with_colon; + #endif + return *p == '"'; + } + # define CURRENT_WIN_NR current_win_nr(curwin) # define LAST_WIN_NR current_win_nr(NULL) # define CURRENT_TAB_NR current_tab_nr(curtab) *************** *** 1886,1897 **** * If we got a line, but no command, then go to the line. * If we find a '|' or '\n' we set ea.nextcmd. */ ! if (*ea.cmd == NUL || *ea.cmd == '"' ! #ifdef FEAT_EVAL ! || (*ea.cmd == '#' && ea.cmd[1] != '{' ! && !starts_with_colon && vim9script) ! #endif ! || (ea.nextcmd = check_nextcmd(ea.cmd)) != NULL) { /* * strange vi behaviour: --- 1896,1903 ---- * If we got a line, but no command, then go to the line. * If we find a '|' or '\n' we set ea.nextcmd. */ ! if (*ea.cmd == NUL || comment_start(ea.cmd, starts_with_colon) ! || (ea.nextcmd = check_nextcmd(ea.cmd)) != NULL) { /* * strange vi behaviour: *************** *** 2225,2231 **** ea.do_ecmd_cmd = getargcmd(&ea.arg); /* ! * Check for '|' to separate commands and '"' to start comments. * Don't do this for ":read !cmd" and ":write !cmd". */ if ((ea.argt & EX_TRLBAR) && !ea.usefilter) --- 2231,2237 ---- ea.do_ecmd_cmd = getargcmd(&ea.arg); /* ! * Check for '|' to separate commands and '"' or '#' to start comments. * Don't do this for ":read !cmd" and ":write !cmd". */ if ((ea.argt & EX_TRLBAR) && !ea.usefilter) *************** *** 2659,2665 **** int parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only) { ! char_u *p; CLEAR_FIELD(cmdmod); eap->verbose_save = -1; --- 2665,2672 ---- int parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only) { ! char_u *p; ! int starts_with_colon = FALSE; CLEAR_FIELD(cmdmod); eap->verbose_save = -1; *************** *** 2669,2675 **** --- 2676,2686 ---- for (;;) { while (*eap->cmd == ' ' || *eap->cmd == '\t' || *eap->cmd == ':') + { + if (*eap->cmd == ':') + starts_with_colon = TRUE; ++eap->cmd; + } // in ex mode, an empty line works like :+ if (*eap->cmd == NUL && exmode_active *************** *** 2683,2689 **** } // ignore comment and empty lines ! if (*eap->cmd == '"') return FAIL; if (*eap->cmd == NUL) { --- 2694,2700 ---- } // ignore comment and empty lines ! if (comment_start(eap->cmd, starts_with_colon)) return FAIL; if (*eap->cmd == NUL) { *************** *** 4521,4534 **** // Check for '"': start of comment or '|': next command // :@" and :*" do not start a comment! // :redir @" doesn't either. ! else if ((*p == '"' && !(eap->argt & EX_NOTRLCOM) && ((eap->cmdidx != CMD_at && eap->cmdidx != CMD_star) ! || p != eap->arg) && (eap->cmdidx != CMD_redir ! || p != eap->arg + 1 || p[-1] != '@')) #ifdef FEAT_EVAL ! || (*p == '#' && in_vim9script() ! && p[1] != '{' && p > eap->cmd && VIM_ISWHITE(p[-1])) #endif || *p == '|' || *p == '\n') { --- 4532,4551 ---- // Check for '"': start of comment or '|': next command // :@" and :*" do not start a comment! // :redir @" doesn't either. ! else if ((*p == '"' ! #ifdef FEAT_EVAL ! && !in_vim9script() ! #endif ! && !(eap->argt & EX_NOTRLCOM) && ((eap->cmdidx != CMD_at && eap->cmdidx != CMD_star) ! || p != eap->arg) && (eap->cmdidx != CMD_redir ! || p != eap->arg + 1 || p[-1] != '@')) #ifdef FEAT_EVAL ! || (*p == '#' ! && in_vim9script() ! && p[1] != '{' ! && p > eap->cmd && VIM_ISWHITE(p[-1])) #endif || *p == '|' || *p == '\n') { *************** *** 4867,4877 **** int ends_excmd(int c) { #ifdef FEAT_EVAL ! if (c == '#') ! return in_vim9script(); #endif ! return (c == NUL || c == '|' || c == '"' || c == '\n'); } /* --- 4884,4896 ---- int ends_excmd(int c) { + int comment_char = '"'; + #ifdef FEAT_EVAL ! if (in_vim9script()) ! comment_char = '#'; #endif ! return (c == NUL || c == '|' || c == comment_char || c == '\n'); } /* *************** *** 4883,4893 **** { int c = *cmd; #ifdef FEAT_EVAL ! if (c == '#' && cmd[1] != '{' && (cmd == cmd_start || VIM_ISWHITE(cmd[-1]))) ! return in_vim9script(); #endif ! return (c == NUL || c == '|' || c == '"' || c == '\n'); } #if defined(FEAT_SYN_HL) || defined(FEAT_SEARCH_EXTRA) || defined(FEAT_EVAL) \ --- 4902,4915 ---- { int c = *cmd; + if (c == NUL || c == '|' || c == '\n') + return TRUE; #ifdef FEAT_EVAL ! if (in_vim9script()) ! return c == '#' && cmd[1] != '{' ! && (cmd == cmd_start || VIM_ISWHITE(cmd[-1])); #endif ! return c == '"'; } #if defined(FEAT_SYN_HL) || defined(FEAT_SEARCH_EXTRA) || defined(FEAT_EVAL) \ *************** *** 7029,7035 **** eap->nextcmd = check_nextcmd(p); p = skipwhite(p); ! if (*p != NUL && *p != '"' && eap->nextcmd == NULL) emsg(_(e_invarg)); else if (!eap->skip) { --- 7051,7062 ---- eap->nextcmd = check_nextcmd(p); p = skipwhite(p); ! if (*p != NUL && *p != ( ! #ifdef FEAT_EVAL ! in_vim9script() ? '#' : ! #endif ! '"') ! && eap->nextcmd == NULL) emsg(_(e_invarg)); else if (!eap->skip) { *** ../vim-8.2.1226/src/proto/ex_docmd.pro 2020-07-05 18:18:24.342937456 +0200 --- src/proto/ex_docmd.pro 2020-07-17 18:30:35.250672884 +0200 *************** *** 5,10 **** --- 5,11 ---- int getline_equal(char_u *(*fgetline)(int, void *, int, int), void *cookie, char_u *(*func)(int, void *, int, int)); void *getline_cookie(char_u *(*fgetline)(int, void *, int, int), void *cookie); char_u *getline_peek(char_u *(*fgetline)(int, void *, int, int), void *cookie); + int comment_start(char_u *p, int starts_with_colon); int parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only); void undo_cmdmod(exarg_T *eap, int save_msg_scroll); int parse_cmd_address(exarg_T *eap, char **errormsg, int silent); *** ../vim-8.2.1226/src/vim9compile.c 2020-07-15 19:48:14.216759531 +0200 --- src/vim9compile.c 2020-07-17 20:20:32.640147868 +0200 *************** *** 2420,2426 **** * Return TRUE if "p" points at a "#" but not at "#{". */ static int ! comment_start(char_u *p) { return p[0] == '#' && p[1] != '{'; } --- 2420,2426 ---- * Return TRUE if "p" points at a "#" but not at "#{". */ static int ! vim9_comment_start(char_u *p) { return p[0] == '#' && p[1] != '{'; } *************** *** 2443,2449 **** if (line == NULL) break; p = skipwhite(line); ! if (*p != NUL && !comment_start(p)) return p; } return NULL; --- 2443,2449 ---- if (line == NULL) break; p = skipwhite(line); ! if (*p != NUL && !vim9_comment_start(p)) return p; } return NULL; *************** *** 2461,2467 **** char_u *p = skipwhite(arg); *nextp = NULL; ! if (*p == NUL || (VIM_ISWHITE(*arg) && comment_start(p))) { *nextp = peek_next_line_from_context(cctx); if (*nextp != NULL) --- 2461,2467 ---- char_u *p = skipwhite(arg); *nextp = NULL; ! if (*p == NUL || (VIM_ISWHITE(*arg) && vim9_comment_start(p))) { *nextp = peek_next_line_from_context(cctx); if (*nextp != NULL) *************** *** 2492,2498 **** cctx->ctx_line_start = line; SOURCING_LNUM = cctx->ctx_lnum + 1; } while (line == NULL || *skipwhite(line) == NUL ! || (skip_comment && comment_start(skipwhite(line)))); return line; } --- 2492,2498 ---- cctx->ctx_line_start = line; SOURCING_LNUM = cctx->ctx_lnum + 1; } while (line == NULL || *skipwhite(line) == NUL ! || (skip_comment && vim9_comment_start(skipwhite(line)))); return line; } *************** *** 2504,2510 **** static int may_get_next_line(char_u *whitep, char_u **arg, cctx_T *cctx) { ! if (**arg == NUL || (VIM_ISWHITE(*whitep) && comment_start(*arg))) { char_u *next = next_line_from_context(cctx, TRUE); --- 2504,2510 ---- static int may_get_next_line(char_u *whitep, char_u **arg, cctx_T *cctx) { ! if (**arg == NUL || (VIM_ISWHITE(*whitep) && vim9_comment_start(*arg))) { char_u *next = next_line_from_context(cctx, TRUE); *************** *** 3100,3106 **** { ++p; // Allow for following comment, after at least one space. ! if (VIM_ISWHITE(*p) && *skipwhite(p) == '"') p += STRLEN(p); break; } --- 3100,3106 ---- { ++p; // Allow for following comment, after at least one space. ! if (VIM_ISWHITE(*p) && *skipwhite(p) == '#') p += STRLEN(p); break; } *************** *** 3157,3162 **** --- 3157,3164 ---- if (ufunc->uf_def_status == UF_COMPILED) return generate_FUNCREF(cctx, ufunc->uf_dfunc_idx); + + func_ptr_unref(ufunc); return FAIL; } *************** *** 3201,3206 **** --- 3203,3210 ---- // call the compiled function ret = generate_CALL(cctx, ufunc, argcount); + if (ret == FAIL) + func_ptr_unref(ufunc); return ret; } *************** *** 3327,3333 **** // Allow for following comment, after at least one space. p = skipwhite(*arg); ! if (VIM_ISWHITE(**arg) && (*p == '"' || comment_start(p))) *arg += STRLEN(*arg); dict_unref(d); --- 3331,3337 ---- // Allow for following comment, after at least one space. p = skipwhite(*arg); ! if (VIM_ISWHITE(**arg) && vim9_comment_start(p)) *arg += STRLEN(*arg); dict_unref(d); *************** *** 3618,3624 **** { char_u *p = skipwhite(*arg); ! if (*p == NUL || (VIM_ISWHITE(**arg) && comment_start(p))) { char_u *next = peek_next_line_from_context(cctx); --- 3622,3628 ---- { char_u *p = skipwhite(*arg); ! if (*p == NUL || (VIM_ISWHITE(**arg) && vim9_comment_start(p))) { char_u *next = peek_next_line_from_context(cctx); *** ../vim-8.2.1226/src/testdir/test_vim9_disassemble.vim 2020-07-13 18:17:53.279714725 +0200 --- src/testdir/test_vim9_disassemble.vim 2020-07-17 20:03:14.079697549 +0200 *************** *** 463,469 **** '\d RETURN', res) ! " Calling the function will change UCALL into the faster DCALL assert_equal('yes', FuncWithForwardCall()) res = execute('disass s:FuncWithForwardCall') --- 463,469 ---- '\d RETURN', res) ! # Calling the function will change UCALL into the faster DCALL assert_equal('yes', FuncWithForwardCall()) res = execute('disass s:FuncWithForwardCall') *************** *** 1073,1079 **** let nr = 1 for case in cases ! " declare local variables to get a non-constant with the right type writefile(['def TestCase' .. nr .. '()', ' let isFalse = false', ' let isNull = v:null', --- 1073,1079 ---- let nr = 1 for case in cases ! # declare local variables to get a non-constant with the right type writefile(['def TestCase' .. nr .. '()', ' let isFalse = false', ' let isNull = v:null', *************** *** 1121,1127 **** source Xdisassemble let instr = execute('disassemble TestCase' .. nr) if case[1] ! " condition true, "echo 42" executed assert_match('TestCase' .. nr .. '.*' .. 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' .. '\d PUSHNR 42.*' .. --- 1121,1127 ---- source Xdisassemble let instr = execute('disassemble TestCase' .. nr) if case[1] ! # condition true, "echo 42" executed assert_match('TestCase' .. nr .. '.*' .. 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' .. '\d PUSHNR 42.*' .. *************** *** 1130,1136 **** '\d RETURN.*', instr) else ! " condition false, function just returns assert_match('TestCase' .. nr .. '.*' .. 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' .. 'echo 42[ \n]*' .. --- 1130,1136 ---- '\d RETURN.*', instr) else ! # condition false, function just returns assert_match('TestCase' .. nr .. '.*' .. 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' .. 'echo 42[ \n]*' .. *************** *** 1245,1251 **** writefile(lines, 'Xdisassemble') source Xdisassemble ! " check that the first function calls the second with DCALL assert_match('\\d*_FuncOne\_s*' .. 'return FuncTwo()\_s*' .. '\d DCALL \d\+_FuncTwo(argc 0)\_s*' .. --- 1245,1251 ---- writefile(lines, 'Xdisassemble') source Xdisassemble ! # check that the first function calls the second with DCALL assert_match('\\d*_FuncOne\_s*' .. 'return FuncTwo()\_s*' .. '\d DCALL \d\+_FuncTwo(argc 0)\_s*' .. *** ../vim-8.2.1226/src/testdir/test_vim9_expr.vim 2020-07-14 15:01:00.468662548 +0200 --- src/testdir/test_vim9_expr.vim 2020-07-17 20:05:21.895191200 +0200 *************** *** 46,52 **** enddef def Test_expr1_vimscript() ! " only checks line continuation let lines =<< trim END vim9script let var = 1 --- 46,52 ---- enddef def Test_expr1_vimscript() ! # only checks line continuation let lines =<< trim END vim9script let var = 1 *************** *** 127,133 **** enddef def Test_expr2_vimscript() ! " check line continuation let lines =<< trim END vim9script let var = 0 --- 127,133 ---- enddef def Test_expr2_vimscript() ! # check line continuation let lines =<< trim END vim9script let var = 0 *************** *** 154,160 **** END CheckScriptSuccess(lines) ! " check keeping the value lines =<< trim END vim9script assert_equal(2, 2 || 0) --- 154,160 ---- END CheckScriptSuccess(lines) ! # check keeping the value lines =<< trim END vim9script assert_equal(2, 2 || 0) *************** *** 231,237 **** enddef def Test_expr3_vimscript() ! " check line continuation let lines =<< trim END vim9script let var = 0 --- 231,237 ---- enddef def Test_expr3_vimscript() ! # check line continuation let lines =<< trim END vim9script let var = 0 *************** *** 258,264 **** END CheckScriptSuccess(lines) ! " check keeping the value lines =<< trim END vim9script assert_equal(0, 2 && 0) --- 258,264 ---- END CheckScriptSuccess(lines) ! # check keeping the value lines =<< trim END vim9script assert_equal(0, 2 && 0) *************** *** 625,631 **** enddef def Test_expr4_vimscript() ! " check line continuation let lines =<< trim END vim9script let var = 0 --- 625,631 ---- enddef def Test_expr4_vimscript() ! # check line continuation let lines =<< trim END vim9script let var = 0 *************** *** 668,674 **** END CheckScriptSuccess(lines) ! " spot check mismatching types lines =<< trim END vim9script echo '' == 0 --- 668,674 ---- END CheckScriptSuccess(lines) ! # spot check mismatching types lines =<< trim END vim9script echo '' == 0 *************** *** 791,797 **** enddef def Test_expr5_vim9script() ! " only checks line continuation let lines =<< trim END vim9script let var = 11 --- 791,797 ---- enddef def Test_expr5_vim9script() ! # only checks line continuation let lines =<< trim END vim9script let var = 11 *************** *** 902,908 **** enddef def Test_expr6_vim9script() ! " only checks line continuation let lines =<< trim END vim9script let var = 11 --- 902,908 ---- enddef def Test_expr6_vim9script() ! # only checks line continuation let lines =<< trim END vim9script let var = 11 *************** *** 1024,1030 **** " test low level expression def Test_expr7_number() ! " number constant assert_equal(0, 0) assert_equal(654, 0654) --- 1024,1030 ---- " test low level expression def Test_expr7_number() ! # number constant assert_equal(0, 0) assert_equal(654, 0654) *************** *** 1034,1040 **** enddef def Test_expr7_float() ! " float constant if !has('float') MissingFeature 'float' else --- 1034,1040 ---- enddef def Test_expr7_float() ! # float constant if !has('float') MissingFeature 'float' else *************** *** 1046,1052 **** enddef def Test_expr7_blob() ! " blob constant assert_equal(g:blob_empty, 0z) assert_equal(g:blob_one, 0z01) assert_equal(g:blob_long, 0z0102.0304) --- 1046,1052 ---- enddef def Test_expr7_blob() ! # blob constant assert_equal(g:blob_empty, 0z) assert_equal(g:blob_one, 0z01) assert_equal(g:blob_long, 0z0102.0304) *************** *** 1055,1061 **** enddef def Test_expr7_string() ! " string constant assert_equal(g:string_empty, '') assert_equal(g:string_empty, "") assert_equal(g:string_short, 'x') --- 1055,1061 ---- enddef def Test_expr7_string() ! # string constant assert_equal(g:string_empty, '') assert_equal(g:string_empty, "") assert_equal(g:string_short, 'x') *************** *** 1077,1083 **** enddef def Test_expr7_special() ! " special constant assert_equal(g:special_true, true) assert_equal(g:special_false, false) assert_equal(g:special_true, v:true) --- 1077,1083 ---- enddef def Test_expr7_special() ! # special constant assert_equal(g:special_true, true) assert_equal(g:special_false, false) assert_equal(g:special_true, v:true) *************** *** 1106,1112 **** enddef def Test_expr7_list() ! " list assert_equal(g:list_empty, []) assert_equal(g:list_empty, [ ]) assert_equal(g:list_mixed, [1, 'b', false,]) --- 1106,1112 ---- enddef def Test_expr7_list() ! # list assert_equal(g:list_empty, []) assert_equal(g:list_empty, [ ]) assert_equal(g:list_mixed, [1, 'b', false,]) *************** *** 1152,1158 **** assert_equal('result', La()) assert_equal([1, 3, 5], [1, 2, 3]->map({key, val -> key + val})) ! " line continuation inside lambda with "cond ? expr : expr" works let ll = range(3) map(ll, {k, v -> v % 2 ? { '111': 111 } : {} --- 1152,1158 ---- assert_equal('result', La()) assert_equal([1, 3, 5], [1, 2, 3]->map({key, val -> key + val})) ! # line continuation inside lambda with "cond ? expr : expr" works let ll = range(3) map(ll, {k, v -> v % 2 ? { '111': 111 } : {} *************** *** 1189,1195 **** enddef def Test_expr7_dict() ! " dictionary assert_equal(g:dict_empty, {}) assert_equal(g:dict_empty, { }) assert_equal(g:dict_one, {'one': 1}) --- 1189,1195 ---- enddef def Test_expr7_dict() ! # dictionary assert_equal(g:dict_empty, {}) assert_equal(g:dict_empty, { }) assert_equal(g:dict_one, {'one': 1}) *************** *** 1316,1322 **** enddef def Test_expr7_option() ! " option set ts=11 assert_equal(11, &ts) &ts = 9 --- 1316,1322 ---- enddef def Test_expr7_option() ! # option set ts=11 assert_equal(11, &ts) &ts = 9 *************** *** 1330,1336 **** enddef def Test_expr7_environment() ! " environment variable assert_equal('testvar', $TESTVAR) assert_equal('', $ASDF_ASD_XXX) --- 1330,1336 ---- enddef def Test_expr7_environment() ! # environment variable assert_equal('testvar', $TESTVAR) assert_equal('', $ASDF_ASD_XXX) *************** *** 1343,1349 **** enddef def Test_expr7_parens() ! " (expr) assert_equal(4, (6 * 4) / 6) assert_equal(0, 6 * ( 4 / 6 )) --- 1343,1349 ---- enddef def Test_expr7_parens() ! # (expr) assert_equal(4, (6 * 4) / 6) assert_equal(0, 6 * ( 4 / 6 )) *************** *** 1474,1480 **** endfunc def Test_expr7_trailing() ! " user function call assert_equal(123, g:CallMe(123)) assert_equal(123, g:CallMe( 123)) assert_equal(123, g:CallMe(123 )) --- 1474,1480 ---- endfunc def Test_expr7_trailing() ! # user function call assert_equal(123, g:CallMe(123)) assert_equal(123, g:CallMe( 123)) assert_equal(123, g:CallMe(123 )) *************** *** 1482,1507 **** assert_equal('yesno', g:CallMe2( 'yes', 'no' )) assert_equal('nothing', g:CallMe('nothing')) ! " partial call let Part = function('g:CallMe') assert_equal('yes', Part('yes')) ! " funcref call, using list index let l = [] g:Funcrefs[0](l, 2) assert_equal([2], l) ! " method call l = [2, 5, 6] l->map({k, v -> k + v}) assert_equal([2, 6, 8], l) ! " lambda method call l = [2, 5] l->{l -> add(l, 8)}() assert_equal([2, 5, 8], l) ! " dict member let d = #{key: 123} assert_equal(123, d.key) enddef --- 1482,1507 ---- assert_equal('yesno', g:CallMe2( 'yes', 'no' )) assert_equal('nothing', g:CallMe('nothing')) ! # partial call let Part = function('g:CallMe') assert_equal('yes', Part('yes')) ! # funcref call, using list index let l = [] g:Funcrefs[0](l, 2) assert_equal([2], l) ! # method call l = [2, 5, 6] l->map({k, v -> k + v}) assert_equal([2, 6, 8], l) ! # lambda method call l = [2, 5] l->{l -> add(l, 8)}() assert_equal([2, 5, 8], l) ! # dict member let d = #{key: 123} assert_equal(123, d.key) enddef *** ../vim-8.2.1226/src/testdir/test_vim9_func.vim 2020-07-15 22:38:52.681292060 +0200 --- src/testdir/test_vim9_func.vim 2020-07-17 20:06:51.742853413 +0200 *************** *** 80,86 **** Increment() Increment() Increment() ! " works with and without :call assert_equal(4, g:counter) call assert_equal(4, g:counter) unlet g:counter --- 80,86 ---- Increment() Increment() Increment() ! # works with and without :call assert_equal(4, g:counter) call assert_equal(4, g:counter) unlet g:counter *************** *** 236,242 **** enddef def Test_assign_to_argument() ! " works for dict and list let d: dict = {} DictArg(d) assert_equal('value', d['key']) --- 236,242 ---- enddef def Test_assign_to_argument() ! # works for dict and list let d: dict = {} DictArg(d) assert_equal('value', d['key']) *************** *** 266,284 **** let NotAFunc = 'text' def CombineFuncrefTypes() ! " same arguments, different return type let Ref1: func(bool): string let Ref2: func(bool): number let Ref3: func(bool): any Ref3 = g:cond ? Ref1 : Ref2 ! " different number of arguments let Refa1: func(bool): number let Refa2: func(bool, number): number let Refa3: func: number Refa3 = g:cond ? Refa1 : Refa2 ! " different argument types let Refb1: func(bool, string): number let Refb2: func(string, number): number let Refb3: func(any, any): number --- 266,284 ---- let NotAFunc = 'text' def CombineFuncrefTypes() ! # same arguments, different return type let Ref1: func(bool): string let Ref2: func(bool): number let Ref3: func(bool): any Ref3 = g:cond ? Ref1 : Ref2 ! # different number of arguments let Refa1: func(bool): number let Refa2: func(bool, number): number let Refa3: func: number Refa3 = g:cond ? Refa1 : Refa2 ! # different argument types let Refb1: func(bool, string): number let Refb2: func(string, number): number let Refb3: func(any, any): number *************** *** 294,300 **** enddef def Test_error_in_nested_function() ! " Error in called function requires unwinding the call stack. assert_fails('call FuncWithForwardCall()', 'E1096') enddef --- 294,300 ---- enddef def Test_error_in_nested_function() ! # Error in called function requires unwinding the call stack. assert_fails('call FuncWithForwardCall()', 'E1096') enddef *** ../vim-8.2.1226/src/testdir/test_vim9_script.vim 2020-07-11 22:14:54.318422203 +0200 --- src/testdir/test_vim9_script.vim 2020-07-17 19:58:03.768764552 +0200 *************** *** 113,119 **** let lines =<< trim END vim9script ! " single character variable declarations work let a: string let b: number let l: list --- 113,119 ---- let lines =<< trim END vim9script ! # single character variable declarations work let a: string let b: number let l: list *************** *** 122,128 **** let v: number let w: number ! " script-local variables can be used without s: prefix a = 'script-a' b = 111 l = [1, 2, 3] --- 122,128 ---- let v: number let w: number ! # script-local variables can be used without s: prefix a = 'script-a' b = 111 l = [1, 2, 3] *************** *** 175,181 **** let dict4: dict = #{one: 1, two: '2'} let dict5: dict = #{one: 0z01, two: 0z02} ! " overwrite dict3['key'] = 'another' call CheckDefExecFailure(['let dd = {}', 'dd[""] = 6'], 'E713:') --- 175,181 ---- let dict4: dict = #{one: 1, two: '2'} let dict5: dict = #{one: 0z01, two: 0z02} ! # overwrite dict3['key'] = 'another' call CheckDefExecFailure(['let dd = {}', 'dd[""] = 6'], 'E713:') *************** *** 185,192 **** enddef def Test_assignment_local() ! " Test in a separated file in order not to the current buffer/window/tab is ! " changed. let script_lines: list =<< trim END let b:existing = 'yes' let w:existing = 'yes' --- 185,192 ---- enddef def Test_assignment_local() ! # Test in a separated file in order not to the current buffer/window/tab is ! # changed. let script_lines: list =<< trim END let b:existing = 'yes' let w:existing = 'yes' *************** *** 259,265 **** assert_equal(test_null_channel(), thechannel) if has('unix') && executable('cat') ! " check with non-null job and channel, types must match thejob = job_start("cat ", #{}) thechannel = job_getchannel(thejob) job_stop(thejob, 'kill') --- 259,265 ---- assert_equal(test_null_channel(), thechannel) if has('unix') && executable('cat') ! # check with non-null job and channel, types must match thejob = job_start("cat ", #{}) thechannel = job_getchannel(thejob) job_stop(thejob, 'kill') *************** *** 394,400 **** enddef def Test_delfunction() ! " Check function is defined in script namespace CheckScriptSuccess([ 'vim9script', 'func CheckMe()', --- 394,400 ---- enddef def Test_delfunction() ! # Check function is defined in script namespace CheckScriptSuccess([ 'vim9script', 'func CheckMe()', *************** *** 403,409 **** 'assert_equal(123, s:CheckMe())', ]) ! " Check function in script namespace cannot be deleted CheckScriptFailure([ 'vim9script', 'func DeleteMe1()', --- 403,409 ---- 'assert_equal(123, s:CheckMe())', ]) ! # Check function in script namespace cannot be deleted CheckScriptFailure([ 'vim9script', 'func DeleteMe1()', *************** *** 586,592 **** enddef def Test_throw_vimscript() ! " only checks line continuation let lines =<< trim END vim9script try --- 586,592 ---- enddef def Test_throw_vimscript() ! # only checks line continuation let lines =<< trim END vim9script try *************** *** 600,606 **** enddef def Test_cexpr_vimscript() ! " only checks line continuation set errorformat=File\ %f\ line\ %l let lines =<< trim END vim9script --- 600,606 ---- enddef def Test_cexpr_vimscript() ! # only checks line continuation set errorformat=File\ %f\ line\ %l let lines =<< trim END vim9script *************** *** 727,733 **** END writefile(import_in_def_lines, 'Ximport2.vim') source Ximport2.vim ! " TODO: this should be 9879 assert_equal(9876, g:imported) assert_equal(9883, g:imported_added) unlet g:imported --- 727,733 ---- END writefile(import_in_def_lines, 'Ximport2.vim') source Ximport2.vim ! # TODO: this should be 9879 assert_equal(9876, g:imported) assert_equal(9883, g:imported_added) unlet g:imported *************** *** 802,808 **** writefile(import_star_lines, 'Ximport.vim') assert_fails('source Ximport.vim', 'E1045:') ! " try to import something that exists but is not exported let import_not_exported_lines =<< trim END vim9script import name from './Xexport.vim' --- 802,808 ---- writefile(import_star_lines, 'Ximport.vim') assert_fails('source Ximport.vim', 'E1045:') ! # try to import something that exists but is not exported let import_not_exported_lines =<< trim END vim9script import name from './Xexport.vim' *************** *** 810,816 **** writefile(import_not_exported_lines, 'Ximport.vim') assert_fails('source Ximport.vim', 'E1049:') ! " try to import something that is already defined let import_already_defined =<< trim END vim9script let exported = 'something' --- 810,816 ---- writefile(import_not_exported_lines, 'Ximport.vim') assert_fails('source Ximport.vim', 'E1049:') ! # try to import something that is already defined let import_already_defined =<< trim END vim9script let exported = 'something' *************** *** 819,825 **** writefile(import_already_defined, 'Ximport.vim') assert_fails('source Ximport.vim', 'E1073:') ! " try to import something that is already defined import_already_defined =<< trim END vim9script let exported = 'something' --- 819,825 ---- writefile(import_already_defined, 'Ximport.vim') assert_fails('source Ximport.vim', 'E1073:') ! # try to import something that is already defined import_already_defined =<< trim END vim9script let exported = 'something' *************** *** 828,834 **** writefile(import_already_defined, 'Ximport.vim') assert_fails('source Ximport.vim', 'E1073:') ! " try to import something that is already defined import_already_defined =<< trim END vim9script let exported = 'something' --- 828,834 ---- writefile(import_already_defined, 'Ximport.vim') assert_fails('source Ximport.vim', 'E1073:') ! # try to import something that is already defined import_already_defined =<< trim END vim9script let exported = 'something' *************** *** 837,843 **** writefile(import_already_defined, 'Ximport.vim') assert_fails('source Ximport.vim', 'E1073:') ! " import a very long name, requires making a copy let import_long_name_lines =<< trim END vim9script import name012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 from './Xexport.vim' --- 837,843 ---- writefile(import_already_defined, 'Ximport.vim') assert_fails('source Ximport.vim', 'E1073:') ! # import a very long name, requires making a copy let import_long_name_lines =<< trim END vim9script import name012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 from './Xexport.vim' *************** *** 877,883 **** delete('Ximport3.vim') delete('Xexport.vim') ! " Check that in a Vim9 script 'cpo' is set to the Vim default. set cpo&vi let cpo_before = &cpo let lines =<< trim END --- 877,883 ---- delete('Ximport3.vim') delete('Xexport.vim') ! # Check that in a Vim9 script 'cpo' is set to the Vim default. set cpo&vi let cpo_before = &cpo let lines =<< trim END *************** *** 962,973 **** writefile(testlines, 'Ximport.vim') source Ximport.vim ! " Test that when not using "morelines" GetValtwo() and valtwo are still ! " defined, because import doesn't reload a script. writefile(lines, 'Xreload.vim') source Ximport.vim ! " cannot declare a var twice lines =<< trim END vim9script let valone = 1234 --- 962,973 ---- writefile(testlines, 'Ximport.vim') source Ximport.vim ! # Test that when not using "morelines" GetValtwo() and valtwo are still ! # defined, because import doesn't reload a script. writefile(lines, 'Xreload.vim') source Ximport.vim ! # cannot declare a var twice lines =<< trim END vim9script let valone = 1234 *************** *** 1185,1191 **** try source Ximport.vim catch /E1001/ ! " Error should be fore the Xexported.vim file. assert_match('E1001: variable not found: notDefined', v:exception) assert_match('function \d\+_ImpFunc\[1\]..\d\+_ExpFunc, line 1', v:throwpoint) endtry --- 1185,1191 ---- try source Ximport.vim catch /E1001/ ! # Error should be fore the Xexported.vim file. assert_match('E1001: variable not found: notDefined', v:exception) assert_match('function \d\+_ImpFunc\[1\]..\d\+_ExpFunc, line 1', v:throwpoint) endtry *************** *** 1195,1201 **** enddef def Test_fixed_size_list() ! " will be allocated as one piece of memory, check that changes work let l = [1, 2, 3, 4] l->remove(0) l->add(5) --- 1195,1201 ---- enddef def Test_fixed_size_list() ! # will be allocated as one piece of memory, check that changes work let l = [1, 2, 3, 4] l->remove(0) l->add(5) *************** *** 1357,1365 **** let x: number = 0 if i % 2 if 1 ! " comment else ! " comment endif x += 1 else --- 1357,1365 ---- let x: number = 0 if i % 2 if 1 ! # comment else ! # comment endif x += 1 else *************** *** 1401,1407 **** enddef def Test_execute_cmd_vimscript() ! " only checks line continuation let lines =<< trim END vim9script execute 'g:someVar' --- 1401,1407 ---- enddef def Test_execute_cmd_vimscript() ! # only checks line continuation let lines =<< trim END vim9script execute 'g:someVar' *************** *** 1441,1447 **** enddef def Test_echomsg_cmd_vimscript() ! " only checks line continuation let lines =<< trim END vim9script echomsg 'here' --- 1441,1447 ---- enddef def Test_echomsg_cmd_vimscript() ! # only checks line continuation let lines =<< trim END vim9script echomsg 'here' *************** *** 1461,1467 **** enddef def Test_echoerr_cmd_vimscript() ! " only checks line continuation let lines =<< trim END vim9script try --- 1461,1467 ---- enddef def Test_echoerr_cmd_vimscript() ! # only checks line continuation let lines =<< trim END vim9script try *************** *** 1569,1575 **** 'one', 'two', 'three', ! ] " comment assert_equal(['one', 'two', 'three'], mylist) let mydict = { --- 1569,1575 ---- 'one', 'two', 'three', ! ] # comment assert_equal(['one', 'two', 'three'], mylist) let mydict = { *************** *** 1577,1583 **** 'two': 2, 'three': 3, ! } " comment assert_equal({'one': 1, 'two': 2, 'three': 3}, mydict) mydict = #{ one: 1, # comment --- 1577,1583 ---- 'two': 2, 'three': 3, ! } # comment assert_equal({'one': 1, 'two': 2, 'three': 3}, mydict) mydict = #{ one: 1, # comment *************** *** 1754,1761 **** 'hi clear This # comment', 'hi clear # comment', ]) ! " not tested, because it doesn't give an error but a warning: ! " hi clear This# comment', CheckScriptFailure([ 'vim9script', 'hi clear# comment', --- 1754,1761 ---- 'hi clear This # comment', 'hi clear # comment', ]) ! # not tested, because it doesn't give an error but a warning: ! # hi clear This# comment', CheckScriptFailure([ 'vim9script', 'hi clear# comment', *************** *** 2091,2109 **** 'bwipe!', ]) ! " CheckScriptFailure([ ! " 'vim9script', ! " 'new' ! " 'call setline(1, ["# define pat", "last"])', ! " ':$', ! " 'dsearch /pat/#comment', ! " 'bwipe!', ! " ], 'E488:') ! " ! " CheckScriptFailure([ ! " 'vim9script', ! " 'func! SomeFunc()', ! " ], 'E477:') enddef def Test_finish() --- 2091,2109 ---- 'bwipe!', ]) ! CheckScriptFailure([ ! 'vim9script', ! 'new' ! 'call setline(1, ["# define pat", "last"])', ! ':$', ! 'dsearch /pat/#comment', ! 'bwipe!', ! ], 'E488:') ! ! CheckScriptFailure([ ! 'vim9script', ! 'func! SomeFunc()', ! ], 'E477:') enddef def Test_finish() *************** *** 2135,2146 **** return 'this' endfunc let val: string = GetValue() ! " env var is always a string let env = $TERM END writefile(lines, 'Xfinished') source Xfinished ! " GetValue() is not called during discovery phase assert_equal(1, g:count) unlet g:count --- 2135,2146 ---- return 'this' endfunc let val: string = GetValue() ! # env var is always a string let env = $TERM END writefile(lines, 'Xfinished') source Xfinished ! # GetValue() is not called during discovery phase assert_equal(1, g:count) unlet g:count *************** *** 2169,2175 **** g:var_uninit = var var = 'text' g:var_test = var ! " prefixing s: is optional s:var = 'prefixed' g:var_prefixed = s:var --- 2169,2175 ---- g:var_uninit = var var = 'text' g:var_test = var ! # prefixing s: is optional s:var = 'prefixed' g:var_prefixed = s:var *************** *** 2281,2287 **** source Xlegacy_script.vim assert_equal('global', g:global) ! " unlet g:global delete('Xlegacy_script.vim') delete('Xvim9_script.vim') --- 2281,2287 ---- source Xlegacy_script.vim assert_equal('global', g:global) ! unlet g:global delete('Xlegacy_script.vim') delete('Xvim9_script.vim') *************** *** 2301,2307 **** assert_equal('otherthing', getline(1)) bwipe! ! " also when the context is Vim9 script let lines =<< trim END vim9script new --- 2301,2307 ---- assert_equal('otherthing', getline(1)) bwipe! ! # also when the context is Vim9 script let lines =<< trim END vim9script new *** ../vim-8.2.1226/src/version.c 2020-07-16 22:30:27.874455428 +0200 --- src/version.c 2020-07-17 18:20:32.244138193 +0200 *************** *** 756,757 **** --- 756,759 ---- { /* Add new patch number below this line */ + /**/ + 1227, /**/ -- hundred-and-one symptoms of being an internet addict: 30. Even though you died last week, you've managed to retain OPS on your favorite IRC channel. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///