changeset 17462:9088fafff9b3 v8.1.1729

patch 8.1.1729: heredoc with trim not properly handled in function commit https://github.com/vim/vim/commit/ecaa75b4cea329a3902b8565e028b32279b8322b Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jul 21 23:04:21 2019 +0200 patch 8.1.1729: heredoc with trim not properly handled in function Problem: Heredoc with trim not properly handled in function. Solution: Allow for missing indent. (FUJIWARA Takuya, closes https://github.com/vim/vim/issues/4713)
author Bram Moolenaar <Bram@vim.org>
date Sun, 21 Jul 2019 23:15:05 +0200
parents 1fc9ec9b71a0
children 16f01738068b
files src/testdir/test_let.vim src/userfunc.c src/version.c
diffstat 3 files changed, 34 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_let.vim
+++ b/src/testdir/test_let.vim
@@ -188,6 +188,15 @@ func Test_let_heredoc_fails()
   call delete('XheredocBadMarker')
 endfunc
 
+func Test_let_heredoc_trim_no_indent_marker()
+  let text =<< trim END
+  Text
+  with
+  indent
+END
+  call assert_equal(['Text', 'with', 'indent'], text)
+endfunc
+
 " Test for the setting a variable using the heredoc syntax
 func Test_let_heredoc()
   let var1 =<< END
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -2000,8 +2000,6 @@ ex_function(exarg_T *eap)
     int		overwrite = FALSE;
     int		indent;
     int		nesting;
-    char_u	*skip_until = NULL;
-    char_u	*trimmed = NULL;
     dictitem_T	*v;
     funcdict_T	fudi;
     static int	func_nr = 0;	    /* number for nameless function */
@@ -2012,6 +2010,9 @@ ex_function(exarg_T *eap)
     int		do_concat = TRUE;
     linenr_T	sourcing_lnum_off;
     linenr_T	sourcing_lnum_top;
+    int		is_heredoc = FALSE;
+    char_u	*skip_until = NULL;
+    char_u	*heredoc_trimmed = NULL;
 
     /*
      * ":function" without argument: list functions.
@@ -2331,17 +2332,28 @@ ex_function(exarg_T *eap)
 
 	if (skip_until != NULL)
 	{
-	    // Between ":append" and "." and between ":python <<EOF" and "EOF"
-	    // don't check for ":endfunc".
-	    if (trimmed == NULL
-			    || STRNCMP(theline, trimmed, STRLEN(trimmed)) == 0)
+	    // Don't check for ":endfunc" between
+	    // * ":append" and "."
+	    // * ":python <<EOF" and "EOF"
+	    // * ":let {var-name} =<< [trim] {marker}" and "{marker}"
+	    if (heredoc_trimmed == NULL
+		    || (is_heredoc && skipwhite(theline) == theline)
+		    || STRNCMP(theline, heredoc_trimmed,
+						 STRLEN(heredoc_trimmed)) == 0)
 	    {
-		p = trimmed == NULL ? theline : theline + STRLEN(trimmed);
+		if (heredoc_trimmed == NULL)
+		    p = theline;
+		else if (is_heredoc)
+		    p = skipwhite(theline) == theline
+				 ? theline : theline + STRLEN(heredoc_trimmed);
+		else
+		    p = theline + STRLEN(heredoc_trimmed);
 		if (STRCMP(p, skip_until) == 0)
 		{
 		    VIM_CLEAR(skip_until);
-		    VIM_CLEAR(trimmed);
+		    VIM_CLEAR(heredoc_trimmed);
 		    do_concat = TRUE;
+		    is_heredoc = FALSE;
 		}
 	    }
 	}
@@ -2453,20 +2465,17 @@ ex_function(exarg_T *eap)
 			    && (!ASCII_ISALNUM(p[2])
 				|| (p[2] == 't' && !ASCII_ISALNUM(p[3]))))))
 	    {
-		// ":let v =<<" continues until a dot
 		p = skipwhite(arg + 3);
 		if (STRNCMP(p, "trim", 4) == 0)
 		{
 		    // Ignore leading white space.
 		    p = skipwhite(p + 4);
-		    trimmed = vim_strnsave(theline,
+		    heredoc_trimmed = vim_strnsave(theline,
 					  (int)(skipwhite(theline) - theline));
 		}
-		if (*p == NUL)
-		    skip_until = vim_strsave((char_u *)".");
-		else
-		    skip_until = vim_strnsave(p, (int)(skiptowhite(p) - p));
+		skip_until = vim_strnsave(p, (int)(skiptowhite(p) - p));
 		do_concat = FALSE;
+		is_heredoc = TRUE;
 	    }
 	}
 
--- a/src/version.c
+++ b/src/version.c
@@ -778,6 +778,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1729,
+/**/
     1728,
 /**/
     1727,