changeset 22732:4c21a3a47707 v8.2.1914

patch 8.2.1914: Vim9: cannot put line break in expression for '=' register Commit: https://github.com/vim/vim/commit/b4bcea474d9006e4db1fa5d6828773e739af14bb Author: Bram Moolenaar <Bram@vim.org> Date: Wed Oct 28 13:53:50 2020 +0100 patch 8.2.1914: Vim9: cannot put line break in expression for '=' register Problem: Vim9: cannot put line break in expression for '=' register. Solution: Pass fgetline to set_expr_line(). (closes https://github.com/vim/vim/issues/7209)
author Bram Moolenaar <Bram@vim.org>
date Wed, 28 Oct 2020 14:00:04 +0100
parents 45c95095984a
children e4eaa35280c9
files src/eval.c src/ex_docmd.c src/misc2.c src/proto/eval.pro src/proto/register.pro src/register.c src/testdir/test_vim9_script.vim src/version.c
diffstat 8 files changed, 47 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/eval.c
+++ b/src/eval.c
@@ -474,9 +474,10 @@ skip_expr_concatenate(
  * Return pointer to allocated memory, or NULL for failure.
  */
     char_u *
-eval_to_string(
+eval_to_string_eap(
     char_u	*arg,
-    int		convert)
+    int		convert,
+    exarg_T	*eap)
 {
     typval_T	tv;
     char_u	*retval;
@@ -484,8 +485,10 @@ eval_to_string(
 #ifdef FEAT_FLOAT
     char_u	numbuf[NUMBUFLEN];
 #endif
-
-    if (eval0(arg, &tv, NULL, &EVALARG_EVALUATE) == FAIL)
+    evalarg_T	evalarg;
+
+    fill_evalarg_from_eap(&evalarg, eap, eap != NULL && eap->skip);
+    if (eval0(arg, &tv, NULL, &evalarg) == FAIL)
 	retval = NULL;
     else
     {
@@ -512,11 +515,19 @@ eval_to_string(
 	    retval = vim_strsave(tv_get_string(&tv));
 	clear_tv(&tv);
     }
-    clear_evalarg(&EVALARG_EVALUATE, NULL);
+    clear_evalarg(&evalarg, NULL);
 
     return retval;
 }
 
+    char_u *
+eval_to_string(
+    char_u	*arg,
+    int		convert)
+{
+    return eval_to_string_eap(arg, convert, NULL);
+}
+
 /*
  * Call eval_to_string() without using current local variables and using
  * textwinlock.  When "use_sandbox" is TRUE use the sandbox.
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -1719,6 +1719,7 @@ do_one_cmd(
 #ifdef FEAT_EVAL
     int		may_have_range;
     int		vim9script = in_vim9script();
+    int		did_set_expr_line = FALSE;
 #endif
 
     CLEAR_FIELD(ea);
@@ -2315,8 +2316,9 @@ do_one_cmd(
 	    // for '=' register: accept the rest of the line as an expression
 	    if (ea.arg[-1] == '=' && ea.arg[0] != NUL)
 	    {
-		set_expr_line(vim_strsave(ea.arg));
+		set_expr_line(vim_strsave(ea.arg), &ea);
 		ea.arg += STRLEN(ea.arg);
+		did_set_expr_line = TRUE;
 	    }
 #endif
 	    ea.arg = skipwhite(ea.arg);
@@ -2595,6 +2597,9 @@ doend:
     do_errthrow(cstack,
 	    (ea.cmdidx != CMD_SIZE && !IS_USER_CMDIDX(ea.cmdidx))
 			? cmdnames[(int)ea.cmdidx].cmd_name : (char_u *)NULL);
+
+    if (did_set_expr_line)
+	set_expr_line(NULL, NULL);
 #endif
 
     undo_cmdmod(&cmdmod);
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -1131,7 +1131,7 @@ free_all_mem(void)
     free_signs();
 # endif
 # ifdef FEAT_EVAL
-    set_expr_line(NULL);
+    set_expr_line(NULL, NULL);
 # endif
 # ifdef FEAT_DIFF
     if (curtab != NULL)
--- a/src/proto/eval.pro
+++ b/src/proto/eval.pro
@@ -11,6 +11,7 @@ int eval_expr_to_bool(typval_T *expr, in
 char_u *eval_to_string_skip(char_u *arg, exarg_T *eap, int skip);
 int skip_expr(char_u **pp, evalarg_T *evalarg);
 int skip_expr_concatenate(char_u **arg, char_u **start, char_u **end, evalarg_T *evalarg);
+char_u *eval_to_string_eap(char_u *arg, int convert, exarg_T *eap);
 char_u *eval_to_string(char_u *arg, int convert);
 char_u *eval_to_string_safe(char_u *arg, int use_sandbox);
 varnumber_T eval_to_number(char_u *expr);
--- a/src/proto/register.pro
+++ b/src/proto/register.pro
@@ -6,7 +6,7 @@ yankreg_T *get_y_previous(void);
 void set_y_current(yankreg_T *yreg);
 void set_y_previous(yankreg_T *yreg);
 int get_expr_register(void);
-void set_expr_line(char_u *new_line);
+void set_expr_line(char_u *new_line, exarg_T *eap);
 char_u *get_expr_line(void);
 int valid_yank_reg(int regname, int writing);
 int get_yank_register(int regname, int writing);
--- a/src/register.c
+++ b/src/register.c
@@ -79,6 +79,7 @@ set_y_previous(yankreg_T *yreg)
  * Keep the last expression line here, for repeating.
  */
 static char_u	*expr_line = NULL;
+static exarg_T	*expr_eap = NULL;
 
 /*
  * Get an expression for the "\"=expr1" or "CTRL-R =expr1"
@@ -95,19 +96,22 @@ get_expr_register(void)
     if (*new_line == NUL)	// use previous line
 	vim_free(new_line);
     else
-	set_expr_line(new_line);
+	set_expr_line(new_line, NULL);
     return '=';
 }
 
 /*
  * Set the expression for the '=' register.
  * Argument must be an allocated string.
+ * "eap" may be used if the next line needs to be checked when evaluating the
+ * expression.
  */
     void
-set_expr_line(char_u *new_line)
+set_expr_line(char_u *new_line, exarg_T *eap)
 {
     vim_free(expr_line);
     expr_line = new_line;
+    expr_eap = eap;
 }
 
 /*
@@ -136,7 +140,7 @@ get_expr_line(void)
 	return expr_copy;
 
     ++nested;
-    rv = eval_to_string(expr_copy, TRUE);
+    rv = eval_to_string_eap(expr_copy, TRUE, expr_eap);
     --nested;
     vim_free(expr_copy);
     return rv;
@@ -2774,7 +2778,7 @@ write_reg_contents_ex(
 	    vim_free(p);
 	    p = s;
 	}
-	set_expr_line(p);
+	set_expr_line(p, NULL);
 	return;
     }
 
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -2859,6 +2859,18 @@ def Test_catch_exception_in_callback()
   unlet g:caught
 enddef
 
+def Test_put_with_linebreak()
+  new
+  var lines =<< trim END
+    vim9script
+    pu=split('abc', '\zs')
+            ->join()
+  END
+  CheckScriptSuccess(lines)
+  getline(2)->assert_equal('a b c')
+  bwipe!
+enddef
+
 " Keep this last, it messes up highlighting.
 def Test_substitute_cmd()
   new
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1914,
+/**/
     1913,
 /**/
     1912,