@@ -1710,7 +1710,7 @@ do_one_cmd(
17101710 char_u * cmd ;
17111711 int starts_with_colon = FALSE;
17121712#ifdef FEAT_EVAL
1713- int starts_with_quote ;
1713+ int may_have_range ;
17141714 int vim9script = in_vim9script ();
17151715#endif
17161716
@@ -1773,8 +1773,9 @@ do_one_cmd(
17731773 */
17741774 cmd = ea .cmd ;
17751775#ifdef FEAT_EVAL
1776- starts_with_quote = vim9script && !starts_with_colon && * ea .cmd == '\'' ;
1777- if (!starts_with_quote )
1776+ // In Vim9 script a colon is required before the range.
1777+ may_have_range = !vim9script || starts_with_colon ;
1778+ if (may_have_range )
17781779#endif
17791780 ea .cmd = skip_range (ea .cmd , NULL );
17801781 if (* ea .cmd == '*' && vim_strchr (p_cpo , CPO_STAR ) == NULL )
@@ -1783,7 +1784,10 @@ do_one_cmd(
17831784#ifdef FEAT_EVAL
17841785 if (vim9script && !starts_with_colon )
17851786 {
1786- if (ea .cmd > cmd )
1787+ if (ea .cmd == cmd + 1 && * cmd == '$' )
1788+ // should be "$VAR = val"
1789+ -- ea .cmd ;
1790+ else if (ea .cmd > cmd )
17871791 {
17881792 emsg (_ (e_colon_required ));
17891793 goto doend ;
@@ -1876,7 +1880,7 @@ do_one_cmd(
18761880
18771881 ea .cmd = cmd ;
18781882#ifdef FEAT_EVAL
1879- if (! starts_with_quote )
1883+ if (may_have_range )
18801884#endif
18811885 if (parse_cmd_address (& ea , & errormsg , FALSE) == FAIL )
18821886 goto doend ;
@@ -3267,80 +3271,90 @@ find_ex_command(
32673271 * "lvar = value", "lvar(arg)", "[1, 2 3]->Func()"
32683272 */
32693273 p = eap -> cmd ;
3270- if (lookup != NULL && (vim_strchr ((char_u * )"{('[" , * p ) != NULL
3271- || ((p = to_name_const_end (eap -> cmd )) > eap -> cmd
3272- && * p != NUL )))
3274+ if (lookup != NULL )
32733275 {
3274- int oplen ;
3275- int heredoc ;
3276+ // Skip over first char for "&opt = val", "$ENV = val" and "@r = val".
3277+ char_u * pskip = (* eap -> cmd == '&' || * eap -> cmd == '$'
3278+ || * eap -> cmd == '@' ) ? eap -> cmd + 1 : eap -> cmd ;
32763279
3277- if (
3278- // "(..." is an expression.
3279- // "funcname(" is always a function call.
3280- * p == '('
3281- || (p == eap -> cmd
3282- ? (
3283- // "{..." is an dict expression.
3284- * eap -> cmd == '{'
3285- // "'string'->func()" is an expression.
3286- || * eap -> cmd == '\''
3287- // "g:varname" is an expression.
3288- || eap -> cmd [1 ] == ':'
3289- )
3290- : (
3291- // "varname[]" is an expression.
3292- * p == '['
3293- // "varname->func()" is an expression.
3294- || (* p == '-' && p [1 ] == '>' )
3295- // "varname.expr" is an expression.
3296- || (* p == '.' && ASCII_ISALPHA (p [1 ]))
3297- )))
3298- {
3299- eap -> cmdidx = CMD_eval ;
3300- return eap -> cmd ;
3301- }
3302-
3303- // "[...]->Method()" is a list expression, but "[a, b] = Func()" is
3304- // an assignment.
3305- // If there is no line break inside the "[...]" then "p" is advanced to
3306- // after the "]" by to_name_const_end(): check if a "=" follows.
3307- // If "[...]" has a line break "p" still points at the "[" and it can't
3308- // be an assignment.
3309- if (* eap -> cmd == '[' )
3310- {
3311- p = to_name_const_end (eap -> cmd );
3312- if (p == eap -> cmd || * skipwhite (p ) != '=' )
3280+ if (vim_strchr ((char_u * )"{('[" , * p ) != NULL
3281+ || ((p = to_name_const_end (pskip )) > eap -> cmd && * p != NUL ))
3282+ {
3283+ int oplen ;
3284+ int heredoc ;
3285+
3286+ if (
3287+ // "(..." is an expression.
3288+ // "funcname(" is always a function call.
3289+ * p == '('
3290+ || (p == eap -> cmd
3291+ ? (
3292+ // "{..." is an dict expression.
3293+ * eap -> cmd == '{'
3294+ // "'string'->func()" is an expression.
3295+ || * eap -> cmd == '\''
3296+ // "g:varname" is an expression.
3297+ || eap -> cmd [1 ] == ':'
3298+ )
3299+ : (
3300+ // "varname[]" is an expression.
3301+ * p == '['
3302+ // "varname->func()" is an expression.
3303+ || (* p == '-' && p [1 ] == '>' )
3304+ // "varname.expr" is an expression.
3305+ || (* p == '.' && ASCII_ISALPHA (p [1 ]))
3306+ )))
33133307 {
33143308 eap -> cmdidx = CMD_eval ;
33153309 return eap -> cmd ;
33163310 }
3317- if (p > eap -> cmd && * skipwhite (p ) == '=' )
3311+
3312+ // "[...]->Method()" is a list expression, but "[a, b] = Func()" is
3313+ // an assignment.
3314+ // If there is no line break inside the "[...]" then "p" is
3315+ // advanced to after the "]" by to_name_const_end(): check if a "="
3316+ // follows.
3317+ // If "[...]" has a line break "p" still points at the "[" and it
3318+ // can't be an assignment.
3319+ if (* eap -> cmd == '[' )
33183320 {
3319- eap -> cmdidx = CMD_let ;
3320- return eap -> cmd ;
3321+ p = to_name_const_end (eap -> cmd );
3322+ if (p == eap -> cmd || * skipwhite (p ) != '=' )
3323+ {
3324+ eap -> cmdidx = CMD_eval ;
3325+ return eap -> cmd ;
3326+ }
3327+ if (p > eap -> cmd && * skipwhite (p ) == '=' )
3328+ {
3329+ eap -> cmdidx = CMD_let ;
3330+ return eap -> cmd ;
3331+ }
33213332 }
3322- }
33233333
3324- // Recognize an assignment if we recognize the variable name:
3325- // "g:var = expr"
3326- // "var = expr" where "var" is a local var name.
3327- oplen = assignment_len (skipwhite (p ), & heredoc );
3328- if (oplen > 0 )
3329- {
3330- if (((p - eap -> cmd ) > 2 && eap -> cmd [1 ] == ':' )
3331- || lookup (eap -> cmd , p - eap -> cmd , cctx ) != NULL )
3334+ // Recognize an assignment if we recognize the variable name:
3335+ // "g:var = expr"
3336+ // "var = expr" where "var" is a local var name.
3337+ oplen = assignment_len (skipwhite (p ), & heredoc );
3338+ if (oplen > 0 )
33323339 {
3333- eap -> cmdidx = CMD_let ;
3334- return eap -> cmd ;
3340+ if (((p - eap -> cmd ) > 2 && eap -> cmd [1 ] == ':' )
3341+ || * eap -> cmd == '&'
3342+ || * eap -> cmd == '$'
3343+ || * eap -> cmd == '@'
3344+ || lookup (eap -> cmd , p - eap -> cmd , cctx ) != NULL )
3345+ {
3346+ eap -> cmdidx = CMD_let ;
3347+ return eap -> cmd ;
3348+ }
33353349 }
3336- }
33373350
3338- // Recognize using a type for a w:, b:, t: or g: variable:
3339- // "w:varname: number = 123".
3340- if (eap -> cmd [1 ] == ':' && * p == ':' )
3341- {
3342- eap -> cmdidx = CMD_eval ;
3343- return eap -> cmd ;
3351+ // Recognize using a type for a w:, b:, t: or g: variable:
3352+ // "w:varname: number = 123".
3353+ if (eap -> cmd [1 ] == ':' && * p == ':' )
3354+ {
3355+ eap -> cmdidx = CMD_eval ;
3356+ return eap -> cmd ;
3357+ }
33443358 }
33453359 }
33463360#endif
0 commit comments