diff options
-rw-r--r-- | runtime/doc/vim9.txt | 29 | ||||
-rw-r--r-- | src/ex_docmd.c | 69 | ||||
-rw-r--r-- | src/proto/ex_docmd.pro | 1 | ||||
-rw-r--r-- | src/testdir/test_vim9_disassemble.vim | 10 | ||||
-rw-r--r-- | src/testdir/test_vim9_expr.vim | 52 | ||||
-rw-r--r-- | src/testdir/test_vim9_func.vim | 12 | ||||
-rw-r--r-- | src/testdir/test_vim9_script.vim | 98 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9compile.c | 20 |
9 files changed, 167 insertions, 126 deletions
diff --git a/runtime/doc/vim9.txt b/runtime/doc/vim9.txt index ad96817ff1..748dd7cd55 100644 --- a/runtime/doc/vim9.txt +++ b/runtime/doc/vim9.txt @@ -1,4 +1,4 @@ -*vim9.txt* For Vim version 8.2. Last change: 2020 Jul 10 +*vim9.txt* For Vim version 8.2. Last change: 2020 Jul 17 VIM REFERENCE MANUAL by Bram Moolenaar @@ -64,20 +64,24 @@ THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE Comments starting with # ~ -In Vim script comments 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 -normally starts with #. In Vi this is a command to list text with numbers, -but you can also use `:number` for that. > +In legacy Vim script comments start with double quote. In Vim9 script +comments start with #. > + # declarations let count = 0 # number of occurrences -To improve readability there must be a space between the command and the # +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. -Since Vim9 script allows for line breaks in many places, the double quoted -comment also cannot be used at the start of a line after an expression. To -avoid confusion it is best to only use # comments. - Vim9 functions ~ @@ -400,6 +404,7 @@ The boolean operators "||" and "&&" do not change the value: > 0 || '' == '' 8 && 2 == 2 0 && 2 == 0 + 2 && 0 == 0 [] && 2 == [] When using `..` for string concatenation the arguments are always converted to @@ -418,13 +423,15 @@ 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 + ->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: > diff --git a/src/ex_docmd.c b/src/ex_docmd.c index a326d20d3c..bb83eba877 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -1649,6 +1649,16 @@ current_tab_nr(tabpage_T *tab) 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,12 +1896,8 @@ do_one_cmd( * 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) + if (*ea.cmd == NUL || comment_start(ea.cmd, starts_with_colon) + || (ea.nextcmd = check_nextcmd(ea.cmd)) != NULL) { /* * strange vi behaviour: @@ -2225,7 +2231,7 @@ do_one_cmd( ea.do_ecmd_cmd = getargcmd(&ea.arg); /* - * Check for '|' to separate commands and '"' to start comments. + * 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,7 +2665,8 @@ doend: int parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only) { - char_u *p; + char_u *p; + int starts_with_colon = FALSE; CLEAR_FIELD(cmdmod); eap->verbose_save = -1; @@ -2669,7 +2676,11 @@ parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only) 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,7 +2694,7 @@ parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only) } // ignore comment and empty lines - if (*eap->cmd == '"') + if (comment_start(eap->cmd, starts_with_colon)) return FAIL; if (*eap->cmd == NUL) { @@ -4521,14 +4532,20 @@ separate_nextcmd(exarg_T *eap) // 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) + else if ((*p == '"' +#ifdef FEAT_EVAL + && !in_vim9script() +#endif + && !(eap->argt & EX_NOTRLCOM) && ((eap->cmdidx != CMD_at && eap->cmdidx != CMD_star) - || p != eap->arg) + || p != eap->arg) && (eap->cmdidx != CMD_redir - || p != eap->arg + 1 || p[-1] != '@')) + || p != eap->arg + 1 || p[-1] != '@')) #ifdef FEAT_EVAL - || (*p == '#' && in_vim9script() - && p[1] != '{' && p > eap->cmd && VIM_ISWHITE(p[-1])) + || (*p == '#' + && in_vim9script() + && p[1] != '{' + && p > eap->cmd && VIM_ISWHITE(p[-1])) #endif || *p == '|' || *p == '\n') { @@ -4867,11 +4884,13 @@ ex_blast(exarg_T *eap) int ends_excmd(int c) { + int comment_char = '"'; + #ifdef FEAT_EVAL - if (c == '#') - return in_vim9script(); + if (in_vim9script()) + comment_char = '#'; #endif - return (c == NUL || c == '|' || c == '"' || c == '\n'); + return (c == NUL || c == '|' || c == comment_char || c == '\n'); } /* @@ -4883,11 +4902,14 @@ ends_excmd2(char_u *cmd_start UNUSED, char_u *cmd) { int c = *cmd; + if (c == NUL || c == '|' || c == '\n') + return TRUE; #ifdef FEAT_EVAL - if (c == '#' && cmd[1] != '{' && (cmd == cmd_start || VIM_ISWHITE(cmd[-1]))) - return in_vim9script(); + if (in_vim9script()) + return c == '#' && cmd[1] != '{' + && (cmd == cmd_start || VIM_ISWHITE(cmd[-1])); #endif - return (c == NUL || c == '|' || c == '"' || c == '\n'); + return c == '"'; } #if defined(FEAT_SYN_HL) || defined(FEAT_SEARCH_EXTRA) || defined(FEAT_EVAL) \ @@ -7029,7 +7051,12 @@ ex_wincmd(exarg_T *eap) eap->nextcmd = check_nextcmd(p); p = skipwhite(p); - if (*p != NUL && *p != '"' && eap->nextcmd == NULL) + if (*p != NUL && *p != ( +#ifdef FEAT_EVAL + in_vim9script() ? '#' : +#endif + '"') + && eap->nextcmd == NULL) emsg(_(e_invarg)); else if (!eap->skip) { diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro index 85050313b6..4881c76af7 100644 --- a/src/proto/ex_docmd.pro +++ b/src/proto/ex_docmd.pro @@ -5,6 +5,7 @@ int do_cmdline(char_u *cmdline, char_u *(*fgetline)(int, void *, int, int), void 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); diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim index f1f943ecb8..186ce6d1c6 100644 --- a/src/testdir/test_vim9_disassemble.vim +++ b/src/testdir/test_vim9_disassemble.vim @@ -463,7 +463,7 @@ def Test_disassemble_update_instr() '\d RETURN', res) - " Calling the function will change UCALL into the faster DCALL + # Calling the function will change UCALL into the faster DCALL assert_equal('yes', FuncWithForwardCall()) res = execute('disass s:FuncWithForwardCall') @@ -1073,7 +1073,7 @@ def Test_disassemble_compare() let nr = 1 for case in cases - " declare local variables to get a non-constant with the right type + # declare local variables to get a non-constant with the right type writefile(['def TestCase' .. nr .. '()', ' let isFalse = false', ' let isNull = v:null', @@ -1121,7 +1121,7 @@ def Test_disassemble_compare_const() source Xdisassemble let instr = execute('disassemble TestCase' .. nr) if case[1] - " condition true, "echo 42" executed + # condition true, "echo 42" executed assert_match('TestCase' .. nr .. '.*' .. 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' .. '\d PUSHNR 42.*' .. @@ -1130,7 +1130,7 @@ def Test_disassemble_compare_const() '\d RETURN.*', instr) else - " condition false, function just returns + # condition false, function just returns assert_match('TestCase' .. nr .. '.*' .. 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' .. 'echo 42[ \n]*' .. @@ -1245,7 +1245,7 @@ def Test_vim9script_forward_func() writefile(lines, 'Xdisassemble') source Xdisassemble - " check that the first function calls the second with DCALL + # check that the first function calls the second with DCALL assert_match('\<SNR>\d*_FuncOne\_s*' .. 'return FuncTwo()\_s*' .. '\d DCALL <SNR>\d\+_FuncTwo(argc 0)\_s*' .. diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim index dc95144800..4c8e6e169f 100644 --- a/src/testdir/test_vim9_expr.vim +++ b/src/testdir/test_vim9_expr.vim @@ -46,7 +46,7 @@ def Test_expr1() enddef def Test_expr1_vimscript() - " only checks line continuation + # only checks line continuation let lines =<< trim END vim9script let var = 1 @@ -127,7 +127,7 @@ def Test_expr2() enddef def Test_expr2_vimscript() - " check line continuation + # check line continuation let lines =<< trim END vim9script let var = 0 @@ -154,7 +154,7 @@ def Test_expr2_vimscript() END CheckScriptSuccess(lines) - " check keeping the value + # check keeping the value lines =<< trim END vim9script assert_equal(2, 2 || 0) @@ -231,7 +231,7 @@ def Test_expr3() enddef def Test_expr3_vimscript() - " check line continuation + # check line continuation let lines =<< trim END vim9script let var = 0 @@ -258,7 +258,7 @@ def Test_expr3_vimscript() END CheckScriptSuccess(lines) - " check keeping the value + # check keeping the value lines =<< trim END vim9script assert_equal(0, 2 && 0) @@ -625,7 +625,7 @@ def RetVoid() enddef def Test_expr4_vimscript() - " check line continuation + # check line continuation let lines =<< trim END vim9script let var = 0 @@ -668,7 +668,7 @@ def Test_expr4_vimscript() END CheckScriptSuccess(lines) - " spot check mismatching types + # spot check mismatching types lines =<< trim END vim9script echo '' == 0 @@ -791,7 +791,7 @@ def Test_expr5() enddef def Test_expr5_vim9script() - " only checks line continuation + # only checks line continuation let lines =<< trim END vim9script let var = 11 @@ -902,7 +902,7 @@ def Test_expr6() enddef def Test_expr6_vim9script() - " only checks line continuation + # only checks line continuation let lines =<< trim END vim9script let var = 11 @@ -1024,7 +1024,7 @@ let $TESTVAR = 'testvar' " test low level expression def Test_expr7_number() - " number constant + # number constant assert_equal(0, 0) assert_equal(654, 0654) @@ -1034,7 +1034,7 @@ def Test_expr7_number() enddef def Test_expr7_float() - " float constant + # float constant if !has('float') MissingFeature 'float' else @@ -1046,7 +1046,7 @@ def Test_expr7_float() enddef def Test_expr7_blob() - " blob constant + # blob constant assert_equal(g:blob_empty, 0z) assert_equal(g:blob_one, 0z01) assert_equal(g:blob_long, 0z0102.0304) @@ -1055,7 +1055,7 @@ def Test_expr7_blob() enddef def Test_expr7_string() - " string constant + # string constant assert_equal(g:string_empty, '') assert_equal(g:string_empty, "") assert_equal(g:string_short, 'x') @@ -1077,7 +1077,7 @@ def Test_expr7_vimvar() enddef def Test_expr7_special() - " special constant + # special constant assert_equal(g:special_true, true) assert_equal(g:special_false, false) assert_equal(g:special_true, v:true) @@ -1106,7 +1106,7 @@ def Test_expr7_special_vim9script() enddef def Test_expr7_list() - " list + # list assert_equal(g:list_empty, []) assert_equal(g:list_empty, [ ]) assert_equal(g:list_mixed, [1, 'b', false,]) @@ -1152,7 +1152,7 @@ def Test_expr7_lambda() 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 + # line continuation inside lambda with "cond ? expr : expr" works let ll = range(3) map(ll, {k, v -> v % 2 ? { '111': 111 } : {} @@ -1189,7 +1189,7 @@ def Test_expr7_lambda_vim9script() enddef def Test_expr7_dict() - " dictionary + # dictionary assert_equal(g:dict_empty, {}) assert_equal(g:dict_empty, { }) assert_equal(g:dict_one, {'one': 1}) @@ -1316,7 +1316,7 @@ def Test_expr_member_vim9script() enddef def Test_expr7_option() - " option + # option set ts=11 assert_equal(11, &ts) &ts = 9 @@ -1330,7 +1330,7 @@ def Test_expr7_option() enddef def Test_expr7_environment() - " environment variable + # environment variable assert_equal('testvar', $TESTVAR) assert_equal('', $ASDF_ASD_XXX) @@ -1343,7 +1343,7 @@ def Test_expr7_register() enddef def Test_expr7_parens() - " (expr) + # (expr) assert_equal(4, (6 * 4) / 6) assert_equal(0, 6 * ( 4 / 6 )) @@ -1474,7 +1474,7 @@ func CallMe2(one, two) endfunc def Test_expr7_trailing() - " user function call + # user function call assert_equal(123, g:CallMe(123)) assert_equal(123, g:CallMe( 123)) assert_equal(123, g:CallMe(123 )) @@ -1482,26 +1482,26 @@ def Test_expr7_trailing() assert_equal('yesno', g:CallMe2( 'yes', 'no' )) assert_equal('nothing', g:CallMe('nothing')) - " partial call + # partial call let Part = function('g:CallMe') assert_equal('yes', Part('yes')) - " funcref call, using list index + # funcref call, using list index let l = [] g:Funcrefs[0](l, 2) assert_equal([2], l) - " method call + # method call l = [2, 5, 6] l->map({k, v -> k + v}) assert_equal([2, 6, 8], l) - " lambda method call + # lambda method call l = [2, 5] l->{l -> add(l, 8)}() assert_equal([2, 5, 8], l) - " dict member + # dict member let d = #{key: 123} assert_equal(123, d.key) enddef diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index d201181fae..9b61821a55 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -80,7 +80,7 @@ def Test_call_ufunc_count() Increment() Increment() Increment() - " works with and without :call + # works with and without :call assert_equal(4, g:counter) call assert_equal(4, g:counter) unlet g:counter @@ -236,7 +236,7 @@ def ListArg(arg: list<string>) enddef def Test_assign_to_argument() - " works for dict and list + # works for dict and list let d: dict<string> = {} DictArg(d) assert_equal('value', d['key']) @@ -266,19 +266,19 @@ let SomeFunc = function('len') let NotAFunc = 'text' def CombineFuncrefTypes() - " same arguments, different return type + # 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 + # 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 + # different argument types let Refb1: func(bool, string): number let Refb2: func(string, number): number let Refb3: func(any, any): number @@ -294,7 +294,7 @@ def DefinedEvenLater(arg: string): string enddef def Test_error_in_nested_function() - " Error in called function requires unwinding the call stack. + # Error in called function requires unwinding the call stack. assert_fails('call FuncWithForwardCall()', 'E1096') enddef diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim index aa0130cce4..24ce668d10 100644 --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -113,7 +113,7 @@ def Test_vim9_single_char_vars() let lines =<< trim END vim9script - " single character variable declarations work + # single character variable declarations work let a: string let b: number let l: list<any> @@ -122,7 +122,7 @@ def Test_vim9_single_char_vars() let v: number let w: number - " script-local variables can be used without s: prefix + # script-local variables can be used without s: prefix a = 'script-a' b = 111 l = [1, 2, 3] @@ -175,7 +175,7 @@ def Test_assignment_dict() let dict4: dict<any> = #{one: 1, two: '2'} let dict5: dict<blob> = #{one: 0z01, two: 0z02} - " overwrite + # overwrite dict3['key'] = 'another' call CheckDefExecFailure(['let dd = {}', 'dd[""] = 6'], 'E713:') @@ -185,8 +185,8 @@ def Test_assignment_dict() enddef def Test_assignment_local() - " Test in a separated file in order not to the current buffer/window/tab is - " changed. + # Test in a separated file in order not to the current buffer/window/tab is + # changed. let script_lines: list<string> =<< trim END let b:existing = 'yes' let w:existing = 'yes' @@ -259,7 +259,7 @@ def Test_assignment_default() assert_equal(test_null_channel(), thechannel) if has('unix') && executable('cat') - " check with non-null job and channel, types must match + # check with non-null job and channel, types must match thejob = job_start("cat ", #{}) thechannel = job_getchannel(thejob) job_stop(thejob, 'kill') @@ -394,7 +394,7 @@ def Test_unlet() enddef def Test_delfunction() - " Check function is defined in script namespace + # Check function is defined in script namespace CheckScriptSuccess([ 'vim9script', 'func CheckMe()', @@ -403,7 +403,7 @@ def Test_delfunction() 'assert_equal(123, s:CheckMe())', ]) - " Check function in script namespace cannot be deleted + # Check function in script namespace cannot be deleted CheckScriptFailure([ 'vim9script', 'func DeleteMe1()', @@ -586,7 +586,7 @@ def Test_try_catch_fails() enddef def Test_throw_vimscript() - " only checks line continuation + # only checks line continuation let lines =<< trim END vim9script try @@ -600,7 +600,7 @@ def Test_throw_vimscript() enddef def Test_cexpr_vimscript() - " only checks line continuation + # only checks line continuation set errorformat=File\ %f\ line\ %l let lines =<< trim END vim9script @@ -727,7 +727,7 @@ def Test_vim9_import_export() END writefile(import_in_def_lines, 'Ximport2.vim') source Ximport2.vim - " TODO: this should be 9879 + # TODO: this should be 9879 assert_equal(9876, g:imported) assert_equal(9883, g:imported_added) unlet g:imported @@ -802,7 +802,7 @@ def Test_vim9_import_export() writefile(import_star_lines, 'Ximport.vim') assert_fails('source Ximport.vim', 'E1045:') - " try to import something that exists but is not exported + # try to import something that exists but is not exported let import_not_exported_lines =<< trim END vim9script import name from './Xexport.vim' @@ -810,7 +810,7 @@ def Test_vim9_import_export() writefile(import_not_exported_lines, 'Ximport.vim') assert_fails('source Ximport.vim', 'E1049:') - " try to import something that is already defined + # try to import something that is already defined let import_already_defined =<< trim END vim9script let exported = 'something' @@ -819,7 +819,7 @@ def Test_vim9_import_export() writefile(import_already_defined, 'Ximport.vim') assert_fails('source Ximport.vim', 'E1073:') - " try to import something that is already defined + # try to import something that is already defined import_already_defined =<< trim END vim9script let exported = 'something' @@ -828,7 +828,7 @@ def Test_vim9_import_export() writefile(import_already_defined, 'Ximport.vim') assert_fails('source Ximport.vim', 'E1073:') - " try to import something that is already defined + # try to import something that is already defined import_already_defined =<< trim END vim9script let exported = 'something' @@ -837,7 +837,7 @@ def Test_vim9_import_export() writefile(import_already_defined, 'Ximport.vim') assert_fails('source Ximport.vim', 'E1073:') - " import a very long name, requires making a copy + # import a very long name, requires making a copy let import_long_name_lines =<< trim END vim9script import name012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 from './Xexport.vim' @@ -877,7 +877,7 @@ def Test_vim9_import_export() delete('Ximport3.vim') delete('Xexport.vim') - " Check that in a Vim9 script 'cpo' is set to the Vim default. + # 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,12 +962,12 @@ def Test_vim9script_reload_import() 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. + # 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 + # cannot declare a var twice lines =<< trim END vim9script let valone = 1234 @@ -1185,7 +1185,7 @@ def Test_import_compile_error() try source Ximport.vim catch /E1001/ - " Error should be fore the Xexported.vim file. + # Error should be fore the Xexported.vim file. assert_match('E1001: variable not found: notDefined', v:exception) assert_match('function <SNR>\d\+_ImpFunc\[1\]..<SNR>\d\+_ExpFunc, line 1', v:throwpoint) endtry @@ -1195,7 +1195,7 @@ def Test_import_compile_error() enddef def Test_fixed_size_list() - " will be allocated as one piece of memory, check that changes work + # 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,9 +1357,9 @@ def RunNested(i: number): number let x: number = 0 if i % 2 if 1 - " comment + # comment else - " comment + # comment endif x += 1 else @@ -1401,7 +1401,7 @@ def Test_execute_cmd() enddef def Test_execute_cmd_vimscript() - " only checks line continuation + # only checks line continuation let lines =<< trim END vim9script execute 'g:someVar' @@ -1441,7 +1441,7 @@ def Test_echomsg_cmd() enddef def Test_echomsg_cmd_vimscript() - " only checks line continuation + # only checks line continuation let lines =<< trim END vim9script echomsg 'here' @@ -1461,7 +1461,7 @@ def Test_echoerr_cmd() enddef def Test_echoerr_cmd_vimscript() - " only checks line continuation + # only checks line continuation let lines =<< trim END vim9script try @@ -1569,7 +1569,7 @@ def Test_automatic_line_continuation() 'one', 'two', 'three', - ] " comment + ] # comment assert_equal(['one', 'two', 'three'], mylist) let mydict = { @@ -1577,7 +1577,7 @@ def Test_automatic_line_continuation() 'two': 2, 'three': 3, - } " comment + } # comment assert_equal({'one': 1, 'two': 2, 'three': 3}, mydict) mydict = #{ one: 1, # comment @@ -1754,8 +1754,8 @@ def Test_vim9_comment() 'hi clear This # comment', 'hi clear # comment', ]) - " not tested, because it doesn't give an error but a warning: - " hi clear This# comment', + # not tested, because it doesn't give an error but a warning: + # hi clear This# comment', CheckScriptFailure([ 'vim9script', 'hi clear# comment', @@ -2091,19 +2091,19 @@ def Test_vim9_comment_not_compiled() 'bwipe!', ]) -" CheckScriptFailure([ -" 'vim9script', -" 'new' -" 'call setline(1, ["# define pat", "last"])', -" ':$', -" 'dsearch /pat/#comment', -" 'bwipe!', -" ], 'E488:') -" -" CheckScriptFailure([ -" 'vim9script', -" 'func! SomeFunc()', -" ], 'E477:') + CheckScriptFailure([ + 'vim9script', + 'new' + 'call setline(1, ["# define pat", "last"])', + ':$', + 'dsearch /pat/#comment', + 'bwipe!', + ], 'E488:') + + CheckScriptFailure([ + 'vim9script', + 'func! SomeFunc()', + ], 'E477:') enddef def Test_finish() @@ -2135,12 +2135,12 @@ def Test_let_func_call() return 'this' endfunc let val: string = GetValue() - " env var is always a string + # env var is always a string let env = $TERM END writefile(lines, 'Xfinished') source Xfinished - " GetValue() is not called during discovery phase + # GetValue() is not called during discovery phase assert_equal(1, g:count) unlet g:count @@ -2169,7 +2169,7 @@ def Test_let_declaration() g:var_uninit = var var = 'text' g:var_test = var - " prefixing s: is optional + # prefixing s: is optional s:var = 'prefixed' g:var_prefixed = s:var @@ -2281,7 +2281,7 @@ def Test_source_vim9_from_legacy() source Xlegacy_script.vim assert_equal('global', g:global) -" unlet g:global + unlet g:global delete('Xlegacy_script.vim') delete('Xvim9_script.vim') @@ -2301,7 +2301,7 @@ def Test_substitute_cmd() assert_equal('otherthing', getline(1)) bwipe! - " also when the context is Vim9 script + # also when the context is Vim9 script let lines =<< trim END vim9script new diff --git a/src/version.c b/src/version.c index f363ff1f91..d585377a50 100644 --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1227, +/**/ 1226, /**/ 1225, diff --git a/src/vim9compile.c b/src/vim9compile.c index ec940df73a..8c2de343a1 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -2420,7 +2420,7 @@ free_imported(cctx_T *cctx) * Return TRUE if "p" points at a "#" but not at "#{". */ static int -comment_start(char_u *p) +vim9_comment_start(char_u *p) { return p[0] == '#' && p[1] != '{'; } @@ -2443,7 +2443,7 @@ peek_next_line_from_context(cctx_T *cctx) if (line == NULL) break; p = skipwhite(line); - if (*p != NUL && !comment_start(p)) + if (*p != NUL && !vim9_comment_start(p)) return p; } return NULL; @@ -2461,7 +2461,7 @@ may_peek_next_line(cctx_T *cctx, char_u *arg, char_u **nextp) char_u *p = skipwhite(arg); *nextp = NULL; - if (*p == NUL || (VIM_ISWHITE(*arg) && comment_start(p))) + if (*p == NUL || (VIM_ISWHITE(*arg) && vim9_comment_start(p))) { *nextp = peek_next_line_from_context(cctx); if (*nextp != NULL) @@ -2492,7 +2492,7 @@ next_line_from_context(cctx_T *cctx, int skip_comment) cctx->ctx_line_start = line; SOURCING_LNUM = cctx->ctx_lnum + 1; } while (line == NULL || *skipwhite(line) == NUL - || (skip_comment && comment_start(skipwhite(line)))); + || (skip_comment && vim9_comment_start(skipwhite(line)))); return line; } @@ -2504,7 +2504,7 @@ next_line_from_context(cctx_T *cctx, int skip_comment) static int may_get_next_line(char_u *whitep, char_u **arg, cctx_T *cctx) { - if (**arg == NUL || (VIM_ISWHITE(*whitep) && comment_start(*arg))) + if (**arg == NUL || (VIM_ISWHITE(*whitep) && vim9_comment_start(*arg))) { char_u *next = next_line_from_context(cctx, TRUE); @@ -3100,7 +3100,7 @@ compile_list(char_u **arg, cctx_T *cctx) { ++p; // Allow for following comment, after at least one space. - if (VIM_ISWHITE(*p) && *skipwhite(p) == '"') + if (VIM_ISWHITE(*p) && *skipwhite(p) == '#') p += STRLEN(p); break; } @@ -3157,6 +3157,8 @@ compile_lambda(char_u **arg, cctx_T *cctx) if (ufunc->uf_def_status == UF_COMPILED) return generate_FUNCREF(cctx, ufunc->uf_dfunc_idx); + + func_ptr_unref(ufunc); return FAIL; } @@ -3201,6 +3203,8 @@ compile_lambda_call(char_u **arg, cctx_T *cctx) // call the compiled function ret = generate_CALL(cctx, ufunc, argcount); + if (ret == FAIL) + func_ptr_unref(ufunc); return ret; } @@ -3327,7 +3331,7 @@ compile_dict(char_u **arg, cctx_T *cctx, int literal) // Allow for following comment, after at least one space. p = skipwhite(*arg); - if (VIM_ISWHITE(**arg) && (*p == '"' || comment_start(p))) + if (VIM_ISWHITE(**arg) && vim9_comment_start(p)) *arg += STRLEN(*arg); dict_unref(d); @@ -3618,7 +3622,7 @@ compile_subscript( { char_u *p = skipwhite(*arg); - if (*p == NUL || (VIM_ISWHITE(**arg) && comment_start(p))) + if (*p == NUL || (VIM_ISWHITE(**arg) && vim9_comment_start(p))) { char_u *next = peek_next_line_from_context(cctx); |