Support variables/interpolation in o>, e>, o+e> redirect (#9747)

# Description
Fixes:  #8517
Fixes: #9246
Fixes: #9709
Relative: #9723


## About the change
Before the pr, nushell only parse redirection target as a string(through
`parse_string` call).
In the pr, I'm trying to make the value more generic(using `parse_value`
with `SyntaxShape::Any`)

And during eval stage, we guard it to only eval `String`,
`StringInterpolation`, `FullCellPath`, `FilePath`, so other type of
redirection target like `1ms` won't be permitted.

# User-Facing Changes

After the pr: redirection support something like the following:
1. `let a = "x"; cat toolkit.nu o> $a`
2. `let a = "x"; cat toolkit.nu o> $"($a).txt"`
3. `cat toolkit.nu out> ("~/a.txt" | path expand)`
This commit is contained in:
WindSoilder
2023-07-20 19:56:46 +08:00
committed by GitHub
parent 488002f4bc
commit ba4723cc9f
3 changed files with 82 additions and 8 deletions

View File

@ -795,7 +795,10 @@ pub fn eval_element_with_input(
redirect_stderr,
),
PipelineElement::Redirection(span, redirection, expr) => match &expr.expr {
Expr::String(_) => {
Expr::String(_)
| Expr::FullCellPath(_)
| Expr::StringInterpolation(_)
| Expr::Filepath(_) => {
let exit_code = match &mut input {
PipelineData::ExternalStream { exit_code, .. } => exit_code.take(),
_ => None,
@ -880,7 +883,16 @@ pub fn eval_element_with_input(
out: (out_span, out_expr),
err: (err_span, err_expr),
} => match (&out_expr.expr, &err_expr.expr) {
(Expr::String(_), Expr::String(_)) => {
(
Expr::String(_)
| Expr::FullCellPath(_)
| Expr::StringInterpolation(_)
| Expr::Filepath(_),
Expr::String(_)
| Expr::FullCellPath(_)
| Expr::StringInterpolation(_)
| Expr::Filepath(_),
) => {
if let Some(save_command) = engine_state.find_decl(b"save", &[]) {
let exit_code = match &mut input {
PipelineData::ExternalStream { exit_code, .. } => exit_code.take(),