From e8dfd4ba39a5d40c99d51a16794e7581bfa73692 Mon Sep 17 00:00:00 2001 From: JT Date: Thu, 10 Jun 2021 09:01:40 +1200 Subject: [PATCH] Enable syntax/completions for source (#3589) --- crates/nu-command/src/commands/source.rs | 2 +- crates/nu-errors/src/lib.rs | 8 +++ crates/nu-parser/src/parse.rs | 66 ++++++++++++------------ 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/crates/nu-command/src/commands/source.rs b/crates/nu-command/src/commands/source.rs index 636490ec89..2629f8e9d0 100644 --- a/crates/nu-command/src/commands/source.rs +++ b/crates/nu-command/src/commands/source.rs @@ -21,7 +21,7 @@ impl WholeStreamCommand for Source { fn signature(&self) -> Signature { Signature::build("source").required( "filename", - SyntaxShape::String, + SyntaxShape::FilePath, "the filepath to the script file to source", ) } diff --git a/crates/nu-errors/src/lib.rs b/crates/nu-errors/src/lib.rs index fdde500e48..8c56a8fb9d 100644 --- a/crates/nu-errors/src/lib.rs +++ b/crates/nu-errors/src/lib.rs @@ -155,6 +155,8 @@ pub enum ArgumentError { /// A sequence of characters was found that was not syntactically valid (but would have /// been valid if the command was an external command) InvalidExternalWord, + /// A bad value in this location + BadValue(String), } impl PrettyDebug for ArgumentError { @@ -186,6 +188,11 @@ impl PrettyDebug for ArgumentError { + DbgDocBldr::description("`") } ArgumentError::InvalidExternalWord => DbgDocBldr::description("invalid word"), + ArgumentError::BadValue(msg) => { + DbgDocBldr::description("bad value `") + + DbgDocBldr::description(msg) + + DbgDocBldr::description("`") + } } } } @@ -522,6 +529,7 @@ impl ShellError { ), ) .with_labels(vec![Label::primary(0, command.span)]), + ArgumentError::BadValue(msg) => Diagnostic::error().with_message(msg.clone()).with_labels(vec![Label::primary(0, command.span).with_message(msg)]) }), ProximateShellError::TypeError { expected, diff --git a/crates/nu-parser/src/parse.rs b/crates/nu-parser/src/parse.rs index a26688e2e5..d43732f8ec 100644 --- a/crates/nu-parser/src/parse.rs +++ b/crates/nu-parser/src/parse.rs @@ -1836,38 +1836,6 @@ fn parse_call( error, ); } - } else if lite_cmd.parts[0].item == "source" { - if lite_cmd.parts.len() != 2 { - return ( - None, - Some(ParseError::argument_error( - lite_cmd.parts[0].clone(), - ArgumentError::MissingMandatoryPositional("a path for sourcing".into()), - )), - ); - } - if lite_cmd.parts[1].item.starts_with('$') { - return ( - None, - Some(ParseError::mismatch( - "a filepath constant", - lite_cmd.parts[1].clone(), - )), - ); - } - if let Ok(contents) = - std::fs::read_to_string(expand_path(&lite_cmd.parts[1].item).into_owned()) - { - let _ = parse(&contents, 0, scope); - } else { - return ( - None, - Some(ParseError::mismatch( - "a filepath to a source file", - lite_cmd.parts[1].clone(), - )), - ); - } } else if lite_cmd.parts.len() > 1 { // Check if it's a sub-command if let Some(signature) = scope.get_signature(&format!( @@ -1899,6 +1867,40 @@ fn parse_call( } let (mut internal_command, err) = parse_internal_command(&lite_cmd, scope, &signature, 0); + if internal_command.name == "source" { + if lite_cmd.parts.len() != 2 { + return ( + Some(ClassifiedCommand::Internal(internal_command)), + Some(ParseError::argument_error( + lite_cmd.parts[0].clone(), + ArgumentError::MissingMandatoryPositional("a path for sourcing".into()), + )), + ); + } + if lite_cmd.parts[1].item.starts_with('$') { + return ( + Some(ClassifiedCommand::Internal(internal_command)), + Some(ParseError::mismatch( + "a filepath constant", + lite_cmd.parts[1].clone(), + )), + ); + } + if let Ok(contents) = + std::fs::read_to_string(expand_path(&lite_cmd.parts[1].item).into_owned()) + { + let _ = parse(&contents, 0, scope); + } else { + return ( + Some(ClassifiedCommand::Internal(internal_command)), + Some(ParseError::argument_error( + lite_cmd.parts[1].clone(), + ArgumentError::BadValue("can't load source file".into()), + )), + ); + } + } + error = error.or(err); internal_command.args.external_redirection = if end_of_pipeline { ExternalRedirection::None