mirror of
https://github.com/nushell/nushell
synced 2024-12-25 20:43:09 +00:00
Simplify expressions (#3389)
* WIP: experiment with simpler expressions * fix simple invoke * update tests * fix a few tests * Make paren parsing more robust * fix external args * Remove old invocation * Update tests * Update tests
This commit is contained in:
parent
c80a9585b0
commit
25a8caa9b0
38 changed files with 181 additions and 364 deletions
|
@ -81,11 +81,7 @@ ptree-support = ["nu-cli/ptree", "nu-command/ptree"]
|
|||
rustyline-support = ["nu-cli/rustyline-support", "nu-command/rustyline-support"]
|
||||
term-support = ["nu-cli/term", "nu-command/term"]
|
||||
uuid-support = ["nu-cli/uuid_crate", "nu-command/uuid_crate"]
|
||||
which-support = [
|
||||
"nu-cli/which",
|
||||
"nu-command/which",
|
||||
"nu-engine/which",
|
||||
]
|
||||
which-support = ["nu-cli/which", "nu-command/which", "nu-engine/which"]
|
||||
|
||||
default = [
|
||||
"nu-cli/shadow-rs",
|
||||
|
|
|
@ -384,7 +384,7 @@ mod tests {
|
|||
#[test]
|
||||
fn completes_incomplete_nested_structure() {
|
||||
let registry: VecRegistry = vec![Signature::build("sys")].into();
|
||||
let line = "echo $(sy";
|
||||
let line = "echo (sy";
|
||||
|
||||
assert_eq!(
|
||||
completion_location(line, ®istry, 8),
|
||||
|
|
|
@ -145,7 +145,7 @@ fn requote(orig_value: String) -> String {
|
|||
if should_quote {
|
||||
if quotes.is_empty() {
|
||||
// TODO we don't really have an escape character, so there isn't a great option right
|
||||
// now. One possibility is `{{$(char backtick)}}`
|
||||
// now. One possibility is `{{(char backtick)}}`
|
||||
value.to_string()
|
||||
} else {
|
||||
let quote = quotes[0];
|
||||
|
|
|
@ -44,7 +44,7 @@ impl WholeStreamCommand for Command {
|
|||
},
|
||||
Example {
|
||||
description: "Check that all values are even",
|
||||
example: "echo [2 4 6 8] | all? $(= $it mod 2) == 0",
|
||||
example: "echo [2 4 6 8] | all? ($it mod 2) == 0",
|
||||
result: Some(vec![Value::from(true)]),
|
||||
},
|
||||
]
|
||||
|
|
|
@ -69,7 +69,7 @@ following values:
|
|||
https://en.wikipedia.org/wiki/ANSI_escape_code
|
||||
|
||||
OSC: '\x1b]' is not required for --osc parameter
|
||||
Example: echo [$(ansi -o '0') 'some title' $(char bel)] | str collect
|
||||
Example: echo [(ansi -o '0') 'some title' (char bel)] | str collect
|
||||
Format: #
|
||||
0 Set window title and icon name
|
||||
1 Set icon name
|
||||
|
@ -96,7 +96,7 @@ Format: #
|
|||
Example {
|
||||
description:
|
||||
"Use ansi to color text (rb = red bold, gb = green bold, pb = purple bold)",
|
||||
example: r#"echo [$(ansi rb) Hello " " $(ansi gb) Nu " " $(ansi pb) World] | str collect"#,
|
||||
example: r#"echo [(ansi rb) Hello " " (ansi gb) Nu " " (ansi pb) World] | str collect"#,
|
||||
result: Some(vec![Value::from(
|
||||
"\u{1b}[1;31mHello \u{1b}[1;32mNu \u{1b}[1;35mWorld",
|
||||
)]),
|
||||
|
@ -104,7 +104,7 @@ Format: #
|
|||
Example {
|
||||
description:
|
||||
"Use ansi to color text (rb = red bold, gb = green bold, pb = purple bold)",
|
||||
example: r#"echo [$(ansi -e '3;93;41m') Hello $(ansi reset) " " $(ansi gb) Nu " " $(ansi pb) World] | str collect"#,
|
||||
example: r#"echo [(ansi -e '3;93;41m') Hello (ansi reset) " " (ansi gb) Nu " " (ansi pb) World] | str collect"#,
|
||||
result: Some(vec![Value::from(
|
||||
"\u{1b}[3;93;41mHello\u{1b}[0m \u{1b}[1;32mNu \u{1b}[1;35mWorld",
|
||||
)]),
|
||||
|
@ -299,7 +299,7 @@ pub fn str_to_ansi(s: &str) -> Option<String> {
|
|||
// Reference for ansi codes https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797
|
||||
// Another good reference http://ascii-table.com/ansi-escape-sequences.php
|
||||
|
||||
// For setting title like `echo [$(char title) $(pwd) $(char bel)] | str collect`
|
||||
// For setting title like `echo [(char title) (pwd) (char bel)] | str collect`
|
||||
"title" => Some("\x1b]2;".to_string()), // ESC]2; xterm sets window title using OSC syntax escapes
|
||||
|
||||
// Ansi Erase Sequences
|
||||
|
|
|
@ -31,7 +31,7 @@ impl WholeStreamCommand for SubCommand {
|
|||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "strip ansi escape sequences from string",
|
||||
example: "echo [$(ansi gb) 'hello' $(ansi reset)] | str collect | ansi strip",
|
||||
example: "echo [(ansi gb) 'hello' (ansi reset)] | str collect | ansi strip",
|
||||
result: None,
|
||||
}]
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ impl WholeStreamCommand for Command {
|
|||
},
|
||||
Example {
|
||||
description: "Check if any of the values is odd",
|
||||
example: "echo [2 4 1 6 8] | any? $(= $it mod 2) == 1",
|
||||
example: "echo [2 4 1 6 8] | any? ($it mod 2) == 1",
|
||||
result: Some(vec![Value::from(true)]),
|
||||
},
|
||||
]
|
||||
|
|
|
@ -35,7 +35,7 @@ impl WholeStreamCommand for Char {
|
|||
},
|
||||
Example {
|
||||
description: "Output prompt character, newline and a hamburger character",
|
||||
example: r#"echo $(char prompt) $(char newline) $(char hamburger)"#,
|
||||
example: r#"echo (char prompt) (char newline) (char hamburger)"#,
|
||||
result: Some(vec![
|
||||
UntaggedValue::string("\u{25b6}").into(),
|
||||
UntaggedValue::string("\n").into(),
|
||||
|
|
|
@ -42,7 +42,7 @@ impl WholeStreamCommand for Each {
|
|||
},
|
||||
Example {
|
||||
description: "Echo the square of each integer",
|
||||
example: "echo [1 2 3] | each { echo $(= $it * $it) }",
|
||||
example: "echo [1 2 3] | each { echo ($it * $it) }",
|
||||
result: Some(vec![
|
||||
UntaggedValue::int(1).into(),
|
||||
UntaggedValue::int(4).into(),
|
||||
|
|
|
@ -63,7 +63,7 @@ impl WholeStreamCommand for Command {
|
|||
),
|
||||
},Example {
|
||||
description: "use a block if setting the empty cell contents is wanted",
|
||||
example: "echo [[2020/04/16 2020/07/10 2020/11/16]; ['' [27] [37]]] | empty? 2020/04/16 { = [33 37] }",
|
||||
example: "echo [[2020/04/16 2020/07/10 2020/11/16]; ['' [27] [37]]] | empty? 2020/04/16 { [33 37] }",
|
||||
result: Some(
|
||||
vec![
|
||||
UntaggedValue::row(indexmap! {
|
||||
|
|
|
@ -39,12 +39,12 @@ impl WholeStreamCommand for Command {
|
|||
},
|
||||
Example {
|
||||
description: "flatten a column having a nested table",
|
||||
example: "echo [[origin, people]; [Ecuador, $(echo [[name, meal]; ['Andres', 'arepa']])]] | flatten | get meal",
|
||||
example: "echo [[origin, people]; [Ecuador, (echo [[name, meal]; ['Andres', 'arepa']])]] | flatten | get meal",
|
||||
result: Some(vec![Value::from("arepa")]),
|
||||
},
|
||||
Example {
|
||||
description: "restrict the flattening by passing column names",
|
||||
example: "echo [[origin, crate, versions]; [World, $(echo [[name]; ['nu-cli']]), ['0.21', '0.22']]] | flatten versions | last | get versions",
|
||||
example: "echo [[origin, crate, versions]; [World, (echo [[name]; ['nu-cli']]), ['0.21', '0.22']]] | flatten versions | last | get versions",
|
||||
result: Some(vec![Value::from("0.22")]),
|
||||
}
|
||||
]
|
||||
|
|
|
@ -100,7 +100,7 @@ impl WholeStreamCommand for Command {
|
|||
Example {
|
||||
description:
|
||||
"use the block form to generate a grouping key when each row gets processed",
|
||||
example: "echo [1 3 1 3 2 1 1] | group-by { = ($it - 1) mod 3 }",
|
||||
example: "echo [1 3 1 3 2 1 1] | group-by { ($it - 1) mod 3 }",
|
||||
result: Some(vec![UntaggedValue::row(indexmap! {
|
||||
"0".to_string() => UntaggedValue::Table(vec![
|
||||
UntaggedValue::int(1).into(),
|
||||
|
|
|
@ -51,7 +51,7 @@ impl WholeStreamCommand for Command {
|
|||
.into()]),
|
||||
},Example {
|
||||
description: "Use in block form for more involved insertion logic",
|
||||
example: "echo [[author, lucky_number]; ['Yehuda', 4]] | insert success { = $it.lucky_number * 10 }",
|
||||
example: "echo [[author, lucky_number]; ['Yehuda', 4]] | insert success { $it.lucky_number * 10 }",
|
||||
result: Some(vec![UntaggedValue::row(indexmap! {
|
||||
"author".to_string() => Value::from("Yehuda"),
|
||||
"lucky_number".to_string() => UntaggedValue::int(4).into(),
|
||||
|
|
|
@ -67,7 +67,7 @@ On Windows, an extra 'prefix' column is added."#
|
|||
},
|
||||
Example {
|
||||
description: "Replace a complex extension",
|
||||
example: r"echo 'C:\Users\viking\spam.tar.gz' | path parse -e tar.gz | update extension { = txt }",
|
||||
example: r"echo 'C:\Users\viking\spam.tar.gz' | path parse -e tar.gz | update extension { 'txt' }",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
|
@ -93,7 +93,7 @@ On Windows, an extra 'prefix' column is added."#
|
|||
},
|
||||
Example {
|
||||
description: "Replace a complex extension",
|
||||
example: r"echo '/home/viking/spam.tar.gz' | path parse -e tar.gz | update extension { = txt }",
|
||||
example: r"echo '/home/viking/spam.tar.gz' | path parse -e tar.gz | update extension { 'txt' }",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
|
|
|
@ -57,22 +57,22 @@ impl WholeStreamCommand for Reduce {
|
|||
vec![
|
||||
Example {
|
||||
description: "Simple summation (equivalent to math sum)",
|
||||
example: "echo 1 2 3 4 | reduce { = $acc + $it }",
|
||||
example: "echo 1 2 3 4 | reduce { $acc + $it }",
|
||||
result: Some(vec![UntaggedValue::int(10).into()]),
|
||||
},
|
||||
Example {
|
||||
description: "Summation from starting value using fold",
|
||||
example: "echo 1 2 3 4 | reduce -f $(= -1) { = $acc + $it }",
|
||||
example: "echo 1 2 3 4 | reduce -f (-1) { $acc + $it }",
|
||||
result: Some(vec![UntaggedValue::int(9).into()]),
|
||||
},
|
||||
Example {
|
||||
description: "Folding with rows",
|
||||
example: "<table> | reduce -f 1.6 { = $acc * $(echo $it.a | str to-int) + $(echo $it.b | str to-int) }",
|
||||
example: "<table> | reduce -f 1.6 { $acc * (echo $it.a | str to-int) + (echo $it.b | str to-int) }",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Numbered reduce to find index of longest word",
|
||||
example: "echo one longest three bar | reduce -n { if $(echo $it.item | str length) > $(echo $acc.item | str length) {echo $it} {echo $acc}} | get index",
|
||||
example: "echo one longest three bar | reduce -n { if ($it.item | str length) > ($acc.item | str length) {echo $it} {echo $acc}} | get index",
|
||||
result: None,
|
||||
},
|
||||
]
|
||||
|
|
|
@ -69,7 +69,7 @@ impl WholeStreamCommand for Command {
|
|||
},
|
||||
Example {
|
||||
description: "Treat each row as a markdown element",
|
||||
example: "echo [[H1]; [\"Welcome to Nushell\"]] | append $(ls | first 2) | to md --per-element --pretty",
|
||||
example: "echo [[H1]; [\"Welcome to Nushell\"]] | append (ls | first 2) | to md --per-element --pretty",
|
||||
result: Some(vec![Value::from(one(r#"
|
||||
# Welcome to Nushell
|
||||
| name | type | chickens | modified |
|
||||
|
|
|
@ -10,7 +10,7 @@ fn filesystem_change_from_current_directory_using_relative_path() {
|
|||
cwd: dirs.root(),
|
||||
r#"
|
||||
cd cd_test_1
|
||||
echo $(pwd)
|
||||
echo (pwd)
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -25,7 +25,7 @@ fn filesystem_change_from_current_directory_using_absolute_path() {
|
|||
cwd: dirs.test(),
|
||||
r#"
|
||||
cd "{}"
|
||||
echo $(pwd)
|
||||
echo (pwd)
|
||||
"#,
|
||||
dirs.formats()
|
||||
);
|
||||
|
@ -44,7 +44,7 @@ fn filesystem_switch_back_to_previous_working_directory() {
|
|||
r#"
|
||||
cd {}
|
||||
cd -
|
||||
echo $(pwd)
|
||||
echo (pwd)
|
||||
"#,
|
||||
dirs.test()
|
||||
);
|
||||
|
@ -62,7 +62,7 @@ fn filesytem_change_from_current_directory_using_relative_path_and_dash() {
|
|||
cwd: dirs.test(),
|
||||
r#"
|
||||
cd odin/-
|
||||
echo $(pwd)
|
||||
echo (pwd)
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -80,7 +80,7 @@ fn filesystem_change_current_directory_to_parent_directory() {
|
|||
cwd: dirs.test(),
|
||||
r#"
|
||||
cd ..
|
||||
echo $(pwd)
|
||||
echo (pwd)
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -97,7 +97,7 @@ fn filesystem_change_current_directory_to_two_parents_up_using_multiple_dots() {
|
|||
cwd: dirs.test().join("foo/bar"),
|
||||
r#"
|
||||
cd ...
|
||||
echo $(pwd)
|
||||
echo (pwd)
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -116,7 +116,7 @@ fn filesystem_change_current_directory_to_parent_directory_after_delete_cwd() {
|
|||
rm {}/foo/bar
|
||||
echo ","
|
||||
cd ..
|
||||
echo $(pwd)
|
||||
echo (pwd)
|
||||
"#,
|
||||
dirs.test()
|
||||
);
|
||||
|
@ -135,7 +135,7 @@ fn filesystem_change_to_home_directory() {
|
|||
cwd: dirs.test(),
|
||||
r#"
|
||||
cd ~
|
||||
echo $(pwd)
|
||||
echo (pwd)
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -152,7 +152,7 @@ fn filesystem_change_to_a_directory_containing_spaces() {
|
|||
cwd: dirs.test(),
|
||||
r#"
|
||||
cd "robalino turner katz"
|
||||
echo $(pwd)
|
||||
echo (pwd)
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -219,7 +219,7 @@ fn filesystem_change_directory_to_symlink_relative() {
|
|||
cwd: dirs.test().join("boo"),
|
||||
r#"
|
||||
cd ../foo_link
|
||||
echo $(pwd)
|
||||
echo (pwd)
|
||||
"#
|
||||
);
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ fn each_group_works() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
echo [1 2 3 4 5 6] | each group 3 { echo $it } | to json
|
||||
echo [1 2 3 4 5 6] | each group 3 { $it } | to json
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -29,7 +29,7 @@ fn each_window() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
echo [1 2 3 4] | each window 3 { echo $it } | to json
|
||||
echo [1 2 3 4] | each window 3 { $it } | to json
|
||||
"#
|
||||
));
|
||||
|
||||
|
|
|
@ -6,9 +6,9 @@ fn reports_emptiness() {
|
|||
cwd: ".", pipeline(
|
||||
r#"
|
||||
echo [[are_empty];
|
||||
[$(= [[check]; [[]] ])]
|
||||
[$(= [[check]; [""] ])]
|
||||
[$(= [[check]; [$(wrap)] ])]
|
||||
[([[check]; [[]] ])]
|
||||
[([[check]; [""] ])]
|
||||
[([[check]; [(wrap)] ])]
|
||||
]
|
||||
| get are_empty
|
||||
| empty? check
|
||||
|
@ -32,7 +32,7 @@ fn sets_block_run_value_for_an_empty_column() {
|
|||
[ Jason, Gedge, 10/11/2013, 1 ]
|
||||
[ Yehuda, Katz, 10/11/2013, '' ]
|
||||
]
|
||||
| empty? likes { = 1 }
|
||||
| empty? likes { 1 }
|
||||
| get likes
|
||||
| math sum
|
||||
"#
|
||||
|
@ -50,9 +50,9 @@ fn sets_block_run_value_for_many_empty_columns() {
|
|||
[ boost check ];
|
||||
[ 1, [] ]
|
||||
[ 1, "" ]
|
||||
[ 1, $(wrap) ]
|
||||
[ 1, (wrap) ]
|
||||
]
|
||||
| empty? boost check { = 1 }
|
||||
| empty? boost check { 1 }
|
||||
| get boost check
|
||||
| math sum
|
||||
"#
|
||||
|
@ -73,9 +73,9 @@ fn passing_a_block_will_set_contents_on_empty_cells_and_leave_non_empty_ones_unt
|
|||
[ Arepas, "", "" ]
|
||||
[ Jorge, 30, 3000 ]
|
||||
]
|
||||
| empty? LVL { = 9 }
|
||||
| empty? LVL { 9 }
|
||||
| empty? HP {
|
||||
= $it.LVL * 1000
|
||||
$it.LVL * 1000
|
||||
}
|
||||
| math sum
|
||||
| get HP
|
||||
|
|
|
@ -7,8 +7,8 @@ fn flatten_nested_tables_with_columns() {
|
|||
let actual = nu!(
|
||||
cwd: ".", pipeline(
|
||||
r#"
|
||||
echo [[origin, people]; [Ecuador, $(= 'Andres' | wrap name)]]
|
||||
[[origin, people]; [Nu, $(= 'nuno' | wrap name)]]
|
||||
echo [[origin, people]; [Ecuador, ('Andres' | wrap name)]]
|
||||
[[origin, people]; [Nu, ('nuno' | wrap name)]]
|
||||
| flatten
|
||||
| get name
|
||||
| str collect ','
|
||||
|
@ -23,8 +23,8 @@ fn flatten_nested_tables_that_have_many_columns() {
|
|||
let actual = nu!(
|
||||
cwd: ".", pipeline(
|
||||
r#"
|
||||
echo [[origin, people]; [Ecuador, $(echo [[name, meal]; ['Andres', 'arepa']])]]
|
||||
[[origin, people]; [USA, $(echo [[name, meal]; ['Katz', 'nurepa']])]]
|
||||
echo [[origin, people]; [Ecuador, (echo [[name, meal]; ['Andres', 'arepa']])]]
|
||||
[[origin, people]; [USA, (echo [[name, meal]; ['Katz', 'nurepa']])]]
|
||||
| flatten
|
||||
| get meal
|
||||
| str collect ','
|
||||
|
|
|
@ -35,7 +35,7 @@ fn sets_the_column_from_an_invocation() {
|
|||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
wrap content
|
||||
| insert content $(open --raw cargo_sample.toml | lines | first 5)
|
||||
| insert content (open --raw cargo_sample.toml | lines | first 5)
|
||||
| get content.1
|
||||
| str contains "nu"
|
||||
"#
|
||||
|
|
|
@ -5,7 +5,7 @@ fn into_int_filesize() {
|
|||
let actual = nu!(
|
||||
cwd: ".", pipeline(
|
||||
r#"
|
||||
echo 1kb | into int | each {= $it / 1000 }
|
||||
echo 1kb | into int | each { $it / 1000 }
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -17,7 +17,7 @@ fn into_int_filesize2() {
|
|||
let actual = nu!(
|
||||
cwd: ".", pipeline(
|
||||
r#"
|
||||
echo 1kib | into int | each {= $it / 1024 }
|
||||
echo 1kib | into int | each { $it / 1024 }
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -29,7 +29,7 @@ fn into_int_int() {
|
|||
let actual = nu!(
|
||||
cwd: ".", pipeline(
|
||||
r#"
|
||||
echo 1024 | into int | each {= $it / 1024 }
|
||||
echo 1024 | into int | each { $it / 1024 }
|
||||
"#
|
||||
));
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ fn one_arg() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 1
|
||||
1
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -24,7 +24,7 @@ fn add() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 1 + 1
|
||||
1 + 1
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -36,7 +36,7 @@ fn add_compound() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 1 + 2 + 2
|
||||
1 + 2 + 2
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -48,7 +48,7 @@ fn precedence_of_operators() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 1 + 2 * 2
|
||||
1 + 2 * 2
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -60,7 +60,7 @@ fn precedence_of_operators2() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 1 + 2 * 2 + 1
|
||||
1 + 2 * 2 + 1
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -72,7 +72,7 @@ fn division_of_ints() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 4 / 2
|
||||
4 / 2
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -84,7 +84,7 @@ fn division_of_ints2() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 1 / 4
|
||||
1 / 4
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -96,7 +96,7 @@ fn error_zero_division_int_int() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 1 / 0
|
||||
1 / 0
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -108,7 +108,7 @@ fn error_zero_division_decimal_int() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 1.0 / 0
|
||||
1.0 / 0
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -120,7 +120,7 @@ fn error_zero_division_int_decimal() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 1 / 0.0
|
||||
1 / 0.0
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -132,7 +132,7 @@ fn error_zero_division_decimal_decimal() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 1.0 / 0.0
|
||||
1.0 / 0.0
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -144,7 +144,7 @@ fn proper_precedence_history() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 2 / 2 / 2 + 1
|
||||
2 / 2 / 2 + 1
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -156,7 +156,7 @@ fn parens_precedence() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 4 * (6 - 3)
|
||||
4 * (6 - 3)
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -168,7 +168,7 @@ fn modulo() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 9 mod 2
|
||||
9 mod 2
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -180,7 +180,7 @@ fn duration_math() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 1wk + 1day
|
||||
1wk + 1day
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -192,7 +192,7 @@ fn duration_decimal_math() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 5.5day + 0.5day
|
||||
5.5day + 0.5day
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -204,7 +204,7 @@ fn duration_math_with_nanoseconds() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 1wk + 10ns
|
||||
1wk + 10ns
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -216,7 +216,7 @@ fn duration_decimal_math_with_nanoseconds() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 1.5wk + 10ns
|
||||
1.5wk + 10ns
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -228,7 +228,7 @@ fn duration_math_with_negative() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 1day - 1wk
|
||||
1day - 1wk
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -240,7 +240,7 @@ fn compound_comparison() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 4 > 3 && 2 > 1
|
||||
4 > 3 && 2 > 1
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -252,7 +252,7 @@ fn compound_comparison2() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
= 4 < 3 || 2 > 1
|
||||
4 < 3 || 2 > 1
|
||||
"#
|
||||
));
|
||||
|
||||
|
@ -276,7 +276,7 @@ fn compound_where_paren() {
|
|||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
echo '[{"a": 1, "b": 1}, {"a": 2, "b": 1}, {"a": 2, "b": 2}]' | from json | where (a == 2 && b == 1) || b == 2 | to json
|
||||
echo '[{"a": 1, "b": 1}, {"a": 2, "b": 1}, {"a": 2, "b": 2}]' | from json | where ($it.a == 2 && $it.b == 1) || $it.b == 2 | to json
|
||||
"#
|
||||
));
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ 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
|
||||
"#
|
||||
)
|
||||
|
@ -21,7 +21,7 @@ fn reduce_table_column() {
|
|||
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
|
||||
"#
|
||||
)
|
||||
|
@ -38,7 +38,7 @@ fn reduce_rows_example() {
|
|||
echo a,b 1,2 3,4
|
||||
| split column ,
|
||||
| headers
|
||||
| reduce -f 1.6 { = $acc * $(echo $it.a | str to-int) + $(echo $it.b | str to-int) }
|
||||
| reduce -f 1.6 { $acc * ($it.a | str to-int) + ($it.b | str to-int) }
|
||||
"#
|
||||
)
|
||||
);
|
||||
|
@ -52,7 +52,7 @@ fn reduce_numbered_example() {
|
|||
cwd: ".", pipeline(
|
||||
r#"
|
||||
echo one longest three bar
|
||||
| reduce -n { if $(echo $it.item | str length) > $(echo $acc.item | str length) {echo $it} {echo $acc}}
|
||||
| reduce -n { if ($it.item | str length) > ($acc.item | str length) {echo $it} {echo $acc}}
|
||||
| get index
|
||||
"#
|
||||
)
|
||||
|
@ -67,7 +67,7 @@ fn reduce_numbered_integer_addition_example() {
|
|||
cwd: ".", pipeline(
|
||||
r#"
|
||||
echo [1 2 3 4]
|
||||
| reduce -n {= $acc.item + $it.item }
|
||||
| reduce -n { $acc.item + $it.item }
|
||||
| get item
|
||||
"#
|
||||
)
|
||||
|
@ -84,7 +84,7 @@ fn folding_with_tables() {
|
|||
echo [10 20 30 40]
|
||||
| reduce -f [] {
|
||||
with-env [value $it] {
|
||||
echo $acc | append $(= 10 * $(= $nu.env.value | str to-int))
|
||||
echo $acc | append (10 * ($nu.env.value | str to-int))
|
||||
}
|
||||
}
|
||||
| math sum
|
||||
|
@ -100,7 +100,7 @@ fn error_reduce_fold_type_mismatch() {
|
|||
let actual = nu!(
|
||||
cwd: ".", pipeline(
|
||||
r#"
|
||||
echo a b c | reduce -f 0 { = $acc + $it }
|
||||
echo a b c | reduce -f 0 { $acc + $it }
|
||||
"#
|
||||
)
|
||||
);
|
||||
|
@ -113,7 +113,7 @@ fn error_reduce_empty() {
|
|||
let actual = nu!(
|
||||
cwd: ".", pipeline(
|
||||
r#"
|
||||
reduce { = $acc + $it }
|
||||
reduce { $acc + $it }
|
||||
"#
|
||||
)
|
||||
);
|
||||
|
|
|
@ -136,7 +136,7 @@ mod columns {
|
|||
| get bit
|
||||
| reverse
|
||||
| each --numbered {
|
||||
= $it.item * (2 ** $it.index)
|
||||
$it.item * (2 ** $it.index)
|
||||
}
|
||||
| math sum
|
||||
"#,
|
||||
|
|
|
@ -50,7 +50,7 @@ fn sets_the_column_from_an_invocation() {
|
|||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
wrap content
|
||||
| update content $(open --raw cargo_sample.toml | lines | first 5)
|
||||
| update content (open --raw cargo_sample.toml | lines | first 5)
|
||||
| get content.1
|
||||
| str contains "nu"
|
||||
"#
|
||||
|
|
|
@ -86,7 +86,7 @@ fn md_combined() {
|
|||
};
|
||||
|
||||
title
|
||||
| append $(meals)
|
||||
| append (meals)
|
||||
| to md --per-element --pretty
|
||||
"#
|
||||
));
|
||||
|
|
|
@ -293,6 +293,11 @@ pub fn compute_values(
|
|||
|
||||
Ok(UntaggedValue::Primitive(Primitive::Duration(result)))
|
||||
}
|
||||
(Primitive::String(x), Primitive::String(y)) => {
|
||||
let mut new_string = x.clone();
|
||||
new_string.push_str(y);
|
||||
Ok(UntaggedValue::Primitive(Primitive::String(new_string)))
|
||||
}
|
||||
_ => Err((left.type_name(), right.type_name())),
|
||||
},
|
||||
_ => Err((left.type_name(), right.type_name())),
|
||||
|
|
|
@ -5,6 +5,7 @@ use log::{log_enabled, trace};
|
|||
use crate::evaluation_context::EvaluationContext;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::hir::SpannedExpression;
|
||||
use nu_protocol::{UntaggedValue, Value};
|
||||
use nu_stream::{InputStream, ToInputStream};
|
||||
|
||||
pub(crate) fn run_expression_block(
|
||||
|
@ -18,5 +19,11 @@ pub(crate) fn run_expression_block(
|
|||
|
||||
let output = evaluate_baseline_expr(expr, ctx)?;
|
||||
|
||||
Ok(std::iter::once(Ok(output)).to_input_stream())
|
||||
match output {
|
||||
Value {
|
||||
value: UntaggedValue::Table(x),
|
||||
..
|
||||
} => Ok(InputStream::from_stream(x.into_iter())),
|
||||
output => Ok(std::iter::once(Ok(output)).to_input_stream()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ fn test_parse_invocation_with_range() {
|
|||
cwd: ".",
|
||||
r#"
|
||||
let foo = 3
|
||||
echo $(echo 1..$foo | each { echo $it }) | to json
|
||||
echo (echo 1..$foo | each { $it }) | to json
|
||||
"#
|
||||
);
|
||||
assert_eq!(actual.out, "[1,2,3]")
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use std::{path::Path, sync::Arc};
|
||||
|
||||
use bigdecimal::BigDecimal;
|
||||
use indexmap::IndexMap;
|
||||
use log::trace;
|
||||
use nu_errors::{ArgumentError, ParseError};
|
||||
|
@ -12,11 +13,12 @@ use nu_protocol::{NamedType, PositionalType, Signature, SyntaxShape, UnspannedPa
|
|||
use nu_source::{HasSpan, Span, Spanned, SpannedItem};
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use crate::lex::lexer::{lex, parse_block};
|
||||
use crate::lex::tokens::{LiteBlock, LiteCommand, LitePipeline};
|
||||
use crate::path::expand_path;
|
||||
use crate::scope::ParserScope;
|
||||
use bigdecimal::BigDecimal;
|
||||
use crate::{
|
||||
lex::lexer::{lex, parse_block},
|
||||
ParserScope,
|
||||
};
|
||||
|
||||
use self::{
|
||||
def::{parse_definition, parse_definition_prototype},
|
||||
|
@ -94,8 +96,7 @@ pub fn parse_full_column_path(
|
|||
lite_arg: &Spanned<String>,
|
||||
scope: &dyn ParserScope,
|
||||
) -> (SpannedExpression, Option<ParseError>) {
|
||||
let mut delimiter = '.';
|
||||
let mut inside_delimiter = false;
|
||||
let mut inside_delimiter = vec![];
|
||||
let mut output = vec![];
|
||||
let mut current_part = String::new();
|
||||
let mut start_index = 0;
|
||||
|
@ -106,23 +107,21 @@ pub fn parse_full_column_path(
|
|||
|
||||
for (idx, c) in lite_arg.item.char_indices() {
|
||||
last_index = idx;
|
||||
if inside_delimiter {
|
||||
if c == delimiter {
|
||||
inside_delimiter = false;
|
||||
if c == '(' {
|
||||
inside_delimiter.push(')');
|
||||
} else if let Some(delimiter) = inside_delimiter.last() {
|
||||
if c == *delimiter {
|
||||
inside_delimiter.pop();
|
||||
}
|
||||
} else if c == '(' {
|
||||
inside_delimiter = true;
|
||||
delimiter = ')';
|
||||
} else if c == '\'' || c == '"' {
|
||||
inside_delimiter = true;
|
||||
delimiter = c;
|
||||
inside_delimiter.push(c);
|
||||
} else if c == '.' {
|
||||
let part_span = Span::new(
|
||||
lite_arg.span.start() + start_index,
|
||||
lite_arg.span.start() + idx,
|
||||
);
|
||||
|
||||
if head.is_none() && current_part.starts_with("$(") && current_part.ends_with(')') {
|
||||
if head.is_none() && current_part.starts_with('(') && current_part.ends_with(')') {
|
||||
let (invoc, err) =
|
||||
parse_invocation(¤t_part.clone().spanned(part_span), scope);
|
||||
if error.is_none() {
|
||||
|
@ -158,7 +157,7 @@ pub fn parse_full_column_path(
|
|||
);
|
||||
|
||||
if head.is_none() {
|
||||
if current_part.starts_with("$(") && current_part.ends_with(')') {
|
||||
if current_part.starts_with('(') && current_part.ends_with(')') {
|
||||
let (invoc, err) = parse_invocation(¤t_part.spanned(part_span), scope);
|
||||
if error.is_none() {
|
||||
error = err;
|
||||
|
@ -419,12 +418,12 @@ fn parse_invocation(
|
|||
let string: String = lite_arg
|
||||
.item
|
||||
.chars()
|
||||
.skip(2)
|
||||
.take(lite_arg.item.chars().count() - 3)
|
||||
.skip(1)
|
||||
.take(lite_arg.item.chars().count() - 2)
|
||||
.collect();
|
||||
|
||||
// We haven't done much with the inner string, so let's go ahead and work with it
|
||||
let (tokens, err) = lex(&string, lite_arg.span.start() + 2);
|
||||
let (tokens, err) = lex(&string, lite_arg.span.start() + 1);
|
||||
if err.is_some() {
|
||||
return (garbage(lite_arg.span), err);
|
||||
};
|
||||
|
@ -468,21 +467,7 @@ fn parse_dollar_expr(
|
|||
scope: &dyn ParserScope,
|
||||
) -> (SpannedExpression, Option<ParseError>) {
|
||||
trace!("Parsing dollar expression: {:?}", lite_arg.item);
|
||||
if lite_arg.item == "$true" {
|
||||
(
|
||||
SpannedExpression::new(Expression::boolean(true), lite_arg.span),
|
||||
None,
|
||||
)
|
||||
} else if lite_arg.item == "$false" {
|
||||
(
|
||||
SpannedExpression::new(Expression::boolean(false), lite_arg.span),
|
||||
None,
|
||||
)
|
||||
} else if lite_arg.item.ends_with(')') {
|
||||
//Return invocation
|
||||
trace!("Parsing invocation expression");
|
||||
parse_invocation(lite_arg, scope)
|
||||
} else if let (expr, None) = parse_range(lite_arg, scope) {
|
||||
if let (expr, None) = parse_range(lite_arg, scope) {
|
||||
(expr, None)
|
||||
} else if let (expr, None) = parse_full_column_path(lite_arg, scope) {
|
||||
(expr, None)
|
||||
|
@ -661,10 +646,13 @@ fn parse_external_arg(
|
|||
scope: &dyn ParserScope,
|
||||
) -> (SpannedExpression, Option<ParseError>) {
|
||||
if lite_arg.item.starts_with('$') {
|
||||
return parse_dollar_expr(&lite_arg, scope);
|
||||
}
|
||||
|
||||
if lite_arg.item.starts_with('`') && lite_arg.item.len() > 1 && lite_arg.item.ends_with('`') {
|
||||
parse_dollar_expr(&lite_arg, scope)
|
||||
} else if lite_arg.item.starts_with('(') {
|
||||
parse_invocation(&lite_arg, scope)
|
||||
} else if lite_arg.item.starts_with('`')
|
||||
&& lite_arg.item.len() > 1
|
||||
&& lite_arg.item.ends_with('`')
|
||||
{
|
||||
// This is an interpolated string
|
||||
parse_interpolated_string(&lite_arg, scope)
|
||||
} else {
|
||||
|
@ -772,65 +760,6 @@ fn parse_table(
|
|||
)
|
||||
}
|
||||
|
||||
/// Tries to parse a number in a paranthesis, e.g., (123) or (-123)
|
||||
fn try_parse_number_in_paranthesis(
|
||||
lite_arg: &Spanned<String>,
|
||||
) -> (SpannedExpression, Option<ParseError>) {
|
||||
let mut chars = lite_arg.item.chars();
|
||||
|
||||
match (chars.next(), chars.next_back()) {
|
||||
(Some('('), Some(')')) => {
|
||||
match chars.as_str().trim().parse::<BigInt>() {
|
||||
Ok(parsed_integer) => (
|
||||
SpannedExpression::new(Expression::integer(parsed_integer), lite_arg.span),
|
||||
None,
|
||||
),
|
||||
// we don't care if it does not manage to parse it, because then likely it is not a number
|
||||
Err(_) => {
|
||||
match chars.as_str().trim().parse::<BigDecimal>() {
|
||||
Ok(parsed_decimal) => (
|
||||
SpannedExpression::new(
|
||||
Expression::decimal(parsed_decimal),
|
||||
lite_arg.span,
|
||||
),
|
||||
None,
|
||||
),
|
||||
// we don't care if it does not manage to parse it, because then likely it is not a number
|
||||
Err(_) => (
|
||||
garbage(lite_arg.span),
|
||||
Some(ParseError::mismatch(
|
||||
"cannot parse number",
|
||||
lite_arg.clone(),
|
||||
)),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
(Some('('), _) => (
|
||||
garbage(lite_arg.span),
|
||||
Some(ParseError::mismatch(
|
||||
"missing closing bracket",
|
||||
lite_arg.clone(),
|
||||
)),
|
||||
),
|
||||
(_, Some(')')) => (
|
||||
garbage(lite_arg.span),
|
||||
Some(ParseError::mismatch(
|
||||
"missing starting bracket",
|
||||
lite_arg.clone(),
|
||||
)),
|
||||
),
|
||||
(_, _) => (
|
||||
garbage(lite_arg.span),
|
||||
Some(ParseError::mismatch(
|
||||
"number in paranthesis",
|
||||
lite_arg.clone(),
|
||||
)),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses the given argument using the shape as a guide for how to correctly parse the argument
|
||||
fn parse_arg(
|
||||
expected_type: SyntaxShape,
|
||||
|
@ -843,7 +772,7 @@ fn parse_arg(
|
|||
|
||||
// before anything else, try to see if this is a number in paranthesis
|
||||
if lite_arg.item.starts_with('(') {
|
||||
let (expr, err) = try_parse_number_in_paranthesis(lite_arg);
|
||||
let (expr, err) = parse_full_column_path(&lite_arg, scope);
|
||||
if err.is_none() {
|
||||
return (expr, None);
|
||||
}
|
||||
|
@ -1117,69 +1046,15 @@ fn shorthand_reparse(
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_parenthesized_expression(
|
||||
lite_arg: &Spanned<String>,
|
||||
scope: &dyn ParserScope,
|
||||
shorthand_mode: bool,
|
||||
) -> (SpannedExpression, Option<ParseError>) {
|
||||
let mut chars = lite_arg.item.chars();
|
||||
|
||||
match (chars.next(), chars.next_back()) {
|
||||
(Some('('), Some(')')) => {
|
||||
// We have a literal row
|
||||
let string: String = chars.collect();
|
||||
|
||||
// We haven't done much with the inner string, so let's go ahead and work with it
|
||||
let (tokens, err) = lex(&string, lite_arg.span.start() + 1);
|
||||
if err.is_some() {
|
||||
return (garbage(lite_arg.span), err);
|
||||
}
|
||||
|
||||
let (lite_block, err) = parse_block(tokens);
|
||||
if err.is_some() {
|
||||
return (garbage(lite_arg.span), err);
|
||||
}
|
||||
|
||||
if lite_block.block.len() != 1 {
|
||||
return (
|
||||
garbage(lite_arg.span),
|
||||
Some(ParseError::mismatch("math expression", lite_arg.clone())),
|
||||
);
|
||||
}
|
||||
|
||||
let mut lite_pipeline = lite_block.block[0].clone();
|
||||
|
||||
let mut collection = vec![];
|
||||
for lite_pipeline in lite_pipeline.pipelines.iter_mut() {
|
||||
for lite_cmd in lite_pipeline.commands.iter_mut() {
|
||||
collection.append(&mut lite_cmd.parts);
|
||||
}
|
||||
}
|
||||
let (_, expr, err) = parse_math_expression(0, &collection[..], scope, shorthand_mode);
|
||||
(expr, err)
|
||||
}
|
||||
_ => (
|
||||
garbage(lite_arg.span),
|
||||
Some(ParseError::mismatch("table", lite_arg.clone())),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_possibly_parenthesized(
|
||||
lite_arg: &Spanned<String>,
|
||||
scope: &dyn ParserScope,
|
||||
shorthand_mode: bool,
|
||||
) -> (
|
||||
(Option<Spanned<String>>, SpannedExpression),
|
||||
Option<ParseError>,
|
||||
) {
|
||||
if lite_arg.item.starts_with('(') {
|
||||
let (lhs, err) = parse_parenthesized_expression(lite_arg, scope, shorthand_mode);
|
||||
((None, lhs), err)
|
||||
} else {
|
||||
let (lhs, err) = parse_arg(SyntaxShape::Any, scope, lite_arg);
|
||||
((Some(lite_arg.clone()), lhs), err)
|
||||
}
|
||||
let (lhs, err) = parse_arg(SyntaxShape::Any, scope, lite_arg);
|
||||
((Some(lite_arg.clone()), lhs), err)
|
||||
}
|
||||
|
||||
/// Handle parsing math expressions, complete with working with the precedence of the operators
|
||||
|
@ -1200,8 +1075,7 @@ pub fn parse_math_expression(
|
|||
let mut working_exprs = vec![];
|
||||
let mut prec = vec![];
|
||||
|
||||
let (lhs_working_expr, err) =
|
||||
parse_possibly_parenthesized(&lite_args[idx], scope, shorthand_mode);
|
||||
let (lhs_working_expr, err) = parse_possibly_parenthesized(&lite_args[idx], scope);
|
||||
|
||||
if error.is_none() {
|
||||
error = err;
|
||||
|
@ -1239,8 +1113,7 @@ pub fn parse_math_expression(
|
|||
prec
|
||||
);
|
||||
|
||||
let (rhs_working_expr, err) =
|
||||
parse_possibly_parenthesized(&lite_args[idx], scope, shorthand_mode);
|
||||
let (rhs_working_expr, err) = parse_possibly_parenthesized(&lite_args[idx], scope);
|
||||
|
||||
if error.is_none() {
|
||||
error = err;
|
||||
|
@ -1740,22 +1613,32 @@ fn parse_call(
|
|||
})),
|
||||
error,
|
||||
);
|
||||
} else if lite_cmd.parts[0].item.starts_with('$') || lite_cmd.parts[0].item.starts_with('{') {
|
||||
// } else if lite_cmd.parts[0].item.starts_with('(') {
|
||||
// let (expr, err) = parse_simple_invocation(&lite_cmd.parts[0], scope);
|
||||
// error = error.or(err);
|
||||
// return (Some(ClassifiedCommand::Expr(Box::new(expr))), error);
|
||||
} else if lite_cmd.parts[0].item.starts_with('{') {
|
||||
return parse_value_call(lite_cmd, scope);
|
||||
} else if lite_cmd.parts[0].item == "=" {
|
||||
let expr = if lite_cmd.parts.len() > 1 {
|
||||
let (_, expr, err) = parse_math_expression(0, &lite_cmd.parts[1..], scope, false);
|
||||
error = error.or(err);
|
||||
expr
|
||||
} else {
|
||||
error = error.or_else(|| {
|
||||
Some(ParseError::argument_error(
|
||||
lite_cmd.parts[0].clone(),
|
||||
ArgumentError::MissingMandatoryPositional("an expression".into()),
|
||||
))
|
||||
});
|
||||
garbage(lite_cmd.span())
|
||||
};
|
||||
} else if lite_cmd.parts[0].item.starts_with('$')
|
||||
|| lite_cmd.parts[0].item.starts_with('\"')
|
||||
|| lite_cmd.parts[0].item.starts_with('\'')
|
||||
|| lite_cmd.parts[0].item.starts_with('`')
|
||||
|| lite_cmd.parts[0].item.starts_with('-')
|
||||
|| lite_cmd.parts[0].item.starts_with('0')
|
||||
|| lite_cmd.parts[0].item.starts_with('1')
|
||||
|| lite_cmd.parts[0].item.starts_with('2')
|
||||
|| lite_cmd.parts[0].item.starts_with('3')
|
||||
|| lite_cmd.parts[0].item.starts_with('4')
|
||||
|| lite_cmd.parts[0].item.starts_with('5')
|
||||
|| lite_cmd.parts[0].item.starts_with('6')
|
||||
|| lite_cmd.parts[0].item.starts_with('7')
|
||||
|| lite_cmd.parts[0].item.starts_with('8')
|
||||
|| lite_cmd.parts[0].item.starts_with('9')
|
||||
|| lite_cmd.parts[0].item.starts_with('[')
|
||||
|| lite_cmd.parts[0].item.starts_with('(')
|
||||
{
|
||||
let (_, expr, err) = parse_math_expression(0, &lite_cmd.parts[..], scope, false);
|
||||
error = error.or(err);
|
||||
return (Some(ClassifiedCommand::Expr(Box::new(expr))), error);
|
||||
} else if lite_cmd.parts[0].item == "alias" {
|
||||
let error = parse_alias(&lite_cmd, scope);
|
||||
|
@ -1925,77 +1808,6 @@ fn expand_shorthand_forms(
|
|||
}
|
||||
}
|
||||
|
||||
// pub fn parse_block(lite_block: &LiteBlock, scope: &dyn ParserScope) -> ClassifiedBlock {
|
||||
// let mut block = vec![];
|
||||
// let mut error = None;
|
||||
// for lite_group in &lite_block.block {
|
||||
// let mut command_list = vec![];
|
||||
// for lite_pipeline in &lite_group.pipelines {
|
||||
// let (lite_pipeline, vars, err) = expand_shorthand_forms(lite_pipeline);
|
||||
// if error.is_none() {
|
||||
// error = err;
|
||||
// }
|
||||
|
||||
// let (pipeline, err) = parse_pipeline(&lite_pipeline, scope);
|
||||
|
||||
// let pipeline = if let Some(vars) = vars {
|
||||
// let span = pipeline.commands.span;
|
||||
// let group = Group::new(vec![pipeline.commands.clone()], span);
|
||||
// let block = hir::Block::new(vec![], vec![group], span);
|
||||
// let mut call = hir::Call::new(
|
||||
// Box::new(SpannedExpression {
|
||||
// expr: Expression::string("with-env".to_string()),
|
||||
// span,
|
||||
// }),
|
||||
// span,
|
||||
// );
|
||||
// call.positional = Some(vec![
|
||||
// SpannedExpression {
|
||||
// expr: Expression::List(vec![
|
||||
// SpannedExpression {
|
||||
// expr: Expression::string(vars.0.item),
|
||||
// span: vars.0.span,
|
||||
// },
|
||||
// SpannedExpression {
|
||||
// expr: Expression::string(vars.1.item),
|
||||
// span: vars.1.span,
|
||||
// },
|
||||
// ]),
|
||||
// span: Span::new(vars.0.span.start(), vars.1.span.end()),
|
||||
// },
|
||||
// SpannedExpression {
|
||||
// expr: Expression::Block(block),
|
||||
// span,
|
||||
// },
|
||||
// ]);
|
||||
// let classified_with_env = ClassifiedCommand::Internal(InternalCommand {
|
||||
// name: "with-env".to_string(),
|
||||
// name_span: Span::unknown(),
|
||||
// args: call,
|
||||
// });
|
||||
// ClassifiedPipeline {
|
||||
// commands: Pipeline {
|
||||
// list: vec![classified_with_env],
|
||||
// span,
|
||||
// },
|
||||
// }
|
||||
// } else {
|
||||
// pipeline
|
||||
// };
|
||||
|
||||
// command_list.push(pipeline.commands);
|
||||
// if error.is_none() {
|
||||
// error = err;
|
||||
// }
|
||||
// }
|
||||
// let group = Group::new(command_list, lite_block.span());
|
||||
// block.push(group);
|
||||
// }
|
||||
// let block = Block::new(vec![], block, lite_block.span());
|
||||
|
||||
// ClassifiedBlock::new(block, error)
|
||||
// }
|
||||
|
||||
fn parse_alias(call: &LiteCommand, scope: &dyn ParserScope) -> Option<ParseError> {
|
||||
if call.parts.len() < 4 {
|
||||
return Some(ParseError::mismatch("alias", call.parts[0].clone()));
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
[package]
|
||||
authors = [
|
||||
"Andrei Volnin <wolandr@gmail.com>",
|
||||
"The Nu Project Contributors"
|
||||
]
|
||||
authors = ["Andrei Volnin <wolandr@gmail.com>", "The Nu Project Contributors"]
|
||||
description = "Pretty hex dump of bytes slice in the common style."
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
|
|
|
@ -48,7 +48,7 @@ Some text
|
|||
The style used by `textview` can be configured in `config.toml`.
|
||||
|
||||
```shell
|
||||
> open --raw $(which nu | get path) | autoview
|
||||
> open --raw (which nu | get path) | autoview
|
||||
...
|
||||
126d1c0: 64 31 66 37 62 30 31 63 36 2e 31 31 38 2e 6c 6c d1f7b01c6.118.ll
|
||||
126d1d0: 76 6d 2e 34 34 38 37 35 37 31 32 34 39 35 33 39 vm.4487571249539
|
||||
|
|
|
@ -56,7 +56,7 @@ We want to add two totals (numbers `33` and `37`) for the day `2020/04/16`
|
|||
|
||||
Set a table with two numbers for the empty column
|
||||
```shell
|
||||
> echo [[2020/04/16 2020/07/10 2020/11/16]; ['' [27] [37]]] | empty? 2020/04/16 { = [33 37] }
|
||||
> echo [[2020/04/16 2020/07/10 2020/11/16]; ['' [27] [37]]] | empty? 2020/04/16 { [33 37] }
|
||||
═══╦════════════════╦════════════════╦════════════════
|
||||
# ║ 2020/04/16 ║ 2020/07/10 ║ 2020/11/16
|
||||
═══╬════════════════╬════════════════╬════════════════
|
||||
|
@ -66,7 +66,7 @@ Set a table with two numbers for the empty column
|
|||
|
||||
Checking all the numbers
|
||||
```shell
|
||||
> echo [[2020/04/16 2020/07/10 2020/11/16]; ['' [27] [37]]] | empty? 2020/04/16 { = [33 37] } | pivot _ totals | get totals
|
||||
> echo [[2020/04/16 2020/07/10 2020/11/16]; ['' [27] [37]]] | empty? 2020/04/16 { [33 37] } | pivot _ totals | get totals
|
||||
═══╦════
|
||||
0 ║ 33
|
||||
1 ║ 37
|
||||
|
|
|
@ -14,7 +14,7 @@ pivot_mode = "auto" # auto, always, never
|
|||
ctrlc_exit = false
|
||||
complete_from_path = true
|
||||
rm_always_trash = true
|
||||
prompt = "build-string $(ansi gb) $(pwd) $(ansi reset) '(' $(ansi cb) $(do -i { git rev-parse --abbrev-ref HEAD } | str trim ) $(ansi reset) ')' $(ansi yb) $(date format '%m/%d/%Y %I:%M:%S%.3f %p' ) $(ansi reset) '> ' "
|
||||
prompt = "build-string (ansi gb) (pwd) (ansi reset) '(' (ansi cb) (do -i { git rev-parse --abbrev-ref HEAD } | str trim ) (ansi reset) ')' (ansi yb) (date format '%m/%d/%Y %I:%M:%S%.3f %p' ) (ansi reset) '> ' "
|
||||
|
||||
# for each of the options in the color_config section, you are able to set
|
||||
# the color alone or with one of the following attributes.
|
||||
|
|
|
@ -47,7 +47,7 @@ fn plugins_are_declared_with_wix() {
|
|||
| wrap wix
|
||||
}
|
||||
| default wix _
|
||||
| each { if $it.wix != $it.cargo { = 1 } { = 0 } }
|
||||
| each { if $it.wix != $it.cargo { 1 } { 0 } }
|
||||
| math sum
|
||||
"#
|
||||
));
|
||||
|
|
|
@ -34,7 +34,7 @@ fn automatically_change_directory() {
|
|||
cwd: dirs.test(),
|
||||
r#"
|
||||
autodir
|
||||
echo $(pwd)
|
||||
echo (pwd)
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -300,7 +300,7 @@ mod external_command_arguments {
|
|||
let actual = nu!(
|
||||
cwd: dirs.test(), pipeline(
|
||||
r#"
|
||||
nu --testbin cococo $(ls | get name)
|
||||
nu --testbin cococo (ls | get name)
|
||||
"#
|
||||
));
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ fn treats_dot_dot_as_path_not_range() {
|
|||
r#"
|
||||
mkdir temp;
|
||||
cd temp;
|
||||
echo $(open ../nu_times.csv).name | autoview;
|
||||
echo (open ../nu_times.csv).name | autoview;
|
||||
cd ..;
|
||||
rmdir temp
|
||||
"#
|
||||
|
@ -66,7 +66,7 @@ fn invocation_properly_redirects() {
|
|||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
echo $(nu --testbin cococo "hello") | str collect
|
||||
echo (nu --testbin cococo "hello") | str collect
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -78,7 +78,7 @@ fn argument_invocation() {
|
|||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
echo "foo" | each { echo $(echo $it) }
|
||||
echo "foo" | each { echo (echo $it) }
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -102,7 +102,7 @@ fn invocation_handles_dot() {
|
|||
let actual = nu!(
|
||||
cwd: dirs.test(), pipeline(
|
||||
r#"
|
||||
echo $(open nu_times.csv)
|
||||
echo (open nu_times.csv)
|
||||
| get name
|
||||
| each { nu --testbin chop $it | lines }
|
||||
| nth 3
|
||||
|
@ -202,7 +202,7 @@ fn run_custom_command() {
|
|||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
def add-me [x y] { = $x + $y}; add-me 10 5
|
||||
def add-me [x y] { $x + $y}; add-me 10 5
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -214,7 +214,7 @@ fn run_custom_command_with_flag() {
|
|||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
def foo [--bar:number] { if $(echo $bar | empty?) { echo "empty" } { echo $bar } }; foo --bar 10
|
||||
def foo [--bar:number] { if ($bar | empty?) { echo "empty" } { echo $bar } }; foo --bar 10
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -226,7 +226,7 @@ fn run_custom_command_with_flag_missing() {
|
|||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
def foo [--bar:number] { if $(echo $bar | empty?) { echo "empty" } { echo $bar } }; foo
|
||||
def foo [--bar:number] { if ($bar | empty?) { echo "empty" } { echo $bar } }; foo
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -325,7 +325,7 @@ fn set_variable() {
|
|||
r#"
|
||||
let x = 5
|
||||
let y = 12
|
||||
= $x + $y
|
||||
$x + $y
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -396,7 +396,7 @@ fn run_dynamic_blocks() {
|
|||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
let block = { echo "holaaaa" }; $block
|
||||
let block = { echo "holaaaa" }; do $block
|
||||
"#
|
||||
);
|
||||
assert_eq!(actual.out, "holaaaa");
|
||||
|
@ -407,7 +407,7 @@ fn run_dynamic_blocks() {
|
|||
fn argument_invocation_reports_errors() {
|
||||
let actual = nu!(
|
||||
cwd: ".",
|
||||
"echo $(ferris_is_not_here.exe)"
|
||||
"echo (ferris_is_not_here.exe)"
|
||||
);
|
||||
|
||||
assert!(actual.err.contains("Command not found"));
|
||||
|
@ -644,7 +644,7 @@ fn filesize_math() {
|
|||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
= 100 * 10kb
|
||||
100 * 10kb
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -658,7 +658,7 @@ fn filesize_math2() {
|
|||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
= 100 / 10kb
|
||||
100 / 10kb
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -670,7 +670,7 @@ fn filesize_math3() {
|
|||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
= 100kb / 10
|
||||
100kb / 10
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -681,7 +681,7 @@ fn filesize_math4() {
|
|||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
= 100kb * 5
|
||||
100kb * 5
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -693,7 +693,7 @@ fn filesize_math5() {
|
|||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
= 1001 * 1kb
|
||||
1001 * 1kb
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -705,7 +705,7 @@ fn filesize_math6() {
|
|||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
= 1001 * 1mb
|
||||
1001 * 1mb
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -717,7 +717,7 @@ fn filesize_math7() {
|
|||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
= 1001 * 1gb
|
||||
1001 * 1gb
|
||||
"#
|
||||
);
|
||||
|
||||
|
@ -753,7 +753,7 @@ fn duration_overflow() {
|
|||
let actual = nu!(
|
||||
cwd: ".", pipeline(
|
||||
r#"
|
||||
ls | get modified | each { = $it + 10000000000000000day }
|
||||
ls | get modified | each { $it + 10000000000000000day }
|
||||
"#)
|
||||
);
|
||||
|
||||
|
@ -765,7 +765,7 @@ fn date_and_duration_overflow() {
|
|||
let actual = nu!(
|
||||
cwd: ".", pipeline(
|
||||
r#"
|
||||
ls | get modified | each { = $it + 1000000000day }
|
||||
ls | get modified | each { $it + 1000000000day }
|
||||
"#)
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in a new issue