summaryrefslogtreecommitdiffstats
path: root/src/evalvars.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/evalvars.c')
-rw-r--r--src/evalvars.c63
1 files changed, 52 insertions, 11 deletions
diff --git a/src/evalvars.c b/src/evalvars.c
index f16d4757f2..62728ed8ab 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -779,8 +779,10 @@ heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile)
int eval_failed = FALSE;
cctx_T *cctx = vim9compile ? eap->cookie : NULL;
int count = 0;
+ int heredoc_in_string = FALSE;
+ char_u *line_arg = NULL;
- if (eap->ea_getline == NULL)
+ if (eap->ea_getline == NULL && vim_strchr(cmd, '\n') == NULL)
{
emsg(_(e_cannot_use_heredoc_here));
return NULL;
@@ -824,8 +826,14 @@ heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile)
if (*cmd != NUL && *cmd != comment_char)
{
marker = skipwhite(cmd);
- p = skiptowhite(marker);
- if (*skipwhite(p) != NUL && *skipwhite(p) != comment_char)
+ p = skiptowhite_or_nl(marker);
+ if (*p == NL)
+ {
+ // heredoc in a string
+ line_arg = p + 1;
+ heredoc_in_string = TRUE;
+ }
+ else if (*skipwhite(p) != NUL && *skipwhite(p) != comment_char)
{
semsg(_(e_trailing_characters_str), p);
return NULL;
@@ -859,12 +867,38 @@ heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile)
int mi = 0;
int ti = 0;
- vim_free(theline);
- theline = eap->ea_getline(NUL, eap->cookie, 0, FALSE);
- if (theline == NULL)
+ if (heredoc_in_string)
{
- semsg(_(e_missing_end_marker_str), marker);
- break;
+ char_u *next_line;
+
+ // heredoc in a string separated by newlines. Get the next line
+ // from the string.
+
+ if (*line_arg == NUL)
+ {
+ semsg(_(e_missing_end_marker_str), marker);
+ break;
+ }
+
+ theline = line_arg;
+ next_line = vim_strchr(theline, '\n');
+ if (next_line == NULL)
+ line_arg += STRLEN(line_arg);
+ else
+ {
+ *next_line = NUL;
+ line_arg = next_line + 1;
+ }
+ }
+ else
+ {
+ vim_free(theline);
+ theline = eap->ea_getline(NUL, eap->cookie, 0, FALSE);
+ if (theline == NULL)
+ {
+ semsg(_(e_missing_end_marker_str), marker);
+ break;
+ }
}
// with "trim": skip the indent matching the :let line to find the
@@ -911,6 +945,8 @@ heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile)
}
else
{
+ int free_str = FALSE;
+
if (evalstr && !eap->skip)
{
str = eval_all_expr_in_str(str);
@@ -920,15 +956,20 @@ heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile)
eval_failed = TRUE;
continue;
}
- vim_free(theline);
- theline = str;
+ free_str = TRUE;
}
if (list_append_string(l, str, -1) == FAIL)
break;
+ if (free_str)
+ vim_free(str);
}
}
- vim_free(theline);
+ if (heredoc_in_string)
+ // Next command follows the heredoc in the string.
+ eap->nextcmd = line_arg;
+ else
+ vim_free(theline);
vim_free(text_indent);
if (vim9compile && cctx->ctx_skip != SKIP_YES && !eval_failed)