Merge pull request #105 from nushell/improve_external_args

Allow vars and subexprs in extern args
This commit is contained in:
JT 2021-10-09 10:56:24 +13:00 committed by GitHub
commit b654415494
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 22 deletions

View File

@ -39,8 +39,12 @@ impl Highlighter for NuHighlighter {
.to_string();
match shape.1 {
FlatShape::Custom(..) => output.push((Style::new().bold(), next_token)),
FlatShape::External => output.push((Style::new().bold(), next_token)),
FlatShape::ExternalArg => output.push((Style::new().bold(), next_token)),
FlatShape::External => {
output.push((Style::new().fg(nu_ansi_term::Color::Green), next_token))
}
FlatShape::ExternalArg => {
output.push((Style::new().fg(nu_ansi_term::Color::Green), next_token))
}
FlatShape::Garbage => output.push((
Style::new()
.fg(nu_ansi_term::Color::White)

View File

@ -2,6 +2,8 @@ use nu_protocol::ast::{Block, Call, Expr, Expression, Operator, Statement};
use nu_protocol::engine::EvaluationContext;
use nu_protocol::{Range, ShellError, Span, Type, Unit, Value};
use crate::FromValue;
pub fn eval_operator(op: &Expression) -> Result<Operator, ShellError> {
match op {
Expression {
@ -71,7 +73,7 @@ fn eval_call(context: &EvaluationContext, call: &Call, input: Value) -> Result<V
fn eval_external(
context: &EvaluationContext,
name: &Span,
args: &[Span],
args: &[Expression],
input: Value,
last_expression: bool,
) -> Result<Value, ShellError> {
@ -84,20 +86,28 @@ fn eval_external(
let command = engine_state.get_decl(decl_id);
let mut call = Call::new();
call.positional = [*name]
.iter()
.chain(args.iter())
.map(|span| {
let contents = engine_state.get_span_contents(span);
let val = String::from_utf8_lossy(contents);
Expression {
expr: Expr::String(val.into()),
span: *span,
ty: Type::String,
custom_completion: None,
}
let name_span = name;
let name = engine_state.get_span_contents(name);
call.positional.push(Expression {
expr: Expr::String(String::from_utf8_lossy(name).to_string()),
span: *name_span,
ty: Type::String,
custom_completion: None,
});
for arg in args {
let span = arg.span;
let result = eval_expression(context, arg)?;
let result: String = FromValue::from_value(&result)?;
call.positional.push(Expression {
expr: Expr::String(result),
span,
ty: Type::String,
custom_completion: None,
})
.collect();
}
if last_expression {
call.named.push(("last_expression".into(), None))

View File

@ -67,7 +67,19 @@ pub fn flatten_expression(
let mut output = vec![(*name, FlatShape::External)];
for arg in args {
output.push((*arg, FlatShape::ExternalArg));
//output.push((*arg, FlatShape::ExternalArg));
match arg {
Expression {
expr: Expr::String(..),
span,
..
} => {
output.push((*span, FlatShape::ExternalArg));
}
_ => {
output.extend(flatten_expression(working_set, arg));
}
}
}
output

View File

@ -104,14 +104,28 @@ pub fn check_name<'a>(
}
pub fn parse_external_call(
_working_set: &mut StateWorkingSet,
working_set: &mut StateWorkingSet,
spans: &[Span],
) -> (Expression, Option<ParseError>) {
// TODO: add external parsing
let mut args = vec![];
let name = spans[0];
let mut error = None;
for span in &spans[1..] {
args.push(*span);
let contents = working_set.get_span_contents(*span);
if contents.starts_with(b"$") || contents.starts_with(b"(") {
let (arg, err) = parse_expression(working_set, &[*span], true);
error = error.or(err);
args.push(arg);
} else {
args.push(Expression {
expr: Expr::String(String::from_utf8_lossy(contents).to_string()),
span: *span,
ty: Type::String,
custom_completion: None,
})
}
}
(
Expression {
@ -120,7 +134,7 @@ pub fn parse_external_call(
ty: Type::Unknown,
custom_completion: None,
},
None,
error,
)
}

View File

@ -14,7 +14,7 @@ pub enum Expr {
),
Var(VarId),
Call(Box<Call>),
ExternalCall(Span, Vec<Span>),
ExternalCall(Span, Vec<Expression>),
Operator(Operator),
RowCondition(VarId, Box<Expression>),
BinaryOp(Box<Expression>, Box<Expression>, Box<Expression>), //lhs, op, rhs