diff --git a/crates/nu-cli/src/syntax_highlight.rs b/crates/nu-cli/src/syntax_highlight.rs index d0d5d06431..a8878b23c0 100644 --- a/crates/nu-cli/src/syntax_highlight.rs +++ b/crates/nu-cli/src/syntax_highlight.rs @@ -84,6 +84,9 @@ impl Highlighter for NuHighlighter { Style::new().fg(nu_ansi_term::Color::Yellow).bold(), next_token, )), + FlatShape::Flag => { + output.push((Style::new().fg(nu_ansi_term::Color::Yellow), next_token)) + } FlatShape::Filepath => output.push(( Style::new().fg(nu_ansi_term::Color::Yellow).bold(), next_token, diff --git a/crates/nu-engine/src/eval.rs b/crates/nu-engine/src/eval.rs index 6a642f7d50..4aa8465492 100644 --- a/crates/nu-engine/src/eval.rs +++ b/crates/nu-engine/src/eval.rs @@ -1,6 +1,6 @@ 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 nu_protocol::{Range, ShellError, Span, Spanned, Type, Unit, Value}; pub fn eval_operator(op: &Expression) -> Result { match op { @@ -60,6 +60,29 @@ fn eval_call(context: &EvaluationContext, call: &Call, input: Value) -> Result { diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index e1cdcb9781..da71974f05 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -57,7 +57,7 @@ fn check_call(command: Span, sig: &Signature, call: &Call) -> Option Some(ParseError::MissingPositional(missing.name.clone(), command)) } else { for req_flag in sig.named.iter().filter(|x| x.required) { - if call.named.iter().all(|(n, _)| n != &req_flag.long) { + if call.named.iter().all(|(n, _)| n.item != req_flag.long) { return Some(ParseError::MissingRequiredFlag( req_flag.long.clone(), command, @@ -478,7 +478,13 @@ pub fn parse_internal_call( if let Some(long_name) = long_name { // We found a long flag, like --bar error = error.or(err); - call.named.push((long_name, arg)); + call.named.push(( + Spanned { + item: long_name, + span: arg_span, + }, + arg, + )); spans_idx += 1; continue; } @@ -500,13 +506,25 @@ pub fn parse_internal_call( let (arg, err) = parse_value(working_set, *arg, &arg_shape); error = error.or(err); - call.named.push((flag.long.clone(), Some(arg))); + call.named.push(( + Spanned { + item: flag.long.clone(), + span: spans[spans_idx], + }, + Some(arg), + )); spans_idx += 1; } else { error = error.or(Some(ParseError::MissingFlagParam(arg_span))) } } else { - call.named.push((flag.long.clone(), None)); + call.named.push(( + Spanned { + item: flag.long.clone(), + span: spans[spans_idx], + }, + None, + )); } } spans_idx += 1; @@ -1850,7 +1868,18 @@ pub fn parse_signature( if bytes.starts_with(b"[") { start += 1; + } else { + error = error.or_else(|| { + Some(ParseError::Expected( + "[".into(), + Span { + start, + end: start + 1, + }, + )) + }); } + if bytes.ends_with(b"]") { end -= 1; } else { diff --git a/crates/nu-protocol/src/ast/call.rs b/crates/nu-protocol/src/ast/call.rs index 1f2a4870e7..815e18a649 100644 --- a/crates/nu-protocol/src/ast/call.rs +++ b/crates/nu-protocol/src/ast/call.rs @@ -1,5 +1,5 @@ use super::Expression; -use crate::{DeclId, Span}; +use crate::{DeclId, Span, Spanned}; #[derive(Debug, Clone)] pub struct Call { @@ -7,7 +7,7 @@ pub struct Call { pub decl_id: DeclId, pub head: Span, pub positional: Vec, - pub named: Vec<(String, Option)>, + pub named: Vec<(Spanned, Option)>, } impl Default for Call { @@ -28,7 +28,7 @@ impl Call { pub fn has_flag(&self, flag_name: &str) -> bool { for name in &self.named { - if flag_name == name.0 { + if flag_name == name.0.item { return true; } } @@ -38,7 +38,7 @@ impl Call { pub fn get_flag_expr(&self, flag_name: &str) -> Option { for name in &self.named { - if flag_name == name.0 { + if flag_name == name.0.item { return name.1.clone(); } } diff --git a/src/tests.rs b/src/tests.rs index 1d441cc3ee..fbfbf67d99 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -709,3 +709,16 @@ fn missing_column_error() -> TestResult { "cannot find column", ) } + +#[test] +fn missing_parameters() -> TestResult { + fail_test(r#"def foo {}"#, "expected [") +} + +#[test] +fn flag_param_value() -> TestResult { + run_test( + r#"def foo [--bob: int] { $bob + 100 }; foo --bob 55"#, + "155", + ) +}