# HG changeset patch # User Bram Moolenaar # Date 1652446803 -7200 # Node ID 338212bba072bacaa85b04a48a8a819cbf945ae8 # Parent be5bc2060ee8aca5899c50be32df1ffa7280bb4f patch 8.2.4948: cannot use Perl heredoc in nested :def function Commit: https://github.com/vim/vim/commit/d881d1598467d88808bafd2fa86982ebbca7dcc1 Author: Bram Moolenaar Date: Fri May 13 13:50:36 2022 +0100 patch 8.2.4948: cannot use Perl heredoc in nested :def function Problem: Cannot use Perl heredoc in nested :def function. (Virginia Senioria) Solution: Only concatenate heredoc lines when not in a nested function. (closes #10415) diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -4155,5 +4155,23 @@ if has('lua') enddef endif +if has('perl') + def Test_perl_heredoc_nested() + var lines =<< trim END + vim9script + def F(): string + def G(): string + perl << EOF + EOF + return 'done' + enddef + return G() + enddef + assert_equal('done', F()) + END + v9.CheckScriptSuccess(lines) + enddef +endif + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/userfunc.c b/src/userfunc.c --- a/src/userfunc.c +++ b/src/userfunc.c @@ -1051,53 +1051,57 @@ get_function_body( skip_until = vim_strnsave(p, skiptowhite(p) - p); getline_options = GETLINE_NONE; is_heredoc = TRUE; - if (eap->cmdidx == CMD_def) + if (eap->cmdidx == CMD_def && nesting == 0) heredoc_concat_len = newlines->ga_len + 1; } - // Check for ":cmd v =<< [trim] EOF" - // and ":cmd [a, b] =<< [trim] EOF" - // and "lines =<< [trim] EOF" for Vim9 - // Where "cmd" can be "let", "var", "final" or "const". - arg = skipwhite(skiptowhite(p)); - if (*arg == '[') - arg = vim_strchr(arg, ']'); - if (arg != NULL) + if (!is_heredoc) { - int found = (eap->cmdidx == CMD_def && arg[0] == '=' - && arg[1] == '<' && arg[2] =='<'); - - if (!found) - // skip over the argument after "cmd" - arg = skipwhite(skiptowhite(arg)); - if (found || (arg[0] == '=' && arg[1] == '<' && arg[2] =='<' - && (checkforcmd(&p, "let", 2) - || checkforcmd(&p, "var", 3) - || checkforcmd(&p, "final", 5) - || checkforcmd(&p, "const", 5)))) + // Check for ":cmd v =<< [trim] EOF" + // and ":cmd [a, b] =<< [trim] EOF" + // and "lines =<< [trim] EOF" for Vim9 + // Where "cmd" can be "let", "var", "final" or "const". + arg = skipwhite(skiptowhite(p)); + if (*arg == '[') + arg = vim_strchr(arg, ']'); + if (arg != NULL) { - p = skipwhite(arg + 3); - while (TRUE) + int found = (eap->cmdidx == CMD_def && arg[0] == '=' + && arg[1] == '<' && arg[2] =='<'); + + if (!found) + // skip over the argument after "cmd" + arg = skipwhite(skiptowhite(arg)); + if (found || (arg[0] == '=' && arg[1] == '<' + && arg[2] =='<' + && (checkforcmd(&p, "let", 2) + || checkforcmd(&p, "var", 3) + || checkforcmd(&p, "final", 5) + || checkforcmd(&p, "const", 5)))) { - if (STRNCMP(p, "trim", 4) == 0) + p = skipwhite(arg + 3); + while (TRUE) { - // Ignore leading white space. - p = skipwhite(p + 4); - heredoc_trimmed = vim_strnsave(theline, - skipwhite(theline) - theline); - continue; + if (STRNCMP(p, "trim", 4) == 0) + { + // Ignore leading white space. + p = skipwhite(p + 4); + heredoc_trimmed = vim_strnsave(theline, + skipwhite(theline) - theline); + continue; + } + if (STRNCMP(p, "eval", 4) == 0) + { + // Ignore leading white space. + p = skipwhite(p + 4); + continue; + } + break; } - if (STRNCMP(p, "eval", 4) == 0) - { - // Ignore leading white space. - p = skipwhite(p + 4); - continue; - } - break; + skip_until = vim_strnsave(p, skiptowhite(p) - p); + getline_options = GETLINE_NONE; + is_heredoc = TRUE; } - skip_until = vim_strnsave(p, skiptowhite(p) - p); - getline_options = GETLINE_NONE; - is_heredoc = TRUE; } } } diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -747,6 +747,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4948, +/**/ 4947, /**/ 4946,