0
0
mirror of https://github.com/vim/vim.git synced 2025-09-29 04:34:16 -04:00

patch 8.2.4804: expression in heredoc doesn't work for compiled function

Problem:    Expression in heredoc doesn't work for compiled function.
Solution:   Implement compiling the heredoc expressions. (Yegappan Lakshmanan,
            closes #10232)
This commit is contained in:
Yegappan Lakshmanan
2022-04-21 23:30:15 +01:00
committed by Bram Moolenaar
parent 66e13aedc7
commit 1fc6ea9bf3
8 changed files with 187 additions and 58 deletions

View File

@@ -673,16 +673,21 @@ eval_all_expr_in_str(char_u *str)
*
* The {marker} is a string. If the optional 'trim' word is supplied before the
* marker, then the leading indentation before the lines (matching the
* indentation in the 'cmd' line) is stripped.
* indentation in the "cmd" line) is stripped.
*
* When getting lines for an embedded script (e.g. python, lua, perl, ruby,
* tcl, mzscheme), script_get is set to TRUE. In this case, if the marker is
* tcl, mzscheme), "script_get" is set to TRUE. In this case, if the marker is
* missing, then '.' is accepted as a marker.
*
* When compiling a heredoc assignment to a variable in a Vim9 def function,
* "vim9compile" is set to TRUE. In this case, instead of generating a list of
* string values from the heredoc, vim9 instructions are generated. On success
* the returned list will be empty.
*
* Returns a List with {lines} or NULL on failure.
*/
list_T *
heredoc_get(exarg_T *eap, char_u *cmd, int script_get)
heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile)
{
char_u *theline = NULL;
char_u *marker;
@@ -696,6 +701,8 @@ heredoc_get(exarg_T *eap, char_u *cmd, int script_get)
int comment_char = in_vim9script() ? '#' : '"';
int evalstr = FALSE;
int eval_failed = FALSE;
cctx_T *cctx = vim9compile ? eap->cookie : NULL;
int count = 0;
if (eap->getline == NULL)
{
@@ -816,25 +823,41 @@ heredoc_get(exarg_T *eap, char_u *cmd, int script_get)
break;
str = theline + ti;
if (evalstr)
if (vim9compile)
{
str = eval_all_expr_in_str(str);
if (str == NULL)
if (compile_heredoc_string(str, evalstr, cctx) == FAIL)
{
// expression evaluation failed
eval_failed = TRUE;
continue;
vim_free(theline);
vim_free(text_indent);
return FAIL;
}
vim_free(theline);
theline = str;
count++;
}
else
{
if (evalstr)
{
str = eval_all_expr_in_str(str);
if (str == NULL)
{
// expression evaluation failed
eval_failed = TRUE;
continue;
}
vim_free(theline);
theline = str;
}
if (list_append_string(l, str, -1) == FAIL)
break;
if (list_append_string(l, str, -1) == FAIL)
break;
}
}
vim_free(theline);
vim_free(text_indent);
if (vim9compile && cctx->ctx_skip != SKIP_YES && !eval_failed)
generate_NEWLIST(cctx, count, FALSE);
if (eval_failed)
{
// expression evaluation in the heredoc failed
@@ -986,7 +1009,7 @@ ex_let(exarg_T *eap)
long cur_lnum = SOURCING_LNUM;
// HERE document
l = heredoc_get(eap, expr + 3, FALSE);
l = heredoc_get(eap, expr + 3, FALSE, FALSE);
if (l != NULL)
{
rettv_list_set(&rettv, l);