From 4fdbf30308fb658ab058c7cd387df8122180892f Mon Sep 17 00:00:00 2001 From: JT Date: Fri, 21 May 2021 10:55:38 +1200 Subject: [PATCH] Paren interpolation (#3452) * Switch interp to use parens * improve interp parsing --- .../nu-command/src/commands/each/command.rs | 2 +- crates/nu-command/tests/commands/reduce.rs | 7 +++-- crates/nu-parser/src/parse.rs | 29 ++++++++++++++----- tests/shell/pipeline/commands/internal.rs | 18 ++++++++++-- 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/crates/nu-command/src/commands/each/command.rs b/crates/nu-command/src/commands/each/command.rs index 9f6eefed19..1f56faf1ff 100644 --- a/crates/nu-command/src/commands/each/command.rs +++ b/crates/nu-command/src/commands/each/command.rs @@ -52,7 +52,7 @@ impl WholeStreamCommand for Each { Example { description: "Number each item and echo a message", example: - "echo ['bob' 'fred'] | each --numbered { echo $\"{$it.index} is {$it.item}\" }", + "echo ['bob' 'fred'] | each --numbered { echo $\"($it.index) is ($it.item)\" }", result: Some(vec![Value::from("0 is bob"), Value::from("1 is fred")]), }, Example { diff --git a/crates/nu-command/tests/commands/reduce.rs b/crates/nu-command/tests/commands/reduce.rs index 3ff1daddb1..834db6f72b 100644 --- a/crates/nu-command/tests/commands/reduce.rs +++ b/crates/nu-command/tests/commands/reduce.rs @@ -8,20 +8,23 @@ fn reduce_table_column() { echo "[{month:2,total:30}, {month:3,total:10}, {month:4,total:3}, {month:5,total:60}]" | from json | get total - | reduce -f 20 { $it + (math eval $"{$acc}^1.05")} + | reduce -f 20 { $it + (math eval $"($acc)^1.05")} | str from -d 1 "# ) ); assert_eq!(actual.out, "180.6"); +} +#[test] +fn reduce_table_column_with_path() { let actual = nu!( cwd: ".", pipeline( r#" echo "[{month:2,total:30}, {month:3,total:10}, {month:4,total:3}, {month:5,total:60}]" | from json - | reduce -f 20 { $it.total + (math eval $"{$acc}^1.05")} + | reduce -f 20 { $it.total + (math eval $"($acc)^1.05")} | str from -d 1 "# ) diff --git a/crates/nu-parser/src/parse.rs b/crates/nu-parser/src/parse.rs index 9f8cb17999..ee216b19da 100644 --- a/crates/nu-parser/src/parse.rs +++ b/crates/nu-parser/src/parse.rs @@ -499,7 +499,7 @@ fn format(input: &str, start: usize) -> (Vec, Option) loop { end += 1; if let Some(c) = loop_input.next() { - if c == '{' { + if c == '(' { break; } before.push(c); @@ -518,14 +518,29 @@ fn format(input: &str, start: usize) -> (Vec, Option) start = end; let mut found_end = false; - let mut open_count = 1; + let mut delimiter_stack = vec![')']; + while let Some(c) = loop_input.next() { end += 1; - if c == '{' { - open_count += 1; - } else if c == '}' { - open_count -= 1; - if open_count == 0 { + if let Some('\'') = delimiter_stack.last() { + if c == '\'' { + delimiter_stack.pop(); + } + } else if let Some('"') = delimiter_stack.last() { + if c == '"' { + delimiter_stack.pop(); + } + } else if c == '\'' { + delimiter_stack.push('\''); + } else if c == '"' { + delimiter_stack.push('"'); + } else if c == '(' { + delimiter_stack.push(')'); + } else if c == ')' { + if let Some(')') = delimiter_stack.last() { + delimiter_stack.pop(); + } + if delimiter_stack.is_empty() { found_end = true; break; } diff --git a/tests/shell/pipeline/commands/internal.rs b/tests/shell/pipeline/commands/internal.rs index 047358c5c3..744b272042 100644 --- a/tests/shell/pipeline/commands/internal.rs +++ b/tests/shell/pipeline/commands/internal.rs @@ -118,7 +118,7 @@ fn string_interpolation_with_it() { let actual = nu!( cwd: ".", r#" - echo "foo" | each { echo $"{$it}" } + echo "foo" | each { echo $"($it)" } "# ); @@ -130,7 +130,7 @@ fn string_interpolation_with_it_column_path() { let actual = nu!( cwd: ".", r#" - echo [[name]; [sammie]] | each { echo $"{$it.name}" } + echo [[name]; [sammie]] | each { echo $"($it.name)" } "# ); @@ -142,13 +142,25 @@ fn string_interpolation_shorthand_overlap() { let actual = nu!( cwd: ".", r#" - $"3 + 4 = {3 + 4}" + $"3 + 4 = (3 + 4)" "# ); assert_eq!(actual.out, "3 + 4 = 7"); } +#[test] +fn string_interpolation_and_paren() { + let actual = nu!( + cwd: ".", + r#" + $"a paren is ('(')" + "# + ); + + assert_eq!(actual.out, "a paren is ("); +} + #[test] fn bignum_large_integer() { let actual = nu!(