To: vim_dev@googlegroups.com Subject: Patch 8.2.0298 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0298 Problem: Vim9 script: cannot start command with a string constant. Solution: Recognize expression starting with '('. Files: src/ex_docmd.c, src/vim9compile.c, src/testdir/test_vim9_script.vim, runtime/doc/vim9.txt *** ../vim-8.2.0297/src/ex_docmd.c 2020-02-21 21:30:33.867979726 +0100 --- src/ex_docmd.c 2020-02-22 18:22:58.599229827 +0100 *************** *** 3146,3153 **** * Recognize a Vim9 script function/method call and assignment: * "lvar = value", "lvar(arg)", "[1, 2 3]->Func()" */ ! if (lookup != NULL && (p = to_name_const_end(eap->cmd)) > eap->cmd ! && *p != NUL) { int oplen; int heredoc; --- 3146,3154 ---- * Recognize a Vim9 script function/method call and assignment: * "lvar = value", "lvar(arg)", "[1, 2 3]->Func()" */ ! p = eap->cmd; ! if (lookup != NULL && (*p == '(' ! || ((p = to_name_const_end(eap->cmd)) > eap->cmd && *p != NUL))) { int oplen; int heredoc; *************** *** 3156,3161 **** --- 3157,3163 ---- // "varname[]" is an expression. // "g:varname" is an expression. // "varname->expr" is an expression. + // "(..." is an expression. if (*p == '(' || *p == '[' || p[1] == ':' *** ../vim-8.2.0297/src/vim9compile.c 2020-02-21 18:41:49.249885543 +0100 --- src/vim9compile.c 2020-02-22 18:14:18.812973176 +0100 *************** *** 4821,4842 **** p = (*ea.cmd == '&' || *ea.cmd == '$' || *ea.cmd == '@') ? ea.cmd + 1 : ea.cmd; p = to_name_end(p); ! if (p > ea.cmd && *p != NUL) { int oplen; int heredoc; - // "funcname(" is always a function call. - // "varname[]" is an expression. - // "varname->expr" is an expression. - if (*p == '(' - || *p == '[' - || ((p - ea.cmd) > 2 && ea.cmd[1] == ':') - || (*p == '-' && p[1] == '>')) - { - // TODO - } - oplen = assignment_len(skipwhite(p), &heredoc); if (oplen > 0) { --- 4821,4831 ---- p = (*ea.cmd == '&' || *ea.cmd == '$' || *ea.cmd == '@') ? ea.cmd + 1 : ea.cmd; p = to_name_end(p); ! if ((p > ea.cmd && *p != NUL) || *p == '(') { int oplen; int heredoc; oplen = assignment_len(skipwhite(p), &heredoc); if (oplen > 0) { *** ../vim-8.2.0297/src/testdir/test_vim9_script.vim 2020-02-21 18:41:49.249885543 +0100 --- src/testdir/test_vim9_script.vim 2020-02-22 18:30:10.165752662 +0100 *************** *** 370,375 **** --- 370,380 ---- assert_equal(#{a: 1, b: 2}, dictvar) #{a: 3, b: 4}->DictFunc() assert_equal(#{a: 3, b: 4}, dictvar) + + ('text')->MyFunc() + assert_equal('text', var) + ("some")->MyFunc() + assert_equal('some', var) END writefile(lines, 'Xcall.vim') source Xcall.vim *** ../vim-8.2.0297/runtime/doc/vim9.txt 2020-02-21 18:41:49.249885543 +0100 --- runtime/doc/vim9.txt 2020-02-22 18:10:32.689707147 +0100 *************** *** 131,151 **** Using `:call` is still possible, but this is discouraged. A method call without `eval` is possible, so long as the start is an ! identifier or can't be an Ex command. It does not work for string constants: > myList->add(123) " works g:myList->add(123) " works [1, 2, 3]->Process() " works #{a: 1, b: 2}->Process() " works {'a': 1, 'b': 2}->Process() " works "foobar"->Process() " does NOT work ! eval "foobar"->Process() " works In case there is ambiguity between a function name and an Ex command, use ":" to make clear you want to use the Ex command. For example, there is both the `:substitute` command and the `substitute()` function. When the line starts with `substitute(` this will use the function, prepend a colon to use the command instead: > ! :substitute(pattern(replacement( No curly braces expansion ~ --- 131,153 ---- Using `:call` is still possible, but this is discouraged. A method call without `eval` is possible, so long as the start is an ! identifier or can't be an Ex command. It does NOT work for string constants: > myList->add(123) " works g:myList->add(123) " works [1, 2, 3]->Process() " works #{a: 1, b: 2}->Process() " works {'a': 1, 'b': 2}->Process() " works "foobar"->Process() " does NOT work ! ("foobar")->Process() " works ! 'foobar'->Process() " does NOT work ! ('foobar')->Process() " works In case there is ambiguity between a function name and an Ex command, use ":" to make clear you want to use the Ex command. For example, there is both the `:substitute` command and the `substitute()` function. When the line starts with `substitute(` this will use the function, prepend a colon to use the command instead: > ! :substitute(pattern (replacement ( No curly braces expansion ~ *** ../vim-8.2.0297/src/version.c 2020-02-22 15:00:50.646459120 +0100 --- src/version.c 2020-02-22 18:10:01.613806148 +0100 *************** *** 740,741 **** --- 740,743 ---- { /* Add new patch number below this line */ + /**/ + 298, /**/ -- From "know your smileys": <|-) Chinese <|-( Chinese and doesn't like these kind of jokes /// 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 ///