changeset 20982:bb49b5090a9c v8.2.1042

patch 8.2.1042: Vim9: cannot put an operator on the next line Commit: https://github.com/vim/vim/commit/df069eec3b90401e880e9b0e258146d8f36c474d Author: Bram Moolenaar <Bram@vim.org> Date: Mon Jun 22 23:02:51 2020 +0200 patch 8.2.1042: Vim9: cannot put an operator on the next line Problem: Vim9: cannot put an operator on the next line. Solution: Require a colon before a range to see if that causes problems.
author Bram Moolenaar <Bram@vim.org>
date Mon, 22 Jun 2020 23:15:04 +0200
parents 6e0166b4443d
children 3bf150ea4d44
files runtime/doc/vim9.txt src/ex_docmd.c src/globals.h src/testdir/test_vim9_expr.vim src/testdir/test_vim9_script.vim src/version.c src/vim9compile.c
diffstat 7 files changed, 59 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/vim9.txt
+++ b/runtime/doc/vim9.txt
@@ -1,4 +1,4 @@
-*vim9.txt*	For Vim version 8.2.  Last change: 2020 Jun 21
+*vim9.txt*	For Vim version 8.2.  Last change: 2020 Jun 22
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -257,27 +257,32 @@ Function call: >
 			arg2
 			)
 
-For binary operators iin expressions not in [], {} or () a line break is
-possible AFTER the operators.  For example: >
-	let text = lead ..
-		   middle ..
-		   end
+For binary operators in expressions not in [], {} or () a line break is
+possible just before or after the operator.  For example: >
+	let text = lead
+		   .. middle
+		   .. end
 	let total = start +
 	            end -
 		    correction
-	let result = positive ?
-			PosFunc(arg) :
-			NegFunc(arg)
+	let result = positive
+			? PosFunc(arg)
+			: NegFunc(arg)
 
-A special case is "->" for function call chains, it can appear in the next
-line: >
 	let result = GetBuilder()
 			->BuilderSetWidth(333)
 			->BuilderSetHeight(777)
 			->BuilderBuild()
 
-Note that "enddef" cannot be used at the start of a continuation line, it ends
-the current function.
+<							*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
 
 It is also possible to split a function header over multiple lines, in between
 arguments: >
@@ -286,6 +291,9 @@ arguments: >
 		separator = '-'
 		): string
 
+Note that "enddef" cannot be used at the start of a continuation line, it ends
+the current function.
+
 
 No curly braces expansion ~
 
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -1729,7 +1729,14 @@ do_one_cmd(
 
 #ifdef FEAT_EVAL
     if (current_sctx.sc_version == SCRIPT_VERSION_VIM9 && !starts_with_colon)
+    {
+	if (ea.cmd > cmd)
+	{
+	    emsg(_(e_colon_required));
+	    goto doend;
+	}
 	p = find_ex_command(&ea, NULL, lookup_scriptvar, NULL);
+    }
     else
 #endif
 	p = find_ex_command(&ea, NULL, NULL, NULL);
@@ -3446,7 +3453,7 @@ excmd_get_argt(cmdidx_T idx)
  * Backslashed delimiters after / or ? will be skipped, and commands will
  * not be expanded between /'s and ?'s or after "'".
  *
- * Also skip white space and ":" characters.
+ * Also skip white space and ":" characters after the range.
  * Returns the "cmd" pointer advanced to beyond the range.
  */
     char_u *
--- a/src/globals.h
+++ b/src/globals.h
@@ -1790,6 +1790,7 @@ EXTERN char e_const_req_value[] INIT(= N
 EXTERN char e_type_req[]	INIT(= N_("E1022: type or initialization required"));
 EXTERN char e_declare_var[]	INIT(= N_("E1016: Cannot declare a %s variable: %s"));
 EXTERN char e_declare_env_var[]	INIT(= N_("E1016: Cannot declare an environment variable: %s"));
+EXTERN char e_colon_required[]	INIT(= N_("E1050: Colon required before a range"));
 #endif
 #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
 EXTERN char e_alloc_color[]	INIT(= N_("E254: Cannot allocate color %s"));
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -585,12 +585,12 @@ func Test_expr5_fails()
   call CheckDefFailure(["let x = '1' ..'2'"], msg)
   call CheckDefFailure(["let x = '1'.. '2'"], msg)
 
-  call CheckDefFailure(["let x = 0z1122 + 33"], 'E1035')
-  call CheckDefFailure(["let x = 0z1122 + [3]"], 'E1035')
-  call CheckDefFailure(["let x = 0z1122 + 'asd'"], 'E1035')
-  call CheckDefFailure(["let x = 33 + 0z1122"], 'E1035')
-  call CheckDefFailure(["let x = [3] + 0z1122"], 'E1035')
-  call CheckDefFailure(["let x = 'asdf' + 0z1122"], 'E1035')
+  call CheckDefFailure(["let x = 0z1122 + 33"], 'E1051')
+  call CheckDefFailure(["let x = 0z1122 + [3]"], 'E1051')
+  call CheckDefFailure(["let x = 0z1122 + 'asd'"], 'E1051')
+  call CheckDefFailure(["let x = 33 + 0z1122"], 'E1051')
+  call CheckDefFailure(["let x = [3] + 0z1122"], 'E1051')
+  call CheckDefFailure(["let x = 'asdf' + 0z1122"], 'E1051')
   call CheckDefFailure(["let x = 6 + xxx"], 'E1001')
 endfunc
 
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -468,6 +468,14 @@ func Test_const()
   call CheckDefFailure(['const &option'], 'E996:')
 endfunc
 
+def Test_range_no_colon()
+  call CheckDefFailure(['%s/a/b/'], 'E1050:')
+  call CheckDefFailure(['+ s/a/b/'], 'E1050:')
+  call CheckDefFailure(['- s/a/b/'], 'E1050:')
+  call CheckDefFailure(['. s/a/b/'], 'E1050:')
+enddef
+
+
 def Test_block()
   let outer = 1
   {
@@ -1279,7 +1287,7 @@ def Test_echomsg_cmd()
   echomsg 'some' 'more' # comment
   assert_match('^some more$', Screenline(&lines))
   echo 'clear'
-  1messages
+  :1messages
   assert_match('^some more$', Screenline(&lines))
 
   call CheckDefFailure(['echomsg "xxx"# comment'], 'E488:')
@@ -1898,7 +1906,7 @@ def Test_vim9_comment_not_compiled()
       'vim9script',
       'new'
       'call setline(1, ["# define pat", "last"])',
-      '$',
+      ':$',
       'dsearch /pat/ #comment',
       'bwipe!',
       ])
@@ -1907,7 +1915,7 @@ def Test_vim9_comment_not_compiled()
       'vim9script',
       'new'
       'call setline(1, ["# define pat", "last"])',
-      '$',
+      ':$',
       'dsearch /pat/#comment',
       'bwipe!',
       ], 'E488:')
--- 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 */
 /**/
+    1042,
+/**/
     1041,
 /**/
     1040,
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -643,7 +643,7 @@ check_number_or_float(vartype_T type1, v
 							 || type2 == VAR_ANY)))
     {
 	if (*op == '+')
-	    emsg(_("E1035: wrong argument type for +"));
+	    emsg(_("E1051: wrong argument type for +"));
 	else
 	    semsg(_("E1036: %c requires number or float arguments"), *op);
 	return FAIL;
@@ -6695,6 +6695,7 @@ compile_def_function(ufunc_T *ufunc, int
     {
 	exarg_T	ea;
 	int	starts_with_colon = FALSE;
+	char_u	*cmd;
 
 	// Bail out on the first error to avoid a flood of errors and report
 	// the right line number when inside try/catch.
@@ -6853,7 +6854,13 @@ compile_def_function(ufunc_T *ufunc, int
 	/*
 	 * COMMAND after range
 	 */
+	cmd = ea.cmd;
 	ea.cmd = skip_range(ea.cmd, NULL);
+	if (ea.cmd > cmd && !starts_with_colon)
+	{
+	    emsg(_(e_colon_required));
+	    goto erret;
+	}
 	p = find_ex_command(&ea, NULL, starts_with_colon ? NULL
 		   : (void *(*)(char_u *, size_t, cctx_T *))lookup_local,
 									&cctx);
@@ -7008,8 +7015,9 @@ compile_def_function(ufunc_T *ufunc, int
 		    line = compile_mult_expr(p, ea.cmdidx, &cctx);
 		    break;
 
+	    // TODO: other commands with an expression argument
+
 	    default:
-		    // TODO: other commands with an expression argument
 		    // Not recognized, execute with do_cmdline_cmd().
 		    ea.arg = p;
 		    line = compile_exec(line, &ea, &cctx);