diff --git a/crates/nu-command/src/strings/build_string.rs b/crates/nu-command/src/strings/build_string.rs index b8045dbf86..db79dbd886 100644 --- a/crates/nu-command/src/strings/build_string.rs +++ b/crates/nu-command/src/strings/build_string.rs @@ -39,7 +39,7 @@ impl Command for BuildString { }), }, Example { - example: "build-string (1 + 2) = one ' ' plus ' ' two", + example: r#"build-string $"(1 + 2)" = one ' ' plus ' ' two"#, description: "Builds a string from letters a b c", result: Some(Value::String { val: "3=one plus two".to_string(), diff --git a/crates/nu-command/src/strings/char_.rs b/crates/nu-command/src/strings/char_.rs index 873d8c7b54..f0bd321dfa 100644 --- a/crates/nu-command/src/strings/char_.rs +++ b/crates/nu-command/src/strings/char_.rs @@ -161,7 +161,7 @@ impl Command for Char { SyntaxShape::Any, "the name of the character to output", ) - .rest("rest", SyntaxShape::String, "multiple Unicode bytes") + .rest("rest", SyntaxShape::Any, "multiple Unicode bytes") .switch("list", "List all supported character names", Some('l')) .switch("unicode", "Unicode string i.e. 1f378", Some('u')) .switch("integer", "Create a codepoint from an integer", Some('i')) diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index 277beaf11d..f23e1f59e0 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -1872,6 +1872,16 @@ pub fn parse_full_cell_path( .type_scope .add_type(working_set.type_scope.get_last_output()); + let ty = output + .pipelines + .last() + .and_then(|Pipeline { expressions, .. }| expressions.last()) + .map(|expr| match expr.expr { + Expr::BinaryOp(..) => expr.ty.clone(), + _ => working_set.type_scope.get_last_output(), + }) + .unwrap_or_else(|| working_set.type_scope.get_last_output()); + error = error.or(err); let block_id = working_set.add_block(output); @@ -1881,7 +1891,7 @@ pub fn parse_full_cell_path( Expression { expr: Expr::Subexpression(block_id), span: head_span, - ty: working_set.type_scope.get_last_output(), + ty, custom_completion: None, }, true, diff --git a/crates/nu-parser/tests/test_parser.rs b/crates/nu-parser/tests/test_parser.rs index 7e68f5cecd..155d4870e8 100644 --- a/crates/nu-parser/tests/test_parser.rs +++ b/crates/nu-parser/tests/test_parser.rs @@ -929,6 +929,45 @@ mod input_types { } } + #[derive(Clone)] + pub struct IfMocked; + + impl Command for IfMocked { + fn name(&self) -> &str { + "if" + } + + fn usage(&self) -> &str { + "Mock if command" + } + + fn signature(&self) -> nu_protocol::Signature { + Signature::build("if") + .required("cond", SyntaxShape::Expression, "condition to check") + .required( + "then_block", + SyntaxShape::Block(Some(vec![])), + "block to run if check succeeds", + ) + .optional( + "else_expression", + SyntaxShape::Keyword(b"else".to_vec(), Box::new(SyntaxShape::Expression)), + "expression or block to run if check fails", + ) + .category(Category::Core) + } + + fn run( + &self, + _engine_state: &EngineState, + _stack: &mut Stack, + _call: &nu_protocol::ast::Call, + _input: nu_protocol::PipelineData, + ) -> Result { + todo!() + } + } + fn add_declations(engine_state: &mut EngineState) { let delta = { let mut working_set = StateWorkingSet::new(&engine_state); @@ -942,6 +981,7 @@ mod input_types { working_set.add_decl(Box::new(AggMin)); working_set.add_decl(Box::new(Collect)); working_set.add_decl(Box::new(WithColumn)); + working_set.add_decl(Box::new(IfMocked)); working_set.render() }; @@ -1194,4 +1234,26 @@ mod input_types { _ => panic!("Expected expression Call not found"), } } + + #[test] + fn operations_within_blocks_test() { + let mut engine_state = EngineState::new(); + add_declations(&mut engine_state); + + let mut working_set = StateWorkingSet::new(&engine_state); + let inputs = vec![ + r#"let a = 'b'; ($a == 'b') || ($a == 'b')"#, + r#"let a = 'b'; ($a == 'b') || ($a == 'b') && ($a == 'b')"#, + r#"let a = 1; ($a == 1) || ($a == 2) && ($a == 3)"#, + r#"let a = 'b'; if ($a == 'b') || ($a == 'b') { true } else { false }"#, + r#"let a = 1; if ($a == 1) || ($a > 0) { true } else { false }"#, + ]; + + for input in inputs { + let (block, err) = parse(&mut working_set, None, input.as_bytes(), true, &[]); + + assert!(err.is_none(), "testing: {}", input); + assert!(block.len() == 2, "testing: {}", input); + } + } }