Add magic $in variable (#309)

* Add magic in variable

* Oops, missing file
This commit is contained in:
JT
2021-11-08 19:21:24 +13:00
committed by GitHub
parent e0a26cd048
commit e9a7def183
9 changed files with 393 additions and 6 deletions

View File

@ -1197,6 +1197,16 @@ pub fn parse_variable_expr(
},
None,
);
} else if contents == b"$in" {
return (
Expression {
expr: Expr::Var(nu_protocol::IN_VARIABLE_ID),
span,
ty: Type::Unknown,
custom_completion: None,
},
None,
);
}
let (id, err) = parse_variable(working_set, span);
@ -3168,7 +3178,7 @@ pub fn parse_block(
.iter()
.map(|pipeline| {
if pipeline.commands.len() > 1 {
let output = pipeline
let mut output = pipeline
.commands
.iter()
.map(|command| {
@ -3182,6 +3192,11 @@ pub fn parse_block(
})
.collect::<Vec<Expression>>();
for expr in output.iter_mut().skip(1) {
if expr.has_in_variable(working_set) {
*expr = wrap_expr_with_collect(working_set, expr);
}
}
Statement::Pipeline(Pipeline {
expressions: output,
})
@ -3375,6 +3390,62 @@ pub fn find_captures_in_expr(
output
}
fn wrap_expr_with_collect(working_set: &mut StateWorkingSet, expr: &Expression) -> Expression {
let span = expr.span;
if let Some(decl_id) = working_set.find_decl(b"collect") {
let mut output = vec![];
let var_id = working_set.next_var_id();
let mut signature = Signature::new("");
signature.required_positional.push(PositionalArg {
var_id: Some(var_id),
name: "$it".into(),
desc: String::new(),
shape: SyntaxShape::Any,
});
let mut expr = expr.clone();
expr.replace_in_variable(working_set, var_id);
let mut block = Block {
stmts: vec![Statement::Pipeline(Pipeline {
expressions: vec![expr],
})],
signature: Box::new(signature),
..Default::default()
};
let mut seen = vec![];
let captures = find_captures_in_block(working_set, &block, &mut seen);
block.captures = captures;
let block_id = working_set.add_block(block);
output.push(Expression {
expr: Expr::Block(block_id),
span,
ty: Type::Unknown,
custom_completion: None,
});
Expression {
expr: Expr::Call(Box::new(Call {
head: Span::unknown(),
named: vec![],
positional: output,
decl_id,
})),
span,
ty: Type::String,
custom_completion: None,
}
} else {
Expression::garbage(span)
}
}
// Parses a vector of u8 to create an AST Block. If a file name is given, then
// the name is stored in the working set. When parsing a source without a file
// name, the source of bytes is stored as "source"