Skip to content

allow Vim script expressions to be evaluated inside heredocs #10129

@lacygoill

Description

@lacygoill

Is your feature request about something that is currently impossible or hard to do? Please describe the problem.

It is not easy to include the value of a Vim script expression inside a heredoc:

vim9script
var lines =<< trim END
    echo $HOME
END
echo lines
['echo $HOME']

If we want $HOME to be evaluated, we need an extra call to a combination of map() and substitute():

vim9script
var lines =<< trim END
    echo $HOME
END
lines->map((_, line) => line->substitute('$HOME', $HOME, ''))
echo lines
[echo /home/user]

Which makes the code less readable, and is probably not always reliable in the general case (i.e. substitute() might replace tokens which we want to be left alone).

Describe the solution you'd like

Extend the backtick expansion syntax which supports Vim script expressions (the one documented at :help E1083) to heredocs:

:e `=tempname()`
   ^^          ^

With this feature, the previous snippet could be simplified into this:

vim9script
var lines =<< trim eval END
    echo `=$HOME`
END
echo lines

Notice the presence of the new eval argument on the first line of the assigment:

var lines =<< trim eval END
                   ^--^

It would be necessary to avoid breaking existing scripts. With eval, Vim would look for Vim script expressions to evaluate.

Describe alternatives you've considered

An alternative is to continue using an extra call to a combination of map() and substitute(), which – again – is less readable and less reliable than the proposed syntax.

Additional context

In bash, there are 2 kinds of heredocs. The ones which do not try to expand any parameter:

cat <<'EOF'
    echo $HOME
EOF
echo $HOME

And the ones which do:

cat <<EOF
    echo $HOME
EOF
echo /home/user

The difference between the 2 depends on whether the end word is quoted. Currently, Vim script only supports the first kind. I think it would be useful to support the second one too.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions