Mercurial > vim
changeset 28850:338212bba072 v8.2.4948
patch 8.2.4948: cannot use Perl heredoc in nested :def function
Commit: https://github.com/vim/vim/commit/d881d1598467d88808bafd2fa86982ebbca7dcc1
Author: Bram Moolenaar <Bram@vim.org>
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)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Fri, 13 May 2022 15:00:03 +0200 |
parents | be5bc2060ee8 |
children | 9b622f8fdfa0 |
files | src/testdir/test_vim9_func.vim src/userfunc.c src/version.c |
diffstat | 3 files changed, 62 insertions(+), 38 deletions(-) [+] |
line wrap: on
line diff
--- 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
--- 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; } } }