From c0c514fd243a1f02b840e5b17ea150e5e8e401cc Mon Sep 17 00:00:00 2001 From: WindSoilder Date: Thu, 23 Nov 2023 06:57:37 +0800 Subject: [PATCH] enable to pass switch values dynamically (#11057) # Description Closes: #7260 About the change: When we make an internalcall, and meet a `switch` (Flag.arg is None), nushell will try to see if the switch is called like `--xyz=false` , if that is true, `parse_long_flag` will return relative value. # User-Facing Changes So after the pr, the following would be possible: ```nushell def build-imp [--push, --release] { echo $"Doing a build with push: ($push) and release: ($release)" } def build [--push, --release] { build-imp --push=$push --release=$release } build --push --release=false build --push=false --release=true build --push=false --release=false build --push --release build ``` # Tests + Formatting Done # After Submitting Needs to submit a doc update, mentioned about the difference between `def a [--x] {}` and `def a [--x: bool] {}` --- crates/nu-parser/src/parser.rs | 32 ++++++++++++++++++++++++------- src/tests/test_custom_commands.rs | 31 +++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index 47c631b68ae58..cf30f46c24627 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -401,13 +401,31 @@ fn parse_long_flag( } } else { // A flag with no argument - ( - Some(Spanned { - item: long_name, - span: arg_span, - }), - None, - ) + // It can also takes a boolean value like --x=true + if split.len() > 1 { + // and we also have the argument + let long_name_len = long_name.len(); + let mut span = arg_span; + span.start += long_name_len + 3; //offset by long flag and '=' + + let arg = parse_value(working_set, span, &SyntaxShape::Boolean); + + ( + Some(Spanned { + item: long_name, + span: Span::new(arg_span.start, arg_span.start + long_name_len + 2), + }), + Some(arg), + ) + } else { + ( + Some(Spanned { + item: long_name, + span: arg_span, + }), + None, + ) + } } } else { working_set.error(ParseError::UnknownFlag( diff --git a/src/tests/test_custom_commands.rs b/src/tests/test_custom_commands.rs index f9daa5c543718..3447d80f11999 100644 --- a/src/tests/test_custom_commands.rs +++ b/src/tests/test_custom_commands.rs @@ -83,6 +83,35 @@ fn custom_switch2() -> TestResult { #[test] fn custom_switch3() -> TestResult { + run_test( + r#"def florb [ --dry-run ] { $dry_run }; florb --dry-run=false"#, + "false", + ) +} + +#[test] +fn custom_switch4() -> TestResult { + run_test( + r#"def florb [ --dry-run ] { $dry_run }; florb --dry-run=true"#, + "true", + ) +} + +#[test] +fn custom_switch5() -> TestResult { + run_test(r#"def florb [ --dry-run ] { $dry_run }; florb"#, "false") +} + +#[test] +fn custom_switch6() -> TestResult { + run_test( + r#"def florb [ --dry-run ] { $dry_run }; florb --dry-run"#, + "true", + ) +} + +#[test] +fn custom_flag1() -> TestResult { run_test( r#"def florb [ --age: int = 0 @@ -96,7 +125,7 @@ fn custom_switch3() -> TestResult { } #[test] -fn custom_switch4() -> TestResult { +fn custom_flag2() -> TestResult { run_test( r#"def florb [ --age: int