fix quotation rules (#16089)

# Description
This script as example for demonstration
```nushell
def miku [] { print "Hiii world! 初音ミクはみんなのことが大好きだよ!" }

def main [leek: int, fn: closure] {
  print $"Miku has ($leek) leeks 🩵"
  do $fn
}
```
---

`escape_for_string_arg` quoting strings misses, where `|` and `;` did
split the command into 2+ commands
```console
~:►  nu ./miku.nu '32' '{miku}'
Miku has 32 leeks 🩵
Hiii world! 初音ミクはみんなのことが大好きだよ!
~:►  nu ./miku.nu '32' '{miku};ls|' where type == dir 
Miku has 32 leeks 🩵
Hiii world! 初音ミクはみんなのことが大好きだよ!
╭────┬─────────────┬──────┬────────┬──────────────╮
│  # │    name     │ type │  size  │   modified   │
├────┼─────────────┼──────┼────────┼──────────────┤
│  0 │ Desktop     │ dir  │ 4.0 kB │ 5 months ago │
│  1 │ Documents   │ dir  │ 4.0 kB │ a day ago    │
│  2 │ Downloads   │ dir  │ 4.0 kB │ a day ago    │
│  3 │ Music       │ dir  │ 4.0 kB │ 9 months ago │
│  4 │ Pictures    │ dir  │ 4.0 kB │ 3 weeks ago  │
│  5 │ Public      │ dir  │ 4.0 kB │ 9 months ago │
│  6 │ Templates   │ dir  │ 4.0 kB │ 3 months ago │
│  7 │ Videos      │ dir  │ 4.0 kB │ 9 months ago │
│  8 │ __pycache__ │ dir  │ 4.0 kB │ 3 weeks ago  │
│  9 │ bin         │ dir  │ 4.0 kB │ 3 days ago   │
│ 10 │ repos       │ dir  │ 4.0 kB │ a day ago    │
│ 11 │ trash       │ dir  │ 4.0 kB │ 3 days ago   │
╰────┴─────────────┴──────┴────────┴──────────────╯
```

# User-Facing Changes

This adjustment won't need a change, aside from clarifying the following
behavior, which is unintuitive and potentially ambiguous

```console
~:►  nu ./miku.nu '32' {miku}
Miku has 32 leeks 🩵
Hiii world! 初音ミクはみんなのことが大好きだよ!
~:►  nu ./miku.nu '32' { miku }
Error: nu::parser::parse_mismatch

  × Parse mismatch during operation.
   ╭─[<commandline>:1:9]
 1 │ main 32 "{ miku }"
   ·         ─────┬────
   ·              ╰── expected block, closure or record
   ╰────

~:►  nu ./miku.nu '32' '{' miku '}'
Miku has 32 leeks 🩵
Hiii world! 初音ミクはみんなのことが大好きだよ!
```
This commit is contained in:
Klapptnot
2025-07-17 10:36:06 -03:00
committed by GitHub
parent 1ba4fe0aac
commit c2622589ef

View File

@ -2,9 +2,16 @@ use nu_utils::escape_quote_string;
fn string_should_be_quoted(input: &str) -> bool {
input.starts_with('$')
|| input
.chars()
.any(|c| c == ' ' || c == '(' || c == '\'' || c == '`' || c == '"' || c == '\\')
|| input.chars().any(|c| {
c == ' '
|| c == '('
|| c == '\''
|| c == '`'
|| c == '"'
|| c == '\\'
|| c == ';'
|| c == '|'
})
}
// Escape rules:
@ -51,14 +58,17 @@ mod test {
#[test]
fn test_quote_special() {
// check for input arg like this:
// nu b.nu "two words" $nake "`123"
assert_eq!(
escape_for_script_arg("two words"),
r#""two words""#.to_string()
);
assert_eq!(escape_for_script_arg("$nake"), r#""$nake""#.to_string());
assert_eq!(escape_for_script_arg("`123"), r#""`123""#.to_string());
let cases = vec![
("two words", r#""two words""#),
("$nake", r#""$nake""#),
("`123", r#""`123""#),
("this|cat", r#""this|cat""#),
("this;cat", r#""this;cat""#),
];
for (input, expected) in cases {
assert_eq!(escape_for_script_arg(input).as_str(), expected);
}
}
#[test]