forked from extern/nushell
Compare commits
28 Commits
Author | SHA1 | Date | |
---|---|---|---|
b93b80ccaa | |||
48128c9db6 | |||
6dafaa197d | |||
1634d8e087 | |||
7a583083b8 | |||
75156ab0c9 | |||
9fd6923821 | |||
91a929b2a9 | |||
0f8e31af06 | |||
bd71c2f34d | |||
001123dbd6 | |||
cfee151d4e | |||
fc59291191 | |||
4fc05cac56 | |||
cc4616f25b | |||
e82fbb7bcf | |||
8cd639f6a2 | |||
a8f555856a | |||
3792562046 | |||
d05c48a1d7 | |||
36cc5eb933 | |||
f9f74a0f7d | |||
77f42931ff | |||
73f62266c6 | |||
df2f3d25b0 | |||
599c43ce04 | |||
5c2199e7f4 | |||
3ad4e0348f |
206
Cargo.lock
generated
206
Cargo.lock
generated
@ -184,13 +184,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
|
||||
[[package]]
|
||||
name = "async-attributes"
|
||||
version = "1.1.2"
|
||||
name = "as-slice"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5"
|
||||
checksum = "45403b49e3954a4b8428a0ac21a4b7afadccf92bfd96273f1a58cd4812496ae0"
|
||||
dependencies = [
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.63",
|
||||
"generic-array 0.12.4",
|
||||
"generic-array 0.13.3",
|
||||
"generic-array 0.14.4",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -290,7 +292,6 @@ version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9f06685bad74e0570f5213741bea82158279a4103d988e57bfada11ad230341"
|
||||
dependencies = [
|
||||
"async-attributes",
|
||||
"async-channel",
|
||||
"async-global-executor",
|
||||
"async-io",
|
||||
@ -1978,6 +1979,24 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f797e67af32588215eaaab8327027ee8e71b9dd0b2b26996aedf20c030fce309"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.4"
|
||||
@ -2119,6 +2138,15 @@ dependencies = [
|
||||
"regex 1.4.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hash32"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4041af86e63ac4298ce40e5cca669066e75b6f1aa3390fe2561ffa5e1d9f4cc"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.9.1"
|
||||
@ -2137,6 +2165,18 @@ dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heapless"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "634bd4d29cbf24424d0a4bfcbf80c6960129dc24424752a7d1d1390607023422"
|
||||
dependencies = [
|
||||
"as-slice",
|
||||
"generic-array 0.14.4",
|
||||
"hash32",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.2"
|
||||
@ -2394,18 +2434,6 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ichwh"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea685d38f1becb4f0a04e6cbff9256c6c2cd5e5905563b251401d1c13d12c654"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"cfg-if 0.1.10",
|
||||
"futures 0.3.13",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.2"
|
||||
@ -3087,7 +3115,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"ctrlc",
|
||||
@ -3132,7 +3160,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.30.0"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6bd69a141e8fdfa5ac882d8b816db2b9ad138ef7e3baa7cb753a9b3789aa8c7e"
|
||||
dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"doc-comment",
|
||||
"regex 1.4.3",
|
||||
@ -3143,7 +3180,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-cli"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"arboard",
|
||||
@ -3176,13 +3213,12 @@ dependencies = [
|
||||
"glob",
|
||||
"htmlescape",
|
||||
"ical",
|
||||
"ichwh",
|
||||
"indexmap",
|
||||
"itertools",
|
||||
"lazy_static 1.4.0",
|
||||
"log 0.4.14",
|
||||
"meval",
|
||||
"nu-ansi-term",
|
||||
"nu-ansi-term 0.31.0",
|
||||
"nu-command",
|
||||
"nu-data",
|
||||
"nu-engine",
|
||||
@ -3190,6 +3226,7 @@ dependencies = [
|
||||
"nu-json",
|
||||
"nu-parser",
|
||||
"nu-plugin",
|
||||
"nu-pretty-hex",
|
||||
"nu-protocol",
|
||||
"nu-source",
|
||||
"nu-stream",
|
||||
@ -3201,7 +3238,6 @@ dependencies = [
|
||||
"num-traits 0.2.14",
|
||||
"parking_lot 0.11.1",
|
||||
"pin-utils",
|
||||
"pretty-hex",
|
||||
"ptree",
|
||||
"query_interface",
|
||||
"quick-xml 0.21.0",
|
||||
@ -3244,7 +3280,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-command"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"arboard",
|
||||
@ -3275,7 +3311,6 @@ dependencies = [
|
||||
"hamcrest2",
|
||||
"htmlescape",
|
||||
"ical",
|
||||
"ichwh",
|
||||
"indexmap",
|
||||
"itertools",
|
||||
"lazy_static 1.4.0",
|
||||
@ -3283,13 +3318,14 @@ dependencies = [
|
||||
"md5 0.7.0",
|
||||
"meval",
|
||||
"minus",
|
||||
"nu-ansi-term",
|
||||
"nu-ansi-term 0.31.0",
|
||||
"nu-data",
|
||||
"nu-engine",
|
||||
"nu-errors",
|
||||
"nu-json",
|
||||
"nu-parser",
|
||||
"nu-plugin",
|
||||
"nu-pretty-hex",
|
||||
"nu-protocol",
|
||||
"nu-source",
|
||||
"nu-stream",
|
||||
@ -3301,7 +3337,6 @@ dependencies = [
|
||||
"num-traits 0.2.14",
|
||||
"parking_lot 0.11.1",
|
||||
"pin-utils",
|
||||
"pretty-hex",
|
||||
"ptree",
|
||||
"query_interface",
|
||||
"quick-xml 0.21.0",
|
||||
@ -3344,7 +3379,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-data"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"bigdecimal",
|
||||
"byte-unit",
|
||||
@ -3356,7 +3391,7 @@ dependencies = [
|
||||
"getset",
|
||||
"indexmap",
|
||||
"log 0.4.14",
|
||||
"nu-ansi-term",
|
||||
"nu-ansi-term 0.31.0",
|
||||
"nu-errors",
|
||||
"nu-protocol",
|
||||
"nu-source",
|
||||
@ -3375,7 +3410,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-engine"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"ansi_term 0.12.1",
|
||||
"async-recursion",
|
||||
@ -3400,7 +3435,7 @@ dependencies = [
|
||||
"indexmap",
|
||||
"itertools",
|
||||
"log 0.4.14",
|
||||
"nu-ansi-term",
|
||||
"nu-ansi-term 0.31.0",
|
||||
"nu-data",
|
||||
"nu-errors",
|
||||
"nu-parser",
|
||||
@ -3428,14 +3463,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-errors"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"bigdecimal",
|
||||
"codespan-reporting",
|
||||
"derive-new",
|
||||
"getset",
|
||||
"glob",
|
||||
"nu-ansi-term",
|
||||
"nu-ansi-term 0.31.0",
|
||||
"nu-source",
|
||||
"num-bigint 0.3.2",
|
||||
"num-traits 0.2.14",
|
||||
@ -3447,7 +3482,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-json"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"dunce",
|
||||
"lazy_static 1.4.0",
|
||||
@ -3461,7 +3496,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-parser"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"bigdecimal",
|
||||
"codespan-reporting",
|
||||
@ -3484,7 +3519,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-plugin"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"bigdecimal",
|
||||
"indexmap",
|
||||
@ -3498,9 +3533,18 @@ dependencies = [
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-pretty-hex"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"heapless",
|
||||
"nu-ansi-term 0.29.0",
|
||||
"rand 0.8.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-protocol"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"bigdecimal",
|
||||
"byte-unit",
|
||||
@ -3523,7 +3567,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-source"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"derive-new",
|
||||
"getset",
|
||||
@ -3534,7 +3578,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-stream"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"futures 0.3.13",
|
||||
"nu-errors",
|
||||
@ -3544,16 +3588,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-table"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"nu-ansi-term",
|
||||
"nu-ansi-term 0.31.0",
|
||||
"regex 1.4.3",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-test-support"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"bigdecimal",
|
||||
"chrono",
|
||||
@ -3572,7 +3616,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-value-ext"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itertools",
|
||||
@ -3584,23 +3628,23 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_binaryview"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"crossterm 0.19.0",
|
||||
"image 0.22.5",
|
||||
"neso",
|
||||
"nu-ansi-term",
|
||||
"nu-ansi-term 0.31.0",
|
||||
"nu-errors",
|
||||
"nu-plugin",
|
||||
"nu-pretty-hex",
|
||||
"nu-protocol",
|
||||
"nu-source",
|
||||
"pretty-hex",
|
||||
"rawkey",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_chart"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"crossterm 0.19.0",
|
||||
"nu-cli",
|
||||
@ -3615,7 +3659,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_fetch"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"base64 0.13.0",
|
||||
"futures 0.3.13",
|
||||
@ -3630,7 +3674,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_from_bson"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"bigdecimal",
|
||||
"bson",
|
||||
@ -3644,7 +3688,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_from_sqlite"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"bigdecimal",
|
||||
"nu-errors",
|
||||
@ -3659,7 +3703,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_inc"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"nu-errors",
|
||||
"nu-plugin",
|
||||
@ -3672,7 +3716,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_match"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"nu-errors",
|
||||
"nu-plugin",
|
||||
@ -3683,7 +3727,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_post"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"base64 0.13.0",
|
||||
"futures 0.3.13",
|
||||
@ -3699,7 +3743,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_ps"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"futures 0.3.13",
|
||||
"futures-timer",
|
||||
@ -3713,7 +3757,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_query_json"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"gjson",
|
||||
"nu-errors",
|
||||
@ -3725,7 +3769,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_s3"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"futures 0.3.13",
|
||||
"nu-errors",
|
||||
@ -3737,7 +3781,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_selector"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"nipper",
|
||||
"nu-errors",
|
||||
@ -3749,7 +3793,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_start"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"nu-errors",
|
||||
@ -3758,11 +3802,12 @@ dependencies = [
|
||||
"nu-source",
|
||||
"open",
|
||||
"url",
|
||||
"webbrowser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_sys"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"futures 0.3.13",
|
||||
"futures-util",
|
||||
@ -3776,10 +3821,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_textview"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"bat",
|
||||
"nu-ansi-term",
|
||||
"nu-ansi-term 0.31.0",
|
||||
"nu-data",
|
||||
"nu-errors",
|
||||
"nu-plugin",
|
||||
@ -3791,7 +3836,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_to_bson"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"bson",
|
||||
"nu-errors",
|
||||
@ -3804,7 +3849,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_to_sqlite"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"hex 0.4.3",
|
||||
"nu-errors",
|
||||
@ -3819,7 +3864,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_tree"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"derive-new",
|
||||
"nu-errors",
|
||||
@ -3831,7 +3876,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_xpath"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
dependencies = [
|
||||
"bigdecimal",
|
||||
"indexmap",
|
||||
@ -4408,12 +4453,6 @@ dependencies = [
|
||||
"typed-arena",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pretty-hex"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc5c99d529f0d30937f6f4b8a86d988047327bb88d04d2c4afc356de74722131"
|
||||
|
||||
[[package]]
|
||||
name = "pretty_env_logger"
|
||||
version = "0.4.0"
|
||||
@ -6787,6 +6826,17 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webbrowser"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecad156490d6b620308ed411cfee90d280b3cbd13e189ea0d3fada8acc89158a"
|
||||
dependencies = [
|
||||
"web-sys",
|
||||
"widestring",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "weezl"
|
||||
version = "0.1.4"
|
||||
@ -6804,14 +6854,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.0.2"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87c14ef7e1b8b8ecfc75d5eca37949410046e66f15d185c01d70824f1f8111ef"
|
||||
checksum = "b55551e42cbdf2ce2bedd2203d0cc08dba002c27510f86dab6d0ce304cba3dfe"
|
||||
dependencies = [
|
||||
"either",
|
||||
"libc",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "widestring"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c"
|
||||
|
||||
[[package]]
|
||||
name = "wild"
|
||||
version = "2.0.4"
|
||||
|
64
Cargo.toml
64
Cargo.toml
@ -10,7 +10,7 @@ license = "MIT"
|
||||
name = "nu"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/nushell/nushell"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
|
||||
[workspace]
|
||||
members = ["crates/*/"]
|
||||
@ -18,36 +18,36 @@ members = ["crates/*/"]
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
nu-cli = { version = "0.30.0", path = "./crates/nu-cli", default-features = false }
|
||||
nu-command = { version = "0.30.0", path = "./crates/nu-command" }
|
||||
nu-data = { version = "0.30.0", path = "./crates/nu-data" }
|
||||
nu-engine = { version = "0.30.0", path = "./crates/nu-engine" }
|
||||
nu-errors = { version = "0.30.0", path = "./crates/nu-errors" }
|
||||
nu-parser = { version = "0.30.0", path = "./crates/nu-parser" }
|
||||
nu-plugin = { version = "0.30.0", path = "./crates/nu-plugin" }
|
||||
nu-protocol = { version = "0.30.0", path = "./crates/nu-protocol" }
|
||||
nu-source = { version = "0.30.0", path = "./crates/nu-source" }
|
||||
nu-value-ext = { version = "0.30.0", path = "./crates/nu-value-ext" }
|
||||
nu-cli = { version = "0.31.0", path = "./crates/nu-cli", default-features = false }
|
||||
nu-command = { version = "0.31.0", path = "./crates/nu-command" }
|
||||
nu-data = { version = "0.31.0", path = "./crates/nu-data" }
|
||||
nu-engine = { version = "0.31.0", path = "./crates/nu-engine" }
|
||||
nu-errors = { version = "0.31.0", path = "./crates/nu-errors" }
|
||||
nu-parser = { version = "0.31.0", path = "./crates/nu-parser" }
|
||||
nu-plugin = { version = "0.31.0", path = "./crates/nu-plugin" }
|
||||
nu-protocol = { version = "0.31.0", path = "./crates/nu-protocol" }
|
||||
nu-source = { version = "0.31.0", path = "./crates/nu-source" }
|
||||
nu-value-ext = { version = "0.31.0", path = "./crates/nu-value-ext" }
|
||||
|
||||
nu_plugin_binaryview = { version = "0.30.0", path = "./crates/nu_plugin_binaryview", optional = true }
|
||||
nu_plugin_chart = { version = "0.30.0", path = "./crates/nu_plugin_chart", optional = true }
|
||||
nu_plugin_fetch = { version = "0.30.0", path = "./crates/nu_plugin_fetch", optional = true }
|
||||
nu_plugin_from_bson = { version = "0.30.0", path = "./crates/nu_plugin_from_bson", optional = true }
|
||||
nu_plugin_from_sqlite = { version = "0.30.0", path = "./crates/nu_plugin_from_sqlite", optional = true }
|
||||
nu_plugin_inc = { version = "0.30.0", path = "./crates/nu_plugin_inc", optional = true }
|
||||
nu_plugin_match = { version = "0.30.0", path = "./crates/nu_plugin_match", optional = true }
|
||||
nu_plugin_post = { version = "0.30.0", path = "./crates/nu_plugin_post", optional = true }
|
||||
nu_plugin_ps = { version = "0.30.0", path = "./crates/nu_plugin_ps", optional = true }
|
||||
nu_plugin_query_json = { version = "0.30.0", path = "./crates/nu_plugin_query_json", optional = true }
|
||||
nu_plugin_s3 = { version = "0.30.0", path = "./crates/nu_plugin_s3", optional = true }
|
||||
nu_plugin_selector = { version = "0.30.0", path = "./crates/nu_plugin_selector", optional = true }
|
||||
nu_plugin_start = { version = "0.30.0", path = "./crates/nu_plugin_start", optional = true }
|
||||
nu_plugin_sys = { version = "0.30.0", path = "./crates/nu_plugin_sys", optional = true }
|
||||
nu_plugin_textview = { version = "0.30.0", path = "./crates/nu_plugin_textview", optional = true }
|
||||
nu_plugin_to_bson = { version = "0.30.0", path = "./crates/nu_plugin_to_bson", optional = true }
|
||||
nu_plugin_to_sqlite = { version = "0.30.0", path = "./crates/nu_plugin_to_sqlite", optional = true }
|
||||
nu_plugin_tree = { version = "0.30.0", path = "./crates/nu_plugin_tree", optional = true }
|
||||
nu_plugin_xpath = { version = "0.30.0", path = "./crates/nu_plugin_xpath", optional = true }
|
||||
nu_plugin_binaryview = { version = "0.31.0", path = "./crates/nu_plugin_binaryview", optional = true }
|
||||
nu_plugin_chart = { version = "0.31.0", path = "./crates/nu_plugin_chart", optional = true }
|
||||
nu_plugin_fetch = { version = "0.31.0", path = "./crates/nu_plugin_fetch", optional = true }
|
||||
nu_plugin_from_bson = { version = "0.31.0", path = "./crates/nu_plugin_from_bson", optional = true }
|
||||
nu_plugin_from_sqlite = { version = "0.31.0", path = "./crates/nu_plugin_from_sqlite", optional = true }
|
||||
nu_plugin_inc = { version = "0.31.0", path = "./crates/nu_plugin_inc", optional = true }
|
||||
nu_plugin_match = { version = "0.31.0", path = "./crates/nu_plugin_match", optional = true }
|
||||
nu_plugin_post = { version = "0.31.0", path = "./crates/nu_plugin_post", optional = true }
|
||||
nu_plugin_ps = { version = "0.31.0", path = "./crates/nu_plugin_ps", optional = true }
|
||||
nu_plugin_query_json = { version = "0.31.0", path = "./crates/nu_plugin_query_json", optional = true }
|
||||
nu_plugin_s3 = { version = "0.31.0", path = "./crates/nu_plugin_s3", optional = true }
|
||||
nu_plugin_selector = { version = "0.31.0", path = "./crates/nu_plugin_selector", optional = true }
|
||||
nu_plugin_start = { version = "0.31.0", path = "./crates/nu_plugin_start", optional = true }
|
||||
nu_plugin_sys = { version = "0.31.0", path = "./crates/nu_plugin_sys", optional = true }
|
||||
nu_plugin_textview = { version = "0.31.0", path = "./crates/nu_plugin_textview", optional = true }
|
||||
nu_plugin_to_bson = { version = "0.31.0", path = "./crates/nu_plugin_to_bson", optional = true }
|
||||
nu_plugin_to_sqlite = { version = "0.31.0", path = "./crates/nu_plugin_to_sqlite", optional = true }
|
||||
nu_plugin_tree = { version = "0.31.0", path = "./crates/nu_plugin_tree", optional = true }
|
||||
nu_plugin_xpath = { version = "0.31.0", path = "./crates/nu_plugin_xpath", optional = true }
|
||||
|
||||
# Required to bootstrap the main binary
|
||||
clap = "2.33.3"
|
||||
@ -58,7 +58,7 @@ log = "0.4.14"
|
||||
pretty_env_logger = "0.4.0"
|
||||
|
||||
[dev-dependencies]
|
||||
nu-test-support = { version = "0.30.0", path = "./crates/nu-test-support" }
|
||||
nu-test-support = { version = "0.31.0", path = "./crates/nu-test-support" }
|
||||
dunce = "1.0.1"
|
||||
serial_test = "0.5.1"
|
||||
hamcrest2 = "0.3.0"
|
||||
@ -82,9 +82,7 @@ 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/ichwh",
|
||||
"nu-cli/which",
|
||||
"nu-command/ichwh",
|
||||
"nu-command/which",
|
||||
"nu-engine/which",
|
||||
]
|
||||
|
@ -9,7 +9,7 @@ description = "Library for ANSI terminal colors and styles (bold, underline)"
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
name = "nu-ansi-term"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
@ -5,26 +5,27 @@ description = "CLI for nushell"
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
name = "nu-cli"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
nu-command = { version = "0.30.0", path = "../nu-command" }
|
||||
nu-data = { version = "0.30.0", path = "../nu-data" }
|
||||
nu-engine = { version = "0.30.0", path = "../nu-engine" }
|
||||
nu-errors = { version = "0.30.0", path = "../nu-errors" }
|
||||
nu-json = { version = "0.30.0", path = "../nu-json" }
|
||||
nu-parser = { version = "0.30.0", path = "../nu-parser" }
|
||||
nu-plugin = { version = "0.30.0", path = "../nu-plugin" }
|
||||
nu-protocol = { version = "0.30.0", path = "../nu-protocol" }
|
||||
nu-source = { version = "0.30.0", path = "../nu-source" }
|
||||
nu-stream = { version = "0.30.0", path = "../nu-stream" }
|
||||
nu-table = { version = "0.30.0", path = "../nu-table" }
|
||||
nu-test-support = { version = "0.30.0", path = "../nu-test-support" }
|
||||
nu-value-ext = { version = "0.30.0", path = "../nu-value-ext" }
|
||||
nu-ansi-term = { version = "0.30.0", path = "../nu-ansi-term" }
|
||||
nu-command = { version = "0.31.0", path = "../nu-command" }
|
||||
nu-data = { version = "0.31.0", path = "../nu-data" }
|
||||
nu-engine = { version = "0.31.0", path = "../nu-engine" }
|
||||
nu-errors = { version = "0.31.0", path = "../nu-errors" }
|
||||
nu-json = { version = "0.31.0", path = "../nu-json" }
|
||||
nu-parser = { version = "0.31.0", path = "../nu-parser" }
|
||||
nu-plugin = { version = "0.31.0", path = "../nu-plugin" }
|
||||
nu-protocol = { version = "0.31.0", path = "../nu-protocol" }
|
||||
nu-source = { version = "0.31.0", path = "../nu-source" }
|
||||
nu-stream = { version = "0.31.0", path = "../nu-stream" }
|
||||
nu-table = { version = "0.31.0", path = "../nu-table" }
|
||||
nu-test-support = { version = "0.31.0", path = "../nu-test-support" }
|
||||
nu-value-ext = { version = "0.31.0", path = "../nu-value-ext" }
|
||||
nu-ansi-term = { version = "0.31.0", path = "../nu-ansi-term" }
|
||||
nu-pretty-hex = { version = "0.31.0", path = "../nu-pretty-hex" }
|
||||
|
||||
Inflector = "0.11"
|
||||
arboard = { version = "1.1.0", optional = true }
|
||||
@ -57,7 +58,6 @@ getset = "0.1.1"
|
||||
glob = "0.3.0"
|
||||
htmlescape = "0.3.1"
|
||||
ical = "0.7.0"
|
||||
ichwh = { version = "0.3.4", optional = true }
|
||||
indexmap = { version = "1.6.1", features = ["serde-1"] }
|
||||
itertools = "0.10.0"
|
||||
lazy_static = "1.*"
|
||||
@ -68,7 +68,6 @@ num-format = { version = "0.4.0", features = ["with-num-bigint"] }
|
||||
num-traits = "0.2.14"
|
||||
parking_lot = "0.11.1"
|
||||
pin-utils = "0.1.0"
|
||||
pretty-hex = "0.2.1"
|
||||
ptree = { version = "0.3.1", optional = true }
|
||||
query_interface = "0.3.5"
|
||||
quick-xml = "0.21.0"
|
||||
|
@ -229,13 +229,7 @@ pub fn cli(context: EvaluationContext, options: Options) -> Result<(), Box<dyn E
|
||||
let prompt_line = prompt.as_string()?;
|
||||
|
||||
context.scope.enter_scope();
|
||||
let (mut prompt_block, err) = nu_parser::parse(&prompt_line, 0, &context.scope);
|
||||
|
||||
if let Some(block) =
|
||||
std::sync::Arc::<nu_protocol::hir::Block>::get_mut(&mut prompt_block)
|
||||
{
|
||||
block.set_redirect(ExternalRedirection::Stdout);
|
||||
}
|
||||
let (prompt_block, err) = nu_parser::parse(&prompt_line, 0, &context.scope);
|
||||
|
||||
if err.is_some() {
|
||||
context.scope.exit_scope();
|
||||
@ -250,7 +244,12 @@ pub fn cli(context: EvaluationContext, options: Options) -> Result<(), Box<dyn E
|
||||
nu_ansi_term::ansi::RESET
|
||||
)
|
||||
} else {
|
||||
let run_result = run_block(&prompt_block, &context, InputStream::empty());
|
||||
let run_result = run_block(
|
||||
&prompt_block,
|
||||
&context,
|
||||
InputStream::empty(),
|
||||
ExternalRedirection::Stdout,
|
||||
);
|
||||
context.scope.exit_scope();
|
||||
|
||||
match run_result {
|
||||
@ -302,7 +301,9 @@ pub fn cli(context: EvaluationContext, options: Options) -> Result<(), Box<dyn E
|
||||
}
|
||||
};
|
||||
|
||||
rl.helper_mut().expect("No helper").colored_prompt = colored_prompt;
|
||||
if let Some(helper) = rl.helper_mut() {
|
||||
helper.colored_prompt = colored_prompt;
|
||||
}
|
||||
let mut initial_command = Some(String::new());
|
||||
let mut readline = Err(ReadlineError::Eof);
|
||||
while let Some(ref cmd) = initial_command {
|
||||
@ -485,7 +486,12 @@ pub fn parse_and_eval(line: &str, ctx: &EvaluationContext) -> Result<String, She
|
||||
|
||||
let input_stream = InputStream::empty();
|
||||
|
||||
let result = run_block(&classified_block, ctx, input_stream);
|
||||
let result = run_block(
|
||||
&classified_block,
|
||||
ctx,
|
||||
input_stream,
|
||||
ExternalRedirection::Stdout,
|
||||
);
|
||||
ctx.scope.exit_scope();
|
||||
|
||||
result?.collect_string(Tag::unknown()).map(|x| x.item)
|
||||
@ -509,14 +515,14 @@ fn current_branch() -> String {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use nu_engine::basic_evaluation_context;
|
||||
use nu_engine::EvaluationContext;
|
||||
|
||||
#[quickcheck]
|
||||
fn quickcheck_parse(data: String) -> bool {
|
||||
let (tokens, err) = nu_parser::lex(&data, 0);
|
||||
let (lite_block, err2) = nu_parser::parse_block(tokens);
|
||||
if err.is_none() && err2.is_none() {
|
||||
let context = basic_evaluation_context().unwrap();
|
||||
let context = EvaluationContext::basic();
|
||||
let _ = nu_parser::classify_block(&lite_block, &context.scope);
|
||||
}
|
||||
true
|
||||
|
@ -150,7 +150,7 @@ impl rustyline::Helper for Helper {}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use nu_engine::basic_evaluation_context;
|
||||
use nu_engine::EvaluationContext;
|
||||
use rustyline::completion::Completer;
|
||||
use rustyline::line_buffer::LineBuffer;
|
||||
|
||||
@ -164,7 +164,7 @@ mod tests {
|
||||
buffer.insert_str(0, text);
|
||||
buffer.set_pos(text.len() - 1);
|
||||
|
||||
let helper = Helper::new(basic_evaluation_context().unwrap(), None);
|
||||
let helper = Helper::new(EvaluationContext::basic(), None);
|
||||
|
||||
helper.update(&mut buffer, "cd ".len(), &replacement);
|
||||
|
||||
@ -184,7 +184,7 @@ mod tests {
|
||||
buffer.insert_str(0, text);
|
||||
buffer.set_pos(text.len() - 30);
|
||||
|
||||
let helper = Helper::new(basic_evaluation_context().unwrap(), None);
|
||||
let helper = Helper::new(EvaluationContext::basic(), None);
|
||||
|
||||
helper.update(&mut buffer, "cd ".len(), &replacement);
|
||||
|
||||
|
@ -377,10 +377,7 @@ impl VarSyntaxShapeDeductor {
|
||||
.iter()
|
||||
.map(|decl| {
|
||||
let usage: VarUsage = decl.into();
|
||||
let deduction = match deducer.inferences.get(&usage) {
|
||||
Some(vec) => Some(vec.clone()),
|
||||
None => None,
|
||||
};
|
||||
let deduction = deducer.inferences.get(&usage).cloned();
|
||||
(decl.clone(), deduction)
|
||||
})
|
||||
.collect())
|
||||
@ -1023,7 +1020,7 @@ impl VarSyntaxShapeDeductor {
|
||||
Some(combination)
|
||||
}
|
||||
})
|
||||
.filter_map(|elem| elem)
|
||||
.flatten()
|
||||
.collect()
|
||||
}
|
||||
//No any's intersection of both is result
|
||||
@ -1044,7 +1041,7 @@ impl VarSyntaxShapeDeductor {
|
||||
Some(combination)
|
||||
}
|
||||
})
|
||||
.filter_map(|elem| elem)
|
||||
.flatten()
|
||||
.collect();
|
||||
if intersection.is_empty() {
|
||||
//TODO pass all labels somehow
|
||||
|
@ -5,25 +5,26 @@ description = "CLI for nushell"
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
name = "nu-command"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
nu-data = { version = "0.30.0", path = "../nu-data" }
|
||||
nu-engine = { version = "0.30.0", path = "../nu-engine" }
|
||||
nu-errors = { version = "0.30.0", path = "../nu-errors" }
|
||||
nu-json = { version = "0.30.0", path = "../nu-json" }
|
||||
nu-parser = { version = "0.30.0", path = "../nu-parser" }
|
||||
nu-plugin = { version = "0.30.0", path = "../nu-plugin" }
|
||||
nu-protocol = { version = "0.30.0", path = "../nu-protocol" }
|
||||
nu-source = { version = "0.30.0", path = "../nu-source" }
|
||||
nu-stream = { version = "0.30.0", path = "../nu-stream" }
|
||||
nu-table = { version = "0.30.0", path = "../nu-table" }
|
||||
nu-test-support = { version = "0.30.0", path = "../nu-test-support" }
|
||||
nu-value-ext = { version = "0.30.0", path = "../nu-value-ext" }
|
||||
nu-ansi-term = { version = "0.30.0", path = "../nu-ansi-term" }
|
||||
nu-data = { version = "0.31.0", path = "../nu-data" }
|
||||
nu-engine = { version = "0.31.0", path = "../nu-engine" }
|
||||
nu-errors = { version = "0.31.0", path = "../nu-errors" }
|
||||
nu-json = { version = "0.31.0", path = "../nu-json" }
|
||||
nu-parser = { version = "0.31.0", path = "../nu-parser" }
|
||||
nu-plugin = { version = "0.31.0", path = "../nu-plugin" }
|
||||
nu-protocol = { version = "0.31.0", path = "../nu-protocol" }
|
||||
nu-source = { version = "0.31.0", path = "../nu-source" }
|
||||
nu-stream = { version = "0.31.0", path = "../nu-stream" }
|
||||
nu-table = { version = "0.31.0", path = "../nu-table" }
|
||||
nu-test-support = { version = "0.31.0", path = "../nu-test-support" }
|
||||
nu-value-ext = { version = "0.31.0", path = "../nu-value-ext" }
|
||||
nu-ansi-term = { version = "0.31.0", path = "../nu-ansi-term" }
|
||||
nu-pretty-hex = { version = "0.31.0", path = "../nu-pretty-hex" }
|
||||
|
||||
Inflector = "0.11"
|
||||
arboard = { version = "1.1.0", optional = true }
|
||||
@ -53,7 +54,6 @@ getset = "0.1.1"
|
||||
glob = "0.3.0"
|
||||
htmlescape = "0.3.1"
|
||||
ical = "0.7.0"
|
||||
ichwh = { version = "0.3.4", optional = true }
|
||||
indexmap = { version = "1.6.1", features = ["serde-1"] }
|
||||
itertools = "0.10.0"
|
||||
lazy_static = "1.*"
|
||||
@ -66,7 +66,6 @@ num-format = { version = "0.4.0", features = ["with-num-bigint"] }
|
||||
num-traits = "0.2.14"
|
||||
parking_lot = "0.11.1"
|
||||
pin-utils = "0.1.0"
|
||||
pretty-hex = "0.2.1"
|
||||
ptree = { version = "0.3.1", optional = true }
|
||||
query_interface = "0.3.5"
|
||||
quick-xml = "0.21.0"
|
||||
@ -97,7 +96,7 @@ trash = { version = "1.3.0", optional = true }
|
||||
unicode-segmentation = "1.7.1"
|
||||
url = "2.2.0"
|
||||
uuid_crate = { package = "uuid", version = "0.8.2", features = ["v4"], optional = true }
|
||||
which = { version = "4.0.2", optional = true }
|
||||
which = { version = "4.1.0", optional = true }
|
||||
zip = { version = "0.5.9", optional = true }
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
|
@ -172,7 +172,9 @@ pub(crate) use echo::Echo;
|
||||
pub(crate) use empty::Command as Empty;
|
||||
pub(crate) use if_::If;
|
||||
pub(crate) use into::Into;
|
||||
pub(crate) use into::IntoBinary;
|
||||
pub(crate) use into::IntoInt;
|
||||
pub(crate) use into::IntoString;
|
||||
pub(crate) use nu::NuPlugin;
|
||||
pub(crate) use update::Command as Update;
|
||||
pub(crate) mod kill;
|
||||
|
@ -83,7 +83,7 @@ fn all(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
}
|
||||
};
|
||||
|
||||
let scope = args.scope.clone();
|
||||
let scope = args.scope();
|
||||
|
||||
let init = Ok(InputStream::one(
|
||||
UntaggedValue::boolean(true).into_value(&tag),
|
||||
|
@ -2,7 +2,7 @@ use crate::prelude::*;
|
||||
use nu_ansi_term::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use nu_protocol::{Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use nu_source::Tagged;
|
||||
|
||||
pub struct Command;
|
||||
@ -112,7 +112,7 @@ Format: #
|
||||
]
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let args = args.evaluate_once()?;
|
||||
|
||||
let code: Option<Tagged<String>> = args.opt(0)?;
|
||||
@ -129,9 +129,9 @@ Format: #
|
||||
));
|
||||
}
|
||||
let output = format!("\x1b[{}", e.item);
|
||||
return Ok(ActionStream::one(ReturnSuccess::value(
|
||||
return Ok(OutputStream::one(
|
||||
UntaggedValue::string(output).into_value(e.tag()),
|
||||
)));
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(o) = osc {
|
||||
@ -147,18 +147,18 @@ Format: #
|
||||
//Operating system command aka osc ESC ] <- note the right brace, not left brace for osc
|
||||
// OCS's need to end with a bell '\x07' char
|
||||
let output = format!("\x1b]{};", o.item);
|
||||
return Ok(ActionStream::one(ReturnSuccess::value(
|
||||
return Ok(OutputStream::one(
|
||||
UntaggedValue::string(output).into_value(o.tag()),
|
||||
)));
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(code) = code {
|
||||
let ansi_code = str_to_ansi(&code.item);
|
||||
|
||||
if let Some(output) = ansi_code {
|
||||
Ok(ActionStream::one(ReturnSuccess::value(
|
||||
Ok(OutputStream::one(
|
||||
UntaggedValue::string(output).into_value(code.tag()),
|
||||
)))
|
||||
))
|
||||
} else {
|
||||
Err(ShellError::labeled_error(
|
||||
"Unknown ansi code",
|
||||
|
@ -2,19 +2,12 @@ use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::ShellTypeName;
|
||||
use nu_protocol::{
|
||||
ColumnPath, Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
use nu_protocol::{Primitive, Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use nu_source::Tag;
|
||||
use strip_ansi_escapes::strip;
|
||||
|
||||
pub struct SubCommand;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Arguments {
|
||||
rest: Vec<ColumnPath>,
|
||||
}
|
||||
|
||||
impl WholeStreamCommand for SubCommand {
|
||||
fn name(&self) -> &str {
|
||||
"ansi strip"
|
||||
@ -31,7 +24,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
"strip ansi escape sequences from string"
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
operate(args)
|
||||
}
|
||||
|
||||
@ -44,14 +37,16 @@ impl WholeStreamCommand for SubCommand {
|
||||
}
|
||||
}
|
||||
|
||||
fn operate(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let (Arguments { rest }, input) = args.process()?;
|
||||
let column_paths: Vec<_> = rest;
|
||||
fn operate(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let args = args.evaluate_once()?;
|
||||
|
||||
Ok(input
|
||||
let column_paths: Vec<_> = args.rest_args()?;
|
||||
|
||||
let result: Vec<Value> = args
|
||||
.input
|
||||
.map(move |v| {
|
||||
if column_paths.is_empty() {
|
||||
ReturnSuccess::value(action(&v, v.tag())?)
|
||||
action(&v, v.tag())
|
||||
} else {
|
||||
let mut ret = v;
|
||||
|
||||
@ -62,10 +57,12 @@ fn operate(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
)?;
|
||||
}
|
||||
|
||||
ReturnSuccess::value(ret)
|
||||
Ok(ret)
|
||||
}
|
||||
})
|
||||
.to_action_stream())
|
||||
.collect::<Result<Vec<Value>, _>>()?;
|
||||
|
||||
Ok(OutputStream::from_stream(result.into_iter()))
|
||||
}
|
||||
|
||||
fn action(input: &Value, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
||||
|
@ -8,9 +8,8 @@ use nu_protocol::{
|
||||
|
||||
pub struct Command;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Arguments {
|
||||
block: CapturedBlock,
|
||||
struct AnyArgs {
|
||||
predicate: CapturedBlock,
|
||||
}
|
||||
|
||||
impl WholeStreamCommand for Command {
|
||||
@ -30,7 +29,7 @@ impl WholeStreamCommand for Command {
|
||||
"Find if the table rows matches the condition."
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
any(args)
|
||||
}
|
||||
|
||||
@ -52,72 +51,76 @@ impl WholeStreamCommand for Command {
|
||||
}
|
||||
}
|
||||
|
||||
fn any(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let ctx = Arc::new(EvaluationContext::from_args(&args));
|
||||
fn any(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let ctx = EvaluationContext::from_args(&args);
|
||||
let tag = args.call_info.name_tag.clone();
|
||||
let (Arguments { block }, input) = args.process()?;
|
||||
let args = args.evaluate_once()?;
|
||||
let any_args = AnyArgs {
|
||||
predicate: args.req(0)?,
|
||||
};
|
||||
|
||||
let err = Err(ShellError::labeled_error(
|
||||
"Expected a condition",
|
||||
"expected a condition",
|
||||
args.call_info.name_tag.clone(),
|
||||
));
|
||||
|
||||
//This seems a little odd. Can't we have predicates with pipelines/multiple statements?
|
||||
let condition = {
|
||||
if block.block.block.len() != 1 {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Expected a condition",
|
||||
"expected a condition",
|
||||
tag,
|
||||
));
|
||||
if any_args.predicate.block.block.len() != 1 {
|
||||
return err;
|
||||
}
|
||||
match block.block.block[0].pipelines.get(0) {
|
||||
match any_args.predicate.block.block[0].pipelines.get(0) {
|
||||
Some(item) => match item.list.get(0) {
|
||||
Some(ClassifiedCommand::Expr(expr)) => expr.clone(),
|
||||
_ => {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Expected a condition",
|
||||
"expected a condition",
|
||||
tag,
|
||||
));
|
||||
return err;
|
||||
}
|
||||
},
|
||||
None => {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Expected a condition",
|
||||
"expected a condition",
|
||||
tag,
|
||||
));
|
||||
return err;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let cond = Ok(InputStream::one(
|
||||
let scope = args.scope();
|
||||
|
||||
let init = Ok(InputStream::one(
|
||||
UntaggedValue::boolean(false).into_value(&tag),
|
||||
));
|
||||
|
||||
Ok(input
|
||||
.fold(cond, move |cond, row| {
|
||||
let condition = condition.clone();
|
||||
let ctx = ctx.clone();
|
||||
ctx.scope.enter_scope();
|
||||
ctx.scope.add_vars(&block.captured.entries);
|
||||
ctx.scope.add_var("$it", row);
|
||||
// Variables in nu are immutable. Having the same variable accross invocations
|
||||
// of evaluate_baseline_expr does not mutate the variables and thus each
|
||||
// invocations are independent of each other!
|
||||
scope.enter_scope();
|
||||
scope.add_vars(&any_args.predicate.captured.entries);
|
||||
|
||||
let condition = evaluate_baseline_expr(&condition, &*ctx);
|
||||
ctx.scope.exit_scope();
|
||||
let result = args.input.fold(init, move |acc, row| {
|
||||
let condition = condition.clone();
|
||||
let ctx = ctx.clone();
|
||||
ctx.scope.add_var("$it", row);
|
||||
|
||||
let curr = cond?.drain_vec();
|
||||
let curr = curr
|
||||
.get(0)
|
||||
.ok_or_else(|| ShellError::unexpected("No value to check with"))?;
|
||||
let cond = curr.as_bool()?;
|
||||
let condition = evaluate_baseline_expr(&condition, &ctx);
|
||||
|
||||
match condition {
|
||||
Ok(condition) => match condition.as_bool() {
|
||||
Ok(b) => Ok(InputStream::one(
|
||||
UntaggedValue::boolean(cond || b).into_value(&curr.tag),
|
||||
)),
|
||||
Err(e) => Err(e),
|
||||
},
|
||||
let curr = acc?.drain_vec();
|
||||
let curr = curr
|
||||
.get(0)
|
||||
.ok_or_else(|| ShellError::unexpected("No value to check with"))?;
|
||||
let cond = curr.as_bool()?;
|
||||
|
||||
match condition {
|
||||
Ok(condition) => match condition.as_bool() {
|
||||
Ok(b) => Ok(InputStream::one(
|
||||
UntaggedValue::boolean(cond || b).into_value(&curr.tag),
|
||||
)),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
})?
|
||||
.to_action_stream())
|
||||
},
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
});
|
||||
scope.exit_scope();
|
||||
|
||||
Ok(result?.to_output_stream())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -27,7 +27,7 @@ The .nu-env file has the same format as your $HOME/nu/config.toml file. By loadi
|
||||
}
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
Ok(ActionStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::string(get_full_help(&Autoenv, &args.scope)).into_value(Tag::unknown()),
|
||||
UntaggedValue::string(get_full_help(&Autoenv, args.scope())).into_value(Tag::unknown()),
|
||||
)))
|
||||
}
|
||||
|
||||
|
@ -43,14 +43,15 @@ impl WholeStreamCommand for Command {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn autoview(context: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let configuration = context.configs.lock().global_config();
|
||||
pub fn autoview(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let configuration = args.configs().lock().global_config();
|
||||
let tag = args.call_info.name_tag.clone();
|
||||
|
||||
let binary = context.scope.get_command("binaryview");
|
||||
let text = context.scope.get_command("textview");
|
||||
let table = context.scope.get_command("table");
|
||||
|
||||
let (mut input_stream, context) = context.split();
|
||||
let binary = args.scope().get_command("binaryview");
|
||||
let text = args.scope().get_command("textview");
|
||||
let table = args.scope().get_command("table");
|
||||
let context = args.context;
|
||||
let mut input_stream = args.input;
|
||||
|
||||
if let Some(x) = input_stream.next() {
|
||||
match input_stream.next() {
|
||||
@ -62,7 +63,7 @@ pub fn autoview(context: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let stream = InputStream::from_stream(xy_stream);
|
||||
|
||||
if let Some(table) = table {
|
||||
let command_args = create_default_command_args(&context).with_input(stream);
|
||||
let command_args = create_default_command_args(&context, stream, tag);
|
||||
let result = table.run(command_args)?;
|
||||
let _ = result.collect::<Vec<_>>();
|
||||
}
|
||||
@ -74,12 +75,13 @@ pub fn autoview(context: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
tag: Tag { anchor, span },
|
||||
} if anchor.is_some() => {
|
||||
if let Some(text) = text {
|
||||
let mut stream = VecDeque::new();
|
||||
stream.push_back(
|
||||
UntaggedValue::string(s).into_value(Tag { anchor, span }),
|
||||
let command_args = create_default_command_args(
|
||||
&context,
|
||||
InputStream::one(
|
||||
UntaggedValue::string(s).into_value(Tag { anchor, span }),
|
||||
),
|
||||
tag,
|
||||
);
|
||||
let command_args =
|
||||
create_default_command_args(&context).with_input(stream);
|
||||
let result = text.run_with_actions(command_args)?;
|
||||
let _ = result.collect::<Vec<_>>();
|
||||
} else {
|
||||
@ -158,14 +160,12 @@ pub fn autoview(context: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
..
|
||||
} => {
|
||||
if let Some(binary) = binary {
|
||||
let mut stream = VecDeque::new();
|
||||
stream.push_back(x);
|
||||
let command_args =
|
||||
create_default_command_args(&context).with_input(stream);
|
||||
create_default_command_args(&context, InputStream::one(x), tag);
|
||||
let result = binary.run_with_actions(command_args)?;
|
||||
let _ = result.collect::<Vec<_>>();
|
||||
} else {
|
||||
use pretty_hex::*;
|
||||
use nu_pretty_hex::*;
|
||||
out!("{:?}", b.hex_dump());
|
||||
}
|
||||
}
|
||||
@ -220,10 +220,8 @@ pub fn autoview(context: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
|
||||
println!("{}", nu_table::draw_table(&table, term_width, &color_hm));
|
||||
} else if let Some(table) = table {
|
||||
let mut stream = VecDeque::new();
|
||||
stream.push_back(x);
|
||||
let command_args =
|
||||
create_default_command_args(&context).with_input(stream);
|
||||
create_default_command_args(&context, InputStream::one(x), tag);
|
||||
let result = table.run(command_args)?;
|
||||
let _ = result.collect::<Vec<_>>();
|
||||
} else {
|
||||
@ -240,10 +238,8 @@ pub fn autoview(context: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
value: ref item, ..
|
||||
} => {
|
||||
if let Some(table) = table {
|
||||
let mut stream = VecDeque::new();
|
||||
stream.push_back(x);
|
||||
let command_args =
|
||||
create_default_command_args(&context).with_input(stream);
|
||||
create_default_command_args(&context, InputStream::one(x), tag);
|
||||
let result = table.run(command_args)?;
|
||||
let _ = result.collect::<Vec<_>>();
|
||||
} else {
|
||||
@ -258,14 +254,14 @@ pub fn autoview(context: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
Ok(InputStream::empty())
|
||||
}
|
||||
|
||||
fn create_default_command_args(context: &RunnableContextWithoutInput) -> RawCommandArgs {
|
||||
let span = context.name.span;
|
||||
RawCommandArgs {
|
||||
host: context.host.clone(),
|
||||
ctrl_c: context.ctrl_c.clone(),
|
||||
configs: context.configs.clone(),
|
||||
current_errors: context.current_errors.clone(),
|
||||
shell_manager: context.shell_manager.clone(),
|
||||
fn create_default_command_args(
|
||||
context: &EvaluationContext,
|
||||
input: InputStream,
|
||||
tag: Tag,
|
||||
) -> CommandArgs {
|
||||
let span = tag.span;
|
||||
CommandArgs {
|
||||
context: context.clone(),
|
||||
call_info: UnevaluatedCallInfo {
|
||||
args: hir::Call {
|
||||
head: Box::new(SpannedExpression::new(
|
||||
@ -277,9 +273,9 @@ fn create_default_command_args(context: &RunnableContextWithoutInput) -> RawComm
|
||||
span,
|
||||
external_redirection: ExternalRedirection::Stdout,
|
||||
},
|
||||
name_tag: context.name.clone(),
|
||||
name_tag: tag,
|
||||
},
|
||||
scope: Scope::new(),
|
||||
input,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,10 @@ use nu_engine::run_block;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{
|
||||
hir::{Block, CapturedBlock, ClassifiedCommand, Group, InternalCommand, Pipeline},
|
||||
hir::{
|
||||
Block, CapturedBlock, ClassifiedCommand, ExternalRedirection, Group, InternalCommand,
|
||||
Pipeline,
|
||||
},
|
||||
Dictionary, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
use rand::{
|
||||
@ -47,7 +50,7 @@ impl WholeStreamCommand for Benchmark {
|
||||
"Runs a block and returns the time it took to execute it."
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
benchmark(args)
|
||||
}
|
||||
|
||||
@ -67,11 +70,16 @@ impl WholeStreamCommand for Benchmark {
|
||||
}
|
||||
}
|
||||
|
||||
fn benchmark(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let tag = raw_args.call_info.args.span;
|
||||
let mut context = EvaluationContext::from_args(&raw_args);
|
||||
let scope = raw_args.scope.clone();
|
||||
let (BenchmarkArgs { block, passthrough }, input) = raw_args.process()?;
|
||||
fn benchmark(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let tag = args.call_info.args.span;
|
||||
let mut context = EvaluationContext::from_args(&args);
|
||||
let scope = args.scope().clone();
|
||||
|
||||
let args = args.evaluate_once()?;
|
||||
let cmd_args = BenchmarkArgs {
|
||||
block: args.req(0)?,
|
||||
passthrough: args.get_flag("passthrough")?,
|
||||
};
|
||||
|
||||
let env = scope.get_env_vars();
|
||||
let name = generate_free_name(&env);
|
||||
@ -84,7 +92,13 @@ fn benchmark(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
// let start = time();
|
||||
|
||||
context.scope.enter_scope();
|
||||
let result = run_block(&block.block, &context, input);
|
||||
let result = run_block(
|
||||
&cmd_args.block.block,
|
||||
&context,
|
||||
args.input,
|
||||
ExternalRedirection::StdoutAndStderr,
|
||||
);
|
||||
|
||||
context.scope.exit_scope();
|
||||
let output = result?.into_vec();
|
||||
|
||||
@ -101,7 +115,7 @@ fn benchmark(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
|
||||
let real_time = into_big_int(end_time - start_time);
|
||||
indexmap.insert("real time".to_string(), real_time);
|
||||
benchmark_output(indexmap, output, passthrough, &tag, &mut context)
|
||||
benchmark_output(indexmap, output, cmd_args.passthrough, &tag, &mut context)
|
||||
}
|
||||
// return advanced stats
|
||||
// #[cfg(feature = "rich-benchmark")]
|
||||
@ -134,10 +148,10 @@ fn benchmark_output<T, Output>(
|
||||
passthrough: Option<CapturedBlock>,
|
||||
tag: T,
|
||||
context: &mut EvaluationContext,
|
||||
) -> Result<ActionStream, ShellError>
|
||||
) -> Result<OutputStream, ShellError>
|
||||
where
|
||||
T: Into<Tag> + Copy,
|
||||
Output: Into<ActionStream>,
|
||||
Output: Into<OutputStream>,
|
||||
{
|
||||
let value = UntaggedValue::Row(Dictionary::from(
|
||||
indexmap
|
||||
@ -154,14 +168,19 @@ where
|
||||
let time_block = add_implicit_autoview(time_block.block);
|
||||
|
||||
context.scope.enter_scope();
|
||||
let result = run_block(&time_block, context, benchmark_output);
|
||||
let result = run_block(
|
||||
&time_block,
|
||||
context,
|
||||
benchmark_output,
|
||||
ExternalRedirection::StdoutAndStderr,
|
||||
);
|
||||
context.scope.exit_scope();
|
||||
result?;
|
||||
context.clear_errors();
|
||||
|
||||
Ok(block_output.into())
|
||||
} else {
|
||||
let benchmark_output = ActionStream::one(value);
|
||||
let benchmark_output = OutputStream::one(value);
|
||||
Ok(benchmark_output)
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use nu_errors::ShellError;
|
||||
|
||||
use nu_data::value::format_leaf;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use nu_protocol::{Signature, SyntaxShape, UntaggedValue, Value};
|
||||
|
||||
pub struct BuildString;
|
||||
|
||||
@ -21,7 +21,7 @@ impl WholeStreamCommand for BuildString {
|
||||
"Builds a string from the arguments."
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let tag = args.call_info.name_tag.clone();
|
||||
let args = args.evaluate_once()?;
|
||||
let rest: Vec<Value> = args.rest(0)?;
|
||||
@ -32,9 +32,9 @@ impl WholeStreamCommand for BuildString {
|
||||
output_string.push_str(&format_leaf(&r).plain_string(100_000))
|
||||
}
|
||||
|
||||
Ok(ActionStream::one(ReturnSuccess::value(
|
||||
Ok(OutputStream::one(
|
||||
UntaggedValue::string(output_string).into_value(tag),
|
||||
)))
|
||||
))
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::prelude::*;
|
||||
use chrono::{Datelike, Local, NaiveDate};
|
||||
use indexmap::IndexMap;
|
||||
use nu_engine::{EvaluatedWholeStreamCommandArgs, WholeStreamCommand};
|
||||
use nu_engine::{EvaluatedCommandArgs, WholeStreamCommand};
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{Dictionary, Signature, SyntaxShape, UntaggedValue, Value};
|
||||
|
||||
@ -165,7 +165,7 @@ fn get_current_date() -> (i32, u32, u32) {
|
||||
}
|
||||
|
||||
fn add_months_of_year_to_table(
|
||||
args: &EvaluatedWholeStreamCommandArgs,
|
||||
args: &EvaluatedCommandArgs,
|
||||
mut calendar_vec_deque: &mut VecDeque<Value>,
|
||||
tag: &Tag,
|
||||
selected_year: i32,
|
||||
@ -198,7 +198,7 @@ fn add_months_of_year_to_table(
|
||||
}
|
||||
|
||||
fn add_month_to_table(
|
||||
args: &EvaluatedWholeStreamCommandArgs,
|
||||
args: &EvaluatedCommandArgs,
|
||||
calendar_vec_deque: &mut VecDeque<Value>,
|
||||
tag: &Tag,
|
||||
selected_year: i32,
|
||||
|
@ -26,7 +26,7 @@ impl WholeStreamCommand for Cd {
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let name = args.call_info.name_tag.clone();
|
||||
let shell_manager = args.shell_manager.clone();
|
||||
let shell_manager = args.shell_manager();
|
||||
let (args, _): (CdArgs, _) = args.process()?;
|
||||
shell_manager.cd(args, name)
|
||||
}
|
||||
|
@ -20,14 +20,14 @@ impl WholeStreamCommand for Chart {
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
if args.scope.get_command("chart bar").is_none() {
|
||||
if args.scope().get_command("chart bar").is_none() {
|
||||
return Err(ShellError::untagged_runtime_error(
|
||||
"nu_plugin_chart not installed.",
|
||||
));
|
||||
}
|
||||
|
||||
Ok(ActionStream::one(Ok(ReturnSuccess::Value(
|
||||
UntaggedValue::string(get_full_help(&Chart, &args.scope)).into_value(Tag::unknown()),
|
||||
UntaggedValue::string(get_full_help(&Chart, args.scope())).into_value(Tag::unknown()),
|
||||
))))
|
||||
}
|
||||
}
|
||||
|
@ -199,247 +199,250 @@ fn spawn(
|
||||
trace!(target: "nu::run::external", "built command {:?}", process);
|
||||
|
||||
// TODO Switch to async_std::process once it's stabilized
|
||||
if let Ok(mut child) = process.spawn() {
|
||||
let (tx, rx) = mpsc::sync_channel(0);
|
||||
match process.spawn() {
|
||||
Ok(mut child) => {
|
||||
let (tx, rx) = mpsc::sync_channel(0);
|
||||
|
||||
let mut stdin = child.stdin.take();
|
||||
let mut stdin = child.stdin.take();
|
||||
|
||||
let stdin_write_tx = tx.clone();
|
||||
let stdout_read_tx = tx;
|
||||
let stdin_name_tag = command.name_tag.clone();
|
||||
let stdout_name_tag = command.name_tag;
|
||||
let stdin_write_tx = tx.clone();
|
||||
let stdout_read_tx = tx;
|
||||
let stdin_name_tag = command.name_tag.clone();
|
||||
let stdout_name_tag = command.name_tag;
|
||||
|
||||
std::thread::spawn(move || {
|
||||
if !input.is_empty() {
|
||||
let mut stdin_write = stdin
|
||||
.take()
|
||||
.expect("Internal error: could not get stdin pipe for external command");
|
||||
std::thread::spawn(move || {
|
||||
if !input.is_empty() {
|
||||
let mut stdin_write = stdin
|
||||
.take()
|
||||
.expect("Internal error: could not get stdin pipe for external command");
|
||||
|
||||
for value in input {
|
||||
match &value.value {
|
||||
UntaggedValue::Primitive(Primitive::Nothing) => continue,
|
||||
UntaggedValue::Primitive(Primitive::String(s)) => {
|
||||
if stdin_write.write(s.as_bytes()).is_err() {
|
||||
// Other side has closed, so exit
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
UntaggedValue::Primitive(Primitive::Binary(b)) => {
|
||||
if stdin_write.write(b).is_err() {
|
||||
// Other side has closed, so exit
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
unsupported => {
|
||||
println!("Unsupported: {:?}", unsupported);
|
||||
let _ = stdin_write_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Error(ShellError::labeled_error(
|
||||
format!(
|
||||
"Received unexpected type from pipeline ({})",
|
||||
unsupported.type_name()
|
||||
),
|
||||
"expected a string",
|
||||
stdin_name_tag.clone(),
|
||||
)),
|
||||
tag: stdin_name_tag,
|
||||
}));
|
||||
return Err(());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
});
|
||||
|
||||
std::thread::spawn(move || {
|
||||
if external_redirection == ExternalRedirection::Stdout
|
||||
|| external_redirection == ExternalRedirection::StdoutAndStderr
|
||||
{
|
||||
let stdout = if let Some(stdout) = child.stdout.take() {
|
||||
stdout
|
||||
} else {
|
||||
let _ = stdout_read_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Can't redirect the stdout for external command",
|
||||
"can't redirect stdout",
|
||||
&stdout_name_tag,
|
||||
)),
|
||||
tag: stdout_name_tag,
|
||||
}));
|
||||
return Err(());
|
||||
};
|
||||
|
||||
// let file = futures::io::AllowStdIo::new(stdout);
|
||||
// let stream = FramedRead::new(file, MaybeTextCodec::default());
|
||||
let buf_read = BufReader::new(stdout);
|
||||
let buf_codec = BufCodecReader::new(buf_read, MaybeTextCodec::default());
|
||||
|
||||
for line in buf_codec {
|
||||
match line {
|
||||
Ok(line) => match line {
|
||||
StringOrBinary::String(s) => {
|
||||
let result = stdout_read_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Primitive(Primitive::String(s.clone())),
|
||||
tag: stdout_name_tag.clone(),
|
||||
}));
|
||||
|
||||
if result.is_err() {
|
||||
break;
|
||||
for value in input {
|
||||
match &value.value {
|
||||
UntaggedValue::Primitive(Primitive::Nothing) => continue,
|
||||
UntaggedValue::Primitive(Primitive::String(s)) => {
|
||||
if stdin_write.write(s.as_bytes()).is_err() {
|
||||
// Other side has closed, so exit
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
StringOrBinary::Binary(b) => {
|
||||
let result = stdout_read_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Primitive(Primitive::Binary(
|
||||
b.into_iter().collect(),
|
||||
)),
|
||||
tag: stdout_name_tag.clone(),
|
||||
}));
|
||||
|
||||
if result.is_err() {
|
||||
break;
|
||||
UntaggedValue::Primitive(Primitive::Binary(b)) => {
|
||||
if stdin_write.write(b).is_err() {
|
||||
// Other side has closed, so exit
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
// If there's an exit status, it makes sense that we may error when
|
||||
// trying to read from its stdout pipe (likely been closed). In that
|
||||
// case, don't emit an error.
|
||||
let should_error = match child.wait() {
|
||||
Ok(exit_status) => !exit_status.success(),
|
||||
Err(_) => true,
|
||||
};
|
||||
|
||||
if should_error {
|
||||
let _ = stdout_read_tx.send(Ok(Value {
|
||||
unsupported => {
|
||||
println!("Unsupported: {:?}", unsupported);
|
||||
let _ = stdin_write_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Error(ShellError::labeled_error(
|
||||
format!("Unable to read from stdout ({})", e),
|
||||
"unable to read from stdout",
|
||||
&stdout_name_tag,
|
||||
format!(
|
||||
"Received unexpected type from pipeline ({})",
|
||||
unsupported.type_name()
|
||||
),
|
||||
"expected a string",
|
||||
stdin_name_tag.clone(),
|
||||
)),
|
||||
tag: stdout_name_tag.clone(),
|
||||
tag: stdin_name_tag,
|
||||
}));
|
||||
return Err(());
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
if external_redirection == ExternalRedirection::Stderr
|
||||
|| external_redirection == ExternalRedirection::StdoutAndStderr
|
||||
{
|
||||
let stderr = if let Some(stderr) = child.stderr.take() {
|
||||
stderr
|
||||
} else {
|
||||
let _ = stdout_read_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Can't redirect the stderr for external command",
|
||||
"can't redirect stderr",
|
||||
&stdout_name_tag,
|
||||
)),
|
||||
tag: stdout_name_tag,
|
||||
}));
|
||||
return Err(());
|
||||
};
|
||||
|
||||
// let file = futures::io::AllowStdIo::new(stderr);
|
||||
// let stream = FramedRead::new(file, MaybeTextCodec::default());
|
||||
let buf_reader = BufReader::new(stderr);
|
||||
let buf_codec = BufCodecReader::new(buf_reader, MaybeTextCodec::default());
|
||||
Ok(())
|
||||
});
|
||||
|
||||
for line in buf_codec {
|
||||
match line {
|
||||
Ok(line) => match line {
|
||||
StringOrBinary::String(s) => {
|
||||
let result = stdout_read_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Error(
|
||||
ShellError::untagged_runtime_error(s),
|
||||
),
|
||||
tag: stdout_name_tag.clone(),
|
||||
}));
|
||||
|
||||
if result.is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
StringOrBinary::Binary(_) => {
|
||||
let result = stdout_read_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Error(
|
||||
ShellError::untagged_runtime_error("<binary stderr>"),
|
||||
),
|
||||
tag: stdout_name_tag.clone(),
|
||||
}));
|
||||
|
||||
if result.is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
// If there's an exit status, it makes sense that we may error when
|
||||
// trying to read from its stdout pipe (likely been closed). In that
|
||||
// case, don't emit an error.
|
||||
let should_error = match child.wait() {
|
||||
Ok(exit_status) => !exit_status.success(),
|
||||
Err(_) => true,
|
||||
};
|
||||
|
||||
if should_error {
|
||||
let _ = stdout_read_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Error(ShellError::labeled_error(
|
||||
format!("Unable to read from stdout ({})", e),
|
||||
"unable to read from stdout",
|
||||
&stdout_name_tag,
|
||||
)),
|
||||
tag: stdout_name_tag.clone(),
|
||||
}));
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We can give an error when we see a non-zero exit code, but this is different
|
||||
// than what other shells will do.
|
||||
let external_failed = match child.wait() {
|
||||
Err(_) => true,
|
||||
Ok(exit_status) => !exit_status.success(),
|
||||
};
|
||||
|
||||
if external_failed {
|
||||
let cfg = nu_data::config::config(Tag::unknown());
|
||||
if let Ok(cfg) = cfg {
|
||||
if cfg.contains_key("nonzero_exit_errors") {
|
||||
std::thread::spawn(move || {
|
||||
if external_redirection == ExternalRedirection::Stdout
|
||||
|| external_redirection == ExternalRedirection::StdoutAndStderr
|
||||
{
|
||||
let stdout = if let Some(stdout) = child.stdout.take() {
|
||||
stdout
|
||||
} else {
|
||||
let _ = stdout_read_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Error(ShellError::labeled_error(
|
||||
"External command failed",
|
||||
"command failed",
|
||||
"Can't redirect the stdout for external command",
|
||||
"can't redirect stdout",
|
||||
&stdout_name_tag,
|
||||
)),
|
||||
tag: stdout_name_tag.clone(),
|
||||
tag: stdout_name_tag,
|
||||
}));
|
||||
return Err(());
|
||||
};
|
||||
|
||||
// let file = futures::io::AllowStdIo::new(stdout);
|
||||
// let stream = FramedRead::new(file, MaybeTextCodec::default());
|
||||
let buf_read = BufReader::new(stdout);
|
||||
let buf_codec = BufCodecReader::new(buf_read, MaybeTextCodec::default());
|
||||
|
||||
for line in buf_codec {
|
||||
match line {
|
||||
Ok(line) => match line {
|
||||
StringOrBinary::String(s) => {
|
||||
let result = stdout_read_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Primitive(Primitive::String(
|
||||
s.clone(),
|
||||
)),
|
||||
tag: stdout_name_tag.clone(),
|
||||
}));
|
||||
|
||||
if result.is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
StringOrBinary::Binary(b) => {
|
||||
let result = stdout_read_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Primitive(Primitive::Binary(
|
||||
b.into_iter().collect(),
|
||||
)),
|
||||
tag: stdout_name_tag.clone(),
|
||||
}));
|
||||
|
||||
if result.is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
// If there's an exit status, it makes sense that we may error when
|
||||
// trying to read from its stdout pipe (likely been closed). In that
|
||||
// case, don't emit an error.
|
||||
let should_error = match child.wait() {
|
||||
Ok(exit_status) => !exit_status.success(),
|
||||
Err(_) => true,
|
||||
};
|
||||
|
||||
if should_error {
|
||||
let _ = stdout_read_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Error(ShellError::labeled_error(
|
||||
format!("Unable to read from stdout ({})", e),
|
||||
"unable to read from stdout",
|
||||
&stdout_name_tag,
|
||||
)),
|
||||
tag: stdout_name_tag.clone(),
|
||||
}));
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let _ = stdout_read_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Error(ShellError::external_non_zero()),
|
||||
tag: stdout_name_tag,
|
||||
}));
|
||||
}
|
||||
if external_redirection == ExternalRedirection::Stderr
|
||||
|| external_redirection == ExternalRedirection::StdoutAndStderr
|
||||
{
|
||||
let stderr = if let Some(stderr) = child.stderr.take() {
|
||||
stderr
|
||||
} else {
|
||||
let _ = stdout_read_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Can't redirect the stderr for external command",
|
||||
"can't redirect stderr",
|
||||
&stdout_name_tag,
|
||||
)),
|
||||
tag: stdout_name_tag,
|
||||
}));
|
||||
return Err(());
|
||||
};
|
||||
|
||||
Ok(())
|
||||
});
|
||||
// let file = futures::io::AllowStdIo::new(stderr);
|
||||
// let stream = FramedRead::new(file, MaybeTextCodec::default());
|
||||
let buf_reader = BufReader::new(stderr);
|
||||
let buf_codec = BufCodecReader::new(buf_reader, MaybeTextCodec::default());
|
||||
|
||||
let stream = ChannelReceiver::new(rx);
|
||||
Ok(stream.to_input_stream())
|
||||
} else {
|
||||
Err(ShellError::labeled_error(
|
||||
"Failed to spawn process",
|
||||
for line in buf_codec {
|
||||
match line {
|
||||
Ok(line) => match line {
|
||||
StringOrBinary::String(s) => {
|
||||
let result = stdout_read_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Error(
|
||||
ShellError::untagged_runtime_error(s),
|
||||
),
|
||||
tag: stdout_name_tag.clone(),
|
||||
}));
|
||||
|
||||
if result.is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
StringOrBinary::Binary(_) => {
|
||||
let result = stdout_read_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Error(
|
||||
ShellError::untagged_runtime_error("<binary stderr>"),
|
||||
),
|
||||
tag: stdout_name_tag.clone(),
|
||||
}));
|
||||
|
||||
if result.is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
// If there's an exit status, it makes sense that we may error when
|
||||
// trying to read from its stdout pipe (likely been closed). In that
|
||||
// case, don't emit an error.
|
||||
let should_error = match child.wait() {
|
||||
Ok(exit_status) => !exit_status.success(),
|
||||
Err(_) => true,
|
||||
};
|
||||
|
||||
if should_error {
|
||||
let _ = stdout_read_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Error(ShellError::labeled_error(
|
||||
format!("Unable to read from stdout ({})", e),
|
||||
"unable to read from stdout",
|
||||
&stdout_name_tag,
|
||||
)),
|
||||
tag: stdout_name_tag.clone(),
|
||||
}));
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We can give an error when we see a non-zero exit code, but this is different
|
||||
// than what other shells will do.
|
||||
let external_failed = match child.wait() {
|
||||
Err(_) => true,
|
||||
Ok(exit_status) => !exit_status.success(),
|
||||
};
|
||||
|
||||
if external_failed {
|
||||
let cfg = nu_data::config::config(Tag::unknown());
|
||||
if let Ok(cfg) = cfg {
|
||||
if cfg.contains_key("nonzero_exit_errors") {
|
||||
let _ = stdout_read_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Error(ShellError::labeled_error(
|
||||
"External command failed",
|
||||
"command failed",
|
||||
&stdout_name_tag,
|
||||
)),
|
||||
tag: stdout_name_tag.clone(),
|
||||
}));
|
||||
}
|
||||
}
|
||||
let _ = stdout_read_tx.send(Ok(Value {
|
||||
value: UntaggedValue::Error(ShellError::external_non_zero()),
|
||||
tag: stdout_name_tag,
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
});
|
||||
|
||||
let stream = ChannelReceiver::new(rx);
|
||||
Ok(stream.to_input_stream())
|
||||
}
|
||||
Err(e) => Err(ShellError::labeled_error(
|
||||
format!("{}", e),
|
||||
"failed to spawn",
|
||||
&command.name_tag,
|
||||
))
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -531,7 +534,7 @@ mod tests {
|
||||
use super::{run_external_command, InputStream};
|
||||
|
||||
#[cfg(feature = "which")]
|
||||
use nu_engine::basic_evaluation_context;
|
||||
use nu_engine::EvaluationContext;
|
||||
|
||||
#[cfg(feature = "which")]
|
||||
use nu_test_support::commands::ExternalBuilder;
|
||||
@ -554,8 +557,7 @@ mod tests {
|
||||
let cmd = ExternalBuilder::for_name("i_dont_exist.exe").build();
|
||||
|
||||
let input = InputStream::empty();
|
||||
let mut ctx =
|
||||
basic_evaluation_context().expect("There was a problem creating a basic context.");
|
||||
let mut ctx = EvaluationContext::basic();
|
||||
|
||||
assert!(run_external_command(cmd, &mut ctx, input, ExternalRedirection::Stdout).is_err());
|
||||
}
|
||||
@ -563,7 +565,7 @@ mod tests {
|
||||
// fn failure_run() -> Result<(), ShellError> {
|
||||
// let cmd = ExternalBuilder::for_name("fail").build();
|
||||
|
||||
// let mut ctx = crate::cli::basic_evaluation_context().expect("There was a problem creating a basic context.");
|
||||
// let mut ctx = crate::cli::EvaluationContext::basic().expect("There was a problem creating a basic context.");
|
||||
// let stream = run_external_command(cmd, &mut ctx, None, false)
|
||||
// ?
|
||||
// .expect("There was a problem running the external command.");
|
||||
|
@ -34,7 +34,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
pub fn clear(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let ctx = EvaluationContext::from_args(&args);
|
||||
|
||||
let result = if let Some(global_cfg) = &mut args.configs.lock().global_config {
|
||||
let result = if let Some(global_cfg) = &mut args.configs().lock().global_config {
|
||||
global_cfg.vars.clear();
|
||||
global_cfg.write()?;
|
||||
ctx.reload_config(global_cfg)?;
|
||||
|
@ -21,9 +21,9 @@ impl WholeStreamCommand for Command {
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let name = args.call_info.name_tag;
|
||||
let name = args.call_info.name_tag.clone();
|
||||
|
||||
if let Some(global_cfg) = &args.configs.lock().global_config {
|
||||
if let Some(global_cfg) = &args.configs().lock().global_config {
|
||||
let result = global_cfg.vars.clone();
|
||||
Ok(vec![ReturnSuccess::value(
|
||||
UntaggedValue::Row(result.into()).into_value(name),
|
||||
|
@ -32,7 +32,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
}
|
||||
|
||||
pub fn path(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
if let Some(global_cfg) = &mut args.configs.lock().global_config {
|
||||
if let Some(global_cfg) = &mut args.configs().lock().global_config {
|
||||
Ok(ActionStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::Primitive(Primitive::FilePath(global_cfg.file_path.clone())),
|
||||
)))
|
||||
|
@ -26,7 +26,7 @@ impl WholeStreamCommand for Cpy {
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let shell_manager = args.shell_manager.clone();
|
||||
let shell_manager = args.shell_manager();
|
||||
let name = args.call_info.name_tag.clone();
|
||||
let (args, _) = args.process()?;
|
||||
shell_manager.cp(args, name)
|
||||
|
@ -20,7 +20,7 @@ impl WholeStreamCommand for Command {
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
Ok(ActionStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::string(get_full_help(&Command, &args.scope)).into_value(Tag::unknown()),
|
||||
UntaggedValue::string(get_full_help(&Command, args.scope())).into_value(Tag::unknown()),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::basic_evaluation_context;
|
||||
use nu_engine::whole_stream_command;
|
||||
use std::error::Error;
|
||||
|
||||
pub fn create_default_context(interactive: bool) -> Result<EvaluationContext, Box<dyn Error>> {
|
||||
let context = basic_evaluation_context()?;
|
||||
let context = EvaluationContext::basic();
|
||||
|
||||
{
|
||||
use crate::commands::*;
|
||||
@ -122,7 +121,9 @@ pub fn create_default_context(interactive: bool) -> Result<EvaluationContext, Bo
|
||||
whole_stream_command(Update),
|
||||
whole_stream_command(Insert),
|
||||
whole_stream_command(Into),
|
||||
whole_stream_command(IntoBinary),
|
||||
whole_stream_command(IntoInt),
|
||||
whole_stream_command(IntoString),
|
||||
whole_stream_command(SplitBy),
|
||||
// Row manipulation
|
||||
whole_stream_command(All),
|
||||
|
@ -58,7 +58,7 @@ fn do_(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let (
|
||||
DoArgs {
|
||||
ignore_errors,
|
||||
mut block,
|
||||
block,
|
||||
},
|
||||
input,
|
||||
) = raw_args.process()?;
|
||||
@ -81,11 +81,8 @@ fn do_(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
x => x,
|
||||
};
|
||||
|
||||
if let Some(block) = std::sync::Arc::<nu_protocol::hir::Block>::get_mut(&mut block.block) {
|
||||
block.set_redirect(block_redirection);
|
||||
}
|
||||
context.scope.enter_scope();
|
||||
let result = run_block(&block.block, &context, input);
|
||||
let result = run_block(&block.block, &context, input, block_redirection);
|
||||
context.scope.exit_scope();
|
||||
|
||||
if ignore_errors {
|
||||
|
@ -85,7 +85,7 @@ impl WholeStreamCommand for Du {
|
||||
|
||||
fn du(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let tag = args.call_info.name_tag.clone();
|
||||
let ctrl_c = args.ctrl_c.clone();
|
||||
let ctrl_c = args.ctrl_c();
|
||||
let ctrl_c_copy = ctrl_c.clone();
|
||||
|
||||
let (args, _): (DuArgs, _) = args.process()?;
|
||||
|
@ -4,7 +4,8 @@ use nu_engine::WholeStreamCommand;
|
||||
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{
|
||||
hir::CapturedBlock, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, Value,
|
||||
hir::{CapturedBlock, ExternalRedirection},
|
||||
Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, Value,
|
||||
};
|
||||
|
||||
pub struct Each;
|
||||
@ -62,6 +63,7 @@ pub fn process_row(
|
||||
captured_block: Arc<Box<CapturedBlock>>,
|
||||
context: Arc<EvaluationContext>,
|
||||
input: Value,
|
||||
external_redirection: ExternalRedirection,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let input_clone = input.clone();
|
||||
// When we process a row, we need to know whether the block wants to have the contents of the row as
|
||||
@ -86,7 +88,12 @@ pub fn process_row(
|
||||
context.scope.add_var("$it", input);
|
||||
}
|
||||
|
||||
let result = run_block(&captured_block.block, &*context, input_stream);
|
||||
let result = run_block(
|
||||
&captured_block.block,
|
||||
&*context,
|
||||
input_stream,
|
||||
external_redirection,
|
||||
);
|
||||
|
||||
context.scope.exit_scope();
|
||||
|
||||
@ -103,6 +110,7 @@ pub(crate) fn make_indexed_item(index: usize, item: Value) -> Value {
|
||||
|
||||
fn each(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let context = Arc::new(EvaluationContext::from_args(&raw_args));
|
||||
let external_redirection = raw_args.call_info.args.external_redirection;
|
||||
let args = raw_args.evaluate_once()?;
|
||||
|
||||
let block: CapturedBlock = args.req(0)?;
|
||||
@ -119,7 +127,7 @@ fn each(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let context = context.clone();
|
||||
let row = make_indexed_item(input.0, input.1);
|
||||
|
||||
match process_row(block, context, row) {
|
||||
match process_row(block, context, row, external_redirection) {
|
||||
Ok(s) => s,
|
||||
Err(e) => OutputStream::one(Value::error(e)),
|
||||
}
|
||||
@ -133,7 +141,7 @@ fn each(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let block = block.clone();
|
||||
let context = context.clone();
|
||||
|
||||
match process_row(block, context, input) {
|
||||
match process_row(block, context, input, external_redirection) {
|
||||
Ok(s) => s,
|
||||
Err(e) => OutputStream::one(Value::error(e)),
|
||||
}
|
||||
|
@ -2,7 +2,10 @@ use crate::commands::each::process_row;
|
||||
use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{hir::CapturedBlock, Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use nu_protocol::{
|
||||
hir::{CapturedBlock, ExternalRedirection},
|
||||
Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
use nu_source::Tagged;
|
||||
use serde::Deserialize;
|
||||
|
||||
@ -44,6 +47,7 @@ impl WholeStreamCommand for EachGroup {
|
||||
|
||||
fn run_with_actions(&self, raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let context = Arc::new(EvaluationContext::from_args(&raw_args));
|
||||
let external_redirection = raw_args.call_info.args.external_redirection;
|
||||
let (each_args, input): (EachGroupArgs, _) = raw_args.process()?;
|
||||
let block = Arc::new(Box::new(each_args.block));
|
||||
|
||||
@ -52,6 +56,7 @@ impl WholeStreamCommand for EachGroup {
|
||||
context,
|
||||
group_size: each_args.group_size.item,
|
||||
input,
|
||||
external_redirection,
|
||||
};
|
||||
|
||||
Ok(each_group_iterator.flatten().to_action_stream())
|
||||
@ -63,6 +68,7 @@ struct EachGroupIterator {
|
||||
context: Arc<EvaluationContext>,
|
||||
group_size: usize,
|
||||
input: InputStream,
|
||||
external_redirection: ExternalRedirection,
|
||||
}
|
||||
|
||||
impl Iterator for EachGroupIterator {
|
||||
@ -89,6 +95,7 @@ impl Iterator for EachGroupIterator {
|
||||
group,
|
||||
self.block.clone(),
|
||||
self.context.clone(),
|
||||
self.external_redirection,
|
||||
))
|
||||
}
|
||||
}
|
||||
@ -97,13 +104,14 @@ pub(crate) fn run_block_on_vec(
|
||||
input: Vec<Value>,
|
||||
block: Arc<Box<CapturedBlock>>,
|
||||
context: Arc<EvaluationContext>,
|
||||
external_redirection: ExternalRedirection,
|
||||
) -> OutputStream {
|
||||
let value = Value {
|
||||
value: UntaggedValue::Table(input),
|
||||
tag: Tag::unknown(),
|
||||
};
|
||||
|
||||
match process_row(block, context, value) {
|
||||
match process_row(block, context, value, external_redirection) {
|
||||
Ok(s) => {
|
||||
// We need to handle this differently depending on whether process_row
|
||||
// returned just 1 value or if it returned multiple as a stream.
|
||||
|
@ -51,6 +51,7 @@ impl WholeStreamCommand for EachWindow {
|
||||
|
||||
fn run_with_actions(&self, raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let context = Arc::new(EvaluationContext::from_args(&raw_args));
|
||||
let external_redirection = raw_args.call_info.args.external_redirection;
|
||||
let (each_args, mut input): (EachWindowArgs, _) = raw_args.process()?;
|
||||
let block = Arc::new(Box::new(each_args.block));
|
||||
|
||||
@ -76,12 +77,17 @@ impl WholeStreamCommand for EachWindow {
|
||||
let local_window = window.clone();
|
||||
|
||||
if i % stride == 0 {
|
||||
Some(run_block_on_vec(local_window, block, context))
|
||||
Some(run_block_on_vec(
|
||||
local_window,
|
||||
block,
|
||||
context,
|
||||
external_redirection,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.filter_map(|x| x)
|
||||
.flatten()
|
||||
.flatten()
|
||||
.to_action_stream())
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ use nu_engine::run_block;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{
|
||||
hir::CapturedBlock, ColumnPath, Primitive, ReturnSuccess, Signature, SyntaxShape,
|
||||
UntaggedValue, Value,
|
||||
hir::CapturedBlock, hir::ExternalRedirection, ColumnPath, Primitive, ReturnSuccess, Signature,
|
||||
SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
|
||||
use crate::utils::arguments::arguments;
|
||||
@ -142,7 +142,12 @@ fn process_row(
|
||||
context.scope.add_vars(&default_block.captured.entries);
|
||||
context.scope.add_var("$it", input.clone());
|
||||
|
||||
let stream = run_block(&default_block.block, &*context, input_stream);
|
||||
let stream = run_block(
|
||||
&default_block.block,
|
||||
&*context,
|
||||
input_stream,
|
||||
ExternalRedirection::Stdout,
|
||||
);
|
||||
context.scope.exit_scope();
|
||||
|
||||
let mut stream = stream?;
|
||||
|
@ -75,16 +75,12 @@ documentation link at https://docs.rs/encoding_rs/0.8.28/encoding_rs/#statics"#
|
||||
}
|
||||
}
|
||||
|
||||
fn enter(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let scope = raw_args.scope.clone();
|
||||
let shell_manager = raw_args.shell_manager.clone();
|
||||
let head = raw_args.call_info.args.head.clone();
|
||||
let ctrl_c = raw_args.ctrl_c.clone();
|
||||
let configs = raw_args.configs.clone();
|
||||
let current_errors = raw_args.current_errors.clone();
|
||||
let host = raw_args.host.clone();
|
||||
let tag = raw_args.call_info.name_tag.clone();
|
||||
let (EnterArgs { location, encoding }, _) = raw_args.process()?;
|
||||
fn enter(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let head = args.call_info.args.head.clone();
|
||||
let context = args.context.clone();
|
||||
let scope = args.scope().clone();
|
||||
let path = args.context.shell_manager.path();
|
||||
let (EnterArgs { location, encoding }, _) = args.process()?;
|
||||
let location_string = location.display().to_string();
|
||||
|
||||
if location.is_dir() {
|
||||
@ -93,7 +89,7 @@ fn enter(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
)))
|
||||
} else {
|
||||
// If it's a file, attempt to open the file as a value and enter it
|
||||
let cwd = shell_manager.path();
|
||||
let cwd = path;
|
||||
|
||||
let full_path = std::path::PathBuf::from(cwd);
|
||||
let span = location.span();
|
||||
@ -110,12 +106,9 @@ fn enter(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
if let Some(extension) = file_extension {
|
||||
let command_name = format!("from {}", extension);
|
||||
if let Some(converter) = scope.get_command(&command_name) {
|
||||
let new_args = RawCommandArgs {
|
||||
host,
|
||||
ctrl_c,
|
||||
configs,
|
||||
current_errors,
|
||||
shell_manager,
|
||||
let tag = tagged_contents.tag.clone();
|
||||
let new_args = CommandArgs {
|
||||
context,
|
||||
call_info: UnevaluatedCallInfo {
|
||||
args: nu_protocol::hir::Call {
|
||||
head,
|
||||
@ -124,13 +117,11 @@ fn enter(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
span: Span::unknown(),
|
||||
external_redirection: ExternalRedirection::Stdout,
|
||||
},
|
||||
name_tag: tag,
|
||||
name_tag: tag.clone(),
|
||||
},
|
||||
scope,
|
||||
input: InputStream::one(tagged_contents),
|
||||
};
|
||||
let tag = tagged_contents.tag.clone();
|
||||
let mut result =
|
||||
converter.run(new_args.with_input(vec![tagged_contents]))?;
|
||||
let mut result = converter.run(new_args)?;
|
||||
let result_vec: Vec<Value> = result.drain_vec();
|
||||
Ok(result_vec
|
||||
.into_iter()
|
||||
|
@ -20,7 +20,7 @@ impl WholeStreamCommand for From {
|
||||
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
Ok(OutputStream::one(
|
||||
UntaggedValue::string(get_full_help(&From, &args.scope)).into_value(Tag::unknown()),
|
||||
UntaggedValue::string(get_full_help(&From, args.scope())).into_value(Tag::unknown()),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -228,8 +228,8 @@ pub fn get_column_from_row_error(
|
||||
} => {
|
||||
let primary_label = format!("There isn't a column named '{}'", &column);
|
||||
|
||||
if let Some(suggestions) = did_you_mean(&obj_source, column_path_tried.as_string()) {
|
||||
Some(ShellError::labeled_error_with_secondary(
|
||||
did_you_mean(&obj_source, column_path_tried.as_string()).map(|suggestions| {
|
||||
ShellError::labeled_error_with_secondary(
|
||||
"Unknown column",
|
||||
primary_label,
|
||||
column_path_tried.span,
|
||||
@ -239,10 +239,8 @@ pub fn get_column_from_row_error(
|
||||
&obj_source.data_descriptors().join(", ")
|
||||
),
|
||||
column_path_tried.span.since(path_members_span),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
PathMember {
|
||||
unspanned: UnspannedPathMember::Int(idx),
|
||||
|
@ -2,6 +2,7 @@ use crate::prelude::*;
|
||||
use crate::utils::suggestions::suggestions;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::hir::ExternalRedirection;
|
||||
use nu_protocol::{Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use nu_source::Tagged;
|
||||
use nu_value_ext::as_string;
|
||||
@ -148,7 +149,12 @@ pub fn group_by(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let run = block.clone();
|
||||
let context = context.clone();
|
||||
|
||||
match crate::commands::each::process_row(run, context, value.clone()) {
|
||||
match crate::commands::each::process_row(
|
||||
run,
|
||||
context,
|
||||
value.clone(),
|
||||
ExternalRedirection::Stdout,
|
||||
) {
|
||||
Ok(mut s) => {
|
||||
let collection: Vec<Value> = s.drain_vec();
|
||||
|
||||
|
@ -23,7 +23,7 @@ impl WholeStreamCommand for Command {
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
Ok(ActionStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::string(get_full_help(&Command, &args.scope)).into_value(Tag::unknown()),
|
||||
UntaggedValue::string(get_full_help(&Command, args.scope())).into_value(Tag::unknown()),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ impl WholeStreamCommand for Help {
|
||||
|
||||
fn help(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let name = args.call_info.name_tag.clone();
|
||||
let scope = args.scope.clone();
|
||||
let scope = args.scope().clone();
|
||||
let (HelpArgs { rest }, ..) = args.process()?;
|
||||
|
||||
if !rest.is_empty() {
|
||||
|
@ -76,10 +76,10 @@ pub fn histogram(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
};
|
||||
|
||||
let column_grouper = if !columns.is_empty() {
|
||||
match columns.remove(0).split_last() {
|
||||
Some((key, _)) => Some(key.as_string().tagged(&name)),
|
||||
None => None,
|
||||
}
|
||||
columns
|
||||
.remove(0)
|
||||
.split_last()
|
||||
.map(|(key, _)| key.as_string().tagged(&name))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -59,6 +59,7 @@ impl WholeStreamCommand for If {
|
||||
}
|
||||
fn if_command(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let tag = raw_args.call_info.name_tag.clone();
|
||||
let external_redirection = raw_args.call_info.args.external_redirection;
|
||||
let context = Arc::new(EvaluationContext::from_args(&raw_args));
|
||||
|
||||
let args = raw_args.evaluate_once()?;
|
||||
@ -105,9 +106,9 @@ fn if_command(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
Ok(condition) => match condition.as_bool() {
|
||||
Ok(b) => {
|
||||
let result = if b {
|
||||
run_block(&then_case.block, &*context, input)
|
||||
run_block(&then_case.block, &*context, input, external_redirection)
|
||||
} else {
|
||||
run_block(&else_case.block, &*context, input)
|
||||
run_block(&else_case.block, &*context, input, external_redirection)
|
||||
};
|
||||
context.scope.exit_scope();
|
||||
|
||||
|
@ -2,6 +2,7 @@ use crate::prelude::*;
|
||||
use nu_engine::run_block;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::hir::ExternalRedirection;
|
||||
use nu_protocol::{
|
||||
ColumnPath, Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
@ -81,7 +82,12 @@ fn process_row(
|
||||
context.scope.add_vars(&block.captured.entries);
|
||||
context.scope.add_var("$it", input.clone());
|
||||
|
||||
let result = run_block(&block.block, &*context, input_stream);
|
||||
let result = run_block(
|
||||
&block.block,
|
||||
&*context,
|
||||
input_stream,
|
||||
ExternalRedirection::Stdout,
|
||||
);
|
||||
|
||||
context.scope.exit_scope();
|
||||
|
||||
|
269
crates/nu-command/src/commands/into/binary.rs
Normal file
269
crates/nu-command/src/commands/into/binary.rs
Normal file
@ -0,0 +1,269 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{
|
||||
ColumnPath, Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
use num_bigint::{BigInt, ToBigInt};
|
||||
|
||||
pub struct SubCommand;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Arguments {
|
||||
pub rest: Vec<ColumnPath>,
|
||||
pub skip: Option<Value>,
|
||||
pub bytes: Option<Value>,
|
||||
}
|
||||
|
||||
impl WholeStreamCommand for SubCommand {
|
||||
fn name(&self) -> &str {
|
||||
"into binary"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("into binary")
|
||||
.rest(
|
||||
SyntaxShape::ColumnPath,
|
||||
"column paths to convert to binary (for table input)",
|
||||
)
|
||||
.named(
|
||||
"skip",
|
||||
SyntaxShape::Int,
|
||||
"skip x number of bytes",
|
||||
Some('s'),
|
||||
)
|
||||
.named(
|
||||
"bytes",
|
||||
SyntaxShape::Int,
|
||||
"show y number of bytes",
|
||||
Some('b'),
|
||||
)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Convert value to a binary primitive"
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
into_binary(args)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
description: "convert string to a nushell binary primitive",
|
||||
example:
|
||||
"echo 'This is a string that is exactly 52 characters long.' | into binary",
|
||||
result: Some(vec![UntaggedValue::binary(
|
||||
"This is a string that is exactly 52 characters long."
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
)
|
||||
.into()]),
|
||||
},
|
||||
Example {
|
||||
description: "convert string to a nushell binary primitive",
|
||||
example:
|
||||
"echo 'This is a string that is exactly 52 characters long.' | into binary --skip 10",
|
||||
result: Some(vec![UntaggedValue::binary(
|
||||
"string that is exactly 52 characters long."
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
)
|
||||
.into()]),
|
||||
},
|
||||
Example {
|
||||
description: "convert string to a nushell binary primitive",
|
||||
example:
|
||||
"echo 'This is a string that is exactly 52 characters long.' | into binary --skip 10 --bytes 10",
|
||||
result: Some(vec![UntaggedValue::binary(
|
||||
"string tha"
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
)
|
||||
.into()]),
|
||||
},
|
||||
Example {
|
||||
description: "convert a number to a nushell binary primitive",
|
||||
example: "echo 1 | into binary",
|
||||
result: Some(vec![
|
||||
UntaggedValue::binary(BigInt::from(1).to_bytes_le().1).into()
|
||||
]),
|
||||
},
|
||||
Example {
|
||||
description: "convert a boolean to a nushell binary primitive",
|
||||
example: "echo $true | into binary",
|
||||
result: Some(vec![
|
||||
UntaggedValue::binary(BigInt::from(1).to_bytes_le().1).into()
|
||||
]),
|
||||
},
|
||||
Example {
|
||||
description: "convert a filesize to a nushell binary primitive",
|
||||
example: "ls | where name == LICENSE | get size | into binary",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "convert a filepath to a nushell binary primitive",
|
||||
example: "ls | where name == LICENSE | get name | path expand | into binary",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "convert a decimal to a nushell binary primitive",
|
||||
example: "echo 1.234 | into binary",
|
||||
result: Some(vec![
|
||||
UntaggedValue::binary(BigInt::from(1).to_bytes_le().1).into()
|
||||
]),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
fn into_binary(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let (
|
||||
Arguments {
|
||||
rest: column_paths,
|
||||
skip,
|
||||
bytes,
|
||||
},
|
||||
input,
|
||||
) = args.process()?;
|
||||
|
||||
Ok(input
|
||||
.map(move |v| {
|
||||
if column_paths.is_empty() {
|
||||
ReturnSuccess::value(action(&v, v.tag(), &skip, &bytes)?)
|
||||
} else {
|
||||
let mut ret = v;
|
||||
for path in &column_paths {
|
||||
let skip_clone = skip.clone();
|
||||
let bytes_clone = bytes.clone();
|
||||
ret = ret.swap_data_by_column_path(
|
||||
path,
|
||||
Box::new(move |old| action(old, old.tag(), &skip_clone, &bytes_clone)),
|
||||
)?;
|
||||
}
|
||||
|
||||
ReturnSuccess::value(ret)
|
||||
}
|
||||
})
|
||||
.to_action_stream())
|
||||
}
|
||||
|
||||
pub fn bigint_to_endian(n: &BigInt) -> Vec<u8> {
|
||||
if cfg!(target_endian = "little") {
|
||||
// eprintln!("Little Endian");
|
||||
n.to_bytes_le().1
|
||||
} else {
|
||||
// eprintln!("Big Endian");
|
||||
n.to_bytes_be().1
|
||||
}
|
||||
}
|
||||
|
||||
pub fn action(
|
||||
input: &Value,
|
||||
tag: impl Into<Tag>,
|
||||
skip: &Option<Value>,
|
||||
bytes: &Option<Value>,
|
||||
) -> Result<Value, ShellError> {
|
||||
let tag = tag.into();
|
||||
let skip_bytes = match skip {
|
||||
Some(s) => s.as_usize().unwrap_or(0),
|
||||
None => 0usize,
|
||||
};
|
||||
|
||||
let num_bytes = match bytes {
|
||||
Some(b) => b.as_usize().unwrap_or(0),
|
||||
None => 0usize,
|
||||
};
|
||||
|
||||
match &input.value {
|
||||
UntaggedValue::Primitive(prim) => Ok(UntaggedValue::binary(match prim {
|
||||
Primitive::Binary(b) => {
|
||||
if num_bytes == 0usize {
|
||||
b.to_vec().into_iter().skip(skip_bytes).collect()
|
||||
} else {
|
||||
b.to_vec()
|
||||
.into_iter()
|
||||
.skip(skip_bytes)
|
||||
.take(num_bytes)
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
Primitive::Int(n_ref) => bigint_to_endian(n_ref),
|
||||
Primitive::Decimal(dec) => match dec.to_bigint() {
|
||||
Some(n) => bigint_to_endian(&n),
|
||||
None => {
|
||||
return Err(ShellError::unimplemented(
|
||||
"failed to convert decimal to int",
|
||||
));
|
||||
}
|
||||
},
|
||||
Primitive::Filesize(a_filesize) => match a_filesize.to_bigint() {
|
||||
Some(n) => bigint_to_endian(&n),
|
||||
None => {
|
||||
return Err(ShellError::unimplemented(
|
||||
"failed to convert filesize to bigint",
|
||||
));
|
||||
}
|
||||
},
|
||||
Primitive::String(a_string) => {
|
||||
// a_string.as_bytes().to_vec()
|
||||
if num_bytes == 0usize {
|
||||
a_string
|
||||
.as_bytes()
|
||||
.to_vec()
|
||||
.into_iter()
|
||||
.skip(skip_bytes)
|
||||
.collect()
|
||||
} else {
|
||||
a_string
|
||||
.as_bytes()
|
||||
.to_vec()
|
||||
.into_iter()
|
||||
.skip(skip_bytes)
|
||||
.take(num_bytes)
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
Primitive::Boolean(a_bool) => match a_bool {
|
||||
false => bigint_to_endian(&BigInt::from(0)),
|
||||
true => bigint_to_endian(&BigInt::from(1)),
|
||||
},
|
||||
Primitive::Date(a_date) => a_date.format("%c").to_string().as_bytes().to_vec(),
|
||||
Primitive::FilePath(a_filepath) => a_filepath
|
||||
.as_path()
|
||||
.display()
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
_ => {
|
||||
return Err(ShellError::unimplemented(
|
||||
"'into int' for non-numeric primitives",
|
||||
))
|
||||
}
|
||||
})
|
||||
.into_value(&tag)),
|
||||
UntaggedValue::Row(_) => Err(ShellError::labeled_error(
|
||||
"specify column name to use, with 'into int COLUMN'",
|
||||
"found table",
|
||||
tag,
|
||||
)),
|
||||
_ => Err(ShellError::unimplemented("'into int' for unsupported type")),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::ShellError;
|
||||
use super::SubCommand;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
use crate::examples::test as test_examples;
|
||||
|
||||
test_examples(SubCommand {})
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@ impl WholeStreamCommand for Command {
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
Ok(ActionStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::string(get_full_help(&Command, &args.scope)).into_value(Tag::unknown()),
|
||||
UntaggedValue::string(get_full_help(&Command, args.scope())).into_value(Tag::unknown()),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
mod binary;
|
||||
mod command;
|
||||
mod int;
|
||||
mod string;
|
||||
|
||||
pub use binary::SubCommand as IntoBinary;
|
||||
pub use command::Command as Into;
|
||||
pub use int::SubCommand as IntoInt;
|
||||
pub use string::SubCommand as IntoString;
|
||||
|
266
crates/nu-command/src/commands/into/string.rs
Normal file
266
crates/nu-command/src/commands/into/string.rs
Normal file
@ -0,0 +1,266 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{
|
||||
ColumnPath, Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
use nu_source::Tagged;
|
||||
use num_bigint::{BigInt, BigUint, ToBigInt};
|
||||
// TODO num_format::SystemLocale once platform-specific dependencies are stable (see Cargo.toml)
|
||||
use nu_data::base::shape::InlineShape;
|
||||
use num_format::Locale;
|
||||
use num_traits::{Pow, Signed};
|
||||
use std::iter;
|
||||
|
||||
pub struct SubCommand;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Arguments {
|
||||
decimals: Option<Tagged<u64>>,
|
||||
group_digits: bool,
|
||||
column_paths: Vec<ColumnPath>,
|
||||
}
|
||||
|
||||
impl WholeStreamCommand for SubCommand {
|
||||
fn name(&self) -> &str {
|
||||
"into string"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("into string")
|
||||
.rest(
|
||||
SyntaxShape::ColumnPath,
|
||||
"column paths to convert to string (for table input)",
|
||||
)
|
||||
.named(
|
||||
"decimals",
|
||||
SyntaxShape::Int,
|
||||
"decimal digits to which to round",
|
||||
Some('d'),
|
||||
)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Convert value to string"
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
into_string(args)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
description: "convert decimal to string and round to nearest integer",
|
||||
example: "echo 1.7 | into string -d 0",
|
||||
result: Some(vec![UntaggedValue::string("2").into_untagged_value()]),
|
||||
},
|
||||
Example {
|
||||
description: "convert decimal to string",
|
||||
example: "echo 4.3 | into string",
|
||||
result: Some(vec![UntaggedValue::string("4.3").into_untagged_value()]),
|
||||
},
|
||||
Example {
|
||||
description: "convert string to string",
|
||||
example: "echo '1234' | into string",
|
||||
result: Some(vec![UntaggedValue::string("1234").into_untagged_value()]),
|
||||
},
|
||||
Example {
|
||||
description: "convert boolean to string",
|
||||
example: "echo $true | into string",
|
||||
result: Some(vec![UntaggedValue::string("true").into_untagged_value()]),
|
||||
},
|
||||
Example {
|
||||
description: "convert date to string",
|
||||
example: "date now | into string",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "convert filepath to string",
|
||||
example: "ls Cargo.toml | get name | into string",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "convert filesize to string",
|
||||
example: "ls Cargo.toml | get size | into string",
|
||||
result: None,
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
fn into_string(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let (options, input) = args.extract(|params| {
|
||||
Ok(Arguments {
|
||||
decimals: params.get_flag("decimals")?,
|
||||
group_digits: false,
|
||||
column_paths: params.rest_args()?,
|
||||
})
|
||||
})?;
|
||||
|
||||
let digits = options.decimals.as_ref().map(|tagged| tagged.item);
|
||||
let group_digits = options.group_digits;
|
||||
|
||||
Ok(input
|
||||
.map(move |v| {
|
||||
if options.column_paths.is_empty() {
|
||||
ReturnSuccess::value(action(&v, v.tag(), digits, group_digits)?)
|
||||
} else {
|
||||
let mut ret = v;
|
||||
for path in &options.column_paths {
|
||||
ret = ret.swap_data_by_column_path(
|
||||
path,
|
||||
Box::new(move |old| action(old, old.tag(), digits, group_digits)),
|
||||
)?;
|
||||
}
|
||||
|
||||
ReturnSuccess::value(ret)
|
||||
}
|
||||
})
|
||||
.to_action_stream())
|
||||
}
|
||||
|
||||
pub fn action(
|
||||
input: &Value,
|
||||
tag: impl Into<Tag>,
|
||||
digits: Option<u64>,
|
||||
group_digits: bool,
|
||||
) -> Result<Value, ShellError> {
|
||||
match &input.value {
|
||||
UntaggedValue::Primitive(prim) => Ok(UntaggedValue::string(match prim {
|
||||
Primitive::Int(int) => {
|
||||
if group_digits {
|
||||
format_bigint(int) // int.to_formatted_string(*locale)
|
||||
} else {
|
||||
int.to_string()
|
||||
}
|
||||
}
|
||||
Primitive::Decimal(dec) => format_decimal(dec.clone(), digits, group_digits),
|
||||
Primitive::String(a_string) => a_string.to_string(),
|
||||
Primitive::Boolean(a_bool) => a_bool.to_string(),
|
||||
Primitive::Date(a_date) => a_date.format("%c").to_string(),
|
||||
Primitive::FilePath(a_filepath) => a_filepath.as_path().display().to_string(),
|
||||
Primitive::Filesize(a_filesize) => {
|
||||
let byte_string = InlineShape::format_bytes(a_filesize, None);
|
||||
byte_string.1
|
||||
}
|
||||
_ => {
|
||||
return Err(ShellError::unimplemented(
|
||||
"str from for non-numeric primitives",
|
||||
))
|
||||
}
|
||||
})
|
||||
.into_value(tag)),
|
||||
UntaggedValue::Row(_) => Err(ShellError::labeled_error(
|
||||
"specify column to use 'str from'",
|
||||
"found table",
|
||||
input.tag.clone(),
|
||||
)),
|
||||
_ => Err(ShellError::unimplemented(
|
||||
"str from for non-primitive, non-table types",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn format_bigint(int: &BigInt) -> String {
|
||||
format!("{}", int)
|
||||
|
||||
// TODO once platform-specific dependencies are stable (see Cargo.toml)
|
||||
// #[cfg(windows)]
|
||||
// {
|
||||
// int.to_formatted_string(&Locale::en)
|
||||
// }
|
||||
// #[cfg(not(windows))]
|
||||
// {
|
||||
// match SystemLocale::default() {
|
||||
// Ok(locale) => int.to_formatted_string(&locale),
|
||||
// Err(_) => int.to_formatted_string(&Locale::en),
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
fn format_decimal(mut decimal: BigDecimal, digits: Option<u64>, group_digits: bool) -> String {
|
||||
if let Some(n) = digits {
|
||||
decimal = round_decimal(&decimal, n)
|
||||
}
|
||||
|
||||
if decimal.is_integer() && (digits.is_none() || digits == Some(0)) {
|
||||
let int = decimal
|
||||
.to_bigint()
|
||||
.expect("integer BigDecimal should convert to BigInt");
|
||||
return if group_digits {
|
||||
int.to_string()
|
||||
} else {
|
||||
format_bigint(&int)
|
||||
};
|
||||
}
|
||||
|
||||
let (int, exp) = decimal.as_bigint_and_exponent();
|
||||
let factor = BigInt::from(10).pow(BigUint::from(exp as u64)); // exp > 0 for non-int decimal
|
||||
let int_part = &int / &factor;
|
||||
let dec_part = (&int % &factor)
|
||||
.abs()
|
||||
.to_biguint()
|
||||
.expect("BigInt::abs should always produce positive signed BigInt and thus BigUInt")
|
||||
.to_str_radix(10);
|
||||
|
||||
let dec_str = if let Some(n) = digits {
|
||||
dec_part
|
||||
.chars()
|
||||
.chain(iter::repeat('0'))
|
||||
.take(n as usize)
|
||||
.collect()
|
||||
} else {
|
||||
String::from(dec_part.trim_end_matches('0'))
|
||||
};
|
||||
|
||||
let format_default_loc = |int_part: BigInt| {
|
||||
let loc = Locale::en;
|
||||
//TODO: when num_format is available for recent bigint, replace this with the locale-based format
|
||||
let (int_str, sep) = (format!("{}", int_part), String::from(loc.decimal()));
|
||||
|
||||
format!("{}{}{}", int_str, sep, dec_str)
|
||||
};
|
||||
|
||||
format_default_loc(int_part)
|
||||
|
||||
// TODO once platform-specific dependencies are stable (see Cargo.toml)
|
||||
// #[cfg(windows)]
|
||||
// {
|
||||
// format_default_loc(int_part)
|
||||
// }
|
||||
// #[cfg(not(windows))]
|
||||
// {
|
||||
// match SystemLocale::default() {
|
||||
// Ok(sys_loc) => {
|
||||
// let int_str = int_part.to_formatted_string(&sys_loc);
|
||||
// let sep = String::from(sys_loc.decimal());
|
||||
// format!("{}{}{}", int_str, sep, dec_str)
|
||||
// }
|
||||
// Err(_) => format_default_loc(int_part),
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
fn round_decimal(decimal: &BigDecimal, mut digits: u64) -> BigDecimal {
|
||||
let mut mag = decimal.clone();
|
||||
while mag >= BigDecimal::from(1) {
|
||||
mag = mag / 10;
|
||||
digits += 1;
|
||||
}
|
||||
|
||||
decimal.with_prec(digits)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::ShellError;
|
||||
use super::SubCommand;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
use crate::examples::test as test_examples;
|
||||
|
||||
test_examples(SubCommand {})
|
||||
}
|
||||
}
|
@ -41,8 +41,8 @@ impl WholeStreamCommand for Ls {
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let name = args.call_info.name_tag.clone();
|
||||
let ctrl_c = args.ctrl_c.clone();
|
||||
let shell_manager = args.shell_manager.clone();
|
||||
let ctrl_c = args.ctrl_c();
|
||||
let shell_manager = args.shell_manager();
|
||||
let (args, _) = args.process()?;
|
||||
shell_manager.ls(args, name, ctrl_c)
|
||||
}
|
||||
|
@ -1,352 +1,351 @@
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! command {
|
||||
(
|
||||
Named { $export:tt $args:ident $body:block }
|
||||
Positional { $($number:tt)* }
|
||||
Rest {}
|
||||
Signature {
|
||||
name: $config_name:tt,
|
||||
mandatory_positional: vec![ $($mandatory_positional:tt)* ],
|
||||
optional_positional: vec![ $($optional_positional:tt)* ],
|
||||
rest_positional: $rest_positional:tt,
|
||||
named: {
|
||||
$(
|
||||
($named_param:tt : $named_type:ty : $named_kind:tt)
|
||||
)*
|
||||
}
|
||||
}
|
||||
// #[doc(hidden)]
|
||||
// #[macro_export]
|
||||
// macro_rules! command {
|
||||
// (
|
||||
// Named { $export:tt $args:ident $body:block }
|
||||
// Positional { $($number:tt)* }
|
||||
// Rest {}
|
||||
// Signature {
|
||||
// name: $config_name:tt,
|
||||
// mandatory_positional: vec![ $($mandatory_positional:tt)* ],
|
||||
// optional_positional: vec![ $($optional_positional:tt)* ],
|
||||
// rest_positional: $rest_positional:tt,
|
||||
// named: {
|
||||
// $(
|
||||
// ($named_param:tt : $named_type:ty : $named_kind:tt)
|
||||
// )*
|
||||
// }
|
||||
// }
|
||||
|
||||
Function {
|
||||
$( ( $param_name:tt : $param_type:tt ) )*
|
||||
}
|
||||
// Function {
|
||||
// $( ( $param_name:tt : $param_type:tt ) )*
|
||||
// }
|
||||
|
||||
Extract {
|
||||
$($extract:tt)*
|
||||
}
|
||||
) => {
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct $export;
|
||||
// Extract {
|
||||
// $($extract:tt)*
|
||||
// }
|
||||
// ) => {
|
||||
// #[allow(non_camel_case_types)]
|
||||
// pub struct $export;
|
||||
|
||||
impl Command for $export {
|
||||
fn run(&self, $args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
fn command($args: EvaluatedCommandArgs, ( $($param_name),*, ): ( $($param_type),*, )) -> Result<OutputStream, ShellError> {
|
||||
let output = $body;
|
||||
// impl Command for $export {
|
||||
// fn run(&self, $args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
// fn command($args: EvaluatedCommandArgs, ( $($param_name),*, ): ( $($param_type),*, )) -> Result<OutputStream, ShellError> {
|
||||
// let output = $body;
|
||||
|
||||
Ok(output.to_action_stream())
|
||||
}
|
||||
// Ok(output.to_action_stream())
|
||||
// }
|
||||
|
||||
let $args = $args.evaluate_once(registry)?;
|
||||
let tuple = ( $($extract ,)* );
|
||||
command( $args, tuple )
|
||||
}
|
||||
// let $args = $args.evaluate_once(registry)?;
|
||||
// let tuple = ( $($extract ,)* );
|
||||
// command( $args, tuple )
|
||||
// }
|
||||
|
||||
fn name(&self) -> &str {
|
||||
stringify!($config_name)
|
||||
}
|
||||
// fn name(&self) -> &str {
|
||||
// stringify!($config_name)
|
||||
// }
|
||||
|
||||
fn config(&self) -> $nu_parser::registry::Signature {
|
||||
$nu_parser::registry::Signature {
|
||||
name: self.name().to_string(),
|
||||
positional: vec![$($mandatory_positional)*],
|
||||
rest_positional: false,
|
||||
is_filter: false,
|
||||
is_sink: false,
|
||||
// fn config(&self) -> $nu_parser::registry::Signature {
|
||||
// $nu_parser::registry::Signature {
|
||||
// name: self.name().to_string(),
|
||||
// positional: vec![$($mandatory_positional)*],
|
||||
// rest_positional: false,
|
||||
// is_filter: false,
|
||||
// is_sink: false,
|
||||
|
||||
named: {
|
||||
use $nu_parser::registry::NamedType;
|
||||
// named: {
|
||||
// use $nu_parser::registry::NamedType;
|
||||
|
||||
#[allow(unused_mut)]
|
||||
let mut named: indexmap::IndexMap<String, NamedType> = indexmap::IndexMap::new();
|
||||
// #[allow(unused_mut)]
|
||||
// let mut named: indexmap::IndexMap<String, NamedType> = indexmap::IndexMap::new();
|
||||
|
||||
$(
|
||||
named.insert(stringify!($named_param).to_string(), $nu_parser::registry::NamedType::$named_kind);
|
||||
)*
|
||||
// $(
|
||||
// named.insert(stringify!($named_param).to_string(), $nu_parser::registry::NamedType::$named_kind);
|
||||
// )*
|
||||
|
||||
named
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
// named
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
// switch
|
||||
(
|
||||
Named { $export:tt $args:ident $body:block }
|
||||
Positional { $($positional_count:tt)* }
|
||||
Rest { -- $param_name:ident : Switch , $($rest:tt)* }
|
||||
Signature {
|
||||
name: $config_name:tt,
|
||||
mandatory_positional: vec![ $($mandatory_positional:tt)* ],
|
||||
optional_positional: vec![ $($optional_positional:tt)* ],
|
||||
rest_positional: $rest_positional:tt,
|
||||
named: {
|
||||
$($config_named:tt)*
|
||||
}
|
||||
}
|
||||
Function {
|
||||
$($function:tt)*
|
||||
}
|
||||
Extract {
|
||||
$($extract:tt)*
|
||||
}
|
||||
) => {
|
||||
command!(
|
||||
Named { $export $args $body }
|
||||
Positional { $($positional_count)* + 1 }
|
||||
Rest { $($rest)* }
|
||||
Signature {
|
||||
name: $config_name,
|
||||
mandatory_positional: vec![ $($mandatory_positional)* ],
|
||||
optional_positional: vec![ $($optional_positional)* ],
|
||||
rest_positional: $rest_positional,
|
||||
named: {
|
||||
$($config_named)*
|
||||
($param_name : Switch : Switch)
|
||||
}
|
||||
}
|
||||
// // switch
|
||||
// (
|
||||
// Named { $export:tt $args:ident $body:block }
|
||||
// Positional { $($positional_count:tt)* }
|
||||
// Rest { -- $param_name:ident : Switch , $($rest:tt)* }
|
||||
// Signature {
|
||||
// name: $config_name:tt,
|
||||
// mandatory_positional: vec![ $($mandatory_positional:tt)* ],
|
||||
// optional_positional: vec![ $($optional_positional:tt)* ],
|
||||
// rest_positional: $rest_positional:tt,
|
||||
// named: {
|
||||
// $($config_named:tt)*
|
||||
// }
|
||||
// }
|
||||
// Function {
|
||||
// $($function:tt)*
|
||||
// }
|
||||
// Extract {
|
||||
// $($extract:tt)*
|
||||
// }
|
||||
// ) => {
|
||||
// command!(
|
||||
// Named { $export $args $body }
|
||||
// Positional { $($positional_count)* + 1 }
|
||||
// Rest { $($rest)* }
|
||||
// Signature {
|
||||
// name: $config_name,
|
||||
// mandatory_positional: vec![ $($mandatory_positional)* ],
|
||||
// optional_positional: vec![ $($optional_positional)* ],
|
||||
// rest_positional: $rest_positional,
|
||||
// named: {
|
||||
// $($config_named)*
|
||||
// ($param_name : Switch : Switch)
|
||||
// }
|
||||
// }
|
||||
|
||||
Function {
|
||||
$($function)* ($param_name : Switch)
|
||||
}
|
||||
// Function {
|
||||
// $($function)* ($param_name : Switch)
|
||||
// }
|
||||
|
||||
Extract {
|
||||
$($extract)* {
|
||||
use std::convert::TryInto;
|
||||
// Extract {
|
||||
// $($extract)* {
|
||||
// use std::convert::TryInto;
|
||||
|
||||
$args.get(stringify!($param_name)).try_into()?
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
// $args.get(stringify!($param_name)).try_into()?
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
// };
|
||||
|
||||
// mandatory named arguments
|
||||
(
|
||||
Named { $export:tt $args:ident $body:block }
|
||||
Positional { $($positional_count:tt)* }
|
||||
Rest { -- $param_name:ident : $param_kind:ty , $($rest:tt)* }
|
||||
Signature {
|
||||
name: $config_name:tt,
|
||||
mandatory_positional: vec![ $($mandatory_positional:tt)* ],
|
||||
optional_positional: vec![ $($optional_positional:tt)* ],
|
||||
rest_positional: $rest_positional:tt,
|
||||
named: {
|
||||
$($config_named:tt)*
|
||||
}
|
||||
}
|
||||
Function {
|
||||
$($function:tt)*
|
||||
}
|
||||
Extract {
|
||||
$($extract:tt)*
|
||||
}
|
||||
) => {
|
||||
command!(
|
||||
Named { $export $args $body }
|
||||
Positional { $($positional_count)* + 1 }
|
||||
Rest { $($rest)* }
|
||||
Signature {
|
||||
name: $config_name,
|
||||
mandatory_positional: vec![ $($mandatory_positional)* ],
|
||||
optional_positional: vec![ $($optional_positional)* ],
|
||||
rest_positional: $rest_positional,
|
||||
named: {
|
||||
$($config_named)*
|
||||
($param_name : Mandatory(NamedValue::Single))
|
||||
}
|
||||
}
|
||||
// // mandatory named arguments
|
||||
// (
|
||||
// Named { $export:tt $args:ident $body:block }
|
||||
// Positional { $($positional_count:tt)* }
|
||||
// Rest { -- $param_name:ident : $param_kind:ty , $($rest:tt)* }
|
||||
// Signature {
|
||||
// name: $config_name:tt,
|
||||
// mandatory_positional: vec![ $($mandatory_positional:tt)* ],
|
||||
// optional_positional: vec![ $($optional_positional:tt)* ],
|
||||
// rest_positional: $rest_positional:tt,
|
||||
// named: {
|
||||
// $($config_named:tt)*
|
||||
// }
|
||||
// }
|
||||
// Function {
|
||||
// $($function:tt)*
|
||||
// }
|
||||
// Extract {
|
||||
// $($extract:tt)*
|
||||
// }
|
||||
// ) => {
|
||||
// command!(
|
||||
// Named { $export $args $body }
|
||||
// Positional { $($positional_count)* + 1 }
|
||||
// Rest { $($rest)* }
|
||||
// Signature {
|
||||
// name: $config_name,
|
||||
// mandatory_positional: vec![ $($mandatory_positional)* ],
|
||||
// optional_positional: vec![ $($optional_positional)* ],
|
||||
// rest_positional: $rest_positional,
|
||||
// named: {
|
||||
// $($config_named)*
|
||||
// ($param_name : Mandatory(NamedValue::Single))
|
||||
// }
|
||||
// }
|
||||
|
||||
Function {
|
||||
$($function)* ($param_name : $param_kind)
|
||||
}
|
||||
// Function {
|
||||
// $($function)* ($param_name : $param_kind)
|
||||
// }
|
||||
|
||||
Extract {
|
||||
$($extract)* {
|
||||
use std::convert::TryInto;
|
||||
// Extract {
|
||||
// $($extract)* {
|
||||
// use std::convert::TryInto;
|
||||
|
||||
$args.get(stringify!($param_name)).try_into()?
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
// $args.get(stringify!($param_name)).try_into()?
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
// };
|
||||
|
||||
// optional named arguments
|
||||
(
|
||||
Named { $export:tt $args:ident $body:block }
|
||||
Positional { $($positional_count:tt)* }
|
||||
Rest { -- $param_name:ident ? : $param_kind:ty , $($rest:tt)* }
|
||||
Signature {
|
||||
name: $config_name:tt,
|
||||
mandatory_positional: vec![ $($mandatory_positional:tt)* ],
|
||||
optional_positional: vec![ $($optional_positional:tt)* ],
|
||||
rest_positional: $rest_positional:tt,
|
||||
named: {
|
||||
$($config_named:tt)*
|
||||
}
|
||||
}
|
||||
Function {
|
||||
$($function:tt)*
|
||||
}
|
||||
Extract {
|
||||
$($extract:tt)*
|
||||
}
|
||||
) => {
|
||||
command!(
|
||||
Named { $export $args $body }
|
||||
Positional { $($positional_count)* + 1 }
|
||||
Rest { $($rest)* }
|
||||
Signature {
|
||||
name: $config_name,
|
||||
mandatory_positional: vec![ $($mandatory_positional)* ],
|
||||
optional_positional: vec![ $($optional_positional)* ],
|
||||
rest_positional: $rest_positional,
|
||||
named: {
|
||||
$($config_named)*
|
||||
($param_name : Optional(NamedValue::Single))
|
||||
}
|
||||
}
|
||||
// // optional named arguments
|
||||
// (
|
||||
// Named { $export:tt $args:ident $body:block }
|
||||
// Positional { $($positional_count:tt)* }
|
||||
// Rest { -- $param_name:ident ? : $param_kind:ty , $($rest:tt)* }
|
||||
// Signature {
|
||||
// name: $config_name:tt,
|
||||
// mandatory_positional: vec![ $($mandatory_positional:tt)* ],
|
||||
// optional_positional: vec![ $($optional_positional:tt)* ],
|
||||
// rest_positional: $rest_positional:tt,
|
||||
// named: {
|
||||
// $($config_named:tt)*
|
||||
// }
|
||||
// }
|
||||
// Function {
|
||||
// $($function:tt)*
|
||||
// }
|
||||
// Extract {
|
||||
// $($extract:tt)*
|
||||
// }
|
||||
// ) => {
|
||||
// command!(
|
||||
// Named { $export $args $body }
|
||||
// Positional { $($positional_count)* + 1 }
|
||||
// Rest { $($rest)* }
|
||||
// Signature {
|
||||
// name: $config_name,
|
||||
// mandatory_positional: vec![ $($mandatory_positional)* ],
|
||||
// optional_positional: vec![ $($optional_positional)* ],
|
||||
// rest_positional: $rest_positional,
|
||||
// named: {
|
||||
// $($config_named)*
|
||||
// ($param_name : Optional(NamedValue::Single))
|
||||
// }
|
||||
// }
|
||||
|
||||
Function {
|
||||
$($function)* ($param_name : $param_kind)
|
||||
}
|
||||
// Function {
|
||||
// $($function)* ($param_name : $param_kind)
|
||||
// }
|
||||
|
||||
Extract {
|
||||
$($extract)* {
|
||||
use std::convert::TryInto;
|
||||
// Extract {
|
||||
// $($extract)* {
|
||||
// use std::convert::TryInto;
|
||||
|
||||
$args.get(stringify!($param_name)).try_into()?
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
// $args.get(stringify!($param_name)).try_into()?
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
// };
|
||||
|
||||
// mandatory positional block
|
||||
(
|
||||
Named { $export:ident $args:ident $body:block }
|
||||
Positional { $($positional_count:tt)* }
|
||||
Rest { $param_name:ident : Block , $($rest:tt)* }
|
||||
Signature {
|
||||
name: $config_name:tt,
|
||||
mandatory_positional: vec![ $($mandatory_positional:tt)* ],
|
||||
optional_positional: vec![ $($optional_positional:tt)* ],
|
||||
rest_positional: $rest_positional:tt,
|
||||
named: {
|
||||
$($config_named:tt)*
|
||||
}
|
||||
}
|
||||
// // mandatory positional block
|
||||
// (
|
||||
// Named { $export:ident $args:ident $body:block }
|
||||
// Positional { $($positional_count:tt)* }
|
||||
// Rest { $param_name:ident : Block , $($rest:tt)* }
|
||||
// Signature {
|
||||
// name: $config_name:tt,
|
||||
// mandatory_positional: vec![ $($mandatory_positional:tt)* ],
|
||||
// optional_positional: vec![ $($optional_positional:tt)* ],
|
||||
// rest_positional: $rest_positional:tt,
|
||||
// named: {
|
||||
// $($config_named:tt)*
|
||||
// }
|
||||
// }
|
||||
|
||||
Function {
|
||||
$($function:tt)*
|
||||
}
|
||||
// Function {
|
||||
// $($function:tt)*
|
||||
// }
|
||||
|
||||
Extract {
|
||||
$($extract:tt)*
|
||||
}
|
||||
// Extract {
|
||||
// $($extract:tt)*
|
||||
// }
|
||||
|
||||
) => {
|
||||
command!(
|
||||
Named { $export $args $body }
|
||||
Positional { $($positional_count)* + 1 }
|
||||
Rest { $($rest)* }
|
||||
Signature {
|
||||
name: $config_name,
|
||||
mandatory_positional: vec![ $($mandatory_positional)* $nu_parser::registry::PositionalType::mandatory_block(
|
||||
stringify!($param_name)
|
||||
), ],
|
||||
optional_positional: vec![ $($optional_positional)* ],
|
||||
rest_positional: $rest_positional,
|
||||
named: {
|
||||
$($config_named)*
|
||||
}
|
||||
}
|
||||
// ) => {
|
||||
// command!(
|
||||
// Named { $export $args $body }
|
||||
// Positional { $($positional_count)* + 1 }
|
||||
// Rest { $($rest)* }
|
||||
// Signature {
|
||||
// name: $config_name,
|
||||
// mandatory_positional: vec![ $($mandatory_positional)* $nu_parser::registry::PositionalType::mandatory_block(
|
||||
// stringify!($param_name)
|
||||
// ), ],
|
||||
// optional_positional: vec![ $($optional_positional)* ],
|
||||
// rest_positional: $rest_positional,
|
||||
// named: {
|
||||
// $($config_named)*
|
||||
// }
|
||||
// }
|
||||
|
||||
Function {
|
||||
$($function)* ($param_name : Block)
|
||||
}
|
||||
// Function {
|
||||
// $($function)* ($param_name : Block)
|
||||
// }
|
||||
|
||||
Extract {
|
||||
$($extract:tt)* {
|
||||
use $nu_data::types::ExtractType;
|
||||
let value = $args.expect_nth($($positional_count)*)?;
|
||||
Block::extract(value)?
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
// Extract {
|
||||
// $($extract:tt)* {
|
||||
// use $nu_data::types::ExtractType;
|
||||
// let value = $args.expect_nth($($positional_count)*)?;
|
||||
// Block::extract(value)?
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
// };
|
||||
|
||||
// // mandatory positional argument
|
||||
// (
|
||||
// Named { $export:ident $args:ident $body:block }
|
||||
// Positional { $($positional_count:tt)* }
|
||||
// Rest { $param_name:ident : $param_kind:ty , $($rest:tt)* }
|
||||
// Signature {
|
||||
// name: $config_name:tt,
|
||||
// mandatory_positional: vec![ $($mandatory_positional:tt)* ],
|
||||
// optional_positional: vec![ $($optional_positional:tt)* ],
|
||||
// rest_positional: $rest_positional:tt,
|
||||
// named: {
|
||||
// $($config_named:tt)*
|
||||
// }
|
||||
// }
|
||||
|
||||
// mandatory positional argument
|
||||
(
|
||||
Named { $export:ident $args:ident $body:block }
|
||||
Positional { $($positional_count:tt)* }
|
||||
Rest { $param_name:ident : $param_kind:ty , $($rest:tt)* }
|
||||
Signature {
|
||||
name: $config_name:tt,
|
||||
mandatory_positional: vec![ $($mandatory_positional:tt)* ],
|
||||
optional_positional: vec![ $($optional_positional:tt)* ],
|
||||
rest_positional: $rest_positional:tt,
|
||||
named: {
|
||||
$($config_named:tt)*
|
||||
}
|
||||
}
|
||||
// Function {
|
||||
// $($function:tt)*
|
||||
// }
|
||||
|
||||
Function {
|
||||
$($function:tt)*
|
||||
}
|
||||
// Extract {
|
||||
// $($extract:tt)*
|
||||
// }
|
||||
|
||||
Extract {
|
||||
$($extract:tt)*
|
||||
}
|
||||
// ) => {
|
||||
// command!(
|
||||
// Named { $export $args $body }
|
||||
// Positional { $($positional_count)* + 1 }
|
||||
// Rest { $($rest)* }
|
||||
// Signature {
|
||||
// name: $config_name,
|
||||
// mandatory_positional: vec![ $($mandatory_positional)* $nu_parser::registry::PositionalType::mandatory(
|
||||
// stringify!($param_name), <$param_kind>::syntax_type()
|
||||
// ), ],
|
||||
// optional_positional: vec![ $($optional_positional)* ],
|
||||
// rest_positional: $rest_positional,
|
||||
// named: {
|
||||
// $($config_named)*
|
||||
// }
|
||||
// }
|
||||
|
||||
) => {
|
||||
command!(
|
||||
Named { $export $args $body }
|
||||
Positional { $($positional_count)* + 1 }
|
||||
Rest { $($rest)* }
|
||||
Signature {
|
||||
name: $config_name,
|
||||
mandatory_positional: vec![ $($mandatory_positional)* $nu_parser::registry::PositionalType::mandatory(
|
||||
stringify!($param_name), <$param_kind>::syntax_type()
|
||||
), ],
|
||||
optional_positional: vec![ $($optional_positional)* ],
|
||||
rest_positional: $rest_positional,
|
||||
named: {
|
||||
$($config_named)*
|
||||
}
|
||||
}
|
||||
// Function {
|
||||
// $($function)* ($param_name : $param_kind)
|
||||
// }
|
||||
|
||||
Function {
|
||||
$($function)* ($param_name : $param_kind)
|
||||
}
|
||||
// Extract {
|
||||
// $($extract:tt)* {
|
||||
// use $nu_data::types::ExtractType;
|
||||
// let value = $args.expect_nth($($positional_count)*)?;
|
||||
// <$param_kind>::extract(&value)?
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
// };
|
||||
|
||||
Extract {
|
||||
$($extract:tt)* {
|
||||
use $nu_data::types::ExtractType;
|
||||
let value = $args.expect_nth($($positional_count)*)?;
|
||||
<$param_kind>::extract(&value)?
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
// ($export:ident as $config_name:tt ( $args:ident , $($command_rest:tt)* ) $body:block) => {
|
||||
// command!(
|
||||
// Named { $export $args $body }
|
||||
// Positional { 0 }
|
||||
// Rest { $($command_rest)* }
|
||||
// Signature {
|
||||
// name: $config_name,
|
||||
// mandatory_positional: vec![],
|
||||
// optional_positional: vec![],
|
||||
// rest_positional: false,
|
||||
// named: {}
|
||||
// }
|
||||
|
||||
($export:ident as $config_name:tt ( $args:ident , $($command_rest:tt)* ) $body:block) => {
|
||||
command!(
|
||||
Named { $export $args $body }
|
||||
Positional { 0 }
|
||||
Rest { $($command_rest)* }
|
||||
Signature {
|
||||
name: $config_name,
|
||||
mandatory_positional: vec![],
|
||||
optional_positional: vec![],
|
||||
rest_positional: false,
|
||||
named: {}
|
||||
}
|
||||
// Function {
|
||||
// }
|
||||
|
||||
Function {
|
||||
}
|
||||
|
||||
Extract {
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
// Extract {
|
||||
// }
|
||||
// );
|
||||
// };
|
||||
// }
|
||||
|
@ -20,7 +20,7 @@ impl WholeStreamCommand for Command {
|
||||
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
Ok(OutputStream::one(
|
||||
UntaggedValue::string(get_full_help(&Command, &args.scope)).into_value(Tag::unknown()),
|
||||
UntaggedValue::string(get_full_help(&Command, args.scope())).into_value(Tag::unknown()),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,8 @@ use nu_engine::WholeStreamCommand;
|
||||
use indexmap::IndexMap;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{
|
||||
hir::CapturedBlock, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
hir::CapturedBlock, hir::ExternalRedirection, ReturnSuccess, Signature, SyntaxShape,
|
||||
UntaggedValue, Value,
|
||||
};
|
||||
pub struct Merge;
|
||||
|
||||
@ -53,7 +54,12 @@ fn merge(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
|
||||
context.scope.enter_scope();
|
||||
context.scope.add_vars(&block.captured.entries);
|
||||
let result = run_block(&block.block, &context, InputStream::empty());
|
||||
let result = run_block(
|
||||
&block.block,
|
||||
&context,
|
||||
InputStream::empty(),
|
||||
ExternalRedirection::Stdout,
|
||||
);
|
||||
context.scope.exit_scope();
|
||||
|
||||
let table: Option<Vec<Value>> = match result {
|
||||
|
@ -37,7 +37,7 @@ impl WholeStreamCommand for Mkdir {
|
||||
|
||||
fn mkdir(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let name = args.call_info.name_tag.clone();
|
||||
let shell_manager = args.shell_manager.clone();
|
||||
let shell_manager = args.shell_manager();
|
||||
let (args, _) = args.process()?;
|
||||
|
||||
shell_manager.mkdir(args, name)
|
||||
|
@ -272,10 +272,7 @@ fn move_after(table: &Value, columns: &[String], from: &ColumnPath) -> Result<Va
|
||||
|
||||
Ok(select_fields(
|
||||
table,
|
||||
&reordered_columns
|
||||
.into_iter()
|
||||
.filter_map(|v| v)
|
||||
.collect::<Vec<_>>(),
|
||||
&reordered_columns.into_iter().flatten().collect::<Vec<_>>(),
|
||||
&table.tag,
|
||||
))
|
||||
}
|
||||
@ -321,10 +318,7 @@ fn move_before(table: &Value, columns: &[String], from: &ColumnPath) -> Result<V
|
||||
|
||||
Ok(select_fields(
|
||||
table,
|
||||
&reordered_columns
|
||||
.into_iter()
|
||||
.filter_map(|v| v)
|
||||
.collect::<Vec<_>>(),
|
||||
&reordered_columns.into_iter().flatten().collect::<Vec<_>>(),
|
||||
&table.tag,
|
||||
))
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ impl WholeStreamCommand for Mv {
|
||||
|
||||
fn mv(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let name = args.call_info.name_tag.clone();
|
||||
let shell_manager = args.shell_manager.clone();
|
||||
let shell_manager = args.shell_manager();
|
||||
let (args, _) = args.process()?;
|
||||
|
||||
shell_manager.mv(args, name)
|
||||
|
@ -46,8 +46,8 @@ impl WholeStreamCommand for SubCommand {
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let scope = args.scope.clone();
|
||||
let shell_manager = args.shell_manager.clone();
|
||||
let scope = args.scope().clone();
|
||||
let shell_manager = args.shell_manager();
|
||||
let (Arguments { load_path }, _) = args.process()?;
|
||||
|
||||
if let Some(Tagged {
|
||||
|
@ -100,11 +100,11 @@ pub fn get_encoding(opt: Option<Tagged<String>>) -> Result<&'static Encoding, Sh
|
||||
}
|
||||
|
||||
fn open(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let scope = args.scope.clone();
|
||||
let cwd = PathBuf::from(args.shell_manager.path());
|
||||
let shell_manager = args.shell_manager.clone();
|
||||
let scope = args.scope().clone();
|
||||
let shell_manager = args.shell_manager();
|
||||
let cwd = PathBuf::from(shell_manager.path());
|
||||
let name = args.call_info.name_tag.clone();
|
||||
let ctrl_c = args.ctrl_c.clone();
|
||||
let ctrl_c = args.ctrl_c();
|
||||
|
||||
let (
|
||||
OpenArgs {
|
||||
|
@ -35,7 +35,7 @@ the path literal."#
|
||||
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
Ok(OutputStream::one(
|
||||
UntaggedValue::string(get_full_help(&Path, &args.scope)).into_value(Tag::unknown()),
|
||||
UntaggedValue::string(get_full_help(&Path, args.scope())).into_value(Tag::unknown()),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ impl WholeStreamCommand for Pwd {
|
||||
}
|
||||
|
||||
pub fn pwd(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let shell_manager = args.shell_manager.clone();
|
||||
let shell_manager = args.shell_manager();
|
||||
let args = args.evaluate_once()?;
|
||||
|
||||
shell_manager.pwd(args)
|
||||
|
@ -1,13 +1,12 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue};
|
||||
use nu_protocol::{Signature, SyntaxShape, UntaggedValue};
|
||||
use nu_source::Tagged;
|
||||
use rand::prelude::{thread_rng, Rng};
|
||||
|
||||
pub struct SubCommand;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct BoolArgs {
|
||||
bias: Option<Tagged<f64>>,
|
||||
}
|
||||
@ -30,7 +29,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
"Generate a random boolean value"
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
bool_command(args)
|
||||
}
|
||||
|
||||
@ -50,12 +49,15 @@ impl WholeStreamCommand for SubCommand {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bool_command(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let (BoolArgs { bias }, _) = args.process()?;
|
||||
pub fn bool_command(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let args = args.evaluate_once()?;
|
||||
let cmd_args = BoolArgs {
|
||||
bias: args.get_flag("bias")?,
|
||||
};
|
||||
|
||||
let mut probability = 0.5;
|
||||
|
||||
if let Some(prob) = bias {
|
||||
if let Some(prob) = cmd_args.bias {
|
||||
probability = *prob as f64;
|
||||
|
||||
let probability_is_valid = (0.0..=1.0).contains(&probability);
|
||||
@ -71,9 +73,8 @@ pub fn bool_command(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
|
||||
let mut rng = thread_rng();
|
||||
let bool_result: bool = rng.gen_bool(probability);
|
||||
let bool_untagged_value = UntaggedValue::boolean(bool_result);
|
||||
|
||||
Ok(ActionStream::one(ReturnSuccess::value(bool_untagged_value)))
|
||||
Ok(OutputStream::one(UntaggedValue::boolean(bool_result)))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -1,14 +1,13 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue};
|
||||
use nu_protocol::{Signature, SyntaxShape, UntaggedValue};
|
||||
use nu_source::Tagged;
|
||||
use rand::distributions::Alphanumeric;
|
||||
use rand::prelude::{thread_rng, Rng};
|
||||
|
||||
pub struct SubCommand;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct CharsArgs {
|
||||
length: Option<Tagged<u32>>,
|
||||
}
|
||||
@ -33,7 +32,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
"Generate random chars"
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
chars(args)
|
||||
}
|
||||
|
||||
@ -53,18 +52,20 @@ impl WholeStreamCommand for SubCommand {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn chars(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let (CharsArgs { length }, _) = args.process()?;
|
||||
pub fn chars(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let args = args.evaluate_once()?;
|
||||
let cmd_args = CharsArgs {
|
||||
length: args.get_flag("length")?,
|
||||
};
|
||||
|
||||
let chars_length = length.map_or(DEFAULT_CHARS_LENGTH, |l| l.item);
|
||||
let chars_length = cmd_args.length.map_or(DEFAULT_CHARS_LENGTH, |l| l.item);
|
||||
|
||||
let random_string: String = thread_rng()
|
||||
.sample_iter(&Alphanumeric)
|
||||
.take(chars_length as usize)
|
||||
.collect();
|
||||
|
||||
let result = UntaggedValue::string(random_string);
|
||||
Ok(ActionStream::one(ReturnSuccess::value(result)))
|
||||
Ok(OutputStream::one(UntaggedValue::string(random_string)))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};
|
||||
use nu_protocol::{Signature, UntaggedValue};
|
||||
|
||||
pub struct Command;
|
||||
|
||||
@ -18,9 +18,10 @@ impl WholeStreamCommand for Command {
|
||||
"Generate random values."
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
Ok(ActionStream::one(Ok(ReturnSuccess::Value(
|
||||
UntaggedValue::string(get_full_help(&Command, &args.scope)).into_value(Tag::unknown()),
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
Ok(OutputStream::one(UntaggedValue::string(get_full_help(
|
||||
&Command,
|
||||
args.scope(),
|
||||
))))
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,15 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::deserializer::NumericRange;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue};
|
||||
use nu_protocol::{Range, Signature, SyntaxShape, UntaggedValue};
|
||||
use nu_source::Tagged;
|
||||
use rand::prelude::{thread_rng, Rng};
|
||||
use std::cmp::Ordering;
|
||||
|
||||
pub struct SubCommand;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct DecimalArgs {
|
||||
range: Option<Tagged<NumericRange>>,
|
||||
range: Option<Tagged<Range>>,
|
||||
}
|
||||
|
||||
impl WholeStreamCommand for SubCommand {
|
||||
@ -27,7 +25,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
"Generate a random decimal within a range [min..max]"
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
decimal(args)
|
||||
}
|
||||
|
||||
@ -49,19 +47,22 @@ impl WholeStreamCommand for SubCommand {
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Generate a random decimal between 1 and 10",
|
||||
example: "random decimal 1..10",
|
||||
description: "Generate a random decimal between 1.0 and 1.1",
|
||||
example: "random decimal 1.0..1.1",
|
||||
result: None,
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decimal(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let (DecimalArgs { range }, _) = args.process()?;
|
||||
pub fn decimal(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let args = args.evaluate_once()?;
|
||||
let cmd_args = DecimalArgs {
|
||||
range: args.opt(0)?,
|
||||
};
|
||||
|
||||
let (min, max) = if let Some(range) = &range {
|
||||
(range.item.min() as f64, range.item.max() as f64)
|
||||
let (min, max) = if let Some(range) = &cmd_args.range {
|
||||
(range.item.min_f64()?, range.item.max_f64()?)
|
||||
} else {
|
||||
(0.0, 1.0)
|
||||
};
|
||||
@ -70,21 +71,23 @@ pub fn decimal(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
Some(Ordering::Greater) => Err(ShellError::labeled_error(
|
||||
format!("Invalid range {}..{}", min, max),
|
||||
"expected a valid range",
|
||||
range
|
||||
cmd_args
|
||||
.range
|
||||
.expect("Unexpected ordering error in random decimal")
|
||||
.span(),
|
||||
)),
|
||||
Some(Ordering::Equal) => {
|
||||
let untagged_result = UntaggedValue::decimal_from_float(min, Span::new(64, 64));
|
||||
Ok(ActionStream::one(ReturnSuccess::value(untagged_result)))
|
||||
}
|
||||
Some(Ordering::Equal) => Ok(OutputStream::one(UntaggedValue::decimal_from_float(
|
||||
min,
|
||||
Span::new(64, 64),
|
||||
))),
|
||||
_ => {
|
||||
let mut thread_rng = thread_rng();
|
||||
let result: f64 = thread_rng.gen_range(min, max);
|
||||
|
||||
let untagged_result = UntaggedValue::decimal_from_float(result, Span::new(64, 64));
|
||||
|
||||
Ok(ActionStream::one(ReturnSuccess::value(untagged_result)))
|
||||
Ok(OutputStream::one(UntaggedValue::decimal_from_float(
|
||||
result,
|
||||
Span::new(64, 64),
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ use rand::prelude::{thread_rng, Rng};
|
||||
|
||||
pub struct SubCommand;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct DiceArgs {
|
||||
dice: Option<Tagged<u32>>,
|
||||
sides: Option<Tagged<u32>>,
|
||||
@ -38,7 +37,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
"Generate a random dice roll"
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
dice(args)
|
||||
}
|
||||
|
||||
@ -58,17 +57,22 @@ impl WholeStreamCommand for SubCommand {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dice(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
pub fn dice(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let tag = args.call_info.name_tag.clone();
|
||||
let (DiceArgs { dice, sides }, _) = args.process()?;
|
||||
|
||||
let dice = if let Some(dice_tagged) = dice {
|
||||
let args = args.evaluate_once()?;
|
||||
let cmd_args = DiceArgs {
|
||||
dice: args.get_flag("dice")?,
|
||||
sides: args.get_flag("sides")?,
|
||||
};
|
||||
|
||||
let dice = if let Some(dice_tagged) = cmd_args.dice {
|
||||
*dice_tagged
|
||||
} else {
|
||||
1
|
||||
};
|
||||
|
||||
let sides = if let Some(sides_tagged) = sides {
|
||||
let sides = if let Some(sides_tagged) = cmd_args.sides {
|
||||
*sides_tagged
|
||||
} else {
|
||||
6
|
||||
@ -79,7 +83,7 @@ pub fn dice(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
UntaggedValue::int(thread_rng.gen_range(1, sides + 1)).into_value(tag.clone())
|
||||
});
|
||||
|
||||
Ok((iter).to_action_stream())
|
||||
Ok((iter).to_output_stream())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -1,17 +1,15 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::deserializer::NumericRange;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue};
|
||||
use nu_protocol::{Range, Signature, SyntaxShape, UntaggedValue};
|
||||
use nu_source::Tagged;
|
||||
use rand::prelude::{thread_rng, Rng};
|
||||
use std::cmp::Ordering;
|
||||
|
||||
pub struct SubCommand;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct IntegerArgs {
|
||||
range: Option<Tagged<NumericRange>>,
|
||||
range: Option<Tagged<Range>>,
|
||||
}
|
||||
|
||||
impl WholeStreamCommand for SubCommand {
|
||||
@ -27,7 +25,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
"Generate a random integer [min..max]"
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
integer(args)
|
||||
}
|
||||
|
||||
@ -57,11 +55,14 @@ impl WholeStreamCommand for SubCommand {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn integer(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let (IntegerArgs { range }, _) = args.process()?;
|
||||
pub fn integer(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let args = args.evaluate_once()?;
|
||||
let cmd_args = IntegerArgs {
|
||||
range: args.opt(0)?,
|
||||
};
|
||||
|
||||
let (min, max) = if let Some(range) = &range {
|
||||
(range.item.min(), range.item.max())
|
||||
let (min, max) = if let Some(range) = &cmd_args.range {
|
||||
(range.min_u64()?, range.max_u64()?)
|
||||
} else {
|
||||
(0, u64::MAX)
|
||||
};
|
||||
@ -70,23 +71,23 @@ pub fn integer(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
Ordering::Greater => Err(ShellError::labeled_error(
|
||||
format!("Invalid range {}..{}", min, max),
|
||||
"expected a valid range",
|
||||
range
|
||||
cmd_args
|
||||
.range
|
||||
.expect("Unexpected ordering error in random integer")
|
||||
.span(),
|
||||
)),
|
||||
Ordering::Equal => {
|
||||
let untagged_result = UntaggedValue::int(min).into_value(Tag::unknown());
|
||||
Ok(ActionStream::one(ReturnSuccess::value(untagged_result)))
|
||||
}
|
||||
Ordering::Equal => Ok(OutputStream::one(
|
||||
UntaggedValue::int(min).into_value(Tag::unknown()),
|
||||
)),
|
||||
_ => {
|
||||
let mut thread_rng = thread_rng();
|
||||
// add 1 to max, because gen_range is right-exclusive
|
||||
let max = max.saturating_add(1);
|
||||
let result: u64 = thread_rng.gen_range(min, max);
|
||||
|
||||
let untagged_result = UntaggedValue::int(result).into_value(Tag::unknown());
|
||||
|
||||
Ok(ActionStream::one(ReturnSuccess::value(untagged_result)))
|
||||
Ok(OutputStream::one(
|
||||
UntaggedValue::int(result).into_value(Tag::unknown()),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ReturnSuccess, Signature};
|
||||
use nu_protocol::Signature;
|
||||
use uuid_crate::Uuid;
|
||||
|
||||
pub struct SubCommand;
|
||||
@ -19,7 +19,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
"Generate a random uuid4 string"
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
uuid(args)
|
||||
}
|
||||
|
||||
@ -32,10 +32,10 @@ impl WholeStreamCommand for SubCommand {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uuid(_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
pub fn uuid(_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let uuid_4 = Uuid::new_v4().to_hyphenated().to_string();
|
||||
|
||||
Ok(ActionStream::one(ReturnSuccess::value(uuid_4)))
|
||||
Ok(OutputStream::one(uuid_4))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -1,13 +1,10 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::deserializer::NumericRange;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{RangeInclusion, ReturnSuccess, Signature, SyntaxShape};
|
||||
use nu_source::Tagged;
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct RangeArgs {
|
||||
area: Tagged<NumericRange>,
|
||||
range: nu_protocol::Range,
|
||||
}
|
||||
|
||||
pub struct Range;
|
||||
@ -19,7 +16,7 @@ impl WholeStreamCommand for Range {
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("range").required(
|
||||
"rows ",
|
||||
"rows",
|
||||
SyntaxShape::Range,
|
||||
"range of rows to return: Eg) 4..7 (=> from 4 to 7)",
|
||||
)
|
||||
@ -29,37 +26,25 @@ impl WholeStreamCommand for Range {
|
||||
"Return only the selected rows."
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
range(args)
|
||||
}
|
||||
}
|
||||
|
||||
fn range(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let (RangeArgs { area }, input) = args.process()?;
|
||||
let range = area.item;
|
||||
let (from, left_inclusive) = range.from;
|
||||
let (to, right_inclusive) = range.to;
|
||||
let from = from.map(|from| *from as usize).unwrap_or(0).saturating_add(
|
||||
if left_inclusive == RangeInclusion::Inclusive {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
},
|
||||
);
|
||||
let to = to
|
||||
.map(|to| *to as usize)
|
||||
.unwrap_or(usize::MAX)
|
||||
.saturating_sub(if right_inclusive == RangeInclusion::Inclusive {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
});
|
||||
fn range(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let args = args.evaluate_once()?;
|
||||
let cmd_args = RangeArgs {
|
||||
range: args.req(0)?,
|
||||
};
|
||||
|
||||
Ok(input
|
||||
.skip(from)
|
||||
.take(to - from + 1)
|
||||
.map(ReturnSuccess::value)
|
||||
.to_action_stream())
|
||||
let from = cmd_args.range.min_usize()?;
|
||||
let to = cmd_args.range.max_usize()?;
|
||||
|
||||
if from > to {
|
||||
Ok(OutputStream::one(Value::nothing()))
|
||||
} else {
|
||||
Ok(args.input.skip(from).take(to - from + 1).to_output_stream())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -5,7 +5,9 @@ use nu_engine::WholeStreamCommand;
|
||||
use nu_engine::{CommandArgs, Example};
|
||||
use nu_errors::ShellError;
|
||||
use nu_parser::ParserScope;
|
||||
use nu_protocol::{hir::CapturedBlock, Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use nu_protocol::{
|
||||
hir::CapturedBlock, hir::ExternalRedirection, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
use nu_source::Tagged;
|
||||
use nu_stream::ActionStream;
|
||||
|
||||
@ -88,7 +90,12 @@ fn process_row(
|
||||
context.scope.enter_scope();
|
||||
context.scope.add_vars(&block.captured.entries);
|
||||
context.scope.add_var("$it", row);
|
||||
let result = run_block(&block.block, context, input_stream);
|
||||
let result = run_block(
|
||||
&block.block,
|
||||
context,
|
||||
input_stream,
|
||||
ExternalRedirection::Stdout,
|
||||
);
|
||||
context.scope.exit_scope();
|
||||
|
||||
result
|
||||
@ -148,7 +155,17 @@ fn reduce(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let result = process_row(block, &*context, row);
|
||||
context.scope.exit_scope();
|
||||
|
||||
result
|
||||
// we make sure that result is an indexed item
|
||||
result.and_then(|mut acc| {
|
||||
let values = acc.drain_vec();
|
||||
let value = values
|
||||
.get(0)
|
||||
.ok_or_else(|| ShellError::unexpected("No value to update with"))?;
|
||||
Ok(InputStream::one(match value.value {
|
||||
UntaggedValue::Primitive(_) => each::make_indexed_item(0, value.clone()),
|
||||
_ => value.clone(),
|
||||
}))
|
||||
})
|
||||
})?
|
||||
.to_action_stream())
|
||||
} else {
|
||||
|
@ -64,7 +64,7 @@ impl WholeStreamCommand for Remove {
|
||||
|
||||
fn rm(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let name = args.call_info.name_tag.clone();
|
||||
let shell_manager = args.shell_manager.clone();
|
||||
let shell_manager = args.shell_manager();
|
||||
let (args, _): (RemoveArgs, _) = args.process()?;
|
||||
|
||||
if args.trash.item && args.permanent.item {
|
||||
|
@ -2,7 +2,6 @@ use crate::commands::classified::external;
|
||||
use crate::prelude::*;
|
||||
|
||||
use derive_new::new;
|
||||
use parking_lot::Mutex;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use nu_engine::shell::CdArgs;
|
||||
@ -12,9 +11,6 @@ use nu_protocol::hir::{Expression, ExternalArgs, ExternalCommand, Literal, Spann
|
||||
use nu_protocol::{Signature, SyntaxShape};
|
||||
use nu_source::Tagged;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct RunExternalArgs {}
|
||||
|
||||
#[derive(new)]
|
||||
pub struct RunExternalCommand {
|
||||
/// Whether or not nushell is being used in an interactive context
|
||||
@ -78,17 +74,7 @@ impl WholeStreamCommand for RunExternalCommand {
|
||||
})
|
||||
.and_then(spanned_expression_to_string)?;
|
||||
|
||||
let mut external_context = {
|
||||
EvaluationContext {
|
||||
scope: args.scope.clone(),
|
||||
host: args.host.clone(),
|
||||
shell_manager: args.shell_manager.clone(),
|
||||
ctrl_c: args.ctrl_c.clone(),
|
||||
configs: args.configs.clone(),
|
||||
current_errors: Arc::new(Mutex::new(vec![])),
|
||||
windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())),
|
||||
}
|
||||
};
|
||||
let mut external_context = args.context.clone();
|
||||
|
||||
let is_interactive = self.interactive;
|
||||
|
||||
@ -114,7 +100,7 @@ impl WholeStreamCommand for RunExternalCommand {
|
||||
|
||||
let result = external_context
|
||||
.shell_manager
|
||||
.cd(cd_args, args.call_info.name_tag.clone());
|
||||
.cd(cd_args, args.call_info.name_tag);
|
||||
|
||||
return Ok(result?.to_action_stream());
|
||||
}
|
||||
|
@ -153,19 +153,16 @@ impl WholeStreamCommand for Save {
|
||||
}
|
||||
}
|
||||
|
||||
fn save(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let mut full_path = PathBuf::from(raw_args.shell_manager.path());
|
||||
let name_tag = raw_args.call_info.name_tag.clone();
|
||||
let name = raw_args.call_info.name_tag.clone();
|
||||
let scope = raw_args.scope.clone();
|
||||
let host = raw_args.host.clone();
|
||||
let ctrl_c = raw_args.ctrl_c.clone();
|
||||
let configs = raw_args.configs.clone();
|
||||
let current_errors = raw_args.current_errors.clone();
|
||||
let shell_manager = raw_args.shell_manager.clone();
|
||||
fn save(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let shell_manager = args.shell_manager();
|
||||
let mut full_path = PathBuf::from(shell_manager.path());
|
||||
let name_tag = args.call_info.name_tag.clone();
|
||||
let name = args.call_info.name_tag.clone();
|
||||
let context = args.context.clone();
|
||||
let scope = args.scope().clone();
|
||||
|
||||
let head = raw_args.call_info.args.head.clone();
|
||||
let args = raw_args.evaluate_once()?;
|
||||
let head = args.call_info.args.head.clone();
|
||||
let args = args.evaluate_once()?;
|
||||
|
||||
let path: Option<Tagged<PathBuf>> = args.opt(0)?;
|
||||
let save_raw = args.has_flag("raw");
|
||||
@ -203,12 +200,8 @@ fn save(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
if let Some(extension) = full_path.extension() {
|
||||
let command_name = format!("to {}", extension.to_string_lossy());
|
||||
if let Some(converter) = scope.get_command(&command_name) {
|
||||
let new_args = RawCommandArgs {
|
||||
host,
|
||||
ctrl_c,
|
||||
configs,
|
||||
current_errors,
|
||||
shell_manager: shell_manager.clone(),
|
||||
let new_args = CommandArgs {
|
||||
context,
|
||||
call_info: UnevaluatedCallInfo {
|
||||
args: nu_protocol::hir::Call {
|
||||
head,
|
||||
@ -219,9 +212,9 @@ fn save(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
},
|
||||
name_tag: name_tag.clone(),
|
||||
},
|
||||
scope,
|
||||
input: InputStream::from_stream(input.into_iter()),
|
||||
};
|
||||
let mut result = converter.run(new_args.with_input(input))?;
|
||||
let mut result = converter.run(new_args)?;
|
||||
let result_vec: Vec<Value> = result.drain_vec();
|
||||
if converter.is_binary() {
|
||||
process_binary_return_success!('scope, result_vec, name_tag)
|
||||
|
@ -26,12 +26,14 @@ impl WholeStreamCommand for Shells {
|
||||
|
||||
fn shells(args: CommandArgs) -> ActionStream {
|
||||
let mut shells_out = VecDeque::new();
|
||||
let shell_manager = args.shell_manager();
|
||||
let tag = args.call_info.name_tag;
|
||||
let active_index = shell_manager.current_shell.load(Ordering::SeqCst);
|
||||
|
||||
for (index, shell) in args.shell_manager.shells.lock().iter().enumerate() {
|
||||
for (index, shell) in shell_manager.shells.lock().iter().enumerate() {
|
||||
let mut dict = TaggedDictBuilder::new(&tag);
|
||||
|
||||
if index == (*args.shell_manager.current_shell).load(Ordering::SeqCst) {
|
||||
if index == active_index {
|
||||
dict.insert_untagged("active", true);
|
||||
} else {
|
||||
dict.insert_untagged("active", false);
|
||||
|
@ -35,7 +35,7 @@ impl WholeStreamCommand for Sleep {
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let ctrl_c = args.ctrl_c().clone();
|
||||
let ctrl_c = args.ctrl_c();
|
||||
|
||||
let (SleepArgs { duration, rest }, _) = args.process()?;
|
||||
|
||||
|
@ -21,7 +21,7 @@ impl WholeStreamCommand for Command {
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
Ok(ActionStream::one(Ok(ReturnSuccess::Value(
|
||||
UntaggedValue::string(get_full_help(&Command, &args.scope)).into_value(Tag::unknown()),
|
||||
UntaggedValue::string(get_full_help(&Command, args.scope())).into_value(Tag::unknown()),
|
||||
))))
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ impl WholeStreamCommand for Command {
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
Ok(ActionStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::string(get_full_help(&Command, &args.scope)).into_value(Tag::unknown()),
|
||||
UntaggedValue::string(get_full_help(&Command, args.scope())).into_value(Tag::unknown()),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::commands::table::options::{ConfigExtensions, NuConfig};
|
||||
use crate::prelude::*;
|
||||
use crate::primitive::get_color_config;
|
||||
use futures::executor::block_on;
|
||||
use nu_data::value::{format_leaf, style_leaf};
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
@ -152,11 +153,17 @@ fn values_to_entries(
|
||||
headers.insert(
|
||||
0,
|
||||
StyledString::new(
|
||||
"#".to_owned(),
|
||||
TextStyle::new()
|
||||
.alignment(Alignment::Center)
|
||||
.fg(nu_ansi_term::Color::Green)
|
||||
.bold(Some(true)),
|
||||
"#".to_string(),
|
||||
TextStyle::new().alignment(Alignment::Center).style(
|
||||
color_hm
|
||||
.get("header_color")
|
||||
.unwrap_or(
|
||||
&nu_ansi_term::Style::default()
|
||||
.bold()
|
||||
.fg(nu_ansi_term::Color::Green),
|
||||
)
|
||||
.to_owned(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -166,7 +173,7 @@ fn values_to_entries(
|
||||
|
||||
fn table(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let mut args = args.evaluate_once()?;
|
||||
let configuration = args.configs.lock().global_config();
|
||||
let configuration = args.configs().lock().global_config();
|
||||
|
||||
// Ideally, get_color_config would get all the colors configured in the config.toml
|
||||
// and create a style based on those settings. However, there are few places where
|
||||
@ -184,7 +191,7 @@ fn table(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
|
||||
let mut delay_slot = None;
|
||||
|
||||
let term_width = args.host.lock().width();
|
||||
let term_width = args.host().lock().width();
|
||||
|
||||
#[cfg(feature = "table-pager")]
|
||||
let pager = Pager::new()
|
||||
@ -194,7 +201,7 @@ fn table(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
.set_input_handler(Box::new(input_handling::MinusInputHandler {}))
|
||||
.finish();
|
||||
|
||||
let stream_data = {
|
||||
let stream_data = async {
|
||||
let finished = Arc::new(AtomicBool::new(false));
|
||||
// we are required to clone finished, for use within the callback, otherwise we get borrow errors
|
||||
#[cfg(feature = "table-pager")]
|
||||
@ -204,7 +211,7 @@ fn table(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
// This is called when the pager finishes, to indicate to the
|
||||
// while loop below to finish, in case of long running InputStream consumer
|
||||
// that doesn't finish by the time the user quits out of the pager
|
||||
pager.lock().add_exit_callback(move || {
|
||||
pager.lock().await.add_exit_callback(move || {
|
||||
finished_within_callback.store(true, Ordering::Relaxed);
|
||||
});
|
||||
}
|
||||
@ -265,7 +272,7 @@ fn table(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let output = draw_table(&t, term_width, &color_hm);
|
||||
#[cfg(feature = "table-pager")]
|
||||
{
|
||||
let mut pager = pager.lock();
|
||||
let mut pager = pager.lock().await;
|
||||
writeln!(pager.lines, "{}", output).map_err(|_| {
|
||||
ShellError::untagged_runtime_error("Error writing to pager")
|
||||
})?;
|
||||
@ -280,7 +287,7 @@ fn table(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
|
||||
#[cfg(feature = "table-pager")]
|
||||
{
|
||||
let mut pager_lock = pager.lock();
|
||||
let mut pager_lock = pager.lock().await;
|
||||
pager_lock.data_finished();
|
||||
}
|
||||
|
||||
@ -290,13 +297,14 @@ fn table(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
#[cfg(feature = "table-pager")]
|
||||
{
|
||||
let (minus_result, streaming_result) =
|
||||
join(minus::async_std_updating(pager.clone()), stream_data);
|
||||
block_on(join(minus::async_std_updating(pager.clone()), stream_data));
|
||||
minus_result.map_err(|_| ShellError::untagged_runtime_error("Error paging data"))?;
|
||||
streaming_result?;
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "table-pager"))]
|
||||
stream_data.map_err(|_| ShellError::untagged_runtime_error("Error streaming data"))?;
|
||||
block_on(stream_data)
|
||||
.map_err(|_| ShellError::untagged_runtime_error("Error streaming data"))?;
|
||||
|
||||
Ok(OutputStream::empty())
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ impl WholeStreamCommand for To {
|
||||
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
Ok(OutputStream::one(
|
||||
UntaggedValue::string(get_full_help(&To, &args.scope)).into_value(Tag::unknown()),
|
||||
UntaggedValue::string(get_full_help(&To, args.scope())).into_value(Tag::unknown()),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -435,7 +435,7 @@ fn html_value(value: &Value) -> String {
|
||||
output_string.push_str("\">");
|
||||
}
|
||||
_ => {
|
||||
let output = pretty_hex::pretty_hex(&b);
|
||||
let output = nu_pretty_hex::pretty_hex(&b);
|
||||
|
||||
output_string.push_str("<pre>");
|
||||
output_string.push_str(&output);
|
||||
@ -444,7 +444,7 @@ fn html_value(value: &Value) -> String {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let output = pretty_hex::pretty_hex(&b);
|
||||
let output = nu_pretty_hex::pretty_hex(&b);
|
||||
|
||||
output_string.push_str("<pre>");
|
||||
output_string.push_str(&output);
|
||||
|
@ -11,7 +11,18 @@ impl WholeStreamCommand for Uniq {
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("uniq").switch("count", "Count the unique rows", Some('c'))
|
||||
Signature::build("uniq")
|
||||
.switch("count", "Count the unique rows", Some('c'))
|
||||
.switch(
|
||||
"repeated",
|
||||
"Count the rows that has more than one value",
|
||||
Some('d'),
|
||||
)
|
||||
.switch(
|
||||
"ignore-case",
|
||||
"Ignore differences in case when comparing",
|
||||
Some('i'),
|
||||
)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -33,6 +44,19 @@ impl WholeStreamCommand for Uniq {
|
||||
UntaggedValue::int(4).into(),
|
||||
]),
|
||||
},
|
||||
Example {
|
||||
description: "Only print duplicate lines, one for each group",
|
||||
example: "echo [1 2 2] | uniq -d",
|
||||
result: Some(vec![UntaggedValue::int(2).into()]),
|
||||
},
|
||||
Example {
|
||||
description: "Ignore differences in case when comparing",
|
||||
example: "echo ['hello' 'goodbye' 'Hello'] | uniq -i",
|
||||
result: Some(vec![
|
||||
UntaggedValue::string("hello").into(),
|
||||
UntaggedValue::string("goodbye").into(),
|
||||
]),
|
||||
},
|
||||
Example {
|
||||
description: "Remove duplicate rows and show counts of a list/table",
|
||||
example: "echo [1 2 2] | uniq -c",
|
||||
@ -53,22 +77,49 @@ impl WholeStreamCommand for Uniq {
|
||||
}
|
||||
}
|
||||
|
||||
fn to_lowercase(value: nu_protocol::Value) -> nu_protocol::Value {
|
||||
use nu_protocol::value::StringExt;
|
||||
|
||||
if value.is_string() {
|
||||
value
|
||||
.value
|
||||
.expect_string()
|
||||
.to_lowercase()
|
||||
.to_string_value(value.tag)
|
||||
} else {
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
fn uniq(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let args = args.evaluate_once()?;
|
||||
let should_show_count = args.has_flag("count");
|
||||
let show_repeated = args.has_flag("repeated");
|
||||
let ignore_case = args.has_flag("ignore-case");
|
||||
let input = args.input;
|
||||
let uniq_values = {
|
||||
let mut counter = IndexMap::<nu_protocol::Value, usize>::new();
|
||||
for line in input.into_vec() {
|
||||
*counter.entry(line).or_insert(0) += 1;
|
||||
let item = if ignore_case {
|
||||
to_lowercase(line)
|
||||
} else {
|
||||
line
|
||||
};
|
||||
*counter.entry(item).or_insert(0) += 1;
|
||||
}
|
||||
counter
|
||||
};
|
||||
|
||||
let mut values_vec_deque = VecDeque::new();
|
||||
|
||||
let values = if show_repeated {
|
||||
uniq_values.into_iter().filter(|i| i.1 > 1).collect::<_>()
|
||||
} else {
|
||||
uniq_values
|
||||
};
|
||||
|
||||
if should_show_count {
|
||||
for item in uniq_values {
|
||||
for item in values {
|
||||
use nu_protocol::Value;
|
||||
let value = {
|
||||
match item.0.value {
|
||||
@ -110,7 +161,7 @@ fn uniq(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
values_vec_deque.push_back(value);
|
||||
}
|
||||
} else {
|
||||
for item in uniq_values {
|
||||
for item in values {
|
||||
values_vec_deque.push_back(item.0);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ use crate::prelude::*;
|
||||
use nu_engine::run_block;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::hir::ExternalRedirection;
|
||||
use nu_protocol::{
|
||||
ColumnPath, Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
@ -86,7 +87,12 @@ fn process_row(
|
||||
context.scope.add_var("$it", input.clone());
|
||||
context.scope.add_vars(&captured_block.captured.entries);
|
||||
|
||||
let result = run_block(&captured_block.block, &*context, input_stream);
|
||||
let result = run_block(
|
||||
&captured_block.block,
|
||||
&*context,
|
||||
input_stream,
|
||||
ExternalRedirection::Stdout,
|
||||
);
|
||||
|
||||
context.scope.exit_scope();
|
||||
|
||||
|
@ -20,7 +20,7 @@ impl WholeStreamCommand for Url {
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
Ok(ActionStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::string(get_full_help(&Url, &args.scope)).into_value(Tag::unknown()),
|
||||
UntaggedValue::string(get_full_help(&Url, args.scope())).into_value(Tag::unknown()),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
@ -192,11 +192,6 @@ fn features_enabled() -> Vec<String> {
|
||||
names.push("which".to_string());
|
||||
}
|
||||
|
||||
#[cfg(feature = "ichwh")]
|
||||
{
|
||||
names.push("ichwh".to_string());
|
||||
}
|
||||
|
||||
#[cfg(feature = "zip")]
|
||||
{
|
||||
names.push("zip".to_string());
|
||||
|
@ -95,10 +95,10 @@ fn where_command(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
};
|
||||
|
||||
Ok(WhereIterator {
|
||||
block,
|
||||
condition,
|
||||
context,
|
||||
input,
|
||||
block,
|
||||
}
|
||||
.to_output_stream())
|
||||
}
|
||||
|
@ -135,32 +135,28 @@ macro_rules! entry_path {
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(feature = "ichwh")]
|
||||
#[cfg(feature = "which")]
|
||||
fn get_first_entry_in_path(item: &str, tag: Tag) -> Option<Value> {
|
||||
use futures::executor::block_on;
|
||||
|
||||
block_on(ichwh::which(item))
|
||||
.unwrap_or(None)
|
||||
.map(|path| entry_path!(item, path.into(), tag))
|
||||
which::which(item)
|
||||
.map(|path| entry_path!(item, path, tag))
|
||||
.ok()
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "ichwh"))]
|
||||
#[cfg(not(feature = "which"))]
|
||||
fn get_first_entry_in_path(_: &str, _: Tag) -> Option<Value> {
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(feature = "ichwh")]
|
||||
#[cfg(feature = "which")]
|
||||
fn get_all_entries_in_path(item: &str, tag: Tag) -> Vec<Value> {
|
||||
use futures::executor::block_on;
|
||||
|
||||
block_on(ichwh::which_all(&item))
|
||||
which::which_all(&item)
|
||||
.map(|iter| {
|
||||
iter.map(|path| entry_path!(item, path, tag.clone()))
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(|path| entry_path!(item, path.into(), tag.clone()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "ichwh"))]
|
||||
#[cfg(not(feature = "which"))]
|
||||
fn get_all_entries_in_path(_: &str, _: Tag) -> Vec<Value> {
|
||||
vec![]
|
||||
}
|
||||
@ -224,7 +220,7 @@ fn which(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let mut output = vec![];
|
||||
|
||||
for app in which_args.applications {
|
||||
let values = which_single(app, which_args.all, &args.scope);
|
||||
let values = which_single(app, which_args.all, &args.scope());
|
||||
output.extend(values);
|
||||
}
|
||||
|
||||
|
@ -68,19 +68,9 @@ impl WholeStreamCommand for WithEnv {
|
||||
}
|
||||
|
||||
fn with_env(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let redirection = raw_args.call_info.args.external_redirection;
|
||||
let external_redirection = raw_args.call_info.args.external_redirection;
|
||||
let context = EvaluationContext::from_args(&raw_args);
|
||||
let (
|
||||
WithEnvArgs {
|
||||
variable,
|
||||
mut block,
|
||||
},
|
||||
input,
|
||||
) = raw_args.process()?;
|
||||
|
||||
if let Some(block) = std::sync::Arc::<nu_protocol::hir::Block>::get_mut(&mut block.block) {
|
||||
block.set_redirect(redirection);
|
||||
}
|
||||
let (WithEnvArgs { variable, block }, input) = raw_args.process()?;
|
||||
|
||||
let mut env = IndexMap::new();
|
||||
|
||||
@ -118,7 +108,7 @@ fn with_env(raw_args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
context.scope.add_env(env);
|
||||
context.scope.add_vars(&block.captured.entries);
|
||||
|
||||
let result = run_block(&block.block, &context, input);
|
||||
let result = run_block(&block.block, &context, input, external_redirection);
|
||||
context.scope.exit_scope();
|
||||
|
||||
result.map(|x| x.to_action_stream())
|
||||
|
@ -8,15 +8,15 @@ use double_echo::Command as DoubleEcho;
|
||||
use double_ls::Command as DoubleLs;
|
||||
use stub_generate::{mock_path, Command as StubOpen};
|
||||
|
||||
use nu_engine::basic_evaluation_context;
|
||||
use nu_errors::ShellError;
|
||||
use nu_parser::ParserScope;
|
||||
use nu_protocol::hir::ClassifiedBlock;
|
||||
use nu_protocol::hir::{ClassifiedBlock, ExternalRedirection};
|
||||
use nu_protocol::{ShellTypeName, Value};
|
||||
use nu_source::AnchorLocation;
|
||||
|
||||
use crate::commands::{
|
||||
Append, BuildString, Each, Echo, First, Get, Keep, Last, Let, Nth, Select, StrCollect, Wrap,
|
||||
Append, BuildString, Each, Echo, First, Get, Keep, Last, Let, Math, MathMode, Nth, Select,
|
||||
StrCollect, Wrap,
|
||||
};
|
||||
use nu_engine::{run_block, whole_stream_command, Command, EvaluationContext, WholeStreamCommand};
|
||||
use nu_stream::InputStream;
|
||||
@ -24,7 +24,7 @@ use nu_stream::InputStream;
|
||||
pub fn test_examples(cmd: Command) -> Result<(), ShellError> {
|
||||
let examples = cmd.examples();
|
||||
|
||||
let base_context = basic_evaluation_context()?;
|
||||
let base_context = EvaluationContext::basic();
|
||||
|
||||
base_context.add_commands(vec![
|
||||
// Command Doubles
|
||||
@ -90,9 +90,11 @@ pub fn test_examples(cmd: Command) -> Result<(), ShellError> {
|
||||
pub fn test(cmd: impl WholeStreamCommand + 'static) -> Result<(), ShellError> {
|
||||
let examples = cmd.examples();
|
||||
|
||||
let base_context = basic_evaluation_context()?;
|
||||
let base_context = EvaluationContext::basic();
|
||||
|
||||
base_context.add_commands(vec![
|
||||
whole_stream_command(Math),
|
||||
whole_stream_command(MathMode {}),
|
||||
whole_stream_command(Echo {}),
|
||||
whole_stream_command(BuildString {}),
|
||||
whole_stream_command(Get {}),
|
||||
@ -147,7 +149,7 @@ pub fn test(cmd: impl WholeStreamCommand + 'static) -> Result<(), ShellError> {
|
||||
pub fn test_anchors(cmd: Command) -> Result<(), ShellError> {
|
||||
let examples = cmd.examples();
|
||||
|
||||
let base_context = basic_evaluation_context()?;
|
||||
let base_context = EvaluationContext::basic();
|
||||
|
||||
base_context.add_commands(vec![
|
||||
// Minimal restricted commands to aid in testing
|
||||
@ -231,7 +233,7 @@ fn evaluate_block(
|
||||
|
||||
ctx.scope.enter_scope();
|
||||
|
||||
let result = run_block(&block.block, ctx, input_stream);
|
||||
let result = run_block(&block.block, ctx, input_stream, ExternalRedirection::Stdout);
|
||||
|
||||
ctx.scope.exit_scope();
|
||||
|
||||
|
@ -16,9 +16,8 @@ pub(crate) use nu_data::value;
|
||||
pub(crate) use nu_engine::EvaluationContext;
|
||||
pub(crate) use nu_engine::Example;
|
||||
pub(crate) use nu_engine::Host;
|
||||
pub(crate) use nu_engine::RawCommandArgs;
|
||||
pub(crate) use nu_engine::RunnableContext;
|
||||
pub(crate) use nu_engine::{get_full_help, CommandArgs, Scope, WholeStreamCommand};
|
||||
pub(crate) use nu_engine::{RunnableContext, RunnableContextWithoutInput};
|
||||
pub(crate) use nu_parser::ParserScope;
|
||||
pub(crate) use nu_protocol::{out, row};
|
||||
pub(crate) use nu_source::{AnchorLocation, PrettyDebug, Span, SpannedItem, Tag, TaggedItem};
|
||||
|
@ -68,18 +68,16 @@ pub fn chop() {
|
||||
let stdin = io::stdin();
|
||||
let mut stdout = io::stdout();
|
||||
|
||||
for line in stdin.lock().lines() {
|
||||
if let Ok(given) = line {
|
||||
let chopped = if given.is_empty() {
|
||||
&given
|
||||
} else {
|
||||
let to = given.len() - 1;
|
||||
&given[..to]
|
||||
};
|
||||
for given in stdin.lock().lines().flatten() {
|
||||
let chopped = if given.is_empty() {
|
||||
&given
|
||||
} else {
|
||||
let to = given.len() - 1;
|
||||
&given[..to]
|
||||
};
|
||||
|
||||
if let Err(_e) = writeln!(stdout, "{}", chopped) {
|
||||
break;
|
||||
}
|
||||
if let Err(_e) = writeln!(stdout, "{}", chopped) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,21 @@ fn reduce_numbered_example() {
|
||||
assert_eq!(actual.out, "1");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reduce_numbered_integer_addition_example() {
|
||||
let actual = nu!(
|
||||
cwd: ".", pipeline(
|
||||
r#"
|
||||
echo [1 2 3 4]
|
||||
| reduce -n {= $acc.item + $it.item }
|
||||
| get item
|
||||
"#
|
||||
)
|
||||
);
|
||||
|
||||
assert_eq!(actual.out, "10");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn folding_with_tables() {
|
||||
let actual = nu!(
|
||||
|
@ -4,7 +4,7 @@ description = "CLI for nushell"
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
name = "nu-data"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
@ -29,13 +29,13 @@ toml = "0.5.8"
|
||||
sha2 = "0.9.3"
|
||||
common-path = "1.0.0"
|
||||
|
||||
nu-errors = { version = "0.30.0", path = "../nu-errors" }
|
||||
nu-protocol = { version = "0.30.0", path = "../nu-protocol" }
|
||||
nu-source = { version = "0.30.0", path = "../nu-source" }
|
||||
nu-table = { version = "0.30.0", path = "../nu-table" }
|
||||
nu-test-support = { version = "0.30.0", path = "../nu-test-support" }
|
||||
nu-value-ext = { version = "0.30.0", path = "../nu-value-ext" }
|
||||
nu-ansi-term = { version = "0.30.0", path = "../nu-ansi-term" }
|
||||
nu-errors = { version = "0.31.0", path = "../nu-errors" }
|
||||
nu-protocol = { version = "0.31.0", path = "../nu-protocol" }
|
||||
nu-source = { version = "0.31.0", path = "../nu-source" }
|
||||
nu-table = { version = "0.31.0", path = "../nu-table" }
|
||||
nu-test-support = { version = "0.31.0", path = "../nu-test-support" }
|
||||
nu-value-ext = { version = "0.31.0", path = "../nu-value-ext" }
|
||||
nu-ansi-term = { version = "0.31.0", path = "../nu-ansi-term" }
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
users = "0.11.0"
|
||||
|
@ -59,8 +59,8 @@ impl NuConfig {
|
||||
};
|
||||
|
||||
Ok(NuConfig {
|
||||
file_path,
|
||||
vars,
|
||||
file_path,
|
||||
modified_at,
|
||||
})
|
||||
}
|
||||
|
@ -16,19 +16,11 @@ pub struct Labels {
|
||||
|
||||
impl Labels {
|
||||
pub fn at(&self, idx: usize) -> Option<&str> {
|
||||
if let Some(k) = self.x.get(idx) {
|
||||
Some(&k[..])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
self.x.get(idx).map(|k| &k[..])
|
||||
}
|
||||
|
||||
pub fn at_split(&self, idx: usize) -> Option<&str> {
|
||||
if let Some(k) = self.y.get(idx) {
|
||||
Some(&k[..])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
self.y.get(idx).map(|k| &k[..])
|
||||
}
|
||||
|
||||
pub fn grouped(&self) -> impl Iterator<Item = &String> {
|
||||
|
@ -4,18 +4,18 @@ description = "Core commands for nushell"
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
name = "nu-engine"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
|
||||
[dependencies]
|
||||
nu-data = { version = "0.30.0", path = "../nu-data" }
|
||||
nu-errors = { version = "0.30.0", path = "../nu-errors" }
|
||||
nu-parser = { version = "0.30.0", path = "../nu-parser" }
|
||||
nu-plugin = { version = "0.30.0", path = "../nu-plugin" }
|
||||
nu-protocol = { version = "0.30.0", path = "../nu-protocol" }
|
||||
nu-source = { version = "0.30.0", path = "../nu-source" }
|
||||
nu-stream = { version = "0.30.0", path = "../nu-stream" }
|
||||
nu-value-ext = { version = "0.30.0", path = "../nu-value-ext" }
|
||||
nu-ansi-term = { version = "0.30.0", path = "../nu-ansi-term" }
|
||||
nu-data = { version = "0.31.0", path = "../nu-data" }
|
||||
nu-errors = { version = "0.31.0", path = "../nu-errors" }
|
||||
nu-parser = { version = "0.31.0", path = "../nu-parser" }
|
||||
nu-plugin = { version = "0.31.0", path = "../nu-plugin" }
|
||||
nu-protocol = { version = "0.31.0", path = "../nu-protocol" }
|
||||
nu-source = { version = "0.31.0", path = "../nu-source" }
|
||||
nu-stream = { version = "0.31.0", path = "../nu-stream" }
|
||||
nu-value-ext = { version = "0.31.0", path = "../nu-value-ext" }
|
||||
nu-ansi-term = { version = "0.31.0", path = "../nu-ansi-term" }
|
||||
|
||||
trash = { version = "1.3.0", optional = true }
|
||||
which = { version = "4.0.2", optional = true }
|
||||
@ -57,7 +57,7 @@ umask = "1.0.0"
|
||||
users = "0.11.0"
|
||||
|
||||
[dev-dependencies]
|
||||
nu-test-support = { version = "0.30.0", path = "../nu-test-support" }
|
||||
nu-test-support = { version = "0.31.0", path = "../nu-test-support" }
|
||||
hamcrest2 = "0.3.0"
|
||||
|
||||
[features]
|
||||
|
@ -1,26 +0,0 @@
|
||||
use crate::EvaluationContext;
|
||||
use crate::Scope;
|
||||
use crate::{basic_shell_manager, config_holder::ConfigHolder};
|
||||
use crate::{env::basic_host::BasicHost, Host};
|
||||
use indexmap::IndexMap;
|
||||
use parking_lot::Mutex;
|
||||
use std::error::Error;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub fn basic_evaluation_context() -> Result<EvaluationContext, Box<dyn Error>> {
|
||||
let scope = Scope::new();
|
||||
let mut host = BasicHost {};
|
||||
let env_vars = host.vars().iter().cloned().collect::<IndexMap<_, _>>();
|
||||
scope.add_env(env_vars);
|
||||
|
||||
Ok(EvaluationContext {
|
||||
scope,
|
||||
host: Arc::new(parking_lot::Mutex::new(Box::new(host))),
|
||||
current_errors: Arc::new(Mutex::new(vec![])),
|
||||
ctrl_c: Arc::new(AtomicBool::new(false)),
|
||||
configs: Arc::new(Mutex::new(ConfigHolder::new())),
|
||||
shell_manager: basic_shell_manager::basic_shell_manager()?,
|
||||
windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())),
|
||||
})
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
use crate::filesystem::filesystem_shell::{FilesystemShell, FilesystemShellMode};
|
||||
use crate::shell::shell_manager::ShellManager;
|
||||
|
||||
use parking_lot::Mutex;
|
||||
use std::error::Error;
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub fn basic_shell_manager() -> Result<ShellManager, Box<dyn Error>> {
|
||||
Ok(ShellManager {
|
||||
current_shell: Arc::new(AtomicUsize::new(0)),
|
||||
shells: Arc::new(Mutex::new(vec![Box::new(FilesystemShell::basic(
|
||||
FilesystemShellMode::Cli,
|
||||
)?)])),
|
||||
})
|
||||
}
|
@ -21,72 +21,39 @@ use std::sync::Arc;
|
||||
#[derive(Getters)]
|
||||
#[get = "pub"]
|
||||
pub struct CommandArgs {
|
||||
pub host: Arc<parking_lot::Mutex<Box<dyn Host>>>,
|
||||
pub ctrl_c: Arc<AtomicBool>,
|
||||
pub configs: Arc<Mutex<ConfigHolder>>,
|
||||
pub current_errors: Arc<Mutex<Vec<ShellError>>>,
|
||||
pub shell_manager: ShellManager,
|
||||
pub context: EvaluationContext,
|
||||
pub call_info: UnevaluatedCallInfo,
|
||||
pub scope: Scope,
|
||||
pub input: InputStream,
|
||||
}
|
||||
|
||||
impl CommandArgs {
|
||||
pub fn scope(&self) -> &Scope {
|
||||
&self.context.scope
|
||||
}
|
||||
|
||||
pub fn host(&self) -> Arc<parking_lot::Mutex<Box<dyn Host>>> {
|
||||
self.context.host.clone()
|
||||
}
|
||||
|
||||
pub fn current_errors(&self) -> Arc<Mutex<Vec<ShellError>>> {
|
||||
self.context.current_errors.clone()
|
||||
}
|
||||
|
||||
pub fn ctrl_c(&self) -> Arc<AtomicBool> {
|
||||
self.context.ctrl_c.clone()
|
||||
}
|
||||
|
||||
pub fn configs(&self) -> Arc<Mutex<ConfigHolder>> {
|
||||
self.context.configs.clone()
|
||||
}
|
||||
|
||||
pub fn shell_manager(&self) -> ShellManager {
|
||||
self.context.shell_manager.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub type RunnableContext = CommandArgs;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct RunnableContextWithoutInput {
|
||||
pub shell_manager: ShellManager,
|
||||
pub host: Arc<parking_lot::Mutex<Box<dyn Host>>>,
|
||||
pub current_errors: Arc<Mutex<Vec<ShellError>>>,
|
||||
pub ctrl_c: Arc<AtomicBool>,
|
||||
pub call_info: UnevaluatedCallInfo,
|
||||
pub configs: Arc<Mutex<ConfigHolder>>,
|
||||
pub scope: Scope,
|
||||
pub name: Tag,
|
||||
}
|
||||
|
||||
impl RunnableContextWithoutInput {
|
||||
pub fn with_input(self, input: InputStream) -> CommandArgs {
|
||||
CommandArgs {
|
||||
shell_manager: self.shell_manager,
|
||||
host: self.host,
|
||||
current_errors: self.current_errors,
|
||||
ctrl_c: self.ctrl_c,
|
||||
call_info: self.call_info,
|
||||
configs: self.configs,
|
||||
scope: self.scope,
|
||||
input,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Getters, Clone)]
|
||||
#[get = "pub"]
|
||||
pub struct RawCommandArgs {
|
||||
pub host: Arc<parking_lot::Mutex<Box<dyn Host>>>,
|
||||
pub ctrl_c: Arc<AtomicBool>,
|
||||
pub current_errors: Arc<Mutex<Vec<ShellError>>>,
|
||||
pub configs: Arc<Mutex<ConfigHolder>>,
|
||||
pub shell_manager: ShellManager,
|
||||
pub scope: Scope,
|
||||
pub call_info: UnevaluatedCallInfo,
|
||||
}
|
||||
|
||||
impl RawCommandArgs {
|
||||
pub fn with_input(self, input: impl Into<InputStream>) -> CommandArgs {
|
||||
CommandArgs {
|
||||
host: self.host,
|
||||
ctrl_c: self.ctrl_c,
|
||||
configs: self.configs,
|
||||
current_errors: self.current_errors,
|
||||
shell_manager: self.shell_manager,
|
||||
call_info: self.call_info,
|
||||
scope: self.scope,
|
||||
input: input.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for CommandArgs {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.call_info.fmt(f)
|
||||
@ -94,49 +61,18 @@ impl std::fmt::Debug for CommandArgs {
|
||||
}
|
||||
|
||||
impl CommandArgs {
|
||||
pub fn evaluate_once(self) -> Result<EvaluatedWholeStreamCommandArgs, ShellError> {
|
||||
let ctx = EvaluationContext::new(
|
||||
self.scope,
|
||||
self.host,
|
||||
self.current_errors,
|
||||
self.ctrl_c,
|
||||
self.configs,
|
||||
self.shell_manager,
|
||||
Arc::new(Mutex::new(std::collections::HashMap::new())),
|
||||
);
|
||||
pub fn evaluate_once(self) -> Result<EvaluatedCommandArgs, ShellError> {
|
||||
let ctx = self.context.clone();
|
||||
|
||||
let input = self.input;
|
||||
let call_info = self.call_info.evaluate(&ctx)?;
|
||||
|
||||
Ok(EvaluatedWholeStreamCommandArgs::new(
|
||||
ctx.host,
|
||||
ctx.ctrl_c,
|
||||
ctx.configs,
|
||||
ctx.shell_manager,
|
||||
call_info,
|
||||
input,
|
||||
ctx.scope,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn split(self) -> (InputStream, RunnableContextWithoutInput) {
|
||||
let new_context = RunnableContextWithoutInput {
|
||||
shell_manager: self.shell_manager,
|
||||
host: self.host,
|
||||
ctrl_c: self.ctrl_c,
|
||||
configs: self.configs,
|
||||
name: self.call_info.name_tag.clone(),
|
||||
call_info: self.call_info,
|
||||
current_errors: self.current_errors,
|
||||
scope: self.scope,
|
||||
};
|
||||
|
||||
(self.input, new_context)
|
||||
Ok(EvaluatedCommandArgs::new(ctx, call_info, input))
|
||||
}
|
||||
|
||||
pub fn extract<T>(
|
||||
self,
|
||||
f: impl FnOnce(&EvaluatedCommandArgs) -> Result<T, ShellError>,
|
||||
f: impl FnOnce(&EvaluatedCommandArgsWithoutInput) -> Result<T, ShellError>,
|
||||
) -> Result<(T, InputStream), ShellError> {
|
||||
let evaluated_args = self.evaluate_once()?;
|
||||
|
||||
@ -153,37 +89,26 @@ impl CommandArgs {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EvaluatedWholeStreamCommandArgs {
|
||||
pub args: EvaluatedCommandArgs,
|
||||
pub struct EvaluatedCommandArgs {
|
||||
pub args: EvaluatedCommandArgsWithoutInput,
|
||||
pub input: InputStream,
|
||||
}
|
||||
|
||||
impl Deref for EvaluatedWholeStreamCommandArgs {
|
||||
type Target = EvaluatedCommandArgs;
|
||||
impl Deref for EvaluatedCommandArgs {
|
||||
type Target = EvaluatedCommandArgsWithoutInput;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.args
|
||||
}
|
||||
}
|
||||
|
||||
impl EvaluatedWholeStreamCommandArgs {
|
||||
impl EvaluatedCommandArgs {
|
||||
pub fn new(
|
||||
host: Arc<parking_lot::Mutex<dyn Host>>,
|
||||
ctrl_c: Arc<AtomicBool>,
|
||||
configs: Arc<Mutex<ConfigHolder>>,
|
||||
shell_manager: ShellManager,
|
||||
context: EvaluationContext,
|
||||
call_info: CallInfo,
|
||||
input: impl Into<InputStream>,
|
||||
scope: Scope,
|
||||
) -> EvaluatedWholeStreamCommandArgs {
|
||||
EvaluatedWholeStreamCommandArgs {
|
||||
args: EvaluatedCommandArgs {
|
||||
host,
|
||||
ctrl_c,
|
||||
configs,
|
||||
shell_manager,
|
||||
call_info,
|
||||
scope,
|
||||
},
|
||||
) -> EvaluatedCommandArgs {
|
||||
EvaluatedCommandArgs {
|
||||
args: EvaluatedCommandArgsWithoutInput { context, call_info },
|
||||
input: input.into(),
|
||||
}
|
||||
}
|
||||
@ -193,13 +118,13 @@ impl EvaluatedWholeStreamCommandArgs {
|
||||
}
|
||||
|
||||
pub fn parts(self) -> (InputStream, EvaluatedArgs) {
|
||||
let EvaluatedWholeStreamCommandArgs { args, input } = self;
|
||||
let EvaluatedCommandArgs { args, input } = self;
|
||||
|
||||
(input, args.call_info.args)
|
||||
}
|
||||
|
||||
pub fn split(self) -> (InputStream, EvaluatedCommandArgs) {
|
||||
let EvaluatedWholeStreamCommandArgs { args, input } = self;
|
||||
pub fn split(self) -> (InputStream, EvaluatedCommandArgsWithoutInput) {
|
||||
let EvaluatedCommandArgs { args, input } = self;
|
||||
|
||||
(input, args)
|
||||
}
|
||||
@ -207,20 +132,28 @@ impl EvaluatedWholeStreamCommandArgs {
|
||||
|
||||
#[derive(Getters, new)]
|
||||
#[get = "pub(crate)"]
|
||||
pub struct EvaluatedCommandArgs {
|
||||
pub host: Arc<parking_lot::Mutex<dyn Host>>,
|
||||
pub ctrl_c: Arc<AtomicBool>,
|
||||
pub configs: Arc<Mutex<ConfigHolder>>,
|
||||
pub shell_manager: ShellManager,
|
||||
pub struct EvaluatedCommandArgsWithoutInput {
|
||||
pub context: EvaluationContext,
|
||||
pub call_info: CallInfo,
|
||||
pub scope: Scope,
|
||||
}
|
||||
|
||||
impl EvaluatedCommandArgs {
|
||||
impl EvaluatedCommandArgsWithoutInput {
|
||||
pub fn nth(&self, pos: usize) -> Option<&Value> {
|
||||
self.call_info.args.nth(pos)
|
||||
}
|
||||
|
||||
pub fn scope(&self) -> Scope {
|
||||
self.context.scope.clone()
|
||||
}
|
||||
|
||||
pub fn configs(&self) -> Arc<Mutex<ConfigHolder>> {
|
||||
self.context.configs.clone()
|
||||
}
|
||||
|
||||
pub fn host(&self) -> Arc<parking_lot::Mutex<Box<dyn Host>>> {
|
||||
self.context.host.clone()
|
||||
}
|
||||
|
||||
/// Get the nth positional argument, error if not possible
|
||||
pub fn expect_nth(&self, pos: usize) -> Result<&Value, ShellError> {
|
||||
self.call_info
|
||||
|
5
crates/nu-engine/src/env/host.rs
vendored
5
crates/nu-engine/src/env/host.rs
vendored
@ -114,10 +114,7 @@ impl Host for FakeHost {
|
||||
fn env_get(&mut self, key: OsString) -> Option<OsString> {
|
||||
let key = key.into_string().expect("Couldn't convert to string.");
|
||||
|
||||
match self.env_vars.get(&key) {
|
||||
Some(env) => Some(OsString::from(env)),
|
||||
None => None,
|
||||
}
|
||||
self.env_vars.get(&key).map(OsString::from)
|
||||
}
|
||||
|
||||
fn env_set(&mut self, key: OsString, value: OsString) {
|
||||
|
@ -4,7 +4,8 @@ use crate::evaluation_context::EvaluationContext;
|
||||
use nu_errors::ShellError;
|
||||
use nu_parser::ParserScope;
|
||||
use nu_protocol::hir::{
|
||||
Block, Call, ClassifiedCommand, Expression, Pipeline, SpannedExpression, Synthetic,
|
||||
Block, Call, ClassifiedCommand, Expression, ExternalRedirection, Pipeline, SpannedExpression,
|
||||
Synthetic,
|
||||
};
|
||||
use nu_protocol::{UntaggedValue, Value};
|
||||
use nu_source::{Span, Tag};
|
||||
@ -15,13 +16,15 @@ pub fn run_block(
|
||||
block: &Block,
|
||||
ctx: &EvaluationContext,
|
||||
mut input: InputStream,
|
||||
external_redirection: ExternalRedirection,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let mut output: Result<InputStream, ShellError> = Ok(OutputStream::empty());
|
||||
for (_, definition) in block.definitions.iter() {
|
||||
ctx.scope.add_definition(definition.clone());
|
||||
}
|
||||
|
||||
for group in &block.block {
|
||||
let num_groups = block.block.len();
|
||||
for (group_num, group) in block.block.iter().enumerate() {
|
||||
match output {
|
||||
Ok(inp) if inp.is_empty() => {}
|
||||
Ok(inp) => {
|
||||
@ -75,7 +78,9 @@ pub fn run_block(
|
||||
}
|
||||
}
|
||||
output = Ok(OutputStream::empty());
|
||||
for pipeline in &group.pipelines {
|
||||
|
||||
let num_pipelines = group.pipelines.len();
|
||||
for (pipeline_num, pipeline) in group.pipelines.iter().enumerate() {
|
||||
match output {
|
||||
Ok(inp) if inp.is_empty() => {}
|
||||
Ok(mut output_stream) => {
|
||||
@ -112,7 +117,13 @@ pub fn run_block(
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
output = run_pipeline(pipeline, ctx, input);
|
||||
output = if group_num == (num_groups - 1) && pipeline_num == (num_pipelines - 1) {
|
||||
// we're at the end of the block, so use the given external redirection
|
||||
run_pipeline(pipeline, ctx, input, external_redirection)
|
||||
} else {
|
||||
// otherwise, we're in the middle of the block, so use a default redirection
|
||||
run_pipeline(pipeline, ctx, input, ExternalRedirection::Stdout)
|
||||
};
|
||||
|
||||
input = OutputStream::empty();
|
||||
}
|
||||
@ -125,13 +136,15 @@ fn run_pipeline(
|
||||
commands: &Pipeline,
|
||||
ctx: &EvaluationContext,
|
||||
mut input: InputStream,
|
||||
external_redirection: ExternalRedirection,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
for item in commands.list.clone() {
|
||||
input = match item {
|
||||
let num_commands = commands.list.len();
|
||||
for (command_num, command) in commands.list.iter().enumerate() {
|
||||
input = match command {
|
||||
ClassifiedCommand::Dynamic(call) => {
|
||||
let mut args = vec![];
|
||||
if let Some(positional) = call.positional {
|
||||
for pos in &positional {
|
||||
if let Some(positional) = &call.positional {
|
||||
for pos in positional {
|
||||
let result = run_expression_block(pos, ctx)?.into_vec();
|
||||
args.push(result);
|
||||
}
|
||||
@ -160,7 +173,8 @@ fn run_pipeline(
|
||||
{
|
||||
ctx.scope.add_var(param.0.name(), value[0].clone());
|
||||
}
|
||||
let result = run_block(&captured_block.block, ctx, input);
|
||||
let result =
|
||||
run_block(&captured_block.block, ctx, input, external_redirection);
|
||||
ctx.scope.exit_scope();
|
||||
|
||||
let result = result?;
|
||||
@ -174,9 +188,17 @@ fn run_pipeline(
|
||||
|
||||
ClassifiedCommand::Expr(expr) => run_expression_block(&*expr, ctx)?,
|
||||
|
||||
ClassifiedCommand::Error(err) => return Err(err.into()),
|
||||
ClassifiedCommand::Error(err) => return Err(err.clone().into()),
|
||||
|
||||
ClassifiedCommand::Internal(left) => run_internal_command(left, ctx, input)?,
|
||||
ClassifiedCommand::Internal(left) => {
|
||||
if command_num == (num_commands - 1) {
|
||||
let mut left = left.clone();
|
||||
left.args.external_redirection = external_redirection;
|
||||
run_internal_command(&left, ctx, input)?
|
||||
} else {
|
||||
run_internal_command(left, ctx, input)?
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -278,7 +278,7 @@ fn evaluate_invocation(block: &hir::Block, ctx: &EvaluationContext) -> Result<Va
|
||||
None => InputStream::empty(),
|
||||
};
|
||||
|
||||
let result = run_block(&block, ctx, input)?;
|
||||
let result = run_block(&block, ctx, input, hir::ExternalRedirection::Stdout)?;
|
||||
|
||||
let output = result.into_vec();
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::call_info::UnevaluatedCallInfo;
|
||||
use crate::command_args::RawCommandArgs;
|
||||
use crate::evaluation_context::EvaluationContext;
|
||||
use crate::filesystem::filesystem_shell::{FilesystemShell, FilesystemShellMode};
|
||||
use crate::shell::value_shell::ValueShell;
|
||||
use crate::CommandArgs;
|
||||
use log::{log_enabled, trace};
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::hir::{
|
||||
@ -13,7 +13,7 @@ use nu_source::{PrettyDebug, Span, Tag};
|
||||
use nu_stream::{ActionStream, InputStream};
|
||||
|
||||
pub(crate) fn run_internal_command(
|
||||
command: InternalCommand,
|
||||
command: &InternalCommand,
|
||||
context: &EvaluationContext,
|
||||
input: InputStream,
|
||||
) -> Result<InputStream, ShellError> {
|
||||
@ -30,7 +30,7 @@ pub(crate) fn run_internal_command(
|
||||
let result = context.run_command(
|
||||
internal_command,
|
||||
Tag::unknown_anchor(command.name_span),
|
||||
command.args,
|
||||
command.args.clone(), // FIXME: this is inefficient
|
||||
objects,
|
||||
)?;
|
||||
Ok(InputStream::from_stream(InternalIteratorSimple {
|
||||
@ -90,12 +90,8 @@ impl Iterator for InternalIterator {
|
||||
let contents_tag = tagged_contents.tag.clone();
|
||||
let command_name = format!("from {}", extension);
|
||||
if let Some(converter) = self.context.scope.get_command(&command_name) {
|
||||
let new_args = RawCommandArgs {
|
||||
host: self.context.host.clone(),
|
||||
ctrl_c: self.context.ctrl_c.clone(),
|
||||
configs: self.context.configs.clone(),
|
||||
current_errors: self.context.current_errors.clone(),
|
||||
shell_manager: self.context.shell_manager.clone(),
|
||||
let new_args = CommandArgs {
|
||||
context: self.context.clone(),
|
||||
call_info: UnevaluatedCallInfo {
|
||||
args: nu_protocol::hir::Call {
|
||||
head: Box::new(SpannedExpression {
|
||||
@ -111,9 +107,9 @@ impl Iterator for InternalIterator {
|
||||
},
|
||||
name_tag: tagged_contents.tag(),
|
||||
},
|
||||
scope: self.context.scope.clone(),
|
||||
input: InputStream::one(tagged_contents),
|
||||
};
|
||||
let result = converter.run(new_args.with_input(vec![tagged_contents]));
|
||||
let result = converter.run(new_args);
|
||||
|
||||
match result {
|
||||
Ok(mut result) => {
|
||||
|
@ -1,9 +1,10 @@
|
||||
use crate::env::host::Host;
|
||||
use crate::evaluate::scope::{Scope, ScopeFrame};
|
||||
use crate::shell::shell_manager::ShellManager;
|
||||
use crate::whole_stream_command::Command;
|
||||
use crate::{call_info::UnevaluatedCallInfo, config_holder::ConfigHolder};
|
||||
use crate::{command_args::CommandArgs, script};
|
||||
use crate::{env::basic_host::BasicHost, Host};
|
||||
use indexmap::IndexMap;
|
||||
use log::trace;
|
||||
use nu_data::config::{self, Conf, NuConfig};
|
||||
use nu_errors::ShellError;
|
||||
@ -48,18 +49,27 @@ impl EvaluationContext {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_args(args: &CommandArgs) -> EvaluationContext {
|
||||
pub fn basic() -> EvaluationContext {
|
||||
let scope = Scope::new();
|
||||
let mut host = BasicHost {};
|
||||
let env_vars = host.vars().iter().cloned().collect::<IndexMap<_, _>>();
|
||||
scope.add_env(env_vars);
|
||||
|
||||
EvaluationContext {
|
||||
scope: args.scope.clone(),
|
||||
host: args.host.clone(),
|
||||
current_errors: args.current_errors.clone(),
|
||||
ctrl_c: args.ctrl_c.clone(),
|
||||
configs: args.configs.clone(),
|
||||
shell_manager: args.shell_manager.clone(),
|
||||
scope,
|
||||
host: Arc::new(parking_lot::Mutex::new(Box::new(host))),
|
||||
current_errors: Arc::new(Mutex::new(vec![])),
|
||||
ctrl_c: Arc::new(AtomicBool::new(false)),
|
||||
configs: Arc::new(Mutex::new(ConfigHolder::new())),
|
||||
shell_manager: ShellManager::basic(),
|
||||
windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_args(args: &CommandArgs) -> EvaluationContext {
|
||||
args.context.clone()
|
||||
}
|
||||
|
||||
pub fn error(&self, error: ShellError) {
|
||||
self.with_errors(|errors| errors.push(error))
|
||||
}
|
||||
@ -135,13 +145,8 @@ impl EvaluationContext {
|
||||
|
||||
fn command_args(&self, args: hir::Call, input: InputStream, name_tag: Tag) -> CommandArgs {
|
||||
CommandArgs {
|
||||
host: self.host.clone(),
|
||||
ctrl_c: self.ctrl_c.clone(),
|
||||
configs: self.configs.clone(),
|
||||
current_errors: self.current_errors.clone(),
|
||||
shell_manager: self.shell_manager.clone(),
|
||||
context: self.clone(),
|
||||
call_info: self.call_info(args, name_tag),
|
||||
scope: self.scope.clone(),
|
||||
input,
|
||||
}
|
||||
}
|
||||
@ -173,10 +178,8 @@ impl EvaluationContext {
|
||||
Some(env_paths)
|
||||
} else if let Some(env_paths) = self.scope.get_env("Path") {
|
||||
Some(env_paths)
|
||||
} else if let Some(env_paths) = self.scope.get_env("path") {
|
||||
Some(env_paths)
|
||||
} else {
|
||||
None
|
||||
self.scope.get_env("path")
|
||||
};
|
||||
|
||||
if let Some(env_paths) = env_paths {
|
||||
@ -244,10 +247,8 @@ impl EvaluationContext {
|
||||
Some(env_paths)
|
||||
} else if let Some(env_paths) = self.scope.get_env("Path") {
|
||||
Some(env_paths)
|
||||
} else if let Some(env_paths) = self.scope.get_env("path") {
|
||||
Some(env_paths)
|
||||
} else {
|
||||
None
|
||||
self.scope.get_env("path")
|
||||
};
|
||||
|
||||
if let Some(env_paths) = env_paths {
|
||||
|
@ -4,14 +4,14 @@ use crate::filesystem::utils::FileStructure;
|
||||
use crate::maybe_text_codec::{MaybeTextCodec, StringOrBinary};
|
||||
use crate::shell::shell_args::{CdArgs, CopyArgs, LsArgs, MkdirArgs, MvArgs, RemoveArgs};
|
||||
use crate::shell::Shell;
|
||||
use crate::{command_args::EvaluatedWholeStreamCommandArgs, BufCodecReader};
|
||||
use crate::{command_args::EvaluatedCommandArgs, BufCodecReader};
|
||||
use encoding_rs::Encoding;
|
||||
use nu_data::config::LocalConfigDiff;
|
||||
use nu_protocol::{CommandAction, ConfigPath, TaggedDictBuilder, Value};
|
||||
use nu_source::{Span, Tag};
|
||||
use nu_stream::{ActionStream, Interruptible, OutputStream, ToActionStream};
|
||||
use std::collections::VecDeque;
|
||||
use std::io::{Error, ErrorKind};
|
||||
use std::io::ErrorKind;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::Arc;
|
||||
@ -57,17 +57,17 @@ impl FilesystemShell {
|
||||
matches!(&self.mode, FilesystemShellMode::Cli)
|
||||
}
|
||||
|
||||
pub fn basic(mode: FilesystemShellMode) -> Result<FilesystemShell, Error> {
|
||||
pub fn basic(mode: FilesystemShellMode) -> FilesystemShell {
|
||||
let path = match std::env::current_dir() {
|
||||
Ok(path) => path,
|
||||
Err(_) => PathBuf::from("/"),
|
||||
};
|
||||
|
||||
Ok(FilesystemShell {
|
||||
FilesystemShell {
|
||||
path: path.to_string_lossy().to_string(),
|
||||
last_path: path.to_string_lossy().to_string(),
|
||||
mode,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_location(
|
||||
@ -386,82 +386,80 @@ impl Shell for FilesystemShell {
|
||||
));
|
||||
}
|
||||
|
||||
for entry in sources {
|
||||
if let Ok(entry) = entry {
|
||||
let mut sources = FileStructure::new();
|
||||
sources.walk_decorate(&entry)?;
|
||||
for entry in sources.into_iter().flatten() {
|
||||
let mut sources = FileStructure::new();
|
||||
sources.walk_decorate(&entry)?;
|
||||
|
||||
if entry.is_file() {
|
||||
let sources = sources.paths_applying_with(|(source_file, _depth_level)| {
|
||||
if destination.is_dir() {
|
||||
let mut dest = canonicalize(&path, &dst.item)?;
|
||||
if let Some(name) = entry.file_name() {
|
||||
dest.push(name);
|
||||
}
|
||||
Ok((source_file, dest))
|
||||
} else {
|
||||
Ok((source_file, destination.clone()))
|
||||
if entry.is_file() {
|
||||
let sources = sources.paths_applying_with(|(source_file, _depth_level)| {
|
||||
if destination.is_dir() {
|
||||
let mut dest = canonicalize(&path, &dst.item)?;
|
||||
if let Some(name) = entry.file_name() {
|
||||
dest.push(name);
|
||||
}
|
||||
})?;
|
||||
Ok((source_file, dest))
|
||||
} else {
|
||||
Ok((source_file, destination.clone()))
|
||||
}
|
||||
})?;
|
||||
|
||||
for (src, dst) in sources {
|
||||
if src.is_file() {
|
||||
std::fs::copy(src, dst).map_err(|e| {
|
||||
ShellError::labeled_error(e.to_string(), e.to_string(), &name_tag)
|
||||
})?;
|
||||
for (src, dst) in sources {
|
||||
if src.is_file() {
|
||||
std::fs::copy(src, dst).map_err(|e| {
|
||||
ShellError::labeled_error(e.to_string(), e.to_string(), &name_tag)
|
||||
})?;
|
||||
}
|
||||
}
|
||||
} else if entry.is_dir() {
|
||||
let destination = if !destination.exists() {
|
||||
destination.clone()
|
||||
} else {
|
||||
match entry.file_name() {
|
||||
Some(name) => destination.join(name),
|
||||
None => {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Copy aborted. Not a valid path",
|
||||
"not a valid path",
|
||||
dst.tag,
|
||||
))
|
||||
}
|
||||
}
|
||||
} else if entry.is_dir() {
|
||||
let destination = if !destination.exists() {
|
||||
destination.clone()
|
||||
} else {
|
||||
match entry.file_name() {
|
||||
Some(name) => destination.join(name),
|
||||
None => {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Copy aborted. Not a valid path",
|
||||
"not a valid path",
|
||||
dst.tag,
|
||||
))
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
std::fs::create_dir_all(&destination).map_err(|e| {
|
||||
ShellError::labeled_error(e.to_string(), e.to_string(), &dst.tag)
|
||||
})?;
|
||||
std::fs::create_dir_all(&destination).map_err(|e| {
|
||||
ShellError::labeled_error(e.to_string(), e.to_string(), &dst.tag)
|
||||
})?;
|
||||
|
||||
let sources = sources.paths_applying_with(|(source_file, depth_level)| {
|
||||
let mut dest = destination.clone();
|
||||
let path = canonicalize(&path, &source_file)?;
|
||||
let sources = sources.paths_applying_with(|(source_file, depth_level)| {
|
||||
let mut dest = destination.clone();
|
||||
let path = canonicalize(&path, &source_file)?;
|
||||
|
||||
let comps: Vec<_> = path
|
||||
.components()
|
||||
.map(|fragment| fragment.as_os_str())
|
||||
.rev()
|
||||
.take(1 + depth_level)
|
||||
.collect();
|
||||
let comps: Vec<_> = path
|
||||
.components()
|
||||
.map(|fragment| fragment.as_os_str())
|
||||
.rev()
|
||||
.take(1 + depth_level)
|
||||
.collect();
|
||||
|
||||
for fragment in comps.into_iter().rev() {
|
||||
dest.push(fragment);
|
||||
}
|
||||
for fragment in comps.into_iter().rev() {
|
||||
dest.push(fragment);
|
||||
}
|
||||
|
||||
Ok((PathBuf::from(&source_file), dest))
|
||||
})?;
|
||||
Ok((PathBuf::from(&source_file), dest))
|
||||
})?;
|
||||
|
||||
let dst_tag = &dst.tag;
|
||||
for (src, dst) in sources {
|
||||
if src.is_dir() && !dst.exists() {
|
||||
std::fs::create_dir_all(&dst).map_err(|e| {
|
||||
ShellError::labeled_error(e.to_string(), e.to_string(), dst_tag)
|
||||
})?;
|
||||
}
|
||||
let dst_tag = &dst.tag;
|
||||
for (src, dst) in sources {
|
||||
if src.is_dir() && !dst.exists() {
|
||||
std::fs::create_dir_all(&dst).map_err(|e| {
|
||||
ShellError::labeled_error(e.to_string(), e.to_string(), dst_tag)
|
||||
})?;
|
||||
}
|
||||
|
||||
if src.is_file() {
|
||||
std::fs::copy(&src, &dst).map_err(|e| {
|
||||
ShellError::labeled_error(e.to_string(), e.to_string(), &name_tag)
|
||||
})?;
|
||||
}
|
||||
if src.is_file() {
|
||||
std::fs::copy(&src, &dst).map_err(|e| {
|
||||
ShellError::labeled_error(e.to_string(), e.to_string(), &name_tag)
|
||||
})?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -574,13 +572,11 @@ impl Shell for FilesystemShell {
|
||||
.collect();
|
||||
}
|
||||
|
||||
for entry in sources {
|
||||
if let Ok(entry) = entry {
|
||||
move_file(
|
||||
TaggedPathBuf(&entry, &src.tag),
|
||||
TaggedPathBuf(&destination, &dst.tag),
|
||||
)?
|
||||
}
|
||||
for entry in sources.into_iter().flatten() {
|
||||
move_file(
|
||||
TaggedPathBuf(&entry, &src.tag),
|
||||
TaggedPathBuf(&destination, &dst.tag),
|
||||
)?
|
||||
}
|
||||
|
||||
Ok(ActionStream::empty())
|
||||
@ -713,6 +709,7 @@ impl Shell for FilesystemShell {
|
||||
let result;
|
||||
#[cfg(feature = "trash-support")]
|
||||
{
|
||||
use std::io::Error;
|
||||
result = if _trash.item || (rm_always_trash && !_permanent.item) {
|
||||
trash::delete(&f).map_err(|e: trash::Error| {
|
||||
Error::new(ErrorKind::Other, format!("{:?}", e))
|
||||
@ -765,7 +762,7 @@ impl Shell for FilesystemShell {
|
||||
self.path.clone()
|
||||
}
|
||||
|
||||
fn pwd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<ActionStream, ShellError> {
|
||||
fn pwd(&self, args: EvaluatedCommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let path = PathBuf::from(self.path());
|
||||
let p = match dunce::canonicalize(path.as_path()) {
|
||||
Ok(p) => p,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user