diff options
author | Yegappan Lakshmanan <yegappan@yahoo.com> | 2024-04-12 18:48:35 +0200 |
---|---|---|
committer | Christian Brabandt <cb@256bit.org> | 2024-04-12 18:53:08 +0200 |
commit | e74cad3321ce1dcefc1fc64f617511275b6cd930 (patch) | |
tree | b29c4a7843c748750a448800846bbff1b1dfde19 /src/evalvars.c | |
parent | a1dcd76ce791b5b8bd093765a99b71aa163300a5 (diff) |
patch 9.1.0312: heredocs are not supported for :commandsv9.1.0312
Problem: heredocs are not supported for :commands
(@balki)
Solution: Add heredoc support
(Yegappan Lakshmanan)
fixes: #14491
closes: #14528
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
Diffstat (limited to 'src/evalvars.c')
-rw-r--r-- | src/evalvars.c | 63 |
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) |