Add support for arbitrarily nested subcommands (#3688)

This commit is contained in:
JT 2021-06-26 09:09:06 +12:00 committed by GitHub
parent 6cdd8a2b07
commit b1970f79ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 14 deletions

View File

@ -1841,21 +1841,25 @@ fn parse_call(
error = error.or(err); error = error.or(err);
return (Some(ClassifiedCommand::Expr(Box::new(expr))), error); return (Some(ClassifiedCommand::Expr(Box::new(expr))), error);
} else if lite_cmd.parts.len() > 1 { } else if lite_cmd.parts.len() > 1 {
// Check if it's a sub-command // FIXME: only build up valid subcommands instead of all arguments
if let Some(signature) = scope.get_signature(&format!( // by checking each part to see if it's a valid identifier name
"{} {}", let mut parts: Vec<_> = lite_cmd.parts.clone().into_iter().map(|x| x.item).collect();
lite_cmd.parts[0].item, lite_cmd.parts[1].item
)) {
let (mut internal_command, err) =
parse_internal_command(&lite_cmd, scope, &signature, 1);
error = error.or(err); while parts.len() > 1 {
internal_command.args.external_redirection = if end_of_pipeline { // Check if it's a sub-command
ExternalRedirection::None if let Some(signature) = scope.get_signature(&parts.join(" ")) {
} else { let (mut internal_command, err) =
ExternalRedirection::Stdout parse_internal_command(&lite_cmd, scope, &signature, parts.len() - 1);
};
return (Some(ClassifiedCommand::Internal(internal_command)), error); error = error.or(err);
internal_command.args.external_redirection = if end_of_pipeline {
ExternalRedirection::None
} else {
ExternalRedirection::Stdout
};
return (Some(ClassifiedCommand::Internal(internal_command)), error);
}
parts.pop();
} }
} }
// Check if it's an internal command // Check if it's an internal command

View File

@ -1059,6 +1059,30 @@ fn better_subexpr_lex() {
assert_eq!(actual.out, "6"); assert_eq!(actual.out, "6");
} }
#[test]
fn subsubcommand() {
let actual = nu!(
cwd: ".", pipeline(
r#"
def "aws s3 rb" [url] { $url + " loaded" }; aws s3 rb localhost
"#)
);
assert_eq!(actual.out, "localhost loaded");
}
#[test]
fn manysubcommand() {
let actual = nu!(
cwd: ".", pipeline(
r#"
def "aws s3 rb ax vf qqqq rrrr" [url] { $url + " loaded" }; aws s3 rb ax vf qqqq rrrr localhost
"#)
);
assert_eq!(actual.out, "localhost loaded");
}
mod parse { mod parse {
use nu_test_support::nu; use nu_test_support::nu;